Repository navigation
Design: rework Flex tokens, add Fluent themes, and move Fluent 2 token JSON behind design/deprecated - #4429
Merged
Jason Morse (JasonVMo) merged 19 commits intoNov 2, 2026
Conversation
Add export-map, runtime export, type inventory, legacy theme, adapter, native color, and Flex default fingerprint baselines that later phases must preserve. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 5030bce5-d7f7-4fb1-93de-68599b79269f
Move Flex-owned implementations under src/flex, legacy Fluent theme types, references, token data, compat projection, and legacy styling under src/fluent, shared type-only contracts under src/types, and test-only fixtures and validation under src/test. Package export keys and conditions are unchanged; only their targets moved. - Unify ThemeState in src/types/themeState.types.ts and remove the duplicate RuntimeThemeState. - Share guarded object-path traversal between mapObjectFromObject and themeFromFlexTokens while keeping their overwrite policies and errors. - Add an import-boundary test with positive controls, and give every design bundle-size scenario a required-module control. - Update generator paths, owning references, and docs links. Compatibility baselines and snapshots are unchanged. Bundle module counts are unchanged; Flex scenarios grow 122 B raw from the shared path helpers and the legacy projection shrinks 238 B. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 5030bce5-d7f7-4fb1-93de-68599b79269f
… phase 3) - Add ColorTone (cool|warm) to appearance requests and resolved appearances; tone resolves provider/root > source option > fallback > cool and is keyed separately only for warm. Raw legacy ThemeContext boundaries resolve cool. - Make color-lib's interaction API token-free (colorTone, direction, compositing) and move interactive-token classification to src/flex/colors, exported from the root. - FlexThemeReference derives omitted hover/pressed entries from rest for the appearance's scheme and tone; high contrast and unresolvable rest values use rest. The fill is eager per resolved appearance for now; phase 4 replaces it with lazy state envelopes. - Move the bulk interaction-override helper to test fixtures. - Guard ownership with import-boundary tests and add retained-output bundle assertions so legacy-only scenarios cannot retain the engine. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 5030bce5-d7f7-4fb1-93de-68599b79269f
…ctor phase 4) Represent every Flex semantic color as one authored description and one resolved InteractiveColor envelope with rest, hover, and pressed. - Authored colors accept a value, a [light, dark] tuple, or flexColor options with explicit states and a standard, inverted, or fixed interaction type. - Overrides replace each color atomically; color.hover/pressed maps are rejected with a migration error. - Omitted interactive states derive lazily on first read and memoize per resolved color; defaults and the Theme adapter resolve explicitly. - Recipes receive the authored description plus the resolved appearance; selectColorEntry reads appearance-specific entries. - Migrate components and Storybook runtime reads to .rest/.hover/.pressed, revise component token-path contracts, and document the model and migration in the new design flex-colors reference. - Narrow the legacy-source bundle scenario to allow the engine-free color envelope while still forbidding color-lib and the interaction policy. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 5030bce5-d7f7-4fb1-93de-68599b79269f
Refresh the x3 pin to 206e890b and generate rest-first cool and warm Flex
defaults from the pinned sources. Interactive colors author a hover or
pressed state only where the runtime interaction policy cannot reproduce the
source; a coverage ledger records every destination, its state treatment,
and native adaptations. FlexThemeReference selects the default by colorTone.
Close the approved non-color gaps: layered, scheme-aware shadows with atomic
merging and selectShadowEntry, motion durations and easings, and
spacing.componentBase800. Legacy { ambient, key } Theme shadows project to
and from layers; the legacy projection keeps its Fluent fallbacks.
The forward Theme adapter keeps Fluent-native fallbacks in
flex/adapters/fluentFallbackTokens and stays engine-free, guarded by a new
import-boundary test. The default theme state now reaches the interaction
policy, so the legacy-source bundle scenario requires it instead of
forbidding it. Component tests read defaults from the testing entry point.
Bundle deltas against phase 4 (macOS, raw/gzip): theme-state +17.3k/+2.7k,
themed-root +17.3k/+2.7k, components-button +24.4k/+5.5k, catalog
+24.5k/+5.5k, legacy-source +24.4k/+5.4k, legacy-theme-from-flex +7.6k/+0.9k;
legacy-theme and color-lib are unchanged.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 5030bce5-d7f7-4fb1-93de-68599b79269f
Add changesets for design (minor), components (minor), and storybook-desktop-runtime (patch). Update the repository theming basics for the x3 defaults and interactive color envelope, document the lossy shadow and motion reverse projection, move the plan's open gates (fixed derivation, native layered shadows and motion) into remaining-work.md, and remove the completed plan. Refresh the bundle-size baselines. Against the Phase 1 measurement, Flex-state scenarios grow about 28-29 KB raw / 7.1-7.3 KB gzip, legacy-theme-from-flex +7.9 KB / +4.1 KB, and color-lib -62 B. The committed catalog baseline was already stale before the refactor (155 KB committed vs 205 KB measured). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 5030bce5-d7f7-4fb1-93de-68599b79269f
Completes phase 6; the previous commit only removed the completed plan. Add changesets for design (minor), components (minor), and storybook-desktop-runtime (patch). Update the repository theming basics for the x3 defaults and interactive color envelope, document the lossy shadow and motion reverse projection, and move the plan's open gates (fixed derivation, native layered shadows and motion) into remaining-work.md. Refresh the bundle-size baselines. Against the Phase 1 measurement, Flex-state scenarios grow about 28-29 KB raw / 7.1-7.3 KB gzip, legacy-theme-from-flex +7.9 KB / +4.1 KB, and color-lib -62 B. The committed catalog baseline was already stale before the refactor (155 KB committed vs 205 KB measured). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 5030bce5-d7f7-4fb1-93de-68599b79269f
Tests added on main read Flex colors as flat strings and through the removed color.hover and color.pressed maps. Read each InteractiveColor state instead, drop a duplicate ProgressBar import from the merge, and refresh the bundle-size baseline for the rebased tree. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…ok chrome - Generate light, dark, lightElevated, darkElevated, hcLight, and hcDark Fluent token sets for every platform. Elevated sets fall back to their base scheme, hcLight and hcDark fall back to each other, and missing high-contrast sets use light and dark. Windows high contrast uses the Win32 hc set as SystemColor brushes. - Add fluentHcTheme, and have fluentTheme select the high-contrast theme for the color scheme under high contrast. - Make default-theme use the design package's Fluent themes and remove its own token-building code, including createAliasTokens. - Keep the Storybook chrome and canvas on Flex; the Theme selector applies only to story content. - Update snapshots, the bundle-size baseline, docs, and changesets. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…point Move the Fluent 2 token loaders and pipeline mappers into src/deprecated, exposed as @fluentui-react-native/design/deprecated. Only tests and other deprecated code may import it (R-DESIGN-003, enforced by the design import-boundary test). Remove the legacy default theme, its stock web palettes, and the tokens/legacy and theming/compat/defaults entry points, which had no in-repository consumers. themeFromFlexTokens now uses the generated Fluent theme for the appearance as its base, so the theming entry point no longer bundles the token JSON. Repoint the android, apple, and win32 themes, the theme-tokens and theming-utils shims, and the tester at the deprecated entry point. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…ors reference The legacy default theme is removed, so the x3 Flex defaults changeset and the flex-colors reference no longer describe it as unchanged. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Contributor
Bundle size reportTree-shaken, minified production esbuild bundles with React and React Native runtimes externalized.
The job is advisory: size changes are reported but do not fail the pull request. Bundle or analysis errors still fail. |
Saad Najmi (Saadnajmi)
approved these changes
Nov 2, 2026
Nikolai Aristov (NikoAri)
approved these changes
Nov 2, 2026
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> # Conflicts: # scripts/package.json
Ruriko Araki (rurikoaraki)
approved these changes
Nov 2, 2026
Jason Morse (JasonVMo)
deleted the
user/jasonvmo/design-rework-legacy-removal
branch
November 2, 2026 22:32
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Platforms Impacted
Description of changes
Reworks the
@fluentui-react-native/designtheming contract and moves every module that loads the Fluent 2 token JSONbehind a new
@fluentui-react-native/design/deprecatedentry point. Related to #4263 and #4276 (partial work, so noclosing keyword).
This branch is 18 commits that have not landed on
main. Reviewing by commit is easiest: the first 15 are the designrefactor, token codegen, and theme entry points, and the last three are the Fluent appearance sets, the deprecated
entry point, and a documentation fix.
Flex tokens on the x3 defaults (
design,components,storybook-desktop-runtime)InteractiveColorwithrest,hover, andpressed; omitted states derivefrom rest. Appearances accept a
colorTone(coolorwarm). Defaults follow x3-design/fluent-design@206e890b,and shadows become layered, scheme-aware arrays.
src/flex,src/fluent,src/types, andsrc/test; export keys and conditions areunchanged.
neutral backgrounds, larger corner radii).
content.
Fluent themes and generated tokens (
design,default-theme)light,dark,lightElevated,darkElevated,hcLight, andhcDarksets forevery platform, with scheme and high-contrast fallbacks.
design/themesentry point:fluentLightTheme,fluentDarkTheme,fluentHcTheme,fluentTheme,flexTheme,and
flexWarmTheme. Elevated requests still resolve by color scheme.default-themeuses design's Fluent themes instead of building tokens locally (macOS previously used the Windowsset).
createAliasTokensis removed.Deprecated entry point (
design, theming packages, shims, tester)src/deprecated, exposed as@fluentui-react-native/design/deprecated, holds the token loaders, global andhigh-contrast alias tokens, and
mapPipelineToTheme,mapFontPipelineToTheme, andmapPipelineToShadow. Only testsand other deprecated code may import it (R-DESIGN-003). The design import-boundary test enforces it and bundle-size
scenarios guard the root, legacy-theme, and Theme-from-Flex graphs.
getDefaultLegacyTheme, thestockWebPalettemodules, and the legacydefault colors and alias tokens, with the
./tokens/legacyand./theming/compat/defaultsexports.themingnolonger exports the pipeline mappers.
themeFromFlexTokensnow starts from the generated Fluent theme for the appearance, so thethemingentry point nolonger bundles the token JSON.
android-theme,apple-theme,win32-theme, thetheme-tokensandtheming-utilsshims, and tester-core importfrom
design/deprecatedwith unchanged values and snapshots.references/remaining-work.md.Breaking changes (each has a changeset)
design(minor): Flex colors areInteractiveColorenvelopes and shadows are layer arrays;color-libinteraction functions drop their token parameter; the
tokens/legacyandtheming/compat/defaultsentry points,getDefaultLegacyTheme, and thethemingmapper exports are removed in favor ofdesign/deprecated.default-theme(minor):createAliasTokensis removed; read alias colors fromtheme.colors.components(minor): default Flex rendering changes as above.Verification
Automated, with exact commands and results:
yarn clean-lage-cachethenyarn lage buildciat46305a228: passed. 176 tasks succeeded, 0 failed, 0 skipped,covering lint-repo, check-publishing, check-agent-instructions, check-package-contents, the root build, and every
package's test and lint. No downstream snapshot changed.
yarn oxfmt --check,yarn check-agent-instructions, andyarn change:checkatc33e026c6: all passed.packages/agentic/design:yarn lint,yarn test --ci(41 suites, 527 tests), andyarn check:mappings:passed. A build after deleting
liband the build info also passed, and codegen left the generated token modulesunchanged.
yarn bundle-sizeat the updated baseline: passed.yarn lintin android-theme, apple-theme, win32-theme, theme-tokens, theming-utils, and tester-core: passed.FURN_RN_PLATFORM=<ios|android|windows|win32> yarn test --ciin design: failed with 33, 33, 13, and 14 tests.Design Jest targets macOS, and the parent commit
ca9f3f79efails 33, 33, 14, and 14 with the same test namesafter renames (macOS-recorded snapshots and macOS-only expectations). I did not compare against
main.Not run: native app qualification on any platform, Storybook desktop tests, and manual testing on devices.
Bundle size, macOS raw bytes from
apps/bundle-size/baseline.jsononmainand on this branch (Windows moves the sameway):
design-theme-state: 29.44 KBcomponents-button: 49.44 KBdesign-legacy-theme-from-flex: 95.47 KBdesign-fluent-theme26.81 KB,design-flex-theme22.82 KBThe root
useThemeStategrowth is the interaction algorithm plus the generated x3 defaults. Every Fluent theme bundlekeeps nearly the whole generated token module because esbuild cannot drop unused spread-built objects; emitting
tree-shakable sets is a possible follow-up.
Pull request checklist
This PR has considered (when applicable):
Keyboard accessibility, VoiceOver, and RTL layouts are not applicable: this changes theme data and Storybook chrome
colors, not interactive behavior or layout.