Merge pull request #20803 from storybookjs/jeppe/fix-blocks

Doc Blocks: Fix styling and parameter bugs
This commit is contained in:
Jeppe Reinhold 2023-02-01 23:47:46 +01:00 committed by GitHub
commit dd1ca7f951
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
22 changed files with 139 additions and 17 deletions

View File

@ -60,10 +60,11 @@ test.describe('addon-docs', () => {
// The `<Primary>` block should render the "Basic" story, and the `<Stories/>` block should // The `<Primary>` block should render the "Basic" story, and the `<Stories/>` block should
// render both the "Basic" and "Another" story // render both the "Basic" and "Another" story
const root = sbPage.previewRoot(); const root = sbPage.previewRoot();
const stories = root.locator('.sbdocs-h3'); const stories = root.locator('.sb-story button');
await expect(await stories.count()).toBe(2); await expect(await stories.count()).toBe(3);
await expect(stories.first()).toHaveText('Basic'); await expect(stories.first()).toHaveText('Basic');
await expect(stories.nth(1)).toHaveText('Basic');
await expect(stories.last()).toHaveText('Another'); await expect(stories.last()).toHaveText('Another');
}); });
}); });

View File

@ -3,6 +3,9 @@ import { Anchor } from './Anchor';
const meta = { const meta = {
component: Anchor, component: Anchor,
parameters: {
docsStyles: true,
},
} as Meta<typeof Anchor>; } as Meta<typeof Anchor>;
export default meta; export default meta;

View File

@ -8,6 +8,7 @@ const meta: Meta<typeof ArgTypes> = {
component: ArgTypes, component: ArgTypes,
parameters: { parameters: {
relativeCsfPaths: ['../examples/ArgTypesParameters.stories'], relativeCsfPaths: ['../examples/ArgTypesParameters.stories'],
docsStyles: true,
}, },
}; };
export default meta; export default meta;

View File

@ -25,6 +25,7 @@ const meta: Meta<typeof Canvas> = {
/>`, />`,
}, },
}, },
docsStyles: true,
}, },
decorators: SourceStoriesMeta.decorators, decorators: SourceStoriesMeta.decorators,
}; };

View File

@ -7,6 +7,7 @@ const meta: Meta<typeof Controls> = {
component: Controls, component: Controls,
parameters: { parameters: {
relativeCsfPaths: ['../examples/ControlsParameters.stories'], relativeCsfPaths: ['../examples/ControlsParameters.stories'],
docsStyles: true,
}, },
}; };
export default meta; export default meta;

View File

@ -16,6 +16,7 @@ const meta: Meta<typeof Description> = {
// workaround for https://github.com/storybookjs/storybook/issues/20505 // workaround for https://github.com/storybookjs/storybook/issues/20505
docs: { source: { type: 'code' } }, docs: { source: { type: 'code' } },
attached: false, attached: false,
docsStyles: true,
}, },
}; };
export default meta; export default meta;

View File

@ -10,12 +10,15 @@ import { useOf } from './useOf';
export const DocsStory: FC<DocsStoryProps> = ({ export const DocsStory: FC<DocsStoryProps> = ({
of, of,
expanded = true, expanded = true,
withToolbar = false, withToolbar: withToolbarProp = false,
__forceInitialArgs = false, __forceInitialArgs = false,
__primary = false, __primary = false,
}) => { }) => {
const { story } = useOf(of || 'story', ['story']); const { story } = useOf(of || 'story', ['story']);
// use withToolbar from parameters or default to true in autodocs
const withToolbar = story.parameters.docs?.canvas?.withToolbar ?? withToolbarProp;
return ( return (
<Anchor storyId={story.id}> <Anchor storyId={story.id}>
{expanded && ( {expanded && (

View File

@ -5,6 +5,7 @@ import mdContent from '../examples/Markdown-content.md?raw';
export default { export default {
component: MarkdownComponent, component: MarkdownComponent,
parameters: { docsStyles: true },
}; };
export const Markdown = { export const Markdown = {

View File

@ -0,0 +1,24 @@
import type { Meta, StoryObj } from '@storybook/react';
import { Primary } from './Primary';
const meta = {
component: Primary,
parameters: {
docsStyles: true,
},
} satisfies Meta<typeof Primary>;
export default meta;
type Story = StoryObj<typeof meta>;
export const Default: Story = {
parameters: {
relativeCsfPaths: ['../examples/Button.stories'],
},
};
export const WithoutToolbar: Story = {
parameters: {
relativeCsfPaths: ['../examples/StoriesParameters.stories'],
},
};

View File

@ -23,6 +23,6 @@ export const Primary: FC<PrimaryProps> = ({ name }) => {
const storyId = name && docsContext.storyIdByName(name); const storyId = name && docsContext.storyIdByName(name);
const story = docsContext.storyById(storyId); const story = docsContext.storyById(storyId);
return story ? ( return story ? (
<DocsStory of={story.moduleExport} expanded={false} withToolbar __primary /> <DocsStory of={story.moduleExport} expanded={false} __primary withToolbar />
) : null; ) : null;
}; };

View File

@ -18,6 +18,7 @@ const meta: Meta<typeof Source> = {
code: `const emitted = 'source';`, code: `const emitted = 'source';`,
}, },
}, },
docsStyles: true,
}, },
decorators: [ decorators: [
(Story, { parameters: { snippets = {} } }) => ( (Story, { parameters: { snippets = {} } }) => (
@ -83,6 +84,10 @@ export const CodeUnattached: Story = {
parameters: { attached: false }, parameters: { attached: false },
}; };
export const EmptyUnattached: Story = {
parameters: { attached: false },
};
export const CodeParameters: Story = { export const CodeParameters: Story = {
args: { of: ParametersStories.Code }, args: { of: ParametersStories.Code },
}; };

View File

@ -118,8 +118,7 @@ export const useSourceProps = (
// Always fall back to the primary story for source parameters, even if code is set. // Always fall back to the primary story for source parameters, even if code is set.
stories = [docsContext.storyById()]; stories = [docsContext.storyById()];
} catch (err) { } catch (err) {
// You are allowed to use <Story code="..." /> unattached. // You are allowed to use <Source code="..." /> and <Canvas /> unattached.
if (!props.code) throw err;
} }
} }

View File

@ -0,0 +1,28 @@
import type { Meta, StoryObj } from '@storybook/react';
import { Stories } from './Stories';
const meta = {
component: Stories,
parameters: { docsStyles: true },
} satisfies Meta<typeof Stories>;
export default meta;
type Story = StoryObj<typeof meta>;
export const Default: Story = {
parameters: {
relativeCsfPaths: ['../examples/Button.stories'],
},
};
export const WithoutPrimary: Story = {
args: { includePrimary: false },
parameters: {
relativeCsfPaths: ['../examples/Button.stories'],
},
};
export const DifferentToolbars: Story = {
parameters: {
relativeCsfPaths: ['../examples/StoriesParameters.stories'],
},
};

View File

@ -9,6 +9,7 @@ const meta: Meta<typeof StoryBlock> = {
component: StoryBlock, component: StoryBlock,
parameters: { parameters: {
relativeCsfPaths: ['../examples/Button.stories', '../examples/StoryParameters.stories'], relativeCsfPaths: ['../examples/Button.stories', '../examples/StoryParameters.stories'],
docsStyles: true,
}, },
}; };
export default meta; export default meta;

View File

@ -8,11 +8,19 @@ However sometimes you might want some of your content to not have these styles a
```md ```md
import { Unstyled } from '@storybook/blocks'; import { Unstyled } from '@storybook/blocks';
# This heading will be styled
<h2>So will this subheading</h2>
> This block quote will be styled > This block quote will be styled
... and so will this paragraph. ... and so will this paragraph.
<Unstyled> <Unstyled>
# This heading will not be styled
<h2>Neither will this subheading</h2>
> This block quote will not be styled > This block quote will not be styled
... neither will this paragraph, nor the following component: ... neither will this paragraph, nor the following component:
@ -22,11 +30,19 @@ import { Unstyled } from '@storybook/blocks';
Yields: Yields:
# This heading will be styled
<h2>So will this subheading</h2>
> This block quote will be styled > This block quote will be styled
... and so will this paragraph. ... and so will this paragraph.
<Unstyled> <Unstyled>
# This heading will not be styled
<h2>Neither will this subheading</h2>
> This block quote will not be styled > This block quote will not be styled
... neither will this paragraph, nor the following component: ... neither will this paragraph, nor the following component:

View File

@ -14,6 +14,7 @@ const meta: Meta<typeof Canvas> = {
parameters: { parameters: {
theme: 'light', theme: 'light',
relativeCsfPaths: ['../examples/Button.stories', '../examples/CanvasParameters.stories'], relativeCsfPaths: ['../examples/Button.stories', '../examples/CanvasParameters.stories'],
docsStyles: true,
}, },
render: (args) => { render: (args) => {
return ( return (
@ -50,6 +51,23 @@ export const BasicStoryChildUnattached: Story = {
parameters: { attached: false }, parameters: { attached: false },
}; };
export const NoStoryChildrenUnattached: Story = {
parameters: { attached: false },
render: (args) => {
return (
<Canvas {...args}>
<p>This is a plain paragraph, no stories</p>
</Canvas>
);
},
};
export const NoStoryChildrenUnattachedWithMDXSource: Story = {
...NoStoryChildrenUnattached,
args: {
mdxSource: `const customStaticSource = true;`,
},
};
export const WithSourceOpen: Story = { export const WithSourceOpen: Story = {
args: { args: {
withSource: SourceState.OPEN, withSource: SourceState.OPEN,

View File

@ -7,6 +7,7 @@ const meta: Meta<typeof Description> = {
component: Description, component: Description,
parameters: { parameters: {
relativeCsfPaths: ['../examples/Button.stories'], relativeCsfPaths: ['../examples/Button.stories'],
docsStyles: true,
}, },
args: { args: {
of: Button, of: Button,

View File

@ -7,6 +7,7 @@ const meta: Meta<typeof Source> = {
parameters: { parameters: {
relativeCsfPaths: ['../examples/Button.stories'], relativeCsfPaths: ['../examples/Button.stories'],
attached: false, attached: false,
docsStyles: true,
}, },
}; };

View File

@ -8,6 +8,7 @@ const meta: Meta<typeof StoryBlock> = {
component: StoryBlock, component: StoryBlock,
parameters: { parameters: {
relativeCsfPaths: ['../examples/Button.stories'], relativeCsfPaths: ['../examples/Button.stories'],
docsStyles: true,
}, },
}; };
export default meta; export default meta;

View File

@ -1,7 +1,7 @@
import type { FC, SyntheticEvent } from 'react'; import type { FC, SyntheticEvent } from 'react';
import React, { useContext } from 'react'; import React, { useContext } from 'react';
import { NAVIGATE_URL } from '@storybook/core-events'; import { NAVIGATE_URL } from '@storybook/core-events';
import { Code, components } from '@storybook/components'; import { Code, components, nameSpaceClassNames } from '@storybook/components';
import { global } from '@storybook/global'; import { global } from '@storybook/global';
import { styled } from '@storybook/theming'; import { styled } from '@storybook/theming';
import { Source } from '../components'; import { Source } from '../components';
@ -120,13 +120,12 @@ export const AnchorMdx: FC<AnchorMdxProps> = (props) => {
return <A {...props} />; return <A {...props} />;
}; };
const SUPPORTED_MDX_HEADERS = ['h1', 'h2', 'h3', 'h4', 'h5', 'h6']; const SUPPORTED_MDX_HEADERS = ['h1', 'h2', 'h3', 'h4', 'h5', 'h6'] as const;
const OcticonHeaders = SUPPORTED_MDX_HEADERS.reduce( const OcticonHeaders = SUPPORTED_MDX_HEADERS.reduce(
(acc, headerType) => ({ (acc, headerType) => ({
...acc, ...acc,
// @ts-expect-error (Converted from ts-ignore) [headerType]: styled(headerType)({
[headerType]: styled(components[headerType])({
'& svg': { '& svg': {
visibility: 'hidden', visibility: 'hidden',
}, },
@ -213,12 +212,10 @@ export const HeaderMdx: FC<HeaderMdxProps> = (props) => {
</HeaderWithOcticonAnchor> </HeaderWithOcticonAnchor>
); );
} }
// @ts-expect-error (Converted from ts-ignore)
const Header = components[as];
// Make sure it still work if "remark-slug" plugin is not present. // Make sure it still work if "remark-slug" plugin is not present.
return <Header {...props} />; const Component = as as React.ElementType;
const { as: omittedAs, ...withoutAs } = props;
return <Component {...nameSpaceClassNames(withoutAs, as)} />;
}; };
export const HeadersMdx = SUPPORTED_MDX_HEADERS.reduce( export const HeadersMdx = SUPPORTED_MDX_HEADERS.reduce(

View File

@ -70,6 +70,7 @@ export const Subtitle = styled.h2(withReset, ({ theme }) => ({
color: transparentize(0.25, theme.color.defaultText), color: transparentize(0.25, theme.color.defaultText),
})); }));
// @ts-expect-error don't know why it doesn't accept our returned styles. if we add `...{}` anywhere to the returned object it stops erroring
export const DocsContent = styled.div(({ theme }) => { export const DocsContent = styled.div(({ theme }) => {
const reset = { const reset = {
fontFamily: theme.typography.fonts.base, fontFamily: theme.typography.fonts.base,
@ -121,8 +122,6 @@ export const DocsContent = styled.div(({ theme }) => {
return { return {
maxWidth: 1000, maxWidth: 1000,
width: '100%', width: '100%',
...reset,
[toGlobalSelector('a')]: { [toGlobalSelector('a')]: {
...reset, ...reset,
fontSize: 'inherit', fontSize: 'inherit',

View File

@ -0,0 +1,20 @@
import type { Meta, StoryObj } from '@storybook/react';
import { EmptyExample } from './EmptyExample';
const meta = {
title: 'examples/Stories for the Stories and Primary Block',
component: EmptyExample,
} satisfies Meta<typeof EmptyExample>;
export default meta;
type Story = StoryObj<typeof meta>;
export const WithoutToolbar: Story = {
parameters: { docs: { canvas: { withToolbar: false } } },
};
export const WithToolbar: Story = {
parameters: { docs: { canvas: { withToolbar: true } } },
};
export const ThirdStory: Story = {};