diff --git a/change/@fluentui-react-theme-c1768520-8e1c-4d97-b64c-b2792d4ed903.json b/change/@fluentui-react-theme-c1768520-8e1c-4d97-b64c-b2792d4ed903.json new file mode 100644 index 0000000000000..4bb3850be9a44 --- /dev/null +++ b/change/@fluentui-react-theme-c1768520-8e1c-4d97-b64c-b2792d4ed903.json @@ -0,0 +1,7 @@ +{ + "type": "patch", + "comment": "fix mergeThemes() to avoid object's mutation", + "packageName": "@fluentui/react-theme", + "email": "olfedias@microsoft.com", + "dependentChangeType": "patch" +} diff --git a/packages/react-theme/src/utils/mergeThemes.ts b/packages/react-theme/src/utils/mergeThemes.ts index ecd79ca8ad064..0e8f4f8b431d7 100644 --- a/packages/react-theme/src/utils/mergeThemes.ts +++ b/packages/react-theme/src/utils/mergeThemes.ts @@ -2,5 +2,5 @@ import { merge } from '@fluentui/utilities'; import { PartialTheme, Theme } from '../types'; export function mergeThemes(a: Theme, b: PartialTheme | Theme): Theme { - return merge(a, b) as Theme; + return merge({}, a, b) as Theme; } diff --git a/packages/storybook/package.json b/packages/storybook/package.json index 19fcb238881b7..15a65c10be6ab 100644 --- a/packages/storybook/package.json +++ b/packages/storybook/package.json @@ -25,6 +25,8 @@ }, "dependencies": { "@fluentui/react": "^8.0.0-beta.49", + "@fluentui/react-provider": "^0.1.2", + "@fluentui/react-theme": "^0.3.0", "@fluentui/react-theme-provider": "^1.0.0-beta.20", "@fluentui/theme": "^2.0.0-beta.13", "@storybook/addon-knobs": "^5.3.8", diff --git a/packages/storybook/src/decorators/index.ts b/packages/storybook/src/decorators/index.ts index b5fff59b37f15..acef2356b2a05 100644 --- a/packages/storybook/src/decorators/index.ts +++ b/packages/storybook/src/decorators/index.ts @@ -1,3 +1,4 @@ +export * from './withFluentProvider'; export * from './withKeytipLayer'; export * from './withStrictMode'; export * from './withCompatThemeProvider'; diff --git a/packages/storybook/src/decorators/withFluentProvider.tsx b/packages/storybook/src/decorators/withFluentProvider.tsx new file mode 100644 index 0000000000000..2d55636bad8f8 --- /dev/null +++ b/packages/storybook/src/decorators/withFluentProvider.tsx @@ -0,0 +1,20 @@ +import { makeDecorator } from '@storybook/addons'; +import { FluentProvider } from '@fluentui/react-provider'; +import * as React from 'react'; + +import { useFluentTheme } from '../knobs/useFluentTheme'; + +const ProviderWrapper: React.FunctionComponent = props => { + const { theme } = useFluentTheme(); + + return {props.children}; +}; + +export const withFluentProvider = makeDecorator({ + name: 'withFluentProvider', + parameterName: 'theme', + skipIfNoParametersOrOptions: false, + wrapper: (storyFn, context) => { + return {storyFn(context)}; + }, +}); diff --git a/packages/storybook/src/knobs/useFluentTheme.ts b/packages/storybook/src/knobs/useFluentTheme.ts new file mode 100644 index 0000000000000..52f646559f52f --- /dev/null +++ b/packages/storybook/src/knobs/useFluentTheme.ts @@ -0,0 +1,26 @@ +import { + webLightTheme, + webDarkTheme, + webHighContrastTheme, + teamsLightTheme, + teamsDarkTheme, + teamsHighContrastTheme, + Theme, +} from '@fluentui/react-theme'; +import { select } from '@storybook/addon-knobs'; + +const themeSelectorLabel = 'Theme'; + +const themeOptions = [ + { label: 'Web Light', theme: webLightTheme }, + { label: 'Web Dark', theme: webDarkTheme }, + { label: 'Web High Contrast', theme: webHighContrastTheme }, + { label: 'Teams Light', theme: teamsLightTheme }, + { label: 'Teams Dark', theme: teamsDarkTheme }, + { label: 'Teams High Contrast', theme: teamsHighContrastTheme }, +]; + +export const useFluentTheme = (): { label: string; theme: Theme } => + // Casting any here due to issue: https://github.com/storybookjs/storybook/issues/9751 + // eslint-disable-next-line @typescript-eslint/no-explicit-any + select(themeSelectorLabel, themeOptions as any, themeOptions[0] as any);