Merge branch 'master' into bui-surfaces

This commit is contained in:
Charles de Dreuille
2026-02-06 17:37:05 +00:00
58 changed files with 837 additions and 502 deletions
+30
View File
@@ -0,0 +1,30 @@
---
'@backstage/ui': minor
---
**BREAKING**: Removed gray scale tokens and renamed background surface tokens to neutral tokens
The `--bui-gray-1` through `--bui-gray-8` tokens have been removed. The `--bui-bg-surface-*` and `--bui-bg-neutral-on-surface-*` tokens have been replaced by a unified `--bui-bg-neutral-*` scale.
**Migration:**
Replace surface tokens directly:
```diff
- background: var(--bui-bg-surface-0);
+ background: var(--bui-bg-neutral-0);
```
Replace on-surface tokens shifted by +1:
```diff
- background: var(--bui-bg-neutral-on-surface-0);
+ background: var(--bui-bg-neutral-1);
```
Replace gray tokens 1-4 with neutral equivalents (`--bui-gray-5` through `--bui-gray-8` have no direct replacement):
```diff
- background: var(--bui-gray-1);
+ background: var(--bui-bg-neutral-1);
```
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-auth-backend-module-auth0-provider': patch
---
Add support for organizational invites in auth0 strategy
+1 -1
View File
@@ -42,7 +42,7 @@ For tint colors (backgrounds, foregrounds, borders), migrate to appropriate stat
- background: var(--bui-bg-tint);
+ background: var(--bui-bg-info); /* For informational sections */
+ /* or */
+ background: var(--bui-bg-neutral-on-surface-0); /* For neutral emphasis */
+ background: var(--bui-bg-neutral-1); /* For neutral emphasis */
}
```
+2 -2
View File
@@ -134,11 +134,11 @@ export default definePreview({
};
}, [selectedTheme, selectedThemeName]);
document.body.style.backgroundColor = 'var(--bui-bg-surface-0)';
document.body.style.backgroundColor = 'var(--bui-bg-neutral-0)';
const docsStoryElements = document.getElementsByClassName('docs-story');
Array.from(docsStoryElements).forEach(element => {
(element as HTMLElement).style.backgroundColor =
'var(--bui-bg-surface-0)';
'var(--bui-bg-neutral-0)';
});
return (
+2 -2
View File
@@ -13,7 +13,7 @@
}
[data-theme-mode='dark'] {
--sb-sidebar-bg: var(--bui-bg-surface-1);
--sb-sidebar-bg: var(--bui-bg-neutral-1);
}
[data-theme-name='spotify'] {
@@ -24,7 +24,7 @@
--sb-panel-right: 8px;
--sb-sidebar-border: none;
--sb-sidebar-border-right: none;
--sb-sidebar-bg: var(--bui-bg-surface-1);
--sb-sidebar-bg: var(--bui-bg-neutral-1);
--sb-options-border: none;
--sb-options-border-left: none;
--sb-content-padding-inline: 258px;
+6 -6
View File
@@ -222,11 +222,11 @@
--bui-bg-solid-disabled: #0f6c30;
--bui-fg-primary: var(--bui-black);
--bui-fg-secondary: var(--bui-gray-7);
--bui-fg-secondary: #757575;
--bui-fg-solid: var(--bui-black);
--bui-fg-solid-disabled: #62ab7c;
--bui-border: var(--bui-gray-3);
--bui-border: #d9d9d9;
--bui-border-hover: rgba(0, 0, 0, 0.3);
--bui-border-pressed: rgba(0, 0, 0, 0.5);
--bui-border-disabled: rgba(0, 0, 0, 0.1);
@@ -246,7 +246,7 @@
}
[data-theme-mode='dark'][data-theme-name='spotify'] {
--bui-bg-surface-0: var(--bui-black);
--bui-bg-neutral-0: var(--bui-black);
--bui-bg-solid: #1ed760;
--bui-bg-solid-hover: #3be477;
@@ -258,15 +258,15 @@
--bui-bg-success: #132d21;
--bui-fg-primary: var(--bui-white);
--bui-fg-secondary: var(--bui-gray-7);
--bui-fg-disabled: var(--bui-gray-5);
--bui-fg-secondary: #9e9e9e;
--bui-fg-disabled: #575757;
--bui-fg-solid: var(--bui-black);
--bui-fg-solid-disabled: #072f15;
--bui-fg-danger: #e22b2b;
--bui-fg-warning: #e36d05;
--bui-fg-success: #1db954;
--bui-border: var(--bui-gray-3);
--bui-border: #373737;
--bui-border-hover: rgba(255, 255, 255, 0.4);
--bui-border-pressed: rgba(255, 255, 255, 0.5);
--bui-border-disabled: rgba(255, 255, 255, 0.2);
+1
View File
@@ -289,3 +289,4 @@ _You can do this by using the [Adopter form](https://info.backstage.spotify.com/
| [Swiss Mobiliar Insurance Company Ltd.](https://www.mobiliar.ch/) | [Patrick Wyler](mailto:patrick.wyler@mobiliar.ch) and [Beat Winistörfer](mailto:beat.winistoerfer@mobiliar.ch) | The portal provides a unified interface for accessing all relevant DevOps information previously scattered across various locations, enhancing accessibility and clarity for all IT employees. It relies on an internal graph database that enhances the Backstage software catalog with many additional elements. Significant effort has been invested in the visual representation of information through graphs and diagrams, facilitating analysis and improving the understanding of dependencies. |
| [DB Systel GmbH](https://www.dbsystel.de/dbsystel-en/) | [DB Systel GmbH](https://github.com/dbsystel) | Deutsche Bahn's Internal Developer Portal leverages Backstage and Crossplane.io to deliver a fully GitOps-driven onboarding experience for engineering teams across the company. Our Scaffolder ecosystem accelerates platform setup (Artifactory, GitLab, OpenShift), service bootstrapping, automated testing, AI-ready backends, and modern frontend development. We also make heavy use of custom catalog modules and frontend plugins that support developers in checking their provisioned resources or security and compliance of their code. |
| [Danske StatsBaner (DSB)](https://www.dsb.dk/om-dsb/job-og-karriere/) | [Isaac Livingston](mailto:isjl@dsb.dk), [Paula-Catalina Curca](mailto:PACU@DSB.DK), [Muhammad Salman Khan](mailto:MUSK@DSB.DK) | DSB's portal is a central catalog of all our microservices, APIs, and systems. Developers can easily create new components with templates that run in our CNCF based developer platform |
| [NN Group](https://www.nn-group.com/) | [Flavia Naezer (Product Owner)](mailto:flavia.naezer@nn-group.com), [Vijai Ramcharan (Principal Engineer)](mailto:vijai.ramcharan@nn-group.com) | Our Backstage powered IDP supports engineers and other makers and shapers in our large financial enterprise with the Software Catalog, a Store for infrastructure, TechDocs and Portal Platform with mini App-Store.|
+132 -61
View File
@@ -107,8 +107,6 @@ the value, you add an object with the value and the breakpoint prefix.
## Base colors
These colors are used for special purposes like ring, scrollbar, ...
<Table.Root>
<Table.Header>
<Table.HeaderRow>
@@ -133,62 +131,15 @@ These colors are used for special purposes like ring, scrollbar, ...
Pure white color. This one should be the same in light and dark themes.
</Table.Cell>
</Table.Row>
<Table.Row>
<Table.Cell>
<Chip head>--bui-gray-1</Chip>
</Table.Cell>
<Table.Cell>You can use these mostly for backgrounds colors.</Table.Cell>
</Table.Row>
<Table.Row>
<Table.Cell>
<Chip head>--bui-gray-2</Chip>
</Table.Cell>
<Table.Cell>You can use these mostly for backgrounds colors.</Table.Cell>
</Table.Row>
<Table.Row>
<Table.Cell>
<Chip head>--bui-gray-3</Chip>
</Table.Cell>
<Table.Cell>You can use these mostly for backgrounds colors.</Table.Cell>
</Table.Row>
<Table.Row>
<Table.Cell>
<Chip head>--bui-gray-4</Chip>
</Table.Cell>
<Table.Cell>You can use these mostly for backgrounds colors.</Table.Cell>
</Table.Row>
<Table.Row>
<Table.Cell>
<Chip head>--bui-gray-5</Chip>
</Table.Cell>
<Table.Cell>You can use these mostly for backgrounds colors.</Table.Cell>
</Table.Row>
<Table.Row>
<Table.Cell>
<Chip head>--bui-gray-6</Chip>
</Table.Cell>
<Table.Cell>You can use these mostly for backgrounds colors.</Table.Cell>
</Table.Row>
<Table.Row>
<Table.Cell>
<Chip head>--bui-gray-7</Chip>
</Table.Cell>
<Table.Cell>You can use these mostly for backgrounds colors.</Table.Cell>
</Table.Row>
<Table.Row>
<Table.Cell>
<Chip head>--bui-gray-8</Chip>
</Table.Cell>
<Table.Cell>You can use these mostly for backgrounds colors.</Table.Cell>
</Table.Row>
</Table.Body>
</Table.Root>
## Core background colors
## Neutral background colors
These colors are used for the background of your application. We are mostly using for now a
single elevated background for panels. `--bui-bg-surface-0` should mostly use as the main background
color of your app.
These colors form a layered neutral scale for your application backgrounds.
`--bui-bg-neutral-0` is the base background color of your app. Each subsequent level
(1 through 4) represents an elevated layer on top of the previous one, with hover,
pressed, and disabled variants for interactive states.
<Table.Root>
<Table.Header>
@@ -200,22 +151,129 @@ color of your app.
<Table.Body>
<Table.Row>
<Table.Cell>
<Chip head>--bui-bg-surface-0</Chip>
<Chip head>--bui-bg-neutral-0</Chip>
</Table.Cell>
<Table.Cell>
The base background color of your Backstage instance.
</Table.Cell>
<Table.Cell>The background color of your Backstage instance.</Table.Cell>
</Table.Row>
<Table.Row>
<Table.Cell>
<Chip head>--bui-bg-surface-1</Chip>
<Chip head>--bui-bg-neutral-1</Chip>
</Table.Cell>
<Table.Cell>
First elevated layer. Use for cards, dialogs, and panels.
</Table.Cell>
<Table.Cell>Use for any panels or elevated surfaces.</Table.Cell>
</Table.Row>
<Table.Row>
<Table.Cell>
<Chip head>--bui-bg-surface-2</Chip>
<Chip head>--bui-bg-neutral-1-hover</Chip>
</Table.Cell>
<Table.Cell>Use for any panels or elevated surfaces.</Table.Cell>
<Table.Cell>Hover state for elements on neutral-1.</Table.Cell>
</Table.Row>
<Table.Row>
<Table.Cell>
<Chip head>--bui-bg-neutral-1-pressed</Chip>
</Table.Cell>
<Table.Cell>Pressed state for elements on neutral-1.</Table.Cell>
</Table.Row>
<Table.Row>
<Table.Cell>
<Chip head>--bui-bg-neutral-1-disabled</Chip>
</Table.Cell>
<Table.Cell>Disabled state for elements on neutral-1.</Table.Cell>
</Table.Row>
<Table.Row>
<Table.Cell>
<Chip head>--bui-bg-neutral-2</Chip>
</Table.Cell>
<Table.Cell>
Second elevated layer. Use for elements on top of neutral-1.
</Table.Cell>
</Table.Row>
<Table.Row>
<Table.Cell>
<Chip head>--bui-bg-neutral-2-hover</Chip>
</Table.Cell>
<Table.Cell>Hover state for elements on neutral-2.</Table.Cell>
</Table.Row>
<Table.Row>
<Table.Cell>
<Chip head>--bui-bg-neutral-2-pressed</Chip>
</Table.Cell>
<Table.Cell>Pressed state for elements on neutral-2.</Table.Cell>
</Table.Row>
<Table.Row>
<Table.Cell>
<Chip head>--bui-bg-neutral-2-disabled</Chip>
</Table.Cell>
<Table.Cell>Disabled state for elements on neutral-2.</Table.Cell>
</Table.Row>
<Table.Row>
<Table.Cell>
<Chip head>--bui-bg-neutral-3</Chip>
</Table.Cell>
<Table.Cell>
Third elevated layer. Use for elements on top of neutral-2.
</Table.Cell>
</Table.Row>
<Table.Row>
<Table.Cell>
<Chip head>--bui-bg-neutral-3-hover</Chip>
</Table.Cell>
<Table.Cell>Hover state for elements on neutral-3.</Table.Cell>
</Table.Row>
<Table.Row>
<Table.Cell>
<Chip head>--bui-bg-neutral-3-pressed</Chip>
</Table.Cell>
<Table.Cell>Pressed state for elements on neutral-3.</Table.Cell>
</Table.Row>
<Table.Row>
<Table.Cell>
<Chip head>--bui-bg-neutral-3-disabled</Chip>
</Table.Cell>
<Table.Cell>Disabled state for elements on neutral-3.</Table.Cell>
</Table.Row>
<Table.Row>
<Table.Cell>
<Chip head>--bui-bg-neutral-4</Chip>
</Table.Cell>
<Table.Cell>
Fourth elevated layer. Use for elements on top of neutral-3.
</Table.Cell>
</Table.Row>
<Table.Row>
<Table.Cell>
<Chip head>--bui-bg-neutral-4-hover</Chip>
</Table.Cell>
<Table.Cell>Hover state for elements on neutral-4.</Table.Cell>
</Table.Row>
<Table.Row>
<Table.Cell>
<Chip head>--bui-bg-neutral-4-pressed</Chip>
</Table.Cell>
<Table.Cell>Pressed state for elements on neutral-4.</Table.Cell>
</Table.Row>
<Table.Row>
<Table.Cell>
<Chip head>--bui-bg-neutral-4-disabled</Chip>
</Table.Cell>
<Table.Cell>Disabled state for elements on neutral-4.</Table.Cell>
</Table.Row>
</Table.Body>
</Table.Root>
## Solid background colors
<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-solid</Chip>
@@ -240,6 +298,19 @@ color of your app.
</Table.Cell>
<Table.Cell>Used for solid background colors when disabled.</Table.Cell>
</Table.Row>
</Table.Body>
</Table.Root>
## Status background colors
<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-danger</Chip>
@@ -393,7 +464,7 @@ low contrast to help as a separator with the different background colors.
<Table.Cell>
<Chip head>--bui-border</Chip>
</Table.Cell>
<Table.Cell>It should be used on top of `--bui-bg-surface-1`.</Table.Cell>
<Table.Cell>It should be used on top of `--bui-bg-neutral-1`.</Table.Cell>
</Table.Row>
<Table.Row>
<Table.Cell>
@@ -7,7 +7,7 @@
.preview {
border-radius: 8px;
box-shadow: inset 0 0 0 1px var(--border);
background-color: var(--bui-bg-surface-0);
background-color: var(--bui-bg-neutral-0);
padding: 1px;
position: relative;
}
@@ -90,7 +90,7 @@
.sideBySidePreview {
border-radius: 8px;
box-shadow: inset 0 0 0 1px var(--border);
background-color: var(--bui-bg-surface-0);
background-color: var(--bui-bg-neutral-0);
padding: 1px;
min-width: 0;
display: flex;
+39 -61
View File
@@ -41,45 +41,34 @@
--bui-radius-full: 9999px;
--bui-black: #000;
--bui-white: #fff;
--bui-gray-1: #f8f8f8;
--bui-gray-2: #ececec;
--bui-gray-3: #d9d9d9;
--bui-gray-4: #c1c1c1;
--bui-gray-5: #9e9e9e;
--bui-gray-6: #8c8c8c;
--bui-gray-7: #757575;
--bui-gray-8: #595959;
--bui-bg-surface-0: var(--bui-gray-1);
--bui-bg-surface-1: var(--bui-white);
--bui-bg-surface-2: var(--bui-gray-1);
--bui-bg-surface-3: var(--bui-gray-2);
--bui-bg-solid: #1f5493;
--bui-bg-solid-hover: #163a66;
--bui-bg-solid-pressed: #0f2b4e;
--bui-bg-solid-disabled: #163a66;
--bui-bg-neutral-on-surface-0: oklch(0% 0 0/0.06);
--bui-bg-neutral-on-surface-0-hover: oklch(0% 0 0/0.12);
--bui-bg-neutral-on-surface-0-pressed: oklch(0% 0 0/0.16);
--bui-bg-neutral-on-surface-0-disabled: oklch(0% 0 0/0.06);
--bui-bg-neutral-on-surface-1: oklch(0% 0 0/0.06);
--bui-bg-neutral-on-surface-1-hover: oklch(0% 0 0/0.12);
--bui-bg-neutral-on-surface-1-pressed: oklch(0% 0 0/0.16);
--bui-bg-neutral-on-surface-1-disabled: oklch(0% 0 0/0.06);
--bui-bg-neutral-on-surface-2: oklch(0% 0 0/0.06);
--bui-bg-neutral-on-surface-2-hover: oklch(0% 0 0/0.12);
--bui-bg-neutral-on-surface-2-pressed: oklch(0% 0 0/0.16);
--bui-bg-neutral-on-surface-2-disabled: oklch(0% 0 0/0.06);
--bui-bg-neutral-on-surface-3: oklch(0% 0 0/0.06);
--bui-bg-neutral-on-surface-3-hover: oklch(0% 0 0/0.12);
--bui-bg-neutral-on-surface-3-pressed: oklch(0% 0 0/0.16);
--bui-bg-neutral-on-surface-3-disabled: oklch(0% 0 0/0.06);
--bui-bg-neutral-0: #f8f8f8;
--bui-bg-neutral-1: #fff;
--bui-bg-neutral-1-hover: oklch(0% 0 0/0.12);
--bui-bg-neutral-1-pressed: oklch(0% 0 0/0.16);
--bui-bg-neutral-1-disabled: oklch(0% 0 0/0.06);
--bui-bg-neutral-2: oklch(0% 0 0/0.06);
--bui-bg-neutral-2-hover: oklch(0% 0 0/0.12);
--bui-bg-neutral-2-pressed: oklch(0% 0 0/0.16);
--bui-bg-neutral-2-disabled: oklch(0% 0 0/0.06);
--bui-bg-neutral-3: oklch(0% 0 0/0.06);
--bui-bg-neutral-3-hover: oklch(0% 0 0/0.12);
--bui-bg-neutral-3-pressed: oklch(0% 0 0/0.16);
--bui-bg-neutral-3-disabled: oklch(0% 0 0/0.06);
--bui-bg-neutral-4: oklch(0% 0 0/0.06);
--bui-bg-neutral-4-hover: oklch(0% 0 0/0.12);
--bui-bg-neutral-4-pressed: oklch(0% 0 0/0.16);
--bui-bg-neutral-4-disabled: oklch(0% 0 0/0.06);
--bui-bg-danger: #ffe2e2;
--bui-bg-warning: #ffedd5;
--bui-bg-success: #dcfce7;
--bui-bg-info: #dbeafe;
--bui-fg-primary: var(--bui-black);
--bui-fg-secondary: var(--bui-gray-7);
--bui-fg-disabled: #9e9e9e;
--bui-fg-secondary: oklch(0% 0 0/0.5);
--bui-fg-disabled: oklch(0% 0 0/0.28);
--bui-fg-solid: var(--bui-white);
--bui-fg-solid-disabled: #98a8bc;
--bui-fg-danger-on-bg: #991919;
@@ -105,45 +94,34 @@
--bui-animate-pulse: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
}
[data-theme-mode='dark'] {
--bui-gray-1: #191919;
--bui-gray-2: #242424;
--bui-gray-3: #373737;
--bui-gray-4: #464646;
--bui-gray-5: #575757;
--bui-gray-6: #7b7b7b;
--bui-gray-7: #9e9e9e;
--bui-gray-8: #b4b4b4;
--bui-bg-surface-0: #333;
--bui-bg-surface-1: var(--bui-gray-1);
--bui-bg-surface-2: var(--bui-gray-2);
--bui-bg-surface-3: var(--bui-gray-3);
--bui-bg-solid: #9cc9ff;
--bui-bg-solid-hover: #83b9fd;
--bui-bg-solid-pressed: #83b9fd;
--bui-bg-solid-disabled: #1b3d68;
--bui-bg-neutral-on-surface-0: oklch(100% 0 0/0.1);
--bui-bg-neutral-on-surface-0-hover: oklch(100% 0 0/0.14);
--bui-bg-neutral-on-surface-0-pressed: oklch(100% 0 0/0.2);
--bui-bg-neutral-on-surface-0-disabled: oklch(100% 0 0/0.1);
--bui-bg-neutral-on-surface-1: oklch(100% 0 0/0.06);
--bui-bg-neutral-on-surface-1-hover: oklch(100% 0 0/0.1);
--bui-bg-neutral-on-surface-1-pressed: oklch(100% 0 0/0.16);
--bui-bg-neutral-on-surface-1-disabled: oklch(100% 0 0/0.06);
--bui-bg-neutral-on-surface-2: oklch(100% 0 0/0.08);
--bui-bg-neutral-on-surface-2-hover: oklch(100% 0 0/0.12);
--bui-bg-neutral-on-surface-2-pressed: oklch(100% 0 0/0.2);
--bui-bg-neutral-on-surface-2-disabled: oklch(100% 0 0/0.08);
--bui-bg-neutral-on-surface-3: oklch(100% 0 0/0.08);
--bui-bg-neutral-on-surface-3-hover: oklch(100% 0 0/0.12);
--bui-bg-neutral-on-surface-3-pressed: oklch(100% 0 0/0.2);
--bui-bg-neutral-on-surface-3-disabled: oklch(100% 0 0/0.08);
--bui-bg-neutral-0: #333;
--bui-bg-neutral-1: oklch(100% 0 0/0.1);
--bui-bg-neutral-1-hover: oklch(100% 0 0/0.14);
--bui-bg-neutral-1-pressed: oklch(100% 0 0/0.2);
--bui-bg-neutral-1-disabled: oklch(100% 0 0/0.1);
--bui-bg-neutral-2: oklch(100% 0 0/0.06);
--bui-bg-neutral-2-hover: oklch(100% 0 0/0.1);
--bui-bg-neutral-2-pressed: oklch(100% 0 0/0.16);
--bui-bg-neutral-2-disabled: oklch(100% 0 0/0.06);
--bui-bg-neutral-3: oklch(100% 0 0/0.08);
--bui-bg-neutral-3-hover: oklch(100% 0 0/0.12);
--bui-bg-neutral-3-pressed: oklch(100% 0 0/0.2);
--bui-bg-neutral-3-disabled: oklch(100% 0 0/0.08);
--bui-bg-neutral-4: oklch(100% 0 0/0.08);
--bui-bg-neutral-4-hover: oklch(100% 0 0/0.12);
--bui-bg-neutral-4-pressed: oklch(100% 0 0/0.2);
--bui-bg-neutral-4-disabled: oklch(100% 0 0/0.08);
--bui-bg-danger: #300c0c;
--bui-bg-warning: #302008;
--bui-bg-success: #042713;
--bui-bg-info: #132049;
--bui-fg-primary: var(--bui-white);
--bui-fg-secondary: var(--bui-gray-7);
--bui-fg-disabled: var(--bui-gray-7);
--bui-fg-secondary: oklch(0% 0 0/0.5);
--bui-fg-disabled: oklch(0% 0 0/0.28);
--bui-fg-solid: #101821;
--bui-fg-solid-disabled: #6191cc;
--bui-fg-danger-on-bg: #fca5a5;
@@ -265,7 +243,7 @@
}
}
body {
background-color: var(--bui-bg-surface-0);
background-color: var(--bui-bg-neutral-0);
color: var(--bui-fg-primary);
font-family: var(--bui-font-regular);
font-weight: var(--bui-font-weight-regular);
+6 -6
View File
@@ -195,10 +195,10 @@
--bui-bg-solid-pressed: #1abc54;
--bui-bg-solid-disabled: #0f6c30;
--bui-fg-primary: var(--bui-black);
--bui-fg-secondary: var(--bui-gray-7);
--bui-fg-secondary: #757575;
--bui-fg-solid: var(--bui-black);
--bui-fg-solid-disabled: #62ab7c;
--bui-border: var(--bui-gray-3);
--bui-border: #d9d9d9;
--bui-border-hover: #0000004d;
--bui-border-pressed: #00000080;
--bui-border-disabled: #0000001a;
@@ -212,7 +212,7 @@
}
}
[data-theme-mode='dark'][data-theme-name='spotify'] {
--bui-bg-surface-0: var(--bui-black);
--bui-bg-neutral-0: var(--bui-black);
--bui-bg-solid: #1ed760;
--bui-bg-solid-hover: #3be477;
--bui-bg-solid-pressed: #1abc54;
@@ -221,14 +221,14 @@
--bui-bg-warning: #302008;
--bui-bg-success: #132d21;
--bui-fg-primary: var(--bui-white);
--bui-fg-secondary: var(--bui-gray-7);
--bui-fg-disabled: var(--bui-gray-5);
--bui-fg-secondary: #9e9e9e;
--bui-fg-disabled: #575757;
--bui-fg-solid: var(--bui-black);
--bui-fg-solid-disabled: #072f15;
--bui-fg-danger: #e22b2b;
--bui-fg-warning: #e36d05;
--bui-fg-success: #1db954;
--bui-border: var(--bui-gray-3);
--bui-border: #373737;
--bui-border-hover: #fff6;
--bui-border-pressed: #ffffff80;
--bui-border-disabled: #fff3;
+4 -4
View File
@@ -4,8 +4,8 @@ export const customTheme = `:root {
--bui-font-regular: system-ui;
--bui-font-weight-regular: 400;
--bui-font-weight-bold: 600;
--bui-bg-surface-0: #f8f8f8;
--bui-bg-surface-1: #fff;
--bui-bg-neutral-0: #f8f8f8;
--bui-bg-neutral-1: #fff;
/* ... other CSS variables */
/* Add your custom components styles here */
@@ -19,8 +19,8 @@ export const customTheme = `:root {
--bui-font-regular: system-ui;
--bui-font-weight-regular: 400;
--bui-font-weight-bold: 600;
--bui-bg-surface-0: #f8f8f8;
--bui-bg-surface-1: #fff;
--bui-bg-neutral-0: #f8f8f8;
--bui-bg-neutral-1: #fff;
/* ... other CSS variables */
/* Add your custom components styles here */
@@ -48,7 +48,7 @@ benefits. A few are:
## Decision
We will stop using default exports except when absolutely necessary (such as
[`React.lazy`](https://reactjs.org/docs/code-splitting.html#reactlazy) modules).
[`React.lazy`](https://18.react.dev/reference/react/lazy) modules).
A workaround exists for those that would prefer to never use `default`:
```ts
+48 -35
View File
@@ -103,13 +103,13 @@ Backstage UI is using light by default under `:root` but you can target it more
[data-theme-mode='light'] {
/* Light theme specific styles */
  --bui-bg-surface-0: #f8f8f8;
  --bui-bg-neutral-0: #f8f8f8;
--bui-fg-primary: #000;
}
[data-theme-mode='dark'] {
/* Dark theme specific styles */
  --bui-bg-surface-0: #333333;
  --bui-bg-neutral-0: #333333;
--bui-fg-primary: #fff;
}
```
@@ -124,9 +124,9 @@ And if youd like to go even further, you can target specific component class
| Token Name | Description |
| -------------------- | --------------------------------------------------------------------------------------------- |
| `--bui-bg-surface-0` | This is used to define the background color of your app. It will only be used once. |
| `--bui-bg-surface-1` | We ar using this color to sit on top of `--bui-bg-surface-0` mostly for `Card`, `Dialog`, ... |
| `--bui-bg-surface-2` | This is for content inside elevated components. This colour is less common. |
| `--bui-bg-neutral-0` | This is used to define the background color of your app. It will only be used once. |
| `--bui-bg-neutral-1` | We ar using this color to sit on top of `--bui-bg-neutral-0` mostly for `Card`, `Dialog`, ... |
| `--bui-bg-neutral-2` | This is for content inside elevated components. This colour is less common. |
| `--bui-bg-solid` | This is used for main actions like primary buttons. |
| `--bui-fg-solid` | This is for texts or icons on top of a solid backgrounds. |
| `--bui-fg-primary` | Your primary text or icon colours. |
@@ -143,39 +143,52 @@ And if youd like to go even further, you can target specific component class
#### Base colors
These colors are used for special purposes like ring, scrollbar, ...
| Token Name | Description |
| ------------- | ----------------------------------------------------------------------- |
| `--bui-black` | Pure black color. This one should be the same in light and dark themes. |
| `--bui-white` | Pure white color. This one should be the same in light and dark themes. |
| Token Name | Description |
| -------------- | ----------------------------------------------------------------------- |
| `--bui-black` | Pure black color. This one should be the same in light and dark themes. |
| `--bui-white` | Pure white color. This one should be the same in light and dark themes. |
| `--bui-gray-1` | You can use these mostly for backgrounds colors. |
| `--bui-gray-2` | You can use these mostly for backgrounds colors. |
| `--bui-gray-3` | You can use these mostly for backgrounds colors. |
| `--bui-gray-4` | You can use these mostly for backgrounds colors. |
| `--bui-gray-5` | You can use these mostly for backgrounds colors. |
| `--bui-gray-6` | You can use these mostly for backgrounds colors. |
| `--bui-gray-7` | You can use these mostly for backgrounds colors. |
| `--bui-gray-8` | You can use these mostly for backgrounds colors. |
#### Neutral background colors
#### Core background colors
These colors form a layered neutral scale for your application backgrounds. `--bui-bg-neutral-0` is the base background color. Each subsequent level (1 through 4) represents an elevated layer, with hover, pressed, and disabled variants for interactive states.
These colors are used for the background of your application. We are mostly using for now a single elevated background for panels. `--bui-bg-surface-0` should mostly use as the main background color of your app.
| Token Name | Description |
| ----------------------------- | ------------------------------------------------------------ |
| `--bui-bg-neutral-0` | The base background color of your Backstage instance. |
| `--bui-bg-neutral-1` | First elevated layer. Use for cards, dialogs, and panels. |
| `--bui-bg-neutral-1-hover` | Hover state for elements on neutral-1. |
| `--bui-bg-neutral-1-pressed` | Pressed state for elements on neutral-1. |
| `--bui-bg-neutral-1-disabled` | Disabled state for elements on neutral-1. |
| `--bui-bg-neutral-2` | Second elevated layer. Use for elements on top of neutral-1. |
| `--bui-bg-neutral-2-hover` | Hover state for elements on neutral-2. |
| `--bui-bg-neutral-2-pressed` | Pressed state for elements on neutral-2. |
| `--bui-bg-neutral-2-disabled` | Disabled state for elements on neutral-2. |
| `--bui-bg-neutral-3` | Third elevated layer. Use for elements on top of neutral-2. |
| `--bui-bg-neutral-3-hover` | Hover state for elements on neutral-3. |
| `--bui-bg-neutral-3-pressed` | Pressed state for elements on neutral-3. |
| `--bui-bg-neutral-3-disabled` | Disabled state for elements on neutral-3. |
| `--bui-bg-neutral-4` | Fourth elevated layer. Use for elements on top of neutral-3. |
| `--bui-bg-neutral-4-hover` | Hover state for elements on neutral-4. |
| `--bui-bg-neutral-4-pressed` | Pressed state for elements on neutral-4. |
| `--bui-bg-neutral-4-disabled` | Disabled state for elements on neutral-4. |
| Token Name | Description |
| ------------------------- | ------------------------------------------------ |
| `--bui-bg-surface-0` | The background color of your Backstage instance. |
| `--bui-bg-surface-1` | Use for any panels or elevated surfaces. |
| `--bui-bg-surface-2` | Use for any panels or elevated surfaces. |
| `--bui-bg-surface-3` | Use for any panels or elevated surfaces. |
| `--bui-bg-solid` | Used for solid background colors. |
| `--bui-bg-solid-hover` | Used for solid background colors when hovered. |
| `--bui-bg-solid-pressed` | Used for solid background colors when pressed. |
| `--bui-bg-solid-disabled` | Used for solid background colors when disabled. |
| `--bui-bg-danger` | Used to show errors information. |
| `--bui-bg-warning` | Used to show warnings information. |
| `--bui-bg-success` | Used to show success information. |
| `--bui-bg-info` | Used to show informational content. |
#### Solid background colors
| Token Name | Description |
| ------------------------- | ----------------------------------------------- |
| `--bui-bg-solid` | Used for solid background colors. |
| `--bui-bg-solid-hover` | Used for solid background colors when hovered. |
| `--bui-bg-solid-pressed` | Used for solid background colors when pressed. |
| `--bui-bg-solid-disabled` | Used for solid background colors when disabled. |
#### Status background colors
| Token Name | Description |
| ------------------ | ----------------------------------- |
| `--bui-bg-danger` | Used to show errors information. |
| `--bui-bg-warning` | Used to show warnings information. |
| `--bui-bg-success` | Used to show success information. |
| `--bui-bg-info` | Used to show informational content. |
#### Foreground colors
@@ -202,7 +215,7 @@ These border colors are mostly meant to be used as borders on top of any compone
| Token Name | Description |
| ----------------------- | --------------------------------------------------- |
| `--bui-border` | It should be used on top of `--bui-bg-surface-1`. |
| `--bui-border` | It should be used on top of `--bui-bg-neutral-1`. |
| `--bui-border-hover` | Used when the component is interactive and hovered. |
| `--bui-border-pressed` | Used when the component is interactive and hovered. |
| `--bui-border-disabled` | Used when the component is disabled. |
@@ -45,7 +45,7 @@ export const MyPluginEntityContent = () => {
```
Internally `useEntity` makes use of
[react `Context`s](https://reactjs.org/docs/context.html). The entity context is
[react `Contexts`](https://18.react.dev/learn/passing-data-deeply-with-context). The entity context is
provided by the entity page into which your plugin will be embedded.
### Import your plugin and embed in the entities page
@@ -63,7 +63,7 @@ To add your component to the Entity view, you will need to modify the
your plugin, you may only care about certain kinds of
[entities](https://backstage.io/docs/features/software-catalog/descriptor-format),
each of which has its own
[element](https://reactjs.org/docs/rendering-elements.html) for rendering. This
element for rendering. This
functionality is handled by the `EntitySwitch` component:
```tsx
+39 -61
View File
@@ -43,45 +43,34 @@
--bui-radius-full: 9999px;
--bui-black: #000;
--bui-white: #fff;
--bui-gray-1: #f8f8f8;
--bui-gray-2: #ececec;
--bui-gray-3: #d9d9d9;
--bui-gray-4: #c1c1c1;
--bui-gray-5: #9e9e9e;
--bui-gray-6: #8c8c8c;
--bui-gray-7: #757575;
--bui-gray-8: #595959;
--bui-bg-surface-0: var(--bui-gray-1);
--bui-bg-surface-1: var(--bui-white);
--bui-bg-surface-2: var(--bui-gray-1);
--bui-bg-surface-3: var(--bui-gray-2);
--bui-bg-solid: #1f5493;
--bui-bg-solid-hover: #163a66;
--bui-bg-solid-pressed: #0f2b4e;
--bui-bg-solid-disabled: #163a66;
--bui-bg-neutral-on-surface-0: oklch(0% 0 0 / .06);
--bui-bg-neutral-on-surface-0-hover: oklch(0% 0 0 / .12);
--bui-bg-neutral-on-surface-0-pressed: oklch(0% 0 0 / .16);
--bui-bg-neutral-on-surface-0-disabled: oklch(0% 0 0 / .06);
--bui-bg-neutral-on-surface-1: oklch(0% 0 0 / .06);
--bui-bg-neutral-on-surface-1-hover: oklch(0% 0 0 / .12);
--bui-bg-neutral-on-surface-1-pressed: oklch(0% 0 0 / .16);
--bui-bg-neutral-on-surface-1-disabled: oklch(0% 0 0 / .06);
--bui-bg-neutral-on-surface-2: oklch(0% 0 0 / .06);
--bui-bg-neutral-on-surface-2-hover: oklch(0% 0 0 / .12);
--bui-bg-neutral-on-surface-2-pressed: oklch(0% 0 0 / .16);
--bui-bg-neutral-on-surface-2-disabled: oklch(0% 0 0 / .06);
--bui-bg-neutral-on-surface-3: oklch(0% 0 0 / .06);
--bui-bg-neutral-on-surface-3-hover: oklch(0% 0 0 / .12);
--bui-bg-neutral-on-surface-3-pressed: oklch(0% 0 0 / .16);
--bui-bg-neutral-on-surface-3-disabled: oklch(0% 0 0 / .06);
--bui-bg-neutral-0: #f8f8f8;
--bui-bg-neutral-1: #fff;
--bui-bg-neutral-1-hover: oklch(0% 0 0 / .12);
--bui-bg-neutral-1-pressed: oklch(0% 0 0 / .16);
--bui-bg-neutral-1-disabled: oklch(0% 0 0 / .06);
--bui-bg-neutral-2: oklch(0% 0 0 / .06);
--bui-bg-neutral-2-hover: oklch(0% 0 0 / .12);
--bui-bg-neutral-2-pressed: oklch(0% 0 0 / .16);
--bui-bg-neutral-2-disabled: oklch(0% 0 0 / .06);
--bui-bg-neutral-3: oklch(0% 0 0 / .06);
--bui-bg-neutral-3-hover: oklch(0% 0 0 / .12);
--bui-bg-neutral-3-pressed: oklch(0% 0 0 / .16);
--bui-bg-neutral-3-disabled: oklch(0% 0 0 / .06);
--bui-bg-neutral-4: oklch(0% 0 0 / .06);
--bui-bg-neutral-4-hover: oklch(0% 0 0 / .12);
--bui-bg-neutral-4-pressed: oklch(0% 0 0 / .16);
--bui-bg-neutral-4-disabled: oklch(0% 0 0 / .06);
--bui-bg-danger: #ffe2e2;
--bui-bg-warning: #ffedd5;
--bui-bg-success: #dcfce7;
--bui-bg-info: #dbeafe;
--bui-fg-primary: var(--bui-black);
--bui-fg-secondary: var(--bui-gray-7);
--bui-fg-disabled: #9e9e9e;
--bui-fg-secondary: oklch(0% 0 0 / .5);
--bui-fg-disabled: oklch(0% 0 0 / .28);
--bui-fg-solid: var(--bui-white);
--bui-fg-solid-disabled: #98a8bc;
--bui-fg-danger-on-bg: #991919;
@@ -108,45 +97,34 @@
}
[data-theme-mode="dark"] {
--bui-gray-1: #191919;
--bui-gray-2: #242424;
--bui-gray-3: #373737;
--bui-gray-4: #464646;
--bui-gray-5: #575757;
--bui-gray-6: #7b7b7b;
--bui-gray-7: #9e9e9e;
--bui-gray-8: #b4b4b4;
--bui-bg-surface-0: #333;
--bui-bg-surface-1: var(--bui-gray-1);
--bui-bg-surface-2: var(--bui-gray-2);
--bui-bg-surface-3: var(--bui-gray-3);
--bui-bg-solid: #9cc9ff;
--bui-bg-solid-hover: #83b9fd;
--bui-bg-solid-pressed: #83b9fd;
--bui-bg-solid-disabled: #1b3d68;
--bui-bg-neutral-on-surface-0: oklch(100% 0 0 / .1);
--bui-bg-neutral-on-surface-0-hover: oklch(100% 0 0 / .14);
--bui-bg-neutral-on-surface-0-pressed: oklch(100% 0 0 / .2);
--bui-bg-neutral-on-surface-0-disabled: oklch(100% 0 0 / .1);
--bui-bg-neutral-on-surface-1: oklch(100% 0 0 / .06);
--bui-bg-neutral-on-surface-1-hover: oklch(100% 0 0 / .1);
--bui-bg-neutral-on-surface-1-pressed: oklch(100% 0 0 / .16);
--bui-bg-neutral-on-surface-1-disabled: oklch(100% 0 0 / .06);
--bui-bg-neutral-on-surface-2: oklch(100% 0 0 / .08);
--bui-bg-neutral-on-surface-2-hover: oklch(100% 0 0 / .12);
--bui-bg-neutral-on-surface-2-pressed: oklch(100% 0 0 / .2);
--bui-bg-neutral-on-surface-2-disabled: oklch(100% 0 0 / .08);
--bui-bg-neutral-on-surface-3: oklch(100% 0 0 / .08);
--bui-bg-neutral-on-surface-3-hover: oklch(100% 0 0 / .12);
--bui-bg-neutral-on-surface-3-pressed: oklch(100% 0 0 / .2);
--bui-bg-neutral-on-surface-3-disabled: oklch(100% 0 0 / .08);
--bui-bg-neutral-0: #333;
--bui-bg-neutral-1: oklch(100% 0 0 / .1);
--bui-bg-neutral-1-hover: oklch(100% 0 0 / .14);
--bui-bg-neutral-1-pressed: oklch(100% 0 0 / .2);
--bui-bg-neutral-1-disabled: oklch(100% 0 0 / .1);
--bui-bg-neutral-2: oklch(100% 0 0 / .06);
--bui-bg-neutral-2-hover: oklch(100% 0 0 / .1);
--bui-bg-neutral-2-pressed: oklch(100% 0 0 / .16);
--bui-bg-neutral-2-disabled: oklch(100% 0 0 / .06);
--bui-bg-neutral-3: oklch(100% 0 0 / .08);
--bui-bg-neutral-3-hover: oklch(100% 0 0 / .12);
--bui-bg-neutral-3-pressed: oklch(100% 0 0 / .2);
--bui-bg-neutral-3-disabled: oklch(100% 0 0 / .08);
--bui-bg-neutral-4: oklch(100% 0 0 / .08);
--bui-bg-neutral-4-hover: oklch(100% 0 0 / .12);
--bui-bg-neutral-4-pressed: oklch(100% 0 0 / .2);
--bui-bg-neutral-4-disabled: oklch(100% 0 0 / .08);
--bui-bg-danger: #300c0c;
--bui-bg-warning: #302008;
--bui-bg-success: #042713;
--bui-bg-info: #132049;
--bui-fg-primary: var(--bui-white);
--bui-fg-secondary: var(--bui-gray-7);
--bui-fg-disabled: var(--bui-gray-7);
--bui-fg-secondary: oklch(0% 0 0 / .5);
--bui-fg-disabled: oklch(0% 0 0 / .28);
--bui-fg-solid: #101821;
--bui-fg-solid-disabled: #6191cc;
--bui-fg-danger-on-bg: #fca5a5;
@@ -273,7 +251,7 @@
}
body {
background-color: var(--bui-bg-surface-0);
background-color: var(--bui-bg-neutral-0);
color: var(--bui-fg-primary);
font-family: var(--bui-font-regular);
font-weight: var(--bui-font-weight-regular);
@@ -19,7 +19,7 @@
@layer components {
.bui-Accordion {
width: 100%;
background-color: var(--bui-bg-surface-1);
background-color: var(--bui-bg-neutral-1);
border-radius: var(--bui-radius-3);
padding: var(--bui-space-3);
}
@@ -18,7 +18,7 @@
@layer components {
.bui-Alert {
--alert-bg: var(--bui-bg-surface-1);
--alert-bg: var(--bui-bg-neutral-1);
--alert-fg: var(--bui-fg-primary);
display: flex;
@@ -26,7 +26,7 @@
user-select: none;
font-weight: 500;
color: var(--bui-fg-primary);
background-color: var(--bui-bg-surface-2);
background-color: var(--bui-bg-neutral-2);
font-size: 1rem;
line-height: 1;
overflow: hidden;
@@ -24,19 +24,19 @@
}
.bui-Box[data-surface='0'] {
background-color: var(--bui-bg-surface-0);
background-color: var(--bui-bg-neutral-0);
}
.bui-Box[data-surface='1'] {
background-color: var(--bui-bg-surface-1);
background-color: var(--bui-bg-neutral-1);
}
.bui-Box[data-surface='2'] {
background-color: var(--bui-bg-surface-2);
background-color: var(--bui-bg-neutral-2);
}
.bui-Box[data-surface='3'] {
background-color: var(--bui-bg-surface-3);
background-color: var(--bui-bg-neutral-3);
}
.bui-Box[data-surface='danger'] {
@@ -113,27 +113,27 @@
}
.bui-Button[data-variant='secondary'] {
--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);
--bg: var(--bui-bg-neutral-1);
--bg-hover: var(--bui-bg-neutral-1-hover);
--bg-active: var(--bui-bg-neutral-1-pressed);
--fg: var(--bui-fg-primary);
&[data-on-surface='1'] {
--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);
--bg: var(--bui-bg-neutral-2);
--bg-hover: var(--bui-bg-neutral-2-hover);
--bg-active: var(--bui-bg-neutral-2-pressed);
}
&[data-on-surface='2'] {
--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);
--bg: var(--bui-bg-neutral-3);
--bg-hover: var(--bui-bg-neutral-3-hover);
--bg-active: var(--bui-bg-neutral-3-pressed);
}
&[data-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);
--bg: var(--bui-bg-neutral-4);
--bg-hover: var(--bui-bg-neutral-4-hover);
--bg-active: var(--bui-bg-neutral-4-pressed);
}
&[data-disabled='true'],
@@ -178,23 +178,23 @@
}
.bui-Button[data-variant='tertiary'] {
--bg-hover: var(--bui-bg-neutral-on-surface-0-hover);
--bg-active: var(--bui-bg-neutral-on-surface-0-pressed);
--bg-hover: var(--bui-bg-neutral-1-hover);
--bg-active: var(--bui-bg-neutral-1-pressed);
--fg: var(--bui-fg-primary);
&[data-on-surface='1'] {
--bg-hover: var(--bui-bg-neutral-on-surface-1-hover);
--bg-active: var(--bui-bg-neutral-on-surface-1-pressed);
--bg-hover: var(--bui-bg-neutral-2-hover);
--bg-active: var(--bui-bg-neutral-2-pressed);
}
&[data-on-surface='2'] {
--bg-hover: var(--bui-bg-neutral-on-surface-2-hover);
--bg-active: var(--bui-bg-neutral-on-surface-2-pressed);
--bg-hover: var(--bui-bg-neutral-3-hover);
--bg-active: var(--bui-bg-neutral-3-pressed);
}
&[data-on-surface='3'] {
--bg-hover: var(--bui-bg-neutral-on-surface-3-hover);
--bg-active: var(--bui-bg-neutral-on-surface-3-pressed);
--bg-hover: var(--bui-bg-neutral-4-hover);
--bg-active: var(--bui-bg-neutral-4-pressed);
}
&[data-disabled='true'],
@@ -82,7 +82,7 @@ export const Variants = meta.story({
</Flex>
</Flex>
<Flex direction="column" gap="4">
<Text>On Surface 0</Text>
<Text>Neutral 0</Text>
<Flex align="center" surface="0" p="4">
<Button iconStart={<RiCloudLine />} variant="primary">
Button
@@ -105,7 +105,7 @@ export const Variants = meta.story({
</Flex>
</Flex>
<Flex direction="column" gap="4">
<Text>On Surface 1</Text>
<Text>Neutral 1</Text>
<Flex align="center" surface="1" p="4">
<Button iconStart={<RiCloudLine />} variant="primary">
Button
@@ -128,50 +128,64 @@ export const Variants = meta.story({
</Flex>
</Flex>
<Flex direction="column" gap="4">
<Text>On Surface 2</Text>
<Flex align="center" surface="2" p="4">
<Button iconStart={<RiCloudLine />} variant="primary">
Button
</Button>
<Button iconStart={<RiCloudLine />} variant="secondary">
Button
</Button>
<Button iconStart={<RiCloudLine />} variant="tertiary">
Button
</Button>
<Button iconStart={<RiCloudLine />} variant="primary" destructive>
Button
</Button>
<Button iconStart={<RiCloudLine />} variant="secondary" destructive>
Button
</Button>
<Button iconStart={<RiCloudLine />} variant="tertiary" destructive>
Button
</Button>
</Flex>
<Text>Neutral 2</Text>
<Box surface="1">
<Flex align="center" surface="2" p="4">
<Button iconStart={<RiCloudLine />} variant="primary">
Button
</Button>
<Button iconStart={<RiCloudLine />} variant="secondary">
Button
</Button>
<Button iconStart={<RiCloudLine />} variant="tertiary">
Button
</Button>
<Button iconStart={<RiCloudLine />} variant="primary" destructive>
Button
</Button>
<Button iconStart={<RiCloudLine />} variant="secondary" destructive>
Button
</Button>
<Button iconStart={<RiCloudLine />} variant="tertiary" destructive>
Button
</Button>
</Flex>
</Box>
</Flex>
<Flex direction="column" gap="4">
<Text>On Surface 3</Text>
<Flex align="center" surface="3" p="4">
<Button iconStart={<RiCloudLine />} variant="primary">
Button
</Button>
<Button iconStart={<RiCloudLine />} variant="secondary">
Button
</Button>
<Button iconStart={<RiCloudLine />} variant="tertiary">
Button
</Button>
<Button iconStart={<RiCloudLine />} variant="primary" destructive>
Button
</Button>
<Button iconStart={<RiCloudLine />} variant="secondary" destructive>
Button
</Button>
<Button iconStart={<RiCloudLine />} variant="tertiary" destructive>
Button
</Button>
</Flex>
<Text>Neutral 3</Text>
<Box surface="1">
<Box surface="2">
<Flex align="center" surface="3" p="4">
<Button iconStart={<RiCloudLine />} variant="primary">
Button
</Button>
<Button iconStart={<RiCloudLine />} variant="secondary">
Button
</Button>
<Button iconStart={<RiCloudLine />} variant="tertiary">
Button
</Button>
<Button iconStart={<RiCloudLine />} variant="primary" destructive>
Button
</Button>
<Button
iconStart={<RiCloudLine />}
variant="secondary"
destructive
>
Button
</Button>
<Button
iconStart={<RiCloudLine />}
variant="tertiary"
destructive
>
Button
</Button>
</Flex>
</Box>
</Box>
</Flex>
</Flex>
),
@@ -80,27 +80,27 @@
}
.bui-ButtonIcon[data-variant='secondary'] {
--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);
--bg: var(--bui-bg-neutral-1);
--bg-hover: var(--bui-bg-neutral-1-hover);
--bg-active: var(--bui-bg-neutral-1-pressed);
--fg: var(--bui-fg-primary);
&[data-on-surface='1'] {
--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);
--bg: var(--bui-bg-neutral-2);
--bg-hover: var(--bui-bg-neutral-2-hover);
--bg-active: var(--bui-bg-neutral-2-pressed);
}
&[data-on-surface='2'] {
--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);
--bg: var(--bui-bg-neutral-3);
--bg-hover: var(--bui-bg-neutral-3-hover);
--bg-active: var(--bui-bg-neutral-3-pressed);
}
&[data-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);
--bg: var(--bui-bg-neutral-4);
--bg-hover: var(--bui-bg-neutral-4-hover);
--bg-active: var(--bui-bg-neutral-4-pressed);
}
&[data-disabled='true'],
@@ -118,23 +118,23 @@
}
.bui-ButtonIcon[data-variant='tertiary'] {
--bg-hover: var(--bui-bg-neutral-on-surface-0-hover);
--bg-active: var(--bui-bg-neutral-on-surface-0-pressed);
--bg-hover: var(--bui-bg-neutral-1-hover);
--bg-active: var(--bui-bg-neutral-1-pressed);
--fg: var(--bui-fg-primary);
&[data-on-surface='1'] {
--bg-hover: var(--bui-bg-neutral-on-surface-1-hover);
--bg-active: var(--bui-bg-neutral-on-surface-1-pressed);
--bg-hover: var(--bui-bg-neutral-2-hover);
--bg-active: var(--bui-bg-neutral-2-pressed);
}
&[data-on-surface='2'] {
--bg-hover: var(--bui-bg-neutral-on-surface-2-hover);
--bg-active: var(--bui-bg-neutral-on-surface-2-pressed);
--bg-hover: var(--bui-bg-neutral-3-hover);
--bg-active: var(--bui-bg-neutral-3-pressed);
}
&[data-on-surface='3'] {
--bg-hover: var(--bui-bg-neutral-on-surface-3-hover);
--bg-active: var(--bui-bg-neutral-on-surface-3-pressed);
--bg-hover: var(--bui-bg-neutral-4-hover);
--bg-active: var(--bui-bg-neutral-4-pressed);
}
&[data-disabled='true'],
@@ -74,27 +74,27 @@
}
.bui-ButtonLink[data-variant='secondary'] {
--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);
--bg: var(--bui-bg-neutral-1);
--bg-hover: var(--bui-bg-neutral-1-hover);
--bg-active: var(--bui-bg-neutral-1-pressed);
--fg: var(--bui-fg-primary);
&[data-on-surface='1'] {
--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);
--bg: var(--bui-bg-neutral-2);
--bg-hover: var(--bui-bg-neutral-2-hover);
--bg-active: var(--bui-bg-neutral-2-pressed);
}
&[data-on-surface='2'] {
--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);
--bg: var(--bui-bg-neutral-3);
--bg-hover: var(--bui-bg-neutral-3-hover);
--bg-active: var(--bui-bg-neutral-3-pressed);
}
&[data-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);
--bg: var(--bui-bg-neutral-4);
--bg-hover: var(--bui-bg-neutral-4-hover);
--bg-active: var(--bui-bg-neutral-4-pressed);
}
&[data-disabled='true'] {
@@ -111,23 +111,23 @@
}
.bui-ButtonLink[data-variant='tertiary'] {
--bg-hover: var(--bui-bg-neutral-on-surface-0-hover);
--bg-active: var(--bui-bg-neutral-on-surface-0-pressed);
--bg-hover: var(--bui-bg-neutral-1-hover);
--bg-active: var(--bui-bg-neutral-1-pressed);
--fg: var(--bui-fg-primary);
&[data-on-surface='1'] {
--bg-hover: var(--bui-bg-neutral-on-surface-1-hover);
--bg-active: var(--bui-bg-neutral-on-surface-1-pressed);
--bg-hover: var(--bui-bg-neutral-2-hover);
--bg-active: var(--bui-bg-neutral-2-pressed);
}
&[data-on-surface='2'] {
--bg-hover: var(--bui-bg-neutral-on-surface-2-hover);
--bg-active: var(--bui-bg-neutral-on-surface-2-pressed);
--bg-hover: var(--bui-bg-neutral-3-hover);
--bg-active: var(--bui-bg-neutral-3-pressed);
}
&[data-on-surface='3'] {
--bg-hover: var(--bui-bg-neutral-on-surface-3-hover);
--bg-active: var(--bui-bg-neutral-on-surface-3-pressed);
--bg-hover: var(--bui-bg-neutral-4-hover);
--bg-active: var(--bui-bg-neutral-4-pressed);
}
&[data-disabled='true'] {
@@ -21,6 +21,7 @@
display: flex;
flex-direction: column;
gap: var(--bui-space-3);
background-color: var(--bui-bg-neutral-1);
border-radius: var(--bui-radius-3);
padding-block: var(--bui-space-3);
color: var(--bui-fg-primary);
@@ -83,7 +83,7 @@ const ListRow = ({ children }: { children: React.ReactNode }) => {
style={{
height: 40,
width: '100%',
backgroundColor: 'var(--bui-gray-3)',
backgroundColor: 'var(--bui-bg-neutral-3)',
display: 'flex',
alignItems: 'center',
paddingInline: 'var(--bui-space-3)',
@@ -45,7 +45,7 @@
box-shadow: inset 0 0 0 1px var(--bui-border);
border-radius: 2px;
transition: background-color 0.2s ease-in-out;
background-color: var(--bui-bg-surface-1);
background-color: var(--bui-bg-neutral-1);
padding: 0;
flex-shrink: 0;
color: transparent;
@@ -63,7 +63,7 @@
}
.bui-Checkbox[data-indeterminate] & {
background-color: var(--bui-bg-surface-1);
background-color: var(--bui-bg-neutral-1);
box-shadow: inset 0 0 0 1px var(--bui-border);
color: var(--bui-fg-primary);
}
@@ -23,7 +23,7 @@
left: 0;
width: 100%;
height: 100%;
background: color-mix(in srgb, var(--bui-gray-2) 80%, transparent);
background: color-mix(in srgb, var(--bui-bg-neutral-2) 80%, transparent);
display: flex;
align-items: center;
justify-content: center;
@@ -43,7 +43,7 @@
}
.bui-Dialog {
background: var(--bui-bg-surface-1);
background: var(--bui-bg-neutral-1);
border-radius: 0.5rem;
border: 1px solid var(--bui-border);
color: var(--bui-fg-primary);
@@ -25,19 +25,19 @@
}
.bui-Flex[data-surface='0'] {
background-color: var(--bui-bg-surface-0);
background-color: var(--bui-bg-neutral-0);
}
.bui-Flex[data-surface='1'] {
background-color: var(--bui-bg-surface-1);
background-color: var(--bui-bg-neutral-1);
}
.bui-Flex[data-surface='2'] {
background-color: var(--bui-bg-surface-2);
background-color: var(--bui-bg-neutral-2);
}
.bui-Flex[data-surface='3'] {
background-color: var(--bui-bg-surface-3);
background-color: var(--bui-bg-neutral-3);
}
.bui-Flex[data-surface='danger'] {
@@ -23,22 +23,22 @@
.bui-Grid[data-surface='0'],
.bui-GridItem[data-surface='0'] {
background-color: var(--bui-bg-surface-0);
background-color: var(--bui-bg-neutral-0);
}
.bui-Grid[data-surface='1'],
.bui-GridItem[data-surface='1'] {
background-color: var(--bui-bg-surface-1);
background-color: var(--bui-bg-neutral-1);
}
.bui-Grid[data-surface='2'],
.bui-GridItem[data-surface='2'] {
background-color: var(--bui-bg-surface-2);
background-color: var(--bui-bg-neutral-2);
}
.bui-Grid[data-surface='3'],
.bui-GridItem[data-surface='3'] {
background-color: var(--bui-bg-surface-3);
background-color: var(--bui-bg-neutral-3);
}
.bui-Grid[data-surface='danger'],
@@ -27,7 +27,7 @@
left: 0px;
right: 0px;
height: 16px;
background-color: var(--bui-bg-surface-0);
background-color: var(--bui-bg-neutral-0);
z-index: 0;
}
@@ -43,7 +43,7 @@
flex-direction: row;
align-items: center;
justify-content: space-between;
background-color: var(--bui-bg-surface-1);
background-color: var(--bui-bg-neutral-1);
padding-inline: var(--bui-space-5);
border-bottom: 1px solid var(--bui-border);
color: var(--bui-fg-primary);
@@ -93,6 +93,6 @@
margin-bottom: var(--bui-space-4);
padding-inline: var(--bui-space-3);
border-bottom: 1px solid var(--bui-border);
background-color: var(--bui-bg-surface-1);
background-color: var(--bui-bg-neutral-1);
}
}
@@ -23,7 +23,7 @@
box-shadow: var(--bui-shadow);
border: 1px solid var(--bui-border);
border-radius: var(--bui-radius-2);
background: var(--bui-bg-surface-1);
background: var(--bui-bg-neutral-1);
color: var(--bui-fg-primary);
outline: none;
transition: transform 200ms, opacity 200ms;
@@ -70,12 +70,12 @@
display: block;
&[data-focused] .bui-MenuItemWrapper {
background: var(--bui-bg-surface-2);
background: var(--bui-bg-neutral-2);
color: var(--bui-fg-primary);
}
&[data-open] .bui-MenuItemWrapper {
background: var(--bui-bg-surface-2);
background: var(--bui-bg-neutral-2);
color: var(--bui-fg-primary);
}
@@ -114,7 +114,7 @@
display: block;
&:hover .bui-MenuItemWrapper {
background: var(--bui-bg-surface-2);
background: var(--bui-bg-neutral-2);
color: var(--bui-fg-primary);
}
@@ -195,7 +195,7 @@
display: flex;
align-items: center;
border-bottom: 1px solid var(--bui-border);
background-color: var(--bui-bg-surface-1);
background-color: var(--bui-bg-neutral-1);
height: 2rem;
&[data-empty] {
@@ -38,7 +38,7 @@
align-items: center;
border-radius: var(--bui-radius-2);
border: 1px solid var(--bui-border);
background-color: var(--bui-bg-surface-1);
background-color: var(--bui-bg-neutral-1);
transition: border-color 0.2s ease-in-out, outline-color 0.2s ease-in-out;
&[data-size='small'] {
@@ -20,8 +20,8 @@
.bui-Popover {
box-shadow: var(--bui-shadow);
border-radius: var(--bui-radius-3);
background: var(--bui-bg-surface-1);
border: 1px solid var(--bui-gray-3);
background: var(--bui-bg-neutral-1);
border: 1px solid var(--bui-border);
forced-color-adjust: none;
outline: none;
max-height: inherit;
@@ -90,11 +90,11 @@
elements in order to guarantee that the stroke is
always overlaying a consistent color. */
path:nth-child(1) {
fill: var(--bui-bg-surface-1);
fill: var(--bui-bg-neutral-1);
}
path:nth-child(2) {
fill: var(--bui-gray-3);
fill: var(--bui-fg-secondary);
}
/* The arrow svg overlaps the popover by 2px, so we
@@ -123,15 +123,15 @@
}
[data-theme='dark'] .bui-Popover {
background: var(--bui-bg-surface-2);
border: 1px solid var(--bui-gray-4);
background: var(--bui-bg-neutral-2);
border: 1px solid var(--bui-border);
}
[data-theme='dark'] .bui-PopoverArrow svg path:nth-child(1) {
fill: var(--bui-bg-surface-2);
fill: var(--bui-bg-neutral-2);
}
[data-theme='dark'] .bui-PopoverArrow svg path:nth-child(2) {
fill: var(--bui-gray-4);
fill: var(--bui-fg-secondary);
}
}
@@ -51,7 +51,7 @@
height: 1rem;
box-sizing: border-box;
border: 0.125rem solid var(--bui-border);
background: var(--bui-gray-1);
background: var(--bui-bg-neutral-1);
border-radius: var(--bui-radius-full);
transition: all 200ms;
flex-shrink: 0;
@@ -94,7 +94,7 @@
align-items: center;
border-radius: var(--bui-radius-2);
border: 1px solid var(--bui-border);
background-color: var(--bui-bg-surface-1);
background-color: var(--bui-bg-neutral-1);
transition: border-color 0.2s ease-in-out, outline-color 0.2s ease-in-out;
&[data-size='small'] {
@@ -36,7 +36,7 @@
box-sizing: border-box;
border-radius: var(--bui-radius-3);
border: 1px solid var(--bui-border);
background-color: var(--bui-bg-surface-1);
background-color: var(--bui-bg-neutral-1);
display: flex;
justify-content: space-between;
align-items: center;
@@ -160,7 +160,7 @@
inset-block: 0;
inset-inline: var(--bui-space-1);
border-radius: var(--bui-radius-2);
background: var(--bui-bg-surface-2);
background: var(--bui-bg-neutral-2);
z-index: -1;
}
@@ -19,7 +19,7 @@
@layer components {
.bui-Skeleton {
animation: var(--bui-animate-pulse);
background-color: var(--bui-bg-surface-2);
background-color: var(--bui-bg-neutral-2);
border-radius: var(--bui-radius-2);
}
@@ -50,7 +50,7 @@
&[data-pressed] {
.indicator {
background: var(--bui-gray-3);
background: var(--bui-bg-neutral-3);
}
}
}
@@ -65,7 +65,7 @@
width: 2rem;
height: 1.143rem;
border: 2px;
background: var(--bui-gray-3);
background: var(--bui-bg-neutral-3);
border-radius: 1.143rem;
transition: all 200ms;
@@ -86,7 +86,7 @@
top: calc(var(--hovered-tab-top) + 4px);
width: var(--hovered-tab-width);
height: calc(var(--hovered-tab-height) - 8px);
background-color: var(--bui-gray-2);
background-color: var(--bui-bg-neutral-2);
border-radius: 4px;
opacity: var(--hovered-tab-opacity);
transition: left var(--hovered-transition-duration) ease-out,
@@ -25,7 +25,7 @@
.bui-Tag {
color: var(--bui-fg-primary);
background-color: var(--bui-gray-2);
background-color: var(--bui-bg-neutral-2);
border-radius: var(--bui-radius-2);
display: flex;
align-items: center;
@@ -51,7 +51,7 @@
}
.bui-Tag[data-hovered] {
background-color: var(--bui-gray-3);
background-color: var(--bui-bg-neutral-3);
cursor: pointer;
}
@@ -61,7 +61,7 @@
}
.bui-Tag[data-selected] {
box-shadow: inset 0 0 0 1px var(--bui-gray-8);
box-shadow: inset 0 0 0 1px var(--bui-fg-secondary);
}
.bui-Tag[data-disabled] {
@@ -76,7 +76,7 @@
padding: 0 var(--bui-space-3);
border-radius: var(--bui-radius-2);
border: 1px solid var(--bui-border);
background-color: var(--bui-bg-surface-1);
background-color: var(--bui-bg-neutral-1);
font-size: var(--bui-font-size-3);
font-family: var(--bui-font-regular);
font-weight: var(--bui-font-weight-regular);
@@ -25,7 +25,7 @@
gap: var(--bui-space-1_5);
border: none;
border-radius: var(--bui-radius-2);
background: var(--bui-bg-surface-1);
background: var(--bui-bg-neutral-1);
color: var(--bui-fg-primary);
font-family: var(--bui-font-regular);
font-weight: var(--bui-font-weight-bold);
@@ -41,16 +41,16 @@
}
&:not([data-selected])[data-hovered] {
background: var(--bui-bg-surface-2);
background: var(--bui-bg-neutral-2);
}
&[data-disabled] {
background: var(--bui-bg-neutral-on-surface-0-disabled);
background: var(--bui-bg-neutral-1-disabled);
color: var(--bui-fg-disabled);
}
&[data-disabled][data-hovered] {
background: var(--bui-bg-neutral-on-surface-0-disabled);
background: var(--bui-bg-neutral-1-disabled);
}
&[data-disabled][data-selected] {
@@ -20,8 +20,8 @@
.bui-Tooltip {
box-shadow: var(--bui-shadow);
border-radius: 4px;
background: var(--bui-bg-surface-1);
border: 1px solid var(--bui-gray-3);
background: var(--bui-bg-neutral-1);
border: 1px solid var(--bui-border);
forced-color-adjust: none;
outline: none;
padding: var(--bui-space-2) var(--bui-space-3);
@@ -74,11 +74,11 @@
elements in order to guarantee that the stroke is
always overlaying a consistent color. */
path:nth-child(1) {
fill: var(--bui-bg-surface-1);
fill: var(--bui-bg-neutral-1);
}
path:nth-child(2) {
fill: var(--bui-gray-3);
fill: var(--bui-fg-secondary);
}
/* The arrow svg overlaps the tooltip by 2px, so we
@@ -107,16 +107,16 @@
}
[data-theme='dark'] .bui-Tooltip {
background: var(--bui-bg-surface-2);
background: var(--bui-bg-neutral-2);
box-shadow: none;
border: 1px solid var(--bui-gray-4);
border: 1px solid var(--bui-border);
}
[data-theme='dark'] .bui-TooltipArrow svg path:nth-child(1) {
fill: var(--bui-bg-surface-2);
fill: var(--bui-bg-neutral-2);
}
[data-theme='dark'] .bui-TooltipArrow svg path:nth-child(2) {
fill: var(--bui-gray-4);
fill: var(--bui-fg-secondary);
}
}
+152
View File
@@ -0,0 +1,152 @@
/*
* Copyright 2025 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import preview from '../../../../.storybook/preview';
import { Box } from '../components/Box';
import { Flex } from '../components/Flex';
import { Text } from '../components/Text';
const meta = preview.meta({
title: 'Backstage UI/Colors',
});
export const Default = meta.story({
render: () => (
<div style={{ backgroundColor: 'var(--bui-bg-neutral-0)' }}>
<Box p="4" style={{ backgroundColor: 'var(--bui-bg-neutral-1)' }}>
<Flex direction="row" gap="4" align="center">
<Text>Neutral 1</Text>
<Flex
px="2"
py="1"
style={{ backgroundColor: 'var(--bui-bg-neutral-1-hover)' }}
>
<Text>Hover</Text>
</Flex>
<Flex
px="2"
py="1"
style={{ backgroundColor: 'var(--bui-bg-neutral-1-pressed)' }}
>
<Text>Pressed</Text>
</Flex>
<Flex
px="2"
py="1"
style={{ backgroundColor: 'var(--bui-bg-neutral-1-disabled)' }}
>
<Text style={{ color: 'var(--bui-fg-disabled)' }}>Disabled</Text>
</Flex>
</Flex>
<Box
p="4"
mt="4"
style={{ backgroundColor: 'var(--bui-bg-neutral-2)' }}
>
<Flex direction="row" gap="4" align="center">
<Text>Neutral 2</Text>
<Flex
px="2"
py="1"
style={{ backgroundColor: 'var(--bui-bg-neutral-2-hover)' }}
>
<Text>Hover</Text>
</Flex>
<Flex
px="2"
py="1"
style={{ backgroundColor: 'var(--bui-bg-neutral-2-pressed)' }}
>
<Text>Pressed</Text>
</Flex>
<Flex
px="2"
py="1"
style={{ backgroundColor: 'var(--bui-bg-neutral-2-disabled)' }}
>
<Text style={{ color: 'var(--bui-fg-disabled)' }}>Disabled</Text>
</Flex>
</Flex>
<Box
p="4"
mt="4"
style={{ backgroundColor: 'var(--bui-bg-neutral-3)' }}
>
<Flex direction="row" gap="4" align="center">
<Text>Neutral 3</Text>
<Flex
px="2"
py="1"
style={{ backgroundColor: 'var(--bui-bg-neutral-3-hover)' }}
>
<Text>Hover</Text>
</Flex>
<Flex
px="2"
py="1"
style={{ backgroundColor: 'var(--bui-bg-neutral-3-pressed)' }}
>
<Text>Pressed</Text>
</Flex>
<Flex
px="2"
py="1"
style={{ backgroundColor: 'var(--bui-bg-neutral-3-disabled)' }}
>
<Text style={{ color: 'var(--bui-fg-disabled)' }}>
Disabled
</Text>
</Flex>
</Flex>
<Box
p="4"
mt="4"
style={{ backgroundColor: 'var(--bui-bg-neutral-4)' }}
>
<Flex direction="row" gap="4" align="center">
<Text>Neutral 4</Text>
<Flex
px="2"
py="1"
style={{ backgroundColor: 'var(--bui-bg-neutral-4-hover)' }}
>
<Text>Hover</Text>
</Flex>
<Flex
px="2"
py="1"
style={{ backgroundColor: 'var(--bui-bg-neutral-4-pressed)' }}
>
<Text>Pressed</Text>
</Flex>
<Flex
px="2"
py="1"
style={{
backgroundColor: 'var(--bui-bg-neutral-4-disabled)',
}}
>
<Text style={{ color: 'var(--bui-fg-disabled)' }}>
Disabled
</Text>
</Flex>
</Flex>
</Box>
</Box>
</Box>
</Box>
</div>
),
});
+1 -1
View File
@@ -27,7 +27,7 @@
}
body {
background-color: var(--bui-bg-surface-0);
background-color: var(--bui-bg-neutral-0);
/* Text defaults */
color: var(--bui-fg-primary);
+40 -68
View File
@@ -70,22 +70,6 @@
--bui-black: #000000;
--bui-white: #ffffff;
/* Gray scale */
--bui-gray-1: #f8f8f8;
--bui-gray-2: #ececec;
--bui-gray-3: #d9d9d9;
--bui-gray-4: #c1c1c1;
--bui-gray-5: #9e9e9e;
--bui-gray-6: #8c8c8c;
--bui-gray-7: #757575;
--bui-gray-8: #595959;
/* Surfaces colors */
--bui-bg-surface-0: var(--bui-gray-1);
--bui-bg-surface-1: var(--bui-white);
--bui-bg-surface-2: var(--bui-gray-1);
--bui-bg-surface-3: var(--bui-gray-2);
/* Solid background colors */
--bui-bg-solid: #1f5493;
--bui-bg-solid-hover: #163a66;
@@ -93,25 +77,27 @@
--bui-bg-solid-disabled: #163a66;
/* Neutral background colors */
--bui-bg-neutral-on-surface-0: oklch(0% 0 0 / 6%);
--bui-bg-neutral-on-surface-0-hover: oklch(0% 0 0 / 12%);
--bui-bg-neutral-on-surface-0-pressed: oklch(0% 0 0 / 16%);
--bui-bg-neutral-on-surface-0-disabled: oklch(0% 0 0 / 6%);
--bui-bg-neutral-0: #f8f8f8;
--bui-bg-neutral-on-surface-1: oklch(0% 0 0 / 6%);
--bui-bg-neutral-on-surface-1-hover: oklch(0% 0 0 / 12%);
--bui-bg-neutral-on-surface-1-pressed: oklch(0% 0 0 / 16%);
--bui-bg-neutral-on-surface-1-disabled: oklch(0% 0 0 / 6%);
--bui-bg-neutral-1: #fff;
--bui-bg-neutral-1-hover: oklch(0% 0 0 / 12%);
--bui-bg-neutral-1-pressed: oklch(0% 0 0 / 16%);
--bui-bg-neutral-1-disabled: oklch(0% 0 0 / 6%);
--bui-bg-neutral-on-surface-2: oklch(0% 0 0 / 6%);
--bui-bg-neutral-on-surface-2-hover: oklch(0% 0 0 / 12%);
--bui-bg-neutral-on-surface-2-pressed: oklch(0% 0 0 / 16%);
--bui-bg-neutral-on-surface-2-disabled: oklch(0% 0 0 / 6%);
--bui-bg-neutral-2: oklch(0% 0 0 / 6%);
--bui-bg-neutral-2-hover: oklch(0% 0 0 / 12%);
--bui-bg-neutral-2-pressed: oklch(0% 0 0 / 16%);
--bui-bg-neutral-2-disabled: oklch(0% 0 0 / 6%);
--bui-bg-neutral-on-surface-3: oklch(0% 0 0 / 6%);
--bui-bg-neutral-on-surface-3-hover: oklch(0% 0 0 / 12%);
--bui-bg-neutral-on-surface-3-pressed: oklch(0% 0 0 / 16%);
--bui-bg-neutral-on-surface-3-disabled: oklch(0% 0 0 / 6%);
--bui-bg-neutral-3: oklch(0% 0 0 / 6%);
--bui-bg-neutral-3-hover: oklch(0% 0 0 / 12%);
--bui-bg-neutral-3-pressed: oklch(0% 0 0 / 16%);
--bui-bg-neutral-3-disabled: oklch(0% 0 0 / 6%);
--bui-bg-neutral-4: oklch(0% 0 0 / 6%);
--bui-bg-neutral-4-hover: oklch(0% 0 0 / 12%);
--bui-bg-neutral-4-pressed: oklch(0% 0 0 / 16%);
--bui-bg-neutral-4-disabled: oklch(0% 0 0 / 6%);
/* Status background colors */
--bui-bg-danger: #ffe2e2;
@@ -121,8 +107,8 @@
/* Foreground colors */
--bui-fg-primary: var(--bui-black);
--bui-fg-secondary: var(--bui-gray-7);
--bui-fg-disabled: #9e9e9e;
--bui-fg-secondary: oklch(0% 0 0 / 50%);
--bui-fg-disabled: oklch(0% 0 0 / 28%);
--bui-fg-solid: var(--bui-white);
--bui-fg-solid-disabled: #98a8bc;
@@ -160,22 +146,6 @@
/* Dark theme tokens */
[data-theme-mode='dark'] {
/* Gray scale */
--bui-gray-1: #191919;
--bui-gray-2: #242424;
--bui-gray-3: #373737;
--bui-gray-4: #464646;
--bui-gray-5: #575757;
--bui-gray-6: #7b7b7b;
--bui-gray-7: #9e9e9e;
--bui-gray-8: #b4b4b4;
/* Background Colors */
--bui-bg-surface-0: #333333;
--bui-bg-surface-1: var(--bui-gray-1);
--bui-bg-surface-2: var(--bui-gray-2);
--bui-bg-surface-3: var(--bui-gray-3);
/* Solid background colors */
--bui-bg-solid: #9cc9ff;
--bui-bg-solid-hover: #83b9fd;
@@ -183,25 +153,27 @@
--bui-bg-solid-disabled: #1b3d68;
/* Neutral background colors */
--bui-bg-neutral-on-surface-0: oklch(100% 0 0 / 10%);
--bui-bg-neutral-on-surface-0-hover: oklch(100% 0 0 / 14%);
--bui-bg-neutral-on-surface-0-pressed: oklch(100% 0 0 / 20%);
--bui-bg-neutral-on-surface-0-disabled: oklch(100% 0 0 / 10%);
--bui-bg-neutral-0: #333333;
--bui-bg-neutral-on-surface-1: oklch(100% 0 0 / 6%);
--bui-bg-neutral-on-surface-1-hover: oklch(100% 0 0 / 10%);
--bui-bg-neutral-on-surface-1-pressed: oklch(100% 0 0 / 16%);
--bui-bg-neutral-on-surface-1-disabled: oklch(100% 0 0 / 6%);
--bui-bg-neutral-1: oklch(100% 0 0 / 10%);
--bui-bg-neutral-1-hover: oklch(100% 0 0 / 14%);
--bui-bg-neutral-1-pressed: oklch(100% 0 0 / 20%);
--bui-bg-neutral-1-disabled: oklch(100% 0 0 / 10%);
--bui-bg-neutral-on-surface-2: oklch(100% 0 0 / 8%);
--bui-bg-neutral-on-surface-2-hover: oklch(100% 0 0 / 12%);
--bui-bg-neutral-on-surface-2-pressed: oklch(100% 0 0 / 20%);
--bui-bg-neutral-on-surface-2-disabled: oklch(100% 0 0 / 8%);
--bui-bg-neutral-2: oklch(100% 0 0 / 6%);
--bui-bg-neutral-2-hover: oklch(100% 0 0 / 10%);
--bui-bg-neutral-2-pressed: oklch(100% 0 0 / 16%);
--bui-bg-neutral-2-disabled: oklch(100% 0 0 / 6%);
--bui-bg-neutral-on-surface-3: oklch(100% 0 0 / 8%);
--bui-bg-neutral-on-surface-3-hover: oklch(100% 0 0 / 12%);
--bui-bg-neutral-on-surface-3-pressed: oklch(100% 0 0 / 20%);
--bui-bg-neutral-on-surface-3-disabled: oklch(100% 0 0 / 8%);
--bui-bg-neutral-3: oklch(100% 0 0 / 8%);
--bui-bg-neutral-3-hover: oklch(100% 0 0 / 12%);
--bui-bg-neutral-3-pressed: oklch(100% 0 0 / 20%);
--bui-bg-neutral-3-disabled: oklch(100% 0 0 / 8%);
--bui-bg-neutral-4: oklch(100% 0 0 / 8%);
--bui-bg-neutral-4-hover: oklch(100% 0 0 / 12%);
--bui-bg-neutral-4-pressed: oklch(100% 0 0 / 20%);
--bui-bg-neutral-4-disabled: oklch(100% 0 0 / 8%);
/* Status background colors */
--bui-bg-danger: #300c0c;
@@ -211,8 +183,8 @@
/* Foreground colors */
--bui-fg-primary: var(--bui-white);
--bui-fg-secondary: var(--bui-gray-7);
--bui-fg-disabled: var(--bui-gray-7);
--bui-fg-secondary: oklch(0% 0 0 / 50%);
--bui-fg-disabled: oklch(0% 0 0 / 28%);
--bui-fg-solid: #101821;
--bui-fg-solid-disabled: #6191cc;
@@ -264,7 +264,7 @@ function Extension({ node, depth }: { node: AppNode; depth: number }) {
style={{
width: 'fit-content',
color: enabled ? 'var(--bui-fg-primary)' : 'var(--bui-fg-disabled)',
background: 'var(--bui-bg-surface-1)',
background: 'var(--bui-bg-neutral-1)',
borderTopRightRadius: 'var(--bui-radius-2)',
borderBottomRightRadius: 'var(--bui-radius-2)',
}}
@@ -362,7 +362,7 @@ export function DetailedVisualizer({ tree }: { tree: AppTree }) {
m="2"
style={{
flex: '0 0 auto',
background: 'var(--bui-bg-surface-1)',
background: 'var(--bui-bg-neutral-1)',
border: '1px solid var(--bui-border)',
borderRadius: 'var(--bui-radius-2)',
}}
@@ -92,7 +92,7 @@ export function TextVisualizer({ tree }: { tree: AppTree }) {
py="2"
px="4"
style={{
background: 'var(--bui-bg-surface-1)',
background: 'var(--bui-bg-neutral-1)',
borderTop: '1px solid var(--bui-border)',
}}
>
@@ -35,6 +35,7 @@
},
"dependencies": {
"@backstage/backend-plugin-api": "workspace:^",
"@backstage/errors": "workspace:^",
"@backstage/plugin-auth-node": "workspace:^",
"express": "^4.22.0",
"passport": "^0.7.0",
@@ -87,4 +87,97 @@ describe('authModuleAuth0Provider', () => {
nonce: decodeURIComponent(nonceCookie.value),
});
});
it('should pass through organization and invitation parameters to the authorization URL', async () => {
const { server } = await startTestBackend({
features: [
authPlugin,
authModuleAuth0Provider,
mockServices.rootConfig.factory({
data: {
app: {
baseUrl: 'http://localhost:3000',
},
auth: {
providers: {
auth0: {
development: {
clientId: 'clientId',
clientSecret: 'clientSecret',
domain: 'domain',
connection: 'connection',
connectionScope: 'connectionScope',
organization: 'foo-organization',
},
},
},
session: {
secret: 'secret',
},
},
},
}),
],
});
const agent = request.agent(server);
const res = await agent.get(
'/api/auth/auth0/start?env=development&organization=foo-organization&invitation=foo-invitation',
);
const startUrl = new URL(res.get('location'));
expect(startUrl.origin).toBe('https://domain');
expect(startUrl.pathname).toBe('/authorize');
expect(Object.fromEntries(startUrl.searchParams)).toEqual(
expect.objectContaining({
organization: 'foo-organization',
invitation: 'foo-invitation',
}),
);
});
it('should throw an error if the organization in the request does not match the organization configured in the strategy', async () => {
const { server } = await startTestBackend({
features: [
authPlugin,
authModuleAuth0Provider,
mockServices.rootConfig.factory({
data: {
app: {
baseUrl: 'http://localhost:3000',
},
auth: {
providers: {
auth0: {
development: {
clientId: 'clientId',
clientSecret: 'clientSecret',
domain: 'domain',
connection: 'connection',
connectionScope: 'connectionScope',
organization: 'bar-organization',
},
},
},
session: {
secret: 'secret',
},
},
},
}),
],
});
const agent = request.agent(server);
const res = await agent.get(
'/api/auth/auth0/start?env=development&organization=foo-organization&invitation=foo-invitation',
);
expect(res.status).toEqual(400);
expect(res.text).toContain(
'Organization mismatch. The organization provided in the request does not match the organization configured in the strategy.',
);
});
});
@@ -16,6 +16,8 @@
import Auth0InternalStrategy from 'passport-auth0';
import type { StateStore } from 'passport-oauth2';
import type express from 'express';
import { InputError } from '@backstage/errors';
/** @public */
export interface Auth0StrategyOptionsWithRequest {
@@ -47,15 +49,38 @@ export class Auth0Strategy extends Auth0InternalStrategy {
this.organization = options.organization;
}
authenticate(req: express.Request, options: Record<string, any>): void {
const { organization, invitation } = req.query;
// Throw an error if the organization in the request does not match the organization configured in the strategy
if (
organization &&
this.organization &&
organization !== this.organization
) {
throw new InputError(
'Organization mismatch. The organization provided in the request does not match the organization configured in the strategy.',
);
}
super.authenticate(req, {
...options,
...(organization ? { organization } : {}),
...(invitation ? { invitation } : {}),
});
}
authorizationParams(options: Record<string, any>): Record<string, any> {
const params = super.authorizationParams(options);
if (this.organization) {
return {
...params,
organization: this.organization,
};
if (options.organization || this.organization) {
params.organization = options.organization || this.organization;
}
if (options.invitation) {
params.invitation = options.invitation;
}
return params;
}
}
@@ -25,7 +25,7 @@ describe('BuiThemePreview', () => {
<BuiThemePreview
mode="light"
styleObject={{
'--bui-bg-surface-2': '#ffffff',
'--bui-bg-neutral-2': '#ffffff',
'--bui-border': '#cccccc',
'--bui-radius-2': '4px',
'--bui-space-3': '12px',
@@ -33,7 +33,7 @@ describe('BuiThemePreview', () => {
'--bui-bg-solid': '#000000',
'--bui-fg-solid': '#ffffff',
'--bui-fg-primary': '#111111',
'--bui-bg-surface-1': '#f5f5f5',
'--bui-bg-neutral-1': '#f5f5f5',
}}
/>,
);
@@ -46,7 +46,7 @@ export function BuiThemePreview({ mode, styleObject }: IsolatedPreviewProps) {
// This creates a scoped context where the variables take precedence
...styleObject,
width: '100%',
backgroundColor: 'var(--bui-bg-surface-2)',
backgroundColor: 'var(--bui-bg-neutral-2)',
padding: 'var(--bui-space-3)',
borderRadius: 'var(--bui-radius-2)',
border: '1px solid var(--bui-border)',
@@ -98,7 +98,7 @@ export function ThemeContent({
<Box
p="3"
style={{
backgroundColor: 'var(--bui-bg-surface-2)',
backgroundColor: 'var(--bui-bg-neutral-2)',
border: '1px solid var(--bui-border)',
borderRadius: 'var(--bui-radius-2)',
fontFamily: 'monospace',
@@ -59,9 +59,9 @@ describe('convertMuiToBuiTheme', () => {
// Border radius tokens are only generated when radius is 0
expect(result.css).not.toContain('--bui-radius-3:');
// Background default maps to surface-2
expect(result.css).toContain('--bui-bg-surface-0: #f5f5f5;');
expect(result.css).toContain('--bui-bg-surface-2: #f5f5f5;');
expect(result.css).toContain('--bui-bg-surface-1: #ffffff;');
expect(result.css).toContain('--bui-bg-neutral-0: #f5f5f5;');
expect(result.css).toContain('--bui-bg-neutral-2: #f5f5f5;');
expect(result.css).toContain('--bui-bg-neutral-1: #ffffff;');
expect(result.css).toContain('--bui-fg-primary: #000000;');
// Secondary may not be present without Backstage additions, so don't assert it
expect(result.css).toContain('--bui-bg-solid: #1976d2;');
@@ -98,13 +98,13 @@ describe('convertMuiToBuiTheme', () => {
expect(result.css).toContain("[data-theme-mode='dark'] {");
// Background default maps to surface-2 in dark mode as well
expect(result.css).toContain('--bui-bg-surface-0: #121212;');
expect(result.css).toContain('--bui-bg-surface-2: #121212;');
expect(result.css).toContain('--bui-bg-surface-1: #1e1e1e;');
expect(result.css).toContain('--bui-bg-neutral-0: #121212;');
expect(result.css).toContain('--bui-bg-neutral-2: #121212;');
expect(result.css).toContain('--bui-bg-neutral-1: #1e1e1e;');
expect(result.css).toContain('--bui-fg-primary: #ffffff;');
// Test style object
expect(result.styleObject).toHaveProperty('--bui-bg-surface-1', '#1e1e1e');
expect(result.styleObject).toHaveProperty('--bui-bg-neutral-1', '#1e1e1e');
expect(result.styleObject).toHaveProperty('--bui-fg-primary', '#ffffff');
});
@@ -109,12 +109,12 @@ function generateBuiVariables(theme: Mui5Theme): Record<string, string> {
styleObject[`--bui-fg-${key}`] = value;
});
// Generate surface colors
// Generate neutral background colors
Object.entries({
'surface-0': palette.background.default,
'surface-1': palette.background.paper,
'surface-2': palette.background.default,
'surface-3': palette.background.default,
'neutral-0': palette.background.default,
'neutral-1': palette.background.paper,
'neutral-2': palette.background.default,
'neutral-3': palette.background.default,
solid: palette.primary.main,
'solid-hover': blend(palette.primary.main, palette.primary.dark, 0.5),
'solid-pressed': palette.primary.dark,
+1
View File
@@ -4284,6 +4284,7 @@ __metadata:
"@backstage/backend-plugin-api": "workspace:^"
"@backstage/backend-test-utils": "workspace:^"
"@backstage/cli": "workspace:^"
"@backstage/errors": "workspace:^"
"@backstage/plugin-auth-backend": "workspace:^"
"@backstage/plugin-auth-node": "workspace:^"
"@backstage/types": "workspace:^"