Skip to content

Commit

Permalink
Merge pull request #19886 from storybookjs/jeppe/sb-945-document-and-…
Browse files Browse the repository at this point in the history
…tweak-block-canvas

Blocks: Add story for Canvas `className` prop, cleanup UI SB `preview.tsx
  • Loading branch information
JReinhold authored Nov 28, 2022
2 parents 279053c + 4e18d38 commit 27ce3d4
Show file tree
Hide file tree
Showing 12 changed files with 82 additions and 67 deletions.
1 change: 1 addition & 0 deletions code/ui/.storybook/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ const config: StorybookConfig = {
'@storybook/addon-links',
'@storybook/addon-essentials',
'@storybook/addon-interactions',
'@storybook/addon-storysource',
],
framework: {
name: '@storybook/react-vite',
Expand Down
89 changes: 34 additions & 55 deletions code/ui/.storybook/preview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import { DocsContainer } from '../blocks/src/blocks/DocsContainer';

const { document } = global;

const ThemeBlock = styled.div(
const ThemeBlock = styled.div<{ side: 'left' | 'right' }>(
{
position: 'absolute',
top: 0,
Expand Down Expand Up @@ -84,9 +84,6 @@ const ThemedSetRoot = () => {
useEffect(() => {
document.body.style.background = theme.background.content;
document.body.style.color = theme.color.defaultText;
return () => {
//
};
});

return null;
Expand All @@ -96,24 +93,33 @@ const ThemedSetRoot = () => {
const preview = (window as any).__STORYBOOK_PREVIEW__ as PreviewWeb<ReactRenderer>;
const channel = (window as any).__STORYBOOK_ADDONS_CHANNEL__ as Channel;
export const loaders = [
async () => ({ globalValue: 1 }),

/**
* This loader adds a DocsContext to the story, which is required for the most Blocks to work.
* A story will specify which stories they need in the index with:
* parameters: {
* relativeCsfPaths: ['../stories/MyStory.stories.tsx'], // relative to the story
* }
* The DocsContext will then be added via the decorator below.
*/
async ({ parameters: { relativeCsfPaths } }) => {
if (!relativeCsfPaths) return {};

const csfFiles = await Promise.all(
(relativeCsfPaths as string[]).map(async (relativePath) => {
const webpackPath = `./ui/blocks/src/${relativePath.replace(/^..\//, '')}.tsx`;
const entry = preview.storyStore.storyIndex!.importPathToEntry(webpackPath);
(relativeCsfPaths as string[]).map(async (blocksRelativePath) => {
const projectRelativePath = `./ui/blocks/src/${blocksRelativePath.replace(
/^..\//,
''
)}.tsx`;
const entry = preview.storyStore.storyIndex?.importPathToEntry(projectRelativePath);

if (!entry) {
throw new Error(`Couldn't find story file at ${webpackPath} (passed as ${relativePath})`);
throw new Error(
`Couldn't find story file at ${projectRelativePath} (passed as ${blocksRelativePath})`
);
}

return preview.storyStore.loadCSFFileByStoryId(entry.id);
})
);

return {
docsContext: new DocsContext(
channel,
Expand All @@ -127,6 +133,7 @@ export const loaders = [
];

export const decorators = [
// This decorator adds the DocsContext created in the loader above
(Story, { loaded: { docsContext } }) =>
docsContext ? (
<DocsContainer context={docsContext}>
Expand All @@ -135,6 +142,19 @@ export const decorators = [
) : (
<Story />
),
/**
* This decorator adds Symbols that the sidebar icons references.
* Any sidebar story that uses the icons must set the parameter withSymbols: true .
*/
(Story, { parameters: { withSymbols } }) => (
<>
{withSymbols && <Symbols icons={['folder', 'component', 'document', 'bookmarkhollow']} />}
<Story />
</>
),
/**
* This decorator renders the stories side-by-side, stacked or default based on the theme switcher in the toolbar
*/
(StoryFn, { globals, parameters, playFunction }) => {
const defaultTheme = isChromatic() && !playFunction ? 'stacked' : 'light';
const theme = globals.theme || parameters.theme || defaultTheme;
Expand All @@ -143,7 +163,6 @@ export const decorators = [
case 'side-by-side': {
return (
<Fragment>
<Symbols icons={['folder', 'component', 'document', 'bookmarkhollow']} />
<ThemeProvider theme={convert(themes.light)}>
<Global styles={createReset} />
</ThemeProvider>
Expand All @@ -163,17 +182,16 @@ export const decorators = [
case 'stacked': {
return (
<Fragment>
<Symbols icons={['folder', 'component', 'document', 'bookmarkhollow']} />
<ThemeProvider theme={convert(themes.light)}>
<Global styles={createReset} />
</ThemeProvider>
<ThemeProvider theme={convert(themes.light)}>
<ThemeStack side="left" data-side="left">
<ThemeStack data-side="left">
<StoryFn />
</ThemeStack>
</ThemeProvider>
<ThemeProvider theme={convert(themes.dark)}>
<ThemeStack side="right" data-side="right">
<ThemeStack data-side="right">
<StoryFn />
</ThemeStack>
</ThemeProvider>
Expand All @@ -183,7 +201,6 @@ export const decorators = [
default: {
return (
<ThemeProvider theme={convert(themes[theme])}>
<Symbols icons={['folder', 'component', 'document', 'bookmarkhollow']} />
<Global styles={createReset} />
<ThemedSetRoot />
{!parameters.theme && isChromatic() && playFunction && (
Expand Down Expand Up @@ -232,7 +249,6 @@ export const decorators = [
];

export const parameters = {
exportedParameter: 'exportedParameter',
actions: { argTypesRegex: '^on.*' },
options: {
storySort: (a, b) =>
Expand Down Expand Up @@ -270,13 +286,7 @@ export const parameters = {
},
};

export const globals = {
foo: 'fooValue',
};

export const globalTypes = {
foo: { defaultValue: 'fooDefaultValue' },
bar: { defaultValue: 'barDefaultValue' },
theme: {
name: 'Theme',
description: 'Global theme for components',
Expand All @@ -291,35 +301,4 @@ export const globalTypes = {
],
},
},
locale: {
name: 'Locale',
description: 'Internationalization locale',
toolbar: {
icon: 'globe',
shortcuts: {
next: {
label: 'Go to next language',
keys: ['L'],
},
previous: {
label: 'Go to previous language',
keys: ['K'],
},
reset: {
label: 'Reset language',
keys: ['meta', 'shift', 'L'],
},
},
items: [
{ title: 'Reset locale', type: 'reset' },
{ value: 'en', right: '🇺🇸', title: 'English' },
{ value: 'es', right: '🇪🇸', title: 'Español' },
{ value: 'zh', right: '🇨🇳', title: '中文' },
{ value: 'kr', right: '🇰🇷', title: '한국어' },
],
},
},
};

export const argTypes = { color: { control: 'color' } };
export const args = { color: 'red' };
32 changes: 32 additions & 0 deletions code/ui/blocks/src/blocks/Canvas.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -81,3 +81,35 @@ export const WithAdditionalActions: Story = {
],
},
};

const ClassNameStoryDescripition = () => (
<p>
This story sets the <code>className</code> prop on the <code>Canvas</code> to{' '}
<code>my-custom-classname</code>, which will propagate to the preview element. To demonstrate
this, it also adds a <code>style</code> tag that sets another background color for that class:
</p>
);
/**
* This is a comment on classname
*/
export const ClassName: Story = {
name: 'ClassName',
args: {
className: 'my-custom-classname',
},
render: (args) => (
<>
<ClassNameStoryDescripition />
<style>
{`
.my-custom-classname {
background-color: #fd5c9355;
}
`}
</style>
<Canvas {...args}>
<StoryComponent of={BooleanStories.Undefined} />
</Canvas>
</>
),
};
2 changes: 1 addition & 1 deletion code/ui/blocks/src/blocks/Canvas.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { useStories } from './useStory';

export { SourceState };

type CanvasProps = Omit<PurePreviewProps, 'isExpanded'> & {
type CanvasProps = Omit<PurePreviewProps, 'isExpanded' | 'isLoading'> & {
withSource?: SourceState;
mdxSource?: string;
};
Expand Down
11 changes: 7 additions & 4 deletions code/ui/components/src/icon/icon.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -57,32 +57,35 @@ const Header = styled.h2`

export default {
component: Icons,
argTypes: {
color: { control: 'color' },
},
};

export const Basic = (args: ComponentProps<typeof Icons>) => <Icons {...args} />;
Basic.args = { icon: 'watch' };

export const Labels = () => (
export const Labels = (args: ComponentProps<typeof Icons>) => (
<>
<Header>{Object.keys(icons).length} icons</Header>
<List>
{Object.keys(icons).map((key) => (
<Item key={key}>
<Icons icon={key as IconKey} aria-hidden />
<Icons icon={key as IconKey} aria-hidden {...args} />
<Meta>{key}</Meta>
</Item>
))}
</List>
</>
);

export const NoLabels = () => (
export const NoLabels = (args: ComponentProps<typeof Icons>) => (
<>
<Header>{Object.keys(icons).length} icons</Header>
<List>
{Object.keys(icons).map((key) => (
<Item minimal key={key}>
<Icons icon={key as IconKey} aria-label={key} />
<Icons icon={key as IconKey} aria-label={key} {...args} />
</Item>
))}
</List>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import * as RefStories from './Refs.stories';
export default {
component: Explorer,
title: 'Sidebar/Explorer',
parameters: { layout: 'fullscreen' },
parameters: { layout: 'fullscreen', withSymbols: true },
decorators: [
RefStories.default.decorators[0],
(storyFn: any) => <div style={{ padding: '0 20px', maxWidth: '230px' }}>{storyFn()}</div>,
Expand Down
2 changes: 1 addition & 1 deletion code/ui/manager/src/components/sidebar/Refs.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export default {
component: Ref,
title: 'Sidebar/Refs',
excludeStories: /.*Data$/,
parameters: { layout: 'fullscreen' },
parameters: { layout: 'fullscreen', withSymbols: true },
decorators: [
(storyFn: any) => (
<ManagerContext.Provider value={{ state: { docsOptions: {} } } as any}>
Expand Down
2 changes: 1 addition & 1 deletion code/ui/manager/src/components/sidebar/Search.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ const getLastViewed = () =>
export default {
component: Search,
title: 'Sidebar/Search',
parameters: { layout: 'fullscreen' },
parameters: { layout: 'fullscreen', withSymbols: true },
decorators: [(storyFn: any) => <div style={{ padding: 20, maxWidth: '230px' }}>{storyFn()}</div>],
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export default {
component: SearchResults,
title: 'Sidebar/SearchResults',
includeStories: /^[A-Z]/,
parameters: { layout: 'fullscreen' },
parameters: { layout: 'fullscreen', withSymbols: true },
decorators: [
(storyFn: any) => <div style={{ padding: '0 20px', maxWidth: '230px' }}>{storyFn()}</div>,
],
Expand Down
2 changes: 1 addition & 1 deletion code/ui/manager/src/components/sidebar/Sidebar.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export default {
component: Sidebar,
title: 'Sidebar/Sidebar',
excludeStories: /.*Data$/,
parameters: { layout: 'fullscreen' },
parameters: { layout: 'fullscreen', withSymbols: true },
decorators: [
ExplorerStories.default.decorators[0],
(storyFn: any) => <div style={{ padding: '0 20px', maxWidth: '230px' }}>{storyFn()}</div>,
Expand Down
2 changes: 1 addition & 1 deletion code/ui/manager/src/components/sidebar/Tree.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export default {
component: Tree,
title: 'Sidebar/Tree',
excludeStories: /.*Data$/,
parameters: { layout: 'fullscreen' },
parameters: { layout: 'fullscreen', withSymbols: true },
decorators: [(storyFn: any) => <div style={{ maxWidth: '230px' }}>{storyFn()}</div>],
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { ComponentNode, DocumentNode, GroupNode, StoryNode } from './TreeNode';

export default {
title: 'Sidebar/TreeNode',
parameters: { layout: 'fullscreen' },
parameters: { layout: 'fullscreen', withSymbols: true },
component: StoryNode,
};

Expand Down

0 comments on commit 27ce3d4

Please sign in to comment.