feat(ui): introduce semantic color token families and deprecate legacy tokens
Redesigns the BUI color token system in `@backstage/ui`: - Adds a gray scale (`--bui-gray-1` through `--bui-gray-11`) - Adds new foreground tokens with explicit hex values (primary, secondary, disabled, positive, negative, warning, announcement) - Introduces five new semantic color families — Accent, Announcement, Warning, Negative, Positive — each with bg-base, bg-subdued, border, fg-on-base, and fg-on-subdued variants, for both light and dark themes - Moves all legacy tokens (`--bui-bg-solid-*`, `--bui-bg-neutral-*`, `--bui-bg-danger/warning/success/info`, `--bui-fg-solid`, `--bui-fg-danger/success/info`, `--bui-border-*`, `--bui-shadow`) into a clearly marked `/* Deprecated tokens */` section in both light and dark themes - Updates the Spotify theme overrides to use the new accent tokens and mark legacy overrides as deprecated - Rewrites the `Colors` Storybook story to display all token families as a live, theme-aware reference grid - Adds a new `@backstage/no-deprecated-bui-tokens` ESLint rule to `@backstage/eslint-plugin` that warns when any deprecated BUI token is referenced in JS/TS string literals; the rule is included in the `recommended` config so it applies to all plugin authors automatically Signed-off-by: Charles de Dreuille <charles.dedreuille@gmail.com>
This commit is contained in:
@@ -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,122 @@
|
||||
/*
|
||||
* 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-app',
|
||||
'--bui-bg-neutral-1',
|
||||
'--bui-bg-neutral-1-hover',
|
||||
'--bui-bg-neutral-1-pressed',
|
||||
'--bui-bg-neutral-1-disabled',
|
||||
'--bui-bg-neutral-2',
|
||||
'--bui-bg-neutral-2-hover',
|
||||
'--bui-bg-neutral-2-pressed',
|
||||
'--bui-bg-neutral-2-disabled',
|
||||
'--bui-bg-neutral-3',
|
||||
'--bui-bg-neutral-3-hover',
|
||||
'--bui-bg-neutral-3-pressed',
|
||||
'--bui-bg-neutral-3-disabled',
|
||||
'--bui-bg-neutral-4',
|
||||
'--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. Use the new semantic token families instead: --bui-negative-*, --bui-positive-*, --bui-warning-*, --bui-announcement-*, or --bui-accent-*.",
|
||||
},
|
||||
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);
|
||||
}
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
Reference in New Issue
Block a user