From a63999c2a4c56a68b803c8e8624db913662e91b0 Mon Sep 17 00:00:00 2001 From: Norbert de Langen Date: Wed, 31 Jul 2024 15:05:01 +0200 Subject: [PATCH 01/13] rename the theme global we use internally to `sb_theme`. add addon-themes to template stories, and to main storybook. --- code/.storybook/main.ts | 5 + code/.storybook/preview.tsx | 5 +- .../template/stories/conditional.stories.ts | 8 +- .../src/components/Interaction.stories.tsx | 2 +- .../components/InteractionsPanel.stories.tsx | 2 +- .../template/stories/basics.stories.ts | 2 +- code/addons/themes/src/constants.ts | 1 + .../src/decorators/class-name.decorator.tsx | 4 +- .../decorators/data-attribute.decorator.tsx | 2 +- .../src/decorators/provider.decorator.tsx | 2 +- code/addons/themes/src/preview.tsx | 7 +- code/addons/themes/src/theme-switcher.tsx | 85 +++++++++-------- .../template/stories/decorators.stories.ts | 93 +++++++++++++++++++ .../template/stories/globals.stories.ts | 64 +++++++++++++ .../template/stories/parameters.stories.ts | 81 ++++++++++++++++ .../template/stories/globals.stories.ts | 4 +- .../toolbars/template/stories/preview.ts | 4 +- .../components/tabs/tabs.stories.tsx | 2 +- .../components/layout/Layout.stories.tsx | 6 +- .../mobile/about/MobileAbout.stories.tsx | 4 +- .../navigation/MobileNavigation.stories.tsx | 4 +- .../components/preview/Iframe.stories.tsx | 2 +- .../components/sidebar/Explorer.stories.tsx | 2 +- .../sidebar/FileSearchModal.stories.tsx | 2 +- .../components/sidebar/Tree.stories.tsx | 28 +++--- code/core/src/preview-api/Errors.stories.tsx | 2 +- .../theme-decorator/decorators.stories.ts | 4 +- .../blocks/src/examples/Button.stories.tsx | 2 +- ...uttonWithMetaDescriptionAsBoth.stories.tsx | 2 +- ...onWithMetaDescriptionAsComment.stories.tsx | 2 +- ...WithMetaDescriptionAsParameter.stories.tsx | 3 +- .../ButtonWithMetaSubtitleAsBoth.stories.tsx | 3 +- ...etaSubtitleAsComponentSubtitle.stories.tsx | 3 +- ...WithMetaSubtitleAsDocsSubtitle.stories.tsx | 3 +- .../src/examples/StoryParameters.stories.tsx | 3 +- code/package.json | 1 + 36 files changed, 350 insertions(+), 99 deletions(-) create mode 100644 code/addons/themes/template/stories/decorators.stories.ts create mode 100644 code/addons/themes/template/stories/globals.stories.ts create mode 100644 code/addons/themes/template/stories/parameters.stories.ts diff --git a/code/.storybook/main.ts b/code/.storybook/main.ts index 0f44dde28aa1..24c266d000de 100644 --- a/code/.storybook/main.ts +++ b/code/.storybook/main.ts @@ -68,6 +68,10 @@ const config: StorybookConfig = { directory: '../addons/toolbars/template/stories', titlePrefix: 'addons/toolbars', }, + { + directory: '../addons/themes/template/stories', + titlePrefix: 'addons/themes', + }, { directory: '../addons/onboarding/src', titlePrefix: 'addons/onboarding', @@ -83,6 +87,7 @@ const config: StorybookConfig = { ], addons: [ '@storybook/addon-links', + '@storybook/addon-themes', '@storybook/addon-essentials', '@storybook/addon-interactions', '@storybook/addon-storysource', diff --git a/code/.storybook/preview.tsx b/code/.storybook/preview.tsx index 1f66c2396d9d..9299f42052b3 100644 --- a/code/.storybook/preview.tsx +++ b/code/.storybook/preview.tsx @@ -166,7 +166,7 @@ export const decorators = [ * This decorator renders the stories side-by-side, stacked or default based on the theme switcher in the toolbar */ (StoryFn, { globals, playFunction, args, storyGlobals, parameters }) => { - let theme = globals.theme; + let theme = globals.sb_theme; let showPlayFnNotice = false; // this makes the decorator be out of 'phase' with the actually selected theme in the toolbar @@ -315,6 +315,9 @@ export const parameters = { viewport: { options: MINIMAL_VIEWPORTS, }, + themes: { + disable: true, + }, backgrounds: { options: { light: { name: 'light', value: '#edecec' }, diff --git a/code/addons/controls/template/stories/conditional.stories.ts b/code/addons/controls/template/stories/conditional.stories.ts index 32f795b63f16..ed3c51d8ba8e 100644 --- a/code/addons/controls/template/stories/conditional.stories.ts +++ b/code/addons/controls/template/stories/conditional.stories.ts @@ -54,9 +54,9 @@ export const ToggleExpandCollapse = { export const GlobalBased = { argTypes: { - ifThemeExists: { control: 'text', if: { global: 'theme' } }, - ifThemeNotExists: { control: 'text', if: { global: 'theme', exists: false } }, - ifLightTheme: { control: 'text', if: { global: 'theme', eq: 'light' } }, - ifNotLightTheme: { control: 'text', if: { global: 'theme', neq: 'light' } }, + ifThemeExists: { control: 'text', if: { global: 'sb_theme' } }, + ifThemeNotExists: { control: 'text', if: { global: 'sb_theme', exists: false } }, + ifLightTheme: { control: 'text', if: { global: 'sb_theme', eq: 'light' } }, + ifNotLightTheme: { control: 'text', if: { global: 'sb_theme', neq: 'light' } }, }, }; diff --git a/code/addons/interactions/src/components/Interaction.stories.tsx b/code/addons/interactions/src/components/Interaction.stories.tsx index 731d5dca8f0b..98f579090986 100644 --- a/code/addons/interactions/src/components/Interaction.stories.tsx +++ b/code/addons/interactions/src/components/Interaction.stories.tsx @@ -54,7 +54,7 @@ export const Disabled: Story = { export const Hovered: Story = { ...Done, - globals: { theme: 'light' }, + globals: { sb_theme: 'light' }, play: async ({ canvasElement }) => { const canvas = within(canvasElement); await userEvent.hover(canvas.getByRole('button')); diff --git a/code/addons/interactions/src/components/InteractionsPanel.stories.tsx b/code/addons/interactions/src/components/InteractionsPanel.stories.tsx index 3d673e2605b0..322c3a416001 100644 --- a/code/addons/interactions/src/components/InteractionsPanel.stories.tsx +++ b/code/addons/interactions/src/components/InteractionsPanel.stories.tsx @@ -34,7 +34,7 @@ const meta = { ), ], parameters: { layout: 'fullscreen' }, - globals: { theme: 'light' }, + globals: { sb_theme: 'light' }, args: { calls: new Map(getCalls(CallStates.DONE).map((call) => [call.id, call])), controls: SubnavStories.args.controls, diff --git a/code/addons/interactions/template/stories/basics.stories.ts b/code/addons/interactions/template/stories/basics.stories.ts index 76112af830c1..459471817711 100644 --- a/code/addons/interactions/template/stories/basics.stories.ts +++ b/code/addons/interactions/template/stories/basics.stories.ts @@ -15,7 +15,7 @@ export default { onSuccess: fn(), }, globals: { - theme: 'light', + sb_theme: 'light', }, }; diff --git a/code/addons/themes/src/constants.ts b/code/addons/themes/src/constants.ts index 677c9499a7b4..654cc57ea893 100644 --- a/code/addons/themes/src/constants.ts +++ b/code/addons/themes/src/constants.ts @@ -15,6 +15,7 @@ export const DEFAULT_ADDON_STATE: ThemeAddonState = { export interface ThemeParameters { themeOverride?: string; + disable?: boolean; } export const DEFAULT_THEME_PARAMETERS: ThemeParameters = {}; diff --git a/code/addons/themes/src/decorators/class-name.decorator.tsx b/code/addons/themes/src/decorators/class-name.decorator.tsx index b8ebe8c89810..4bc56202f038 100644 --- a/code/addons/themes/src/decorators/class-name.decorator.tsx +++ b/code/addons/themes/src/decorators/class-name.decorator.tsx @@ -14,7 +14,7 @@ const DEFAULT_ELEMENT_SELECTOR = 'html'; const classStringToArray = (classString: string) => classString.split(' ').filter(Boolean); // TODO check with @kasperpeulen: change the types so they can be correctly inferred from context e.g. any> -export const withThemeByClassName = ({ +export const withThemeByClassName = ({ themes, defaultTheme, parentSelector = DEFAULT_ELEMENT_SELECTOR, @@ -47,7 +47,7 @@ export const withThemeByClassName = ({ if (newThemeClasses.length > 0) { parentElement.classList.add(...newThemeClasses); } - }, [themeOverride, selected, parentSelector]); + }, [themeOverride, selected]); return storyFn(); }; diff --git a/code/addons/themes/src/decorators/data-attribute.decorator.tsx b/code/addons/themes/src/decorators/data-attribute.decorator.tsx index dee9988ec7d0..05ad62792e7c 100644 --- a/code/addons/themes/src/decorators/data-attribute.decorator.tsx +++ b/code/addons/themes/src/decorators/data-attribute.decorator.tsx @@ -31,7 +31,7 @@ export const withThemeByDataAttribute = ({ if (parentElement) { parentElement.setAttribute(attributeName, themes[themeKey]); } - }, [themeOverride, selected, parentSelector, attributeName]); + }, [themeOverride, selected]); return storyFn(); }; diff --git a/code/addons/themes/src/decorators/provider.decorator.tsx b/code/addons/themes/src/decorators/provider.decorator.tsx index 09eb5824c488..f8b477810035 100644 --- a/code/addons/themes/src/decorators/provider.decorator.tsx +++ b/code/addons/themes/src/decorators/provider.decorator.tsx @@ -38,7 +38,7 @@ export const withThemeFromJSXProvider = ({ const pairs = Object.entries(themes); return pairs.length === 1 ? pluckThemeFromKeyPairTuple(pairs[0]) : themes[selectedThemeName]; - }, [themes, selected, themeOverride]); + }, [selected, themeOverride]); if (!Provider) { return ( diff --git a/code/addons/themes/src/preview.tsx b/code/addons/themes/src/preview.tsx index 28c52bdbb57a..6f4a444e7f7c 100644 --- a/code/addons/themes/src/preview.tsx +++ b/code/addons/themes/src/preview.tsx @@ -1,7 +1,6 @@ import type { Renderer, ProjectAnnotations } from 'storybook/internal/types'; -import { GLOBAL_KEY } from './constants'; +import { GLOBAL_KEY as KEY } from './constants'; -export const globals: ProjectAnnotations['globals'] = { - // Required to make sure SB picks this up from URL params - [GLOBAL_KEY]: '', +export const initialGlobals: ProjectAnnotations['initialGlobals'] = { + [KEY]: '', }; diff --git a/code/addons/themes/src/theme-switcher.tsx b/code/addons/themes/src/theme-switcher.tsx index bbc836177ea0..d57b9ce1e5e8 100644 --- a/code/addons/themes/src/theme-switcher.tsx +++ b/code/addons/themes/src/theme-switcher.tsx @@ -1,4 +1,4 @@ -import React, { Fragment, useMemo } from 'react'; +import React from 'react'; import { useAddonState, useChannel, @@ -17,6 +17,7 @@ import { THEMING_EVENTS, DEFAULT_ADDON_STATE, DEFAULT_THEME_PARAMETERS, + GLOBAL_KEY as KEY, } from './constants'; const IconButtonLabel = styled.div(({ theme }) => ({ @@ -27,11 +28,11 @@ const hasMultipleThemes = (themesList: ThemeAddonState['themesList']) => themesL const hasTwoThemes = (themesList: ThemeAddonState['themesList']) => themesList.length === 2; export const ThemeSwitcher = React.memo(function ThemeSwitcher() { - const { themeOverride } = useParameter( + const { themeOverride, disable } = useParameter( PARAM_KEY, DEFAULT_THEME_PARAMETERS ) as ThemeParameters; - const [{ theme: selected }, updateGlobals] = useGlobals(); + const [{ theme: selected }, updateGlobals, storyGlobals] = useGlobals(); const channel = addons.getChannel(); const fromLast = channel.last(THEMING_EVENTS.REGISTER_THEMES); @@ -45,6 +46,8 @@ export const ThemeSwitcher = React.memo(function ThemeSwitcher() { initializeThemeState ); + const isLocked = KEY in storyGlobals || !!themeOverride; + useChannel({ [THEMING_EVENTS.REGISTER_THEMES]: ({ themes, defaultTheme }) => { updateState((state) => ({ @@ -55,21 +58,24 @@ export const ThemeSwitcher = React.memo(function ThemeSwitcher() { }, }); - const label = useMemo(() => { - if (themeOverride) { - return <>Story override; - } - - const themeName = selected || themeDefault; + const themeName = selected || themeDefault; + let label = ''; + if (isLocked) { + label = 'Story override'; + } else if (themeName) { + label = `${themeName} theme`; + } - return themeName && <>{`${themeName} theme`}; - }, [themeOverride, themeDefault, selected]); + if (disable) { + return null; + } if (hasTwoThemes(themesList)) { const currentTheme = selected || themeDefault; const alternateTheme = themesList.find((theme) => theme !== currentTheme); return ( - {label && {label}} + {label ? {label} : null} ); } if (hasMultipleThemes(themesList)) { return ( - - { - return ( - ({ - id: theme, - title: theme, - active: selected === theme, - onClick: () => { - updateGlobals({ theme }); - onHide(); - }, - }))} - /> - ); - }} + { + return ( + ({ + id: theme, + title: theme, + active: selected === theme, + onClick: () => { + updateGlobals({ theme }); + onHide(); + }, + }))} + /> + ); + }} + > + - - - {label && {label}} - - - + + {label && {label}} + + ); } diff --git a/code/addons/themes/template/stories/decorators.stories.ts b/code/addons/themes/template/stories/decorators.stories.ts new file mode 100644 index 000000000000..b5ac268e6956 --- /dev/null +++ b/code/addons/themes/template/stories/decorators.stories.ts @@ -0,0 +1,93 @@ +import { global as globalThis } from '@storybook/global'; +import { + withThemeByClassName, + withThemeByDataAttribute, + withThemeFromJSXProvider, +} from '@storybook/addon-themes'; +import { useEffect } from 'storybook/internal/preview-api'; + +const cleanup = () => { + const existing = globalThis.document.querySelector('style[data-theme-css]'); + if (existing) { + existing.remove(); + } +}; + +const addStyleSheetDecorator = (storyFn: any) => { + useEffect(() => { + cleanup(); + + const sheet = globalThis.document.createElement('style'); + sheet.setAttribute('data-theme-css', ''); + sheet.textContent = ` + [data-theme="theme-a"], .theme-a { + background-color: white; + color: black; + } + [data-theme="theme-b"], .theme-b { + background-color: black; + color: white; + } + `; + + globalThis.document.body.appendChild(sheet); + + return cleanup; + }); + + return storyFn(); +}; + +export default { + component: globalThis.Components.Pre, + args: { + text: 'Testing the themes', + }, + parameters: { + chromatic: { disable: true }, + themes: { disable: false }, + }, + decorators: [addStyleSheetDecorator], +}; + +export const WithThemeByClassName = { + globals: {}, + decorators: [ + withThemeByClassName({ + defaultTheme: 'a', + themes: { a: 'theme-a', b: 'theme-b' }, + parentSelector: '#storybook-root > *', + }), + ], +}; + +export const WithThemeByDataAttribute = { + globals: {}, + decorators: [ + withThemeByDataAttribute({ + defaultTheme: 'a', + themes: { a: 'theme-a', b: 'theme-b' }, + parentSelector: '#storybook-root > *', + }), + ], +}; + +export const WithThemeFromJSXProvider = { + globals: {}, + decorators: [ + withThemeFromJSXProvider({ + defaultTheme: 'a', + themes: { a: { custom: 'theme-a' }, b: { custom: 'theme-b' } }, + Provider: ({ theme, children }: any) => { + // this is not was a normal provider looks like obviously, but this needs to work in non-react as well + // the timeout is to wait for the render to complete, as it's not possible to use the useEffect hook here + setTimeout(() => { + const element = globalThis.document.querySelector('#storybook-root > *'); + element?.classList.remove('theme-a', 'theme-b'); + element?.classList.add(theme.custom); + }, 16); + return children; + }, + }), + ], +}; diff --git a/code/addons/themes/template/stories/globals.stories.ts b/code/addons/themes/template/stories/globals.stories.ts new file mode 100644 index 000000000000..d18025328edc --- /dev/null +++ b/code/addons/themes/template/stories/globals.stories.ts @@ -0,0 +1,64 @@ +import { global as globalThis } from '@storybook/global'; +import { + withThemeByClassName, + withThemeByDataAttribute, + withThemeFromJSXProvider, +} from '@storybook/addon-themes'; +import { useEffect } from 'storybook/internal/preview-api'; + +const cleanup = () => { + const existing = globalThis.document.querySelector('style[data-theme-css]'); + if (existing) { + existing.remove(); + } +}; + +const addStyleSheetDecorator = (storyFn: any) => { + useEffect(() => { + cleanup(); + + const sheet = globalThis.document.createElement('style'); + sheet.setAttribute('data-theme-css', ''); + sheet.textContent = ` + [data-theme="theme-a"], .theme-a { + background-color: white; + color: black; + } + [data-theme="theme-b"], .theme-b { + background-color: black; + color: white; + } + `; + + globalThis.document.body.appendChild(sheet); + + return cleanup; + }); + + return storyFn(); +}; + +export default { + component: globalThis.Components.Pre, + args: { + text: 'Testing the themes', + }, + parameters: { + chromatic: { disable: true }, + themes: { disable: false }, + }, + decorators: [addStyleSheetDecorator], +}; + +export const SetGlobal = { + globals: { + theme: 'b', + }, + decorators: [ + withThemeByClassName({ + defaultTheme: 'a', + themes: { a: 'theme-a', b: 'theme-b' }, + parentSelector: '#storybook-root > *', + }), + ], +}; diff --git a/code/addons/themes/template/stories/parameters.stories.ts b/code/addons/themes/template/stories/parameters.stories.ts new file mode 100644 index 000000000000..acf9171d5ac2 --- /dev/null +++ b/code/addons/themes/template/stories/parameters.stories.ts @@ -0,0 +1,81 @@ +import { global as globalThis } from '@storybook/global'; +import { + withThemeByClassName, + withThemeByDataAttribute, + withThemeFromJSXProvider, +} from '@storybook/addon-themes'; +import { useEffect } from 'storybook/internal/preview-api'; + +const cleanup = () => { + const existing = globalThis.document.querySelector('style[data-theme-css]'); + if (existing) { + existing.remove(); + } +}; + +const addStyleSheetDecorator = (storyFn: any) => { + useEffect(() => { + cleanup(); + + const sheet = globalThis.document.createElement('style'); + sheet.setAttribute('data-theme-css', ''); + sheet.textContent = ` + [data-theme="theme-a"], .theme-a { + background-color: white; + color: black; + } + [data-theme="theme-b"], .theme-b { + background-color: black; + color: white; + } + `; + + globalThis.document.body.appendChild(sheet); + + return cleanup; + }); + + return storyFn(); +}; + +export default { + component: globalThis.Components.Pre, + args: { + text: 'Testing the themes', + }, + parameters: { + chromatic: { disable: true }, + themes: { disable: false }, + }, + decorators: [addStyleSheetDecorator], +}; + +export const SetOverride = { + parameters: { + themes: { + themeOverride: 'b', + }, + }, + decorators: [ + withThemeByClassName({ + defaultTheme: 'a', + themes: { a: 'theme-a', b: 'theme-b' }, + parentSelector: '#storybook-root > *', + }), + ], +}; + +export const Disabled = { + parameters: { + themes: { + disable: true, + }, + }, + decorators: [ + withThemeByClassName({ + defaultTheme: 'a', + themes: { a: 'theme-a', b: 'theme-b' }, + parentSelector: '#storybook-root > *', + }), + ], +}; diff --git a/code/addons/toolbars/template/stories/globals.stories.ts b/code/addons/toolbars/template/stories/globals.stories.ts index 0dd6a353dd84..dd5b52ddece0 100644 --- a/code/addons/toolbars/template/stories/globals.stories.ts +++ b/code/addons/toolbars/template/stories/globals.stories.ts @@ -40,13 +40,13 @@ export const OverrideLocale = { export const OverrideTheme = { globals: { - theme: 'dark', + sb_theme: 'dark', }, }; export const OverrideBoth = { globals: { locale: 'kr', - theme: 'dark', + sb_theme: 'dark', }, }; diff --git a/code/addons/toolbars/template/stories/preview.ts b/code/addons/toolbars/template/stories/preview.ts index 0df95d7080d1..fe2f2531df93 100644 --- a/code/addons/toolbars/template/stories/preview.ts +++ b/code/addons/toolbars/template/stories/preview.ts @@ -1,5 +1,5 @@ export const globalTypes = { - theme: { + sb_theme: { name: 'Theme', description: 'Global theme for components', toolbar: { @@ -44,6 +44,6 @@ export const globalTypes = { }; export const initialGlobals = { - theme: 'light', + sb_theme: 'light', locale: 'en', }; diff --git a/code/core/src/components/components/tabs/tabs.stories.tsx b/code/core/src/components/components/tabs/tabs.stories.tsx index 1e8994ca0503..1958c3e18555 100644 --- a/code/core/src/components/components/tabs/tabs.stories.tsx +++ b/code/core/src/components/components/tabs/tabs.stories.tsx @@ -181,7 +181,7 @@ export const StatefulDynamicWithOpenTooltip = { }, chromatic: { viewports: [380] }, }, - globals: { theme: 'light', viewport: 'sized' }, + globals: { sb_theme: 'light', viewport: 'sized' }, play: async ({ canvasElement }) => { const canvas = within(canvasElement); diff --git a/code/core/src/manager/components/layout/Layout.stories.tsx b/code/core/src/manager/components/layout/Layout.stories.tsx index 7240c364b50b..8282d8434587 100644 --- a/code/core/src/manager/components/layout/Layout.stories.tsx +++ b/code/core/src/manager/components/layout/Layout.stories.tsx @@ -63,7 +63,7 @@ const meta = { setManagerLayoutState: fn(), hasTab: false, }, - globals: { theme: 'light' }, + globals: { sb_theme: 'light' }, parameters: { layout: 'fullscreen' }, decorators: [ MobileNavigationStoriesMeta.decorators[0] as any, @@ -95,7 +95,7 @@ type Story = StoryObj; export const Desktop: Story = {}; export const Dark: Story = { - globals: { theme: 'dark' }, + globals: { sb_theme: 'dark' }, }; export const DesktopHorizontal: Story = { args: { @@ -125,7 +125,7 @@ export const Mobile = { }; export const MobileDark = { ...Mobile, - globals: { theme: 'dark' }, + globals: { sb_theme: 'dark' }, }; export const MobileDocs = { diff --git a/code/core/src/manager/components/mobile/about/MobileAbout.stories.tsx b/code/core/src/manager/components/mobile/about/MobileAbout.stories.tsx index 27a8c1197d43..e552171cca4b 100644 --- a/code/core/src/manager/components/mobile/about/MobileAbout.stories.tsx +++ b/code/core/src/manager/components/mobile/about/MobileAbout.stories.tsx @@ -19,7 +19,7 @@ const OpenAboutHelper = ({ children }: { children: any }) => { const meta = { component: MobileAbout, title: 'Mobile/About', - globals: { theme: 'light' }, + globals: { sb_theme: 'light' }, parameters: { layout: 'fullscreen', viewport: { @@ -56,7 +56,7 @@ type Story = StoryObj; export const Default: Story = {}; export const Dark: Story = { - globals: { theme: 'dark' }, + globals: { sb_theme: 'dark' }, }; export const Closed: Story = { diff --git a/code/core/src/manager/components/mobile/navigation/MobileNavigation.stories.tsx b/code/core/src/manager/components/mobile/navigation/MobileNavigation.stories.tsx index 5d0b8fe8a4ab..552556add58c 100644 --- a/code/core/src/manager/components/mobile/navigation/MobileNavigation.stories.tsx +++ b/code/core/src/manager/components/mobile/navigation/MobileNavigation.stories.tsx @@ -86,10 +86,10 @@ export default meta; type Story = StoryObj; export const Default: Story = { - globals: { theme: 'light' }, + globals: { sb_theme: 'light' }, }; export const Dark: Story = { - globals: { theme: 'dark' }, + globals: { sb_theme: 'dark' }, parameters: { chromatic: { disable: true } }, }; diff --git a/code/core/src/manager/components/preview/Iframe.stories.tsx b/code/core/src/manager/components/preview/Iframe.stories.tsx index 7d95583f3b54..ba63911b6f71 100644 --- a/code/core/src/manager/components/preview/Iframe.stories.tsx +++ b/code/core/src/manager/components/preview/Iframe.stories.tsx @@ -22,7 +22,7 @@ export default { }, chromatic: { viewports: [700] }, }, - globals: { theme: 'light' }, + globals: { sb_theme: 'light' }, }; const style: CSSProperties = { diff --git a/code/core/src/manager/components/sidebar/Explorer.stories.tsx b/code/core/src/manager/components/sidebar/Explorer.stories.tsx index 813163595329..9cf8c887397f 100644 --- a/code/core/src/manager/components/sidebar/Explorer.stories.tsx +++ b/code/core/src/manager/components/sidebar/Explorer.stories.tsx @@ -9,7 +9,7 @@ import { IconSymbols } from './IconSymbols'; export default { component: Explorer, title: 'Sidebar/Explorer', - globals: { theme: 'side-by-side' }, + globals: { sb_theme: 'side-by-side' }, parameters: { layout: 'fullscreen' }, decorators: [ RefStories.default.decorators[0], diff --git a/code/core/src/manager/components/sidebar/FileSearchModal.stories.tsx b/code/core/src/manager/components/sidebar/FileSearchModal.stories.tsx index e419bd2b57ab..c86f3729f63c 100644 --- a/code/core/src/manager/components/sidebar/FileSearchModal.stories.tsx +++ b/code/core/src/manager/components/sidebar/FileSearchModal.stories.tsx @@ -19,7 +19,7 @@ const meta = { (Story, context) => { const [container, setContainer] = useState(null); - if (context.globals.theme === 'side-by-side') { + if (context.globals.sb_theme === 'side-by-side') { return (
{ diff --git a/code/core/src/manager/components/sidebar/Tree.stories.tsx b/code/core/src/manager/components/sidebar/Tree.stories.tsx index 7b8ba3ae817c..dfc2a9e41910 100644 --- a/code/core/src/manager/components/sidebar/Tree.stories.tsx +++ b/code/core/src/manager/components/sidebar/Tree.stories.tsx @@ -8,27 +8,27 @@ import { within, expect } from '@storybook/test'; import { Tree } from './Tree'; import { index } from './mockdata.large'; import { DEFAULT_REF_ID } from './Sidebar'; -import { viewport } from '@popperjs/core'; - -const customViewports = { - sized: { - name: 'Sized', - styles: { - width: '380px', - height: '90%', - }, - }, -}; const meta = { component: Tree, title: 'Sidebar/Tree', excludeStories: /.*Data$/, - globals: { theme: 'light', viewport: 'sized', viewportRotated: false }, + globals: { + sb_theme: 'light', + viewport: { value: 'sized' }, + }, parameters: { layout: 'fullscreen', viewport: { - viewports: customViewports, + viewports: { + sized: { + name: 'Sized', + styles: { + width: '380px', + height: '90%', + }, + }, + }, }, chromatic: { viewports: [380] }, }, @@ -64,7 +64,7 @@ export const Full: Story = { }; export const Dark: Story = { ...Full, - globals: { theme: 'dark' }, + globals: { sb_theme: 'dark' }, }; export const SingleStoryComponents: Story = { diff --git a/code/core/src/preview-api/Errors.stories.tsx b/code/core/src/preview-api/Errors.stories.tsx index 53147f848611..231905e9bca5 100644 --- a/code/core/src/preview-api/Errors.stories.tsx +++ b/code/core/src/preview-api/Errors.stories.tsx @@ -40,7 +40,7 @@ export default { parameters: { layout: 'fullscreen', }, - globals: { theme: 'light' }, + globals: { sb_theme: 'light' }, title: 'Errors', args: { id: 'sb-errordisplay', diff --git a/code/frameworks/angular/template/stories/core/decorators/theme-decorator/decorators.stories.ts b/code/frameworks/angular/template/stories/core/decorators/theme-decorator/decorators.stories.ts index 11bba5843353..71bb347eac71 100644 --- a/code/frameworks/angular/template/stories/core/decorators/theme-decorator/decorators.stories.ts +++ b/code/frameworks/angular/template/stories/core/decorators/theme-decorator/decorators.stories.ts @@ -1,7 +1,7 @@ import { Args, Meta, componentWrapperDecorator } from '@storybook/angular'; export const Base = (args: Args) => ({ - template: 'Change theme with the brush in toolbar', + template: 'Change sb_theme with the brush in toolbar', props: { ...args, }, @@ -14,7 +14,7 @@ export default { componentWrapperDecorator( (story) => `
${story}
`, - ({ globals }) => ({ myTheme: `${globals['theme']}-theme` }) + ({ globals }) => ({ myTheme: `${globals['sb_theme']}-theme` }) ), ], } as Meta; diff --git a/code/lib/blocks/src/examples/Button.stories.tsx b/code/lib/blocks/src/examples/Button.stories.tsx index a7fac335a7c2..71678472a9e7 100644 --- a/code/lib/blocks/src/examples/Button.stories.tsx +++ b/code/lib/blocks/src/examples/Button.stories.tsx @@ -12,7 +12,7 @@ const meta = { backgroundColor: { control: 'color' }, }, // Stop *this* story from being stacked in Chromatic - globals: { theme: 'default' }, + globals: { sb_theme: 'default' }, parameters: { // these are to test the deprecated features of the Description block notes: 'These are notes for the Button stories', diff --git a/code/lib/blocks/src/examples/ButtonWithMetaDescriptionAsBoth.stories.tsx b/code/lib/blocks/src/examples/ButtonWithMetaDescriptionAsBoth.stories.tsx index 84596bac72e9..38c70ac80a86 100644 --- a/code/lib/blocks/src/examples/ButtonWithMetaDescriptionAsBoth.stories.tsx +++ b/code/lib/blocks/src/examples/ButtonWithMetaDescriptionAsBoth.stories.tsx @@ -14,7 +14,7 @@ const meta = { backgroundColor: { control: 'color' }, }, // Stop *this* story from being stacked in Chromatic - globals: { theme: 'default' }, + globals: { sb_theme: 'default' }, parameters: { docs: { description: { diff --git a/code/lib/blocks/src/examples/ButtonWithMetaDescriptionAsComment.stories.tsx b/code/lib/blocks/src/examples/ButtonWithMetaDescriptionAsComment.stories.tsx index 4fb7a5ad5d3a..3060eb59cbfc 100644 --- a/code/lib/blocks/src/examples/ButtonWithMetaDescriptionAsComment.stories.tsx +++ b/code/lib/blocks/src/examples/ButtonWithMetaDescriptionAsComment.stories.tsx @@ -13,7 +13,7 @@ const meta = { backgroundColor: { control: 'color' }, }, // Stop *this* story from being stacked in Chromatic - globals: { theme: 'default' }, + globals: { sb_theme: 'light' }, } satisfies Meta; export default meta; diff --git a/code/lib/blocks/src/examples/ButtonWithMetaDescriptionAsParameter.stories.tsx b/code/lib/blocks/src/examples/ButtonWithMetaDescriptionAsParameter.stories.tsx index ce59432f86dd..e4de6047b668 100644 --- a/code/lib/blocks/src/examples/ButtonWithMetaDescriptionAsParameter.stories.tsx +++ b/code/lib/blocks/src/examples/ButtonWithMetaDescriptionAsParameter.stories.tsx @@ -7,8 +7,7 @@ const meta = { argTypes: { backgroundColor: { control: 'color' }, }, - // Stop *this* story from being stacked in Chromatic - globals: { theme: 'default' }, + globals: { sb_theme: 'light' }, parameters: { docs: { description: { diff --git a/code/lib/blocks/src/examples/ButtonWithMetaSubtitleAsBoth.stories.tsx b/code/lib/blocks/src/examples/ButtonWithMetaSubtitleAsBoth.stories.tsx index ebae54acd1dd..04a6cec92d54 100644 --- a/code/lib/blocks/src/examples/ButtonWithMetaSubtitleAsBoth.stories.tsx +++ b/code/lib/blocks/src/examples/ButtonWithMetaSubtitleAsBoth.stories.tsx @@ -7,8 +7,7 @@ const meta = { argTypes: { backgroundColor: { control: 'color' }, }, - // Stop *this* story from being stacked in Chromatic - globals: { theme: 'default' }, + globals: { sb_theme: 'light' }, parameters: { // this is to test the deprecated features of the Subtitle block componentSubtitle: 'This subtitle is set in parameters.componentSubtitle', diff --git a/code/lib/blocks/src/examples/ButtonWithMetaSubtitleAsComponentSubtitle.stories.tsx b/code/lib/blocks/src/examples/ButtonWithMetaSubtitleAsComponentSubtitle.stories.tsx index f4df18d010e6..11ee4d719169 100644 --- a/code/lib/blocks/src/examples/ButtonWithMetaSubtitleAsComponentSubtitle.stories.tsx +++ b/code/lib/blocks/src/examples/ButtonWithMetaSubtitleAsComponentSubtitle.stories.tsx @@ -7,8 +7,7 @@ const meta = { argTypes: { backgroundColor: { control: 'color' }, }, - // Stop *this* story from being stacked in Chromatic - globals: { theme: 'default' }, + globals: { sb_theme: 'light' }, parameters: { // this is to test the deprecated features of the Subtitle block componentSubtitle: 'This subtitle is set in parameters.componentSubtitle', diff --git a/code/lib/blocks/src/examples/ButtonWithMetaSubtitleAsDocsSubtitle.stories.tsx b/code/lib/blocks/src/examples/ButtonWithMetaSubtitleAsDocsSubtitle.stories.tsx index 971bd1d123db..a36e8ce3bbcb 100644 --- a/code/lib/blocks/src/examples/ButtonWithMetaSubtitleAsDocsSubtitle.stories.tsx +++ b/code/lib/blocks/src/examples/ButtonWithMetaSubtitleAsDocsSubtitle.stories.tsx @@ -7,8 +7,7 @@ const meta = { argTypes: { backgroundColor: { control: 'color' }, }, - // Stop *this* story from being stacked in Chromatic - globals: { theme: 'default' }, + globals: { sb_theme: 'light' }, parameters: { docs: { subtitle: 'This subtitle is set in parameters.docs.subtitle', diff --git a/code/lib/blocks/src/examples/StoryParameters.stories.tsx b/code/lib/blocks/src/examples/StoryParameters.stories.tsx index a8bc66c9e04b..62f5c545df9e 100644 --- a/code/lib/blocks/src/examples/StoryParameters.stories.tsx +++ b/code/lib/blocks/src/examples/StoryParameters.stories.tsx @@ -4,8 +4,7 @@ import { SimpleSizeTest } from './SimpleSizeTest'; const meta = { title: 'examples/Stories for the Story Block', component: SimpleSizeTest, - // Stop *this* story from being stacked in Chromatic (we want the caller to stack though) - globals: { theme: 'default' }, + globals: { sb_theme: 'light' }, } satisfies Meta; export default meta; diff --git a/code/package.json b/code/package.json index 34e857d4681e..fc4a1c93c6ab 100644 --- a/code/package.json +++ b/code/package.json @@ -108,6 +108,7 @@ "@storybook/addon-onboarding": "workspace:*", "@storybook/addon-outline": "workspace:*", "@storybook/addon-storysource": "workspace:*", + "@storybook/addon-themes": "workspace:*", "@storybook/addon-toolbars": "workspace:*", "@storybook/addon-viewport": "workspace:*", "@storybook/angular": "workspace:*", From 6a273c172ba30a959bb6fddcde2d1897470be101 Mon Sep 17 00:00:00 2001 From: Norbert de Langen Date: Wed, 31 Jul 2024 16:02:25 +0200 Subject: [PATCH 02/13] fix lockfile --- code/yarn.lock | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/code/yarn.lock b/code/yarn.lock index 8eea5e0814e1..4b2b7b5fc5b9 100644 --- a/code/yarn.lock +++ b/code/yarn.lock @@ -5382,7 +5382,7 @@ __metadata: languageName: unknown linkType: soft -"@storybook/addon-themes@workspace:addons/themes": +"@storybook/addon-themes@workspace:*, @storybook/addon-themes@workspace:addons/themes": version: 0.0.0-use.local resolution: "@storybook/addon-themes@workspace:addons/themes" dependencies: @@ -6499,6 +6499,7 @@ __metadata: "@storybook/addon-onboarding": "workspace:*" "@storybook/addon-outline": "workspace:*" "@storybook/addon-storysource": "workspace:*" + "@storybook/addon-themes": "workspace:*" "@storybook/addon-toolbars": "workspace:*" "@storybook/addon-viewport": "workspace:*" "@storybook/angular": "workspace:*" From f621766c44b3545ec3d5756a05308c8180a1f6d1 Mon Sep 17 00:00:00 2001 From: Norbert de Langen Date: Wed, 31 Jul 2024 16:58:25 +0200 Subject: [PATCH 03/13] fix --- code/core/src/manager/components/sidebar/Tree.stories.tsx | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/code/core/src/manager/components/sidebar/Tree.stories.tsx b/code/core/src/manager/components/sidebar/Tree.stories.tsx index dfc2a9e41910..ab965dfb7d51 100644 --- a/code/core/src/manager/components/sidebar/Tree.stories.tsx +++ b/code/core/src/manager/components/sidebar/Tree.stories.tsx @@ -20,7 +20,7 @@ const meta = { parameters: { layout: 'fullscreen', viewport: { - viewports: { + options: { sized: { name: 'Sized', styles: { @@ -206,11 +206,6 @@ export const SkipToCanvasLinkFocused: Story = { ...DocsOnlySingleStoryComponents, parameters: { chromatic: { disable: true }, - viewport: { - defaultViewport: 'sized', - viewports: customViewports, - defaultOrientation: 'landscape', - }, }, play: async ({ canvasElement }) => { const screen = await within(canvasElement); From 690368d8f4570288bb153630c287ca5bd983e0c7 Mon Sep 17 00:00:00 2001 From: Norbert de Langen Date: Wed, 31 Jul 2024 18:22:45 +0200 Subject: [PATCH 04/13] improvements --- code/.storybook/preview.tsx | 50 +++++++++++++------ .../template/stories/decorators.stories.ts | 3 ++ .../template/stories/globals.stories.ts | 9 ++-- .../template/stories/parameters.stories.ts | 9 ++-- code/lib/blocks/src/blocks/Anchor.stories.tsx | 1 + .../blocks/src/blocks/ArgTypes.stories.tsx | 1 + code/lib/blocks/src/blocks/Canvas.stories.tsx | 1 + .../blocks/src/blocks/Controls.stories.tsx | 1 + .../blocks/src/blocks/Description.stories.tsx | 1 + .../blocks/src/blocks/DocsPage.stories.tsx | 1 + .../blocks/src/blocks/Markdown.stories.tsx | 5 +- .../lib/blocks/src/blocks/Primary.stories.tsx | 1 + code/lib/blocks/src/blocks/Source.stories.tsx | 1 + .../lib/blocks/src/blocks/Stories.stories.tsx | 5 +- code/lib/blocks/src/blocks/Story.stories.tsx | 1 + .../blocks/src/blocks/Subtitle.stories.tsx | 1 + code/lib/blocks/src/blocks/Title.stories.tsx | 1 + .../components/ArgsTable/ArgRow.stories.tsx | 1 + 18 files changed, 67 insertions(+), 26 deletions(-) diff --git a/code/.storybook/preview.tsx b/code/.storybook/preview.tsx index 9299f42052b3..846a858ed75f 100644 --- a/code/.storybook/preview.tsx +++ b/code/.storybook/preview.tsx @@ -34,7 +34,7 @@ const ThemeBlock = styled.div<{ side: 'left' | 'right'; layout: string }>( overflow: 'auto', }, ({ layout }) => ({ - padding: layout === 'fullscreen' ? 0 : 10, + padding: layout === 'fullscreen' ? 0 : '1rem', }), ({ theme }) => ({ background: theme.background.content, @@ -55,14 +55,15 @@ const ThemeBlock = styled.div<{ side: 'left' | 'right'; layout: string }>( const ThemeStack = styled.div<{ layout: string }>( { position: 'relative', - minHeight: 'calc(50vh - 15px)', + // minHeight: 'calc(50vh - 15px)', + flex: 1, }, ({ theme }) => ({ background: theme.background.content, color: theme.color.defaultText, }), ({ layout }) => ({ - padding: layout === 'fullscreen' ? 0 : 10, + padding: layout === 'fullscreen' ? 0 : '1rem', }) ); @@ -86,6 +87,25 @@ const PlayFnNotice = styled.div( }) ); +const StackContainer = ({ children, layout }) => ( +
+