refactor(ui): simplify Button CSS using custom properties
Replace verbose :not() selectors with CSS custom properties pattern. Variants now define color variables that get neutralized in disabled/loading states, eliminating complex selector chains. - Move common hover/active application to base .bui-Button class - Fix tertiary disabled buttons incorrectly showing hover effects - Unify hover transition to 150ms across all variants Signed-off-by: Johan Persson <johanopersson@gmail.com>
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/ui': patch
|
||||
---
|
||||
|
||||
Fixed disabled tertiary buttons incorrectly showing hover effects on surfaces.
|
||||
@@ -19,6 +19,11 @@
|
||||
@layer components {
|
||||
.bui-Button {
|
||||
--loading-duration: 200ms;
|
||||
--bg: transparent;
|
||||
--bg-hover: transparent;
|
||||
--bg-active: transparent;
|
||||
--fg: inherit;
|
||||
|
||||
position: relative;
|
||||
display: inline-flex;
|
||||
border: none;
|
||||
@@ -31,7 +36,19 @@
|
||||
flex-shrink: 0;
|
||||
transition: background-color var(--loading-duration) ease-out,
|
||||
box-shadow var(--loading-duration) ease-out;
|
||||
background-color: transparent;
|
||||
|
||||
/* Apply variables */
|
||||
color: var(--fg);
|
||||
background-color: var(--bg);
|
||||
|
||||
&:hover {
|
||||
background-color: var(--bg-hover);
|
||||
transition: background-color 150ms ease;
|
||||
}
|
||||
|
||||
&:active {
|
||||
background-color: var(--bg-active);
|
||||
}
|
||||
|
||||
&[data-disabled='true'] {
|
||||
cursor: not-allowed;
|
||||
@@ -43,77 +60,54 @@
|
||||
}
|
||||
|
||||
.bui-Button[data-variant='primary'] {
|
||||
background-color: var(--bui-bg-solid);
|
||||
color: var(--bui-fg-solid);
|
||||
--bg: var(--bui-bg-solid);
|
||||
--bg-hover: var(--bui-bg-solid-hover);
|
||||
--bg-active: var(--bui-bg-solid-pressed);
|
||||
--fg: var(--bui-fg-solid);
|
||||
|
||||
&:hover {
|
||||
background-color: var(--bui-bg-solid-hover);
|
||||
transition: background-color 150ms ease;
|
||||
}
|
||||
|
||||
&:active {
|
||||
background-color: var(--bui-bg-solid-pressed);
|
||||
&[data-disabled='true'],
|
||||
&[data-loading='true'] {
|
||||
--bg: var(--bui-bg-solid-disabled);
|
||||
--bg-hover: var(--bui-bg-solid-disabled);
|
||||
--bg-active: var(--bui-bg-solid-disabled);
|
||||
--fg: var(--bui-fg-solid-disabled);
|
||||
}
|
||||
|
||||
&:focus-visible {
|
||||
outline: 2px solid var(--bui-ring);
|
||||
outline-offset: 2px;
|
||||
}
|
||||
|
||||
&[data-disabled='true'],
|
||||
&[data-loading='true'] {
|
||||
background-color: var(--bui-bg-solid-disabled);
|
||||
color: var(--bui-fg-solid-disabled);
|
||||
}
|
||||
}
|
||||
|
||||
.bui-Button[data-variant='secondary'] {
|
||||
color: var(--bui-fg-primary);
|
||||
background-color: var(--bui-bg-neutral-on-surface-0);
|
||||
|
||||
&:hover:not([data-disabled='true']):not([data-loading='true']) {
|
||||
background-color: var(--bui-bg-neutral-on-surface-0-hover);
|
||||
transition: background-color 150ms ease;
|
||||
}
|
||||
|
||||
&:active:not([data-disabled='true']):not([data-loading='true']) {
|
||||
background-color: var(--bui-bg-neutral-on-surface-0-pressed);
|
||||
}
|
||||
--bg: var(--bui-bg-neutral-on-surface-0);
|
||||
--bg-hover: var(--bui-bg-neutral-on-surface-0-hover);
|
||||
--bg-active: var(--bui-bg-neutral-on-surface-0-pressed);
|
||||
--fg: var(--bui-fg-primary);
|
||||
|
||||
&[data-on-surface='1'] {
|
||||
background-color: var(--bui-bg-neutral-on-surface-1);
|
||||
|
||||
&:hover:not([data-disabled='true']):not([data-loading='true']) {
|
||||
background-color: var(--bui-bg-neutral-on-surface-1-hover);
|
||||
}
|
||||
|
||||
&:active:not([data-disabled='true']):not([data-loading='true']) {
|
||||
background-color: var(--bui-bg-neutral-on-surface-1-pressed);
|
||||
}
|
||||
--bg: var(--bui-bg-neutral-on-surface-1);
|
||||
--bg-hover: var(--bui-bg-neutral-on-surface-1-hover);
|
||||
--bg-active: var(--bui-bg-neutral-on-surface-1-pressed);
|
||||
}
|
||||
|
||||
&[data-on-surface='2'] {
|
||||
background-color: var(--bui-bg-neutral-on-surface-2);
|
||||
|
||||
&:hover:not([data-disabled='true']):not([data-loading='true']) {
|
||||
background-color: var(--bui-bg-neutral-on-surface-2-hover);
|
||||
}
|
||||
|
||||
&:active:not([data-disabled='true']):not([data-loading='true']) {
|
||||
background-color: var(--bui-bg-neutral-on-surface-2-pressed);
|
||||
}
|
||||
--bg: var(--bui-bg-neutral-on-surface-2);
|
||||
--bg-hover: var(--bui-bg-neutral-on-surface-2-hover);
|
||||
--bg-active: var(--bui-bg-neutral-on-surface-2-pressed);
|
||||
}
|
||||
|
||||
&[data-on-surface='3'] {
|
||||
background-color: var(--bui-bg-neutral-on-surface-3);
|
||||
--bg: var(--bui-bg-neutral-on-surface-3);
|
||||
--bg-hover: var(--bui-bg-neutral-on-surface-3-hover);
|
||||
--bg-active: var(--bui-bg-neutral-on-surface-3-pressed);
|
||||
}
|
||||
|
||||
&:hover:not([data-disabled='true']):not([data-loading='true']) {
|
||||
background-color: var(--bui-bg-neutral-on-surface-3-hover);
|
||||
}
|
||||
|
||||
&:active:not([data-disabled='true']):not([data-loading='true']) {
|
||||
background-color: var(--bui-bg-neutral-on-surface-3-pressed);
|
||||
}
|
||||
&[data-disabled='true'],
|
||||
&[data-loading='true'] {
|
||||
--bg-hover: var(--bg);
|
||||
--bg-active: var(--bg);
|
||||
--fg: var(--bui-fg-disabled);
|
||||
}
|
||||
|
||||
&:focus-visible {
|
||||
@@ -121,54 +115,33 @@
|
||||
transition: none;
|
||||
box-shadow: inset 0 0 0 2px var(--bui-ring);
|
||||
}
|
||||
|
||||
&[data-disabled='true'],
|
||||
&[data-loading='true'] {
|
||||
color: var(--bui-fg-disabled);
|
||||
}
|
||||
}
|
||||
|
||||
.bui-Button[data-variant='tertiary'] {
|
||||
background-color: transparent;
|
||||
color: var(--bui-fg-primary);
|
||||
|
||||
&:hover {
|
||||
background-color: var(--bui-bg-neutral-on-surface-0-hover);
|
||||
transition: background-color 200ms ease;
|
||||
}
|
||||
|
||||
&:active {
|
||||
background-color: var(--bui-bg-neutral-on-surface-0-pressed);
|
||||
}
|
||||
--bg-hover: var(--bui-bg-neutral-on-surface-0-hover);
|
||||
--bg-active: var(--bui-bg-neutral-on-surface-0-pressed);
|
||||
--fg: var(--bui-fg-primary);
|
||||
|
||||
&[data-on-surface='1'] {
|
||||
&:hover {
|
||||
background-color: var(--bui-bg-neutral-on-surface-1-hover);
|
||||
}
|
||||
|
||||
&:active {
|
||||
background-color: var(--bui-bg-neutral-on-surface-1-pressed);
|
||||
}
|
||||
--bg-hover: var(--bui-bg-neutral-on-surface-1-hover);
|
||||
--bg-active: var(--bui-bg-neutral-on-surface-1-pressed);
|
||||
}
|
||||
|
||||
&[data-on-surface='2'] {
|
||||
&:hover {
|
||||
background-color: var(--bui-bg-neutral-on-surface-2-hover);
|
||||
}
|
||||
|
||||
&:active {
|
||||
background-color: var(--bui-bg-neutral-on-surface-2-pressed);
|
||||
}
|
||||
--bg-hover: var(--bui-bg-neutral-on-surface-2-hover);
|
||||
--bg-active: var(--bui-bg-neutral-on-surface-2-pressed);
|
||||
}
|
||||
|
||||
&[data-on-surface='3'] {
|
||||
&:hover {
|
||||
background-color: var(--bui-bg-neutral-on-surface-3-hover);
|
||||
}
|
||||
--bg-hover: var(--bui-bg-neutral-on-surface-3-hover);
|
||||
--bg-active: var(--bui-bg-neutral-on-surface-3-pressed);
|
||||
}
|
||||
|
||||
&:active {
|
||||
background-color: var(--bui-bg-neutral-on-surface-3-pressed);
|
||||
}
|
||||
&[data-disabled='true'],
|
||||
&[data-loading='true'] {
|
||||
--bg-hover: var(--bg);
|
||||
--bg-active: var(--bg);
|
||||
--fg: var(--bui-fg-disabled);
|
||||
}
|
||||
|
||||
&:focus-visible {
|
||||
@@ -176,12 +149,6 @@
|
||||
transition: none;
|
||||
box-shadow: inset 0 0 0 2px var(--bui-ring);
|
||||
}
|
||||
|
||||
&[data-disabled='true'],
|
||||
&[data-loading='true'] {
|
||||
background-color: transparent;
|
||||
color: var(--bui-fg-disabled);
|
||||
}
|
||||
}
|
||||
|
||||
.bui-Button[data-size='small'] {
|
||||
|
||||
Reference in New Issue
Block a user