Summary
Extract the PlatformColor-remapping logic shared by the three high-contrast alias
token files into a single internal utility, and eliminate the byte-for-byte duplicate
that win32-theme carries of the theme-tokens Win32 variant.
The Windows/UWP name transform (SystemColor*Color) and the Win32 name transform
(raw system color name) are intentional platform differences that must be preserved
exactly. This task shares the mechanism without silently unifying the behavior.
Goal
Reduce the processAliasTokens body to one definition, called from both platform
variants in theme-tokens, and replace win32-theme's local copy with an import
from @fluentui-react-native/theme-tokens, which win32-theme already depends on.
Stage
Stage 1 - Beta foundations.
Why it matters
- Observed.
packages/theming/theme-tokens/src/highContrast/tokens-alias.win32.ts
and packages/theming/win32-theme/src/highContrast/tokens-alias.ts are
byte-for-byte identical: same JSON import, same processAliasTokens body, same
hcAliasTokens export. A diff of the two files produces no output.
- Observed. A bug fix or behavior change in the Win32
PlatformColor remapping
path must be applied in two places by hand. The duplication has already allowed the
two Win32 files to exist without any comment explaining why a copy lives in
win32-theme instead of importing from theme-tokens.
- Observed. No unit test exists for
processAliasTokens in either package.
The only high-contrast coverage is the win32-theme snapshot suite, which
exercises createOfficeColorAliasTokens for the HighContrast case and captures
round-trip output, but does not assert either name-transform rule directly.
- Inferred. Consolidating before
Package Consolidation is executed avoids migrating
duplicated code into the design package and having to reconcile the copies there.
Observed current state
The three implementations
All three files import
@fluentui-react-native/design-tokens-win32/hc/tokens-aliases.json and export
hcAliasTokens. They differ only in how they rewrite the string-encoded
PlatformColor(name) entries found in the JSON.
Intentional name-transform difference
- Observed. The Windows/UWP
PlatformColor API (react-native-windows) expects
CSS4 system-color names of the form SystemColorButtonFaceColor. The Win32
PlatformColor API (@office-iss/react-native-win32) expects raw Win32 system
color names of the form ButtonFace. The two formats are not interchangeable;
passing the wrong format to either API produces incorrect or missing colors at
runtime.
- Inferred. This difference is a load-bearing platform contract. Any shared
utility must accept the name transform as a parameter rather than encoding one
behavior.
Consumers and package boundary
- Observed.
packages/theming/theme-tokens/src/getTokens.ts
imports { hcAliasTokens } from ./highContrast/tokens-alias and returns it for
mode === 'highContrast'. The React Native bundler resolves the .win32.ts
override on Win32 and falls back to .ts on other platforms.
- Observed.
packages/theming/win32-theme/src/getOfficeTokens.ts
imports { hcAliasTokens } from ./highContrast/tokens-alias (the local
duplicate) and returns it for officeTheme === 'HighContrast'.
- Observed.
win32-theme already declares
@fluentui-react-native/theme-tokens as a direct dependency in its
package.json,
so no new package-level dependency is required to remove the local copy.
Test coverage
- Observed.
packages/theming/theme-tokens has no __tests__ directory and no
unit tests for the high-contrast alias processing.
- Observed.
packages/theming/win32-theme/src/__tests__/win32-theme.test.ts
covers createOfficeColorAliasTokens and createOfficeShadowAliasTokens for
each of the five office themes, including HighContrast, through Jest snapshots.
The snapshots provide round-trip coverage but do not assert either name-transform
rule directly.
Scope
- Extract the
processAliasTokens logic into a single internal utility inside
packages/theming/theme-tokens/src/highContrast/ that accepts the alias token
object and a name-transform function, and returns the remapped result.
- Update
tokens-alias.ts (Windows/UWP) and tokens-alias.win32.ts (Win32) to
call the shared utility with their respective transforms. The visible behavior of
each must be identical to the current implementation.
- Export
hcAliasTokens from packages/theming/theme-tokens/src/index.ts so
win32-theme can import it by package name without reaching into internal paths.
- Update
win32-theme/src/getOfficeTokens.ts to import hcAliasTokens from
@fluentui-react-native/theme-tokens and delete
win32-theme/src/highContrast/tokens-alias.ts.
- Add unit tests in
packages/theming/theme-tokens that assert the two
name-transform rules independently.
- Add changesets for each changed package.
Out of scope
- Changing the
PlatformColor name values, the JSON source file
(design-tokens-win32/hc/tokens-aliases.json), or the two-level loop structure
that iterates over the alias object.
- Modifying the Windows/UWP transform rule (
SystemColor*Color) or the Win32
transform rule (raw name). Both must remain as documented above; see the
intentional difference section.
- Moving the high-contrast alias logic into
@fluentui-react-native/design; that
boundary question belongs to Package Consolidation.
- Broadening unit test coverage in
theme-tokens beyond the processAliasTokens
utility itself.
- Any changes to iOS or Android high-contrast handling.
- Changing the in-place mutation pattern; the function currently mutates the JSON
object passed to it, which is load-time-only and safe today. Altering that
behavior is a separate decision.
Deliverables
- A shared internal utility function in
packages/theming/theme-tokens/src/highContrast/ that processes alias token
JSON with a caller-supplied name-transform function.
- Updated
tokens-alias.ts and tokens-alias.win32.ts using that utility,
verified to produce identical output to the current implementations.
hcAliasTokens added to packages/theming/theme-tokens/src/index.ts exports.
win32-theme/src/getOfficeTokens.ts importing hcAliasTokens from
@fluentui-react-native/theme-tokens, with win32-theme/src/highContrast/
removed.
- Unit tests in
packages/theming/theme-tokens asserting the SystemColor*Color
transform and the raw Win32 name transform.
- Changesets for
@fluentui-react-native/theme-tokens and
@fluentui-react-native/win32-theme.
Acceptance criteria
Dependencies and ordering
- No prerequisite tasks; this cleanup can proceed at any stage independently of the
staged roadmap.
- Interacts with Package Consolidation: if
theme-tokens is shimmed before this task lands, the shared utility and the new
hcAliasTokens export must be placed in the design destination submodule rather
than in theme-tokens directly. Landing this task first avoids migrating
duplicated code.
- Interacts with System Appearance Handling:
hcAliasTokens is currently consumed by getAliasTokens, which that task may
replace or restructure. No sequencing constraint exists; this task changes only
the source location of the alias data, not how it is selected.
Risks and open decisions
- Open decision. Whether
hcAliasTokens is added to the existing
theme-tokens root index or exposed through a separate subpath export. Adding it
to the root barrel makes a Win32-specific value reachable on all platforms; a
subpath entry avoids that but introduces a new export pattern. Inferred: given
that getAliasTokens and getShadowTokens are already in the root index and are
similarly platform-conditional in their useful values, adding hcAliasTokens
there follows the existing precedent.
- Risk. Adding
hcAliasTokens to theme-tokens/index.ts changes the public
export surface of the package. Observed: no consumer in packages/ or apps/
re-exports * from '@fluentui-react-native/theme-tokens'; the package is consumed
by named import throughout, so the surface change has no fan-out risk.
- Risk. The current
processAliasTokens function mutates the imported JSON
object in place. This is safe today because the module-level hcAliasTokens is
the sole reference. The shared utility must carry a comment documenting this
mutation so it is not accidentally removed in a refactor that calls the function
more than once.
Evidence and references
Summary
Extract the
PlatformColor-remapping logic shared by the three high-contrast aliastoken files into a single internal utility, and eliminate the byte-for-byte duplicate
that
win32-themecarries of thetheme-tokensWin32 variant.The Windows/UWP name transform (
SystemColor*Color) and the Win32 name transform(raw system color name) are intentional platform differences that must be preserved
exactly. This task shares the mechanism without silently unifying the behavior.
Goal
Reduce the
processAliasTokensbody to one definition, called from both platformvariants in
theme-tokens, and replacewin32-theme's local copy with an importfrom
@fluentui-react-native/theme-tokens, whichwin32-themealready depends on.Stage
Stage 1 - Beta foundations.
Why it matters
packages/theming/theme-tokens/src/highContrast/tokens-alias.win32.tsand
packages/theming/win32-theme/src/highContrast/tokens-alias.tsarebyte-for-byte identical: same JSON import, same
processAliasTokensbody, samehcAliasTokensexport. Adiffof the two files produces no output.PlatformColorremappingpath must be applied in two places by hand. The duplication has already allowed the
two Win32 files to exist without any comment explaining why a copy lives in
win32-themeinstead of importing fromtheme-tokens.processAliasTokensin either package.The only high-contrast coverage is the
win32-themesnapshot suite, whichexercises
createOfficeColorAliasTokensfor theHighContrastcase and capturesround-trip output, but does not assert either name-transform rule directly.
Package Consolidation is executed avoids migrating
duplicated code into the design package and having to reconcile the copies there.
Observed current state
The three implementations
All three files import
@fluentui-react-native/design-tokens-win32/hc/tokens-aliases.jsonand exporthcAliasTokens. They differ only in how they rewrite the string-encodedPlatformColor(name)entries found in the JSON.packages/theming/theme-tokens/src/highContrast/tokens-alias.tsis the default (Windows/UWP) variant. For each entry whose string value contains
"PlatformColor", it constructs the name as'SystemColor' + entry.substring(14, entry.length - 1) + 'Color'. A JSON entryreading
"PlatformColor(ButtonFace)"becomesPlatformColor('SystemColorButtonFaceColor').packages/theming/theme-tokens/src/highContrast/tokens-alias.win32.tsis the Win32 platform override. It extracts the raw name without prefix or suffix:
entry.substring(14, entry.length - 1). The same JSON entry becomesPlatformColor('ButtonFace').packages/theming/win32-theme/src/highContrast/tokens-alias.tsis an independent copy of
tokens-alias.win32.ts, behaving identically to it.Intentional name-transform difference
PlatformColorAPI (react-native-windows) expectsCSS4 system-color names of the form
SystemColorButtonFaceColor. The Win32PlatformColorAPI (@office-iss/react-native-win32) expects raw Win32 systemcolor names of the form
ButtonFace. The two formats are not interchangeable;passing the wrong format to either API produces incorrect or missing colors at
runtime.
utility must accept the name transform as a parameter rather than encoding one
behavior.
Consumers and package boundary
packages/theming/theme-tokens/src/getTokens.tsimports
{ hcAliasTokens }from./highContrast/tokens-aliasand returns it formode === 'highContrast'. The React Native bundler resolves the.win32.tsoverride on Win32 and falls back to
.tson other platforms.packages/theming/win32-theme/src/getOfficeTokens.tsimports
{ hcAliasTokens }from./highContrast/tokens-alias(the localduplicate) and returns it for
officeTheme === 'HighContrast'.win32-themealready declares@fluentui-react-native/theme-tokensas a directdependencyin itspackage.json,so no new package-level dependency is required to remove the local copy.
Test coverage
packages/theming/theme-tokenshas no__tests__directory and nounit tests for the high-contrast alias processing.
packages/theming/win32-theme/src/__tests__/win32-theme.test.tscovers
createOfficeColorAliasTokensandcreateOfficeShadowAliasTokensforeach of the five office themes, including
HighContrast, through Jest snapshots.The snapshots provide round-trip coverage but do not assert either name-transform
rule directly.
Scope
processAliasTokenslogic into a single internal utility insidepackages/theming/theme-tokens/src/highContrast/that accepts the alias tokenobject and a name-transform function, and returns the remapped result.
tokens-alias.ts(Windows/UWP) andtokens-alias.win32.ts(Win32) tocall the shared utility with their respective transforms. The visible behavior of
each must be identical to the current implementation.
hcAliasTokensfrompackages/theming/theme-tokens/src/index.tssowin32-themecan import it by package name without reaching into internal paths.win32-theme/src/getOfficeTokens.tsto importhcAliasTokensfrom@fluentui-react-native/theme-tokensand deletewin32-theme/src/highContrast/tokens-alias.ts.packages/theming/theme-tokensthat assert the twoname-transform rules independently.
Out of scope
PlatformColorname values, the JSON source file(
design-tokens-win32/hc/tokens-aliases.json), or the two-level loop structurethat iterates over the alias object.
SystemColor*Color) or the Win32transform rule (raw name). Both must remain as documented above; see the
intentional difference section.
@fluentui-react-native/design; thatboundary question belongs to Package Consolidation.
theme-tokensbeyond theprocessAliasTokensutility itself.
object passed to it, which is load-time-only and safe today. Altering that
behavior is a separate decision.
Deliverables
packages/theming/theme-tokens/src/highContrast/that processes alias tokenJSON with a caller-supplied name-transform function.
tokens-alias.tsandtokens-alias.win32.tsusing that utility,verified to produce identical output to the current implementations.
hcAliasTokensadded topackages/theming/theme-tokens/src/index.tsexports.win32-theme/src/getOfficeTokens.tsimportinghcAliasTokensfrom@fluentui-react-native/theme-tokens, withwin32-theme/src/highContrast/removed.
packages/theming/theme-tokensasserting theSystemColor*Colortransform and the raw Win32 name transform.
@fluentui-react-native/theme-tokensand@fluentui-react-native/win32-theme.Acceptance criteria
the two platform-variant files in
theme-tokenscall it with differentname-transform functions.
win32-theme/src/highContrast/does not contain atokens-alias.tsfile.win32-theme/src/getOfficeTokens.tsimportshcAliasTokensfrom@fluentui-react-native/theme-tokens, not from a local relative path."PlatformColor(ButtonFace)"toPlatformColor('SystemColorButtonFaceColor'),and a separate unit test asserts that the Win32 transform converts the same
input to
PlatformColor('ButtonFace').win32-themeJest snapshots for theHighContrasttheme passwithout modifying the snapshot files.
yarn build,yarn lage test, andyarn lage lintpass at the repositoryroot, and changesets are present.
Dependencies and ordering
staged roadmap.
theme-tokensis shimmed before this task lands, the shared utility and the newhcAliasTokensexport must be placed in the design destination submodule ratherthan in
theme-tokensdirectly. Landing this task first avoids migratingduplicated code.
hcAliasTokensis currently consumed bygetAliasTokens, which that task mayreplace or restructure. No sequencing constraint exists; this task changes only
the source location of the alias data, not how it is selected.
Risks and open decisions
hcAliasTokensis added to the existingtheme-tokensroot index or exposed through a separate subpath export. Adding itto the root barrel makes a Win32-specific value reachable on all platforms; a
subpath entry avoids that but introduces a new export pattern. Inferred: given
that
getAliasTokensandgetShadowTokensare already in the root index and aresimilarly platform-conditional in their useful values, adding
hcAliasTokensthere follows the existing precedent.
hcAliasTokenstotheme-tokens/index.tschanges the publicexport surface of the package. Observed: no consumer in
packages/orapps/re-exports
* from '@fluentui-react-native/theme-tokens'; the package is consumedby named import throughout, so the surface change has no fan-out risk.
processAliasTokensfunction mutates the imported JSONobject in place. This is safe today because the module-level
hcAliasTokensisthe sole reference. The shared utility must carry a comment documenting this
mutation so it is not accidentally removed in a refactor that calls the function
more than once.
Evidence and references
packages/theming/theme-tokens/src/highContrast/tokens-alias.ts: Windows/UWP variant;SystemColor*Colortransform.packages/theming/theme-tokens/src/highContrast/tokens-alias.win32.ts: Win32 variant; raw name.packages/theming/win32-theme/src/highContrast/tokens-alias.ts: byte-for-byte duplicate oftokens-alias.win32.ts.packages/theming/theme-tokens/src/getTokens.ts: platform-resolved consumer intheme-tokens.packages/theming/win32-theme/src/getOfficeTokens.ts: consumer inwin32-theme; currently imports from local copy.packages/theming/win32-theme/package.json: confirms existing@fluentui-react-native/theme-tokensdependency.packages/theming/win32-theme/src/__tests__/win32-theme.test.ts: snapshot tests covering theHighContrastpath.packages/theming/theme-tokens/src/index.ts: current exports;hcAliasTokensis not yet public.theme-tokens; landing this task first avoids migrating duplicated code.getAliasTokens; no ordering dependency.