Problem
The color field in defineTheme has a few ergonomic and type issues:
1. accent is required even when you only want neutralStyle
XDSColorScaleConfig defines accent: string as required. If you just want to set neutralStyle: "warm" without changing the accent color, you still have to pass an accent value:
// This should work but doesnt — accent is required
defineTheme({
name: "my-theme",
color: { neutralStyle: "warm" },
});
2. accent only accepts a single string — no light/dark tuple support
The rest of the token system supports [light, dark] tuples via XDSTokenValue, but accent in the color config is typed as just string. This prevents setting a different accent per color scheme:
// Not possible today:
color: { accent: ["#0064E0", "#48CAE4"] }
// Have to use this workaround in tokens instead:
tokens: { "--color-accent": ["#0064E0", "#48CAE4"] }
But that workaround skips the full color scale generation that expandColorScale provides (muted variants, on-accent, text-accent, icon-accent, etc).
3. Unclear light/dark behavior in the color extractor
expandColorScale already generates light-dark() values from a single accent (picking different tonal palette stops for light vs dark). But if a consumer provides both an accent via color.accent AND token overrides via tokens["--color-accent"] as a tuple, the interaction is unclear:
- Does the color extractor generate its full derived palette from the single accent, then get partially overridden by the tuple token?
- Will derived tokens (e.g.
--color-accent-muted, --color-on-accent) still be based on the original single accent while --color-accent itself uses the tuple?
This creates potential inconsistency where the accent and its derived variants diverge.
Suggested fixes
- Make
accent optional in XDSColorScaleConfig — allow neutral-only configuration
- Accept
string | [light: string, dark: string] for accent (matching XDSTokenValue)
- When given a tuple, derive light palette from the light accent and dark palette from the dark accent
- Document the precedence between
color config and tokens overrides for accent-derived values
References
packages/core/src/theme/expandColorScale.ts — XDSColorScaleConfig type
packages/core/src/theme/defineTheme.ts — color config integration
Problem
The
colorfield indefineThemehas a few ergonomic and type issues:1.
accentis required even when you only wantneutralStyleXDSColorScaleConfigdefinesaccent: stringas required. If you just want to setneutralStyle: "warm"without changing the accent color, you still have to pass an accent value:2.
accentonly accepts a single string — no light/dark tuple supportThe rest of the token system supports
[light, dark]tuples viaXDSTokenValue, butaccentin the color config is typed as juststring. This prevents setting a different accent per color scheme:But that workaround skips the full color scale generation that
expandColorScaleprovides (muted variants, on-accent, text-accent, icon-accent, etc).3. Unclear light/dark behavior in the color extractor
expandColorScalealready generateslight-dark()values from a single accent (picking different tonal palette stops for light vs dark). But if a consumer provides both an accent viacolor.accentAND token overrides viatokens["--color-accent"]as a tuple, the interaction is unclear:--color-accent-muted,--color-on-accent) still be based on the original single accent while--color-accentitself uses the tuple?This creates potential inconsistency where the accent and its derived variants diverge.
Suggested fixes
accentoptional inXDSColorScaleConfig— allow neutral-only configurationstring | [light: string, dark: string]foraccent(matchingXDSTokenValue)colorconfig andtokensoverrides for accent-derived valuesReferences
packages/core/src/theme/expandColorScale.ts—XDSColorScaleConfigtypepackages/core/src/theme/defineTheme.ts— color config integration