From fd8c49537ac768c4937f4ef6325ec28bd522bc8f Mon Sep 17 00:00:00 2001 From: Tristan Watanabe Date: Sun, 2 Oct 2022 01:39:28 -0700 Subject: [PATCH 01/53] add utility functions for CSF test creation --- .../src/utilities/StoryDecorators.tsx | 21 ++++++++++++ .../src/utilities/getStoryVariant.ts | 32 +++++++++++++++++++ .../src/utilities/index.ts | 2 ++ 3 files changed, 55 insertions(+) create mode 100644 apps/vr-tests-react-components/src/utilities/StoryDecorators.tsx create mode 100644 apps/vr-tests-react-components/src/utilities/getStoryVariant.ts diff --git a/apps/vr-tests-react-components/src/utilities/StoryDecorators.tsx b/apps/vr-tests-react-components/src/utilities/StoryDecorators.tsx new file mode 100644 index 00000000000000..374f9e47e3f267 --- /dev/null +++ b/apps/vr-tests-react-components/src/utilities/StoryDecorators.tsx @@ -0,0 +1,21 @@ +import * as React from 'react'; +import { DecoratorFunction } from '@storybook/addons'; +import { webLightTheme, teamsHighContrastTheme, webDarkTheme } from '@fluentui/react-theme'; +import { FluentProvider } from '@fluentui/react-provider'; +import { ExtendedStoryFnReturnType } from './types'; + +export const DarkModeDecorator: DecoratorFunction = story => { + return {story()}; +}; + +export const HighContrastDecorator: DecoratorFunction = story => { + return {story()}; +}; + +export const RTLDecorator: DecoratorFunction = story => { + return ( + + {story()} + + ); +}; diff --git a/apps/vr-tests-react-components/src/utilities/getStoryVariant.ts b/apps/vr-tests-react-components/src/utilities/getStoryVariant.ts new file mode 100644 index 00000000000000..28412bc34b5746 --- /dev/null +++ b/apps/vr-tests-react-components/src/utilities/getStoryVariant.ts @@ -0,0 +1,32 @@ +import { ComponentStory } from '@storybook/react'; +import { DarkModeDecorator, HighContrastDecorator, RTLDecorator } from './StoryDecorators'; + +export const DARK_MODE = 'Dark Mode'; +export const HIGH_CONTRAST = 'High Contrast'; +export const RTL = 'RTL'; + +/** + * Helper function that returns a RTL, Dark Mode or High Contrast variant of an existing story. + */ +export const getStoryVariant = (story: ComponentStory, variant: 'RTL' | 'Dark Mode' | 'High Contrast') => { + let decorator; + + if (variant === RTL) { + decorator = RTLDecorator; + } + + if (variant === DARK_MODE) { + decorator = DarkModeDecorator; + } + + if (variant === HIGH_CONTRAST) { + decorator = HighContrastDecorator; + } + + return { + ...story, + render: story, + storyName: `${story.storyName} - ${variant}`, + decorators: [decorator], + }; +}; diff --git a/apps/vr-tests-react-components/src/utilities/index.ts b/apps/vr-tests-react-components/src/utilities/index.ts index 12fc4954c5d706..d071a94751e8b6 100644 --- a/apps/vr-tests-react-components/src/utilities/index.ts +++ b/apps/vr-tests-react-components/src/utilities/index.ts @@ -8,3 +8,5 @@ declare module '@storybook/addons' { } export * from './TestWrapperDecorator'; +export * from './StoryDecorators'; +export * from './getStoryVariant'; From 68f2c3c43f552ae8e7fc814c370f20c362edc66c Mon Sep 17 00:00:00 2001 From: Tristan Watanabe Date: Sun, 2 Oct 2022 02:10:33 -0700 Subject: [PATCH 02/53] chore: convert Button stories to CSF --- .../src/stories/Button.stories.tsx | 569 ------------------ .../src/stories/Button/Button.stories.tsx | 200 ++++++ 2 files changed, 200 insertions(+), 569 deletions(-) delete mode 100644 apps/vr-tests-react-components/src/stories/Button.stories.tsx create mode 100644 apps/vr-tests-react-components/src/stories/Button/Button.stories.tsx diff --git a/apps/vr-tests-react-components/src/stories/Button.stories.tsx b/apps/vr-tests-react-components/src/stories/Button.stories.tsx deleted file mode 100644 index 23c3f2e7077f12..00000000000000 --- a/apps/vr-tests-react-components/src/stories/Button.stories.tsx +++ /dev/null @@ -1,569 +0,0 @@ -import { storiesOf } from '@storybook/react'; -import * as React from 'react'; -import Screener from 'screener-storybook/src/screener'; -import { Button, CompoundButton, ToggleButton, MenuButton } from '@fluentui/react-button'; -import { bundleIcon, CalendarMonthFilled, CalendarMonthRegular } from '@fluentui/react-icons'; -import { makeStyles } from '@griffel/react'; - -const CalendarMonth = bundleIcon(CalendarMonthFilled, CalendarMonthRegular); - -const steps = new Screener.Steps() - .snapshot('default', { cropTo: '.testWrapper' }) - .hover('#button-id') - .snapshot('hover', { cropTo: '.testWrapper' }) - .mouseDown('#button-id') - .snapshot('pressed', { cropTo: '.testWrapper' }) - .end(); - -const buttonId = 'button-id'; - -const useStyles = makeStyles({ - longText: { - width: '280px', - }, -}); - -storiesOf('Button Converged', module) - .addDecorator(story => {story()}) - .addStory('Default', () => , { - includeRtl: true, - includeHighContrast: true, - includeDarkMode: true, - }) - .addStory('Circular', () => ( - - )) - .addStory('Outline', () => ( - - )) - .addStory( - 'Primary', - () => ( - - ), - { - includeHighContrast: true, - includeDarkMode: true, - }, - ) - .addStory( - 'Subtle', - () => ( - - ), - { - includeHighContrast: true, - includeDarkMode: true, - }, - ) - .addStory( - 'Transparent', - () => ( - - ), - { - includeHighContrast: true, - includeDarkMode: true, - }, - ) - .addStory( - 'Disabled', - () => ( - - ), - { - includeHighContrast: true, - includeDarkMode: true, - }, - ) - .addStory( - 'Outline Disabled', - () => ( - - ), - { - includeHighContrast: true, - includeDarkMode: true, - }, - ) - .addStory( - 'Primary Disabled', - () => ( - - ), - { includeHighContrast: true, includeDarkMode: true }, - ) - .addStory( - 'Subtle Disabled', - () => ( - - ), - { includeHighContrast: true, includeDarkMode: true }, - ) - .addStory( - 'Transparent Disabled', - () => ( - - ), - { includeHighContrast: true, includeDarkMode: true }, - ) - .addStory('Size small', () => ( - - )) - .addStory('Size large', () => ( - - )) - .addStory('Size small - with long text wrapping', () => { - const styles = useStyles(); - return ( - - ); - }) - .addStory('Size medium - with long text wrapping', () => { - const styles = useStyles(); - return ( - - ); - }) - .addStory('Size large - with long text wrapping', () => { - const styles = useStyles(); - return ( - - ); - }) - .addStory( - 'With icon before content', - () => ( - - ), - { - includeRtl: true, - }, - ) - .addStory( - 'With icon after content', - () => ( - - ), - { includeRtl: true }, - ) - .addStory('Icon only', () => ; + +export const DefaultRTL = getStoryVariant(Default, RTL); +export const DefaultHighContrast = getStoryVariant(Default, HIGH_CONTRAST); +export const DefaultDarkMode = getStoryVariant(Default, DARK_MODE); + +export const Circular = () => ( + +); + +export const Outline = () => ( + +); + +export const Primary = () => ( + +); + +export const PrimaryHighContrast = getStoryVariant(Primary, HIGH_CONTRAST); +export const PrimaryDarkMode = getStoryVariant(Primary, DARK_MODE); + +export const Subtle = () => ( + +); + +export const SubtleHighContrast = getStoryVariant(Subtle, HIGH_CONTRAST); +export const SubtleDarkMode = getStoryVariant(Subtle, DARK_MODE); + +export const Transparent = () => ( + +); + +export const TransparentHighContrast = getStoryVariant(Transparent, HIGH_CONTRAST); +export const TransparentDarkMode = getStoryVariant(Transparent, DARK_MODE); + +export const Disabled = () => ( + +); + +export const DisabledHighContrast = getStoryVariant(Disabled, HIGH_CONTRAST); +export const DisabledDarkMode = getStoryVariant(Disabled, DARK_MODE); + +export const OutlineDisabled = () => ( + +); + +export const OutlineDisabledHighContrast = getStoryVariant(OutlineDisabled, HIGH_CONTRAST); +export const OutlineDisabledDarkMode = getStoryVariant(OutlineDisabled, DARK_MODE); + +export const PrimaryDisabled = () => ( + +); + +export const PrimaryDisabledHighContrast = getStoryVariant(PrimaryDisabled, HIGH_CONTRAST); +export const PrimaryDisabledDarkMode = getStoryVariant(PrimaryDisabled, DARK_MODE); + +export const SubtleDisabled = () => ( + +); + +export const SubtleDisabledHighContrast = getStoryVariant(SubtleDisabled, HIGH_CONTRAST); +export const SubtleDisabledDarkMode = getStoryVariant(SubtleDisabled, DARK_MODE); + +export const TransparentDisabled = () => ( + +); + +export const TransparentDisabledHighContrast = getStoryVariant(TransparentDisabled, HIGH_CONTRAST); +export const TransparentDisabledDarkMode = getStoryVariant(TransparentDisabled, DARK_MODE); + +export const SizeSmall = () => ( + +); + +SizeSmall.storyName = 'Size small'; + +export const SizeLarge = () => ( + +); + +SizeLarge.storyName = 'Size large'; + +export const SizeSmallWithLongTextWrapping = () => { + const styles = useStyles(); + return ( + + ); +}; + +SizeSmallWithLongTextWrapping.storyName = 'Size small - with long text wrapping'; + +export const SizeMediumWithLongTextWrapping = () => { + const styles = useStyles(); + return ( + + ); +}; + +SizeMediumWithLongTextWrapping.storyName = 'Size medium - with long text wrapping'; + +export const SizeLargeWithLongTextWrapping = () => { + const styles = useStyles(); + return ( + + ); +}; + +SizeLargeWithLongTextWrapping.storyName = 'Size large - with long text wrapping'; + +export const WithIconBeforeContent = () => ( + +); + +WithIconBeforeContent.storyName = 'With icon before content'; + +export const WithIconBeforeContentRTL = getStoryVariant(WithIconBeforeContent, RTL); + +export const WithIconAfterContent = () => ( + +); + +WithIconAfterContent.storyName = 'With icon after content'; + +export const WithIconAfterContentRTL = getStoryVariant(WithIconAfterContent, RTL); + +export const IconOnly = () => ; export const DefaultRTL = getStoryVariant(Default, RTL); -export const DefaultHighContrast = getStoryVariant(Default, HIGH_CONTRAST); export const DefaultDarkMode = getStoryVariant(Default, DARK_MODE); +export const DefaultHighContrast = getStoryVariant(Default, HIGH_CONTRAST); export const Circular = () => ( ; + +export const ButtonDarkMode = { + render: Button, + parameters: { variant: DARK_MODE }, // story renders in Dark mode. +}; + +export const ButtonHighContrast = { + render: Button, + parameters: { variant: HIGH_CONTRAST }; // story renders in High Contrast mode. +} + +export const ButtonRTL = { + render: Button, + parameters: { variant: RTL }, // story renders in RTL. +}; + ``` From 794bd7f6fbc9c96db7818b54d2fe356356e018b0 Mon Sep 17 00:00:00 2001 From: Tristan Watanabe Date: Mon, 10 Oct 2022 15:11:35 -0700 Subject: [PATCH 16/53] remove unneed peerDep --- packages/react-components/react-storybook/package.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/react-components/react-storybook/package.json b/packages/react-components/react-storybook/package.json index 290b65ba83ad48..434ee71641d773 100644 --- a/packages/react-components/react-storybook/package.json +++ b/packages/react-components/react-storybook/package.json @@ -36,8 +36,7 @@ "@types/react": ">=16.8.0 <18.0.0", "react": ">=16.8.0 <18.0.0", "@storybook/addon-knobs": "^6.0.28", - "@storybook/addons": "^6.0.28", - "@storybook/react": "^6.5.5" + "@storybook/addons": "^6.0.28" }, "beachball": { "disallowedChangeTypes": [ From f3068462f8eb3c66df12f4c82b09971b403e6f3c Mon Sep 17 00:00:00 2001 From: Tristan Watanabe Date: Mon, 10 Oct 2022 16:03:03 -0700 Subject: [PATCH 17/53] fix: typing --- .../src/decorators/withFluentVrTestVariants.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/react-components/react-storybook/src/decorators/withFluentVrTestVariants.tsx b/packages/react-components/react-storybook/src/decorators/withFluentVrTestVariants.tsx index ec430031650f4e..bced594168eb31 100644 --- a/packages/react-components/react-storybook/src/decorators/withFluentVrTestVariants.tsx +++ b/packages/react-components/react-storybook/src/decorators/withFluentVrTestVariants.tsx @@ -1,8 +1,8 @@ import * as React from 'react'; import { FluentProvider } from '@fluentui/react-provider'; import { teamsHighContrastTheme, webDarkTheme, webLightTheme } from '@fluentui/react-theme'; -import { makeDecorator, DecoratorFunction } from '@storybook/addons'; -import type { StoryContext } from '@storybook/react'; +import { makeDecorator } from '@storybook/addons'; +import type { StoryContext } from '@storybook/addons'; export const DARK_MODE = 'DarkMode'; export const HIGH_CONTRAST = 'HighContrast'; @@ -27,7 +27,7 @@ type AssertedMakeDecorator = ({ parameterName, skipIfNoParametersOrOptions, wrapper, -}: AssertedMakeDecoratorOptions) => DecoratorFunction; +}: AssertedMakeDecoratorOptions) => () => React.ReactNode; export const withFluentVrTestVariants = ((makeDecorator as unknown) as AssertedMakeDecorator)({ name: 'withFluentVrTestVariants.', From fb87708ab46c08f137d00166a5293b5af2e62204 Mon Sep 17 00:00:00 2001 From: Tristan Watanabe Date: Mon, 10 Oct 2022 16:03:22 -0700 Subject: [PATCH 18/53] Update API --- .../react-storybook/etc/react-storybook.api.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/react-components/react-storybook/etc/react-storybook.api.md b/packages/react-components/react-storybook/etc/react-storybook.api.md index 1290f16b5b06a1..a78d1619f159d1 100644 --- a/packages/react-components/react-storybook/etc/react-storybook.api.md +++ b/packages/react-components/react-storybook/etc/react-storybook.api.md @@ -4,7 +4,6 @@ ```ts -import { DecoratorFunction } from '@storybook/addons'; import * as React_2 from 'react'; // @public (undocumented) @@ -20,7 +19,7 @@ export const RTL = "Rtl"; export const withFluentProvider: (...args: any) => any; // @public (undocumented) -export const withFluentVrTestVariants: DecoratorFunction; +export const withFluentVrTestVariants: () => React_2.ReactNode; // @public (undocumented) export const withStrictMode: (storyFn: () => React_2.ReactNode) => JSX.Element; From 7bf18738bc1378b1e1bfa5e800dd3248879d5ede Mon Sep 17 00:00:00 2001 From: Tristan Watanabe Date: Wed, 12 Oct 2022 11:42:11 -0700 Subject: [PATCH 19/53] revert additions to react-storybook package --- .../decorators/withFluentVrTestVariants.tsx | 80 +++++++++++++++++++ .../react-storybook/src/decorators/index.ts | 1 - .../react-storybook/src/index.test.ts | 4 +- .../react-storybook/src/index.ts | 9 +-- 4 files changed, 83 insertions(+), 11 deletions(-) create mode 100644 packages/react-components/react-storybook-addon/src/decorators/withFluentVrTestVariants.tsx diff --git a/packages/react-components/react-storybook-addon/src/decorators/withFluentVrTestVariants.tsx b/packages/react-components/react-storybook-addon/src/decorators/withFluentVrTestVariants.tsx new file mode 100644 index 00000000000000..5efc1159b6df1d --- /dev/null +++ b/packages/react-components/react-storybook-addon/src/decorators/withFluentVrTestVariants.tsx @@ -0,0 +1,80 @@ +import * as React from 'react'; +import { FluentProvider } from '@fluentui/react-provider'; +import { teamsHighContrastTheme, webDarkTheme, webLightTheme } from '@fluentui/react-theme'; +import { makeDecorator } from '@storybook/addons'; +import type { StoryContext } from '@storybook/addons'; +import { useParameter } from '@storybook/api'; + +export const DARK_MODE = 'DarkMode'; +export const HIGH_CONTRAST = 'HighContrast'; +export const RTL = 'Rtl'; + +// MakeDecoratorOptions is not an exported interface by storybook so had to include necessary options +interface AssertedMakeDecoratorOptions { + name: string; + parameterName: string; + skipIfNoParametersOrOptions?: boolean; + wrapper: ( + storyFn: (context: StoryContext) => React.ReactNode, + context: StoryContext, + settings: { + parameters: typeof DARK_MODE | typeof HIGH_CONTRAST | typeof RTL; + }, + ) => React.ReactNode; +} + +type AssertedMakeDecorator = ({ + name, + parameterName, + skipIfNoParametersOrOptions, + wrapper, +}: AssertedMakeDecoratorOptions) => () => React.ReactNode; + +// export const withFluentVrTestVariants = ((makeDecorator as unknown) as AssertedMakeDecorator)({ +// name: 'withFluentVrTestVariants.', +// parameterName: 'vrTestVariant', +// skipIfNoParametersOrOptions: true, +// wrapper: (storyFn, context, { parameters }) => { +// console.log('parameter ', parameters); +// if (parameters === RTL) { +// return ( +// +// {storyFn(context)} +// +// ); +// } + +// if (parameters === DARK_MODE) { +// return {storyFn(context)}; +// } + +// if (parameters === HIGH_CONTRAST) { +// return {storyFn(context)}; +// } + +// return storyFn(context); +// }, +// }); + +export const withFluentVrTestVariants = (storyFn: () => JSX.Element, context: StoryContext) => { + const { variant } = context.parameters; + + // console.log('context', context); + if (variant === RTL) { + return ( + + {storyFn()} + + ); + } + + if (variant === DARK_MODE) { + return {storyFn()}; + } + + if (variant === HIGH_CONTRAST) { + return {storyFn()}; + } + + return storyFn(); +}; diff --git a/packages/react-components/react-storybook/src/decorators/index.ts b/packages/react-components/react-storybook/src/decorators/index.ts index fc01a36add316a..ff044dce8afc1a 100644 --- a/packages/react-components/react-storybook/src/decorators/index.ts +++ b/packages/react-components/react-storybook/src/decorators/index.ts @@ -1,3 +1,2 @@ export * from './withFluentProvider'; export * from './withStrictMode'; -export * from './withFluentVrTestVariants'; diff --git a/packages/react-components/react-storybook/src/index.test.ts b/packages/react-components/react-storybook/src/index.test.ts index b43c19d8229ea0..3f2fe8451a8629 100644 --- a/packages/react-components/react-storybook/src/index.test.ts +++ b/packages/react-components/react-storybook/src/index.test.ts @@ -1,9 +1,9 @@ -import { withFluentProvider, withFluentVrTestVariants, withStrictMode } from './index'; +import { withFluentProvider, withStrictMode } from './index'; describe(`public api`, () => { describe(`decorators`, () => { it(`should work`, () => { - const decorators = [withFluentProvider, withStrictMode, withFluentVrTestVariants]; + const decorators = [withFluentProvider, withStrictMode]; // @TODO - added proper tests expect(decorators).toBeDefined(); diff --git a/packages/react-components/react-storybook/src/index.ts b/packages/react-components/react-storybook/src/index.ts index a24f21148fefcb..0a74f9e4785213 100644 --- a/packages/react-components/react-storybook/src/index.ts +++ b/packages/react-components/react-storybook/src/index.ts @@ -1,8 +1 @@ -export { - withFluentProvider, - withStrictMode, - withFluentVrTestVariants, - DARK_MODE, - HIGH_CONTRAST, - RTL, -} from './decorators/index'; +export { withFluentProvider, withStrictMode } from './decorators/index'; From ed168ee6ee2f8b54993be9f0a5ac6262464cb761 Mon Sep 17 00:00:00 2001 From: Tristan Watanabe Date: Wed, 12 Oct 2022 11:48:45 -0700 Subject: [PATCH 20/53] delete withFluentVrTestVariants --- .../src/decorators/withFluentProvider.tsx | 22 ++++++-- .../decorators/withFluentVrTestVariants.tsx | 55 ------------------- 2 files changed, 16 insertions(+), 61 deletions(-) delete mode 100644 packages/react-components/react-storybook/src/decorators/withFluentVrTestVariants.tsx diff --git a/packages/react-components/react-storybook-addon/src/decorators/withFluentProvider.tsx b/packages/react-components/react-storybook-addon/src/decorators/withFluentProvider.tsx index 7132f18de9f27f..2a0b3419f6950d 100644 --- a/packages/react-components/react-storybook-addon/src/decorators/withFluentProvider.tsx +++ b/packages/react-components/react-storybook-addon/src/decorators/withFluentProvider.tsx @@ -2,23 +2,33 @@ import * as React from 'react'; import { FluentProvider } from '@fluentui/react-provider'; import { Theme } from '@fluentui/react-theme'; - -import { themes, defaultTheme } from '../theme'; +import { themes, defaultTheme, ThemeIds } from '../theme'; import { THEME_ID } from '../constants'; import { FluentGlobals, FluentStoryContext } from '../hooks'; +const findTheme = (themeId?: ThemeIds) => { + if (!themeId) { + return; + } + return themes.find(value => value.id === themeId); +}; + const getActiveFluentTheme = (globals: FluentGlobals) => { const selectedThemeId = globals[THEME_ID]; - const { theme } = themes.find(value => value.id === selectedThemeId) ?? defaultTheme; + const { theme } = findTheme(selectedThemeId) ?? defaultTheme; return { theme }; }; export const withFluentProvider = (StoryFn: () => JSX.Element, context: FluentStoryContext) => { - const { theme } = getActiveFluentTheme(context.globals); + const { globals, parameters } = context; + + const globalTheme = getActiveFluentTheme(globals); + const paramTheme = findTheme(parameters.fluentTheme) ?? undefined; + const { theme } = paramTheme ?? globalTheme; return ( - + {StoryFn()} ); @@ -28,5 +38,5 @@ const FluentExampleContainer: React.FC<{ theme: Theme }> = props => { const { theme } = props; const backgroundColor = theme.colorNeutralBackground2; - return
{props.children}
; + return
{props.children}
; }; diff --git a/packages/react-components/react-storybook/src/decorators/withFluentVrTestVariants.tsx b/packages/react-components/react-storybook/src/decorators/withFluentVrTestVariants.tsx deleted file mode 100644 index bced594168eb31..00000000000000 --- a/packages/react-components/react-storybook/src/decorators/withFluentVrTestVariants.tsx +++ /dev/null @@ -1,55 +0,0 @@ -import * as React from 'react'; -import { FluentProvider } from '@fluentui/react-provider'; -import { teamsHighContrastTheme, webDarkTheme, webLightTheme } from '@fluentui/react-theme'; -import { makeDecorator } from '@storybook/addons'; -import type { StoryContext } from '@storybook/addons'; - -export const DARK_MODE = 'DarkMode'; -export const HIGH_CONTRAST = 'HighContrast'; -export const RTL = 'Rtl'; - -// MakeDecoratorOptions is not an exported interface by storybook so had to include necessary options -interface AssertedMakeDecoratorOptions { - name: string; - parameterName: string; - skipIfNoParametersOrOptions?: boolean; - wrapper: ( - storyFn: (context: StoryContext) => React.ReactNode, - context: StoryContext, - settings: { - parameters: typeof DARK_MODE | typeof HIGH_CONTRAST | typeof RTL; - }, - ) => React.ReactNode; -} - -type AssertedMakeDecorator = ({ - name, - parameterName, - skipIfNoParametersOrOptions, - wrapper, -}: AssertedMakeDecoratorOptions) => () => React.ReactNode; - -export const withFluentVrTestVariants = ((makeDecorator as unknown) as AssertedMakeDecorator)({ - name: 'withFluentVrTestVariants.', - parameterName: 'vrTestVariant', - skipIfNoParametersOrOptions: true, - wrapper: (storyFn, context, { parameters }) => { - if (parameters === RTL) { - return ( - - {storyFn(context)} - - ); - } - - if (parameters === DARK_MODE) { - return {storyFn(context)}; - } - - if (parameters === HIGH_CONTRAST) { - return {storyFn(context)}; - } - - return storyFn(context); - }, -}); From d3765acfd699ac7a6e47d041ba9fdfa6137b97a5 Mon Sep 17 00:00:00 2001 From: Tristan Watanabe Date: Wed, 12 Oct 2022 11:52:59 -0700 Subject: [PATCH 21/53] remove withFluentVrTestVariant --- .../decorators/withFluentVrTestVariants.tsx | 80 ------------------- 1 file changed, 80 deletions(-) delete mode 100644 packages/react-components/react-storybook-addon/src/decorators/withFluentVrTestVariants.tsx diff --git a/packages/react-components/react-storybook-addon/src/decorators/withFluentVrTestVariants.tsx b/packages/react-components/react-storybook-addon/src/decorators/withFluentVrTestVariants.tsx deleted file mode 100644 index 5efc1159b6df1d..00000000000000 --- a/packages/react-components/react-storybook-addon/src/decorators/withFluentVrTestVariants.tsx +++ /dev/null @@ -1,80 +0,0 @@ -import * as React from 'react'; -import { FluentProvider } from '@fluentui/react-provider'; -import { teamsHighContrastTheme, webDarkTheme, webLightTheme } from '@fluentui/react-theme'; -import { makeDecorator } from '@storybook/addons'; -import type { StoryContext } from '@storybook/addons'; -import { useParameter } from '@storybook/api'; - -export const DARK_MODE = 'DarkMode'; -export const HIGH_CONTRAST = 'HighContrast'; -export const RTL = 'Rtl'; - -// MakeDecoratorOptions is not an exported interface by storybook so had to include necessary options -interface AssertedMakeDecoratorOptions { - name: string; - parameterName: string; - skipIfNoParametersOrOptions?: boolean; - wrapper: ( - storyFn: (context: StoryContext) => React.ReactNode, - context: StoryContext, - settings: { - parameters: typeof DARK_MODE | typeof HIGH_CONTRAST | typeof RTL; - }, - ) => React.ReactNode; -} - -type AssertedMakeDecorator = ({ - name, - parameterName, - skipIfNoParametersOrOptions, - wrapper, -}: AssertedMakeDecoratorOptions) => () => React.ReactNode; - -// export const withFluentVrTestVariants = ((makeDecorator as unknown) as AssertedMakeDecorator)({ -// name: 'withFluentVrTestVariants.', -// parameterName: 'vrTestVariant', -// skipIfNoParametersOrOptions: true, -// wrapper: (storyFn, context, { parameters }) => { -// console.log('parameter ', parameters); -// if (parameters === RTL) { -// return ( -// -// {storyFn(context)} -// -// ); -// } - -// if (parameters === DARK_MODE) { -// return {storyFn(context)}; -// } - -// if (parameters === HIGH_CONTRAST) { -// return {storyFn(context)}; -// } - -// return storyFn(context); -// }, -// }); - -export const withFluentVrTestVariants = (storyFn: () => JSX.Element, context: StoryContext) => { - const { variant } = context.parameters; - - // console.log('context', context); - if (variant === RTL) { - return ( - - {storyFn()} - - ); - } - - if (variant === DARK_MODE) { - return {storyFn()}; - } - - if (variant === HIGH_CONTRAST) { - return {storyFn()}; - } - - return storyFn(); -}; From 1f26987d978f866c1c5b259b06d02e3d07fb6673 Mon Sep 17 00:00:00 2001 From: Tristan Watanabe Date: Wed, 12 Oct 2022 12:18:24 -0700 Subject: [PATCH 22/53] feat: withFluentProvider now accepts fluentTheme and dir --- .../react-storybook-addon/src/components/ThemePicker.tsx | 7 +++++-- .../react-components/react-storybook-addon/src/hooks.ts | 8 +++++++- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/packages/react-components/react-storybook-addon/src/components/ThemePicker.tsx b/packages/react-components/react-storybook-addon/src/components/ThemePicker.tsx index 8d06603b3e645f..d48dbf24dac82e 100644 --- a/packages/react-components/react-storybook-addon/src/components/ThemePicker.tsx +++ b/packages/react-components/react-storybook-addon/src/components/ThemePicker.tsx @@ -1,9 +1,10 @@ import * as React from 'react'; import { IconButton, Icons, TooltipLinkList, WithTooltip } from '@storybook/components'; +import { useParameter } from '@storybook/api'; import { ThemeIds, themes, defaultTheme } from '../theme'; import { THEME_ID } from '../constants'; -import { useGlobals } from '../hooks'; +import { useGlobals, FluentParameters } from '../hooks'; export interface ThemeSelectorItem { id: string; @@ -33,7 +34,9 @@ function createThemeItems( export const ThemePicker = () => { const [globals, updateGlobals] = useGlobals(); - const selectedThemeId = globals[THEME_ID] ?? defaultTheme.id; + const fluentTheme: FluentParameters['fluentTheme'] = useParameter('fluentTheme'); + + const selectedThemeId = fluentTheme ? fluentTheme : globals[THEME_ID] ?? defaultTheme.id; const selectedTheme = themes.find(entry => entry.id === selectedThemeId); const isActive = selectedThemeId !== defaultTheme.id; diff --git a/packages/react-components/react-storybook-addon/src/hooks.ts b/packages/react-components/react-storybook-addon/src/hooks.ts index 649100df48ae84..0254f22f609f3b 100644 --- a/packages/react-components/react-storybook-addon/src/hooks.ts +++ b/packages/react-components/react-storybook-addon/src/hooks.ts @@ -1,4 +1,4 @@ -import { useGlobals as useStorybookGlobals, Args as StorybookArgs } from '@storybook/api'; +import { useGlobals as useStorybookGlobals, Args as StorybookArgs, Parameters } from '@storybook/api'; import { StoryContext as StorybookContext } from '@storybook/addons'; import { THEME_ID } from './constants'; @@ -6,6 +6,7 @@ import { ThemeIds } from './theme'; export interface FluentStoryContext extends StorybookContext { globals: FluentGlobals; + parameters: FluentParameters; } /** @@ -18,3 +19,8 @@ export interface FluentGlobals extends StorybookArgs { export function useGlobals(): [FluentGlobals, (newGlobals: FluentGlobals) => void] { return useStorybookGlobals(); } + +export interface FluentParameters extends Parameters { + fluentTheme: ThemeIds; + dir: 'ltr' | 'rtl'; +} From 66c95ef92034ce3c4de6a02c7d00d4da143121ca Mon Sep 17 00:00:00 2001 From: Tristan Watanabe Date: Wed, 12 Oct 2022 12:35:30 -0700 Subject: [PATCH 23/53] Add exported theme constants --- .../react-storybook-addon/src/theme.ts | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/packages/react-components/react-storybook-addon/src/theme.ts b/packages/react-components/react-storybook-addon/src/theme.ts index 52484c93063684..447342ad141eec 100644 --- a/packages/react-components/react-storybook-addon/src/theme.ts +++ b/packages/react-components/react-storybook-addon/src/theme.ts @@ -8,12 +8,18 @@ import { import type { Theme } from '@fluentui/react-theme'; +export const WEB_LIGHT = 'web-light'; +export const WEB_DARK = 'web-dark'; +export const TEAMS_LIGHT = 'teams-light'; +export const TEAMS_DARK = 'teams-dark'; +export const TEAMS_HIGH_CONTRAST = 'teams-high-contrast'; + export const themes = [ - { id: 'web-light', label: 'Web Light', theme: webLightTheme }, - { id: 'web-dark', label: 'Web Dark', theme: webDarkTheme }, - { id: 'teams-light', label: 'Teams Light', theme: teamsLightTheme }, - { id: 'teams-dark', label: 'Teams Dark', theme: teamsDarkTheme }, - { id: 'teams-high-contrast', label: 'Teams High Contrast', theme: teamsHighContrastTheme }, + { id: WEB_LIGHT, label: 'Web Light', theme: webLightTheme }, + { id: WEB_DARK, label: 'Web Dark', theme: webDarkTheme }, + { id: TEAMS_LIGHT, label: 'Teams Light', theme: teamsLightTheme }, + { id: TEAMS_DARK, label: 'Teams Dark', theme: teamsDarkTheme }, + { id: TEAMS_HIGH_CONTRAST, label: 'Teams High Contrast', theme: teamsHighContrastTheme }, ] as const; export const defaultTheme = themes[0]; From ab22cd51fa4c424b464b18065f721b6415247feb Mon Sep 17 00:00:00 2001 From: Tristan Watanabe Date: Thu, 13 Oct 2022 03:33:20 -0700 Subject: [PATCH 24/53] feat: add isVrTest parameter --- .../src/decorators/withFluentProvider.tsx | 6 +++--- .../react-storybook-addon/src/hooks.ts | 16 ++++++++++------ 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/packages/react-components/react-storybook-addon/src/decorators/withFluentProvider.tsx b/packages/react-components/react-storybook-addon/src/decorators/withFluentProvider.tsx index 2a0b3419f6950d..f79427b6fab7f6 100644 --- a/packages/react-components/react-storybook-addon/src/decorators/withFluentProvider.tsx +++ b/packages/react-components/react-storybook-addon/src/decorators/withFluentProvider.tsx @@ -22,14 +22,14 @@ const getActiveFluentTheme = (globals: FluentGlobals) => { export const withFluentProvider = (StoryFn: () => JSX.Element, context: FluentStoryContext) => { const { globals, parameters } = context; - + const { isVrTest } = parameters; const globalTheme = getActiveFluentTheme(globals); - const paramTheme = findTheme(parameters.fluentTheme) ?? undefined; + const paramTheme = findTheme(parameters.fluentTheme); const { theme } = paramTheme ?? globalTheme; return ( - {StoryFn()} + {isVrTest ? StoryFn() : {StoryFn()}} ); }; diff --git a/packages/react-components/react-storybook-addon/src/hooks.ts b/packages/react-components/react-storybook-addon/src/hooks.ts index 0254f22f609f3b..26c19856de5497 100644 --- a/packages/react-components/react-storybook-addon/src/hooks.ts +++ b/packages/react-components/react-storybook-addon/src/hooks.ts @@ -10,17 +10,21 @@ export interface FluentStoryContext extends StorybookContext { } /** - * Extends the storybook globals object to include fluent specific propoerties + * Extends the storybook globals object to include fluent specific properties */ export interface FluentGlobals extends StorybookArgs { [THEME_ID]?: ThemeIds; } -export function useGlobals(): [FluentGlobals, (newGlobals: FluentGlobals) => void] { - return useStorybookGlobals(); +/** + * Extends the storybook parameters object to include fluent specific properties + */ +export interface FluentParameters extends Parameters { + dir?: 'ltr' | 'rtl'; + fluentTheme?: ThemeIds; + isVrTest?: boolean; } -export interface FluentParameters extends Parameters { - fluentTheme: ThemeIds; - dir: 'ltr' | 'rtl'; +export function useGlobals(): [FluentGlobals, (newGlobals: FluentGlobals) => void] { + return useStorybookGlobals(); } From 060d69623e580aeb8ed280e5370a6bb8300ce906 Mon Sep 17 00:00:00 2001 From: Tristan Watanabe Date: Thu, 13 Oct 2022 03:34:07 -0700 Subject: [PATCH 25/53] Revert "Add usage of decorator to README" This reverts commit dcfcde39f3c7dfac22ecb96bc133c511e61a6adf. --- .../react-storybook/README.md | 29 ++----------------- 1 file changed, 2 insertions(+), 27 deletions(-) diff --git a/packages/react-components/react-storybook/README.md b/packages/react-components/react-storybook/README.md index 64607466e8d423..bdc825fa64b223 100644 --- a/packages/react-components/react-storybook/README.md +++ b/packages/react-components/react-storybook/README.md @@ -22,33 +22,8 @@ You need to register fluentui decorators on your particular level (global/story/ // @filename: .storybook/preview.js import { withKnobs } from '@storybook/addon-knobs'; -import { withStrictMode, withFluentVrTestVariants } from '@fluentui/react-storybook'; +import { withStrictMode } from '@fluentui/react-storybook'; // Register decorators on global level -export const decorators = [withKnobs, withStrictMode, withFluentVrTestVariants]; -``` - -## withFluentVrTestVariants: - -```js -import { withFluentVrTestVariants, DARK_MODE, HIGH_CONTRAST, RTL } from '@fluentui/react-storybook'; -import { Button } from '@fluentui/react-components'; - -export const Button = () => ; - -export const ButtonDarkMode = { - render: Button, - parameters: { variant: DARK_MODE }, // story renders in Dark mode. -}; - -export const ButtonHighContrast = { - render: Button, - parameters: { variant: HIGH_CONTRAST }; // story renders in High Contrast mode. -} - -export const ButtonRTL = { - render: Button, - parameters: { variant: RTL }, // story renders in RTL. -}; - +export const decorators = [withKnobs, withStrictMode]; ``` From 18c3e6d2551e137a3f64b183b96420f027e2d67e Mon Sep 17 00:00:00 2001 From: Tristan Watanabe Date: Thu, 13 Oct 2022 03:48:09 -0700 Subject: [PATCH 26/53] update ReadMe --- .../react-storybook-addon/README.md | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/packages/react-components/react-storybook-addon/README.md b/packages/react-components/react-storybook-addon/README.md index 452ce80d947b88..1e95d5ecc715fe 100644 --- a/packages/react-components/react-storybook-addon/README.md +++ b/packages/react-components/react-storybook-addon/README.md @@ -68,3 +68,34 @@ module.exports = { - > 💡 this will run `prestorybook` script that compiles addon implementation with all of its direct dependencies that live within monorepo, so it can be consumed by local storybook 2. Every time you do any change to implementation, after you ran your local storybook you'll need to manually run `yarn workspace @fluentui/react-storybook-addon build` to reflect those changes + +## Parameter Configuration + +- Three custom optional parameters can be set to alter behavior of the addon + 1. `dir` - determines whether to render story in `ltr` or `rtl` mode. Default is `undefined`. + 2. `fluentTheme` - determines whether to render story theme in `web-light`, `web-dark`, `teams-high-contrast`, `teams-dark`, or `teams-light`. Setting this + parameter will disable ability to dynamically change the theme within story canvas or doc. + 3. `isVrTest` - when set to `true`, this removes injected padding and background theme that's automatically applied from rendered story. + +```js +import { TEAMS_HIGH_CONTRAST, WEB_DARK, WEB_LIGHT } from '@fluentui/react-storybook-addon'; +import { Button } from '@fluentui/react-components'; + +export const Button = () => ; + +export const ButtonDarkMode = { + render: Button, + parameters: { fluentTheme: WEB_DARK }, // story renders in Dark mode. +}; + +export const ButtonHighContrast = { + render: Button, + parameters: { fluentTheme: TEAMS_HIGH_CONTRAST, isVrTest: true }; // story renders in High Contrast mode without injected padding and background style. +} + +export const ButtonRTL = { + render: Button, + parameters: { fluentTheme: WEB_LIGHT, dir: 'rtl', isVrTest: true}, // story renders in RTL, Web light mode and without injected padding and background style. +}; + +``` From 14847d92f4bd6910a7d0c5f3f65918f6b5878d23 Mon Sep 17 00:00:00 2001 From: Tristan Watanabe Date: Thu, 13 Oct 2022 03:54:10 -0700 Subject: [PATCH 27/53] Add constants and FluentParameters to exports --- packages/react-components/react-storybook-addon/src/index.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/react-components/react-storybook-addon/src/index.ts b/packages/react-components/react-storybook-addon/src/index.ts index ecb1744ced790a..4a5bdd736135a1 100644 --- a/packages/react-components/react-storybook-addon/src/index.ts +++ b/packages/react-components/react-storybook-addon/src/index.ts @@ -1,4 +1,4 @@ -export type { FluentGlobals, FluentStoryContext } from './hooks'; +export type { FluentGlobals, FluentParameters, FluentStoryContext } from './hooks'; export type { ThemeIds } from './theme'; -export { themes } from './theme'; +export { themes, TEAMS_DARK, TEAMS_HIGH_CONTRAST, TEAMS_LIGHT, WEB_DARK, WEB_LIGHT } from './theme'; export { THEME_ID } from './constants'; From 20091d7bb91074ebfe0742b1946ab5391ecd95bf Mon Sep 17 00:00:00 2001 From: Tristan Watanabe Date: Thu, 13 Oct 2022 03:55:38 -0700 Subject: [PATCH 28/53] Update API --- .../etc/react-storybook-addon.api.md | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/packages/react-components/react-storybook-addon/etc/react-storybook-addon.api.md b/packages/react-components/react-storybook-addon/etc/react-storybook-addon.api.md index c9d140b21ddb9c..a60d1b5abd5419 100644 --- a/packages/react-components/react-storybook-addon/etc/react-storybook-addon.api.md +++ b/packages/react-components/react-storybook-addon/etc/react-storybook-addon.api.md @@ -5,6 +5,7 @@ ```ts import { Args } from '@storybook/api'; +import { Parameters as Parameters_2 } from '@storybook/api'; import { StoryContext } from '@storybook/addons'; import type { Theme } from '@fluentui/react-theme'; @@ -14,12 +15,33 @@ export interface FluentGlobals extends Args { [THEME_ID]?: ThemeIds; } +// @public +export interface FluentParameters extends Parameters_2 { + // (undocumented) + dir?: 'ltr' | 'rtl'; + // (undocumented) + fluentTheme?: ThemeIds; + // (undocumented) + isVrTest?: boolean; +} + // @public (undocumented) export interface FluentStoryContext extends StoryContext { // (undocumented) globals: FluentGlobals; + // (undocumented) + parameters: FluentParameters; } +// @public (undocumented) +export const TEAMS_DARK = "teams-dark"; + +// @public (undocumented) +export const TEAMS_HIGH_CONTRAST = "teams-high-contrast"; + +// @public (undocumented) +export const TEAMS_LIGHT = "teams-light"; + // @public (undocumented) export const THEME_ID: "storybook/fluentui-react-addon/theme"; @@ -49,6 +71,12 @@ export const themes: readonly [{ readonly theme: Theme; }]; +// @public (undocumented) +export const WEB_DARK = "web-dark"; + +// @public (undocumented) +export const WEB_LIGHT = "web-light"; + // (No @packageDocumentation comment for this package) ``` From e840ba7141db7df3b5db18eae095275e84306200 Mon Sep 17 00:00:00 2001 From: Tristan Watanabe Date: Thu, 13 Oct 2022 03:56:50 -0700 Subject: [PATCH 29/53] Revert "Update API" This reverts commit fb87708ab46c08f137d00166a5293b5af2e62204. --- .../react-storybook/etc/react-storybook.api.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/react-components/react-storybook/etc/react-storybook.api.md b/packages/react-components/react-storybook/etc/react-storybook.api.md index a78d1619f159d1..1290f16b5b06a1 100644 --- a/packages/react-components/react-storybook/etc/react-storybook.api.md +++ b/packages/react-components/react-storybook/etc/react-storybook.api.md @@ -4,6 +4,7 @@ ```ts +import { DecoratorFunction } from '@storybook/addons'; import * as React_2 from 'react'; // @public (undocumented) @@ -19,7 +20,7 @@ export const RTL = "Rtl"; export const withFluentProvider: (...args: any) => any; // @public (undocumented) -export const withFluentVrTestVariants: () => React_2.ReactNode; +export const withFluentVrTestVariants: DecoratorFunction; // @public (undocumented) export const withStrictMode: (storyFn: () => React_2.ReactNode) => JSX.Element; From 21eba2e5a72be790593be98154a38dc3251a9ece Mon Sep 17 00:00:00 2001 From: Tristan Watanabe Date: Thu, 13 Oct 2022 03:57:27 -0700 Subject: [PATCH 30/53] Revert "fix: typing and update API" This reverts commit bda9ea40291e1e694a3ff7b968b8490269a38ec9. --- .../react-storybook/etc/react-storybook.api.md | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/packages/react-components/react-storybook/etc/react-storybook.api.md b/packages/react-components/react-storybook/etc/react-storybook.api.md index 1290f16b5b06a1..3b8bfcc94de544 100644 --- a/packages/react-components/react-storybook/etc/react-storybook.api.md +++ b/packages/react-components/react-storybook/etc/react-storybook.api.md @@ -3,28 +3,13 @@ > Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). ```ts - -import { DecoratorFunction } from '@storybook/addons'; import * as React_2 from 'react'; -// @public (undocumented) -export const DARK_MODE = "DarkMode"; - -// @public (undocumented) -export const HIGH_CONTRAST = "HighContrast"; - -// @public (undocumented) -export const RTL = "Rtl"; - // @public (undocumented) export const withFluentProvider: (...args: any) => any; -// @public (undocumented) -export const withFluentVrTestVariants: DecoratorFunction; - // @public (undocumented) export const withStrictMode: (storyFn: () => React_2.ReactNode) => JSX.Element; // (No @packageDocumentation comment for this package) - ``` From 81de5233d94b8fa35eb180143530d4392370a572 Mon Sep 17 00:00:00 2001 From: Tristan Watanabe Date: Sun, 16 Oct 2022 04:49:58 -0700 Subject: [PATCH 31/53] feedback: don't export constants, export FluentParameter type --- .../etc/react-storybook-addon.api.md | 15 --------------- .../react-storybook-addon/src/index.ts | 2 +- .../react-storybook-addon/src/theme.ts | 16 +++++----------- 3 files changed, 6 insertions(+), 27 deletions(-) diff --git a/packages/react-components/react-storybook-addon/etc/react-storybook-addon.api.md b/packages/react-components/react-storybook-addon/etc/react-storybook-addon.api.md index a60d1b5abd5419..7260db227a34f1 100644 --- a/packages/react-components/react-storybook-addon/etc/react-storybook-addon.api.md +++ b/packages/react-components/react-storybook-addon/etc/react-storybook-addon.api.md @@ -33,15 +33,6 @@ export interface FluentStoryContext extends StoryContext { parameters: FluentParameters; } -// @public (undocumented) -export const TEAMS_DARK = "teams-dark"; - -// @public (undocumented) -export const TEAMS_HIGH_CONTRAST = "teams-high-contrast"; - -// @public (undocumented) -export const TEAMS_LIGHT = "teams-light"; - // @public (undocumented) export const THEME_ID: "storybook/fluentui-react-addon/theme"; @@ -71,12 +62,6 @@ export const themes: readonly [{ readonly theme: Theme; }]; -// @public (undocumented) -export const WEB_DARK = "web-dark"; - -// @public (undocumented) -export const WEB_LIGHT = "web-light"; - // (No @packageDocumentation comment for this package) ``` diff --git a/packages/react-components/react-storybook-addon/src/index.ts b/packages/react-components/react-storybook-addon/src/index.ts index 4a5bdd736135a1..d0b55796b9660b 100644 --- a/packages/react-components/react-storybook-addon/src/index.ts +++ b/packages/react-components/react-storybook-addon/src/index.ts @@ -1,4 +1,4 @@ export type { FluentGlobals, FluentParameters, FluentStoryContext } from './hooks'; export type { ThemeIds } from './theme'; -export { themes, TEAMS_DARK, TEAMS_HIGH_CONTRAST, TEAMS_LIGHT, WEB_DARK, WEB_LIGHT } from './theme'; +export { themes } from './theme'; export { THEME_ID } from './constants'; diff --git a/packages/react-components/react-storybook-addon/src/theme.ts b/packages/react-components/react-storybook-addon/src/theme.ts index 447342ad141eec..52484c93063684 100644 --- a/packages/react-components/react-storybook-addon/src/theme.ts +++ b/packages/react-components/react-storybook-addon/src/theme.ts @@ -8,18 +8,12 @@ import { import type { Theme } from '@fluentui/react-theme'; -export const WEB_LIGHT = 'web-light'; -export const WEB_DARK = 'web-dark'; -export const TEAMS_LIGHT = 'teams-light'; -export const TEAMS_DARK = 'teams-dark'; -export const TEAMS_HIGH_CONTRAST = 'teams-high-contrast'; - export const themes = [ - { id: WEB_LIGHT, label: 'Web Light', theme: webLightTheme }, - { id: WEB_DARK, label: 'Web Dark', theme: webDarkTheme }, - { id: TEAMS_LIGHT, label: 'Teams Light', theme: teamsLightTheme }, - { id: TEAMS_DARK, label: 'Teams Dark', theme: teamsDarkTheme }, - { id: TEAMS_HIGH_CONTRAST, label: 'Teams High Contrast', theme: teamsHighContrastTheme }, + { id: 'web-light', label: 'Web Light', theme: webLightTheme }, + { id: 'web-dark', label: 'Web Dark', theme: webDarkTheme }, + { id: 'teams-light', label: 'Teams Light', theme: teamsLightTheme }, + { id: 'teams-dark', label: 'Teams Dark', theme: teamsDarkTheme }, + { id: 'teams-high-contrast', label: 'Teams High Contrast', theme: teamsHighContrastTheme }, ] as const; export const defaultTheme = themes[0]; From b5f378816a1794245bd352c8c4612a222481fac1 Mon Sep 17 00:00:00 2001 From: Tristan Watanabe Date: Sun, 16 Oct 2022 05:01:16 -0700 Subject: [PATCH 32/53] feedback: replace isVrTest param with more dynamic mode param --- .../src/decorators/withFluentProvider.tsx | 4 +++- packages/react-components/react-storybook-addon/src/hooks.ts | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/react-components/react-storybook-addon/src/decorators/withFluentProvider.tsx b/packages/react-components/react-storybook-addon/src/decorators/withFluentProvider.tsx index f79427b6fab7f6..8d513eb8961f6a 100644 --- a/packages/react-components/react-storybook-addon/src/decorators/withFluentProvider.tsx +++ b/packages/react-components/react-storybook-addon/src/decorators/withFluentProvider.tsx @@ -22,7 +22,9 @@ const getActiveFluentTheme = (globals: FluentGlobals) => { export const withFluentProvider = (StoryFn: () => JSX.Element, context: FluentStoryContext) => { const { globals, parameters } = context; - const { isVrTest } = parameters; + const { mode } = parameters; + const isVrTest = mode === 'vr-test'; + const globalTheme = getActiveFluentTheme(globals); const paramTheme = findTheme(parameters.fluentTheme); const { theme } = paramTheme ?? globalTheme; diff --git a/packages/react-components/react-storybook-addon/src/hooks.ts b/packages/react-components/react-storybook-addon/src/hooks.ts index 26c19856de5497..7a2d27ccc99529 100644 --- a/packages/react-components/react-storybook-addon/src/hooks.ts +++ b/packages/react-components/react-storybook-addon/src/hooks.ts @@ -22,7 +22,7 @@ export interface FluentGlobals extends StorybookArgs { export interface FluentParameters extends Parameters { dir?: 'ltr' | 'rtl'; fluentTheme?: ThemeIds; - isVrTest?: boolean; + mode?: 'default' | 'vr-test'; } export function useGlobals(): [FluentGlobals, (newGlobals: FluentGlobals) => void] { From 4842eb93b92f604ee2f7bb7ad95186520588427f Mon Sep 17 00:00:00 2001 From: Tristan Watanabe Date: Sun, 16 Oct 2022 05:17:28 -0700 Subject: [PATCH 33/53] feedback: add parameters identity function and export --- packages/react-components/react-storybook-addon/src/hooks.ts | 4 ++++ packages/react-components/react-storybook-addon/src/index.ts | 1 + 2 files changed, 5 insertions(+) diff --git a/packages/react-components/react-storybook-addon/src/hooks.ts b/packages/react-components/react-storybook-addon/src/hooks.ts index 7a2d27ccc99529..ac9a7055cef9ff 100644 --- a/packages/react-components/react-storybook-addon/src/hooks.ts +++ b/packages/react-components/react-storybook-addon/src/hooks.ts @@ -28,3 +28,7 @@ export interface FluentParameters extends Parameters { export function useGlobals(): [FluentGlobals, (newGlobals: FluentGlobals) => void] { return useStorybookGlobals(); } + +export function parameters(options?: FluentParameters) { + return { dir: 'ltr', fluentTheme: 'web-light', mode: 'default', ...options }; +} diff --git a/packages/react-components/react-storybook-addon/src/index.ts b/packages/react-components/react-storybook-addon/src/index.ts index d0b55796b9660b..7e02b8967b3eaa 100644 --- a/packages/react-components/react-storybook-addon/src/index.ts +++ b/packages/react-components/react-storybook-addon/src/index.ts @@ -2,3 +2,4 @@ export type { FluentGlobals, FluentParameters, FluentStoryContext } from './hook export type { ThemeIds } from './theme'; export { themes } from './theme'; export { THEME_ID } from './constants'; +export { parameters } from './hooks'; From 83173292245f6d44df971414a0f43547b3ce469c Mon Sep 17 00:00:00 2001 From: Tristan Watanabe Date: Sun, 16 Oct 2022 05:17:39 -0700 Subject: [PATCH 34/53] Update API --- .../etc/react-storybook-addon.api.md | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/packages/react-components/react-storybook-addon/etc/react-storybook-addon.api.md b/packages/react-components/react-storybook-addon/etc/react-storybook-addon.api.md index 7260db227a34f1..02800552969e24 100644 --- a/packages/react-components/react-storybook-addon/etc/react-storybook-addon.api.md +++ b/packages/react-components/react-storybook-addon/etc/react-storybook-addon.api.md @@ -22,7 +22,7 @@ export interface FluentParameters extends Parameters_2 { // (undocumented) fluentTheme?: ThemeIds; // (undocumented) - isVrTest?: boolean; + mode?: 'default' | 'vr-test'; } // @public (undocumented) @@ -33,6 +33,13 @@ export interface FluentStoryContext extends StoryContext { parameters: FluentParameters; } +// @public (undocumented) +export function parameters(options?: FluentParameters): { + dir: string; + fluentTheme: string; + mode: string; +}; + // @public (undocumented) export const THEME_ID: "storybook/fluentui-react-addon/theme"; From 55836b63c0e4ba1b4fda5b16be399a696e073286 Mon Sep 17 00:00:00 2001 From: Tristan Watanabe Date: Sun, 16 Oct 2022 05:23:30 -0700 Subject: [PATCH 35/53] Update README --- .../react-components/react-storybook-addon/README.md | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/packages/react-components/react-storybook-addon/README.md b/packages/react-components/react-storybook-addon/README.md index 1e95d5ecc715fe..a11182fce4201d 100644 --- a/packages/react-components/react-storybook-addon/README.md +++ b/packages/react-components/react-storybook-addon/README.md @@ -75,27 +75,28 @@ module.exports = { 1. `dir` - determines whether to render story in `ltr` or `rtl` mode. Default is `undefined`. 2. `fluentTheme` - determines whether to render story theme in `web-light`, `web-dark`, `teams-high-contrast`, `teams-dark`, or `teams-light`. Setting this parameter will disable ability to dynamically change the theme within story canvas or doc. - 3. `isVrTest` - when set to `true`, this removes injected padding and background theme that's automatically applied from rendered story. + 3. `mode` - when set to `vr-test`, this removes injected padding and background theme that's automatically applied from rendered story. Default is `default`. ```js -import { TEAMS_HIGH_CONTRAST, WEB_DARK, WEB_LIGHT } from '@fluentui/react-storybook-addon'; +import { FluentParameters, parameters } from '@fluentui/react-storybook-addon'; import { Button } from '@fluentui/react-components'; export const Button = () => ; export const ButtonDarkMode = { render: Button, - parameters: { fluentTheme: WEB_DARK }, // story renders in Dark mode. + parameters: { fluentTheme: 'web-dark' } as FluentParameters, // story renders in Dark mode. }; export const ButtonHighContrast = { render: Button, - parameters: { fluentTheme: TEAMS_HIGH_CONTRAST, isVrTest: true }; // story renders in High Contrast mode without injected padding and background style. + parameters: { fluentTheme: 'teams-high-contrast', mode: 'vr-test' } as FluentParameters; // story renders in High Contrast mode without injected padding and background style. } export const ButtonRTL = { render: Button, - parameters: { fluentTheme: WEB_LIGHT, dir: 'rtl', isVrTest: true}, // story renders in RTL, Web light mode and without injected padding and background style. + // parameters identity function will have all TS type annotations built in for intellisense. + parameters: parameters({ fluentTheme: 'web-light', dir: 'rtl', mode: 'vr-test'}), // story renders in RTL, Web light mode and without injected padding and background style. }; ``` From d1b213d0879e58065edf099dc5cc662a38cd16e2 Mon Sep 17 00:00:00 2001 From: Tristan Watanabe Date: Sun, 16 Oct 2022 11:11:49 -0700 Subject: [PATCH 36/53] refactor: use withFluentProvider addon instead and configure parameters for VR stories --- .../.storybook/main.js | 2 ++ .../.storybook/preview.js | 9 ++----- apps/vr-tests-react-components/package.json | 1 + .../src/utilities/StoryDecorators.tsx | 21 ---------------- .../src/utilities/getStoryVariant.ts | 25 +++++++------------ .../src/utilities/index.ts | 1 - 6 files changed, 14 insertions(+), 45 deletions(-) delete mode 100644 apps/vr-tests-react-components/src/utilities/StoryDecorators.tsx diff --git a/apps/vr-tests-react-components/.storybook/main.js b/apps/vr-tests-react-components/.storybook/main.js index 66d036830a2187..f5d8408fdc6126 100644 --- a/apps/vr-tests-react-components/.storybook/main.js +++ b/apps/vr-tests-react-components/.storybook/main.js @@ -1,7 +1,9 @@ const path = require('path'); const { TsconfigPathsPlugin } = require('tsconfig-paths-webpack-plugin'); +const { loadWorkspaceAddon } = require('@fluentui/scripts/storybook'); module.exports = /** @type {import('../../../.storybook/main').StorybookBaseConfig} */ ({ + addons: [loadWorkspaceAddon('@fluentui/react-storybook-addon')], stories: ['../src/**/*.stories.tsx'], core: { builder: 'webpack5', diff --git a/apps/vr-tests-react-components/.storybook/preview.js b/apps/vr-tests-react-components/.storybook/preview.js index 191e2c99aa41b5..da9d74b6076224 100644 --- a/apps/vr-tests-react-components/.storybook/preview.js +++ b/apps/vr-tests-react-components/.storybook/preview.js @@ -53,13 +53,8 @@ setAddon({ }, }); -export const parameters = { layout: 'none' }; - -export const decorators = [ - /** @type {import("@storybook/csf").DecoratorFunction} */ story => ( - {story()} - ), -]; +/** @type {import("@fluentui/react-storybook-addon").FluentParameters} */ +export const parameters = { layout: 'none', mode: 'vr-test' }; // For static storybook per https://github.com/screener-io/screener-storybook#testing-with-static-storybook-app if (typeof window === 'object') { diff --git a/apps/vr-tests-react-components/package.json b/apps/vr-tests-react-components/package.json index d6c2208498a5f0..f830fda47e453b 100644 --- a/apps/vr-tests-react-components/package.json +++ b/apps/vr-tests-react-components/package.json @@ -43,6 +43,7 @@ "@fluentui/react-slider": "^9.0.8", "@fluentui/react-spinner": "^9.0.8", "@fluentui/react-spinbutton": "^9.0.5", + "@fluentui/react-storybook-addon": "^9.0.0-rc.1", "@fluentui/react-switch": "^9.0.9", "@fluentui/react-tabs": "^9.0.9", "@fluentui/react-table": "9.0.0-alpha.7", diff --git a/apps/vr-tests-react-components/src/utilities/StoryDecorators.tsx b/apps/vr-tests-react-components/src/utilities/StoryDecorators.tsx deleted file mode 100644 index 374f9e47e3f267..00000000000000 --- a/apps/vr-tests-react-components/src/utilities/StoryDecorators.tsx +++ /dev/null @@ -1,21 +0,0 @@ -import * as React from 'react'; -import { DecoratorFunction } from '@storybook/addons'; -import { webLightTheme, teamsHighContrastTheme, webDarkTheme } from '@fluentui/react-theme'; -import { FluentProvider } from '@fluentui/react-provider'; -import { ExtendedStoryFnReturnType } from './types'; - -export const DarkModeDecorator: DecoratorFunction = story => { - return {story()}; -}; - -export const HighContrastDecorator: DecoratorFunction = story => { - return {story()}; -}; - -export const RTLDecorator: DecoratorFunction = story => { - return ( - - {story()} - - ); -}; diff --git a/apps/vr-tests-react-components/src/utilities/getStoryVariant.ts b/apps/vr-tests-react-components/src/utilities/getStoryVariant.ts index 7550a60a30c3ed..48fd8229cbb888 100644 --- a/apps/vr-tests-react-components/src/utilities/getStoryVariant.ts +++ b/apps/vr-tests-react-components/src/utilities/getStoryVariant.ts @@ -1,5 +1,5 @@ import { ComponentStory } from '@storybook/react'; -import { DarkModeDecorator, HighContrastDecorator, RTLDecorator } from './StoryDecorators'; +import { parameters } from '@fluentui/react-storybook-addon'; export const DARK_MODE = 'Dark Mode'; export const HIGH_CONTRAST = 'High Contrast'; @@ -8,26 +8,19 @@ export const RTL = 'RTL'; /** * Helper function that returns a RTL, Dark Mode or High Contrast variant of an existing story. */ -export const getStoryVariant = (story: ComponentStory, variant: 'RTL' | 'Dark Mode' | 'High Contrast') => { - let decorator; +export const getStoryVariant = ( + story: ComponentStory, + variant: typeof DARK_MODE | typeof HIGH_CONTRAST | typeof RTL, +) => { const name = story.name.replace(/([a-z])([A-Z])/g, '$1 $2'); - - if (variant === RTL) { - decorator = RTLDecorator; - } - - if (variant === DARK_MODE) { - decorator = DarkModeDecorator; - } - - if (variant === HIGH_CONTRAST) { - decorator = HighContrastDecorator; - } + const fluentTheme = + variant === DARK_MODE ? 'web-dark' : variant === HIGH_CONTRAST ? 'teams-high-contrast' : 'web-light'; + const dir = variant === RTL ? 'rtl' : 'ltr'; return { ...story, render: story, storyName: `${story.storyName ?? name} - ${variant}`, - decorators: [decorator], + parameters: parameters({ fluentTheme, dir, mode: 'vr-test' }), }; }; diff --git a/apps/vr-tests-react-components/src/utilities/index.ts b/apps/vr-tests-react-components/src/utilities/index.ts index d071a94751e8b6..e2de063e017a08 100644 --- a/apps/vr-tests-react-components/src/utilities/index.ts +++ b/apps/vr-tests-react-components/src/utilities/index.ts @@ -8,5 +8,4 @@ declare module '@storybook/addons' { } export * from './TestWrapperDecorator'; -export * from './StoryDecorators'; export * from './getStoryVariant'; From d888f928b85731ab96921ff6ff9ae6704e1e9dd8 Mon Sep 17 00:00:00 2001 From: Tristan Watanabe Date: Thu, 20 Oct 2022 10:30:39 -0700 Subject: [PATCH 37/53] remove unintended prettier changes --- packages/react-components/react-persona/MIGRATION.md | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/react-components/react-persona/MIGRATION.md b/packages/react-components/react-persona/MIGRATION.md index 57e145ba51c7a2..697c575bbd7365 100644 --- a/packages/react-components/react-persona/MIGRATION.md +++ b/packages/react-components/react-persona/MIGRATION.md @@ -13,7 +13,6 @@ Here's how the API of v8's `Persona` compares to the one from v9's `Persona` com - ``` ``` - - `imageShouldFadeIn` => NOT SUPPORTED - `isOutOfOffice` => Use the `outOfOffice` prop of the `presence` slot. E.g.: `presence={{ outOfOffice: true }}` - `presence` => Use the `status` prop of the `presence` slot. E.g.: `presence={{ status: 'away' }}` From 6c6550a7d868f5595c7f4fb93114a902c229043b Mon Sep 17 00:00:00 2001 From: Tristan Watanabe Date: Sun, 16 Oct 2022 11:56:24 -0700 Subject: [PATCH 38/53] add react-storybook-addon and update github workflow --- .github/workflows/screener-build.yml | 4 ++++ apps/vr-tests-react-components/.storybook/main.js | 1 + 2 files changed, 5 insertions(+) diff --git a/.github/workflows/screener-build.yml b/.github/workflows/screener-build.yml index f4ddf2e6633f10..098a8a6a9b82bd 100644 --- a/.github/workflows/screener-build.yml +++ b/.github/workflows/screener-build.yml @@ -272,6 +272,10 @@ jobs: printenv | sort ;\ echo "SHELLOPTS $SHELLOPTS" ;\ + - name: build @fluentui/react-storybook-addon + run: yarn workspace @fluentui/react-storybook-addon build + if: ${{env.SKIP_SCREENER_BUILD == 'false'}} + - name: build vr-tests-react-components storybook run: yarn workspace @fluentui/vr-tests-react-components screener:build if: ${{env.SKIP_SCREENER_BUILD == 'false'}} diff --git a/apps/vr-tests-react-components/.storybook/main.js b/apps/vr-tests-react-components/.storybook/main.js index f5d8408fdc6126..7d8c374a4e61f9 100644 --- a/apps/vr-tests-react-components/.storybook/main.js +++ b/apps/vr-tests-react-components/.storybook/main.js @@ -4,6 +4,7 @@ const { loadWorkspaceAddon } = require('@fluentui/scripts/storybook'); module.exports = /** @type {import('../../../.storybook/main').StorybookBaseConfig} */ ({ addons: [loadWorkspaceAddon('@fluentui/react-storybook-addon')], + stories: ['../src/**/*.stories.tsx'], core: { builder: 'webpack5', From 139aed9f61a3f80a8b07fd735c2fee92cd093fd0 Mon Sep 17 00:00:00 2001 From: Tristan Watanabe Date: Sun, 16 Oct 2022 12:04:59 -0700 Subject: [PATCH 39/53] fix: build react-storybook-addon in screener CI --- .github/workflows/screener-build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/screener-build.yml b/.github/workflows/screener-build.yml index 098a8a6a9b82bd..a968727e1a1f3f 100644 --- a/.github/workflows/screener-build.yml +++ b/.github/workflows/screener-build.yml @@ -273,7 +273,7 @@ jobs: echo "SHELLOPTS $SHELLOPTS" ;\ - name: build @fluentui/react-storybook-addon - run: yarn workspace @fluentui/react-storybook-addon build + run: yarn build --to @fluentui/react-storybook-addon if: ${{env.SKIP_SCREENER_BUILD == 'false'}} - name: build vr-tests-react-components storybook From 6cf51af21ec787b18903b5f1122d7ef70be290dc Mon Sep 17 00:00:00 2001 From: Tristan Watanabe Date: Sun, 16 Oct 2022 12:23:49 -0700 Subject: [PATCH 40/53] test: remove loadworkspaceaddon --- apps/vr-tests-react-components/.storybook/main.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/apps/vr-tests-react-components/.storybook/main.js b/apps/vr-tests-react-components/.storybook/main.js index 7d8c374a4e61f9..c87c619441da70 100644 --- a/apps/vr-tests-react-components/.storybook/main.js +++ b/apps/vr-tests-react-components/.storybook/main.js @@ -1,9 +1,8 @@ const path = require('path'); const { TsconfigPathsPlugin } = require('tsconfig-paths-webpack-plugin'); -const { loadWorkspaceAddon } = require('@fluentui/scripts/storybook'); module.exports = /** @type {import('../../../.storybook/main').StorybookBaseConfig} */ ({ - addons: [loadWorkspaceAddon('@fluentui/react-storybook-addon')], + addons: ['@fluentui/react-storybook-addon'], stories: ['../src/**/*.stories.tsx'], core: { From c0616d0d63fad1ee087c61db779d94eb5aab5c9d Mon Sep 17 00:00:00 2001 From: Tristan Watanabe Date: Sun, 16 Oct 2022 13:53:52 -0700 Subject: [PATCH 41/53] feat: add utils file to host reused stuff in various Button stories --- .../src/stories/Button/Button.stories.tsx | 23 +++-------------- .../stories/Button/CompoundButton.stories.tsx | 23 +++-------------- .../Button/CompoundButtonDefault.stories.tsx | 5 ++-- .../src/stories/Button/MenuButton.stories.tsx | 23 +++-------------- .../stories/Button/ToggleButton.stories.tsx | 23 +++-------------- .../src/stories/Button/utils.tsx | 25 +++++++++++++++++++ 6 files changed, 39 insertions(+), 83 deletions(-) create mode 100644 apps/vr-tests-react-components/src/stories/Button/utils.tsx diff --git a/apps/vr-tests-react-components/src/stories/Button/Button.stories.tsx b/apps/vr-tests-react-components/src/stories/Button/Button.stories.tsx index a146157cda10b2..ca21b59d4ca521 100644 --- a/apps/vr-tests-react-components/src/stories/Button/Button.stories.tsx +++ b/apps/vr-tests-react-components/src/stories/Button/Button.stories.tsx @@ -1,33 +1,16 @@ import * as React from 'react'; -import Screener from 'screener-storybook/src/screener'; import { Button } from '@fluentui/react-button'; import { bundleIcon, CalendarMonthFilled, CalendarMonthRegular } from '@fluentui/react-icons'; -import { makeStyles } from '@griffel/react'; import { ComponentMeta } from '@storybook/react'; -import { getStoryVariant, DARK_MODE, HIGH_CONTRAST, RTL } from '../../utilities/index'; +import { getStoryVariant, DARK_MODE, HIGH_CONTRAST, RTL } from '../../utilities'; +import { buttonId, useStyles, ButtonDecorator } from './utils'; const CalendarMonth = bundleIcon(CalendarMonthFilled, CalendarMonthRegular); -const steps = new Screener.Steps() - .snapshot('default', { cropTo: '.testWrapper' }) - .hover('#button-id') - .snapshot('hover', { cropTo: '.testWrapper' }) - .mouseDown('#button-id') - .snapshot('pressed', { cropTo: '.testWrapper' }) - .end(); - -const buttonId = 'button-id'; - -const useStyles = makeStyles({ - longText: { - width: '280px', - }, -}); - export default { title: 'Button Converged', Component: Button, - decorators: [story => {story()}], + decorators: [ButtonDecorator], } as ComponentMeta; export const Default = () => ; diff --git a/apps/vr-tests-react-components/src/stories/Button/CompoundButton.stories.tsx b/apps/vr-tests-react-components/src/stories/Button/CompoundButton.stories.tsx index fe45ea529b1031..c5ff7b2306f7b7 100644 --- a/apps/vr-tests-react-components/src/stories/Button/CompoundButton.stories.tsx +++ b/apps/vr-tests-react-components/src/stories/Button/CompoundButton.stories.tsx @@ -1,33 +1,16 @@ import * as React from 'react'; -import Screener from 'screener-storybook/src/screener'; import { CompoundButton } from '@fluentui/react-button'; import { bundleIcon, CalendarMonthFilled, CalendarMonthRegular } from '@fluentui/react-icons'; -import { makeStyles } from '@griffel/react'; import { ComponentMeta } from '@storybook/react'; -import { getStoryVariant, RTL } from '../../utilities/index'; +import { getStoryVariant, RTL } from '../../utilities'; +import { buttonId, useStyles, ButtonDecorator } from './utils'; const CalendarMonth = bundleIcon(CalendarMonthFilled, CalendarMonthRegular); -const steps = new Screener.Steps() - .snapshot('default', { cropTo: '.testWrapper' }) - .hover('#button-id') - .snapshot('hover', { cropTo: '.testWrapper' }) - .mouseDown('#button-id') - .snapshot('pressed', { cropTo: '.testWrapper' }) - .end(); - -const buttonId = 'button-id'; - -const useStyles = makeStyles({ - longText: { - width: '280px', - }, -}); - export default { title: 'CompoundButton Converged', component: CompoundButton, - decorators: [story => {story()}], + decorators: [ButtonDecorator], } as ComponentMeta; export const Outline = () => ( diff --git a/apps/vr-tests-react-components/src/stories/Button/CompoundButtonDefault.stories.tsx b/apps/vr-tests-react-components/src/stories/Button/CompoundButtonDefault.stories.tsx index e0d1dad5a54f72..d1ee4973d32c07 100644 --- a/apps/vr-tests-react-components/src/stories/Button/CompoundButtonDefault.stories.tsx +++ b/apps/vr-tests-react-components/src/stories/Button/CompoundButtonDefault.stories.tsx @@ -3,12 +3,11 @@ import Screener from 'screener-storybook/src/screener'; import { CompoundButton } from '@fluentui/react-button'; import { bundleIcon, CalendarMonthFilled, CalendarMonthRegular } from '@fluentui/react-icons'; import { ComponentMeta } from '@storybook/react'; -import { getStoryVariant, RTL } from '../../utilities/index'; +import { getStoryVariant, RTL } from '../../utilities'; +import { buttonId } from './utils'; const CalendarMonth = bundleIcon(CalendarMonthFilled, CalendarMonthRegular); -const buttonId = 'button-id'; - export default { title: 'CompoundButton Converged', component: CompoundButton, diff --git a/apps/vr-tests-react-components/src/stories/Button/MenuButton.stories.tsx b/apps/vr-tests-react-components/src/stories/Button/MenuButton.stories.tsx index a9e92209f91178..a227773fa8210f 100644 --- a/apps/vr-tests-react-components/src/stories/Button/MenuButton.stories.tsx +++ b/apps/vr-tests-react-components/src/stories/Button/MenuButton.stories.tsx @@ -1,33 +1,16 @@ import * as React from 'react'; -import Screener from 'screener-storybook/src/screener'; import { MenuButton } from '@fluentui/react-button'; import { bundleIcon, CalendarMonthFilled, CalendarMonthRegular } from '@fluentui/react-icons'; -import { makeStyles } from '@griffel/react'; import { ComponentMeta } from '@storybook/react'; -import { getStoryVariant, RTL } from '../../utilities/index'; +import { getStoryVariant, RTL } from '../../utilities'; +import { buttonId, useStyles, ButtonDecorator } from './utils'; const CalendarMonth = bundleIcon(CalendarMonthFilled, CalendarMonthRegular); -const steps = new Screener.Steps() - .snapshot('default', { cropTo: '.testWrapper' }) - .hover('#button-id') - .snapshot('hover', { cropTo: '.testWrapper' }) - .mouseDown('#button-id') - .snapshot('pressed', { cropTo: '.testWrapper' }) - .end(); - -const buttonId = 'button-id'; - -const useStyles = makeStyles({ - longText: { - width: '280px', - }, -}); - export default { title: 'MenuButton Converged', component: MenuButton, - decorators: [story => {story()}], + decorators: [ButtonDecorator], } as ComponentMeta; export const Default = () => Hello, world; diff --git a/apps/vr-tests-react-components/src/stories/Button/ToggleButton.stories.tsx b/apps/vr-tests-react-components/src/stories/Button/ToggleButton.stories.tsx index 597c073843f68e..61e3579dc4aa73 100644 --- a/apps/vr-tests-react-components/src/stories/Button/ToggleButton.stories.tsx +++ b/apps/vr-tests-react-components/src/stories/Button/ToggleButton.stories.tsx @@ -1,33 +1,16 @@ import * as React from 'react'; -import Screener from 'screener-storybook/src/screener'; import { ToggleButton } from '@fluentui/react-button'; import { bundleIcon, CalendarMonthFilled, CalendarMonthRegular } from '@fluentui/react-icons'; -import { makeStyles } from '@griffel/react'; import { ComponentMeta } from '@storybook/react'; -import { DARK_MODE, getStoryVariant, HIGH_CONTRAST, RTL } from '../../utilities/index'; +import { getStoryVariant, DARK_MODE, HIGH_CONTRAST, RTL } from '../../utilities'; +import { buttonId, useStyles, ButtonDecorator } from './utils'; const CalendarMonth = bundleIcon(CalendarMonthFilled, CalendarMonthRegular); -const steps = new Screener.Steps() - .snapshot('default', { cropTo: '.testWrapper' }) - .hover('#button-id') - .snapshot('hover', { cropTo: '.testWrapper' }) - .mouseDown('#button-id') - .snapshot('pressed', { cropTo: '.testWrapper' }) - .end(); - -const buttonId = 'button-id'; - -const useStyles = makeStyles({ - longText: { - width: '280px', - }, -}); - export default { title: 'ToggleButton Converged', component: ToggleButton, - decorators: [story => {story()}], + decorators: [ButtonDecorator], } as ComponentMeta; export const Default = () => Hello, world; diff --git a/apps/vr-tests-react-components/src/stories/Button/utils.tsx b/apps/vr-tests-react-components/src/stories/Button/utils.tsx new file mode 100644 index 00000000000000..97534881617088 --- /dev/null +++ b/apps/vr-tests-react-components/src/stories/Button/utils.tsx @@ -0,0 +1,25 @@ +import * as React from 'react'; +import Screener from 'screener-storybook/src/screener'; +import { DecoratorFunction } from '@storybook/addons'; +import { ExtendedStoryFnReturnType } from '../../utilities/types'; +import { makeStyles } from '@griffel/react'; + +export const buttonId = 'button-id'; + +export const useStyles = makeStyles({ + longText: { + width: '280px', + }, +}); + +const steps = new Screener.Steps() + .snapshot('default', { cropTo: '.testWrapper' }) + .hover('#button-id') + .snapshot('hover', { cropTo: '.testWrapper' }) + .mouseDown('#button-id') + .snapshot('pressed', { cropTo: '.testWrapper' }) + .end(); + +export const ButtonDecorator: DecoratorFunction = story => { + return {story()} ; +}; From cd7b01dd99dc45e2e14ba54dd36067133dec4169 Mon Sep 17 00:00:00 2001 From: Tristan Watanabe Date: Sun, 16 Oct 2022 14:33:09 -0700 Subject: [PATCH 42/53] refactor: add generalized withScreenerSteps decorator --- .../src/stories/Button/Button.stories.tsx | 6 ++-- .../stories/Button/CompoundButton.stories.tsx | 6 ++-- .../Button/CompoundButtonDefault.stories.tsx | 28 ++++++++----------- .../src/stories/Button/MenuButton.stories.tsx | 6 ++-- .../stories/Button/ToggleButton.stories.tsx | 6 ++-- .../stories/Button/{utils.tsx => utils.ts} | 9 +----- .../src/utilities/index.ts | 1 + .../src/utilities/withScreenerSteps.tsx | 15 ++++++++++ 8 files changed, 40 insertions(+), 37 deletions(-) rename apps/vr-tests-react-components/src/stories/Button/{utils.tsx => utils.ts} (56%) create mode 100644 apps/vr-tests-react-components/src/utilities/withScreenerSteps.tsx diff --git a/apps/vr-tests-react-components/src/stories/Button/Button.stories.tsx b/apps/vr-tests-react-components/src/stories/Button/Button.stories.tsx index ca21b59d4ca521..09f8c3b1f63281 100644 --- a/apps/vr-tests-react-components/src/stories/Button/Button.stories.tsx +++ b/apps/vr-tests-react-components/src/stories/Button/Button.stories.tsx @@ -2,15 +2,15 @@ import * as React from 'react'; import { Button } from '@fluentui/react-button'; import { bundleIcon, CalendarMonthFilled, CalendarMonthRegular } from '@fluentui/react-icons'; import { ComponentMeta } from '@storybook/react'; -import { getStoryVariant, DARK_MODE, HIGH_CONTRAST, RTL } from '../../utilities'; -import { buttonId, useStyles, ButtonDecorator } from './utils'; +import { getStoryVariant, withScreenerSteps, DARK_MODE, HIGH_CONTRAST, RTL } from '../../utilities'; +import { buttonId, steps, useStyles } from './utils'; const CalendarMonth = bundleIcon(CalendarMonthFilled, CalendarMonthRegular); export default { title: 'Button Converged', Component: Button, - decorators: [ButtonDecorator], + decorators: [story => withScreenerSteps({ story, steps })], } as ComponentMeta; export const Default = () => ; diff --git a/apps/vr-tests-react-components/src/stories/Button/CompoundButton.stories.tsx b/apps/vr-tests-react-components/src/stories/Button/CompoundButton.stories.tsx index c5ff7b2306f7b7..4c067d60f87042 100644 --- a/apps/vr-tests-react-components/src/stories/Button/CompoundButton.stories.tsx +++ b/apps/vr-tests-react-components/src/stories/Button/CompoundButton.stories.tsx @@ -2,15 +2,15 @@ import * as React from 'react'; import { CompoundButton } from '@fluentui/react-button'; import { bundleIcon, CalendarMonthFilled, CalendarMonthRegular } from '@fluentui/react-icons'; import { ComponentMeta } from '@storybook/react'; -import { getStoryVariant, RTL } from '../../utilities'; -import { buttonId, useStyles, ButtonDecorator } from './utils'; +import { getStoryVariant, withScreenerSteps, RTL } from '../../utilities'; +import { buttonId, steps, useStyles } from './utils'; const CalendarMonth = bundleIcon(CalendarMonthFilled, CalendarMonthRegular); export default { title: 'CompoundButton Converged', component: CompoundButton, - decorators: [ButtonDecorator], + decorators: [story => withScreenerSteps({ story, steps })], } as ComponentMeta; export const Outline = () => ( diff --git a/apps/vr-tests-react-components/src/stories/Button/CompoundButtonDefault.stories.tsx b/apps/vr-tests-react-components/src/stories/Button/CompoundButtonDefault.stories.tsx index d1ee4973d32c07..3d73daf5f7d912 100644 --- a/apps/vr-tests-react-components/src/stories/Button/CompoundButtonDefault.stories.tsx +++ b/apps/vr-tests-react-components/src/stories/Button/CompoundButtonDefault.stories.tsx @@ -3,30 +3,24 @@ import Screener from 'screener-storybook/src/screener'; import { CompoundButton } from '@fluentui/react-button'; import { bundleIcon, CalendarMonthFilled, CalendarMonthRegular } from '@fluentui/react-icons'; import { ComponentMeta } from '@storybook/react'; -import { getStoryVariant, RTL } from '../../utilities'; +import { getStoryVariant, withScreenerSteps, RTL } from '../../utilities'; import { buttonId } from './utils'; const CalendarMonth = bundleIcon(CalendarMonthFilled, CalendarMonthRegular); +const steps = new Screener.Steps() + .snapshot('default', { cropTo: '.testWrapper' }) + // https://github.com/microsoft/fluentui/issues/21998 + // .hover('#button-id') + // .snapshot('hover', { cropTo: '.testWrapper' }) + .mouseDown('#button-id') + .snapshot('pressed', { cropTo: '.testWrapper' }) + .end(); + export default { title: 'CompoundButton Converged', component: CompoundButton, - decorators: [ - story => ( - - {story()} - - ), - ], + decorators: [story => withScreenerSteps({ story, steps })], } as ComponentMeta; export const Default = () => ( diff --git a/apps/vr-tests-react-components/src/stories/Button/MenuButton.stories.tsx b/apps/vr-tests-react-components/src/stories/Button/MenuButton.stories.tsx index a227773fa8210f..492115ce9318c0 100644 --- a/apps/vr-tests-react-components/src/stories/Button/MenuButton.stories.tsx +++ b/apps/vr-tests-react-components/src/stories/Button/MenuButton.stories.tsx @@ -2,15 +2,15 @@ import * as React from 'react'; import { MenuButton } from '@fluentui/react-button'; import { bundleIcon, CalendarMonthFilled, CalendarMonthRegular } from '@fluentui/react-icons'; import { ComponentMeta } from '@storybook/react'; -import { getStoryVariant, RTL } from '../../utilities'; -import { buttonId, useStyles, ButtonDecorator } from './utils'; +import { getStoryVariant, withScreenerSteps, RTL } from '../../utilities'; +import { buttonId, steps, useStyles } from './utils'; const CalendarMonth = bundleIcon(CalendarMonthFilled, CalendarMonthRegular); export default { title: 'MenuButton Converged', component: MenuButton, - decorators: [ButtonDecorator], + decorators: [story => withScreenerSteps({ story, steps })], } as ComponentMeta; export const Default = () => Hello, world; diff --git a/apps/vr-tests-react-components/src/stories/Button/ToggleButton.stories.tsx b/apps/vr-tests-react-components/src/stories/Button/ToggleButton.stories.tsx index 61e3579dc4aa73..4e8e4bff57ea60 100644 --- a/apps/vr-tests-react-components/src/stories/Button/ToggleButton.stories.tsx +++ b/apps/vr-tests-react-components/src/stories/Button/ToggleButton.stories.tsx @@ -2,15 +2,15 @@ import * as React from 'react'; import { ToggleButton } from '@fluentui/react-button'; import { bundleIcon, CalendarMonthFilled, CalendarMonthRegular } from '@fluentui/react-icons'; import { ComponentMeta } from '@storybook/react'; -import { getStoryVariant, DARK_MODE, HIGH_CONTRAST, RTL } from '../../utilities'; -import { buttonId, useStyles, ButtonDecorator } from './utils'; +import { getStoryVariant, withScreenerSteps, DARK_MODE, HIGH_CONTRAST, RTL } from '../../utilities'; +import { buttonId, steps, useStyles } from './utils'; const CalendarMonth = bundleIcon(CalendarMonthFilled, CalendarMonthRegular); export default { title: 'ToggleButton Converged', component: ToggleButton, - decorators: [ButtonDecorator], + decorators: [story => withScreenerSteps({ story, steps })], } as ComponentMeta; export const Default = () => Hello, world; diff --git a/apps/vr-tests-react-components/src/stories/Button/utils.tsx b/apps/vr-tests-react-components/src/stories/Button/utils.ts similarity index 56% rename from apps/vr-tests-react-components/src/stories/Button/utils.tsx rename to apps/vr-tests-react-components/src/stories/Button/utils.ts index 97534881617088..41cf2954cabb2b 100644 --- a/apps/vr-tests-react-components/src/stories/Button/utils.tsx +++ b/apps/vr-tests-react-components/src/stories/Button/utils.ts @@ -1,7 +1,4 @@ -import * as React from 'react'; import Screener from 'screener-storybook/src/screener'; -import { DecoratorFunction } from '@storybook/addons'; -import { ExtendedStoryFnReturnType } from '../../utilities/types'; import { makeStyles } from '@griffel/react'; export const buttonId = 'button-id'; @@ -12,14 +9,10 @@ export const useStyles = makeStyles({ }, }); -const steps = new Screener.Steps() +export const steps = new Screener.Steps() .snapshot('default', { cropTo: '.testWrapper' }) .hover('#button-id') .snapshot('hover', { cropTo: '.testWrapper' }) .mouseDown('#button-id') .snapshot('pressed', { cropTo: '.testWrapper' }) .end(); - -export const ButtonDecorator: DecoratorFunction = story => { - return {story()} ; -}; diff --git a/apps/vr-tests-react-components/src/utilities/index.ts b/apps/vr-tests-react-components/src/utilities/index.ts index e2de063e017a08..9b57e0061e559c 100644 --- a/apps/vr-tests-react-components/src/utilities/index.ts +++ b/apps/vr-tests-react-components/src/utilities/index.ts @@ -9,3 +9,4 @@ declare module '@storybook/addons' { export * from './TestWrapperDecorator'; export * from './getStoryVariant'; +export * from './withScreenerSteps'; diff --git a/apps/vr-tests-react-components/src/utilities/withScreenerSteps.tsx b/apps/vr-tests-react-components/src/utilities/withScreenerSteps.tsx new file mode 100644 index 00000000000000..f38886fbe95628 --- /dev/null +++ b/apps/vr-tests-react-components/src/utilities/withScreenerSteps.tsx @@ -0,0 +1,15 @@ +import * as React from 'react'; +import Screener, { Step } from 'screener-storybook/src/screener'; +import { StoryContext } from './types'; + +export const withScreenerSteps = ({ + story, + context, + steps, +}: { + story: () => React.ReactNode; + steps: Step[]; + context?: StoryContext; +}) => { + return {story()} ; +}; From 4488610ed7bcd43f6a4b64bdc3d5baae3428a6e7 Mon Sep 17 00:00:00 2001 From: Tristan Watanabe Date: Sun, 16 Oct 2022 15:04:15 -0700 Subject: [PATCH 43/53] uncomment out flaky test --- .../src/stories/Button/Button.stories.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/vr-tests-react-components/src/stories/Button/Button.stories.tsx b/apps/vr-tests-react-components/src/stories/Button/Button.stories.tsx index 09f8c3b1f63281..c50d505dd8ae3c 100644 --- a/apps/vr-tests-react-components/src/stories/Button/Button.stories.tsx +++ b/apps/vr-tests-react-components/src/stories/Button/Button.stories.tsx @@ -170,7 +170,7 @@ export const WithIconAfterContent = () => ( WithIconAfterContent.storyName = 'With icon after content'; -// export const WithIconAfterContentRTL = getStoryVariant(WithIconAfterContent, RTL); +export const WithIconAfterContentRTL = getStoryVariant(WithIconAfterContent, RTL); export const IconOnly = () => +); + +AsAnAnchor.storyName = 'As an anchor'; + export const Circular = () => ( ; + + it('should set the correct direction for story', () => { + const ltrStory = getStoryVariant(DefaultStory, DARK_MODE); + const rtlStory = getStoryVariant(DefaultStory, RTL); + + expect(ltrStory.parameters.dir).toBe('ltr'); + expect(rtlStory.parameters.dir).toBe('rtl'); + }); + + it('should set the correct theme for story', () => { + const darkModeStory = getStoryVariant(DefaultStory, DARK_MODE); + const highContrastStory = getStoryVariant(DefaultStory, HIGH_CONTRAST); + + expect(darkModeStory.parameters.fluentTheme).toBe('web-dark'); + expect(highContrastStory.parameters.fluentTheme).toBe('teams-high-contrast'); + }); + }); +}); From 5d7527f27feae6a33c4a8b0707e2255158359f12 Mon Sep 17 00:00:00 2001 From: Tristan Watanabe Date: Tue, 1 Nov 2022 16:23:28 -0700 Subject: [PATCH 50/53] fix: make fluent storybook-addon a caret dep again to fix syncpack error --- apps/vr-tests-react-components/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/vr-tests-react-components/package.json b/apps/vr-tests-react-components/package.json index 99d34d2d37d4f2..d1b71c1c23e6ec 100644 --- a/apps/vr-tests-react-components/package.json +++ b/apps/vr-tests-react-components/package.json @@ -48,7 +48,7 @@ "@fluentui/react-slider": "^9.0.8", "@fluentui/react-spinner": "^9.0.8", "@fluentui/react-spinbutton": "^9.0.6", - "@fluentui/react-storybook-addon": "9.0.0-rc.1", + "@fluentui/react-storybook-addon": "^9.0.0-rc.1", "@fluentui/react-switch": "^9.0.9", "@fluentui/react-tabs": "^9.0.9", "@fluentui/react-table": "9.0.0-alpha.8", From e2ba1f00c1e6ac21c9b7b21cfba198763baf2a98 Mon Sep 17 00:00:00 2001 From: Tristan Watanabe Date: Tue, 1 Nov 2022 17:42:03 -0700 Subject: [PATCH 51/53] fix(react-storybook-addon): update API --- .../react-storybook-addon/etc/react-storybook-addon.api.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/packages/react-components/react-storybook-addon/etc/react-storybook-addon.api.md b/packages/react-components/react-storybook-addon/etc/react-storybook-addon.api.md index 02800552969e24..684361e99da9f4 100644 --- a/packages/react-components/react-storybook-addon/etc/react-storybook-addon.api.md +++ b/packages/react-components/react-storybook-addon/etc/react-storybook-addon.api.md @@ -5,7 +5,8 @@ ```ts import { Args } from '@storybook/api'; -import { Parameters as Parameters_2 } from '@storybook/api'; +import { OptionsParameter } from '@storybook/addons'; +import { Parameters as Parameters_2 } from '@storybook/addons'; import { StoryContext } from '@storybook/addons'; import type { Theme } from '@fluentui/react-theme'; @@ -38,6 +39,10 @@ export function parameters(options?: FluentParameters): { dir: string; fluentTheme: string; mode: string; + fileName?: string | undefined; + options?: OptionsParameter | undefined; + layout?: "centered" | "fullscreen" | "padded" | "none" | undefined; + docsOnly?: boolean | undefined; }; // @public (undocumented) From 3d6983dec781386e1378bfde6a73206cad70c6c2 Mon Sep 17 00:00:00 2001 From: Tristan Watanabe Date: Tue, 1 Nov 2022 19:44:32 -0700 Subject: [PATCH 52/53] nit: generalize extra screener-build step for v9 --- .github/workflows/screener-build.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/screener-build.yml b/.github/workflows/screener-build.yml index a968727e1a1f3f..ad95963a40f805 100644 --- a/.github/workflows/screener-build.yml +++ b/.github/workflows/screener-build.yml @@ -272,8 +272,8 @@ jobs: printenv | sort ;\ echo "SHELLOPTS $SHELLOPTS" ;\ - - name: build @fluentui/react-storybook-addon - run: yarn build --to @fluentui/react-storybook-addon + - name: build vr-tests-react-components storybook + run: yarn lage build --to @fluentui/vr-tests-react-components if: ${{env.SKIP_SCREENER_BUILD == 'false'}} - name: build vr-tests-react-components storybook From 781e403f9b5618858c9ce9104437d949e202b994 Mon Sep 17 00:00:00 2001 From: Tristan Watanabe Date: Tue, 1 Nov 2022 20:33:25 -0700 Subject: [PATCH 53/53] test: add test for story naming --- .../src/utilities/utilities.test.tsx | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/apps/vr-tests-react-components/src/utilities/utilities.test.tsx b/apps/vr-tests-react-components/src/utilities/utilities.test.tsx index 9ab112eabf0d5d..c8acd36d1b6981 100644 --- a/apps/vr-tests-react-components/src/utilities/utilities.test.tsx +++ b/apps/vr-tests-react-components/src/utilities/utilities.test.tsx @@ -2,6 +2,7 @@ import * as React from 'react'; import { getStoryVariant, DARK_MODE, HIGH_CONTRAST, RTL } from './getStoryVariant'; import { Button } from '@fluentui/react-button'; +import { ComponentStory } from '@storybook/react'; describe('utility functions', () => { describe('getStoryVariant', () => { @@ -22,5 +23,26 @@ describe('utility functions', () => { expect(darkModeStory.parameters.fluentTheme).toBe('web-dark'); expect(highContrastStory.parameters.fluentTheme).toBe('teams-high-contrast'); }); + + it('should set the correct name for story', () => { + const darkModeStory = getStoryVariant(DefaultStory, DARK_MODE); + const highContrastStory = getStoryVariant(DefaultStory, HIGH_CONTRAST); + const rtlStory = getStoryVariant(DefaultStory, RTL); + + expect(darkModeStory.storyName).toEqual('Default Story - Dark Mode'); + expect(highContrastStory.storyName).toEqual('Default Story - High Contrast'); + expect(rtlStory.storyName).toEqual('Default Story - RTL'); + + const buttonStory: ComponentStory = DefaultStory; + buttonStory.storyName = 'button'; + + const buttonDarkModeStory = getStoryVariant(buttonStory, DARK_MODE); + const buttonHighContrastStory = getStoryVariant(buttonStory, HIGH_CONTRAST); + const buttonRtlStory = getStoryVariant(buttonStory, RTL); + + expect(buttonDarkModeStory.storyName).toEqual('button - Dark Mode'); + expect(buttonHighContrastStory.storyName).toEqual('button - High Contrast'); + expect(buttonRtlStory.storyName).toEqual('button - RTL'); + }); }); });