Skip to content

feat(theme): variants carry their own styles - #803

Merged
cixzhang merged 1 commit into
mainfrom
navi/feat/variant-styles
Mar 21, 2026
Merged

feat(theme): variants carry their own styles#803
cixzhang merged 1 commit into
mainfrom
navi/feat/variant-styles

Conversation

@cixzhang

@cixzhang cixzhang commented Mar 21, 2026

Copy link
Copy Markdown
Contributor

Changes the variants input from string arrays to style objects — declaration and styles live together.

// Before
variants: { button: ['primary-muted'] }

// After
variants: {
  button: {
    'primary-muted': {
      backgroundColor: 'var(--color-accent-muted)',
      color: 'var(--color-accent)',
    },
  },
}

What changed:

  • variants input type: Record<string, string[]>Record<string, Record<string, Record<string, string>>>
  • defineTheme extracts variant names for type augmentation (output stays string[])
  • Variant styles merge into components as variant: keys — CSS generation unchanged
  • Empty {} registers the name without styles
  • Explicit components overrides win on collision

Why: Declaring a variant in one place and styling it in another (components) meant you could forget one side. Now they're co-located. components stays for overriding existing built-in variants.

Part of #802.


Changes the variants input from string arrays to style objects:

  // Before
  variants: { button: ['primary-muted'] }

  // After
  variants: {
    button: {
      'primary-muted': {
        backgroundColor: 'var(--color-accent-muted)',
        color: 'var(--color-accent)',
      },
    },
  }

Declaration and styles live together. Empty {} registers the variant
name without adding styles.

defineTheme merges variant styles into components as variant: keys,
so the CSS generation path is unchanged. The output variants field
stays as string[] for CLI type augmentation compatibility.

Explicit component overrides take precedence over variant styles
on collision (deepMergeComponents).

Part of #802 — unified defineTheme API.

Co-authored-by: Navi <navi@navibot.dev>
@cixzhang
cixzhang requested a review from josephfarina as a code owner March 21, 2026 15:16
@meta-cla meta-cla Bot added the CLA Signed This label is managed by the Meta Open Source bot. label Mar 21, 2026
@github-actions

Copy link
Copy Markdown
Contributor

PR Analysis Report

📚 Storybook Preview

View Storybook for this PR
GitHub Pages may take up to a minute to hydrate after deploy.

🧪 Sandbox Preview

View Sandbox for this PR
GitHub Pages may take up to a minute to hydrate after deploy.

No new or modified components detected.

Bundle Size Summary

Package Size (ESM) Size (CJS) Gzipped
@xds/core 10.9KB 17.3KB 2.7KB

Accessibility Audit

Status: No accessibility violations detected.


Generated by PR Enrichment workflow | Storybook | Sandbox | View full report

@cixzhang
cixzhang merged commit 1e1abe0 into main Mar 21, 2026
13 checks passed
rubyycheung added a commit that referenced this pull request Mar 22, 2026
Migrate to the unified defineTheme API from #803/#804:

- typeScale → typography.scale + typography roles (body/code)
  Fonts now declared via typography config instead of raw --font-* tokens
- motionScale → motion
- variants: string[] → Record<string, styles>
  Custom button variant styles moved from components into variants
  (declaration + styles together)
- CLI: fix generateVariantDeclarations to handle new object-style variants
  alongside legacy array format
@rubyycheung rubyycheung mentioned this pull request Mar 22, 2026
@cixzhang
cixzhang deleted the navi/feat/variant-styles branch April 9, 2026 14:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed This label is managed by the Meta Open Source bot.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant