diff --git a/.changeset/angry-hornets-clap.md b/.changeset/angry-hornets-clap.md new file mode 100644 index 0000000000..bd590e71d9 --- /dev/null +++ b/.changeset/angry-hornets-clap.md @@ -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); +``` diff --git a/.changeset/brown-grapes-fold.md b/.changeset/brown-grapes-fold.md new file mode 100644 index 0000000000..d8ab0a23f3 --- /dev/null +++ b/.changeset/brown-grapes-fold.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-auth-backend-module-auth0-provider': patch +--- + +Add support for organizational invites in auth0 strategy diff --git a/.changeset/wicked-walls-accept.md b/.changeset/wicked-walls-accept.md index dc5e86a0d4..6f16088ed9 100644 --- a/.changeset/wicked-walls-accept.md +++ b/.changeset/wicked-walls-accept.md @@ -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 */ } ``` diff --git a/.storybook/preview.tsx b/.storybook/preview.tsx index 12122e6200..e67522fd87 100644 --- a/.storybook/preview.tsx +++ b/.storybook/preview.tsx @@ -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 ( diff --git a/.storybook/storybook.css b/.storybook/storybook.css index e69c4a8eb1..617af88ba2 100644 --- a/.storybook/storybook.css +++ b/.storybook/storybook.css @@ -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; diff --git a/.storybook/themes/spotify.css b/.storybook/themes/spotify.css index 4f8b1b137d..c52062fe96 100644 --- a/.storybook/themes/spotify.css +++ b/.storybook/themes/spotify.css @@ -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); diff --git a/ADOPTERS.md b/ADOPTERS.md index 3080075343..9a0e2fb0fd 100644 --- a/ADOPTERS.md +++ b/ADOPTERS.md @@ -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.| \ No newline at end of file diff --git a/docs-ui/src/app/tokens/page.mdx b/docs-ui/src/app/tokens/page.mdx index fdc8aa9a90..46d67ded95 100644 --- a/docs-ui/src/app/tokens/page.mdx +++ b/docs-ui/src/app/tokens/page.mdx @@ -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, ... - @@ -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. - - - --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. - -## 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. @@ -200,22 +151,129 @@ color of your app. - --bui-bg-surface-0 + --bui-bg-neutral-0 + + + The base background color of your Backstage instance. - The background color of your Backstage instance. - --bui-bg-surface-1 + --bui-bg-neutral-1 + + + First elevated layer. Use for cards, dialogs, and panels. - Use for any panels or elevated surfaces. - --bui-bg-surface-2 + --bui-bg-neutral-1-hover - Use for any panels or elevated surfaces. + 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. + + + + +## Solid background colors + + + + + Prop + Description + + + --bui-bg-solid @@ -240,6 +298,19 @@ color of your app. Used for solid background colors when disabled. + + + +## Status background colors + + + + + Prop + Description + + + --bui-bg-danger @@ -393,7 +464,7 @@ low contrast to help as a separator with the different background colors. --bui-border - It should be used on top of `--bui-bg-surface-1`. + It should be used on top of `--bui-bg-neutral-1`. diff --git a/docs-ui/src/components/Snippet/styles.module.css b/docs-ui/src/components/Snippet/styles.module.css index 20f74c4df8..01ed111b91 100644 --- a/docs-ui/src/components/Snippet/styles.module.css +++ b/docs-ui/src/components/Snippet/styles.module.css @@ -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; diff --git a/docs-ui/src/css/theme-backstage.css b/docs-ui/src/css/theme-backstage.css index e1ba6ba5b0..96861993ee 100644 --- a/docs-ui/src/css/theme-backstage.css +++ b/docs-ui/src/css/theme-backstage.css @@ -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); diff --git a/docs-ui/src/css/theme-spotify.css b/docs-ui/src/css/theme-spotify.css index dc660b5b5d..73a067d5b0 100644 --- a/docs-ui/src/css/theme-spotify.css +++ b/docs-ui/src/css/theme-spotify.css @@ -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; diff --git a/docs-ui/src/snippets/code-snippets.ts b/docs-ui/src/snippets/code-snippets.ts index 57169ae32a..92a9cfe2db 100644 --- a/docs-ui/src/snippets/code-snippets.ts +++ b/docs-ui/src/snippets/code-snippets.ts @@ -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 */ diff --git a/docs/architecture-decisions/adr003-avoid-default-exports.md b/docs/architecture-decisions/adr003-avoid-default-exports.md index 8ba37914df..3a4aa47435 100644 --- a/docs/architecture-decisions/adr003-avoid-default-exports.md +++ b/docs/architecture-decisions/adr003-avoid-default-exports.md @@ -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 diff --git a/docs/conf/user-interface/index.md b/docs/conf/user-interface/index.md index 002383c6f4..abe74dddef 100644 --- a/docs/conf/user-interface/index.md +++ b/docs/conf/user-interface/index.md @@ -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 you’d 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 you’d 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. | diff --git a/docs/plugins/integrating-plugin-into-software-catalog.md b/docs/plugins/integrating-plugin-into-software-catalog.md index 3542e073cb..911d74b019 100644 --- a/docs/plugins/integrating-plugin-into-software-catalog.md +++ b/docs/plugins/integrating-plugin-into-software-catalog.md @@ -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 diff --git a/packages/ui/css/styles.css b/packages/ui/css/styles.css index 7538f53bbe..f501f5144b 100644 --- a/packages/ui/css/styles.css +++ b/packages/ui/css/styles.css @@ -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); diff --git a/packages/ui/src/components/Accordion/Accordion.module.css b/packages/ui/src/components/Accordion/Accordion.module.css index 357696b0ff..7300b802e2 100644 --- a/packages/ui/src/components/Accordion/Accordion.module.css +++ b/packages/ui/src/components/Accordion/Accordion.module.css @@ -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); } diff --git a/packages/ui/src/components/Alert/Alert.module.css b/packages/ui/src/components/Alert/Alert.module.css index 9c2fc6a586..b14483cd20 100644 --- a/packages/ui/src/components/Alert/Alert.module.css +++ b/packages/ui/src/components/Alert/Alert.module.css @@ -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; diff --git a/packages/ui/src/components/Avatar/Avatar.module.css b/packages/ui/src/components/Avatar/Avatar.module.css index c1fec3df9b..ffaad2d18f 100644 --- a/packages/ui/src/components/Avatar/Avatar.module.css +++ b/packages/ui/src/components/Avatar/Avatar.module.css @@ -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; diff --git a/packages/ui/src/components/Box/Box.module.css b/packages/ui/src/components/Box/Box.module.css index f5af895f85..6a0ebb9fdd 100644 --- a/packages/ui/src/components/Box/Box.module.css +++ b/packages/ui/src/components/Box/Box.module.css @@ -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'] { diff --git a/packages/ui/src/components/Button/Button.module.css b/packages/ui/src/components/Button/Button.module.css index 740e18f59e..9b6fbbd09d 100644 --- a/packages/ui/src/components/Button/Button.module.css +++ b/packages/ui/src/components/Button/Button.module.css @@ -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'], diff --git a/packages/ui/src/components/Button/Button.stories.tsx b/packages/ui/src/components/Button/Button.stories.tsx index 8d5a67c9fe..b5eb885930 100644 --- a/packages/ui/src/components/Button/Button.stories.tsx +++ b/packages/ui/src/components/Button/Button.stories.tsx @@ -82,7 +82,7 @@ export const Variants = meta.story({ - On Surface 0 + Neutral 0 - - - - - - + Neutral 2 + + + + + + + + + + - On Surface 3 - - - - - - - - + Neutral 3 + + + + + + + + + + + + ), diff --git a/packages/ui/src/components/ButtonIcon/ButtonIcon.module.css b/packages/ui/src/components/ButtonIcon/ButtonIcon.module.css index da1b053701..19a74db3bf 100644 --- a/packages/ui/src/components/ButtonIcon/ButtonIcon.module.css +++ b/packages/ui/src/components/ButtonIcon/ButtonIcon.module.css @@ -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'], diff --git a/packages/ui/src/components/ButtonLink/ButtonLink.module.css b/packages/ui/src/components/ButtonLink/ButtonLink.module.css index be539123a0..1184a160b7 100644 --- a/packages/ui/src/components/ButtonLink/ButtonLink.module.css +++ b/packages/ui/src/components/ButtonLink/ButtonLink.module.css @@ -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'] { diff --git a/packages/ui/src/components/Card/Card.module.css b/packages/ui/src/components/Card/Card.module.css index e6e5758e67..614aa31bf7 100644 --- a/packages/ui/src/components/Card/Card.module.css +++ b/packages/ui/src/components/Card/Card.module.css @@ -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); diff --git a/packages/ui/src/components/Card/Card.stories.tsx b/packages/ui/src/components/Card/Card.stories.tsx index d51c9ed5b3..06ef9a2fa2 100644 --- a/packages/ui/src/components/Card/Card.stories.tsx +++ b/packages/ui/src/components/Card/Card.stories.tsx @@ -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)', diff --git a/packages/ui/src/components/Checkbox/Checkbox.module.css b/packages/ui/src/components/Checkbox/Checkbox.module.css index a4647c935a..0b6613f927 100644 --- a/packages/ui/src/components/Checkbox/Checkbox.module.css +++ b/packages/ui/src/components/Checkbox/Checkbox.module.css @@ -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); } diff --git a/packages/ui/src/components/Dialog/Dialog.module.css b/packages/ui/src/components/Dialog/Dialog.module.css index 5101cbf67c..201f25ed3a 100644 --- a/packages/ui/src/components/Dialog/Dialog.module.css +++ b/packages/ui/src/components/Dialog/Dialog.module.css @@ -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); diff --git a/packages/ui/src/components/Flex/Flex.module.css b/packages/ui/src/components/Flex/Flex.module.css index 1ca3497cba..5923fa160e 100644 --- a/packages/ui/src/components/Flex/Flex.module.css +++ b/packages/ui/src/components/Flex/Flex.module.css @@ -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'] { diff --git a/packages/ui/src/components/Grid/Grid.module.css b/packages/ui/src/components/Grid/Grid.module.css index 1861e38101..aa281b8695 100644 --- a/packages/ui/src/components/Grid/Grid.module.css +++ b/packages/ui/src/components/Grid/Grid.module.css @@ -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'], diff --git a/packages/ui/src/components/Header/Header.module.css b/packages/ui/src/components/Header/Header.module.css index 031cfd4d16..cb51d60535 100644 --- a/packages/ui/src/components/Header/Header.module.css +++ b/packages/ui/src/components/Header/Header.module.css @@ -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); } } diff --git a/packages/ui/src/components/Menu/Menu.module.css b/packages/ui/src/components/Menu/Menu.module.css index d8ebf6cba8..759bfb9043 100644 --- a/packages/ui/src/components/Menu/Menu.module.css +++ b/packages/ui/src/components/Menu/Menu.module.css @@ -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] { diff --git a/packages/ui/src/components/PasswordField/PasswordField.module.css b/packages/ui/src/components/PasswordField/PasswordField.module.css index adad950816..d89060f248 100644 --- a/packages/ui/src/components/PasswordField/PasswordField.module.css +++ b/packages/ui/src/components/PasswordField/PasswordField.module.css @@ -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'] { diff --git a/packages/ui/src/components/Popover/Popover.module.css b/packages/ui/src/components/Popover/Popover.module.css index 5156b95ffc..8fb53b9ab0 100644 --- a/packages/ui/src/components/Popover/Popover.module.css +++ b/packages/ui/src/components/Popover/Popover.module.css @@ -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); } } diff --git a/packages/ui/src/components/RadioGroup/RadioGroup.module.css b/packages/ui/src/components/RadioGroup/RadioGroup.module.css index a18f2d385d..3b816709ef 100644 --- a/packages/ui/src/components/RadioGroup/RadioGroup.module.css +++ b/packages/ui/src/components/RadioGroup/RadioGroup.module.css @@ -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; diff --git a/packages/ui/src/components/SearchField/SearchField.module.css b/packages/ui/src/components/SearchField/SearchField.module.css index 765527c8c3..44c1691ab9 100644 --- a/packages/ui/src/components/SearchField/SearchField.module.css +++ b/packages/ui/src/components/SearchField/SearchField.module.css @@ -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'] { diff --git a/packages/ui/src/components/Select/Select.module.css b/packages/ui/src/components/Select/Select.module.css index a2eb41040e..2c3945b4c2 100644 --- a/packages/ui/src/components/Select/Select.module.css +++ b/packages/ui/src/components/Select/Select.module.css @@ -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; } diff --git a/packages/ui/src/components/Skeleton/Skeleton.module.css b/packages/ui/src/components/Skeleton/Skeleton.module.css index da2796244a..5f9c85fa73 100644 --- a/packages/ui/src/components/Skeleton/Skeleton.module.css +++ b/packages/ui/src/components/Skeleton/Skeleton.module.css @@ -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); } diff --git a/packages/ui/src/components/Switch/Switch.module.css b/packages/ui/src/components/Switch/Switch.module.css index d35caf41a6..2d15cc0930 100644 --- a/packages/ui/src/components/Switch/Switch.module.css +++ b/packages/ui/src/components/Switch/Switch.module.css @@ -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; diff --git a/packages/ui/src/components/Tabs/Tabs.module.css b/packages/ui/src/components/Tabs/Tabs.module.css index 158a92952a..68808ae021 100644 --- a/packages/ui/src/components/Tabs/Tabs.module.css +++ b/packages/ui/src/components/Tabs/Tabs.module.css @@ -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, diff --git a/packages/ui/src/components/TagGroup/TagGroup.module.css b/packages/ui/src/components/TagGroup/TagGroup.module.css index 25ea694b0f..5bf6ff605e 100644 --- a/packages/ui/src/components/TagGroup/TagGroup.module.css +++ b/packages/ui/src/components/TagGroup/TagGroup.module.css @@ -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] { diff --git a/packages/ui/src/components/TextField/TextField.module.css b/packages/ui/src/components/TextField/TextField.module.css index 0ac9bc7f77..5d582d775c 100644 --- a/packages/ui/src/components/TextField/TextField.module.css +++ b/packages/ui/src/components/TextField/TextField.module.css @@ -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); diff --git a/packages/ui/src/components/ToggleButton/ToggleButton.module.css b/packages/ui/src/components/ToggleButton/ToggleButton.module.css index e23c4d53eb..729ede2af2 100644 --- a/packages/ui/src/components/ToggleButton/ToggleButton.module.css +++ b/packages/ui/src/components/ToggleButton/ToggleButton.module.css @@ -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] { diff --git a/packages/ui/src/components/Tooltip/Tooltip.module.css b/packages/ui/src/components/Tooltip/Tooltip.module.css index b668952848..3841fbbcec 100644 --- a/packages/ui/src/components/Tooltip/Tooltip.module.css +++ b/packages/ui/src/components/Tooltip/Tooltip.module.css @@ -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); } } diff --git a/packages/ui/src/css/colors.stories.tsx b/packages/ui/src/css/colors.stories.tsx new file mode 100644 index 0000000000..c4768da3ae --- /dev/null +++ b/packages/ui/src/css/colors.stories.tsx @@ -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: () => ( +
+ + + Neutral 1 + + Hover + + + Pressed + + + Disabled + + + + + Neutral 2 + + Hover + + + Pressed + + + Disabled + + + + + Neutral 3 + + Hover + + + Pressed + + + + Disabled + + + + + + Neutral 4 + + Hover + + + Pressed + + + + Disabled + + + + + + + +
+ ), +}); diff --git a/packages/ui/src/css/core.css b/packages/ui/src/css/core.css index 321ca07eff..f744f253bf 100644 --- a/packages/ui/src/css/core.css +++ b/packages/ui/src/css/core.css @@ -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); diff --git a/packages/ui/src/css/tokens.css b/packages/ui/src/css/tokens.css index 9cd6ea98e5..f889b4cb7c 100644 --- a/packages/ui/src/css/tokens.css +++ b/packages/ui/src/css/tokens.css @@ -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; diff --git a/plugins/app-visualizer/src/components/AppVisualizerPage/DetailedVisualizer.tsx b/plugins/app-visualizer/src/components/AppVisualizerPage/DetailedVisualizer.tsx index ef0a329b8c..37cf9787ae 100644 --- a/plugins/app-visualizer/src/components/AppVisualizerPage/DetailedVisualizer.tsx +++ b/plugins/app-visualizer/src/components/AppVisualizerPage/DetailedVisualizer.tsx @@ -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)', }} diff --git a/plugins/app-visualizer/src/components/AppVisualizerPage/TextVisualizer.tsx b/plugins/app-visualizer/src/components/AppVisualizerPage/TextVisualizer.tsx index 82fd913bf2..b8bcd859ac 100644 --- a/plugins/app-visualizer/src/components/AppVisualizerPage/TextVisualizer.tsx +++ b/plugins/app-visualizer/src/components/AppVisualizerPage/TextVisualizer.tsx @@ -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)', }} > diff --git a/plugins/auth-backend-module-auth0-provider/package.json b/plugins/auth-backend-module-auth0-provider/package.json index 5bd7e342ee..edb5b457b4 100644 --- a/plugins/auth-backend-module-auth0-provider/package.json +++ b/plugins/auth-backend-module-auth0-provider/package.json @@ -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", diff --git a/plugins/auth-backend-module-auth0-provider/src/module.test.ts b/plugins/auth-backend-module-auth0-provider/src/module.test.ts index 7e7f649831..28ccf90fa4 100644 --- a/plugins/auth-backend-module-auth0-provider/src/module.test.ts +++ b/plugins/auth-backend-module-auth0-provider/src/module.test.ts @@ -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.', + ); + }); }); diff --git a/plugins/auth-backend-module-auth0-provider/src/strategy.ts b/plugins/auth-backend-module-auth0-provider/src/strategy.ts index a8699555a7..b6252aa7bd 100644 --- a/plugins/auth-backend-module-auth0-provider/src/strategy.ts +++ b/plugins/auth-backend-module-auth0-provider/src/strategy.ts @@ -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): 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): Record { 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; } } diff --git a/plugins/mui-to-bui/src/components/BuiThemerPage/BuiThemePreview.test.tsx b/plugins/mui-to-bui/src/components/BuiThemerPage/BuiThemePreview.test.tsx index 375f9411a7..355100be86 100644 --- a/plugins/mui-to-bui/src/components/BuiThemerPage/BuiThemePreview.test.tsx +++ b/plugins/mui-to-bui/src/components/BuiThemerPage/BuiThemePreview.test.tsx @@ -25,7 +25,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', }} />, ); diff --git a/plugins/mui-to-bui/src/components/BuiThemerPage/BuiThemePreview.tsx b/plugins/mui-to-bui/src/components/BuiThemerPage/BuiThemePreview.tsx index 0b62134178..0a745e1aeb 100644 --- a/plugins/mui-to-bui/src/components/BuiThemerPage/BuiThemePreview.tsx +++ b/plugins/mui-to-bui/src/components/BuiThemerPage/BuiThemePreview.tsx @@ -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)', diff --git a/plugins/mui-to-bui/src/components/BuiThemerPage/ThemeContent.tsx b/plugins/mui-to-bui/src/components/BuiThemerPage/ThemeContent.tsx index 0974b8f15d..19749165d7 100644 --- a/plugins/mui-to-bui/src/components/BuiThemerPage/ThemeContent.tsx +++ b/plugins/mui-to-bui/src/components/BuiThemerPage/ThemeContent.tsx @@ -98,7 +98,7 @@ export function ThemeContent({ { // 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'); }); diff --git a/plugins/mui-to-bui/src/components/BuiThemerPage/convertMuiToBuiTheme.ts b/plugins/mui-to-bui/src/components/BuiThemerPage/convertMuiToBuiTheme.ts index dc72e3d597..326fd08ef2 100644 --- a/plugins/mui-to-bui/src/components/BuiThemerPage/convertMuiToBuiTheme.ts +++ b/plugins/mui-to-bui/src/components/BuiThemerPage/convertMuiToBuiTheme.ts @@ -109,12 +109,12 @@ function generateBuiVariables(theme: Mui5Theme): Record { 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, diff --git a/yarn.lock b/yarn.lock index 8cbe70fc51..f428351f0f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -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:^"