From a11dc162530cf7bf133a54f31c4b1b41fc878f65 Mon Sep 17 00:00:00 2001 From: David Newell Date: Wed, 3 Jan 2024 15:24:33 +0000 Subject: [PATCH] consolidate styles --- .../lib/lemon-ui/LemonButton/LemonButton.scss | 389 ++++++++++++++---- .../lib/lemon-ui/LemonButton/LemonButton.tsx | 1 - .../lemon-ui/LemonButton/LemonButton3000.scss | 333 --------------- 3 files changed, 312 insertions(+), 411 deletions(-) delete mode 100644 frontend/src/lib/lemon-ui/LemonButton/LemonButton3000.scss diff --git a/frontend/src/lib/lemon-ui/LemonButton/LemonButton.scss b/frontend/src/lib/lemon-ui/LemonButton/LemonButton.scss index 95cf04c36bf94..e9a38c6e255d9 100644 --- a/frontend/src/lib/lemon-ui/LemonButton/LemonButton.scss +++ b/frontend/src/lib/lemon-ui/LemonButton/LemonButton.scss @@ -1,50 +1,130 @@ +@mixin secondary-variables { + --button-border-color: var(--secondary-3000-button-border); + --lemon-button-bg-color-active: var(--bg-light); + --lemon-button-border-color-hover: var(--secondary-3000-button-border-hover); + --lemon-button-frame-bg-color: var(--secondary-3000-frame-bg); +} + .LemonButton, .Link.LemonButton { + --lemon-button-chrome-depth: 0.1875rem; + --lemon-button-hover-depth: -0.03125rem; + --lemon-button-press-depth: 0.03125rem; + --lemon-button-padding-horizontal: 0.75rem; + --lemon-button-padding-adjacent-icon: 0.375rem; + --lemon-button-side-action-width: 2rem; + --lemon-button-transition: opacity 200ms ease, transform 200ms ease; + --lemon-button-border-width: 0; + --lemon-button-bg-color: transparent; + --button-border-color: none; + --lemon-button-border-color-hover: none; + --lemon-button-frame-bg-color: none; + --lemon-button-font-size: 0.875rem; + --lemon-button-height: 2.3125rem; + --lemon-button-gap: 0.5rem; + --lemon-button-icon-opacity: 0.5; + --lemon-button-profile-picture-opacity: 0.75; // Profile pictures must be more prominent than icons + --lemon-button-color: var(--default); + // Make sure we override .Link's styles where needed, e.g. padding position: relative; - display: flex; - flex-direction: row; - flex-shrink: 0; - gap: 0.5rem; - align-items: center; - justify-content: flex-start; - padding: 0.25rem 0.75rem; - font-size: 0.875rem; - font-weight: 500; - line-height: 1.5rem; - text-align: left; + padding: 0; + font-family: var(--font-title); appearance: none !important; // Important as this gets overridden by Ant styles... cursor: pointer; user-select: none; background: none; - border: none; border-radius: var(--radius); - transition: background-color 200ms ease, color 200ms ease, border 200ms ease, opacity 200ms ease, - transform 100ms ease; + outline: none; + transition: var(--lemon-button-transition); .font-normal { font-family: var(--font-sans); } .LemonButton__chrome { + position: relative; display: flex; flex: 1; - gap: 0.5rem; - } - - .LemonButton__content { - display: flex; - flex: 1; + flex-direction: row; + flex-shrink: 0; + gap: var(--lemon-button-gap); align-items: center; - line-height: initial; + justify-content: flex-start; + width: 100%; + height: 100%; + min-height: var(--lemon-button-height); + padding: 0.25rem var(--lemon-button-padding-horizontal); + font-size: var(--lemon-button-font-size); + font-weight: 500; + line-height: 1.5rem; + color: var(--lemon-button-color); + text-align: left; + background: none; + border-color: transparent; + border-style: solid; + border-width: var(--lemon-button-border-width); + + .LemonButton__content { + display: flex; + flex: 1; + align-items: center; + overflow: hidden; + line-height: initial; + } + + .LemonButton__icon { + display: flex; + flex-shrink: 0; + place-items: center center; + font-size: 1.5rem; + + > * { + opacity: var(--lemon-button-icon-opacity); + } + + > .ProfilePicture, + > .Lettermark { + opacity: var(--lemon-button-profile-picture-opacity); + } + } } &[aria-disabled='true']:not(.LemonButton--loading) { cursor: not-allowed; opacity: var(--opacity-disabled); + } + + &.LemonButton--active, + &:hover:not([aria-disabled='true']), + &:not([aria-disabled='true']):active { + --lemon-button-icon-opacity: 0.75; + --lemon-button-profile-picture-opacity: 1; + } + + &.LemonButton--full-width { + --lemon-button-padding-horizontal: 0.5rem; + + width: 100%; + } + + &.LemonButton--loading { + cursor: default; + } + + &.LemonButton--no-padding { + width: auto; + height: auto; + min-height: 0; + padding: 0; - > span { - cursor: not-allowed; + .LemonButton__chrome { + min-height: 0; + padding: 0; + } + + &.LemonButton--full-width { + width: 100%; } } @@ -62,16 +142,8 @@ } } - &.LemonButton--loading { - cursor: default; - } - - &.LemonButton--full-width { - width: 100%; - } - &.LemonButton--centered { - > span { + .LemonButton__chrome { justify-content: center !important; } @@ -81,69 +153,184 @@ } } - &.LemonButton--has-icon { - padding-left: 0.5rem; + &.LemonButton--no-content { + --lemon-button-padding-horizontal: 0.5rem; } - &.LemonButton--no-content { - padding-right: 0.5rem; - padding-left: 0.5rem; + &.LemonButton--has-icon { + --lemon-button-padding-left: 0.5rem; } &.LemonButton--xsmall { - gap: 0.25rem; - font-size: 0.75rem; + --lemon-button-padding-horizontal: 0.375rem; + --lemon-button-padding-adjacent-icon: 0.25rem; + --lemon-button-font-size: 0.75rem; + --lemon-button-height: 1.625rem; + --lemon-button-gap: 0.25rem; + --lemon-button-side-action-width: 1.5rem; + } + + &.LemonButton--small { + --lemon-button-padding-horizontal: 0.5rem; + --lemon-button-height: 2.0625rem; + --lemon-button-gap: 0.25rem; + --lemon-button-side-action-width: 1.75rem; + } - > span { - gap: 0.25rem; + &.LemonButton--large { + --lemon-button-font-size: 1rem; + --lemon-button-padding-adjacent-icon: 0.75rem; + --lemon-button-height: 3.0625rem; + --lemon-button-gap: 0.75rem; + } + + &.LemonButton--primary { + --lemon-button-bg-color: var(--primary-3000-button-bg); + --lemon-button-bg-color-active: var(--primary-3000-button-bg); + --button-border-color: var(--primary-3000-button-border); + --lemon-button-border-color-hover: var(--primary-3000-button-border-hover); + --lemon-button-frame-bg-color: var(--primary-3000-frame-bg); + --lemon-button-color: var(--text-3000-light); + + &.LemonButton--status-alt { + --lemon-button-bg-color: var(--primary-3000-frame-bg-light); + --lemon-button-bg-color-active: var(--lemon-button-bg-color); + --button-border-color: var(--primary-3000-button-border); + --lemon-button-border-color-hover: var(--primary-3000-button-border-hover); + --lemon-button-frame-bg-color: var(--primary-3000-button-bg-dark); + --lemon-button-color: var(--text-3000-light); } + } - .LemonButton__icon { - font-size: 0.875rem; + &.LemonButton--secondary.LemonButton--status-alt:hover, + &.LemonButton--secondary.LemonButton--status-alt.LemonButton--active, + &.LemonButton--secondary:not(.LemonButton--status-alt, .LemonButton--status-danger) { + @include secondary-variables; + } + + &.LemonButton--status-danger, + &.LemonButton--primary.LemonButton--status-danger, + &.LemonButton--secondary.LemonButton--status-danger { + --lemon-button-color: var(--danger-3000-button-border-hover); + --button-border-color: var(--danger-3000-button-border); + --lemon-button-border-color-hover: var(--danger-3000-button-border-hover); + --lemon-button-frame-bg-color: var(--danger-3000-frame-bg); + --lemon-button-icon-opacity: 1; + } + + &.LemonButton--secondary.LemonButton--status-alt { + --lemon-button-color: var(--muted); + + &.LemonButton--active, + &:hover:not([aria-disabled='true']) { + --lemon-button-color: var(--default); } } - &.LemonButton--small { - gap: 0.25rem; + &.LemonButton--primary, + &.LemonButton--secondary { + --lemon-button-border-width: 1px; - > span { - gap: 0.25rem; + &:not([aria-disabled='true']):hover .LemonButton__chrome { + &::after { + border-color: var(--lemon-button-border-color-hover); + } } - .LemonButton__icon { - font-size: 1.25rem; + &.LemonButton--has-icon:not(.LemonButton--no-content, .LemonButton--no-padding) { + --lemon-button-padding-left: var(--lemon-button-padding-adjacent-icon); } - } - &.LemonButton--large { - font-size: 1rem; + &.LemonButton--has-side-icon:not(.LemonButton--no-content, .LemonButton--no-padding) { + --lemon-button-padding-right: var(--lemon-button-padding-adjacent-icon); + } - > span { - gap: 0.75rem; + .LemonButton__chrome { + padding: calc(0.25rem - var(--lemon-button-chrome-depth) * 0.5) + var(--lemon-button-padding-right, var(--lemon-button-padding-horizontal)) + calc(0.25rem + var(--lemon-button-chrome-depth) * 0.5) + var(--lemon-button-padding-left, var(--lemon-button-padding-horizontal)); + background: transparent; + + & > * { + z-index: 1; // Places button content above the ::after element + } + + &::before { + position: absolute; + inset: -1px; + z-index: 0; + content: ''; + border: 1px solid var(--button-border-color); + border-radius: var(--radius); + } + + &::after { + position: absolute; + inset: -1px -1px calc(var(--lemon-button-chrome-depth) - 1px) -1px; + z-index: 0; + content: ''; + background: var(--lemon-button-bg-color); + border: 1px solid var(--button-border-color); + border-radius: var(--radius); + box-shadow: 0 var(--lemon-button-chrome-depth) 0 -1px var(--lemon-button-frame-bg-color); + transition: opacity 200ms ease; + } } - .LemonButton__icon { - font-size: 1.75rem; + &.LemonButton--active, + &:not([aria-disabled='true']):active { + .LemonButton__chrome { + &::after { + border: 1px solid var(--lemon-button-border-color-hover); + } + } } - } - &.LemonButton--no-padding { - width: auto; - height: auto; - min-height: 0; - padding: 0; + &:hover:not([aria-disabled='true']) { + --lemon-button-depth: var(--lemon-button-hover-depth); + } - &.LemonButton--full-width { - width: 100%; + &:not([aria-disabled='true']):active { + --lemon-button-depth: var(--lemon-button-press-depth); + } + + &:hover:not([aria-disabled='true']), + &:not([aria-disabled='true']):active { + .LemonButton__chrome { + transform: translateY(var(--lemon-button-depth)); + + &::after { + box-shadow: 0 calc(var(--lemon-button-chrome-depth) - var(--lemon-button-depth)) 0 -1px var(--lemon-button-frame-bg-color); + } + + &::before { + bottom: calc(var(--lemon-button-depth) - 1px); + } + } + } + + &.LemonButton--active { + .LemonButton__chrome { + &::after { + background: var(--lemon-button-bg-color-active); + } + } } } - .LemonButton__icon { - display: flex; - flex-shrink: 0; - place-items: center center; - font-size: 1.5rem; - transition: color 200ms ease; + &.LemonButton--tertiary { + &:not([aria-disabled='true']):hover, + &.LemonButton--active { + background-color: var(--glass-border-3000); + } + + &.LemonButton--status-danger { + &:not([aria-disabled='true']):hover, + &.LemonButton--active { + background-color: var(--danger-highlight); + } + } } .ant-tooltip & { @@ -169,24 +356,72 @@ &--full-width { width: 100%; } + + &:hover > .LemonButton--secondary.LemonButton--status-alt { + @include secondary-variables; + } } .LemonButtonWithSideAction__spacer { box-sizing: content-box; - - &.LemonButtonWithSideAction__spacer--divider { + width: calc( + var(--lemon-button-side-action-width) - + var(--lemon-button-padding-right, var(--lemon-button-padding-horizontal)) + ); + height: 1.25rem; + color: var(--muted); + + &--divider { + padding: 0; + margin-left: calc(var(--lemon-button-padding-horizontal) / 2); border-left: 1px solid currentColor; } } +// SideAction buttons are buttons next to other buttons in the DOM but layered on top. since they're on another button, we don't want them to look like buttons. .LemonButtonWithSideAction__side-button { position: absolute; - top: 50%; - right: 0.5rem; + top: 1px; + right: 1px; + bottom: calc(var(--lemon-button-chrome-depth) + 1px); + z-index: 1; // Places button content above the main button background: none; - transform: translateY(-50%); + border-top-right-radius: calc(var(--radius) - 1px); + border-bottom-right-radius: calc(var(--radius) - 1px); + transform: none; + + .LemonButton { + --lemon-button-depth: 0px; + --lemon-button-icon-opacity: 0.5; + + width: var(--lemon-button-side-action-width); + height: 100%; + border-top-left-radius: 0; + border-bottom-left-radius: 0; + } + + .LemonButton__chrome { + justify-content: center !important; + padding: 0 !important; + border: none !important; + + &::before, + &::after { + content: none !important; + } + } + + &:not([aria-disabled='true']):active { + .LemonButton__chrome { + transform: none !important; + } + } + + .LemonButton__icon { + color: currentColor; + } - .LemonButton--small & { - right: 0.375rem; + &:not([aria-disabled='true']):hover { + background: rgb(0 0 0 / 10%); } } diff --git a/frontend/src/lib/lemon-ui/LemonButton/LemonButton.tsx b/frontend/src/lib/lemon-ui/LemonButton/LemonButton.tsx index 44f02e8c72ff6..5b2dc935c3dee 100644 --- a/frontend/src/lib/lemon-ui/LemonButton/LemonButton.tsx +++ b/frontend/src/lib/lemon-ui/LemonButton/LemonButton.tsx @@ -1,5 +1,4 @@ import './LemonButton.scss' -import './LemonButton3000.scss' import { IconChevronDown } from '@posthog/icons' import clsx from 'clsx' diff --git a/frontend/src/lib/lemon-ui/LemonButton/LemonButton3000.scss b/frontend/src/lib/lemon-ui/LemonButton/LemonButton3000.scss deleted file mode 100644 index e1a6b1b7551e8..0000000000000 --- a/frontend/src/lib/lemon-ui/LemonButton/LemonButton3000.scss +++ /dev/null @@ -1,333 +0,0 @@ -@mixin secondary-variables { - --button-border-color: var(--secondary-3000-button-border); - --lemon-button-bg-color-active: var(--bg-light); - --lemon-button-border-color-hover: var(--secondary-3000-button-border-hover); - --lemon-button-frame-bg-color: var(--secondary-3000-frame-bg); -} - -.posthog-3000 { - --lemon-button-chrome-depth: 0.1875rem; - --lemon-button-hover-depth: -0.03125rem; - --lemon-button-press-depth: 0.03125rem; - --lemon-button-padding-horizontal: 0.75rem; - --lemon-button-padding-adjacent-icon: 0.375rem; - --lemon-button-side-action-width: 2rem; - - .LemonButton, - .Link.LemonButton { - --lemon-button-transition: opacity 200ms ease, transform 200ms ease; - --lemon-button-border-width: 0; - --lemon-button-bg-color: transparent; - --button-border-color: none; - --lemon-button-border-color-hover: none; - --lemon-button-frame-bg-color: none; - --lemon-button-font-size: 0.875rem; - --lemon-button-height: 2.3125rem; - --lemon-button-gap: 0.5rem; - --lemon-button-icon-opacity: 0.5; - --lemon-button-profile-picture-opacity: 0.75; // Profile pictures must be more prominent than icons - --lemon-button-color: var(--default); - - position: relative; - padding: 0; - font-family: var(--font-title); - cursor: pointer; - outline: none; - transition: var(--lemon-button-transition); - - .LemonButton__chrome { - position: relative; - display: flex; - flex-direction: row; - flex-shrink: 0; - gap: var(--lemon-button-gap); - align-items: center; - justify-content: flex-start; - width: 100%; - height: 100%; - min-height: var(--lemon-button-height); - padding: 0.25rem var(--lemon-button-padding-horizontal); - font-size: var(--lemon-button-font-size); - font-weight: 500; - line-height: 1.5rem; - color: var(--lemon-button-color); - text-align: left; - background: none; - border-color: transparent; - border-style: solid; - border-width: var(--lemon-button-border-width); - - .LemonButton__content { - overflow: hidden; - } - - .LemonButton__icon { - > * { - opacity: var(--lemon-button-icon-opacity); - } - - > .ProfilePicture, - > .Lettermark { - opacity: var(--lemon-button-profile-picture-opacity); - } - } - } - - &.LemonButton--active, - &:hover:not([aria-disabled='true']), - &:not([aria-disabled='true']):active { - --lemon-button-icon-opacity: 0.75; - --lemon-button-profile-picture-opacity: 1; - } - - &.LemonButton--full-width { - --lemon-button-padding-horizontal: 0.5rem; - } - - &.LemonButton--xsmall { - --lemon-button-padding-horizontal: 0.375rem; - --lemon-button-padding-adjacent-icon: 0.25rem; - --lemon-button-font-size: 0.75rem; - --lemon-button-height: 1.625rem; - --lemon-button-gap: 0.25rem; - --lemon-button-side-action-width: 1.5rem; - } - - &.LemonButton--small { - --lemon-button-padding-horizontal: 0.5rem; - --lemon-button-height: 2.0625rem; - --lemon-button-gap: 0.25rem; - --lemon-button-side-action-width: 1.75rem; - } - - &.LemonButton--large { - --lemon-button-font-size: 1rem; - --lemon-button-padding-adjacent-icon: 0.75rem; - --lemon-button-height: 3.0625rem; - --lemon-button-gap: 0.75rem; - } - - &.LemonButton--no-padding { - min-height: 0; - padding: 0; - - .LemonButton__chrome { - min-height: 0; - padding: 0; - } - } - - &.LemonButton--primary { - --lemon-button-bg-color: var(--primary-3000-button-bg); - --lemon-button-bg-color-active: var(--primary-3000-button-bg); - --button-border-color: var(--primary-3000-button-border); - --lemon-button-border-color-hover: var(--primary-3000-button-border-hover); - --lemon-button-frame-bg-color: var(--primary-3000-frame-bg); - --lemon-button-color: var(--text-3000-light); - - &.LemonButton--status-alt { - --lemon-button-bg-color: var(--primary-3000-frame-bg-light); - --lemon-button-bg-color-active: var(--lemon-button-bg-color); - --button-border-color: var(--primary-3000-button-border); - --lemon-button-border-color-hover: var(--primary-3000-button-border-hover); - --lemon-button-frame-bg-color: var(--primary-3000-button-bg-dark); - --lemon-button-color: var(--text-3000-light); - } - } - - &.LemonButton--secondary.LemonButton--status-alt:hover, - &.LemonButton--secondary.LemonButton--status-alt.LemonButton--active, - &.LemonButton--secondary:not(.LemonButton--status-alt, .LemonButton--status-danger) { - @include secondary-variables; - } - - &.LemonButton--status-danger, - &.LemonButton--primary.LemonButton--status-danger, - &.LemonButton--secondary.LemonButton--status-danger { - --lemon-button-color: var(--danger-3000-button-border-hover); - --button-border-color: var(--danger-3000-button-border); - --lemon-button-border-color-hover: var(--danger-3000-button-border-hover); - --lemon-button-frame-bg-color: var(--danger-3000-frame-bg); - --lemon-button-icon-opacity: 1; - } - - &.LemonButton--secondary.LemonButton--status-alt { - --lemon-button-color: var(--muted); - - &.LemonButton--active, - &:hover:not([aria-disabled='true']) { - --lemon-button-color: var(--default); - } - } - - &.LemonButton--primary, - &.LemonButton--secondary { - --lemon-button-border-width: 1px; - - &:not([aria-disabled='true']):hover .LemonButton__chrome { - &::after { - border-color: var(--lemon-button-border-color-hover); - } - } - - &.LemonButton--has-icon:not(.LemonButton--no-content, .LemonButton--no-padding) { - --lemon-button-padding-left: var(--lemon-button-padding-adjacent-icon); - } - - &.LemonButton--has-side-icon:not(.LemonButton--no-content, .LemonButton--no-padding) { - --lemon-button-padding-right: var(--lemon-button-padding-adjacent-icon); - } - - .LemonButton__chrome { - padding: calc(0.25rem - var(--lemon-button-chrome-depth) * 0.5) - var(--lemon-button-padding-right, var(--lemon-button-padding-horizontal)) - calc(0.25rem + var(--lemon-button-chrome-depth) * 0.5) - var(--lemon-button-padding-left, var(--lemon-button-padding-horizontal)); - background: transparent; - - & > * { - z-index: 1; // Places button content above the ::after element - } - - &::before { - position: absolute; - inset: -1px; - z-index: 0; - content: ''; - border: 1px solid var(--button-border-color); - border-radius: var(--radius); - } - - &::after { - position: absolute; - inset: -1px -1px calc(var(--lemon-button-chrome-depth) - 1px) -1px; - z-index: 0; - content: ''; - background: var(--lemon-button-bg-color); - border: 1px solid var(--button-border-color); - border-radius: var(--radius); - box-shadow: 0 var(--lemon-button-chrome-depth) 0 -1px var(--lemon-button-frame-bg-color); - transition: opacity 200ms ease; - } - } - - &.LemonButton--active, - &:not([aria-disabled='true']):active { - .LemonButton__chrome { - &::after { - border: 1px solid var(--lemon-button-border-color-hover); - } - } - } - - &:hover:not([aria-disabled='true']) { - --lemon-button-depth: var(--lemon-button-hover-depth); - } - - &:not([aria-disabled='true']):active { - --lemon-button-depth: var(--lemon-button-press-depth); - } - - &:hover:not([aria-disabled='true']), - &:not([aria-disabled='true']):active { - .LemonButton__chrome { - transform: translateY(var(--lemon-button-depth)); - - &::after { - box-shadow: 0 calc(var(--lemon-button-chrome-depth) - var(--lemon-button-depth)) 0 -1px var(--lemon-button-frame-bg-color); - } - - &::before { - bottom: calc(var(--lemon-button-depth) - 1px); - } - } - } - - &.LemonButton--active { - .LemonButton__chrome { - &::after { - background: var(--lemon-button-bg-color-active); - } - } - } - } - - &.LemonButton--tertiary { - &:not([aria-disabled='true']):hover, - &.LemonButton--active { - background-color: var(--glass-border-3000); - } - - &.LemonButton--status-danger { - &:not([aria-disabled='true']):hover, - &.LemonButton--active { - background-color: var(--danger-highlight); - } - } - } - } - - .LemonButtonWithSideAction:hover > .LemonButton--secondary.LemonButton--status-alt { - @include secondary-variables; - } - - .LemonButtonWithSideAction__spacer { - width: calc( - var(--lemon-button-side-action-width) - - var(--lemon-button-padding-right, var(--lemon-button-padding-horizontal)) - ); - height: 1.25rem; - color: var(--muted); - - &--divider { - padding: 0; - margin-left: calc(var(--lemon-button-padding-horizontal) / 2); - } - } - - // SideAction buttons are buttons next to other buttons in the DOM but layered on top. since they're on another button, we don't want them to look like buttons. - .LemonButtonWithSideAction__side-button { - top: 1px; - right: 1px; - bottom: calc(var(--lemon-button-chrome-depth) + 1px); - z-index: 1; // Places button content above the main button - border-top-right-radius: calc(var(--radius) - 1px); - border-bottom-right-radius: calc(var(--radius) - 1px); - transform: none; - - .LemonButton { - --lemon-button-depth: 0px; - --lemon-button-icon-opacity: 0.5; - - width: var(--lemon-button-side-action-width); - height: 100%; - border-top-left-radius: 0; - border-bottom-left-radius: 0; - } - - .LemonButton__chrome { - justify-content: center !important; - padding: 0 !important; - border: none !important; - - &::before, - &::after { - content: none !important; - } - } - - &:not([aria-disabled='true']):active { - .LemonButton__chrome { - transform: none !important; - } - } - - .LemonButton__icon { - color: currentColor; - } - - &:not([aria-disabled='true']):hover { - background: rgb(0 0 0 / 10%); - } - } -}