Merge pull request #34400 from backstage/feat/bui-token-redesign
feat(ui): introduce semantic color token families and deprecate legacy tokens
This commit is contained in:
@@ -0,0 +1,108 @@
|
||||
# no-deprecated-bui-tokens
|
||||
|
||||
Warns when a deprecated `@backstage/ui` CSS token is referenced inside a JS/TS string or template literal.
|
||||
|
||||
The `@backstage/ui` design token system has been updated with a new set of semantic color families. The old tokens still work for backward compatibility, but they are scheduled for removal in a future major version.
|
||||
|
||||
## Rule Details
|
||||
|
||||
This rule reports a warning for any string value that contains a reference to a deprecated BUI CSS custom property, such as `var(--bui-bg-solid)` or `var(--bui-fg-danger)`.
|
||||
|
||||
Examples of **incorrect** code for this rule:
|
||||
|
||||
```js
|
||||
// Deprecated background token
|
||||
const style = { background: 'var(--bui-bg-solid)' };
|
||||
|
||||
// Deprecated foreground token
|
||||
const style = { color: 'var(--bui-fg-danger)' };
|
||||
|
||||
// Deprecated token in a template literal
|
||||
const css = `border: 1px solid var(--bui-border-danger)`;
|
||||
```
|
||||
|
||||
Examples of **correct** code for this rule:
|
||||
|
||||
```js
|
||||
// New accent family
|
||||
const style = { background: 'var(--bui-accent-bg)' };
|
||||
|
||||
// New semantic negative family
|
||||
const style = { color: 'var(--bui-negative-fg-subdued)' };
|
||||
|
||||
// New semantic positive family
|
||||
const style = { borderColor: 'var(--bui-positive-border)' };
|
||||
```
|
||||
|
||||
## Migration Guide
|
||||
|
||||
Replace deprecated tokens with their equivalents from the new semantic families.
|
||||
|
||||
### Neutral backgrounds
|
||||
|
||||
The neutral background tokens (`--bui-bg-app`, `--bui-bg-neutral-1..4`) are now the active semantic tokens with updated solid-color values. The `-hover`, `-pressed`, and `-disabled` interaction variants remain deprecated:
|
||||
|
||||
| Deprecated | Replacement |
|
||||
| ----------------------------- | --------------------- |
|
||||
| `--bui-bg-neutral-1-hover` | _(remove or restyle)_ |
|
||||
| `--bui-bg-neutral-1-pressed` | _(remove or restyle)_ |
|
||||
| `--bui-bg-neutral-1-disabled` | _(remove or restyle)_ |
|
||||
| `--bui-bg-neutral-2-hover` | _(remove or restyle)_ |
|
||||
| `--bui-bg-neutral-2-pressed` | _(remove or restyle)_ |
|
||||
| `--bui-bg-neutral-2-disabled` | _(remove or restyle)_ |
|
||||
| `--bui-bg-neutral-3-hover` | _(remove or restyle)_ |
|
||||
| `--bui-bg-neutral-3-pressed` | _(remove or restyle)_ |
|
||||
| `--bui-bg-neutral-3-disabled` | _(remove or restyle)_ |
|
||||
| `--bui-bg-neutral-4-hover` | _(remove or restyle)_ |
|
||||
| `--bui-bg-neutral-4-pressed` | _(remove or restyle)_ |
|
||||
| `--bui-bg-neutral-4-disabled` | _(remove or restyle)_ |
|
||||
|
||||
### Foreground
|
||||
|
||||
| Deprecated | Replacement |
|
||||
| ------------------ | ----------------------- |
|
||||
| `--bui-fg-danger` | `--bui-fg-negative` |
|
||||
| `--bui-fg-success` | `--bui-fg-positive` |
|
||||
| `--bui-fg-info` | `--bui-fg-announcement` |
|
||||
|
||||
### Accent
|
||||
|
||||
| Deprecated | Replacement |
|
||||
| ------------------------- | -------------------------- |
|
||||
| `--bui-bg-solid` | `--bui-accent-bg` |
|
||||
| `--bui-bg-solid-hover` | `--bui-accent-bg-hover` |
|
||||
| `--bui-bg-solid-disabled` | `--bui-accent-bg-disabled` |
|
||||
| `--bui-fg-solid` | `--bui-accent-fg` |
|
||||
| `--bui-fg-solid-disabled` | `--bui-accent-fg-disabled` |
|
||||
|
||||
### Positive
|
||||
|
||||
| Deprecated | Replacement |
|
||||
| ------------------------ | --------------------------- |
|
||||
| `--bui-bg-success` | `--bui-positive-bg-subdued` |
|
||||
| `--bui-fg-success-on-bg` | `--bui-positive-fg-subdued` |
|
||||
| `--bui-border-success` | `--bui-positive-border` |
|
||||
|
||||
### Negative
|
||||
|
||||
| Deprecated | Replacement |
|
||||
| ----------------------- | --------------------------- |
|
||||
| `--bui-bg-danger` | `--bui-negative-bg-subdued` |
|
||||
| `--bui-fg-danger-on-bg` | `--bui-negative-fg-subdued` |
|
||||
| `--bui-border-danger` | `--bui-negative-border` |
|
||||
|
||||
### Warning
|
||||
|
||||
| Deprecated | Replacement |
|
||||
| ------------------------ | -------------------------- |
|
||||
| `--bui-bg-warning` | `--bui-warning-bg-subdued` |
|
||||
| `--bui-fg-warning-on-bg` | `--bui-warning-fg-subdued` |
|
||||
| `--bui-border-warning` | `--bui-warning-border` |
|
||||
|
||||
### Announcement
|
||||
|
||||
| Deprecated | Replacement |
|
||||
| --------------------- | ------------------------------- |
|
||||
| `--bui-bg-info` | `--bui-announcement-bg-subdued` |
|
||||
| `--bui-fg-info-on-bg` | `--bui-announcement-fg-subdued` |
|
||||
| `--bui-border-info` | `--bui-announcement-border` |
|
||||
@@ -25,6 +25,7 @@ module.exports = {
|
||||
'@backstage/no-mixed-plugin-imports': 'warn',
|
||||
'@backstage/no-ui-css-imports-in-non-frontend': 'error',
|
||||
'@backstage/no-self-package-imports': 'error',
|
||||
'@backstage/no-deprecated-bui-tokens': 'warn',
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -36,5 +37,6 @@ module.exports = {
|
||||
'no-mixed-plugin-imports': require('./rules/no-mixed-plugin-imports'),
|
||||
'no-ui-css-imports-in-non-frontend': require('./rules/no-ui-css-imports-in-non-frontend'),
|
||||
'no-self-package-imports': require('./rules/no-self-package-imports'),
|
||||
'no-deprecated-bui-tokens': require('./rules/no-deprecated-bui-tokens'),
|
||||
},
|
||||
};
|
||||
|
||||
@@ -0,0 +1,117 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
// @ts-check
|
||||
|
||||
/** @type {string[]} */
|
||||
const DEPRECATED_TOKENS = [
|
||||
'--bui-bg-solid',
|
||||
'--bui-bg-solid-hover',
|
||||
'--bui-bg-solid-pressed',
|
||||
'--bui-bg-solid-disabled',
|
||||
'--bui-bg-neutral-1-hover',
|
||||
'--bui-bg-neutral-1-pressed',
|
||||
'--bui-bg-neutral-1-disabled',
|
||||
'--bui-bg-neutral-2-hover',
|
||||
'--bui-bg-neutral-2-pressed',
|
||||
'--bui-bg-neutral-2-disabled',
|
||||
'--bui-bg-neutral-3-hover',
|
||||
'--bui-bg-neutral-3-pressed',
|
||||
'--bui-bg-neutral-3-disabled',
|
||||
'--bui-bg-neutral-4-hover',
|
||||
'--bui-bg-neutral-4-pressed',
|
||||
'--bui-bg-neutral-4-disabled',
|
||||
'--bui-bg-danger',
|
||||
'--bui-bg-warning',
|
||||
'--bui-bg-success',
|
||||
'--bui-bg-info',
|
||||
'--bui-fg-solid',
|
||||
'--bui-fg-solid-disabled',
|
||||
'--bui-fg-danger-on-bg',
|
||||
'--bui-fg-warning-on-bg',
|
||||
'--bui-fg-success-on-bg',
|
||||
'--bui-fg-info-on-bg',
|
||||
'--bui-fg-danger',
|
||||
'--bui-fg-success',
|
||||
'--bui-fg-info',
|
||||
'--bui-border-info',
|
||||
'--bui-border-danger',
|
||||
'--bui-border-warning',
|
||||
'--bui-border-success',
|
||||
'--bui-shadow',
|
||||
];
|
||||
|
||||
const DEPRECATED_SET = new Set(DEPRECATED_TOKENS);
|
||||
|
||||
/**
|
||||
* Extracts all CSS custom property names referenced inside a string value,
|
||||
* e.g. "var(--bui-bg-solid)" → ["--bui-bg-solid"]
|
||||
* @param {string} value
|
||||
* @returns {string[]}
|
||||
*/
|
||||
function extractTokenNames(value) {
|
||||
const matches = value.match(/--bui-[\w-]+/g);
|
||||
return matches ?? [];
|
||||
}
|
||||
|
||||
/** @type {import('eslint').Rule.RuleModule} */
|
||||
module.exports = {
|
||||
meta: {
|
||||
type: 'suggestion',
|
||||
docs: {
|
||||
description:
|
||||
'Warn when deprecated Backstage UI CSS tokens are referenced in JS/TS string literals.',
|
||||
url: 'https://github.com/backstage/backstage/blob/master/packages/eslint-plugin/docs/rules/no-deprecated-bui-tokens.md',
|
||||
},
|
||||
messages: {
|
||||
deprecated:
|
||||
"'{{token}}' is a deprecated BUI token. Replace it with the appropriate current BUI token for its usage (for example, a semantic intent, surface/background, or shadow token); see this rule's migration guide for the correct mapping.",
|
||||
},
|
||||
schema: [],
|
||||
},
|
||||
|
||||
create(context) {
|
||||
/**
|
||||
* @param {import('estree').Node} node
|
||||
* @param {string} value
|
||||
*/
|
||||
function checkValue(node, value) {
|
||||
for (const token of extractTokenNames(value)) {
|
||||
if (DEPRECATED_SET.has(token)) {
|
||||
context.report({
|
||||
node,
|
||||
messageId: 'deprecated',
|
||||
data: { token },
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
Literal(node) {
|
||||
if (typeof node.value === 'string') {
|
||||
checkValue(node, node.value);
|
||||
}
|
||||
},
|
||||
|
||||
TemplateElement(node) {
|
||||
if (node.value?.cooked) {
|
||||
checkValue(node, node.value.cooked);
|
||||
}
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,257 @@
|
||||
/*
|
||||
* 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 { RuleTester } from 'eslint';
|
||||
import rule from '../rules/no-deprecated-bui-tokens';
|
||||
|
||||
const ruleTester = new RuleTester({
|
||||
parserOptions: {
|
||||
sourceType: 'module',
|
||||
ecmaVersion: 2021,
|
||||
},
|
||||
});
|
||||
|
||||
ruleTester.run('no-deprecated-bui-tokens', rule, {
|
||||
valid: [
|
||||
// Non-deprecated tokens — should not warn
|
||||
{ code: `const s = 'var(--bui-fg-primary)'` },
|
||||
{ code: `const s = 'var(--bui-fg-secondary)'` },
|
||||
{ code: `const s = 'var(--bui-fg-disabled)'` },
|
||||
{ code: `const s = 'var(--bui-fg-warning)'` },
|
||||
{ code: `const s = 'var(--bui-fg-positive)'` },
|
||||
{ code: `const s = 'var(--bui-fg-negative)'` },
|
||||
{ code: `const s = 'var(--bui-fg-announcement)'` },
|
||||
{ code: `const s = 'var(--bui-border-1)'` },
|
||||
{ code: `const s = 'var(--bui-border-2)'` },
|
||||
{ code: `const s = 'var(--bui-accent-bg)'` },
|
||||
{ code: `const s = 'var(--bui-accent-bg-hover)'` },
|
||||
{ code: `const s = 'var(--bui-accent-bg-disabled)'` },
|
||||
{ code: `const s = 'var(--bui-accent-fg)'` },
|
||||
{ code: `const s = 'var(--bui-accent-fg-disabled)'` },
|
||||
{ code: `const s = 'var(--bui-negative-bg)'` },
|
||||
{ code: `const s = 'var(--bui-positive-bg)'` },
|
||||
{ code: `const s = 'var(--bui-warning-bg)'` },
|
||||
{ code: `const s = 'var(--bui-announcement-bg)'` },
|
||||
{ code: `const s = 'var(--bui-gray-1)'` },
|
||||
{ code: `const s = 'var(--bui-bg-app)'` },
|
||||
{ code: `const s = 'var(--bui-bg-neutral-1)'` },
|
||||
{ code: `const s = 'var(--bui-bg-neutral-2)'` },
|
||||
{ code: `const s = 'var(--bui-bg-neutral-3)'` },
|
||||
{ code: `const s = 'var(--bui-bg-neutral-4)'` },
|
||||
// Unrelated strings — should not warn
|
||||
{ code: `const s = 'some-other-string'` },
|
||||
{ code: `const n = 42` },
|
||||
],
|
||||
|
||||
invalid: [
|
||||
// Plain string literals
|
||||
{
|
||||
code: `const s = 'var(--bui-bg-solid)'`,
|
||||
errors: [{ messageId: 'deprecated', data: { token: '--bui-bg-solid' } }],
|
||||
},
|
||||
{
|
||||
code: `const s = 'var(--bui-bg-solid-hover)'`,
|
||||
errors: [
|
||||
{ messageId: 'deprecated', data: { token: '--bui-bg-solid-hover' } },
|
||||
],
|
||||
},
|
||||
{
|
||||
code: `const s = 'var(--bui-bg-solid-pressed)'`,
|
||||
errors: [
|
||||
{ messageId: 'deprecated', data: { token: '--bui-bg-solid-pressed' } },
|
||||
],
|
||||
},
|
||||
{
|
||||
code: `const s = 'var(--bui-bg-solid-disabled)'`,
|
||||
errors: [
|
||||
{
|
||||
messageId: 'deprecated',
|
||||
data: { token: '--bui-bg-solid-disabled' },
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
code: `const s = 'var(--bui-bg-neutral-2-hover)'`,
|
||||
errors: [
|
||||
{
|
||||
messageId: 'deprecated',
|
||||
data: { token: '--bui-bg-neutral-2-hover' },
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
code: `const s = 'var(--bui-bg-neutral-3-pressed)'`,
|
||||
errors: [
|
||||
{
|
||||
messageId: 'deprecated',
|
||||
data: { token: '--bui-bg-neutral-3-pressed' },
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
code: `const s = 'var(--bui-bg-neutral-4-disabled)'`,
|
||||
errors: [
|
||||
{
|
||||
messageId: 'deprecated',
|
||||
data: { token: '--bui-bg-neutral-4-disabled' },
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
code: `const s = 'var(--bui-bg-danger)'`,
|
||||
errors: [{ messageId: 'deprecated', data: { token: '--bui-bg-danger' } }],
|
||||
},
|
||||
{
|
||||
code: `const s = 'var(--bui-bg-warning)'`,
|
||||
errors: [
|
||||
{ messageId: 'deprecated', data: { token: '--bui-bg-warning' } },
|
||||
],
|
||||
},
|
||||
{
|
||||
code: `const s = 'var(--bui-bg-success)'`,
|
||||
errors: [
|
||||
{ messageId: 'deprecated', data: { token: '--bui-bg-success' } },
|
||||
],
|
||||
},
|
||||
{
|
||||
code: `const s = 'var(--bui-bg-info)'`,
|
||||
errors: [{ messageId: 'deprecated', data: { token: '--bui-bg-info' } }],
|
||||
},
|
||||
{
|
||||
code: `const s = 'var(--bui-fg-solid)'`,
|
||||
errors: [{ messageId: 'deprecated', data: { token: '--bui-fg-solid' } }],
|
||||
},
|
||||
{
|
||||
code: `const s = 'var(--bui-fg-solid-disabled)'`,
|
||||
errors: [
|
||||
{ messageId: 'deprecated', data: { token: '--bui-fg-solid-disabled' } },
|
||||
],
|
||||
},
|
||||
{
|
||||
code: `const s = 'var(--bui-fg-danger-on-bg)'`,
|
||||
errors: [
|
||||
{ messageId: 'deprecated', data: { token: '--bui-fg-danger-on-bg' } },
|
||||
],
|
||||
},
|
||||
{
|
||||
code: `const s = 'var(--bui-fg-warning-on-bg)'`,
|
||||
errors: [
|
||||
{ messageId: 'deprecated', data: { token: '--bui-fg-warning-on-bg' } },
|
||||
],
|
||||
},
|
||||
{
|
||||
code: `const s = 'var(--bui-fg-success-on-bg)'`,
|
||||
errors: [
|
||||
{ messageId: 'deprecated', data: { token: '--bui-fg-success-on-bg' } },
|
||||
],
|
||||
},
|
||||
{
|
||||
code: `const s = 'var(--bui-fg-info-on-bg)'`,
|
||||
errors: [
|
||||
{ messageId: 'deprecated', data: { token: '--bui-fg-info-on-bg' } },
|
||||
],
|
||||
},
|
||||
{
|
||||
code: `const s = 'var(--bui-fg-danger)'`,
|
||||
errors: [{ messageId: 'deprecated', data: { token: '--bui-fg-danger' } }],
|
||||
},
|
||||
{
|
||||
code: `const s = 'var(--bui-fg-success)'`,
|
||||
errors: [
|
||||
{ messageId: 'deprecated', data: { token: '--bui-fg-success' } },
|
||||
],
|
||||
},
|
||||
{
|
||||
code: `const s = 'var(--bui-fg-info)'`,
|
||||
errors: [{ messageId: 'deprecated', data: { token: '--bui-fg-info' } }],
|
||||
},
|
||||
{
|
||||
code: `const s = 'var(--bui-border-info)'`,
|
||||
errors: [
|
||||
{ messageId: 'deprecated', data: { token: '--bui-border-info' } },
|
||||
],
|
||||
},
|
||||
{
|
||||
code: `const s = 'var(--bui-border-danger)'`,
|
||||
errors: [
|
||||
{ messageId: 'deprecated', data: { token: '--bui-border-danger' } },
|
||||
],
|
||||
},
|
||||
{
|
||||
code: `const s = 'var(--bui-border-warning)'`,
|
||||
errors: [
|
||||
{ messageId: 'deprecated', data: { token: '--bui-border-warning' } },
|
||||
],
|
||||
},
|
||||
{
|
||||
code: `const s = 'var(--bui-border-success)'`,
|
||||
errors: [
|
||||
{ messageId: 'deprecated', data: { token: '--bui-border-success' } },
|
||||
],
|
||||
},
|
||||
{
|
||||
code: `const s = 'var(--bui-shadow)'`,
|
||||
errors: [{ messageId: 'deprecated', data: { token: '--bui-shadow' } }],
|
||||
},
|
||||
|
||||
// Template literals
|
||||
{
|
||||
code: 'const s = `var(--bui-bg-solid)`',
|
||||
errors: [{ messageId: 'deprecated', data: { token: '--bui-bg-solid' } }],
|
||||
},
|
||||
{
|
||||
code: 'const s = `var(--bui-fg-danger)`',
|
||||
errors: [{ messageId: 'deprecated', data: { token: '--bui-fg-danger' } }],
|
||||
},
|
||||
{
|
||||
code: 'const s = `border: 1px solid var(--bui-border-danger)`',
|
||||
errors: [
|
||||
{ messageId: 'deprecated', data: { token: '--bui-border-danger' } },
|
||||
],
|
||||
},
|
||||
|
||||
// Multiple deprecated tokens in one string — one error per token
|
||||
{
|
||||
code: `const s = 'background: var(--bui-bg-solid); color: var(--bui-fg-solid)'`,
|
||||
errors: [
|
||||
{ messageId: 'deprecated', data: { token: '--bui-bg-solid' } },
|
||||
{ messageId: 'deprecated', data: { token: '--bui-fg-solid' } },
|
||||
],
|
||||
},
|
||||
|
||||
// Inline style usage patterns (JSX)
|
||||
{
|
||||
code: `const el = <div style={{ background: 'var(--bui-bg-danger)' }} />`,
|
||||
parserOptions: {
|
||||
sourceType: 'module',
|
||||
ecmaVersion: 2021,
|
||||
ecmaFeatures: { jsx: true },
|
||||
},
|
||||
errors: [{ messageId: 'deprecated', data: { token: '--bui-bg-danger' } }],
|
||||
},
|
||||
{
|
||||
code: `const el = <div style={{ color: 'var(--bui-fg-success)' }} />`,
|
||||
parserOptions: {
|
||||
sourceType: 'module',
|
||||
ecmaVersion: 2021,
|
||||
ecmaFeatures: { jsx: true },
|
||||
},
|
||||
errors: [
|
||||
{ messageId: 'deprecated', data: { token: '--bui-fg-success' } },
|
||||
],
|
||||
},
|
||||
],
|
||||
});
|
||||
@@ -3,7 +3,8 @@ module.exports = {
|
||||
extends: ['plugin:storybook/recommended'],
|
||||
rules: {
|
||||
'react/forbid-elements': 'off',
|
||||
'@backstage/no-mixed-plugin-imports': 'off'
|
||||
'@backstage/no-mixed-plugin-imports': 'off',
|
||||
'@backstage/no-deprecated-bui-tokens': 'warn',
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
@@ -14,192 +14,289 @@
|
||||
* 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',
|
||||
tags: ['!manifest'],
|
||||
});
|
||||
|
||||
/**
|
||||
* A `<div>` styled with `background: var(--bui-bg-inherit)` should always
|
||||
* resolve to the same color as the surrounding bg provider — at every level
|
||||
* of the neutral chain and inside intent surfaces.
|
||||
*/
|
||||
const Probe = ({ label }: { label: string }) => (
|
||||
type SwatchItem = { label: string; token: string };
|
||||
|
||||
const Swatch = ({ label, token }: SwatchItem) => (
|
||||
<div
|
||||
style={{
|
||||
backgroundColor: 'var(--bui-bg-inherit)',
|
||||
padding: '0.5rem 0.75rem',
|
||||
borderRadius: '0.25rem',
|
||||
outline: '1px dashed var(--bui-fg-secondary)',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
gap: '0.75rem',
|
||||
padding: '0.375rem 0',
|
||||
}}
|
||||
>
|
||||
<Text>{label}</Text>
|
||||
<div
|
||||
style={{
|
||||
width: 28,
|
||||
height: 28,
|
||||
borderRadius: 6,
|
||||
backgroundColor: `var(${token})`,
|
||||
border: '1px solid rgba(127 127 127 / 20%)',
|
||||
flexShrink: 0,
|
||||
}}
|
||||
/>
|
||||
<div style={{ display: 'flex', flexDirection: 'column', gap: 1 }}>
|
||||
<span
|
||||
style={{
|
||||
fontSize: '0.8125rem',
|
||||
color: 'var(--bui-fg-primary)',
|
||||
lineHeight: 1.3,
|
||||
}}
|
||||
>
|
||||
{label}
|
||||
</span>
|
||||
<span
|
||||
style={{
|
||||
fontSize: '0.6875rem',
|
||||
color: 'var(--bui-fg-secondary)',
|
||||
fontFamily: 'var(--bui-font-monospace)',
|
||||
lineHeight: 1.3,
|
||||
}}
|
||||
>
|
||||
{token}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
export const Default = meta.story({
|
||||
const Section = ({
|
||||
title,
|
||||
tokens,
|
||||
}: {
|
||||
title: string;
|
||||
tokens: SwatchItem[];
|
||||
}) => (
|
||||
<div style={{ display: 'flex', flexDirection: 'column', minWidth: 260 }}>
|
||||
<div
|
||||
style={{
|
||||
fontSize: '0.75rem',
|
||||
fontWeight: 600,
|
||||
textTransform: 'uppercase',
|
||||
letterSpacing: '0.06em',
|
||||
color: 'var(--bui-fg-secondary)',
|
||||
padding: '0.5rem 0',
|
||||
marginBottom: '0.25rem',
|
||||
borderBottom: '1px solid var(--bui-border-1)',
|
||||
}}
|
||||
>
|
||||
{title}
|
||||
</div>
|
||||
{tokens.map(t => (
|
||||
<Swatch key={t.token} {...t} />
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
|
||||
export const All = meta.story({
|
||||
name: 'All Colors',
|
||||
render: () => (
|
||||
<div style={{ backgroundColor: 'var(--bui-bg-app)' }}>
|
||||
<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
|
||||
style={{
|
||||
display: 'grid',
|
||||
gridTemplateColumns: 'repeat(auto-fill, minmax(260px, 1fr))',
|
||||
gap: '2.5rem 3rem',
|
||||
padding: '2rem',
|
||||
}}
|
||||
>
|
||||
<Section
|
||||
title="Gray Scale"
|
||||
tokens={[
|
||||
{ label: 'Gray 1', token: '--bui-gray-1' },
|
||||
{ label: 'Gray 2', token: '--bui-gray-2' },
|
||||
{ label: 'Gray 3', token: '--bui-gray-3' },
|
||||
{ label: 'Gray 4', token: '--bui-gray-4' },
|
||||
{ label: 'Gray 5', token: '--bui-gray-5' },
|
||||
{ label: 'Gray 6', token: '--bui-gray-6' },
|
||||
{ label: 'Gray 7', token: '--bui-gray-7' },
|
||||
{ label: 'Gray 8', token: '--bui-gray-8' },
|
||||
{ label: 'Gray 9', token: '--bui-gray-9' },
|
||||
{ label: 'Gray 10', token: '--bui-gray-10' },
|
||||
{ label: 'Gray 11', token: '--bui-gray-11' },
|
||||
]}
|
||||
/>
|
||||
|
||||
<Section
|
||||
title="Neutral Backgrounds"
|
||||
tokens={[
|
||||
{ label: 'App', token: '--bui-bg-app' },
|
||||
{ label: 'Neutral 1', token: '--bui-bg-neutral-1' },
|
||||
{ label: 'Neutral 2', token: '--bui-bg-neutral-2' },
|
||||
{ label: 'Neutral 3', token: '--bui-bg-neutral-3' },
|
||||
{ label: 'Neutral 4', token: '--bui-bg-neutral-4' },
|
||||
]}
|
||||
/>
|
||||
|
||||
<Section
|
||||
title="Foreground"
|
||||
tokens={[
|
||||
{ label: 'Primary', token: '--bui-fg-primary' },
|
||||
{ label: 'Secondary', token: '--bui-fg-secondary' },
|
||||
{ label: 'Disabled', token: '--bui-fg-disabled' },
|
||||
{ label: 'Positive', token: '--bui-fg-positive' },
|
||||
{ label: 'Negative', token: '--bui-fg-negative' },
|
||||
{ label: 'Warning', token: '--bui-fg-warning' },
|
||||
{ label: 'Announcement', token: '--bui-fg-announcement' },
|
||||
]}
|
||||
/>
|
||||
|
||||
<Section
|
||||
title="Border"
|
||||
tokens={[
|
||||
{ label: 'Border 1', token: '--bui-border-1' },
|
||||
{ label: 'Border 2', token: '--bui-border-2' },
|
||||
]}
|
||||
/>
|
||||
|
||||
<Section
|
||||
title="Accent"
|
||||
tokens={[
|
||||
{ label: 'Bg', token: '--bui-accent-bg' },
|
||||
{ label: 'Bg - Hover', token: '--bui-accent-bg-hover' },
|
||||
{ label: 'Bg - Disabled', token: '--bui-accent-bg-disabled' },
|
||||
{ label: 'Fg', token: '--bui-accent-fg' },
|
||||
{ label: 'Fg - Disabled', token: '--bui-accent-fg-disabled' },
|
||||
]}
|
||||
/>
|
||||
|
||||
<Section
|
||||
title="Announcement"
|
||||
tokens={[
|
||||
{ label: 'Bg - Base', token: '--bui-announcement-bg' },
|
||||
{
|
||||
label: 'Bg - Base - Hover',
|
||||
token: '--bui-announcement-bg-hover',
|
||||
},
|
||||
{
|
||||
label: 'Bg - Base - Disabled',
|
||||
token: '--bui-announcement-bg-disabled',
|
||||
},
|
||||
{ label: 'Bg - Subdued', token: '--bui-announcement-bg-subdued' },
|
||||
{
|
||||
label: 'Bg - Subdued - Hover',
|
||||
token: '--bui-announcement-bg-subdued-hover',
|
||||
},
|
||||
{
|
||||
label: 'Bg - Subdued - Disabled',
|
||||
token: '--bui-announcement-bg-subdued-disabled',
|
||||
},
|
||||
{ label: 'Border', token: '--bui-announcement-border' },
|
||||
{ label: 'Fg - On Base', token: '--bui-announcement-fg' },
|
||||
{
|
||||
label: 'Fg - On Base - Disabled',
|
||||
token: '--bui-announcement-fg-disabled',
|
||||
},
|
||||
{
|
||||
label: 'Fg - On Subdued',
|
||||
token: '--bui-announcement-fg-subdued',
|
||||
},
|
||||
{
|
||||
label: 'Fg - On Subdued - Disabled',
|
||||
token: '--bui-announcement-fg-subdued-disabled',
|
||||
},
|
||||
]}
|
||||
/>
|
||||
|
||||
<Section
|
||||
title="Warning"
|
||||
tokens={[
|
||||
{ label: 'Bg - Base', token: '--bui-warning-bg' },
|
||||
{ label: 'Bg - Base - Hover', token: '--bui-warning-bg-hover' },
|
||||
{
|
||||
label: 'Bg - Base - Disabled',
|
||||
token: '--bui-warning-bg-disabled',
|
||||
},
|
||||
{ label: 'Bg - Subdued', token: '--bui-warning-bg-subdued' },
|
||||
{
|
||||
label: 'Bg - Subdued - Hover',
|
||||
token: '--bui-warning-bg-subdued-hover',
|
||||
},
|
||||
{
|
||||
label: 'Bg - Subdued - Disabled',
|
||||
token: '--bui-warning-bg-subdued-disabled',
|
||||
},
|
||||
{ label: 'Border', token: '--bui-warning-border' },
|
||||
{ label: 'Fg - On Base', token: '--bui-warning-fg' },
|
||||
{
|
||||
label: 'Fg - On Base - Disabled',
|
||||
token: '--bui-warning-fg-disabled',
|
||||
},
|
||||
{ label: 'Fg - On Subdued', token: '--bui-warning-fg-subdued' },
|
||||
{
|
||||
label: 'Fg - On Subdued - Disabled',
|
||||
token: '--bui-warning-fg-subdued-disabled',
|
||||
},
|
||||
]}
|
||||
/>
|
||||
|
||||
<Section
|
||||
title="Negative"
|
||||
tokens={[
|
||||
{ label: 'Bg - Base', token: '--bui-negative-bg' },
|
||||
{ label: 'Bg - Base - Hover', token: '--bui-negative-bg-hover' },
|
||||
{
|
||||
label: 'Bg - Base - Disabled',
|
||||
token: '--bui-negative-bg-disabled',
|
||||
},
|
||||
{ label: 'Bg - Subdued', token: '--bui-negative-bg-subdued' },
|
||||
{
|
||||
label: 'Bg - Subdued - Hover',
|
||||
token: '--bui-negative-bg-subdued-hover',
|
||||
},
|
||||
{
|
||||
label: 'Bg - Subdued - Disabled',
|
||||
token: '--bui-negative-bg-subdued-disabled',
|
||||
},
|
||||
{ label: 'Border', token: '--bui-negative-border' },
|
||||
{ label: 'Fg - On Base', token: '--bui-negative-fg' },
|
||||
{
|
||||
label: 'Fg - On Base - Disabled',
|
||||
token: '--bui-negative-fg-disabled',
|
||||
},
|
||||
{ label: 'Fg - On Subdued', token: '--bui-negative-fg-subdued' },
|
||||
{
|
||||
label: 'Fg - On Subdued - Disabled',
|
||||
token: '--bui-negative-fg-subdued-disabled',
|
||||
},
|
||||
]}
|
||||
/>
|
||||
|
||||
<Section
|
||||
title="Positive"
|
||||
tokens={[
|
||||
{ label: 'Bg - Base', token: '--bui-positive-bg' },
|
||||
{ label: 'Bg - Base - Hover', token: '--bui-positive-bg-hover' },
|
||||
{
|
||||
label: 'Bg - Base - Disabled',
|
||||
token: '--bui-positive-bg-disabled',
|
||||
},
|
||||
{ label: 'Bg - Subdued', token: '--bui-positive-bg-subdued' },
|
||||
{
|
||||
label: 'Bg - Subdued - Hover',
|
||||
token: '--bui-positive-bg-subdued-hover',
|
||||
},
|
||||
{
|
||||
label: 'Bg - Subdued - Disabled',
|
||||
token: '--bui-positive-bg-subdued-disabled',
|
||||
},
|
||||
{ label: 'Border', token: '--bui-positive-border' },
|
||||
{ label: 'Fg - On Base', token: '--bui-positive-fg' },
|
||||
{
|
||||
label: 'Fg - On Base - Disabled',
|
||||
token: '--bui-positive-fg-disabled',
|
||||
},
|
||||
{ label: 'Fg - On Subdued', token: '--bui-positive-fg-subdued' },
|
||||
{
|
||||
label: 'Fg - On Subdued - Disabled',
|
||||
token: '--bui-positive-fg-subdued-disabled',
|
||||
},
|
||||
]}
|
||||
/>
|
||||
</div>
|
||||
),
|
||||
});
|
||||
|
||||
export const BgInherit = meta.story({
|
||||
render: () => (
|
||||
<Flex direction="column" gap="4">
|
||||
<Probe label="App level (no provider) — resolves to --bui-bg-app" />
|
||||
|
||||
<Box bg="neutral" p="4">
|
||||
<Flex direction="column" gap="3">
|
||||
<Probe label="Inside neutral-1 — resolves to --bui-bg-neutral-1" />
|
||||
<Box bg="neutral" p="4">
|
||||
<Flex direction="column" gap="3">
|
||||
<Probe label="Inside neutral-2 — resolves to --bui-bg-neutral-2" />
|
||||
<Box bg="neutral" p="4">
|
||||
<Probe label="Inside neutral-3 — resolves to --bui-bg-neutral-3" />
|
||||
</Box>
|
||||
</Flex>
|
||||
</Box>
|
||||
</Flex>
|
||||
</Box>
|
||||
|
||||
<Box bg="danger" p="4">
|
||||
<Probe label="Inside danger — resolves to --bui-bg-danger" />
|
||||
</Box>
|
||||
|
||||
<Box bg="warning" p="4">
|
||||
<Probe label="Inside warning — resolves to --bui-bg-warning" />
|
||||
</Box>
|
||||
|
||||
<Box bg="success" p="4">
|
||||
<Probe label="Inside success — resolves to --bui-bg-success" />
|
||||
</Box>
|
||||
</Flex>
|
||||
),
|
||||
});
|
||||
|
||||
+184
-68
@@ -67,150 +67,266 @@
|
||||
--bui-radius-6: calc(1.25rem);
|
||||
--bui-radius-full: 9999px;
|
||||
|
||||
/* Animations */
|
||||
--bui-animate-pulse: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
|
||||
|
||||
/* Base Colors */
|
||||
--bui-black: #000000;
|
||||
--bui-white: #ffffff;
|
||||
--bui-ring: #1f5493;
|
||||
--bui-scrollbar: #a0a0a03b;
|
||||
--bui-scrollbar-thumb: #a0a0a0;
|
||||
|
||||
/* Solid background colors */
|
||||
/* Gray scale */
|
||||
--bui-gray-1: #fafafa;
|
||||
--bui-gray-2: #f5f5f5;
|
||||
--bui-gray-3: #e5e5e5;
|
||||
--bui-gray-4: #d4d4d4;
|
||||
--bui-gray-5: #a1a1a1;
|
||||
--bui-gray-6: #737373;
|
||||
--bui-gray-7: #525252;
|
||||
--bui-gray-8: #404040;
|
||||
--bui-gray-9: #262626;
|
||||
--bui-gray-10: #171717;
|
||||
--bui-gray-11: #0a0a0a;
|
||||
|
||||
/* Neutral background colors */
|
||||
--bui-bg-app: #f5f5f5;
|
||||
--bui-bg-neutral-1: var(--bui-white);
|
||||
--bui-bg-neutral-2: #f7f7f7;
|
||||
--bui-bg-neutral-3: var(--bui-white);
|
||||
--bui-bg-neutral-4: #f7f7f7;
|
||||
|
||||
/* Foreground colors */
|
||||
--bui-fg-primary: var(--bui-black);
|
||||
--bui-fg-secondary: #696969;
|
||||
--bui-fg-disabled: #aaaaaa;
|
||||
--bui-fg-positive: #1abc54;
|
||||
--bui-fg-negative: #ee3a4c;
|
||||
--bui-fg-warning: #f18900;
|
||||
--bui-fg-announcement: #2a86f3;
|
||||
|
||||
/* Border colors */
|
||||
--bui-border-1: var(--bui-gray-3);
|
||||
--bui-border-2: var(--bui-gray-6);
|
||||
|
||||
/* Accent */
|
||||
--bui-accent-bg: #1f5493;
|
||||
--bui-accent-bg-hover: #163a66;
|
||||
--bui-accent-bg-disabled: #163a66;
|
||||
--bui-accent-fg: #ffffff;
|
||||
--bui-accent-fg-disabled: #98a8bc;
|
||||
|
||||
/* Announcement */
|
||||
--bui-announcement-bg: #0d72ea;
|
||||
--bui-announcement-bg-hover: #2b88f5;
|
||||
--bui-announcement-bg-disabled: #0d72ea;
|
||||
--bui-announcement-bg-subdued: #c8e0fc;
|
||||
--bui-announcement-bg-subdued-hover: #e0edfd;
|
||||
--bui-announcement-bg-subdued-disabled: #c8e0fc;
|
||||
--bui-announcement-border: #549ef4;
|
||||
--bui-announcement-fg: #ffffff;
|
||||
--bui-announcement-fg-disabled: #a4ccfb;
|
||||
--bui-announcement-fg-subdued: #173da6;
|
||||
--bui-announcement-fg-subdued-disabled: #7391e3;
|
||||
|
||||
/* Warning */
|
||||
--bui-warning-bg: #ff9400;
|
||||
--bui-warning-bg-hover: #ffb656;
|
||||
--bui-warning-bg-disabled: #ff9400;
|
||||
--bui-warning-bg-subdued: #ffedd5;
|
||||
--bui-warning-bg-subdued-hover: #f8ddb9;
|
||||
--bui-warning-bg-subdued-disabled: #f8ddb9;
|
||||
--bui-warning-border: #ff9400;
|
||||
--bui-warning-fg: #000000;
|
||||
--bui-warning-fg-disabled: #aa4d00;
|
||||
--bui-warning-fg-subdued: #aa4d00;
|
||||
--bui-warning-fg-subdued-disabled: #e3a572;
|
||||
|
||||
/* Negative */
|
||||
--bui-negative-bg: #dc2626;
|
||||
--bui-negative-bg-hover: #f44b4b;
|
||||
--bui-negative-bg-disabled: #ff8686;
|
||||
--bui-negative-bg-subdued: #ffcbcb;
|
||||
--bui-negative-bg-subdued-hover: #f7b6b6;
|
||||
--bui-negative-bg-subdued-disabled: #f7b6b6;
|
||||
--bui-negative-border: #d06565;
|
||||
--bui-negative-fg: #ffffff;
|
||||
--bui-negative-fg-disabled: #f7b6b6;
|
||||
--bui-negative-fg-subdued: #991919;
|
||||
--bui-negative-fg-subdued-disabled: #bb7272;
|
||||
|
||||
/* Positive */
|
||||
--bui-positive-bg: #1ed760;
|
||||
--bui-positive-bg-hover: #3be477;
|
||||
--bui-positive-bg-disabled: #1abc54;
|
||||
--bui-positive-bg-subdued: #96f0b6;
|
||||
--bui-positive-bg-subdued-hover: #c5f7d7;
|
||||
--bui-positive-bg-subdued-disabled: #96f0b6;
|
||||
--bui-positive-border: #54a671;
|
||||
--bui-positive-fg: #000000;
|
||||
--bui-positive-fg-disabled: #0c632b;
|
||||
--bui-positive-fg-subdued: #0c632b;
|
||||
--bui-positive-fg-subdued-disabled: #4b9666;
|
||||
|
||||
/* Deprecated tokens */
|
||||
--bui-bg-solid: #1f5493;
|
||||
--bui-bg-solid-hover: #163a66;
|
||||
--bui-bg-solid-pressed: #0f2b4e;
|
||||
--bui-bg-solid-disabled: #163a66;
|
||||
|
||||
/* Neutral background colors */
|
||||
--bui-bg-app: #f8f8f8;
|
||||
|
||||
--bui-bg-neutral-1: #fff;
|
||||
--bui-bg-neutral-1-hover: oklch(0% 0 0 / 6%);
|
||||
--bui-bg-neutral-1-pressed: oklch(0% 0 0 / 12%);
|
||||
--bui-bg-neutral-1-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-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;
|
||||
--bui-bg-warning: #ffedd5;
|
||||
--bui-bg-success: #dcfce7;
|
||||
--bui-bg-info: #dbeafe;
|
||||
|
||||
/* Foreground colors */
|
||||
--bui-fg-primary: var(--bui-black);
|
||||
--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;
|
||||
|
||||
/* Foreground Statuses */
|
||||
--bui-fg-danger-on-bg: #991919;
|
||||
--bui-fg-warning-on-bg: #92310a;
|
||||
--bui-fg-success-on-bg: #116932;
|
||||
--bui-fg-info-on-bg: #173da6;
|
||||
--bui-fg-danger: #ec3b18;
|
||||
--bui-fg-warning: #ef7a32;
|
||||
--bui-fg-success: #1aaf4f;
|
||||
--bui-fg-info: #0d74ce;
|
||||
|
||||
/* Border colors */
|
||||
--bui-border-1: #d5d5d5;
|
||||
--bui-border-2: #bababa;
|
||||
--bui-border-info: #7ea9d6;
|
||||
--bui-border-danger: #f87a7a;
|
||||
--bui-border-warning: #e36d05;
|
||||
--bui-border-success: #53db83;
|
||||
|
||||
/* Special colors */
|
||||
--bui-ring: #1f5493;
|
||||
--bui-scrollbar: #a0a0a03b;
|
||||
--bui-scrollbar-thumb: #a0a0a0;
|
||||
|
||||
/* Shadows */
|
||||
--bui-shadow: 0 10px 15px -3px rgba(0 0 0 / 0.1),
|
||||
0 4px 6px -4px rgba(0 0 0 / 0.1);
|
||||
|
||||
--bui-animate-pulse: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
|
||||
}
|
||||
|
||||
/* Dark theme tokens */
|
||||
[data-theme-mode='dark'] {
|
||||
/* Solid background colors */
|
||||
/* Base colors */
|
||||
--bui-ring: #1f5493;
|
||||
--bui-scrollbar: #3636363a;
|
||||
--bui-scrollbar-thumb: #575757;
|
||||
|
||||
/* Neutral background colors */
|
||||
--bui-bg-app: #333333;
|
||||
--bui-bg-neutral-1: #1a1a1a;
|
||||
--bui-bg-neutral-2: #282828;
|
||||
--bui-bg-neutral-3: #393939;
|
||||
--bui-bg-neutral-4: #474747;
|
||||
|
||||
/* Foreground colors */
|
||||
--bui-fg-primary: var(--bui-white);
|
||||
--bui-fg-secondary: #a3a3a3;
|
||||
--bui-fg-disabled: var(--bui-white);
|
||||
--bui-fg-positive: #21b656;
|
||||
--bui-fg-negative: #ee3a4c;
|
||||
--bui-fg-warning: #f18900;
|
||||
--bui-fg-announcement: #2a86f3;
|
||||
|
||||
/* Border colors */
|
||||
--bui-border-1: var(--bui-gray-6);
|
||||
--bui-border-2: var(--bui-gray-5);
|
||||
|
||||
/* Accent */
|
||||
--bui-accent-bg: #9cc9ff;
|
||||
--bui-accent-bg-hover: #83b9fd;
|
||||
--bui-accent-bg-disabled: #3b6293;
|
||||
--bui-accent-fg: #101821;
|
||||
--bui-accent-fg-disabled: #6191cc;
|
||||
|
||||
/* Announcement */
|
||||
--bui-announcement-bg: #0d72ea;
|
||||
--bui-announcement-bg-hover: #2b88f5;
|
||||
--bui-announcement-bg-disabled: #0d72ea;
|
||||
--bui-announcement-bg-subdued: #052a56;
|
||||
--bui-announcement-bg-subdued-hover: #0c3d77;
|
||||
--bui-announcement-bg-subdued-disabled: #052a56;
|
||||
--bui-announcement-border: #2363af;
|
||||
--bui-announcement-fg: #ffffff;
|
||||
--bui-announcement-fg-disabled: #70b8ff;
|
||||
--bui-announcement-fg-subdued: #70b8ff;
|
||||
--bui-announcement-fg-subdued-disabled: #4275a6;
|
||||
|
||||
/* Warning */
|
||||
--bui-warning-bg: #ffa42c;
|
||||
--bui-warning-bg-hover: #ffb656;
|
||||
--bui-warning-bg-disabled: #ffb656;
|
||||
--bui-warning-bg-subdued: #491e00;
|
||||
--bui-warning-bg-subdued-hover: #612901;
|
||||
--bui-warning-bg-subdued-disabled: #582400;
|
||||
--bui-warning-border: #7c4903;
|
||||
--bui-warning-fg: #000000;
|
||||
--bui-warning-fg-disabled: #aa4d00;
|
||||
--bui-warning-fg-subdued: #f2ab4a;
|
||||
--bui-warning-fg-subdued-disabled: #aa4d00;
|
||||
|
||||
/* Negative */
|
||||
--bui-negative-bg: #dc2626;
|
||||
--bui-negative-bg-hover: #f44b4b;
|
||||
--bui-negative-bg-disabled: #dc2626;
|
||||
--bui-negative-bg-subdued: #350708;
|
||||
--bui-negative-bg-subdued-hover: #5e1a1b;
|
||||
--bui-negative-bg-subdued-disabled: #5e1a1b;
|
||||
--bui-negative-border: #6f101c;
|
||||
--bui-negative-fg: #ffffff;
|
||||
--bui-negative-fg-disabled: #f7b6b6;
|
||||
--bui-negative-fg-subdued: #fca5a5;
|
||||
--bui-negative-fg-subdued-disabled: #bb7272;
|
||||
|
||||
/* Positive */
|
||||
--bui-positive-bg: #1ed760;
|
||||
--bui-positive-bg-hover: #3be477;
|
||||
--bui-positive-bg-disabled: #1abc54;
|
||||
--bui-positive-bg-subdued: #073116;
|
||||
--bui-positive-bg-subdued-hover: #0b431f;
|
||||
--bui-positive-bg-subdued-disabled: #073116;
|
||||
--bui-positive-border: #136d33;
|
||||
--bui-positive-fg: #000000;
|
||||
--bui-positive-fg-disabled: #0c632b;
|
||||
--bui-positive-fg-subdued: #8ddeaa;
|
||||
--bui-positive-fg-subdued-disabled: #509c6b;
|
||||
|
||||
/* Deprecated tokens */
|
||||
--bui-bg-solid: #9cc9ff;
|
||||
--bui-bg-solid-hover: #83b9fd;
|
||||
--bui-bg-solid-pressed: #83b9fd;
|
||||
--bui-bg-solid-disabled: #1b3d68;
|
||||
|
||||
/* Neutral background colors */
|
||||
--bui-bg-app: #333333;
|
||||
|
||||
--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-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-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;
|
||||
--bui-bg-warning: #302008;
|
||||
--bui-bg-success: #042713;
|
||||
--bui-bg-info: #132049;
|
||||
|
||||
/* Foreground colors */
|
||||
--bui-fg-primary: var(--bui-white);
|
||||
--bui-fg-secondary: oklch(100% 0 0 / 50%);
|
||||
--bui-fg-disabled: oklch(100% 0 0 / 28%);
|
||||
--bui-fg-solid: #101821;
|
||||
--bui-fg-solid-disabled: #6191cc;
|
||||
|
||||
/* Foreground statuses */
|
||||
--bui-fg-danger-on-bg: #fca5a5;
|
||||
--bui-fg-warning-on-bg: #fdba74;
|
||||
--bui-fg-success-on-bg: #86efac;
|
||||
--bui-fg-info-on-bg: #a3cfff;
|
||||
--bui-fg-danger: #ff5a30;
|
||||
--bui-fg-warning: #ffa057;
|
||||
--bui-fg-success: #1ed760;
|
||||
--bui-fg-info: #70b8ff;
|
||||
|
||||
/* Border colors */
|
||||
--bui-border-1: #434343;
|
||||
--bui-border-2: #585858;
|
||||
--bui-border-info: #7ea9d6;
|
||||
--bui-border-danger: #f87a7a;
|
||||
--bui-border-warning: #e36d05;
|
||||
--bui-border-success: #53db83;
|
||||
|
||||
/* Special colors */
|
||||
--bui-ring: #1f5493;
|
||||
--bui-scrollbar: #3636363a;
|
||||
--bui-scrollbar-thumb: #575757;
|
||||
|
||||
/* Shadows */
|
||||
--bui-shadow: none;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user