Repository navigation
Design: require a theme for Flex theme consumers - #4433
Closed
Jason Morse (JasonVMo) wants to merge 1 commit into
Closed
Jason Morse (JasonVMo) wants to merge 1 commit into
Jason Morse (JasonVMo) wants to merge 1 commit into
Conversation
useThemeState and useThemeAppearance now throw when no ThemeProvider, ThemedRoot, or legacy ThemeContext provider is above the caller. The default theme state and default appearance state are removed. Add design/testing/theme with TestThemeProvider and createThemeWrapper so tests can render Flex consumers. It is a separate entry point because design/testing must stay free of react-native. 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. |
| | -------------------- | ---------------------------------------------------------------- | ------------------ | | ||
| | `useThemeState` | `ThemeState`: `tokens`, resolved `appearance`, and `themeStyles` | Throws | | ||
| | `useThemeAppearance` | The requested and resolved appearance | Throws | | ||
| | `useTheme` | The legacy `Theme` (from the `theming` subpath) | `undefined` | |
Collaborator
There was a problem hiding this comment.
I believe with v1 we usually encouraged useFluentTheme usage in the components because it has a fallback theme built in, and thus is more stable for consumers. Are you ok with not having that fallback behavior?
Contributor
Author
There was a problem hiding this comment.
Hmm, good catch, I had forgotten we used the fallback for v1. The tradeoff is in bundle size if you are overriding the theme but it does make things more foolproof.
Thinking about it I will rework this one as:
- switch the current default flex token theme to use the new generated flex theme source
- build the default theme on demand one time, using the current system Appearance dark|light setting to guide which set of defaults to use.
Vladimir Morozov (vmoroz)
approved these changes
Nov 5, 2026
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
Flex components now require a theme.
useThemeStatethrows when no theme information is found instead of falling back to a default theme state, and the default theme state is removed.packages/agentic/designsrc/flex/useThemeState.ts: a shareduseRequiredThemeBoundarymakesuseThemeStateanduseThemeAppearancethrow when there is noThemeProvider,ThemedRoot, or legacyThemeContextprovider above the caller. The message points toThemedRoot/ThemeProviderand to the test helpers.useThemeAppearancethrows too, for consistency; its default appearance state is removed.src/flex/themeState.ts,src/theming/appearance.ts: removedefaultThemeStateanddefaultThemeAppearanceState.src/test/TestThemeProvider.tsx(new):TestThemeProviderandcreateThemeWrapperfor tests that render Flex consumers. Defaults to one theme reference per mounted provider and a pinned light/standard/base appearance source.package.json: new./testing/themeentry point. It is separate from./testing, which must stay free ofreact-nativebecause@fluentui-react-native/test-toolsre-exportsmockThemefrom it and packages on thereactJest platform (for example@uifabricshared/theming-ramp) cannot importreact-native.src/test/compatibility/*: entry-point list and snapshot include./testing/theme; import-boundary tests forbid production imports oftestingandtesting/*.src/flex/useThemeState.test.ts,src/test/TestThemeProvider.test.tsx: wrap provider-less tests, add throw coverage and helper tests.apps/bundle-sizedesign-theme-state-legacy-sourceno longer retains the x3 defaults or the interaction algorithm (onlydefaultThemeStatepulled them in), so its output patterns now forbid them.baseline.jsonis refreshed.Docs and release
design/references/{theming,testing,entry-points,contributing}.md,design/AGENTS.md, andcomponents/references/tests-and-stories.md..changeset/design-require-theme.md(design and components, minor).Breaking behavior: anything that renders a Flex consumer outside a
ThemedRoot,ThemeProvider, or legacyThemeContextprovider now throws. Components tests already render throughThemedRoot(renderWithTheme), and the Storybook runtime wraps stories in a theme, so no component changes were needed.Verification
Run from the repository root:
yarn clean-lage-cachethenyarn lage buildci: passed (176 tasks, 0 failed)yarn lage test-links --verbose --grouped: passed (89 tasks, 0 failed)yarn change:check: passedyarn bundle-sizewith the refreshed baseline: passedNo manual device testing; this is a JS-only change covered by Jest.
useThemeStatewithout a provider returned the default theme stateuseThemeStatewithout a provider throws and namesThemedRoot,ThemeProvider, and the test helpersPull request checklist
This PR has considered (when applicable):