From ec117c0e18c995b02cb97965e38184b9a9a86f1d Mon Sep 17 00:00:00 2001 From: Lingfan Gao Date: Thu, 21 Oct 2021 20:27:36 +0200 Subject: [PATCH 01/35] experiment(storybook): Version picker Chromatic stores published storybooks with commits, we can simply build an azure function to keep the version -> commit mapping and integrate a picker into the docs page --- .../.storybook/{preview.js => preview.jsx} | 11 +++++- .../src/Migrations/utils.stories.tsx | 35 ++++++++++++++++++- 2 files changed, 44 insertions(+), 2 deletions(-) rename packages/react-components/.storybook/{preview.js => preview.jsx} (72%) diff --git a/packages/react-components/.storybook/preview.js b/packages/react-components/.storybook/preview.jsx similarity index 72% rename from packages/react-components/.storybook/preview.js rename to packages/react-components/.storybook/preview.jsx index f488f6cbdf571..acd7547cddef1 100644 --- a/packages/react-components/.storybook/preview.js +++ b/packages/react-components/.storybook/preview.jsx @@ -1,3 +1,5 @@ +import * as React from 'react'; +import { FluentDocsContainer } from '../src/Migrations/utils.stories'; import * as rootPreview from '../../../.storybook/preview'; // load global styles @@ -24,4 +26,11 @@ const options = { export const decorators = [...rootPreview.decorators]; /** @type {typeof rootPreview.parameters} */ -export const parameters = { ...rootPreview.parameters, options }; +export const parameters = { + ...rootPreview.parameters, + docs: { + // TODO extract this to a separate component + container: FluentDocsContainer, + }, + options, +}; diff --git a/packages/react-components/src/Migrations/utils.stories.tsx b/packages/react-components/src/Migrations/utils.stories.tsx index b3926d0fd37e2..022d5bcba4219 100644 --- a/packages/react-components/src/Migrations/utils.stories.tsx +++ b/packages/react-components/src/Migrations/utils.stories.tsx @@ -1,6 +1,6 @@ import * as React from 'react'; // eslint-disable-next-line import/no-extraneous-dependencies -import { Source } from '@storybook/addon-docs'; +import { DocsContainer, Source } from '@storybook/addon-docs'; import { makeStyles } from '@fluentui/react-make-styles'; const useCodeComparisonStyles = makeStyles({ @@ -58,3 +58,36 @@ export const CodeExample = (props: { title?: string; children: React.ReactElemen ); }; + +export const VersionPicker = () => { + // TODO fetch this mapping from an azure function + const versions: Record = { + '9.0.0-alpha.123': 'https://f6366b4--6002298f95a00c00213f4d55.chromatic.com', + '9.0.0-beta.1': 'https://3c3fae8--6002298f95a00c00213f4d55.chromatic.com', + }; + + const onChange = (e: React.ChangeEvent) => { + window.parent.location.href = e.target.value; + }; + + return ( + + ); +}; + +// eslint-disable-next-line @typescript-eslint/ban-ts-comment +// @ts-ignore +export const FluentDocsContainer = ({ children, context }) => { + return ( + <> + + {children} + + ); +}; From 85e17c3b6b89750ea6c60f44eb2eaee98376c573 Mon Sep 17 00:00:00 2001 From: Lingfan Gao Date: Thu, 21 Oct 2021 20:29:00 +0200 Subject: [PATCH 02/35] Change files --- ...ct-components-639d9023-4a53-403d-a3eb-fa50ca331ac6.json | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 change/@fluentui-react-components-639d9023-4a53-403d-a3eb-fa50ca331ac6.json diff --git a/change/@fluentui-react-components-639d9023-4a53-403d-a3eb-fa50ca331ac6.json b/change/@fluentui-react-components-639d9023-4a53-403d-a3eb-fa50ca331ac6.json new file mode 100644 index 0000000000000..e4e5e3540ba7c --- /dev/null +++ b/change/@fluentui-react-components-639d9023-4a53-403d-a3eb-fa50ca331ac6.json @@ -0,0 +1,7 @@ +{ + "type": "none", + "comment": "experiment(storybook): Version picker", + "packageName": "@fluentui/react-components", + "email": "lingfangao@hotmail.com", + "dependentChangeType": "none" +} From a8db3293ee2ad881f131dcf092c0db1d0112b0c7 Mon Sep 17 00:00:00 2001 From: Lingfan Gao Date: Thu, 21 Oct 2021 20:41:42 +0200 Subject: [PATCH 03/35] use fluent menu --- .../src/Migrations/utils.stories.tsx | 38 ++++++++++++++----- 1 file changed, 29 insertions(+), 9 deletions(-) diff --git a/packages/react-components/src/Migrations/utils.stories.tsx b/packages/react-components/src/Migrations/utils.stories.tsx index 022d5bcba4219..e61291caa80e3 100644 --- a/packages/react-components/src/Migrations/utils.stories.tsx +++ b/packages/react-components/src/Migrations/utils.stories.tsx @@ -2,6 +2,16 @@ import * as React from 'react'; // eslint-disable-next-line import/no-extraneous-dependencies import { DocsContainer, Source } from '@storybook/addon-docs'; import { makeStyles } from '@fluentui/react-make-styles'; +import { + Menu, + MenuItem, + MenuList, + MenuPopover, + MenuTrigger, + MenuButton, + FluentProvider, + webLightTheme, +} from '../index'; const useCodeComparisonStyles = makeStyles({ root: { @@ -61,23 +71,33 @@ export const CodeExample = (props: { title?: string; children: React.ReactElemen export const VersionPicker = () => { // TODO fetch this mapping from an azure function + // This URL can just be constructed during publish time and fed to the azure function const versions: Record = { '9.0.0-alpha.123': 'https://f6366b4--6002298f95a00c00213f4d55.chromatic.com', '9.0.0-beta.1': 'https://3c3fae8--6002298f95a00c00213f4d55.chromatic.com', }; - const onChange = (e: React.ChangeEvent) => { - window.parent.location.href = e.target.value; + const navigateHandler = (href: string) => () => { + window.parent.location.href = href; }; return ( - + + + + {Object.keys(versions)[0]} + + + + {Object.keys(versions).map(version => ( + + {version} + + ))} + + + + ); }; From 8dcc43863216b51d0d834c74197f459b8bf1ff5b Mon Sep 17 00:00:00 2001 From: Lingfan Gao Date: Thu, 21 Oct 2021 21:10:34 +0200 Subject: [PATCH 04/35] cleanup --- .../react-components/.storybook/{preview.jsx => preview.js} | 2 -- packages/react-components/src/Migrations/utils.stories.tsx | 6 ++---- 2 files changed, 2 insertions(+), 6 deletions(-) rename packages/react-components/.storybook/{preview.jsx => preview.js} (91%) diff --git a/packages/react-components/.storybook/preview.jsx b/packages/react-components/.storybook/preview.js similarity index 91% rename from packages/react-components/.storybook/preview.jsx rename to packages/react-components/.storybook/preview.js index acd7547cddef1..16bf5766a4f09 100644 --- a/packages/react-components/.storybook/preview.jsx +++ b/packages/react-components/.storybook/preview.js @@ -1,4 +1,3 @@ -import * as React from 'react'; import { FluentDocsContainer } from '../src/Migrations/utils.stories'; import * as rootPreview from '../../../.storybook/preview'; @@ -29,7 +28,6 @@ export const decorators = [...rootPreview.decorators]; export const parameters = { ...rootPreview.parameters, docs: { - // TODO extract this to a separate component container: FluentDocsContainer, }, options, diff --git a/packages/react-components/src/Migrations/utils.stories.tsx b/packages/react-components/src/Migrations/utils.stories.tsx index e61291caa80e3..8b63feb16a243 100644 --- a/packages/react-components/src/Migrations/utils.stories.tsx +++ b/packages/react-components/src/Migrations/utils.stories.tsx @@ -1,6 +1,6 @@ import * as React from 'react'; // eslint-disable-next-line import/no-extraneous-dependencies -import { DocsContainer, Source } from '@storybook/addon-docs'; +import { DocsContainer, DocsContainerProps, Meta, Source } from '@storybook/addon-docs'; import { makeStyles } from '@fluentui/react-make-styles'; import { Menu, @@ -101,9 +101,7 @@ export const VersionPicker = () => { ); }; -// eslint-disable-next-line @typescript-eslint/ban-ts-comment -// @ts-ignore -export const FluentDocsContainer = ({ children, context }) => { +export const FluentDocsContainer = ({ children, context }: DocsContainerProps & { children: React.ReactNode }) => { return ( <> From 153d565d60deaa44c3e9f428106a22a5e87568ab Mon Sep 17 00:00:00 2001 From: Lingfan Gao Date: Mon, 25 Oct 2021 10:39:47 +0200 Subject: [PATCH 05/35] add network fetch --- .../src/Migrations/utils.stories.tsx | 34 ++++++++++++------- 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/packages/react-components/src/Migrations/utils.stories.tsx b/packages/react-components/src/Migrations/utils.stories.tsx index 8b63feb16a243..cd3aa43acbc96 100644 --- a/packages/react-components/src/Migrations/utils.stories.tsx +++ b/packages/react-components/src/Migrations/utils.stories.tsx @@ -1,6 +1,6 @@ import * as React from 'react'; // eslint-disable-next-line import/no-extraneous-dependencies -import { DocsContainer, DocsContainerProps, Meta, Source } from '@storybook/addon-docs'; +import { DocsContainer, DocsContainerProps, Source } from '@storybook/addon-docs'; import { makeStyles } from '@fluentui/react-make-styles'; import { Menu, @@ -69,15 +69,24 @@ export const CodeExample = (props: { title?: string; children: React.ReactElemen ); }; +interface VersionEntry { + version: string; + commit: string; +} + export const VersionPicker = () => { - // TODO fetch this mapping from an azure function - // This URL can just be constructed during publish time and fed to the azure function - const versions: Record = { - '9.0.0-alpha.123': 'https://f6366b4--6002298f95a00c00213f4d55.chromatic.com', - '9.0.0-beta.1': 'https://3c3fae8--6002298f95a00c00213f4d55.chromatic.com', - }; + const [versions, setVersions] = React.useState([]); + + React.useEffect(() => { + fetch('https://fluentstorybookversion.azurewebsites.net/api/GetVersions') + .then(res => res.json()) + .then(json => { + setVersions(json); + }); + }, []); - const navigateHandler = (href: string) => () => { + const navigateHandler = (commit: string) => () => { + const href = `https://${commit}--6002298f95a00c00213f4d55.chromatic.com`; window.parent.location.href = href; }; @@ -85,13 +94,13 @@ export const VersionPicker = () => { - {Object.keys(versions)[0]} + Select version - {Object.keys(versions).map(version => ( - - {version} + {versions.map(entry => ( + + {entry.version} ))} @@ -102,6 +111,7 @@ export const VersionPicker = () => { }; export const FluentDocsContainer = ({ children, context }: DocsContainerProps & { children: React.ReactNode }) => { + console.log(process.env.STORYBOOK_THEME); return ( <> From c00b67682b3e29d298f4e6d0f21b2fab063f6460 Mon Sep 17 00:00:00 2001 From: Lingfan Gao Date: Mon, 25 Oct 2021 15:21:26 +0200 Subject: [PATCH 06/35] use addon --- .storybook/main.js | 1 + .storybook/preview.js | 4 +- packages/react-components/.env | 2 + .../react-components/.storybook/manager.js | 12 +++ .../react-components/.storybook/preview.js | 4 - .../react-storybook-addon/src/ThemePicker.tsx | 76 +++++++++++++++++++ .../src/VersionPicker.tsx | 58 ++++++++++++++ .../react-storybook-addon/src/constants.ts | 6 +- packages/react-storybook-addon/src/hooks.ts | 16 ++++ packages/react-storybook-addon/src/preset.ts | 0 .../src/preset/manager.ts | 21 ++++- .../src/preset/preview.ts | 4 +- packages/react-storybook-addon/src/theme.ts | 27 +++++++ .../src/withFluentProvider.tsx | 19 +++++ packages/react-storybook/README.md | 4 +- .../react-storybook/src/decorators/index.ts | 1 - .../src/decorators/withFluentProvider.tsx | 20 ----- packages/react-storybook/src/index.test.ts | 4 +- 18 files changed, 245 insertions(+), 34 deletions(-) create mode 100644 packages/react-components/.env create mode 100644 packages/react-storybook-addon/src/ThemePicker.tsx create mode 100644 packages/react-storybook-addon/src/VersionPicker.tsx create mode 100644 packages/react-storybook-addon/src/hooks.ts create mode 100644 packages/react-storybook-addon/src/preset.ts create mode 100644 packages/react-storybook-addon/src/theme.ts create mode 100644 packages/react-storybook-addon/src/withFluentProvider.tsx delete mode 100644 packages/react-storybook/src/decorators/withFluentProvider.tsx diff --git a/.storybook/main.js b/.storybook/main.js index 1d033ca588735..23c22c5d37efe 100644 --- a/.storybook/main.js +++ b/.storybook/main.js @@ -44,6 +44,7 @@ module.exports = /** @type {Omit} */ ({ '@storybook/addon-knobs/preset', 'storybook-addon-performance', 'storybook-addon-export-to-codesandbox', + '@fluentui/react-storybook-addon', ], webpackFinal: config => { const tsPaths = new TsconfigPathsPlugin({ diff --git a/.storybook/preview.js b/.storybook/preview.js index 9dbedb5216d05..cefe0bed0de8c 100644 --- a/.storybook/preview.js +++ b/.storybook/preview.js @@ -1,9 +1,9 @@ -import { withFluentProvider, withStrictMode } from '@fluentui/react-storybook'; +import { withStrictMode } from '@fluentui/react-storybook'; import 'cypress-storybook/react'; import * as dedent from 'dedent'; /** @type {NonNullable} */ -export const decorators = [withFluentProvider, withStrictMode]; +export const decorators = [withStrictMode]; /** @type {import('@storybook/react').Parameters} */ export const parameters = { diff --git a/packages/react-components/.env b/packages/react-components/.env new file mode 100644 index 0000000000000..5911548270edf --- /dev/null +++ b/packages/react-components/.env @@ -0,0 +1,2 @@ +STORYBOOK_CHROMATIC_APPID=6002298f95a00c00213f4d55.chromatic.com +STORYBOOK_VERSION_API_BASEURL=https://fluentstorybookversion.azurewebsites.net diff --git a/packages/react-components/.storybook/manager.js b/packages/react-components/.storybook/manager.js index 4a91dc7bc27dd..f91ea5d9239a6 100644 --- a/packages/react-components/.storybook/manager.js +++ b/packages/react-components/.storybook/manager.js @@ -5,4 +5,16 @@ addons.setConfig({ showPanel: true, panelPosition: 'right', theme, + toolbar: { + zoom: { hidden: true }, + outline: { hidden: true }, + eject: { hidden: true }, + copy: { hidden: true }, + fullscreen: { hidden: true }, + 'storybook/background': { hidden: true }, + 'storybook/viewport': { hidden: true }, + 'storybook/measure-addon/tool': { hidden: true }, + 'storybook/outline': { hidden: true }, + 'storybook/a11y/panel': { hidden: true }, + }, }); diff --git a/packages/react-components/.storybook/preview.js b/packages/react-components/.storybook/preview.js index 16bf5766a4f09..f2b2e2f988aeb 100644 --- a/packages/react-components/.storybook/preview.js +++ b/packages/react-components/.storybook/preview.js @@ -1,4 +1,3 @@ -import { FluentDocsContainer } from '../src/Migrations/utils.stories'; import * as rootPreview from '../../../.storybook/preview'; // load global styles @@ -27,8 +26,5 @@ export const decorators = [...rootPreview.decorators]; /** @type {typeof rootPreview.parameters} */ export const parameters = { ...rootPreview.parameters, - docs: { - container: FluentDocsContainer, - }, options, }; diff --git a/packages/react-storybook-addon/src/ThemePicker.tsx b/packages/react-storybook-addon/src/ThemePicker.tsx new file mode 100644 index 0000000000000..9ea4f4d78acf0 --- /dev/null +++ b/packages/react-storybook-addon/src/ThemePicker.tsx @@ -0,0 +1,76 @@ +import * as React from 'react'; +import { IconButton, Icons, TooltipLinkList, WithTooltip } from '@storybook/components'; + +import { ThemeIds, themes, defaultTheme } from './theme'; +import { THEME_ID } from './constants'; +import { useGlobals } from './hooks'; + +export interface ThemeSelectorItem { + id: string; + title: string; + onClick: () => void; + value: string; + active: boolean; +} + +function createThemeItems( + value: typeof themes, + changeTheme: (id: ThemeIds) => void, + getCurrentTheme: () => ThemeIds, +): ThemeSelectorItem[] { + return value.map(item => { + return { + id: item.id, + title: item.id === defaultTheme.id ? `${item.label} (Default)` : item.label, + onClick: () => { + changeTheme(item.id); + }, + value: item.id, + active: getCurrentTheme() === item.id, + }; + }); +} + +export const ThemePicker = () => { + const [globals, updateGlobals] = useGlobals(); + const selectedThemeId = globals[THEME_ID] ?? defaultTheme.id; + const selectedTheme = themes.find(entry => entry.id === selectedThemeId); + + const isActive = selectedThemeId !== defaultTheme.id; + + const setTheme = React.useCallback( + (id: ThemeIds) => { + updateGlobals({ [THEME_ID]: id }); + }, + [updateGlobals], + ); + + const renderTooltip = React.useCallback( + (props: { onHide: () => void }) => { + return ( + { + setTheme(id); + props.onHide(); + }, + () => selectedThemeId, + )} + /> + ); + }, + [selectedThemeId, setTheme], + ); + + return ( + <> + + + + Theme: {selectedTheme?.label} + + + + ); +}; diff --git a/packages/react-storybook-addon/src/VersionPicker.tsx b/packages/react-storybook-addon/src/VersionPicker.tsx new file mode 100644 index 0000000000000..f36ad474bd5ea --- /dev/null +++ b/packages/react-storybook-addon/src/VersionPicker.tsx @@ -0,0 +1,58 @@ +import * as React from 'react'; +import { Icons, TooltipLinkList, WithTooltip, IconButton } from '@storybook/components'; +import { VERSION_ID } from './constants'; + +export interface VersionPickerItem { + id: string; + title: string; + onClick: () => void; + value: string; + active: boolean; +} + +function createVersionItems(value: VersionEntry[]): VersionPickerItem[] { + return value.map(item => { + return { + id: item.version, + title: item.version, + onClick: () => { + const href = `https://${item.commit}--${process.env.STORYBOOK_CHROMATIC_APPID}.chromatic.com`; + window.parent.location.href = href; + }, + value: item.version, + active: process.env.STORYBOOK_PACKAGE_VERISION === item.version, + }; + }); +} + +interface VersionEntry { + version: string; + commit: string; +} + +export const VersionPicker = () => { + const [versions, setVersions] = React.useState([]); + + React.useEffect(() => { + fetch(`${process.env.STORYBOOK_VERSION_API_BASEURL}/api/GetVersions`) + .then(res => res.json()) + .then(json => { + setVersions(json); + }); + }, []); + + const renderTooltip = React.useCallback(() => { + return ; + }, [versions]); + + return ( + <> + + + + Version: {process.env.STORYBOOK_PACKAGE_VERISION} + + + + ); +}; diff --git a/packages/react-storybook-addon/src/constants.ts b/packages/react-storybook-addon/src/constants.ts index 3ef367bcec608..baf5991b548e1 100644 --- a/packages/react-storybook-addon/src/constants.ts +++ b/packages/react-storybook-addon/src/constants.ts @@ -1 +1,5 @@ -// @TODO - add addon constants +export const ADDON_ID = 'storybook/fluentui-react-addon'; +export const THEME_ID = `${ADDON_ID}/theme` as const; +export const VERSION_ID = `${ADDON_ID}/versions` as const; +export const PARAM_KEY = `myAddonParameter`; +export const EVENTS = {} as const; diff --git a/packages/react-storybook-addon/src/hooks.ts b/packages/react-storybook-addon/src/hooks.ts new file mode 100644 index 0000000000000..c14ff48f9d760 --- /dev/null +++ b/packages/react-storybook-addon/src/hooks.ts @@ -0,0 +1,16 @@ +import { useGlobals as useStorybookGlobals, Args as StorybookArgs } from '@storybook/api'; +import { StoryContext as StorybookContext } from '@storybook/addons'; + +import { THEME_ID } from './constants'; +import { ThemeIds } from './theme'; + +export interface StoryContext extends StorybookContext { + globals: Globals; +} +export interface Globals extends StorybookArgs { + [THEME_ID]?: ThemeIds; +} + +export function useGlobals(): [Globals, (newGlobals: Globals) => void] { + return useStorybookGlobals(); +} diff --git a/packages/react-storybook-addon/src/preset.ts b/packages/react-storybook-addon/src/preset.ts new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/packages/react-storybook-addon/src/preset/manager.ts b/packages/react-storybook-addon/src/preset/manager.ts index bb08716ee3e20..179efee1d8c82 100644 --- a/packages/react-storybook-addon/src/preset/manager.ts +++ b/packages/react-storybook-addon/src/preset/manager.ts @@ -1 +1,20 @@ -// @TODO - Register the addon +import { addons, types } from '@storybook/addons'; + +import { ADDON_ID, THEME_ID, VERSION_ID } from '../constants'; +import { ThemePicker } from '../ThemePicker'; +import { VersionPicker } from '../VersionPicker'; + +addons.register(ADDON_ID, () => { + addons.add(VERSION_ID, { + title: 'Fluent Version Picker', + type: types.TOOL, + match: ({ viewMode }) => !!(viewMode && viewMode.match(/^(story|docs)$/)), + render: VersionPicker, + }); + addons.add(THEME_ID, { + title: 'Fluent Theme Picker', + type: types.TOOL, + match: ({ viewMode }) => !!(viewMode && viewMode.match(/^(story|docs)$/)), + render: ThemePicker, + }); +}); diff --git a/packages/react-storybook-addon/src/preset/preview.ts b/packages/react-storybook-addon/src/preset/preview.ts index 5540cbb6b136e..ccfbd1a3ef5c0 100644 --- a/packages/react-storybook-addon/src/preset/preview.ts +++ b/packages/react-storybook-addon/src/preset/preview.ts @@ -9,4 +9,6 @@ * https://storybook.js.org/docs/react/writing-stories/decorators#gatsby-focus-wrapper */ -export const decorators = []; +import { withFluentProvider } from '../withFluentProvider'; + +export const decorators = [withFluentProvider]; diff --git a/packages/react-storybook-addon/src/theme.ts b/packages/react-storybook-addon/src/theme.ts new file mode 100644 index 0000000000000..04ec2f84d423c --- /dev/null +++ b/packages/react-storybook-addon/src/theme.ts @@ -0,0 +1,27 @@ +import { + webLightTheme, + webDarkTheme, + webHighContrastTheme, + teamsLightTheme, + teamsDarkTheme, + teamsHighContrastTheme, + Theme, +} from '@fluentui/react-theme'; + +export { FluentProvider } from '@fluentui/react-provider'; + +export const themes = [ + { id: 'web-light', label: 'Web Light', theme: webLightTheme }, + { id: 'web-dark', label: 'Web Dark', theme: webDarkTheme }, + { id: 'web-high-contrast', label: 'Web High Contrast', theme: webHighContrastTheme }, + { 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]; + +export type ThemeIds = typeof themes[number]['id']; +export type ThemeLabels = typeof themes[number]['label']; + +export { Theme }; diff --git a/packages/react-storybook-addon/src/withFluentProvider.tsx b/packages/react-storybook-addon/src/withFluentProvider.tsx new file mode 100644 index 0000000000000..c83b2d7906b73 --- /dev/null +++ b/packages/react-storybook-addon/src/withFluentProvider.tsx @@ -0,0 +1,19 @@ +import * as React from 'react'; +import { StoryFn as StoryFunction } from '@storybook/addons'; + +import { themes, defaultTheme, FluentProvider } from './theme'; +import { THEME_ID } from './constants'; +import { Globals, StoryContext } from './hooks'; + +const getActiveFluentTheme = (globals: Globals) => { + const selectedThemeId = globals[THEME_ID]; + const { theme } = themes.find(value => value.id === selectedThemeId) ?? defaultTheme; + + return { theme }; +}; + +export const withFluentProvider = (StoryFn: StoryFunction, context: StoryContext) => { + const { theme } = getActiveFluentTheme(context.globals); + + return {StoryFn()}; +}; diff --git a/packages/react-storybook/README.md b/packages/react-storybook/README.md index 41e2f9226846d..bdc825fa64b22 100644 --- a/packages/react-storybook/README.md +++ b/packages/react-storybook/README.md @@ -22,8 +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 { withFluentProvider, withStrictMode } from '@fluentui/react-storybook'; +import { withStrictMode } from '@fluentui/react-storybook'; // Register decorators on global level -export const decorators = [withKnobs, withFluentProvider, withStrictMode]; +export const decorators = [withKnobs, withStrictMode]; ``` diff --git a/packages/react-storybook/src/decorators/index.ts b/packages/react-storybook/src/decorators/index.ts index ff044dce8afc1..b5502b4153487 100644 --- a/packages/react-storybook/src/decorators/index.ts +++ b/packages/react-storybook/src/decorators/index.ts @@ -1,2 +1 @@ -export * from './withFluentProvider'; export * from './withStrictMode'; diff --git a/packages/react-storybook/src/decorators/withFluentProvider.tsx b/packages/react-storybook/src/decorators/withFluentProvider.tsx deleted file mode 100644 index 2d55636bad8f8..0000000000000 --- a/packages/react-storybook/src/decorators/withFluentProvider.tsx +++ /dev/null @@ -1,20 +0,0 @@ -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/react-storybook/src/index.test.ts b/packages/react-storybook/src/index.test.ts index 3f2fe8451a862..446d13e865c7f 100644 --- a/packages/react-storybook/src/index.test.ts +++ b/packages/react-storybook/src/index.test.ts @@ -1,9 +1,9 @@ -import { withFluentProvider, withStrictMode } from './index'; +import { withStrictMode } from './index'; describe(`public api`, () => { describe(`decorators`, () => { it(`should work`, () => { - const decorators = [withFluentProvider, withStrictMode]; + const decorators = [withStrictMode]; // @TODO - added proper tests expect(decorators).toBeDefined(); From 4afccab7ca057afe035c40e16021feb5e37144f0 Mon Sep 17 00:00:00 2001 From: Lingfan Gao Date: Mon, 25 Oct 2021 15:23:01 +0200 Subject: [PATCH 07/35] remove old --- .../src/Migrations/utils.stories.tsx | 62 ------------------- 1 file changed, 62 deletions(-) diff --git a/packages/react-components/src/Migrations/utils.stories.tsx b/packages/react-components/src/Migrations/utils.stories.tsx index cd3aa43acbc96..4017d0dd09faf 100644 --- a/packages/react-components/src/Migrations/utils.stories.tsx +++ b/packages/react-components/src/Migrations/utils.stories.tsx @@ -1,17 +1,6 @@ import * as React from 'react'; -// eslint-disable-next-line import/no-extraneous-dependencies import { DocsContainer, DocsContainerProps, Source } from '@storybook/addon-docs'; import { makeStyles } from '@fluentui/react-make-styles'; -import { - Menu, - MenuItem, - MenuList, - MenuPopover, - MenuTrigger, - MenuButton, - FluentProvider, - webLightTheme, -} from '../index'; const useCodeComparisonStyles = makeStyles({ root: { @@ -68,54 +57,3 @@ export const CodeExample = (props: { title?: string; children: React.ReactElemen ); }; - -interface VersionEntry { - version: string; - commit: string; -} - -export const VersionPicker = () => { - const [versions, setVersions] = React.useState([]); - - React.useEffect(() => { - fetch('https://fluentstorybookversion.azurewebsites.net/api/GetVersions') - .then(res => res.json()) - .then(json => { - setVersions(json); - }); - }, []); - - const navigateHandler = (commit: string) => () => { - const href = `https://${commit}--6002298f95a00c00213f4d55.chromatic.com`; - window.parent.location.href = href; - }; - - return ( - - - - Select version - - - - {versions.map(entry => ( - - {entry.version} - - ))} - - - - - ); -}; - -export const FluentDocsContainer = ({ children, context }: DocsContainerProps & { children: React.ReactNode }) => { - console.log(process.env.STORYBOOK_THEME); - return ( - <> - - {children} - - ); -}; From f26fb4c7be1a41f1832b82a25b448adc3b054977 Mon Sep 17 00:00:00 2001 From: Lingfan Gao Date: Mon, 25 Oct 2021 15:34:07 +0200 Subject: [PATCH 08/35] update deps --- packages/react-storybook-addon/package.json | 3 +++ .../src/withFluentProvider.tsx | 22 ++++++++++++++++++- 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/packages/react-storybook-addon/package.json b/packages/react-storybook-addon/package.json index 3787ffc8e7534..ae8ef15ca31ee 100644 --- a/packages/react-storybook-addon/package.json +++ b/packages/react-storybook-addon/package.json @@ -31,6 +31,9 @@ "react": "16.8.6" }, "dependencies": { + "@fluentui/react-theme": "9.0.0-beta.1", + "@fluentui/react-provider": "9.0.0-beta.2", + "@fluentui/react-make-styles": "9.0.0-beta.1", "tslib": "^2.1.0" }, "peerDependencies": { diff --git a/packages/react-storybook-addon/src/withFluentProvider.tsx b/packages/react-storybook-addon/src/withFluentProvider.tsx index c83b2d7906b73..e2b56fe5a4ba9 100644 --- a/packages/react-storybook-addon/src/withFluentProvider.tsx +++ b/packages/react-storybook-addon/src/withFluentProvider.tsx @@ -5,6 +5,17 @@ import { themes, defaultTheme, FluentProvider } from './theme'; import { THEME_ID } from './constants'; import { Globals, StoryContext } from './hooks'; +import { makeStyles } from '@fluentui/react-make-styles'; + +const useStyles = makeStyles({ + root: theme => ({ + padding: '10px', + fontFamily: theme.fontFamilyBase, + color: theme.colorNeutralForeground1, + background: theme.colorNeutralBackground1, + }), +}); + const getActiveFluentTheme = (globals: Globals) => { const selectedThemeId = globals[THEME_ID]; const { theme } = themes.find(value => value.id === selectedThemeId) ?? defaultTheme; @@ -14,6 +25,15 @@ const getActiveFluentTheme = (globals: Globals) => { export const withFluentProvider = (StoryFn: StoryFunction, context: StoryContext) => { const { theme } = getActiveFluentTheme(context.globals); + return ( + + {StoryFn()} + + ); +}; + +const FluentExampleContainer: React.FC = props => { + const styles = useStyles(); - return {StoryFn()}; + return
{props.children}
; }; From 5a797d9e94543bc133f7446eeb0e3a557f831c6d Mon Sep 17 00:00:00 2001 From: Lingfan Gao Date: Mon, 25 Oct 2021 15:35:33 +0200 Subject: [PATCH 09/35] update stypes --- packages/react-components/src/Migrations/utils.stories.tsx | 2 +- packages/react-storybook-addon/src/withFluentProvider.tsx | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/react-components/src/Migrations/utils.stories.tsx b/packages/react-components/src/Migrations/utils.stories.tsx index 4017d0dd09faf..023da5b7ae22d 100644 --- a/packages/react-components/src/Migrations/utils.stories.tsx +++ b/packages/react-components/src/Migrations/utils.stories.tsx @@ -1,5 +1,5 @@ import * as React from 'react'; -import { DocsContainer, DocsContainerProps, Source } from '@storybook/addon-docs'; +import { Source } from '@storybook/addon-docs'; import { makeStyles } from '@fluentui/react-make-styles'; const useCodeComparisonStyles = makeStyles({ diff --git a/packages/react-storybook-addon/src/withFluentProvider.tsx b/packages/react-storybook-addon/src/withFluentProvider.tsx index e2b56fe5a4ba9..54439fa76a772 100644 --- a/packages/react-storybook-addon/src/withFluentProvider.tsx +++ b/packages/react-storybook-addon/src/withFluentProvider.tsx @@ -11,7 +11,6 @@ const useStyles = makeStyles({ root: theme => ({ padding: '10px', fontFamily: theme.fontFamilyBase, - color: theme.colorNeutralForeground1, background: theme.colorNeutralBackground1, }), }); From 89001c05eacf9865760c338b8ef045bc6fb281af Mon Sep 17 00:00:00 2001 From: Lingfan Gao Date: Mon, 25 Oct 2021 15:48:13 +0200 Subject: [PATCH 10/35] update md --- packages/react-storybook/etc/react-storybook.api.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/packages/react-storybook/etc/react-storybook.api.md b/packages/react-storybook/etc/react-storybook.api.md index 4a3d4b6703734..e9d37726e6504 100644 --- a/packages/react-storybook/etc/react-storybook.api.md +++ b/packages/react-storybook/etc/react-storybook.api.md @@ -6,13 +6,9 @@ import * as React_2 from 'react'; -// @public (undocumented) -export const withFluentProvider: (...args: any) => any; - // @public (undocumented) export const withStrictMode: (storyFn: () => React_2.ReactNode) => JSX.Element; - // (No @packageDocumentation comment for this package) ``` From b9e145cb6550d6fa493c9934430924bb75079a54 Mon Sep 17 00:00:00 2001 From: Lingfan Gao Date: Mon, 25 Oct 2021 16:09:12 +0200 Subject: [PATCH 11/35] remove export --- packages/storybook/src/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/storybook/src/index.ts b/packages/storybook/src/index.ts index 3a4c10f824da1..2eeb81228a281 100644 --- a/packages/storybook/src/index.ts +++ b/packages/storybook/src/index.ts @@ -1,2 +1,2 @@ export * from './decorators/index'; -export { withFluentProvider, withStrictMode } from '@fluentui/react-storybook'; +export { withStrictMode } from '@fluentui/react-storybook'; From 75bc101ba5f2205a881b0fe77723d9f452ebc4b4 Mon Sep 17 00:00:00 2001 From: Lingfan Gao Date: Tue, 26 Oct 2021 11:55:38 +0200 Subject: [PATCH 12/35] chore(storybook): Add theme picker to storybook toolbar Adds the theme picker to the storybook toolbar for internal development. The global types are exported since they will be used for the docs page. --- .../etc/react-storybook-addon.api.md | 19 +++++- .../src/VersionPicker.tsx | 58 ------------------- .../src/components/.gitkeep | 0 .../src/{ => components}/ThemePicker.tsx | 16 +++-- .../react-storybook-addon/src/constants.ts | 1 - .../{ => decorators}/withFluentProvider.tsx | 10 ++-- packages/react-storybook-addon/src/hooks.ts | 12 ++-- packages/react-storybook-addon/src/index.ts | 2 +- packages/react-storybook-addon/src/preset.ts | 0 .../src/preset/manager.ts | 11 +--- .../src/preset/preview.ts | 2 +- 11 files changed, 46 insertions(+), 85 deletions(-) delete mode 100644 packages/react-storybook-addon/src/VersionPicker.tsx delete mode 100644 packages/react-storybook-addon/src/components/.gitkeep rename packages/react-storybook-addon/src/{ => components}/ThemePicker.tsx (81%) rename packages/react-storybook-addon/src/{ => decorators}/withFluentProvider.tsx (76%) delete mode 100644 packages/react-storybook-addon/src/preset.ts diff --git a/packages/react-storybook-addon/etc/react-storybook-addon.api.md b/packages/react-storybook-addon/etc/react-storybook-addon.api.md index 4d5ec18c6dbad..a29c11367572a 100644 --- a/packages/react-storybook-addon/etc/react-storybook-addon.api.md +++ b/packages/react-storybook-addon/etc/react-storybook-addon.api.md @@ -4,9 +4,24 @@ ```ts +import { Args } from '@storybook/api'; +import { StoryContext } from '@storybook/addons'; +import { Theme } from '@fluentui/react-theme'; + +// @public +export interface FluentGlobals extends Args { + // Warning: (ae-forgotten-export) The symbol "THEME_ID" needs to be exported by the entry point index.d.ts + // Warning: (ae-forgotten-export) The symbol "ThemeIds" needs to be exported by the entry point index.d.ts + // + // (undocumented) + [THEME_ID]?: ThemeIds; +} + // @public (undocumented) -const _default: {}; -export default _default; +export interface FluentStoryContext extends StoryContext { + // (undocumented) + globals: FluentGlobals; +} // (No @packageDocumentation comment for this package) diff --git a/packages/react-storybook-addon/src/VersionPicker.tsx b/packages/react-storybook-addon/src/VersionPicker.tsx deleted file mode 100644 index f36ad474bd5ea..0000000000000 --- a/packages/react-storybook-addon/src/VersionPicker.tsx +++ /dev/null @@ -1,58 +0,0 @@ -import * as React from 'react'; -import { Icons, TooltipLinkList, WithTooltip, IconButton } from '@storybook/components'; -import { VERSION_ID } from './constants'; - -export interface VersionPickerItem { - id: string; - title: string; - onClick: () => void; - value: string; - active: boolean; -} - -function createVersionItems(value: VersionEntry[]): VersionPickerItem[] { - return value.map(item => { - return { - id: item.version, - title: item.version, - onClick: () => { - const href = `https://${item.commit}--${process.env.STORYBOOK_CHROMATIC_APPID}.chromatic.com`; - window.parent.location.href = href; - }, - value: item.version, - active: process.env.STORYBOOK_PACKAGE_VERISION === item.version, - }; - }); -} - -interface VersionEntry { - version: string; - commit: string; -} - -export const VersionPicker = () => { - const [versions, setVersions] = React.useState([]); - - React.useEffect(() => { - fetch(`${process.env.STORYBOOK_VERSION_API_BASEURL}/api/GetVersions`) - .then(res => res.json()) - .then(json => { - setVersions(json); - }); - }, []); - - const renderTooltip = React.useCallback(() => { - return ; - }, [versions]); - - return ( - <> - - - - Version: {process.env.STORYBOOK_PACKAGE_VERISION} - - - - ); -}; diff --git a/packages/react-storybook-addon/src/components/.gitkeep b/packages/react-storybook-addon/src/components/.gitkeep deleted file mode 100644 index e69de29bb2d1d..0000000000000 diff --git a/packages/react-storybook-addon/src/ThemePicker.tsx b/packages/react-storybook-addon/src/components/ThemePicker.tsx similarity index 81% rename from packages/react-storybook-addon/src/ThemePicker.tsx rename to packages/react-storybook-addon/src/components/ThemePicker.tsx index 9ea4f4d78acf0..c17cf9fa27af2 100644 --- a/packages/react-storybook-addon/src/ThemePicker.tsx +++ b/packages/react-storybook-addon/src/components/ThemePicker.tsx @@ -1,9 +1,16 @@ import * as React from 'react'; import { IconButton, Icons, TooltipLinkList, WithTooltip } from '@storybook/components'; +import { makeStyles } from '@fluentui/react-make-styles'; -import { ThemeIds, themes, defaultTheme } from './theme'; -import { THEME_ID } from './constants'; -import { useGlobals } from './hooks'; +import { ThemeIds, themes, defaultTheme } from '../theme'; +import { THEME_ID } from '../constants'; +import { useGlobals } from '../hooks'; + +const useStyles = makeStyles({ + pickerLabel: { + marginLeft: '5px', + }, +}); export interface ThemeSelectorItem { id: string; @@ -32,6 +39,7 @@ function createThemeItems( } export const ThemePicker = () => { + const styles = useStyles(); const [globals, updateGlobals] = useGlobals(); const selectedThemeId = globals[THEME_ID] ?? defaultTheme.id; const selectedTheme = themes.find(entry => entry.id === selectedThemeId); @@ -68,7 +76,7 @@ export const ThemePicker = () => { - Theme: {selectedTheme?.label} + Theme: {selectedTheme?.label} diff --git a/packages/react-storybook-addon/src/constants.ts b/packages/react-storybook-addon/src/constants.ts index baf5991b548e1..98c41d9786784 100644 --- a/packages/react-storybook-addon/src/constants.ts +++ b/packages/react-storybook-addon/src/constants.ts @@ -1,5 +1,4 @@ export const ADDON_ID = 'storybook/fluentui-react-addon'; export const THEME_ID = `${ADDON_ID}/theme` as const; -export const VERSION_ID = `${ADDON_ID}/versions` as const; export const PARAM_KEY = `myAddonParameter`; export const EVENTS = {} as const; diff --git a/packages/react-storybook-addon/src/withFluentProvider.tsx b/packages/react-storybook-addon/src/decorators/withFluentProvider.tsx similarity index 76% rename from packages/react-storybook-addon/src/withFluentProvider.tsx rename to packages/react-storybook-addon/src/decorators/withFluentProvider.tsx index 54439fa76a772..41a3f215e9013 100644 --- a/packages/react-storybook-addon/src/withFluentProvider.tsx +++ b/packages/react-storybook-addon/src/decorators/withFluentProvider.tsx @@ -1,9 +1,9 @@ import * as React from 'react'; import { StoryFn as StoryFunction } from '@storybook/addons'; -import { themes, defaultTheme, FluentProvider } from './theme'; -import { THEME_ID } from './constants'; -import { Globals, StoryContext } from './hooks'; +import { themes, defaultTheme, FluentProvider } from '../theme'; +import { THEME_ID } from '../constants'; +import { FluentGlobals, FluentStoryContext } from '../hooks'; import { makeStyles } from '@fluentui/react-make-styles'; @@ -15,14 +15,14 @@ const useStyles = makeStyles({ }), }); -const getActiveFluentTheme = (globals: Globals) => { +const getActiveFluentTheme = (globals: FluentGlobals) => { const selectedThemeId = globals[THEME_ID]; const { theme } = themes.find(value => value.id === selectedThemeId) ?? defaultTheme; return { theme }; }; -export const withFluentProvider = (StoryFn: StoryFunction, context: StoryContext) => { +export const withFluentProvider = (StoryFn: StoryFunction, context: FluentStoryContext) => { const { theme } = getActiveFluentTheme(context.globals); return ( diff --git a/packages/react-storybook-addon/src/hooks.ts b/packages/react-storybook-addon/src/hooks.ts index c14ff48f9d760..649100df48ae8 100644 --- a/packages/react-storybook-addon/src/hooks.ts +++ b/packages/react-storybook-addon/src/hooks.ts @@ -4,13 +4,17 @@ import { StoryContext as StorybookContext } from '@storybook/addons'; import { THEME_ID } from './constants'; import { ThemeIds } from './theme'; -export interface StoryContext extends StorybookContext { - globals: Globals; +export interface FluentStoryContext extends StorybookContext { + globals: FluentGlobals; } -export interface Globals extends StorybookArgs { + +/** + * Extends the storybook globals object to include fluent specific propoerties + */ +export interface FluentGlobals extends StorybookArgs { [THEME_ID]?: ThemeIds; } -export function useGlobals(): [Globals, (newGlobals: Globals) => void] { +export function useGlobals(): [FluentGlobals, (newGlobals: FluentGlobals) => void] { return useStorybookGlobals(); } diff --git a/packages/react-storybook-addon/src/index.ts b/packages/react-storybook-addon/src/index.ts index ff8b4c56321a3..71d7efab15dbd 100644 --- a/packages/react-storybook-addon/src/index.ts +++ b/packages/react-storybook-addon/src/index.ts @@ -1 +1 @@ -export default {}; +export type { FluentGlobals, FluentStoryContext } from './hooks'; diff --git a/packages/react-storybook-addon/src/preset.ts b/packages/react-storybook-addon/src/preset.ts deleted file mode 100644 index e69de29bb2d1d..0000000000000 diff --git a/packages/react-storybook-addon/src/preset/manager.ts b/packages/react-storybook-addon/src/preset/manager.ts index 179efee1d8c82..e052cd5e4c6ed 100644 --- a/packages/react-storybook-addon/src/preset/manager.ts +++ b/packages/react-storybook-addon/src/preset/manager.ts @@ -1,16 +1,9 @@ import { addons, types } from '@storybook/addons'; -import { ADDON_ID, THEME_ID, VERSION_ID } from '../constants'; -import { ThemePicker } from '../ThemePicker'; -import { VersionPicker } from '../VersionPicker'; +import { ADDON_ID, THEME_ID } from '../constants'; +import { ThemePicker } from '../components/ThemePicker'; addons.register(ADDON_ID, () => { - addons.add(VERSION_ID, { - title: 'Fluent Version Picker', - type: types.TOOL, - match: ({ viewMode }) => !!(viewMode && viewMode.match(/^(story|docs)$/)), - render: VersionPicker, - }); addons.add(THEME_ID, { title: 'Fluent Theme Picker', type: types.TOOL, diff --git a/packages/react-storybook-addon/src/preset/preview.ts b/packages/react-storybook-addon/src/preset/preview.ts index ccfbd1a3ef5c0..a4e2db0acf3d7 100644 --- a/packages/react-storybook-addon/src/preset/preview.ts +++ b/packages/react-storybook-addon/src/preset/preview.ts @@ -9,6 +9,6 @@ * https://storybook.js.org/docs/react/writing-stories/decorators#gatsby-focus-wrapper */ -import { withFluentProvider } from '../withFluentProvider'; +import { withFluentProvider } from '../decorators/withFluentProvider'; export const decorators = [withFluentProvider]; From e79117f6c75938b22697bbd54a6a8d952bc63359 Mon Sep 17 00:00:00 2001 From: Lingfan Gao Date: Tue, 26 Oct 2021 13:19:11 +0200 Subject: [PATCH 13/35] remove unnecessary changes --- packages/react-components/.env | 2 -- packages/react-storybook-addon/src/constants.ts | 2 -- 2 files changed, 4 deletions(-) delete mode 100644 packages/react-components/.env diff --git a/packages/react-components/.env b/packages/react-components/.env deleted file mode 100644 index 5911548270edf..0000000000000 --- a/packages/react-components/.env +++ /dev/null @@ -1,2 +0,0 @@ -STORYBOOK_CHROMATIC_APPID=6002298f95a00c00213f4d55.chromatic.com -STORYBOOK_VERSION_API_BASEURL=https://fluentstorybookversion.azurewebsites.net diff --git a/packages/react-storybook-addon/src/constants.ts b/packages/react-storybook-addon/src/constants.ts index 98c41d9786784..feac8295cbb2b 100644 --- a/packages/react-storybook-addon/src/constants.ts +++ b/packages/react-storybook-addon/src/constants.ts @@ -1,4 +1,2 @@ export const ADDON_ID = 'storybook/fluentui-react-addon'; export const THEME_ID = `${ADDON_ID}/theme` as const; -export const PARAM_KEY = `myAddonParameter`; -export const EVENTS = {} as const; From e72aead1c0e340ed3f3c5f854a01240a38d80e93 Mon Sep 17 00:00:00 2001 From: Lingfan Gao Date: Tue, 26 Oct 2021 13:20:04 +0200 Subject: [PATCH 14/35] update change --- ...i-react-components-639d9023-4a53-403d-a3eb-fa50ca331ac6.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/change/@fluentui-react-components-639d9023-4a53-403d-a3eb-fa50ca331ac6.json b/change/@fluentui-react-components-639d9023-4a53-403d-a3eb-fa50ca331ac6.json index e4e5e3540ba7c..e2f8f4ec880d5 100644 --- a/change/@fluentui-react-components-639d9023-4a53-403d-a3eb-fa50ca331ac6.json +++ b/change/@fluentui-react-components-639d9023-4a53-403d-a3eb-fa50ca331ac6.json @@ -1,6 +1,6 @@ { "type": "none", - "comment": "experiment(storybook): Version picker", + "comment": "chore(storybook): Theme picker as storybook addon", "packageName": "@fluentui/react-components", "email": "lingfangao@hotmail.com", "dependentChangeType": "none" From dabef22be131b9c33f0b52c67622982f215f2062 Mon Sep 17 00:00:00 2001 From: Lingfan Gao Date: Tue, 26 Oct 2021 14:57:14 +0200 Subject: [PATCH 15/35] chore(storybook): Add custom DocsContainer to react-components storybook Initialize a custom `FluentDocsContainer` and FluentDocsHeader` to the react-components storybook for future toolbar items like theme and version picker. This custom header is required since our future plans to build with `--docs` will remove the native storybook toolbar --- .../react-components/.storybook/preview.js | 10 +++++++++- .../FluentDocsContainer.stories.tsx | 15 +++++++++++++++ .../FluentDocsHeader.stories.tsx | 18 ++++++++++++++++++ 3 files changed, 42 insertions(+), 1 deletion(-) create mode 100644 packages/react-components/src/DocsComponents/FluentDocsContainer.stories.tsx create mode 100644 packages/react-components/src/DocsComponents/FluentDocsHeader.stories.tsx diff --git a/packages/react-components/.storybook/preview.js b/packages/react-components/.storybook/preview.js index f488f6cbdf571..b49fd2e2c5601 100644 --- a/packages/react-components/.storybook/preview.js +++ b/packages/react-components/.storybook/preview.js @@ -2,6 +2,7 @@ import * as rootPreview from '../../../.storybook/preview'; // load global styles import '../public/intro.css'; +import { FluentDocsContainer } from '../src/DocsComponents/FluentDocsContainer.stories'; /** @type {NonNullable} */ const options = { @@ -24,4 +25,11 @@ const options = { export const decorators = [...rootPreview.decorators]; /** @type {typeof rootPreview.parameters} */ -export const parameters = { ...rootPreview.parameters, options }; +export const parameters = { + ...rootPreview.parameters, + /** @type {import('@storybook/react').Parameters['docs']} */ + docs: { + container: FluentDocsContainer, + }, + options, +}; diff --git a/packages/react-components/src/DocsComponents/FluentDocsContainer.stories.tsx b/packages/react-components/src/DocsComponents/FluentDocsContainer.stories.tsx new file mode 100644 index 0000000000000..87288014fb4c2 --- /dev/null +++ b/packages/react-components/src/DocsComponents/FluentDocsContainer.stories.tsx @@ -0,0 +1,15 @@ +import * as React from 'react'; +import { DocsContainer, DocsContainerProps } from '@storybook/addon-docs'; +import { FluentDocsHeader } from './FluentDocsHeader.stories'; + +/** + * A container that wraps storybook's native docs container to add extra components to the docs experience + */ +export const FluentDocsContainer = ({ children, context }: DocsContainerProps & { children: React.ReactNode }) => { + return ( + <> + + {children} + + ); +}; diff --git a/packages/react-components/src/DocsComponents/FluentDocsHeader.stories.tsx b/packages/react-components/src/DocsComponents/FluentDocsHeader.stories.tsx new file mode 100644 index 0000000000000..b4f976813cb46 --- /dev/null +++ b/packages/react-components/src/DocsComponents/FluentDocsHeader.stories.tsx @@ -0,0 +1,18 @@ +import * as React from 'react'; +import { makeStyles } from '../index'; + +const useStyles = makeStyles({ + root: { + position: 'sticky', + top: 0, + padding: '5px', + }, +}); + +/** + * Sticky header over the entire docs page + */ +export const FluentDocsHeader = () => { + const styles = useStyles(); + return
{/** TODO add theme+version picker */}
; +}; From 5f699c22b9e587611141ccabd529f42833d6385b Mon Sep 17 00:00:00 2001 From: Lingfan Gao Date: Tue, 26 Oct 2021 14:59:30 +0200 Subject: [PATCH 16/35] Change files --- ...ct-components-5d59f2d3-fa5b-4bfa-ba01-45fad6992f75.json | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 change/@fluentui-react-components-5d59f2d3-fa5b-4bfa-ba01-45fad6992f75.json diff --git a/change/@fluentui-react-components-5d59f2d3-fa5b-4bfa-ba01-45fad6992f75.json b/change/@fluentui-react-components-5d59f2d3-fa5b-4bfa-ba01-45fad6992f75.json new file mode 100644 index 0000000000000..a8989083a7686 --- /dev/null +++ b/change/@fluentui-react-components-5d59f2d3-fa5b-4bfa-ba01-45fad6992f75.json @@ -0,0 +1,7 @@ +{ + "type": "none", + "comment": "chore(storybook): Add custom DocsContainer to react-components storybook", + "packageName": "@fluentui/react-components", + "email": "lingfangao@hotmail.com", + "dependentChangeType": "none" +} From 43525f3e22acc917c25781f2f286ec4db79c229f Mon Sep 17 00:00:00 2001 From: Lingfan Gao Date: Tue, 26 Oct 2021 15:01:20 +0200 Subject: [PATCH 17/35] add docstring --- packages/react-components/.storybook/preview.js | 1 - .../src/DocsComponents/FluentDocsContainer.stories.tsx | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/react-components/.storybook/preview.js b/packages/react-components/.storybook/preview.js index b49fd2e2c5601..7c0e0a29dd8df 100644 --- a/packages/react-components/.storybook/preview.js +++ b/packages/react-components/.storybook/preview.js @@ -27,7 +27,6 @@ export const decorators = [...rootPreview.decorators]; /** @type {typeof rootPreview.parameters} */ export const parameters = { ...rootPreview.parameters, - /** @type {import('@storybook/react').Parameters['docs']} */ docs: { container: FluentDocsContainer, }, diff --git a/packages/react-components/src/DocsComponents/FluentDocsContainer.stories.tsx b/packages/react-components/src/DocsComponents/FluentDocsContainer.stories.tsx index 87288014fb4c2..14199c20ee7b0 100644 --- a/packages/react-components/src/DocsComponents/FluentDocsContainer.stories.tsx +++ b/packages/react-components/src/DocsComponents/FluentDocsContainer.stories.tsx @@ -9,6 +9,7 @@ export const FluentDocsContainer = ({ children, context }: DocsContainerProps & return ( <> + {/** TODO add table of contents */} {children} ); From 69f0aeee9eb989b2c3c7a184851dcf454d128a98 Mon Sep 17 00:00:00 2001 From: Lingfan Gao Date: Tue, 26 Oct 2021 18:47:21 +0200 Subject: [PATCH 18/35] remove font family style --- .../react-storybook-addon/src/decorators/withFluentProvider.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/react-storybook-addon/src/decorators/withFluentProvider.tsx b/packages/react-storybook-addon/src/decorators/withFluentProvider.tsx index 41a3f215e9013..e26735b10dace 100644 --- a/packages/react-storybook-addon/src/decorators/withFluentProvider.tsx +++ b/packages/react-storybook-addon/src/decorators/withFluentProvider.tsx @@ -10,7 +10,6 @@ import { makeStyles } from '@fluentui/react-make-styles'; const useStyles = makeStyles({ root: theme => ({ padding: '10px', - fontFamily: theme.fontFamilyBase, background: theme.colorNeutralBackground1, }), }); From 4a534c311184a5b952bc6dadea365d854644325b Mon Sep 17 00:00:00 2001 From: Lingfan Gao Date: Wed, 27 Oct 2021 11:30:20 +0200 Subject: [PATCH 19/35] init theme picker --- .../FluentDocsContainer.stories.tsx | 5 +- .../FluentDocsHeader.stories.tsx | 12 +++-- .../DocsComponents/ThemePicker.stories.tsx | 54 +++++++++++++++++++ .../etc/react-storybook-addon.api.md | 27 ++++++++++ packages/react-storybook-addon/src/hooks.ts | 5 ++ packages/react-storybook-addon/src/index.ts | 3 ++ 6 files changed, 102 insertions(+), 4 deletions(-) create mode 100644 packages/react-components/src/DocsComponents/ThemePicker.stories.tsx diff --git a/packages/react-components/src/DocsComponents/FluentDocsContainer.stories.tsx b/packages/react-components/src/DocsComponents/FluentDocsContainer.stories.tsx index 14199c20ee7b0..62c39f60bcac8 100644 --- a/packages/react-components/src/DocsComponents/FluentDocsContainer.stories.tsx +++ b/packages/react-components/src/DocsComponents/FluentDocsContainer.stories.tsx @@ -1,6 +1,7 @@ import * as React from 'react'; import { DocsContainer, DocsContainerProps } from '@storybook/addon-docs'; import { FluentDocsHeader } from './FluentDocsHeader.stories'; +import { FluentProvider, webLightTheme } from '../index'; /** * A container that wraps storybook's native docs container to add extra components to the docs experience @@ -8,7 +9,9 @@ import { FluentDocsHeader } from './FluentDocsHeader.stories'; export const FluentDocsContainer = ({ children, context }: DocsContainerProps & { children: React.ReactNode }) => { return ( <> - + + + {/** TODO add table of contents */} {children} diff --git a/packages/react-components/src/DocsComponents/FluentDocsHeader.stories.tsx b/packages/react-components/src/DocsComponents/FluentDocsHeader.stories.tsx index b4f976813cb46..4758bd892b479 100644 --- a/packages/react-components/src/DocsComponents/FluentDocsHeader.stories.tsx +++ b/packages/react-components/src/DocsComponents/FluentDocsHeader.stories.tsx @@ -1,9 +1,11 @@ import * as React from 'react'; +import { FluentGlobals } from '@fluentui/react-storybook-addon'; import { makeStyles } from '../index'; +import { ThemePicker } from './ThemePicker.stories'; const useStyles = makeStyles({ root: { - position: 'sticky', + position: 'fixed', top: 0, padding: '5px', }, @@ -12,7 +14,11 @@ const useStyles = makeStyles({ /** * Sticky header over the entire docs page */ -export const FluentDocsHeader = () => { +export const FluentDocsHeader: React.FC<{ storybookGlobals: FluentGlobals }> = ({ storybookGlobals }) => { const styles = useStyles(); - return
{/** TODO add theme+version picker */}
; + return ( +
+ +
+ ); }; diff --git a/packages/react-components/src/DocsComponents/ThemePicker.stories.tsx b/packages/react-components/src/DocsComponents/ThemePicker.stories.tsx new file mode 100644 index 0000000000000..8cf1845a3818c --- /dev/null +++ b/packages/react-components/src/DocsComponents/ThemePicker.stories.tsx @@ -0,0 +1,54 @@ +import * as React from 'react'; +import { MenuButton, Menu, MenuPopover, MenuItemRadio, MenuList, MenuTrigger, makeStyles } from '../index'; +import { PaintBucket24Filled } from '@fluentui/react-icons'; +import { themes, setGlobalTheme } from '@fluentui/react-storybook-addon'; + +const useStyles = makeStyles({ + menuButton: { + minWidth: '210px', + }, + + menuPopover: { + minWidth: '210px', + }, +}); + +/** + * Theme picker used in the react-components docs header + */ +export const ThemePicker: React.FC<{ selectedThemeId?: string }> = ({ selectedThemeId }) => { + const styles = useStyles(); + const onCheckedValueChange = ( + e: React.MouseEvent | React.KeyboardEvent, + data: { + name: string; + checkedItems: string[]; + }, + ) => { + setGlobalTheme(data.checkedItems[0]); + }; + + const selectedTheme = themes.find(theme => theme.id === selectedThemeId); + + return ( + + + }> + {selectedTheme?.label} + + + + + {themes.map(theme => ( + + {theme.label} + + ))} + + + + ); +}; diff --git a/packages/react-storybook-addon/etc/react-storybook-addon.api.md b/packages/react-storybook-addon/etc/react-storybook-addon.api.md index a29c11367572a..c0ab5481e6d16 100644 --- a/packages/react-storybook-addon/etc/react-storybook-addon.api.md +++ b/packages/react-storybook-addon/etc/react-storybook-addon.api.md @@ -23,6 +23,33 @@ export interface FluentStoryContext extends StoryContext { globals: FluentGlobals; } +// @public (undocumented) +export const themes: readonly [{ + readonly id: "web-light"; + readonly label: "Web Light"; + readonly theme: Theme; +}, { + readonly id: "web-dark"; + readonly label: "Web Dark"; + readonly theme: Theme; +}, { + readonly id: "web-high-contrast"; + readonly label: "Web High Contrast"; + readonly theme: Theme; +}, { + readonly id: "teams-light"; + readonly label: "Teams Light"; + readonly theme: Theme; +}, { + readonly id: "teams-dark"; + readonly label: "Teams Dark"; + readonly theme: Theme; +}, { + readonly id: "teams-high-contrast"; + readonly label: "Teams High Contrast"; + readonly theme: Theme; +}]; + // (No @packageDocumentation comment for this package) ``` diff --git a/packages/react-storybook-addon/src/hooks.ts b/packages/react-storybook-addon/src/hooks.ts index 649100df48ae8..4b99e1f5f7744 100644 --- a/packages/react-storybook-addon/src/hooks.ts +++ b/packages/react-storybook-addon/src/hooks.ts @@ -1,5 +1,6 @@ import { useGlobals as useStorybookGlobals, Args as StorybookArgs } from '@storybook/api'; import { StoryContext as StorybookContext } from '@storybook/addons'; +import addons from '@storybook/addons'; import { THEME_ID } from './constants'; import { ThemeIds } from './theme'; @@ -18,3 +19,7 @@ export interface FluentGlobals extends StorybookArgs { export function useGlobals(): [FluentGlobals, (newGlobals: FluentGlobals) => void] { return useStorybookGlobals(); } + +export function setGlobalTheme(themeId: string): void { + addons.getChannel().emit('updateGlobals', { globals: { [THEME_ID]: themeId } }); +} diff --git a/packages/react-storybook-addon/src/index.ts b/packages/react-storybook-addon/src/index.ts index 71d7efab15dbd..a3ffce420ff75 100644 --- a/packages/react-storybook-addon/src/index.ts +++ b/packages/react-storybook-addon/src/index.ts @@ -1 +1,4 @@ export type { FluentGlobals, FluentStoryContext } from './hooks'; +export { setGlobalTheme } from './hooks'; +export { themes } from './theme'; +export { THEME_ID } from './constants'; From 1c91a68bda04a967f66bd2e81d7c812f834cafe4 Mon Sep 17 00:00:00 2001 From: Lingfan Gao Date: Tue, 2 Nov 2021 15:13:51 +0100 Subject: [PATCH 20/35] revert manager --- .../react-components/.storybook/manager.js | 20 ------------------- 1 file changed, 20 deletions(-) delete mode 100644 packages/react-components/.storybook/manager.js diff --git a/packages/react-components/.storybook/manager.js b/packages/react-components/.storybook/manager.js deleted file mode 100644 index f91ea5d9239a6..0000000000000 --- a/packages/react-components/.storybook/manager.js +++ /dev/null @@ -1,20 +0,0 @@ -import { addons } from '@storybook/addons'; -import theme from './theme'; - -addons.setConfig({ - showPanel: true, - panelPosition: 'right', - theme, - toolbar: { - zoom: { hidden: true }, - outline: { hidden: true }, - eject: { hidden: true }, - copy: { hidden: true }, - fullscreen: { hidden: true }, - 'storybook/background': { hidden: true }, - 'storybook/viewport': { hidden: true }, - 'storybook/measure-addon/tool': { hidden: true }, - 'storybook/outline': { hidden: true }, - 'storybook/a11y/panel': { hidden: true }, - }, -}); From 29a5f6491a5c6f66705729a6aa2b6bf33e11518c Mon Sep 17 00:00:00 2001 From: Lingfan Gao Date: Tue, 2 Nov 2021 15:14:33 +0100 Subject: [PATCH 21/35] revert .storybook --- .storybook/main.js | 1 - 1 file changed, 1 deletion(-) diff --git a/.storybook/main.js b/.storybook/main.js index 23c22c5d37efe..1d033ca588735 100644 --- a/.storybook/main.js +++ b/.storybook/main.js @@ -44,7 +44,6 @@ module.exports = /** @type {Omit} */ ({ '@storybook/addon-knobs/preset', 'storybook-addon-performance', 'storybook-addon-export-to-codesandbox', - '@fluentui/react-storybook-addon', ], webpackFinal: config => { const tsPaths = new TsconfigPathsPlugin({ From 0c8aa79b5541a25347af864ec75c14ed6d1c6c5a Mon Sep 17 00:00:00 2001 From: Lingfan Gao Date: Tue, 2 Nov 2021 15:17:05 +0100 Subject: [PATCH 22/35] remove dupe export --- packages/react-storybook-addon/src/index.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/react-storybook-addon/src/index.ts b/packages/react-storybook-addon/src/index.ts index a3ffce420ff75..715c7c46ea399 100644 --- a/packages/react-storybook-addon/src/index.ts +++ b/packages/react-storybook-addon/src/index.ts @@ -1,4 +1,3 @@ -export type { FluentGlobals, FluentStoryContext } from './hooks'; -export { setGlobalTheme } from './hooks'; +export type { FluentGlobals, FluentStoryContext, setGlobalTheme } from './hooks'; export { themes } from './theme'; export { THEME_ID } from './constants'; From c4bc7618cfc3290580eaa72e8a2aeb43a85eebd4 Mon Sep 17 00:00:00 2001 From: Lingfan Gao Date: Tue, 2 Nov 2021 15:29:40 +0100 Subject: [PATCH 23/35] export --- packages/react-storybook-addon/src/index.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/react-storybook-addon/src/index.ts b/packages/react-storybook-addon/src/index.ts index 715c7c46ea399..a3ffce420ff75 100644 --- a/packages/react-storybook-addon/src/index.ts +++ b/packages/react-storybook-addon/src/index.ts @@ -1,3 +1,4 @@ -export type { FluentGlobals, FluentStoryContext, setGlobalTheme } from './hooks'; +export type { FluentGlobals, FluentStoryContext } from './hooks'; +export { setGlobalTheme } from './hooks'; export { themes } from './theme'; export { THEME_ID } from './constants'; From 9bcd9c4146bb7b85b1d702f4f3cb32f46f46542f Mon Sep 17 00:00:00 2001 From: Lingfan Gao Date: Tue, 2 Nov 2021 15:44:20 +0100 Subject: [PATCH 24/35] README --- .../FluentDocsContainer.stories.tsx | 9 ++++-- packages/react-storybook-addon/README.md | 30 +++++++++++++++++++ 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/packages/react-components/src/DocsComponents/FluentDocsContainer.stories.tsx b/packages/react-components/src/DocsComponents/FluentDocsContainer.stories.tsx index 62c39f60bcac8..944e0f3fcde1c 100644 --- a/packages/react-components/src/DocsComponents/FluentDocsContainer.stories.tsx +++ b/packages/react-components/src/DocsComponents/FluentDocsContainer.stories.tsx @@ -1,12 +1,17 @@ import * as React from 'react'; -import { DocsContainer, DocsContainerProps } from '@storybook/addon-docs'; +import { DocsContainer, DocsContextProps } from '@storybook/addon-docs'; +import { FluentStoryContext } from '@fluentui/react-storybook-addon'; import { FluentDocsHeader } from './FluentDocsHeader.stories'; import { FluentProvider, webLightTheme } from '../index'; +interface FluentDocsContainerProps { + context: FluentStoryContext & DocsContextProps; +} + /** * A container that wraps storybook's native docs container to add extra components to the docs experience */ -export const FluentDocsContainer = ({ children, context }: DocsContainerProps & { children: React.ReactNode }) => { +export const FluentDocsContainer: React.FC = ({ children, context }) => { return ( <> diff --git a/packages/react-storybook-addon/README.md b/packages/react-storybook-addon/README.md index 9a052541499df..9bd2f2410b30d 100644 --- a/packages/react-storybook-addon/README.md +++ b/packages/react-storybook-addon/README.md @@ -11,6 +11,36 @@ These are not production-ready components and **should never be used in product* - adds fluent theme switcher - ![Fluent Theme Switcher](https://user-images.githubusercontent.com/20744592/138872560-8ef40c25-193c-47db-a216-7c1e86fe8cda.png) +**Theme management in storybook globals** + +Exports types and utilities to set and consume the correct Fluent theme in storybook globals. Here's some example picker +that sets the Fluent them in storybook globals. + +```tsx +import * as React from 'react'; +import { themes, setGlobalTheme, FluentStoryContext, THEME_ID } from '@fluentui/react-storybook-addon'; + +// storybook context which can be accessed for example in decorators +// https://storybook.js.org/docs/react/writing-stories/decorators#context-for-mocking +export const ThemePicker: React.FC<{ context: FluentStoryContext }> = ({ context }) => { + const handleChange = e => { + setGlobalTheme(e.target.value); + }; + + const selectedTheme = themes.find(theme => theme.id === context.globals[THEME_ID]); + + return ( + + ); +}; +``` + ## Getting Started ### Installation From 7a44e5991e33930a97e0747e0983737c7ad3e214 Mon Sep 17 00:00:00 2001 From: Lingfan Gao Date: Tue, 2 Nov 2021 15:46:41 +0100 Subject: [PATCH 25/35] use active theme --- .../src/DocsComponents/FluentDocsContainer.stories.tsx | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/react-components/src/DocsComponents/FluentDocsContainer.stories.tsx b/packages/react-components/src/DocsComponents/FluentDocsContainer.stories.tsx index 944e0f3fcde1c..10b783571355b 100644 --- a/packages/react-components/src/DocsComponents/FluentDocsContainer.stories.tsx +++ b/packages/react-components/src/DocsComponents/FluentDocsContainer.stories.tsx @@ -1,6 +1,6 @@ import * as React from 'react'; import { DocsContainer, DocsContextProps } from '@storybook/addon-docs'; -import { FluentStoryContext } from '@fluentui/react-storybook-addon'; +import { FluentStoryContext, THEME_ID, themes } from '@fluentui/react-storybook-addon'; import { FluentDocsHeader } from './FluentDocsHeader.stories'; import { FluentProvider, webLightTheme } from '../index'; @@ -12,9 +12,11 @@ interface FluentDocsContainerProps { * A container that wraps storybook's native docs container to add extra components to the docs experience */ export const FluentDocsContainer: React.FC = ({ children, context }) => { + const selectedTheme = themes.find(theme => theme.id === context.globals[THEME_ID]); + return ( <> - + {/** TODO add table of contents */} From 8488fd382cfd1da6b487a2bbac2f887df2daaf71 Mon Sep 17 00:00:00 2001 From: Lingfan Gao Date: Tue, 2 Nov 2021 15:55:55 +0100 Subject: [PATCH 26/35] add docstring --- packages/react-storybook-addon/src/hooks.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/react-storybook-addon/src/hooks.ts b/packages/react-storybook-addon/src/hooks.ts index 4b99e1f5f7744..26178eef2feda 100644 --- a/packages/react-storybook-addon/src/hooks.ts +++ b/packages/react-storybook-addon/src/hooks.ts @@ -20,6 +20,10 @@ export function useGlobals(): [FluentGlobals, (newGlobals: FluentGlobals) => voi return useStorybookGlobals(); } -export function setGlobalTheme(themeId: string): void { +/** + * Uses storybook addon API to update globals with the correc theme Id + * Can be used externally be decorators and other addon-docs containers + */ +export function setGlobalTheme(themeId: ThemeIds): void { addons.getChannel().emit('updateGlobals', { globals: { [THEME_ID]: themeId } }); } From 7404702c3ae7f9d1503e061458d00e7b28e0c092 Mon Sep 17 00:00:00 2001 From: Lingfan Gao Date: Tue, 2 Nov 2021 15:58:59 +0100 Subject: [PATCH 27/35] Change files --- ...ct-components-5f56cdc5-254d-4f5d-85fd-05fc8095827d.json | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 change/@fluentui-react-components-5f56cdc5-254d-4f5d-85fd-05fc8095827d.json diff --git a/change/@fluentui-react-components-5f56cdc5-254d-4f5d-85fd-05fc8095827d.json b/change/@fluentui-react-components-5f56cdc5-254d-4f5d-85fd-05fc8095827d.json new file mode 100644 index 0000000000000..7e47302d13abc --- /dev/null +++ b/change/@fluentui-react-components-5f56cdc5-254d-4f5d-85fd-05fc8095827d.json @@ -0,0 +1,7 @@ +{ + "type": "none", + "comment": "chore(react-components): Theme picker for storybook `--docs` mode", + "packageName": "@fluentui/react-components", + "email": "lingfangao@hotmail.com", + "dependentChangeType": "none" +} From 25ee3fed86b5f32c7c5a933d757375d8c6e3710e Mon Sep 17 00:00:00 2001 From: Lingfan Gao Date: Tue, 2 Nov 2021 16:34:32 +0100 Subject: [PATCH 28/35] fix md --- .../src/DocsComponents/ThemePicker.stories.tsx | 4 ++-- .../etc/react-storybook-addon.api.md | 9 +++++---- packages/react-storybook-addon/src/index.ts | 2 +- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/packages/react-components/src/DocsComponents/ThemePicker.stories.tsx b/packages/react-components/src/DocsComponents/ThemePicker.stories.tsx index 0e85b1d83105b..1ae095e5a9879 100644 --- a/packages/react-components/src/DocsComponents/ThemePicker.stories.tsx +++ b/packages/react-components/src/DocsComponents/ThemePicker.stories.tsx @@ -1,7 +1,7 @@ import * as React from 'react'; import { MenuButton, Menu, MenuPopover, MenuItemRadio, MenuList, MenuTrigger, makeStyles } from '../index'; import { PaintBucket24Filled } from '@fluentui/react-icons'; -import { themes, setGlobalTheme } from '@fluentui/react-storybook-addon'; +import { themes, ThemeIds, setGlobalTheme } from '@fluentui/react-storybook-addon'; const useStyles = makeStyles({ menuButton: { @@ -30,7 +30,7 @@ export const ThemePicker: React.FC<{ selectedThemeId?: string }> = ({ selectedTh checkedItems: string[]; }, ) => { - setGlobalTheme(data.checkedItems[0]); + setGlobalTheme(data.checkedItems[0] as ThemeIds); }; const selectedTheme = themes.find(theme => theme.id === selectedThemeId); diff --git a/packages/react-storybook-addon/etc/react-storybook-addon.api.md b/packages/react-storybook-addon/etc/react-storybook-addon.api.md index 4607cac72d212..c14709eb5a71d 100644 --- a/packages/react-storybook-addon/etc/react-storybook-addon.api.md +++ b/packages/react-storybook-addon/etc/react-storybook-addon.api.md @@ -10,8 +10,6 @@ import { Theme } from '@fluentui/react-theme'; // @public export interface FluentGlobals extends Args { - // Warning: (ae-forgotten-export) The symbol "ThemeIds" needs to be exported by the entry point index.d.ts - // // (undocumented) [THEME_ID]?: ThemeIds; } @@ -22,12 +20,15 @@ export interface FluentStoryContext extends StoryContext { globals: FluentGlobals; } -// @public (undocumented) -export function setGlobalTheme(themeId: string): void; +// @public +export function setGlobalTheme(themeId: ThemeIds): void; // @public (undocumented) export const THEME_ID: "storybook/fluentui-react-addon/theme"; +// @public (undocumented) +export type ThemeIds = typeof themes[number]['id']; + // @public (undocumented) export const themes: readonly [{ readonly id: "web-light"; diff --git a/packages/react-storybook-addon/src/index.ts b/packages/react-storybook-addon/src/index.ts index a3ffce420ff75..e08cba64c6af1 100644 --- a/packages/react-storybook-addon/src/index.ts +++ b/packages/react-storybook-addon/src/index.ts @@ -1,4 +1,4 @@ export type { FluentGlobals, FluentStoryContext } from './hooks'; export { setGlobalTheme } from './hooks'; -export { themes } from './theme'; +export { themes, ThemeIds } from './theme'; export { THEME_ID } from './constants'; From 184ac625ade1bc74a88764be2e674deba9909969 Mon Sep 17 00:00:00 2001 From: Lingfan Gao Date: Wed, 3 Nov 2021 09:09:29 +0100 Subject: [PATCH 29/35] drop icon --- .../src/DocsComponents/ThemePicker.stories.tsx | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/packages/react-components/src/DocsComponents/ThemePicker.stories.tsx b/packages/react-components/src/DocsComponents/ThemePicker.stories.tsx index 1ae095e5a9879..aa507d86824e4 100644 --- a/packages/react-components/src/DocsComponents/ThemePicker.stories.tsx +++ b/packages/react-components/src/DocsComponents/ThemePicker.stories.tsx @@ -1,6 +1,5 @@ import * as React from 'react'; import { MenuButton, Menu, MenuPopover, MenuItemRadio, MenuList, MenuTrigger, makeStyles } from '../index'; -import { PaintBucket24Filled } from '@fluentui/react-icons'; import { themes, ThemeIds, setGlobalTheme } from '@fluentui/react-storybook-addon'; const useStyles = makeStyles({ @@ -41,11 +40,7 @@ export const ThemePicker: React.FC<{ selectedThemeId?: string }> = ({ selectedTh checkedValues={{ theme: selectedThemeId ? [selectedThemeId] : [] }} > - } - menuIcon={{ className: styles.chevronIcon }} - > + {selectedTheme?.label ?? 'Theme'} From 208c565ae8d8474bdfd02bec47b736dcf877c0b7 Mon Sep 17 00:00:00 2001 From: Lingfan Gao Date: Fri, 5 Nov 2021 11:56:54 +0100 Subject: [PATCH 30/35] update md --- packages/react-storybook-addon/etc/react-storybook-addon.api.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/react-storybook-addon/etc/react-storybook-addon.api.md b/packages/react-storybook-addon/etc/react-storybook-addon.api.md index c14709eb5a71d..e40c77d4da168 100644 --- a/packages/react-storybook-addon/etc/react-storybook-addon.api.md +++ b/packages/react-storybook-addon/etc/react-storybook-addon.api.md @@ -6,7 +6,7 @@ import { Args } from '@storybook/api'; import { StoryContext } from '@storybook/addons'; -import { Theme } from '@fluentui/react-theme'; +import type { Theme } from '@fluentui/react-theme'; // @public export interface FluentGlobals extends Args { From 80242ae5df664be8ed2abedd0dccd1640e9ed085 Mon Sep 17 00:00:00 2001 From: Lingfan Gao Date: Fri, 5 Nov 2021 13:00:05 +0100 Subject: [PATCH 31/35] set global theme to react-components --- .../src/DocsComponents/ThemePicker.stories.tsx | 7 ++++++- .../etc/react-storybook-addon.api.md | 3 --- packages/react-storybook-addon/src/hooks.ts | 9 --------- packages/react-storybook-addon/src/index.ts | 1 - 4 files changed, 6 insertions(+), 14 deletions(-) diff --git a/packages/react-components/src/DocsComponents/ThemePicker.stories.tsx b/packages/react-components/src/DocsComponents/ThemePicker.stories.tsx index aa507d86824e4..4dd766bd06aab 100644 --- a/packages/react-components/src/DocsComponents/ThemePicker.stories.tsx +++ b/packages/react-components/src/DocsComponents/ThemePicker.stories.tsx @@ -1,6 +1,7 @@ import * as React from 'react'; import { MenuButton, Menu, MenuPopover, MenuItemRadio, MenuList, MenuTrigger, makeStyles } from '../index'; -import { themes, ThemeIds, setGlobalTheme } from '@fluentui/react-storybook-addon'; +import { themes, ThemeIds, THEME_ID } from '@fluentui/react-storybook-addon'; +import addons from '@storybook/addons'; const useStyles = makeStyles({ menuButton: { @@ -22,6 +23,10 @@ const useStyles = makeStyles({ */ export const ThemePicker: React.FC<{ selectedThemeId?: string }> = ({ selectedThemeId }) => { const styles = useStyles(); + + const setGlobalTheme = (themeId: ThemeIds): void => { + addons.getChannel().emit('updateGlobals', { globals: { [THEME_ID]: themeId } }); + }; const onCheckedValueChange = ( e: React.MouseEvent | React.KeyboardEvent, data: { diff --git a/packages/react-storybook-addon/etc/react-storybook-addon.api.md b/packages/react-storybook-addon/etc/react-storybook-addon.api.md index e40c77d4da168..b1244a204d005 100644 --- a/packages/react-storybook-addon/etc/react-storybook-addon.api.md +++ b/packages/react-storybook-addon/etc/react-storybook-addon.api.md @@ -20,9 +20,6 @@ export interface FluentStoryContext extends StoryContext { globals: FluentGlobals; } -// @public -export function setGlobalTheme(themeId: ThemeIds): void; - // @public (undocumented) export const THEME_ID: "storybook/fluentui-react-addon/theme"; diff --git a/packages/react-storybook-addon/src/hooks.ts b/packages/react-storybook-addon/src/hooks.ts index 26178eef2feda..649100df48ae8 100644 --- a/packages/react-storybook-addon/src/hooks.ts +++ b/packages/react-storybook-addon/src/hooks.ts @@ -1,6 +1,5 @@ import { useGlobals as useStorybookGlobals, Args as StorybookArgs } from '@storybook/api'; import { StoryContext as StorybookContext } from '@storybook/addons'; -import addons from '@storybook/addons'; import { THEME_ID } from './constants'; import { ThemeIds } from './theme'; @@ -19,11 +18,3 @@ export interface FluentGlobals extends StorybookArgs { export function useGlobals(): [FluentGlobals, (newGlobals: FluentGlobals) => void] { return useStorybookGlobals(); } - -/** - * Uses storybook addon API to update globals with the correc theme Id - * Can be used externally be decorators and other addon-docs containers - */ -export function setGlobalTheme(themeId: ThemeIds): void { - addons.getChannel().emit('updateGlobals', { globals: { [THEME_ID]: themeId } }); -} diff --git a/packages/react-storybook-addon/src/index.ts b/packages/react-storybook-addon/src/index.ts index e08cba64c6af1..3da679ee45e46 100644 --- a/packages/react-storybook-addon/src/index.ts +++ b/packages/react-storybook-addon/src/index.ts @@ -1,4 +1,3 @@ export type { FluentGlobals, FluentStoryContext } from './hooks'; -export { setGlobalTheme } from './hooks'; export { themes, ThemeIds } from './theme'; export { THEME_ID } from './constants'; From 37eeb82b788e8ec8b62bebbf1f21187cd3755f70 Mon Sep 17 00:00:00 2001 From: Lingfan Gao Date: Fri, 5 Nov 2021 13:09:49 +0100 Subject: [PATCH 32/35] add container to page --- packages/react-components/.storybook/preview.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/react-components/.storybook/preview.js b/packages/react-components/.storybook/preview.js index dc19d1c79118a..495458b1c0668 100644 --- a/packages/react-components/.storybook/preview.js +++ b/packages/react-components/.storybook/preview.js @@ -1,5 +1,5 @@ import * as rootPreview from '../../../.storybook/preview'; -// import { FluentDocsContainer } from '../src/DocsComponents/FluentDocsContainer.stories'; +import { FluentDocsContainer } from '../src/DocsComponents/FluentDocsContainer.stories'; import { FluentDocsPage } from '../src/DocsComponents/FluentDocsPage.stories'; // load global styles @@ -30,6 +30,7 @@ export const parameters = { ...rootPreview.parameters, docs: { ...rootPreview.parameters.docs, + container: FluentDocsContainer, page: FluentDocsPage, // container: FluentDocsContainer, }, From 9c7d6e4a59b3f0061e6ac3141783f32afffb5812 Mon Sep 17 00:00:00 2001 From: Lingfan Gao Date: Fri, 5 Nov 2021 13:10:57 +0100 Subject: [PATCH 33/35] use type --- .../src/DocsComponents/ThemePicker.stories.tsx | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/packages/react-components/src/DocsComponents/ThemePicker.stories.tsx b/packages/react-components/src/DocsComponents/ThemePicker.stories.tsx index 4dd766bd06aab..34e2079da0e4f 100644 --- a/packages/react-components/src/DocsComponents/ThemePicker.stories.tsx +++ b/packages/react-components/src/DocsComponents/ThemePicker.stories.tsx @@ -1,5 +1,5 @@ import * as React from 'react'; -import { MenuButton, Menu, MenuPopover, MenuItemRadio, MenuList, MenuTrigger, makeStyles } from '../index'; +import { MenuButton, Menu, MenuPopover, MenuItemRadio, MenuList, MenuTrigger, makeStyles, MenuProps } from '../index'; import { themes, ThemeIds, THEME_ID } from '@fluentui/react-storybook-addon'; import addons from '@storybook/addons'; @@ -27,13 +27,7 @@ export const ThemePicker: React.FC<{ selectedThemeId?: string }> = ({ selectedTh const setGlobalTheme = (themeId: ThemeIds): void => { addons.getChannel().emit('updateGlobals', { globals: { [THEME_ID]: themeId } }); }; - const onCheckedValueChange = ( - e: React.MouseEvent | React.KeyboardEvent, - data: { - name: string; - checkedItems: string[]; - }, - ) => { + const onCheckedValueChange: MenuProps['onCheckedValueChange'] = (e, data) => { setGlobalTheme(data.checkedItems[0] as ThemeIds); }; From 4b9e1d3cdf7e889c688c91546f7980336065b44c Mon Sep 17 00:00:00 2001 From: Lingfan Gao Date: Fri, 5 Nov 2021 13:18:30 +0100 Subject: [PATCH 34/35] header styling --- .../src/DocsComponents/FluentDocsHeader.stories.tsx | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/packages/react-components/src/DocsComponents/FluentDocsHeader.stories.tsx b/packages/react-components/src/DocsComponents/FluentDocsHeader.stories.tsx index 4758bd892b479..e85276cc32536 100644 --- a/packages/react-components/src/DocsComponents/FluentDocsHeader.stories.tsx +++ b/packages/react-components/src/DocsComponents/FluentDocsHeader.stories.tsx @@ -1,14 +1,19 @@ import * as React from 'react'; -import { FluentGlobals } from '@fluentui/react-storybook-addon'; +import { FluentGlobals, THEME_ID } from '@fluentui/react-storybook-addon'; import { makeStyles } from '../index'; import { ThemePicker } from './ThemePicker.stories'; const useStyles = makeStyles({ - root: { + root: theme => ({ position: 'fixed', top: 0, padding: '5px', - }, + width: '100%', + background: theme.colorNeutralBackground2, + boxShadow: `${theme.shadow8}`, + borderBottom: '1px solid transparent', + zIndex: 1000, + }), }); /** @@ -18,7 +23,7 @@ export const FluentDocsHeader: React.FC<{ storybookGlobals: FluentGlobals }> = ( const styles = useStyles(); return (
- +
); }; From 94c568747db17e00b52df8c09cd5005ea488e9c4 Mon Sep 17 00:00:00 2001 From: Lingfan Gao Date: Fri, 5 Nov 2021 13:31:03 +0100 Subject: [PATCH 35/35] styling updates --- .storybook/preview-head-template.html | 8 -------- .../src/DocsComponents/FluentDocsHeader.stories.tsx | 4 ++-- .../src/decorators/withFluentProvider.tsx | 4 ++-- 3 files changed, 4 insertions(+), 12 deletions(-) diff --git a/.storybook/preview-head-template.html b/.storybook/preview-head-template.html index fc104f390603a..a1cf7c4a6c27c 100644 --- a/.storybook/preview-head-template.html +++ b/.storybook/preview-head-template.html @@ -171,10 +171,6 @@ color: #616161; } - #docs-root .docblock-argstable tbody tr:nth-child(even) td { - background: #fafafa; - } - #docs-root .docblock-argstable tbody tr td { vertical-align: middle; } @@ -197,10 +193,6 @@ background: none; } - #docs-root .docs-story > div > div[scale] { - padding: 48px 24px; - } - #docs-root .docs-story > div:last-child { right: 31px; border-radius: 24px; diff --git a/packages/react-components/src/DocsComponents/FluentDocsHeader.stories.tsx b/packages/react-components/src/DocsComponents/FluentDocsHeader.stories.tsx index e85276cc32536..c452fd98bd4f1 100644 --- a/packages/react-components/src/DocsComponents/FluentDocsHeader.stories.tsx +++ b/packages/react-components/src/DocsComponents/FluentDocsHeader.stories.tsx @@ -9,9 +9,9 @@ const useStyles = makeStyles({ top: 0, padding: '5px', width: '100%', - background: theme.colorNeutralBackground2, + background: theme.colorNeutralBackground3, boxShadow: `${theme.shadow8}`, - borderBottom: '1px solid transparent', + borderBottom: `1px solid ${theme.colorTransparentStroke}`, zIndex: 1000, }), }); diff --git a/packages/react-storybook-addon/src/decorators/withFluentProvider.tsx b/packages/react-storybook-addon/src/decorators/withFluentProvider.tsx index c520b7dde643a..11f8b5a83c810 100644 --- a/packages/react-storybook-addon/src/decorators/withFluentProvider.tsx +++ b/packages/react-storybook-addon/src/decorators/withFluentProvider.tsx @@ -27,6 +27,6 @@ export const withFluentProvider = (StoryFn: StoryFunction, c const FluentExampleContainer: React.FC<{ theme: Theme }> = props => { const { theme } = props; - const backgroundColor = theme.colorNeutralBackground1; - return
{props.children}
; + const backgroundColor = theme.colorNeutralBackground2; + return
{props.children}
; };