Merge pull request #33002 from backstage/cdedreuille/ui-neutral-bg-simplification
feat(ui): neutral bg system overhaul — single incremental value + overlay reset
This commit is contained in:
@@ -0,0 +1,21 @@
|
||||
---
|
||||
'@backstage/ui': minor
|
||||
---
|
||||
|
||||
**BREAKING**: Simplified the neutral background prop API for container components. The explicit `neutral-1`, `neutral-2`, `neutral-3`, and `neutral-auto` values have been removed from `ProviderBg`. They are replaced by a single `'neutral'` value that always auto-increments from the parent context, making it impossible to skip or pin to an explicit neutral level.
|
||||
|
||||
**Migration:**
|
||||
|
||||
Replace any explicit `bg="neutral-1"`, `bg="neutral-2"`, `bg="neutral-3"`, or `bg="neutral-auto"` props with `bg="neutral"`. To achieve a specific neutral level in stories or tests, use nested containers — each additional `bg="neutral"` wrapper increments by one level.
|
||||
|
||||
```tsx
|
||||
// Before
|
||||
<Box bg="neutral-2">...</Box>
|
||||
|
||||
// After
|
||||
<Box bg="neutral">
|
||||
<Box bg="neutral">...</Box>
|
||||
</Box>
|
||||
```
|
||||
|
||||
**Affected components:** Box, Flex, Grid, Card, Accordion, Popover, Tooltip, Dialog, Menu
|
||||
@@ -176,7 +176,7 @@ export default definePreview({
|
||||
: parseInt(selectedBackground.split('-')[1], 10),
|
||||
}).reduce<React.ReactNode>(
|
||||
children => (
|
||||
<Box bg="neutral-auto" p="4">
|
||||
<Box bg="neutral" p="4">
|
||||
{children}
|
||||
</Box>
|
||||
),
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
export const surfacesSnippet = `<Flex direction="column" gap="4">
|
||||
<Box bg="neutral-1">
|
||||
<Box bg="neutral">
|
||||
<Button variant="secondary">Hello World</Button>
|
||||
</Box>
|
||||
<Box bg="neutral-1">
|
||||
<Box bg="neutral">
|
||||
<Button variant="secondary">Hello World</Button>
|
||||
</Box>
|
||||
</Flex>`;
|
||||
|
||||
export const adaptiveSnippet = `<Box bg="neutral-1">
|
||||
export const adaptiveSnippet = `<Box bg="neutral">
|
||||
<Card> {/* automatically set background to neutral-2 */}
|
||||
<Button variant="secondary">Button with background set to neutral-3</Button>
|
||||
</Card>
|
||||
</Box>`;
|
||||
|
||||
export const customCardSnippet = `<Box bg="autoIncrement">
|
||||
export const customCardSnippet = `<Box bg="neutral">
|
||||
<Text>Hello World</Text>
|
||||
</Box>`;
|
||||
|
||||
|
||||
@@ -76,7 +76,7 @@ export const AccordionDefinition: {
|
||||
readonly propDefs: {
|
||||
readonly bg: {
|
||||
readonly dataAttribute: true;
|
||||
readonly default: 'neutral-auto';
|
||||
readonly default: 'neutral';
|
||||
};
|
||||
readonly children: {};
|
||||
readonly className: {};
|
||||
@@ -1012,14 +1012,7 @@ export const FlexDefinition: {
|
||||
'direction',
|
||||
];
|
||||
readonly dataAttributes: {
|
||||
readonly bg: readonly [
|
||||
'neutral-1',
|
||||
'neutral-2',
|
||||
'neutral-3',
|
||||
'danger',
|
||||
'warning',
|
||||
'success',
|
||||
];
|
||||
readonly bg: readonly ['neutral', 'danger', 'warning', 'success'];
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1096,14 +1089,7 @@ export const GridDefinition: {
|
||||
'py',
|
||||
];
|
||||
readonly dataAttributes: {
|
||||
readonly bg: readonly [
|
||||
'neutral-1',
|
||||
'neutral-2',
|
||||
'neutral-3',
|
||||
'danger',
|
||||
'warning',
|
||||
'success',
|
||||
];
|
||||
readonly bg: readonly ['neutral', 'danger', 'warning', 'success'];
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1114,14 +1100,7 @@ export const GridItemDefinition: {
|
||||
};
|
||||
readonly utilityProps: ['colSpan', 'colEnd', 'colStart', 'rowSpan'];
|
||||
readonly dataAttributes: {
|
||||
readonly bg: readonly [
|
||||
'neutral-1',
|
||||
'neutral-2',
|
||||
'neutral-3',
|
||||
'danger',
|
||||
'warning',
|
||||
'success',
|
||||
];
|
||||
readonly bg: readonly ['neutral', 'danger', 'warning', 'success'];
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1604,7 +1583,7 @@ export interface PopoverProps extends Omit<PopoverProps_2, 'children'> {
|
||||
}
|
||||
|
||||
// @public
|
||||
export type ProviderBg = ContainerBg | 'neutral-auto';
|
||||
export type ProviderBg = 'neutral' | 'danger' | 'warning' | 'success';
|
||||
|
||||
// @public (undocumented)
|
||||
export interface QueryOptions<TFilter> {
|
||||
|
||||
@@ -195,7 +195,7 @@ export const AutoBg = meta.story({
|
||||
</AccordionPanel>
|
||||
</Accordion>
|
||||
</Flex>
|
||||
<Box bg="neutral-1" p="4">
|
||||
<Box bg="neutral" p="4">
|
||||
<Text>Neutral 1 container</Text>
|
||||
<Flex mt="2">
|
||||
<Accordion defaultExpanded>
|
||||
@@ -210,35 +210,41 @@ export const AutoBg = meta.story({
|
||||
</Accordion>
|
||||
</Flex>
|
||||
</Box>
|
||||
<Box bg="neutral-2" p="4">
|
||||
<Text>Neutral 2 container</Text>
|
||||
<Flex mt="2">
|
||||
<Accordion defaultExpanded>
|
||||
<AccordionTrigger title="Auto (neutral-3)" />
|
||||
<AccordionPanel>
|
||||
<Content />
|
||||
<Flex mt="3" gap="2">
|
||||
<Button>Action</Button>
|
||||
<Button variant="secondary">Cancel</Button>
|
||||
</Flex>
|
||||
</AccordionPanel>
|
||||
</Accordion>
|
||||
</Flex>
|
||||
<Box bg="neutral">
|
||||
<Box bg="neutral" p="4">
|
||||
<Text>Neutral 2 container</Text>
|
||||
<Flex mt="2">
|
||||
<Accordion defaultExpanded>
|
||||
<AccordionTrigger title="Auto (neutral-3)" />
|
||||
<AccordionPanel>
|
||||
<Content />
|
||||
<Flex mt="3" gap="2">
|
||||
<Button>Action</Button>
|
||||
<Button variant="secondary">Cancel</Button>
|
||||
</Flex>
|
||||
</AccordionPanel>
|
||||
</Accordion>
|
||||
</Flex>
|
||||
</Box>
|
||||
</Box>
|
||||
<Box bg="neutral-3" p="4">
|
||||
<Text>Neutral 3 container</Text>
|
||||
<Flex mt="2">
|
||||
<Accordion defaultExpanded>
|
||||
<AccordionTrigger title="Auto (neutral-3)" />
|
||||
<AccordionPanel>
|
||||
<Content />
|
||||
<Flex mt="3" gap="2">
|
||||
<Button>Action</Button>
|
||||
<Button variant="secondary">Cancel</Button>
|
||||
</Flex>
|
||||
</AccordionPanel>
|
||||
</Accordion>
|
||||
</Flex>
|
||||
<Box bg="neutral">
|
||||
<Box bg="neutral">
|
||||
<Box bg="neutral" p="4">
|
||||
<Text>Neutral 3 container</Text>
|
||||
<Flex mt="2">
|
||||
<Accordion defaultExpanded>
|
||||
<AccordionTrigger title="Auto (neutral-3)" />
|
||||
<AccordionPanel>
|
||||
<Content />
|
||||
<Flex mt="3" gap="2">
|
||||
<Button>Action</Button>
|
||||
<Button variant="secondary">Cancel</Button>
|
||||
</Flex>
|
||||
</AccordionPanel>
|
||||
</Accordion>
|
||||
</Flex>
|
||||
</Box>
|
||||
</Box>
|
||||
</Box>
|
||||
</Flex>
|
||||
),
|
||||
|
||||
@@ -34,7 +34,7 @@ export const AccordionDefinition = defineComponent<AccordionOwnProps>()({
|
||||
},
|
||||
bg: 'provider',
|
||||
propDefs: {
|
||||
bg: { dataAttribute: true, default: 'neutral-auto' },
|
||||
bg: { dataAttribute: true, default: 'neutral' },
|
||||
children: {},
|
||||
className: {},
|
||||
},
|
||||
|
||||
@@ -297,7 +297,7 @@ export const OnDifferentBackgrounds = meta.story({
|
||||
|
||||
<Flex direction="column" gap="4">
|
||||
<Text>On Neutral 1</Text>
|
||||
<Flex direction="column" gap="2" bg="neutral-1" p="4">
|
||||
<Flex direction="column" gap="2" bg="neutral" p="4">
|
||||
<Alert status="info" icon={true} title="Alert on neutral-1" />
|
||||
<Alert status="success" icon={true} title="Alert on neutral-1" />
|
||||
</Flex>
|
||||
@@ -305,18 +305,24 @@ export const OnDifferentBackgrounds = meta.story({
|
||||
|
||||
<Flex direction="column" gap="4">
|
||||
<Text>On Neutral 2</Text>
|
||||
<Flex direction="column" gap="2" bg="neutral-2" p="4">
|
||||
<Alert status="info" icon={true} title="Alert on neutral-2" />
|
||||
<Alert status="success" icon={true} title="Alert on neutral-2" />
|
||||
</Flex>
|
||||
<Box bg="neutral">
|
||||
<Flex direction="column" gap="2" bg="neutral" p="4">
|
||||
<Alert status="info" icon={true} title="Alert on neutral-2" />
|
||||
<Alert status="success" icon={true} title="Alert on neutral-2" />
|
||||
</Flex>
|
||||
</Box>
|
||||
</Flex>
|
||||
|
||||
<Flex direction="column" gap="4">
|
||||
<Text>On Neutral 3</Text>
|
||||
<Flex direction="column" gap="2" bg="neutral-3" p="4">
|
||||
<Alert status="info" icon={true} title="Alert on neutral-3" />
|
||||
<Alert status="success" icon={true} title="Alert on neutral-3" />
|
||||
</Flex>
|
||||
<Box bg="neutral">
|
||||
<Box bg="neutral">
|
||||
<Flex direction="column" gap="2" bg="neutral" p="4">
|
||||
<Alert status="info" icon={true} title="Alert on neutral-3" />
|
||||
<Alert status="success" icon={true} title="Alert on neutral-3" />
|
||||
</Flex>
|
||||
</Box>
|
||||
</Box>
|
||||
</Flex>
|
||||
</Flex>
|
||||
),
|
||||
@@ -337,7 +343,7 @@ export const Responsive = meta.story({
|
||||
|
||||
export const WithUtilityProps = meta.story({
|
||||
render: () => (
|
||||
<Box bg="neutral-1" py="4">
|
||||
<Box bg="neutral" py="4">
|
||||
<Alert
|
||||
status="success"
|
||||
icon={true}
|
||||
|
||||
@@ -353,17 +353,20 @@ export const BackgroundColors = meta.story({
|
||||
render: args => (
|
||||
<Flex align="center" style={{ flexWrap: 'wrap' }}>
|
||||
<Box {...args}>Default</Box>
|
||||
<Box bg="neutral-1" {...args}>
|
||||
Neutral 1
|
||||
<Box bg="neutral" {...args}>
|
||||
Neutral (level 1)
|
||||
</Box>
|
||||
<Box bg="neutral-2" {...args}>
|
||||
Neutral 2
|
||||
<Box bg="neutral">
|
||||
<Box bg="neutral" {...args}>
|
||||
Neutral (level 2)
|
||||
</Box>
|
||||
</Box>
|
||||
<Box bg="neutral-3" {...args}>
|
||||
Neutral 3
|
||||
</Box>
|
||||
<Box bg={{ initial: 'neutral-1', sm: 'neutral-2' }} {...args}>
|
||||
Responsive Neutral
|
||||
<Box bg="neutral">
|
||||
<Box bg="neutral">
|
||||
<Box bg="neutral" {...args}>
|
||||
Neutral (level 3)
|
||||
</Box>
|
||||
</Box>
|
||||
</Box>
|
||||
<Box bg="danger" {...args}>
|
||||
Danger
|
||||
@@ -381,11 +384,11 @@ export const BackgroundColors = meta.story({
|
||||
export const NestedNeutralColors = meta.story({
|
||||
args: { px: '6', py: '4', children: null },
|
||||
render: args => (
|
||||
<Box {...args} bg="neutral-1">
|
||||
<Box {...args} bg="neutral">
|
||||
<Button variant="secondary">Button (on neutral-1)</Button>
|
||||
<Box {...args} bg="neutral-2" mt="4">
|
||||
<Box {...args} bg="neutral" mt="4">
|
||||
<Button variant="secondary">Button (on neutral-2)</Button>
|
||||
<Box {...args} bg="neutral-3" mt="4">
|
||||
<Box {...args} bg="neutral" mt="4">
|
||||
<Button variant="secondary">Button (on neutral-3)</Button>
|
||||
</Box>
|
||||
</Box>
|
||||
|
||||
@@ -357,26 +357,32 @@ export const AutoBg = meta.story({
|
||||
neutral level by 1. No prop is needed on the button -- it's fully
|
||||
automatic.
|
||||
</div>
|
||||
<Box bg="neutral-1" p="4">
|
||||
<Box bg="neutral" p="4">
|
||||
<Text>Neutral 1 container</Text>
|
||||
<Flex gap="2" mt="2">
|
||||
<Button variant="secondary">Auto (neutral-2)</Button>
|
||||
<Button variant="tertiary">Auto (neutral-2)</Button>
|
||||
</Flex>
|
||||
</Box>
|
||||
<Box bg="neutral-2" p="4">
|
||||
<Text>Neutral 2 container</Text>
|
||||
<Flex gap="2" mt="2">
|
||||
<Button variant="secondary">Auto (neutral-3)</Button>
|
||||
<Button variant="tertiary">Auto (neutral-3)</Button>
|
||||
</Flex>
|
||||
<Box bg="neutral">
|
||||
<Box bg="neutral" p="4">
|
||||
<Text>Neutral 2 container</Text>
|
||||
<Flex gap="2" mt="2">
|
||||
<Button variant="secondary">Auto (neutral-3)</Button>
|
||||
<Button variant="tertiary">Auto (neutral-3)</Button>
|
||||
</Flex>
|
||||
</Box>
|
||||
</Box>
|
||||
<Box bg="neutral-3" p="4">
|
||||
<Text>Neutral 3 container</Text>
|
||||
<Flex gap="2" mt="2">
|
||||
<Button variant="secondary">Auto (neutral-4)</Button>
|
||||
<Button variant="tertiary">Auto (neutral-4)</Button>
|
||||
</Flex>
|
||||
<Box bg="neutral">
|
||||
<Box bg="neutral">
|
||||
<Box bg="neutral" p="4">
|
||||
<Text>Neutral 3 container</Text>
|
||||
<Flex gap="2" mt="2">
|
||||
<Button variant="secondary">Auto (neutral-4)</Button>
|
||||
<Button variant="tertiary">Auto (neutral-4)</Button>
|
||||
</Flex>
|
||||
</Box>
|
||||
</Box>
|
||||
</Box>
|
||||
</Flex>
|
||||
),
|
||||
|
||||
@@ -135,23 +135,29 @@ export const Backgrounds = meta.story({
|
||||
<CardHeader>No parent</CardHeader>
|
||||
<CardBody>Defaults to neutral-1</CardBody>
|
||||
</Card>
|
||||
<Box bg="neutral-1" p="4" style={{ borderRadius: '8px' }}>
|
||||
<Box bg="neutral" p="4" style={{ borderRadius: '8px' }}>
|
||||
<Card {...args} style={{ width: '200px' }}>
|
||||
<CardHeader>On neutral-1</CardHeader>
|
||||
<CardBody>Auto-increments to neutral-2</CardBody>
|
||||
</Card>
|
||||
</Box>
|
||||
<Box bg="neutral-2" p="4" style={{ borderRadius: '8px' }}>
|
||||
<Card {...args} style={{ width: '200px' }}>
|
||||
<CardHeader>On neutral-2</CardHeader>
|
||||
<CardBody>Auto-increments to neutral-3</CardBody>
|
||||
</Card>
|
||||
<Box bg="neutral">
|
||||
<Box bg="neutral" p="4" style={{ borderRadius: '8px' }}>
|
||||
<Card {...args} style={{ width: '200px' }}>
|
||||
<CardHeader>On neutral-2</CardHeader>
|
||||
<CardBody>Auto-increments to neutral-3</CardBody>
|
||||
</Card>
|
||||
</Box>
|
||||
</Box>
|
||||
<Box bg="neutral-3" p="4" style={{ borderRadius: '8px' }}>
|
||||
<Card {...args} style={{ width: '200px' }}>
|
||||
<CardHeader>On neutral-3</CardHeader>
|
||||
<CardBody>Steps up to neutral-4</CardBody>
|
||||
</Card>
|
||||
<Box bg="neutral">
|
||||
<Box bg="neutral">
|
||||
<Box bg="neutral" p="4" style={{ borderRadius: '8px' }}>
|
||||
<Card {...args} style={{ width: '200px' }}>
|
||||
<CardHeader>On neutral-3</CardHeader>
|
||||
<CardBody>Steps up to neutral-4</CardBody>
|
||||
</Card>
|
||||
</Box>
|
||||
</Box>
|
||||
</Box>
|
||||
</Flex>
|
||||
),
|
||||
@@ -197,23 +203,29 @@ export const BgOnProviders = meta.story({
|
||||
<CardHeader>No provider</CardHeader>
|
||||
<CardBody>Card defaults to neutral-1</CardBody>
|
||||
</Card>
|
||||
<Box bg="neutral-1" p="4" style={{ borderRadius: '8px' }}>
|
||||
<Box bg="neutral" p="4" style={{ borderRadius: '8px' }}>
|
||||
<Card {...args} style={{ width: '200px' }}>
|
||||
<CardHeader>On neutral-1</CardHeader>
|
||||
<CardBody>Card auto-increments to neutral-2</CardBody>
|
||||
</Card>
|
||||
</Box>
|
||||
<Box bg="neutral-2" p="4" style={{ borderRadius: '8px' }}>
|
||||
<Card {...args} style={{ width: '200px' }}>
|
||||
<CardHeader>On neutral-2</CardHeader>
|
||||
<CardBody>Card auto-increments to neutral-3</CardBody>
|
||||
</Card>
|
||||
<Box bg="neutral">
|
||||
<Box bg="neutral" p="4" style={{ borderRadius: '8px' }}>
|
||||
<Card {...args} style={{ width: '200px' }}>
|
||||
<CardHeader>On neutral-2</CardHeader>
|
||||
<CardBody>Card auto-increments to neutral-3</CardBody>
|
||||
</Card>
|
||||
</Box>
|
||||
</Box>
|
||||
<Box bg="neutral-3" p="4" style={{ borderRadius: '8px' }}>
|
||||
<Card {...args} style={{ width: '200px' }}>
|
||||
<CardHeader>On neutral-3</CardHeader>
|
||||
<CardBody>Card visually at neutral-4</CardBody>
|
||||
</Card>
|
||||
<Box bg="neutral">
|
||||
<Box bg="neutral">
|
||||
<Box bg="neutral" p="4" style={{ borderRadius: '8px' }}>
|
||||
<Card {...args} style={{ width: '200px' }}>
|
||||
<CardHeader>On neutral-3</CardHeader>
|
||||
<CardBody>Card visually at neutral-4</CardBody>
|
||||
</Card>
|
||||
</Box>
|
||||
</Box>
|
||||
</Box>
|
||||
</Flex>
|
||||
),
|
||||
@@ -226,11 +238,7 @@ export const CustomCardWithBox = meta.story({
|
||||
A custom card built with Box. Use Box with an explicit bg prop to create
|
||||
a card-like container that participates in the bg system as a provider.
|
||||
</Box>
|
||||
<Box
|
||||
bg="neutral-auto"
|
||||
p="4"
|
||||
style={{ borderRadius: '8px', width: '300px' }}
|
||||
>
|
||||
<Box bg="neutral" p="4" style={{ borderRadius: '8px', width: '300px' }}>
|
||||
<Button variant="secondary" style={{ marginTop: '8px' }}>
|
||||
Button (on neutral-1)
|
||||
</Button>
|
||||
|
||||
@@ -44,7 +44,7 @@ export const Card = forwardRef<HTMLDivElement, CardProps>((props, ref) => {
|
||||
|
||||
return (
|
||||
<Box
|
||||
bg="neutral-auto"
|
||||
bg="neutral"
|
||||
ref={ref}
|
||||
className={classes.root}
|
||||
{...dataAttributes}
|
||||
|
||||
@@ -34,6 +34,7 @@ import { useStyles } from '../../hooks/useStyles';
|
||||
import { DialogDefinition } from './definition';
|
||||
import { Flex } from '../Flex';
|
||||
import { Box } from '../Box';
|
||||
import { BgReset } from '../../hooks/useBg';
|
||||
import styles from './Dialog.module.css';
|
||||
|
||||
/** @public */
|
||||
@@ -72,12 +73,14 @@ export const Dialog = forwardRef<React.ElementRef<typeof Modal>, DialogProps>(
|
||||
...style,
|
||||
}}
|
||||
>
|
||||
<Box
|
||||
bg="neutral-1"
|
||||
className={clsx(classNames.content, styles[classNames.content])}
|
||||
>
|
||||
{children}
|
||||
</Box>
|
||||
<BgReset>
|
||||
<Box
|
||||
bg="neutral"
|
||||
className={clsx(classNames.content, styles[classNames.content])}
|
||||
>
|
||||
{children}
|
||||
</Box>
|
||||
</BgReset>
|
||||
</RADialog>
|
||||
</Modal>
|
||||
);
|
||||
|
||||
@@ -253,18 +253,21 @@ export const Backgrounds = meta.story({
|
||||
render: args => (
|
||||
<Flex align="center" style={{ flexWrap: 'wrap' }}>
|
||||
<Flex {...args}>Default</Flex>
|
||||
<Flex bg="neutral-1" {...args}>
|
||||
Neutral 1
|
||||
</Flex>
|
||||
<Flex bg="neutral-2" {...args}>
|
||||
Neutral 2
|
||||
</Flex>
|
||||
<Flex bg="neutral-3" {...args}>
|
||||
Neutral 3
|
||||
</Flex>
|
||||
<Flex bg={{ initial: 'neutral-1', sm: 'neutral-2' }} {...args}>
|
||||
Responsive Bg
|
||||
<Flex bg="neutral" {...args}>
|
||||
Neutral (level 1)
|
||||
</Flex>
|
||||
<Box bg="neutral">
|
||||
<Flex bg="neutral" {...args}>
|
||||
Neutral (level 2)
|
||||
</Flex>
|
||||
</Box>
|
||||
<Box bg="neutral">
|
||||
<Box bg="neutral">
|
||||
<Flex bg="neutral" {...args}>
|
||||
Neutral (level 3)
|
||||
</Flex>
|
||||
</Box>
|
||||
</Box>
|
||||
<Flex bg="danger" {...args}>
|
||||
Danger
|
||||
</Flex>
|
||||
@@ -278,20 +281,20 @@ export const Backgrounds = meta.story({
|
||||
),
|
||||
});
|
||||
|
||||
export const BgNeutralAuto = meta.story({
|
||||
export const BgNeutral = meta.story({
|
||||
args: { px: '6', py: '4', gap: '4' },
|
||||
render: args => (
|
||||
<Flex direction="column">
|
||||
<div style={{ maxWidth: '600px', marginBottom: '16px' }}>
|
||||
Using bg="neutral-auto" on Flex auto-increments from the parent context.
|
||||
The first Flex defaults to neutral-1 (no parent), then each nested Flex
|
||||
Using bg="neutral" on Flex auto-increments from the parent context. The
|
||||
first Flex defaults to neutral-1 (no parent), then each nested Flex
|
||||
increments by one, capping at neutral-3.
|
||||
</div>
|
||||
<Flex {...args} bg="neutral-auto" direction="column">
|
||||
<div>Neutral 1 (auto, no parent)</div>
|
||||
<Flex {...args} bg="neutral-auto" direction="column">
|
||||
<Flex {...args} bg="neutral" direction="column">
|
||||
<div>Neutral 1 (no parent)</div>
|
||||
<Flex {...args} bg="neutral" direction="column">
|
||||
<div>Neutral 2 (auto-incremented)</div>
|
||||
<Flex {...args} bg="neutral-auto" direction="column">
|
||||
<Flex {...args} bg="neutral" direction="column">
|
||||
<div>Neutral 3 (auto-incremented, capped)</div>
|
||||
</Flex>
|
||||
</Flex>
|
||||
|
||||
@@ -45,13 +45,6 @@ export const FlexDefinition = {
|
||||
'direction',
|
||||
],
|
||||
dataAttributes: {
|
||||
bg: [
|
||||
'neutral-1',
|
||||
'neutral-2',
|
||||
'neutral-3',
|
||||
'danger',
|
||||
'warning',
|
||||
'success',
|
||||
] as const,
|
||||
bg: ['neutral', 'danger', 'warning', 'success'] as const,
|
||||
},
|
||||
} as const satisfies ComponentDefinition;
|
||||
|
||||
@@ -113,18 +113,21 @@ export const Backgrounds = meta.story({
|
||||
render: args => (
|
||||
<Flex direction="column">
|
||||
<Flex style={{ flexWrap: 'wrap' }}>
|
||||
<Grid.Root {...args} bg="neutral-1">
|
||||
Neutral 1
|
||||
</Grid.Root>
|
||||
<Grid.Root {...args} bg="neutral-2">
|
||||
Neutral 2
|
||||
</Grid.Root>
|
||||
<Grid.Root {...args} bg="neutral-3">
|
||||
Neutral 3
|
||||
</Grid.Root>
|
||||
<Grid.Root {...args} bg={{ initial: 'neutral-1', sm: 'neutral-2' }}>
|
||||
Responsive Bg
|
||||
<Grid.Root {...args} bg="neutral">
|
||||
Neutral (level 1)
|
||||
</Grid.Root>
|
||||
<Box bg="neutral">
|
||||
<Grid.Root {...args} bg="neutral">
|
||||
Neutral (level 2)
|
||||
</Grid.Root>
|
||||
</Box>
|
||||
<Box bg="neutral">
|
||||
<Box bg="neutral">
|
||||
<Grid.Root {...args} bg="neutral">
|
||||
Neutral (level 3)
|
||||
</Grid.Root>
|
||||
</Box>
|
||||
</Box>
|
||||
<Grid.Root {...args} bg="danger">
|
||||
Danger
|
||||
</Grid.Root>
|
||||
@@ -137,28 +140,26 @@ export const Backgrounds = meta.story({
|
||||
</Flex>
|
||||
<Flex style={{ flexWrap: 'wrap' }}>
|
||||
<Grid.Root {...args}>
|
||||
<Grid.Item bg="neutral-1" style={{ padding: '4px' }}>
|
||||
Neutral 1
|
||||
</Grid.Item>
|
||||
</Grid.Root>
|
||||
<Grid.Root {...args}>
|
||||
<Grid.Item bg="neutral-2" style={{ padding: '4px' }}>
|
||||
Neutral 2
|
||||
</Grid.Item>
|
||||
</Grid.Root>
|
||||
<Grid.Root {...args}>
|
||||
<Grid.Item bg="neutral-3" style={{ padding: '4px' }}>
|
||||
Neutral 3
|
||||
</Grid.Item>
|
||||
</Grid.Root>
|
||||
<Grid.Root {...args}>
|
||||
<Grid.Item
|
||||
bg={{ initial: 'neutral-1', sm: 'neutral-2' }}
|
||||
style={{ padding: '4px' }}
|
||||
>
|
||||
Responsive Bg
|
||||
<Grid.Item bg="neutral" style={{ padding: '4px' }}>
|
||||
Neutral (level 1)
|
||||
</Grid.Item>
|
||||
</Grid.Root>
|
||||
<Box bg="neutral">
|
||||
<Grid.Root {...args}>
|
||||
<Grid.Item bg="neutral" style={{ padding: '4px' }}>
|
||||
Neutral (level 2)
|
||||
</Grid.Item>
|
||||
</Grid.Root>
|
||||
</Box>
|
||||
<Box bg="neutral">
|
||||
<Box bg="neutral">
|
||||
<Grid.Root {...args}>
|
||||
<Grid.Item bg="neutral" style={{ padding: '4px' }}>
|
||||
Neutral (level 3)
|
||||
</Grid.Item>
|
||||
</Grid.Root>
|
||||
</Box>
|
||||
</Box>
|
||||
<Grid.Root {...args}>
|
||||
<Grid.Item bg="danger" style={{ padding: '4px' }}>
|
||||
Danger
|
||||
@@ -179,7 +180,7 @@ export const Backgrounds = meta.story({
|
||||
),
|
||||
});
|
||||
|
||||
export const BgNeutralAuto = meta.story({
|
||||
export const BgNeutral = meta.story({
|
||||
args: { px: '6', py: '4', columns: '2', gap: '4' },
|
||||
render: args => (
|
||||
<Flex direction="column">
|
||||
@@ -188,12 +189,12 @@ export const BgNeutralAuto = meta.story({
|
||||
default. Only an explicit bg prop establishes a new bg level. Nested
|
||||
grids without a bg prop inherit the parent context unchanged.
|
||||
</div>
|
||||
<Grid.Root {...args} bg="neutral-1">
|
||||
<Grid.Root {...args} bg="neutral">
|
||||
<Grid.Item>Neutral 1 (Grid.Root)</Grid.Item>
|
||||
<Grid.Item>
|
||||
<Grid.Root {...args} bg="neutral-2">
|
||||
<Grid.Item>Nested: neutral-2 (explicit)</Grid.Item>
|
||||
<Grid.Item>Nested: neutral-2 (explicit)</Grid.Item>
|
||||
<Grid.Root {...args} bg="neutral">
|
||||
<Grid.Item>Nested: neutral-2 (auto-incremented)</Grid.Item>
|
||||
<Grid.Item>Nested: neutral-2 (auto-incremented)</Grid.Item>
|
||||
</Grid.Root>
|
||||
</Grid.Item>
|
||||
</Grid.Root>
|
||||
|
||||
@@ -43,14 +43,7 @@ export const GridDefinition = {
|
||||
'py',
|
||||
],
|
||||
dataAttributes: {
|
||||
bg: [
|
||||
'neutral-1',
|
||||
'neutral-2',
|
||||
'neutral-3',
|
||||
'danger',
|
||||
'warning',
|
||||
'success',
|
||||
] as const,
|
||||
bg: ['neutral', 'danger', 'warning', 'success'] as const,
|
||||
},
|
||||
} as const satisfies ComponentDefinition;
|
||||
|
||||
@@ -64,13 +57,6 @@ export const GridItemDefinition = {
|
||||
},
|
||||
utilityProps: ['colSpan', 'colEnd', 'colStart', 'rowSpan'],
|
||||
dataAttributes: {
|
||||
bg: [
|
||||
'neutral-1',
|
||||
'neutral-2',
|
||||
'neutral-3',
|
||||
'danger',
|
||||
'warning',
|
||||
'success',
|
||||
] as const,
|
||||
bg: ['neutral', 'danger', 'warning', 'success'] as const,
|
||||
},
|
||||
} as const satisfies ComponentDefinition;
|
||||
|
||||
@@ -59,6 +59,7 @@ import {
|
||||
import styles from './Menu.module.css';
|
||||
import clsx from 'clsx';
|
||||
import { Box } from '../Box';
|
||||
import { BgReset } from '../../hooks/useBg';
|
||||
|
||||
const { RoutingProvider, useRoutingRegistrationEffect } =
|
||||
createRoutingRegistration();
|
||||
@@ -120,23 +121,25 @@ export const Menu = (props: MenuProps<object>) => {
|
||||
)}
|
||||
placement={placement}
|
||||
>
|
||||
<Box
|
||||
bg="neutral-1"
|
||||
className={clsx(classNames.inner, styles[classNames.inner])}
|
||||
>
|
||||
{virtualized ? (
|
||||
<Virtualizer
|
||||
layout={ListLayout}
|
||||
layoutOptions={{
|
||||
rowHeight,
|
||||
}}
|
||||
>
|
||||
{menuContent}
|
||||
</Virtualizer>
|
||||
) : (
|
||||
menuContent
|
||||
)}
|
||||
</Box>
|
||||
<BgReset>
|
||||
<Box
|
||||
bg="neutral"
|
||||
className={clsx(classNames.inner, styles[classNames.inner])}
|
||||
>
|
||||
{virtualized ? (
|
||||
<Virtualizer
|
||||
layout={ListLayout}
|
||||
layoutOptions={{
|
||||
rowHeight,
|
||||
}}
|
||||
>
|
||||
{menuContent}
|
||||
</Virtualizer>
|
||||
) : (
|
||||
menuContent
|
||||
)}
|
||||
</Box>
|
||||
</BgReset>
|
||||
</RAPopover>
|
||||
</RoutingProvider>
|
||||
);
|
||||
@@ -175,23 +178,25 @@ export const MenuListBox = (props: MenuListBoxProps<object>) => {
|
||||
)}
|
||||
placement={placement}
|
||||
>
|
||||
<Box
|
||||
bg="neutral-1"
|
||||
className={clsx(classNames.inner, styles[classNames.inner])}
|
||||
>
|
||||
{virtualized ? (
|
||||
<Virtualizer
|
||||
layout={ListLayout}
|
||||
layoutOptions={{
|
||||
rowHeight,
|
||||
}}
|
||||
>
|
||||
{listBoxContent}
|
||||
</Virtualizer>
|
||||
) : (
|
||||
listBoxContent
|
||||
)}
|
||||
</Box>
|
||||
<BgReset>
|
||||
<Box
|
||||
bg="neutral"
|
||||
className={clsx(classNames.inner, styles[classNames.inner])}
|
||||
>
|
||||
{virtualized ? (
|
||||
<Virtualizer
|
||||
layout={ListLayout}
|
||||
layoutOptions={{
|
||||
rowHeight,
|
||||
}}
|
||||
>
|
||||
{listBoxContent}
|
||||
</Virtualizer>
|
||||
) : (
|
||||
listBoxContent
|
||||
)}
|
||||
</Box>
|
||||
</BgReset>
|
||||
</RAPopover>
|
||||
);
|
||||
};
|
||||
@@ -230,48 +235,50 @@ export const MenuAutocomplete = (props: MenuAutocompleteProps<object>) => {
|
||||
)}
|
||||
placement={placement}
|
||||
>
|
||||
<Box
|
||||
bg="neutral-1"
|
||||
className={clsx(classNames.inner, styles[classNames.inner])}
|
||||
>
|
||||
<RAAutocomplete filter={contains}>
|
||||
<RASearchField
|
||||
className={clsx(
|
||||
classNames.searchField,
|
||||
styles[classNames.searchField],
|
||||
<BgReset>
|
||||
<Box
|
||||
bg="neutral"
|
||||
className={clsx(classNames.inner, styles[classNames.inner])}
|
||||
>
|
||||
<RAAutocomplete filter={contains}>
|
||||
<RASearchField
|
||||
className={clsx(
|
||||
classNames.searchField,
|
||||
styles[classNames.searchField],
|
||||
)}
|
||||
aria-label={props.placeholder || 'Search'}
|
||||
>
|
||||
<RAInput
|
||||
className={clsx(
|
||||
classNames.searchFieldInput,
|
||||
styles[classNames.searchFieldInput],
|
||||
)}
|
||||
placeholder={props.placeholder || 'Search...'}
|
||||
/>
|
||||
<RAButton
|
||||
className={clsx(
|
||||
classNames.searchFieldClear,
|
||||
styles[classNames.searchFieldClear],
|
||||
)}
|
||||
>
|
||||
<RiCloseCircleLine />
|
||||
</RAButton>
|
||||
</RASearchField>
|
||||
{virtualized ? (
|
||||
<Virtualizer
|
||||
layout={ListLayout}
|
||||
layoutOptions={{
|
||||
rowHeight,
|
||||
}}
|
||||
>
|
||||
{menuContent}
|
||||
</Virtualizer>
|
||||
) : (
|
||||
menuContent
|
||||
)}
|
||||
aria-label={props.placeholder || 'Search'}
|
||||
>
|
||||
<RAInput
|
||||
className={clsx(
|
||||
classNames.searchFieldInput,
|
||||
styles[classNames.searchFieldInput],
|
||||
)}
|
||||
placeholder={props.placeholder || 'Search...'}
|
||||
/>
|
||||
<RAButton
|
||||
className={clsx(
|
||||
classNames.searchFieldClear,
|
||||
styles[classNames.searchFieldClear],
|
||||
)}
|
||||
>
|
||||
<RiCloseCircleLine />
|
||||
</RAButton>
|
||||
</RASearchField>
|
||||
{virtualized ? (
|
||||
<Virtualizer
|
||||
layout={ListLayout}
|
||||
layoutOptions={{
|
||||
rowHeight,
|
||||
}}
|
||||
>
|
||||
{menuContent}
|
||||
</Virtualizer>
|
||||
) : (
|
||||
menuContent
|
||||
)}
|
||||
</RAAutocomplete>
|
||||
</Box>
|
||||
</RAAutocomplete>
|
||||
</Box>
|
||||
</BgReset>
|
||||
</RAPopover>
|
||||
</RoutingProvider>
|
||||
);
|
||||
@@ -314,48 +321,50 @@ export const MenuAutocompleteListbox = (
|
||||
)}
|
||||
placement={placement}
|
||||
>
|
||||
<Box
|
||||
bg="neutral-1"
|
||||
className={clsx(classNames.inner, styles[classNames.inner])}
|
||||
>
|
||||
<RAAutocomplete filter={contains}>
|
||||
<RASearchField
|
||||
className={clsx(
|
||||
classNames.searchField,
|
||||
styles[classNames.searchField],
|
||||
<BgReset>
|
||||
<Box
|
||||
bg="neutral"
|
||||
className={clsx(classNames.inner, styles[classNames.inner])}
|
||||
>
|
||||
<RAAutocomplete filter={contains}>
|
||||
<RASearchField
|
||||
className={clsx(
|
||||
classNames.searchField,
|
||||
styles[classNames.searchField],
|
||||
)}
|
||||
aria-label={props.placeholder || 'Search'}
|
||||
>
|
||||
<RAInput
|
||||
className={clsx(
|
||||
classNames.searchFieldInput,
|
||||
styles[classNames.searchFieldInput],
|
||||
)}
|
||||
placeholder={props.placeholder || 'Search...'}
|
||||
/>
|
||||
<RAButton
|
||||
className={clsx(
|
||||
classNames.searchFieldClear,
|
||||
styles[classNames.searchFieldClear],
|
||||
)}
|
||||
>
|
||||
<RiCloseCircleLine />
|
||||
</RAButton>
|
||||
</RASearchField>
|
||||
{virtualized ? (
|
||||
<Virtualizer
|
||||
layout={ListLayout}
|
||||
layoutOptions={{
|
||||
rowHeight,
|
||||
}}
|
||||
>
|
||||
{listBoxContent}
|
||||
</Virtualizer>
|
||||
) : (
|
||||
listBoxContent
|
||||
)}
|
||||
aria-label={props.placeholder || 'Search'}
|
||||
>
|
||||
<RAInput
|
||||
className={clsx(
|
||||
classNames.searchFieldInput,
|
||||
styles[classNames.searchFieldInput],
|
||||
)}
|
||||
placeholder={props.placeholder || 'Search...'}
|
||||
/>
|
||||
<RAButton
|
||||
className={clsx(
|
||||
classNames.searchFieldClear,
|
||||
styles[classNames.searchFieldClear],
|
||||
)}
|
||||
>
|
||||
<RiCloseCircleLine />
|
||||
</RAButton>
|
||||
</RASearchField>
|
||||
{virtualized ? (
|
||||
<Virtualizer
|
||||
layout={ListLayout}
|
||||
layoutOptions={{
|
||||
rowHeight,
|
||||
}}
|
||||
>
|
||||
{listBoxContent}
|
||||
</Virtualizer>
|
||||
) : (
|
||||
listBoxContent
|
||||
)}
|
||||
</RAAutocomplete>
|
||||
</Box>
|
||||
</RAAutocomplete>
|
||||
</Box>
|
||||
</BgReset>
|
||||
</RAPopover>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -208,7 +208,7 @@ export const WithRichContent = Default.extend({
|
||||
This is a popover with rich content. It can contain multiple
|
||||
elements and formatted text.
|
||||
</Text>
|
||||
<Box bg="neutral-auto" p="2">
|
||||
<Box bg="neutral" p="2">
|
||||
<Text>You can also use the automatic bg system inside it.</Text>
|
||||
</Box>
|
||||
<Flex gap="2" justify="end">
|
||||
|
||||
@@ -23,6 +23,7 @@ import { useStyles } from '../../hooks/useStyles';
|
||||
import { PopoverDefinition } from './definition';
|
||||
import styles from './Popover.module.css';
|
||||
import { Box } from '../Box';
|
||||
import { BgReset } from '../../hooks/useBg';
|
||||
|
||||
/**
|
||||
* A popover component built on React Aria Components that displays floating
|
||||
@@ -95,12 +96,14 @@ export const Popover = forwardRef<HTMLDivElement, PopoverProps>(
|
||||
</svg>
|
||||
</OverlayArrow>
|
||||
)}
|
||||
<Box
|
||||
bg="neutral-1"
|
||||
className={clsx(classNames.content, styles[classNames.content])}
|
||||
>
|
||||
{children}
|
||||
</Box>
|
||||
<BgReset>
|
||||
<Box
|
||||
bg="neutral"
|
||||
className={clsx(classNames.content, styles[classNames.content])}
|
||||
>
|
||||
{children}
|
||||
</Box>
|
||||
</BgReset>
|
||||
</>
|
||||
)}
|
||||
</AriaPopover>
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
import preview from '../../../../../.storybook/preview';
|
||||
import { ToggleButton } from './ToggleButton';
|
||||
import { Box } from '../Box';
|
||||
import { Flex } from '../Flex';
|
||||
import { Text } from '../Text';
|
||||
import { useState } from 'react';
|
||||
@@ -65,21 +66,27 @@ export const Backgrounds = meta.story({
|
||||
</Flex>
|
||||
<Flex direction="column" gap="4">
|
||||
<Text>On Neutral 1</Text>
|
||||
<Flex align="center" bg="neutral-1" p="4">
|
||||
<Flex align="center" bg="neutral" p="4">
|
||||
<ToggleButton>Toggle</ToggleButton>
|
||||
</Flex>
|
||||
</Flex>
|
||||
<Flex direction="column" gap="4">
|
||||
<Text>On Neutral 2</Text>
|
||||
<Flex align="center" bg="neutral-2" p="4">
|
||||
<ToggleButton>Toggle</ToggleButton>
|
||||
</Flex>
|
||||
<Box bg="neutral">
|
||||
<Flex align="center" bg="neutral" p="4">
|
||||
<ToggleButton>Toggle</ToggleButton>
|
||||
</Flex>
|
||||
</Box>
|
||||
</Flex>
|
||||
<Flex direction="column" gap="4">
|
||||
<Text>On Neutral 3</Text>
|
||||
<Flex align="center" bg="neutral-3" p="4">
|
||||
<ToggleButton>Toggle</ToggleButton>
|
||||
</Flex>
|
||||
<Box bg="neutral">
|
||||
<Box bg="neutral">
|
||||
<Flex align="center" bg="neutral" p="4">
|
||||
<ToggleButton>Toggle</ToggleButton>
|
||||
</Flex>
|
||||
</Box>
|
||||
</Box>
|
||||
</Flex>
|
||||
</Flex>
|
||||
),
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
import preview from '../../../../../.storybook/preview';
|
||||
import { ToggleButtonGroup } from './ToggleButtonGroup';
|
||||
import { ToggleButton } from '../ToggleButton/ToggleButton';
|
||||
import { Box } from '../Box';
|
||||
import { Flex } from '../Flex';
|
||||
import { Text } from '../Text';
|
||||
import { useState } from 'react';
|
||||
@@ -100,7 +101,7 @@ export const Backgrounds = meta.story({
|
||||
</Flex>
|
||||
<Flex direction="column" gap="4">
|
||||
<Text>On Neutral 1</Text>
|
||||
<Flex align="center" bg="neutral-1" p="4" gap="4">
|
||||
<Flex align="center" bg="neutral" p="4" gap="4">
|
||||
<ToggleButtonGroup
|
||||
selectionMode="single"
|
||||
defaultSelectedKeys={['option1']}
|
||||
@@ -113,29 +114,35 @@ export const Backgrounds = meta.story({
|
||||
</Flex>
|
||||
<Flex direction="column" gap="4">
|
||||
<Text>On Neutral 2</Text>
|
||||
<Flex align="center" bg="neutral-2" p="4" gap="4">
|
||||
<ToggleButtonGroup
|
||||
selectionMode="single"
|
||||
defaultSelectedKeys={['option1']}
|
||||
>
|
||||
<ToggleButton id="option1">Option 1</ToggleButton>
|
||||
<ToggleButton id="option2">Option 2</ToggleButton>
|
||||
<ToggleButton id="option3">Option 3</ToggleButton>
|
||||
</ToggleButtonGroup>
|
||||
</Flex>
|
||||
<Box bg="neutral">
|
||||
<Flex align="center" bg="neutral" p="4" gap="4">
|
||||
<ToggleButtonGroup
|
||||
selectionMode="single"
|
||||
defaultSelectedKeys={['option1']}
|
||||
>
|
||||
<ToggleButton id="option1">Option 1</ToggleButton>
|
||||
<ToggleButton id="option2">Option 2</ToggleButton>
|
||||
<ToggleButton id="option3">Option 3</ToggleButton>
|
||||
</ToggleButtonGroup>
|
||||
</Flex>
|
||||
</Box>
|
||||
</Flex>
|
||||
<Flex direction="column" gap="4">
|
||||
<Text>On Neutral 3</Text>
|
||||
<Flex align="center" bg="neutral-3" p="4" gap="4">
|
||||
<ToggleButtonGroup
|
||||
selectionMode="single"
|
||||
defaultSelectedKeys={['option1']}
|
||||
>
|
||||
<ToggleButton id="option1">Option 1</ToggleButton>
|
||||
<ToggleButton id="option2">Option 2</ToggleButton>
|
||||
<ToggleButton id="option3">Option 3</ToggleButton>
|
||||
</ToggleButtonGroup>
|
||||
</Flex>
|
||||
<Box bg="neutral">
|
||||
<Box bg="neutral">
|
||||
<Flex align="center" bg="neutral" p="4" gap="4">
|
||||
<ToggleButtonGroup
|
||||
selectionMode="single"
|
||||
defaultSelectedKeys={['option1']}
|
||||
>
|
||||
<ToggleButton id="option1">Option 1</ToggleButton>
|
||||
<ToggleButton id="option2">Option 2</ToggleButton>
|
||||
<ToggleButton id="option3">Option 3</ToggleButton>
|
||||
</ToggleButtonGroup>
|
||||
</Flex>
|
||||
</Box>
|
||||
</Box>
|
||||
</Flex>
|
||||
</Flex>
|
||||
),
|
||||
|
||||
@@ -28,6 +28,7 @@ import { useStyles } from '../../hooks/useStyles';
|
||||
import { TooltipDefinition } from './definition';
|
||||
import styles from './Tooltip.module.css';
|
||||
import { Box } from '../Box';
|
||||
import { BgReset } from '../../hooks/useBg';
|
||||
|
||||
/** @public */
|
||||
export const TooltipTrigger = (props: TooltipTriggerComponentProps) => {
|
||||
@@ -71,12 +72,14 @@ export const Tooltip = forwardRef<HTMLDivElement, TooltipProps>(
|
||||
<path d="M11.0046 8.14124C10.2439 8.82575 9.08939 8.82578 8.32869 8.14122L3.47189 3.77011C2.92109 3.27432 2.20619 2.99999 1.46509 2.99999L4.10999 3L8.99769 7.39793C9.37799 7.7402 9.95529 7.7402 10.3356 7.39793L15.2226 3L17.8683 2.99999C17.1271 2.99999 16.4122 3.27432 15.8614 3.77011L11.0046 8.14124Z" />
|
||||
</svg>
|
||||
</OverlayArrow>
|
||||
<Box
|
||||
bg="neutral-1"
|
||||
className={clsx(classNames.content, styles[classNames.content])}
|
||||
>
|
||||
{children}
|
||||
</Box>
|
||||
<BgReset>
|
||||
<Box
|
||||
bg="neutral"
|
||||
className={clsx(classNames.content, styles[classNames.content])}
|
||||
>
|
||||
{children}
|
||||
</Box>
|
||||
</BgReset>
|
||||
</AriaTooltip>
|
||||
);
|
||||
},
|
||||
|
||||
@@ -69,6 +69,24 @@ export const BgProvider = ({ bg, children }: BgProviderProps) => {
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* Resets the bg context to undefined, cutting any inherited neutral chain.
|
||||
* Use this inside overlay components (Popover, Tooltip, Dialog, Menu) so
|
||||
* their content always starts from neutral-1 regardless of where the trigger
|
||||
* is placed in the tree.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
export const BgReset = ({ children }: { children: ReactNode }) => {
|
||||
return (
|
||||
<BgContext.Provider
|
||||
value={createVersionedValueMap({ 1: { bg: undefined } })}
|
||||
>
|
||||
{children}
|
||||
</BgContext.Provider>
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* Hook for consumer components (e.g. Button) to read the parent bg context.
|
||||
*
|
||||
@@ -90,10 +108,14 @@ export function useBgConsumer(): BgContextValue {
|
||||
*
|
||||
* - `bg` is `undefined` -- transparent, no context change, returns `{ bg: undefined }`.
|
||||
* This is the default for Box, Flex, and Grid (they do **not** auto-increment).
|
||||
* - `bg` is a `ContainerBg` value -- uses that value directly (e.g. `'neutral-1'`).
|
||||
* - `bg` is `'neutral-auto'` -- increments the neutral level from the parent context,
|
||||
* capping at `neutral-3`. Only components that explicitly pass `'neutral-auto'`
|
||||
* (e.g. Card) will auto-increment; it is never implicit.
|
||||
* - `bg` is `'neutral'` -- when the parent bg is neutral, increments the neutral
|
||||
* level from the parent context, capping at `neutral-3`. When the parent bg is
|
||||
* an intent (`'danger'` | `'warning'` | `'success'`), the intent passes through
|
||||
* unchanged (i.e. `bg: 'neutral'` does not override the parent intent). The
|
||||
* increment is always relative to the parent; it is not possible to pin a
|
||||
* container to an explicit neutral level.
|
||||
* - `bg` is `'danger'` | `'warning'` | `'success'` -- sets the bg to that intent
|
||||
* explicitly, regardless of the parent value.
|
||||
*
|
||||
* **Capping:**
|
||||
*
|
||||
@@ -116,7 +138,7 @@ export function useBgProvider(bg?: Responsive<ProviderBg>): BgContextValue {
|
||||
|
||||
const resolved = resolveResponsiveValue(bg, breakpoint);
|
||||
|
||||
if (resolved === 'neutral-auto') {
|
||||
if (resolved === 'neutral') {
|
||||
return { bg: incrementNeutralBg(context.bg) };
|
||||
}
|
||||
|
||||
|
||||
@@ -182,7 +182,7 @@ export interface ComponentDefinition {
|
||||
}
|
||||
|
||||
/**
|
||||
* Background type for the neutral bg system.
|
||||
* Resolved background level stored in context and applied as `data-bg` on DOM elements.
|
||||
*
|
||||
* Supports neutral levels ('neutral-1' through 'neutral-3') and
|
||||
* intent backgrounds ('danger', 'warning', 'success').
|
||||
@@ -190,6 +190,9 @@ export interface ComponentDefinition {
|
||||
* The 'neutral-4' level is not exposed as a prop value -- it is reserved
|
||||
* for leaf component CSS (e.g. Button on a 'neutral-3' surface).
|
||||
*
|
||||
* This is the resolved/internal representation used by the bg context system.
|
||||
* For the prop type accepted by container components, use `ProviderBg` instead.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export type ContainerBg =
|
||||
@@ -201,11 +204,13 @@ export type ContainerBg =
|
||||
| 'success';
|
||||
|
||||
/**
|
||||
* Background values accepted by provider components.
|
||||
* Background values accepted by provider components (Box, Flex, Grid, Card, etc.).
|
||||
*
|
||||
* Includes all `ContainerBg` values plus `'neutral-auto'` which
|
||||
* automatically increments the neutral level from the parent context.
|
||||
* - `'neutral'` — automatically increments the neutral level from the parent context,
|
||||
* capping at the maximum level. This is always incremental; explicit levels cannot
|
||||
* be set directly.
|
||||
* - `'danger'` | `'warning'` | `'success'` — intent backgrounds used as-is.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export type ProviderBg = ContainerBg | 'neutral-auto';
|
||||
export type ProviderBg = 'neutral' | 'danger' | 'warning' | 'success';
|
||||
|
||||
Reference in New Issue
Block a user