Improve Select style

Signed-off-by: Charles de Dreuille <charles.dedreuille@gmail.com>
This commit is contained in:
Charles de Dreuille
2026-03-03 17:57:26 +00:00
parent 95fecdf617
commit bb66b8617b
5 changed files with 75 additions and 23 deletions
+7
View File
@@ -0,0 +1,7 @@
---
'@backstage/ui': patch
---
The `Select` trigger now automatically adapts its background colour based on the parent background context.
**Affected components:** Select
@@ -35,8 +35,26 @@
.bui-SelectTrigger {
box-sizing: border-box;
border-radius: var(--bui-radius-3);
border: 1px solid var(--bui-border-2);
border: none;
outline: none;
background-color: var(--bui-bg-neutral-1);
transition: box-shadow 0.2s ease-in-out;
&[data-on-bg='neutral-1'] {
background-color: var(--bui-bg-neutral-2);
}
&[data-on-bg='neutral-2'] {
background-color: var(--bui-bg-neutral-3);
}
&[data-on-bg='neutral-3'] {
background-color: var(--bui-bg-neutral-4);
}
.bui-Select[data-focused] & {
box-shadow: inset 0 0 0 1px var(--bui-ring);
}
display: flex;
justify-content: space-between;
align-items: center;
@@ -73,12 +91,7 @@
}
.bui-Select[data-invalid] & {
border-color: var(--bui-fg-danger);
&:focus-visible,
&:hover {
outline: 1px solid var(--bui-fg-danger);
}
box-shadow: inset 0 0 0 1px var(--bui-border-danger);
}
&[disabled] {
@@ -119,6 +132,8 @@
.bui-SelectList {
overflow: auto;
min-height: 0;
padding-block: var(--bui-space-1);
padding-inline: var(--bui-space-1);
&:focus-visible {
/* Remove default focus-visible outline because React Aria
@@ -132,7 +147,6 @@
.bui-SelectItem {
box-sizing: border-box;
position: relative;
width: var(--anchor-width);
display: grid;
grid-template-areas: 'icon text';
grid-template-columns: 1rem 1fr;
@@ -147,20 +161,10 @@
font-size: var(--bui-font-size-3);
gap: var(--bui-space-2);
outline: none;
border-radius: var(--bui-radius-2);
&[data-focus-visible] {
outline: 2px solid var(--bui-ring);
outline-offset: 2px;
}
&[data-focused]::before {
content: '';
position: absolute;
inset-block: 0;
inset-inline: var(--bui-space-1);
border-radius: var(--bui-radius-2);
background: var(--bui-bg-neutral-2);
z-index: -1;
&[data-focused] {
background-color: var(--bui-bg-neutral-2);
}
&[data-disabled] {
@@ -17,6 +17,8 @@
import preview from '../../../../../.storybook/preview';
import { Select } from './Select';
import { Flex } from '../Flex';
import { Box } from '../Box';
import { Text } from '../Text';
import { Form } from 'react-aria-components';
import { RiCloudLine } from '@remixicon/react';
@@ -391,6 +393,41 @@ export const WithLongNamesAndPadding = meta.story({
],
});
export const AutoBg = meta.story({
render: () => (
<Flex direction="column" gap="4">
<div style={{ maxWidth: '600px' }}>
Select automatically detects its parent bg context and increments the
neutral level by 1. No prop is needed it's fully automatic.
</div>
<Box bg="neutral" p="4">
<Text>Neutral 1 container</Text>
<Flex mt="2" style={{ maxWidth: '300px' }}>
<Select options={fontOptions} aria-label="Font family" />
</Flex>
</Box>
<Box bg="neutral">
<Box bg="neutral" p="4">
<Text>Neutral 2 container</Text>
<Flex mt="2" style={{ maxWidth: '300px' }}>
<Select options={fontOptions} aria-label="Font family" />
</Flex>
</Box>
</Box>
<Box bg="neutral">
<Box bg="neutral">
<Box bg="neutral" p="4">
<Text>Neutral 3 container</Text>
<Flex mt="2" style={{ maxWidth: '300px' }}>
<Select options={fontOptions} aria-label="Font family" />
</Flex>
</Box>
</Box>
</Box>
</Flex>
),
});
export const WithAccessibilityProps = meta.story({
args: {
...Default.input.args,
@@ -25,11 +25,14 @@ interface SelectTriggerProps {
}
export function SelectTrigger(props: SelectTriggerProps) {
const { ownProps } = useDefinition(SelectTriggerDefinition, props);
const { ownProps, dataAttributes } = useDefinition(
SelectTriggerDefinition,
props,
);
const { classes, icon } = ownProps;
return (
<Button className={classes.root}>
<Button className={classes.root} {...dataAttributes}>
{icon}
<SelectValue className={classes.value} />
<div className={classes.chevron}>
@@ -59,6 +59,7 @@ export const SelectTriggerDefinition = defineComponent<SelectTriggerOwnProps>()(
chevron: 'bui-SelectTriggerChevron',
value: 'bui-SelectValue',
},
bg: 'consumer',
propDefs: {
icon: {},
},