Skip to content

Theming Workstream #4276

Description

@JasonVMo

Goal

Make @fluentui-react-native/design the single modern theming contract for
agentic Fluent UI React Native components. Themes should be authored from Flex
tokens or legacy Fluent values, resolve appearance consistently across
platforms, preserve compatibility without forcing legacy code into modern
bundles, and have generated, reviewable defaults.

Status

In progress. Four of twelve direct work items are closed; eight remain open.

PR #4295
completed the central theme-source and appearance architecture:

  • Added FlexThemeReference, structured requested/resolved appearance axes, and
    stable theme-state/token identity keyed by source revision and appearance.
  • Reworked ThemeProvider around one external-store source contract for nested
    Flex and legacy themes without mutating author-owned values.
  • Made useThemeState().tokens the sole modern consumption path and removed the
    temporary useFlexTokens API.
  • Kept legacy ThemeReference, ThemeProvider, ThemeContext, and useTheme
    behavior compatible through lazy conversion boundaries.
  • Added schema-v2 forward and reverse token mappings with explicit collisions,
    fallbacks, transforms, and omissions.
  • Migrated default, Android, Apple, Windows, macOS, iOS, and Win32 theme handling
    to the structured appearance model.
  • Added macOS, Windows, and Win32 bundle scenarios proving that modern Flex and
    modern legacy-source paths exclude reverse compatibility payloads.

This closes dynamic theme building
(#4264).
Package consolidation
(#4267),
high-contrast source consolidation
(#4265), and
mapping drift enforcement
(#4266,
PR #4287)
are also closed.

PR #4295 partially completes system appearance handling
(#4270).
The remaining Win32 Office native contract has no synchronous current-state
getter, so an appearance change while no consumer is subscribed cannot be
recovered until another native event. Host-theme string inference remains a
transitional fallback.

What is left

  1. Generate Flex defaults from token sources, including reviewed
    cross-appearance de-duplication
    (#4263).
  2. Finish Theming: Better System Appearance Handling #4270 by resolving the Win32 Office current-state contract and remove
    transitional inference when structured native state is reliable.
  3. Add reviewed resolved-token snapshots for every supported platform and
    appearance (#4271).
  4. Integrate dynamic system appearance and Flex-authored themes into Storybook
    (#4269).
  5. Refresh design and migration documentation around the approved modern and
    compatibility paths
    (#4272).
  6. Build and validate the specification-backed Apple/macOS Flex theme
    (#4261).
  7. Add tree-shakeable runtime color derivation and contrast-audit submodules
    (#4268,
    #4262).

Work items

Status Issue Outcome or remaining work
Open #4261 - Apple Theme Build a Flex-contract macOS theme and validate it against the approved design source.
Open #4262 - Contrast audit submodule Add optional auditing, approved pairings, native-color diagnostics, and bundle isolation.
Open #4263 - Default values codegen Replace hand-authored Flex defaults with generated and de-duplicated values.
Done #4264 - Dynamic theme building Flex-first and legacy-source authoring merged in PR #4295.
Done #4265 - High-contrast source consolidation Shared processing landed while preserving platform-native color naming.
Done #4266 - Mapping drift and upstream pin Offline consistency checks, source pin, and drift reporting merged in PR #4287.
Done #4267 - Package consolidation The design package owns the modern public contract; remaining packages are compatibility or platform layers.
Open #4268 - Runtime color utilities Port verified x3 interaction derivation into an optional submodule.
Open #4269 - Storybook appearance integration Add dynamic appearance controls, Flex-authored theme coverage, and token-driven chrome.
Open, partial #4270 - System appearance handling Structured appearance is merged; Win32 Office current-state recovery remains.
Open #4271 - Theme snapshot parity Review and gate resolved token sets for each supported appearance/platform.
Open #4272 - Theming documentation refresh Document modern authoring, compatibility, migration, appearance, and update workflows.

Beta exit criteria

  • @fluentui-react-native/design owns the modern theme construction,
    appearance, Flex-token, and styling contract.
  • A theme can be authored directly from Flex tokens and consumed without
    first constructing a legacy Fluent Theme.
  • useThemeState().tokens is the sole modern token path; legacy theme
    construction and reverse conversion are lazy compatibility capabilities.
  • Mapping consistency is CI-enforced and the x3 source revision has an
    offline-safe pin, drift report, and update workflow.
  • High-contrast source processing is consolidated without changing
    Windows/Win32 native color naming.
  • Flex default values are generated rather than maintained as color literal
    tables.
  • Structured light, dark, and high-contrast resolution is complete on every
    supported platform, including current-state recovery on Win32 Office.
  • Every supported resolved appearance has a reviewed token snapshot.
  • Storybook follows system appearance and renders a Flex-authored theme.
  • The design package and theming guides document the approved modern,
    compatibility, and migration paths.

Production exit criteria

  • Runtime color derivation is an optional submodule verified against x3 and
    absent unless imported.
  • Generated defaults de-duplicate shared values across appearances and
    platforms, with measured bundle evidence.
  • Legacy Fluent token construction runs only when a legacy consumer requests
    it; modern bundle scenarios enforce the boundary.
  • The Apple/macOS Flex theme matches an owner-approved specification.
  • The optional contrast submodule audits approved pairings, reports
    unresolvable native colors explicitly, and remains tree-shakeable.
  • Deprecation and migration guidance exists for every compatibility layer.
  • Cross-platform package-cost budgets are promoted from warning/advisory
    comparison to required reviewed gates.

Agent context

Public contract

  • Modern consumers use useThemeState() and read ThemeState.tokens.
  • Theme authors may supply an appearance-aware Flex source or a legacy Fluent
    source through the unified provider boundary.
  • Legacy-to-Flex conversion is loaded only when modern consumers receive a
    legacy source.
  • Flex-to-legacy conversion and complete legacy defaults are loaded only when a
    legacy useTheme consumer requests them.
  • Compatibility modules must remain thin and must not become alternate sources
    of theme truth.

Appearance caveats

  • Requested appearance and resolved appearance are distinct axes.
  • Structured colorScheme and isHighContrast values are preferred whenever a
    native source supplies them.
  • Win32 Office currently exposes initial constants and events but no synchronous
    current-state query. Preserve event-maintained state across subscribers until
    that native contract changes.
  • x3 Flex themes define light/dark web behavior but no forced-colors or
    high-contrast source. FURN therefore owns its native high-contrast adaptation
    and must document that divergence.

Sequencing

  1. Generated defaults and final Win32 appearance state unblock reviewed snapshot
    parity.
  2. Stable snapshots and source APIs unblock Storybook appearance coverage and
    documentation.
  3. Runtime color utilities establish the optional color-math boundary reused by
    contrast auditing.
  4. The Apple theme depends on stable dynamic sources, generated defaults, and
    the Storybook macOS validation surface.
  5. Package-cost enforcement is shared with
    #4275;
    component adoption evidence is shared with
    #4274.

Merged evidence

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions