[DRAFT] feat: add design token css variable bridge#9805
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #9805 +/- ##
=======================================
Coverage 91.40% 91.40%
=======================================
Files 577 577
Lines 23847 23847
Branches 4186 4186
=======================================
Hits 21797 21797
Misses 1522 1522
Partials 528 528 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Pull request overview
This PR introduces an initial “design token → CSS variable” bridge for NG-ZORRO’s styling system by defining a token schema, generating token-backed CSS variables, documenting the token/variable mapping, and updating parts of the variable theme to consume the new CSS variables.
Changes:
- Added a token definition registry (
definitions.ts) plus a generator script to emittoken-css-variables.lessandtoken-map.md. - Updated
variable.lessto import the generated token CSS variables and switched several component/theme Less variables (e.g. Button, Card, Tag, Alert) tovar(--ant-*)sources. - Added documentation (
components/style/tokens/README.md,token-map.md) and an npm script (generate:tokens) to run the generator.
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
| scripts/build/generate-design-tokens.ts | New generator that renders token CSS variables + mapping docs from token definitions. |
| package.json | Adds generate:tokens script to run the token generator via tsx. |
| components/style/tokens/token-map.md | Generated markdown mapping table documenting token ↔ Less variable ↔ CSS variable. |
| components/style/tokens/README.md | Docs describing token layers/stability and how to run the generator. |
| components/style/tokens/definitions.ts | Source-of-truth token schema/values used by the generator. |
| components/style/themes/variable.less | Imports generated token CSS vars and maps selected Less vars to token CSS variables. |
| components/style/themes/token-css-variables.less | Generated Less that emits --ant-* CSS variables for defined tokens. |
Comments suppressed due to low confidence (1)
components/style/themes/variable.less:79
token-css-variables.lessgenerates token variables like--@{ant-prefix}-color-primary, but the core Less variables here (@primary-color,@success-color,@info-color, etc.) still read from the legacy CSS variables (--@{ant-prefix}-primary-color,--@{ant-prefix}-success-color, ...). As a result, overriding the documented token CSS variables (e.g.--ant-color-primary) will not affect the actual theme output. Please either align the token CSS variable names with the legacy ones (viacssVariableoverrides in token definitions), or update the legacy variables/derivations so the legacy variables fall back to the token variables (without introducing cyclicvar()references).
@import './token-css-variables';
// -------- Colors -----------
// >>> Primary
@primary-color: ~'var(--@{ant-prefix}-primary-color)';
@primary-color-hover: ~'var(--@{ant-prefix}-primary-color-hover)';
@primary-color-active: ~'var(--@{ant-prefix}-primary-color-active)';
@primary-color-outline: ~'var(--@{ant-prefix}-primary-color-outline)';
| @card-padding-base-sm: (@card-padding-base / 2); | ||
| @card-actions-background: @component-background; | ||
| @card-padding-base: ~'var(--@{ant-prefix}-card-padding)'; | ||
| @card-padding-base-sm: 12px; |
| layer: 'component', | ||
| stability: 'stable', | ||
| lessVariable: '@card-shadow', | ||
| lessValue: '0 1px 2px -2px rgb(0, 0, 0, 0.16), 0 3px 6px 0 rgb(0, 0, 0, 0.12), 0 5px 12px 4px rgb(0, 0, 0, 0.09)', |
| path: 'button.shadow', | ||
| layer: 'component', | ||
| stability: 'stable', | ||
| lessVariable: '@btn-shadow', | ||
| lessValue: '0 2px 0 rgb(0, 0, 0, 0.015)', | ||
| description: 'Default Button shadow.' | ||
| }, | ||
| { | ||
| path: 'button.primaryShadow', | ||
| layer: 'component', | ||
| stability: 'stable', | ||
| lessVariable: '@btn-primary-shadow', | ||
| lessValue: '0 2px 0 rgb(0, 0, 0, 0.045)', | ||
| description: 'Primary Button shadow.' |
| --@{ant-prefix}-card-actions-bg: @component-background; | ||
| --@{ant-prefix}-card-radius: @border-radius-base; | ||
| --@{ant-prefix}-card-shadow: 0 1px 2px -2px rgb(0, 0, 0, 0.16), 0 3px 6px 0 rgb(0, 0, 0, 0.12), 0 5px 12px 4px rgb(0, 0, 0, 0.09); | ||
| --@{ant-prefix}-button-primary-bg: @primary-color; |
| --@{ant-prefix}-button-border-radius: @border-radius-base; | ||
| --@{ant-prefix}-button-border-radius-sm: @border-radius-base; | ||
| --@{ant-prefix}-button-shadow: 0 2px 0 rgb(0, 0, 0, 0.015); | ||
| --@{ant-prefix}-button-primary-shadow: 0 2px 0 rgb(0, 0, 0, 0.045); |
| | `card.padding` | component | stable | `@card-padding-base` | `--ant-card-padding` | `24px` | | ||
| | `card.actionsBg` | component | stable | `@card-actions-background` | `--ant-card-actions-bg` | `@component-background` | | ||
| | `card.radius` | component | stable | `@card-radius` | `--ant-card-radius` | `@border-radius-base` | | ||
| | `card.shadow` | component | stable | `@card-shadow` | `--ant-card-shadow` | `0 1px 2px -2px rgb(0, 0, 0, 0.16), 0 3px 6px 0 rgb(0, 0, 0, 0.12), 0 5px 12px 4px rgb(0, 0, 0, 0.09)` | |
| | `button.shadow` | component | stable | `@btn-shadow` | `--ant-button-shadow` | `0 2px 0 rgb(0, 0, 0, 0.015)` | | ||
| | `button.primaryShadow` | component | stable | `@btn-primary-shadow` | `--ant-button-primary-shadow` | `0 2px 0 rgb(0, 0, 0, 0.045)` | |
There was a problem hiding this comment.
Code Review
This pull request introduces a structured design token system to NG-ZORRO, transitioning from static Less variables to dynamic CSS variables. It includes a new token definition schema in TypeScript, a generation script to produce Less theme files and documentation, and updates to the core variable.less to consume these tokens. Feedback from the reviewer highlights a regression in maintainability where a dynamic calculation for card padding was replaced by a hardcoded value, suggesting the use of CSS calc() instead. Additionally, several instances of hardcoded rgb() values with alpha channels were flagged for replacement with rgba() to ensure better compatibility with older tools and consistency with the existing codebase.
| @card-padding-base-sm: (@card-padding-base / 2); | ||
| @card-actions-background: @component-background; | ||
| @card-padding-base: ~'var(--@{ant-prefix}-card-padding)'; | ||
| @card-padding-base-sm: 12px; |
There was a problem hiding this comment.
Changing the dynamic calculation (@card-padding-base / 2) to a hardcoded 12px is a regression in maintainability. Since @card-padding-base is now mapped to a CSS variable, Less cannot perform arithmetic on it at compile time. You should use the CSS calc() function to maintain the relationship between base and small padding.
@card-padding-base-sm: ~'calc(@{card-padding-base} / 2)';
| layer: 'component', | ||
| stability: 'stable', | ||
| lessVariable: '@card-shadow', | ||
| lessValue: '0 1px 2px -2px rgb(0, 0, 0, 0.16), 0 3px 6px 0 rgb(0, 0, 0, 0.12), 0 5px 12px 4px rgb(0, 0, 0, 0.09)', |
There was a problem hiding this comment.
The shadow values are hardcoded with rgb() and fixed alpha values. This makes them non-reactive to theme changes (e.g., if @black or a base shadow color is changed). It is better to use rgba() for better compatibility and consistency with the existing codebase, or ideally reference Less variables.
| lessValue: '0 1px 2px -2px rgb(0, 0, 0, 0.16), 0 3px 6px 0 rgb(0, 0, 0, 0.12), 0 5px 12px 4px rgb(0, 0, 0, 0.09)', | |
| lessValue: '0 1px 2px -2px rgba(0, 0, 0, 0.16), 0 3px 6px 0 rgba(0, 0, 0, 0.12), 0 5px 12px 4px rgba(0, 0, 0, 0.09)', |
| layer: 'component', | ||
| stability: 'stable', | ||
| lessVariable: '@btn-shadow', | ||
| lessValue: '0 2px 0 rgb(0, 0, 0, 0.015)', |
There was a problem hiding this comment.
Using rgb() with four arguments is part of CSS Colors Level 4. For broader compatibility with older tools and consistency with the rest of the repository, rgba() is preferred for colors with alpha channels.
| lessValue: '0 2px 0 rgb(0, 0, 0, 0.015)', | |
| lessValue: '0 2px 0 rgba(0, 0, 0, 0.015)', |
| layer: 'component', | ||
| stability: 'stable', | ||
| lessVariable: '@btn-primary-shadow', | ||
| lessValue: '0 2px 0 rgb(0, 0, 0, 0.045)', |
There was a problem hiding this comment.
Using rgb() with four arguments is part of CSS Colors Level 4. For broader compatibility with older tools and consistency with the rest of the repository, rgba() is preferred for colors with alpha channels.
| lessValue: '0 2px 0 rgb(0, 0, 0, 0.045)', | |
| lessValue: '0 2px 0 rgba(0, 0, 0, 0.045)', |
|
This function is very good. When can it be used? |
|
When will this function be put into use? |
|
Will the next version be updated? |
|
This should absolutely NOT be rushed out as it's a major change of direction. |
@noah-zzp No, it won't. |
@lppedd Absolutely right, it's just a simple try |
PR Checklist
Please check if your PR fulfills the following requirements:
PR Type
What kind of change does this PR introduce?
What is the current behavior?
ng-zorro currently uses Less variables as the primary path for theme customization, while React antd v5 has moved to Token + CSS-in-JS. This PR establishes a bridge layer between Design Token and CSS Variables for Angular.
Issue Number: N/A
What is the new behavior?
This PR introduces a Design Token to CSS Variable bridge mechanism:
Token Schema Definition (
components/style/tokens/definitions.ts): Defines token schema for color, font, radius, spacing, shadow, motion, z-index and other dimensions.CSS Variables Generation (
components/style/themes/token-css-variables.less): Generates CSS Variables like--ant-color-primary,--ant-color-text,--ant-border-radiusetc.Less Variable Compatibility (
components/style/themes/variable.less): Updated to reference CSS Variables, maintaining backward compatibility.Token Map Documentation (
components/style/tokens/token-map.md): Documents the mapping between Less variables and tokens.Build Script (
scripts/build/generate-design-tokens.ts): Script to generate design tokens.This establishes an evolvable token alignment mechanism, allowing ng-zorro's Less variables, CSS Variables, and future Tailwind preset / runtime theme to consume the same token source.
Does this PR introduce a breaking change?
This PR maintains backward compatibility with existing Less-based theme customization.
Other information
CSS Variables prefix:
--ant-*only. Tailwind integration is out of current phase scope.Multica Issue: be4d0fb6-0c58-410b-bb9b-219f70bc17a6