feat(ui): add --bui-bg-inherit CSS variable (#34124)
* feat(ui): add --bui-bg-inherit CSS variable in core.css Signed-off-by: Johan Persson <johanopersson@gmail.com> * refactor(ui): remove duplicated data-bg painting from Box.module.css Signed-off-by: Johan Persson <johanopersson@gmail.com> * refactor(ui): remove duplicated data-bg painting from Flex.module.css Signed-off-by: Johan Persson <johanopersson@gmail.com> * refactor(ui): remove duplicated data-bg painting from Grid.module.css Signed-off-by: Johan Persson <johanopersson@gmail.com> * refactor(ui): centralize Accordion data-bg painting, preserve no-intent behavior Signed-off-by: Johan Persson <johanopersson@gmail.com> * refactor(ui): use --bui-bg-inherit for Card scroll-shadow gradients Signed-off-by: Johan Persson <johanopersson@gmail.com> * docs(ui): document --bui-bg-inherit token Signed-off-by: Johan Persson <johanopersson@gmail.com> * chore: changeset for --bui-bg-inherit Signed-off-by: Johan Persson <johanopersson@gmail.com> * docs(ui): add Storybook story for --bui-bg-inherit Signed-off-by: Johan Persson <johanopersson@gmail.com> * docs(ui): fold --bui-bg-inherit story into colors stories Signed-off-by: Johan Persson <johanopersson@gmail.com> * changeset: Reword for clarity. Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> Signed-off-by: Johan Persson <johanopersson@gmail.com> --------- Signed-off-by: Johan Persson <johanopersson@gmail.com> Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
@@ -0,0 +1,24 @@
|
||||
---
|
||||
'@backstage/ui': patch
|
||||
---
|
||||
|
||||
Added a public `--bui-bg-inherit` CSS variable that resolves to the background
|
||||
color of the nearest enclosing bg provider (`Box`, `Flex`, `Grid`, `Card`,
|
||||
`Accordion`, or any element with a `data-bg` attribute), falling back to
|
||||
`--bui-bg-app`. Use it from CSS for sticky or fixed elements that need to match
|
||||
their surrounding surface without hardcoding a specific level.
|
||||
|
||||
```css
|
||||
.searchBarContainer {
|
||||
position: sticky;
|
||||
top: 0;
|
||||
background-color: var(--bui-bg-inherit);
|
||||
}
|
||||
```
|
||||
|
||||
As part of this change, the `data-bg` painting rules previously duplicated in
|
||||
`Box`, `Flex`, `Grid`, `Accordion`, and `Card` have been centralized into a
|
||||
single source in `core.css`. Painting and component behavior are unchanged for
|
||||
all existing usages, with one minor expansion: any element with a `data-bg`
|
||||
attribute (including provider elements and any element that sets it directly)
|
||||
is now painted, not only `Box`/`Flex`/`Grid`/`Card`/`Accordion` elements.
|
||||
@@ -264,6 +264,42 @@ pressed, and disabled variants for interactive states.
|
||||
</Table.Body>
|
||||
</Table.Root>
|
||||
|
||||
## Inherited background
|
||||
|
||||
`--bui-bg-inherit` resolves to the bg color of the nearest enclosing element with a
|
||||
`data-bg` attribute (set by `Box`, `Flex`, `Grid`, `Card`, `Accordion`, or any
|
||||
element that explicitly sets `data-bg`). When no such ancestor exists it falls
|
||||
back to `--bui-bg-app`. Use it from CSS when a sticky, fixed, or otherwise
|
||||
overlapping element needs to match its surrounding bg without hardcoding a level.
|
||||
|
||||
<CodeBlock
|
||||
code={`.searchBarContainer {
|
||||
position: sticky;
|
||||
top: 0;
|
||||
background-color: var(--bui-bg-inherit);
|
||||
}`}
|
||||
/>
|
||||
|
||||
<Table.Root>
|
||||
<Table.Header>
|
||||
<Table.HeaderRow>
|
||||
<Table.HeaderCell>Prop</Table.HeaderCell>
|
||||
<Table.HeaderCell>Description</Table.HeaderCell>
|
||||
</Table.HeaderRow>
|
||||
</Table.Header>
|
||||
<Table.Body>
|
||||
<Table.Row>
|
||||
<Table.Cell>
|
||||
<Chip head>--bui-bg-inherit</Chip>
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
Resolves to the bg color of the nearest enclosing `data-bg` ancestor,
|
||||
falling back to `--bui-bg-app`.
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
</Table.Body>
|
||||
</Table.Root>
|
||||
|
||||
## Solid background colors
|
||||
|
||||
<Table.Root>
|
||||
|
||||
@@ -21,18 +21,12 @@
|
||||
width: 100%;
|
||||
border-radius: var(--bui-radius-3);
|
||||
padding: var(--bui-space-3);
|
||||
}
|
||||
|
||||
&[data-bg='neutral-1'] {
|
||||
background-color: var(--bui-bg-neutral-1);
|
||||
}
|
||||
|
||||
&[data-bg='neutral-2'] {
|
||||
background-color: var(--bui-bg-neutral-2);
|
||||
}
|
||||
|
||||
&[data-bg='neutral-3'] {
|
||||
background-color: var(--bui-bg-neutral-3);
|
||||
}
|
||||
.bui-Accordion[data-bg='danger'],
|
||||
.bui-Accordion[data-bg='warning'],
|
||||
.bui-Accordion[data-bg='success'] {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.bui-AccordionTrigger {
|
||||
|
||||
@@ -22,28 +22,4 @@
|
||||
font-weight: var(--bui-font-weight-regular);
|
||||
color: var(--bui-fg-primary);
|
||||
}
|
||||
|
||||
.bui-Box[data-bg='neutral-1'] {
|
||||
background-color: var(--bui-bg-neutral-1);
|
||||
}
|
||||
|
||||
.bui-Box[data-bg='neutral-2'] {
|
||||
background-color: var(--bui-bg-neutral-2);
|
||||
}
|
||||
|
||||
.bui-Box[data-bg='neutral-3'] {
|
||||
background-color: var(--bui-bg-neutral-3);
|
||||
}
|
||||
|
||||
.bui-Box[data-bg='danger'] {
|
||||
background-color: var(--bui-bg-danger);
|
||||
}
|
||||
|
||||
.bui-Box[data-bg='warning'] {
|
||||
background-color: var(--bui-bg-warning);
|
||||
}
|
||||
|
||||
.bui-Box[data-bg='success'] {
|
||||
background-color: var(--bui-bg-success);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,18 +29,6 @@
|
||||
padding: var(--bui-space-3);
|
||||
}
|
||||
|
||||
.bui-Card[data-bg='neutral-1'] {
|
||||
--bui-card-bg: var(--bui-bg-neutral-1);
|
||||
}
|
||||
|
||||
.bui-Card[data-bg='neutral-2'] {
|
||||
--bui-card-bg: var(--bui-bg-neutral-2);
|
||||
}
|
||||
|
||||
.bui-Card[data-bg='neutral-3'] {
|
||||
--bui-card-bg: var(--bui-bg-neutral-3);
|
||||
}
|
||||
|
||||
.bui-Card:has(.bui-CardHeader, .bui-CardBody, .bui-CardFooter) {
|
||||
padding: 0;
|
||||
}
|
||||
@@ -127,8 +115,8 @@
|
||||
margin-bottom: -1.5rem;
|
||||
background: linear-gradient(
|
||||
to bottom,
|
||||
var(--bui-card-bg),
|
||||
rgb(from var(--bui-card-bg) r g b / 0)
|
||||
var(--bui-bg-inherit),
|
||||
rgb(from var(--bui-bg-inherit) r g b / 0)
|
||||
);
|
||||
pointer-events: none;
|
||||
opacity: 0;
|
||||
@@ -146,8 +134,8 @@
|
||||
margin-top: -1.5rem;
|
||||
background: linear-gradient(
|
||||
to top,
|
||||
var(--bui-card-bg),
|
||||
rgb(from var(--bui-card-bg) r g b / 0)
|
||||
var(--bui-bg-inherit),
|
||||
rgb(from var(--bui-bg-inherit) r g b / 0)
|
||||
);
|
||||
pointer-events: none;
|
||||
opacity: 0;
|
||||
|
||||
@@ -23,28 +23,4 @@
|
||||
/* This helps when using `truncate` on text inside a flex container */
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.bui-Flex[data-bg='neutral-1'] {
|
||||
background-color: var(--bui-bg-neutral-1);
|
||||
}
|
||||
|
||||
.bui-Flex[data-bg='neutral-2'] {
|
||||
background-color: var(--bui-bg-neutral-2);
|
||||
}
|
||||
|
||||
.bui-Flex[data-bg='neutral-3'] {
|
||||
background-color: var(--bui-bg-neutral-3);
|
||||
}
|
||||
|
||||
.bui-Flex[data-bg='danger'] {
|
||||
background-color: var(--bui-bg-danger);
|
||||
}
|
||||
|
||||
.bui-Flex[data-bg='warning'] {
|
||||
background-color: var(--bui-bg-warning);
|
||||
}
|
||||
|
||||
.bui-Flex[data-bg='success'] {
|
||||
background-color: var(--bui-bg-success);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,34 +20,4 @@
|
||||
.bui-Grid {
|
||||
display: grid;
|
||||
}
|
||||
|
||||
.bui-Grid[data-bg='neutral-1'],
|
||||
.bui-GridItem[data-bg='neutral-1'] {
|
||||
background-color: var(--bui-bg-neutral-1);
|
||||
}
|
||||
|
||||
.bui-Grid[data-bg='neutral-2'],
|
||||
.bui-GridItem[data-bg='neutral-2'] {
|
||||
background-color: var(--bui-bg-neutral-2);
|
||||
}
|
||||
|
||||
.bui-Grid[data-bg='neutral-3'],
|
||||
.bui-GridItem[data-bg='neutral-3'] {
|
||||
background-color: var(--bui-bg-neutral-3);
|
||||
}
|
||||
|
||||
.bui-Grid[data-bg='danger'],
|
||||
.bui-GridItem[data-bg='danger'] {
|
||||
background-color: var(--bui-bg-danger);
|
||||
}
|
||||
|
||||
.bui-Grid[data-bg='warning'],
|
||||
.bui-GridItem[data-bg='warning'] {
|
||||
background-color: var(--bui-bg-warning);
|
||||
}
|
||||
|
||||
.bui-Grid[data-bg='success'],
|
||||
.bui-GridItem[data-bg='success'] {
|
||||
background-color: var(--bui-bg-success);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,6 +23,24 @@ const meta = preview.meta({
|
||||
tags: ['!manifest'],
|
||||
});
|
||||
|
||||
/**
|
||||
* A `<div>` styled with `background: var(--bui-bg-inherit)` should always
|
||||
* resolve to the same color as the surrounding bg provider — at every level
|
||||
* of the neutral chain and inside intent surfaces.
|
||||
*/
|
||||
const Probe = ({ label }: { label: string }) => (
|
||||
<div
|
||||
style={{
|
||||
backgroundColor: 'var(--bui-bg-inherit)',
|
||||
padding: '0.5rem 0.75rem',
|
||||
borderRadius: '0.25rem',
|
||||
outline: '1px dashed var(--bui-fg-secondary)',
|
||||
}}
|
||||
>
|
||||
<Text>{label}</Text>
|
||||
</div>
|
||||
);
|
||||
|
||||
export const Default = meta.story({
|
||||
render: () => (
|
||||
<div style={{ backgroundColor: 'var(--bui-bg-app)' }}>
|
||||
@@ -151,3 +169,37 @@ export const Default = meta.story({
|
||||
</div>
|
||||
),
|
||||
});
|
||||
|
||||
export const BgInherit = meta.story({
|
||||
render: () => (
|
||||
<Flex direction="column" gap="4">
|
||||
<Probe label="App level (no provider) — resolves to --bui-bg-app" />
|
||||
|
||||
<Box bg="neutral" p="4">
|
||||
<Flex direction="column" gap="3">
|
||||
<Probe label="Inside neutral-1 — resolves to --bui-bg-neutral-1" />
|
||||
<Box bg="neutral" p="4">
|
||||
<Flex direction="column" gap="3">
|
||||
<Probe label="Inside neutral-2 — resolves to --bui-bg-neutral-2" />
|
||||
<Box bg="neutral" p="4">
|
||||
<Probe label="Inside neutral-3 — resolves to --bui-bg-neutral-3" />
|
||||
</Box>
|
||||
</Flex>
|
||||
</Box>
|
||||
</Flex>
|
||||
</Box>
|
||||
|
||||
<Box bg="danger" p="4">
|
||||
<Probe label="Inside danger — resolves to --bui-bg-danger" />
|
||||
</Box>
|
||||
|
||||
<Box bg="warning" p="4">
|
||||
<Probe label="Inside warning — resolves to --bui-bg-warning" />
|
||||
</Box>
|
||||
|
||||
<Box bg="success" p="4">
|
||||
<Probe label="Inside success — resolves to --bui-bg-success" />
|
||||
</Box>
|
||||
</Flex>
|
||||
),
|
||||
});
|
||||
|
||||
@@ -47,4 +47,38 @@
|
||||
[data-theme-mode='light'] {
|
||||
color-scheme: light;
|
||||
}
|
||||
|
||||
:root {
|
||||
--bui-bg-inherit: var(--bui-bg-app);
|
||||
}
|
||||
|
||||
[data-bg='neutral-1'] {
|
||||
background-color: var(--bui-bg-neutral-1);
|
||||
--bui-bg-inherit: var(--bui-bg-neutral-1);
|
||||
}
|
||||
|
||||
[data-bg='neutral-2'] {
|
||||
background-color: var(--bui-bg-neutral-2);
|
||||
--bui-bg-inherit: var(--bui-bg-neutral-2);
|
||||
}
|
||||
|
||||
[data-bg='neutral-3'] {
|
||||
background-color: var(--bui-bg-neutral-3);
|
||||
--bui-bg-inherit: var(--bui-bg-neutral-3);
|
||||
}
|
||||
|
||||
[data-bg='danger'] {
|
||||
background-color: var(--bui-bg-danger);
|
||||
--bui-bg-inherit: var(--bui-bg-danger);
|
||||
}
|
||||
|
||||
[data-bg='warning'] {
|
||||
background-color: var(--bui-bg-warning);
|
||||
--bui-bg-inherit: var(--bui-bg-warning);
|
||||
}
|
||||
|
||||
[data-bg='success'] {
|
||||
background-color: var(--bui-bg-success);
|
||||
--bui-bg-inherit: var(--bui-bg-success);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user