Skip to content

defineTheme color config: accent required for neutral-only, lacks light/dark support #2279

Description

@cixzhang

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

  1. Make accent optional in XDSColorScaleConfig — allow neutral-only configuration
  2. Accept string | [light: string, dark: string] for accent (matching XDSTokenValue)
  3. When given a tuple, derive light palette from the light accent and dark palette from the dark accent
  4. Document the precedence between color config and tokens overrides for accent-derived values

References

  • packages/core/src/theme/expandColorScale.tsXDSColorScaleConfig type
  • packages/core/src/theme/defineTheme.ts — color config integration

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions