Skip to content

Commit

Permalink
Implement of prop support to stories
Browse files Browse the repository at this point in the history
Co-authored-by: Inês Ye Ji <[email protected]>
  • Loading branch information
jorge-ji committed May 16, 2024
1 parent ba69532 commit 1e3558e
Show file tree
Hide file tree
Showing 7 changed files with 141 additions and 12 deletions.
90 changes: 85 additions & 5 deletions code/ui/blocks/src/blocks/Stories.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,26 @@
import type { Meta, StoryObj } from '@storybook/react';
import { Stories } from './Stories';
import * as DefaultButtonStories from '../examples/Button.stories';
import * as ParameterStories from '../examples/StoriesParameters.stories';
import * as ButtonSomeAutodocs from '../examples/ButtonSomeAutodocs.stories';
import * as ButtonNoAutodocs from '../examples/ButtonNoAutodocs.stories';

const meta = {
const meta: Meta<typeof Stories> = {
component: Stories,
parameters: { docsStyles: true },
} satisfies Meta<typeof Stories>;
parameters: {
relativeCsfPaths: [
'../examples/Button.stories',
'../examples/StoriesParameters.stories',
'../examples/ButtonSomeAutodocs.stories',
'../examples/ButtonNoAutodocs.stories',
],
// workaround for https://github.com/storybookjs/storybook/issues/20505
docs: {
source: { type: 'code' },
},
docsStyles: true,
},
};

export default meta;

Expand All @@ -15,8 +31,8 @@ export const Default: Story = {
relativeCsfPaths: ['../examples/Button.stories'],
},
};
export const WithoutPrimary: Story = {
args: { includePrimary: false },
export const WithoutPrimaryStory: Story = {
args: { includePrimaryStory: false },
parameters: {
relativeCsfPaths: ['../examples/Button.stories'],
},
Expand All @@ -36,3 +52,67 @@ export const SomeAutodocs: Story = {
relativeCsfPaths: ['../examples/ButtonSomeAutodocs.stories'],
},
};
export const DefaultWithOf: Story = {
name: 'Default with Of',
args: {
of: DefaultButtonStories,
},
parameters: {
relativeCsfPaths: ['../examples/Button.stories'],
},
};
export const WithoutPrimaryStoryWithOf: Story = {
name: 'Without Primary Story with Of',
args: {
includePrimaryStory: false,
of: DefaultButtonStories,
},
parameters: {
relativeCsfPaths: ['../examples/Button.stories'],
},
};
export const DifferentToolbarsWithOf: Story = {
name: 'Different Toolbars with Of',
args: {
of: ParameterStories,
},
parameters: {
relativeCsfPaths: ['../examples/StoriesParameters.stories'],
},
};
export const DifferentTitleWithOf: Story = {
name: 'Different Title with Of',
args: {
title: 'Different Title',
of: ParameterStories,
},
parameters: {
relativeCsfPaths: ['../examples/StoriesParameters.stories'],
},
};
export const NoAutodocsWithOf: Story = {
args: {
of: ButtonNoAutodocs,
},
parameters: {
relativeCsfPaths: ['../examples/ButtonNoAutodocs.stories'],
},
};
export const SomeAutodocsWithOf: Story = {
args: {
of: ButtonSomeAutodocs,
},
parameters: {
relativeCsfPaths: ['../examples/ButtonSomeAutodocs.stories'],
},
};
export const DefaultAttached: Story = {
parameters: { relativeCsfPaths: ['../examples/Button.stories'], attached: true },
};
export const OfStringMetaAttached: Story = {
name: 'Of "meta" Attached',
args: {
of: 'meta',
},
parameters: { relativeCsfPaths: ['../examples/Button.stories'], attached: true },
};
25 changes: 22 additions & 3 deletions code/ui/blocks/src/blocks/Stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,16 @@ import { styled } from '@storybook/theming';
import { DocsContext } from './DocsContext';
import { DocsStory } from './DocsStory';
import { Heading } from './Heading';
import type { Of } from './useOf';
import { useOf } from './useOf';

interface StoriesProps {
title?: ReactElement | string;
includePrimary?: boolean;
includePrimaryStory?: boolean;
/**
* Specify where to get the stories from.
*/
of?: Of;
}

const StyledHeading: typeof Heading = styled(Heading)(({ theme }) => ({
Expand All @@ -26,7 +32,14 @@ const StyledHeading: typeof Heading = styled(Heading)(({ theme }) => ({
},
}));

export const Stories: FC<StoriesProps> = ({ title = 'Stories', includePrimary = true }) => {
export const Stories: FC<StoriesProps> = (
props = { title: 'Stories', includePrimaryStory: true }
) => {
const { of } = props;

if ('of' in props && of === undefined) {
throw new Error('Unexpected `of={undefined}`, did you mistype a CSF file reference?');
}
const { componentStories, projectAnnotations, getStoryContext } = useContext(DocsContext);

let stories = componentStories();
Expand All @@ -46,7 +59,13 @@ export const Stories: FC<StoriesProps> = ({ title = 'Stories', includePrimary =
stories = stories.filter((story) => story.tags?.includes('autodocs'));
}

if (!includePrimary) stories = stories.slice(1);
const { preparedMeta } = useOf(of || 'meta', ['meta']);

const title = props.title ?? preparedMeta.parameters.docs?.stories?.title;
const includePrimaryStory =
props.includePrimaryStory ?? preparedMeta.parameters.docs?.stories?.includePrimaryStory;

if (!includePrimaryStory) stories = stories.slice(1);

if (!stories || stories.length === 0) {
return null;
Expand Down
4 changes: 4 additions & 0 deletions code/ui/blocks/src/examples/Button.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ const meta = {
info: 'This is info for the Button stories',
jsx: { useBooleanShorthandSyntax: false },
docs: {
stories: {
title: 'Stories',
includePrimaryStory: true,
},
subtitle: 'This is the subtitle for the Button stories',
},
},
Expand Down
6 changes: 6 additions & 0 deletions code/ui/blocks/src/examples/ButtonNoAutodocs.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@ const meta = {
},
parameters: {
chromatic: { disable: true },
docs: {
stories: {
title: 'Stories',
includePrimaryStory: true,
},
},
},
} satisfies Meta<typeof Button>;

Expand Down
6 changes: 6 additions & 0 deletions code/ui/blocks/src/examples/ButtonSomeAutodocs.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@ const meta = {
},
parameters: {
chromatic: { disable: true },
docs: {
stories: {
title: 'Stories',
includePrimaryStory: true,
},
},
},
} satisfies Meta<typeof Button>;

Expand Down
8 changes: 8 additions & 0 deletions code/ui/blocks/src/examples/StoriesParameters.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,14 @@ import { EmptyExample } from './EmptyExample';
const meta = {
title: 'examples/Stories for the Stories and Primary Block',
component: EmptyExample,
parameters: {
docs: {
stories: {
title: 'Title Parameter',
includePrimaryStory: true,
},
},
},
} satisfies Meta<typeof EmptyExample>;
export default meta;

Expand Down
14 changes: 10 additions & 4 deletions docs/api/doc-block-stories.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,24 +29,30 @@ import { Stories } from '@storybook/blocks';

`Stories` is configured with the following props:

### `includePrimary`
### `includePrimaryStory`

Type: `boolean`

Default: `true`
Default: `parameters.docs.stories.includePrimaryStory`

Determines if the collection of stories includes the primary (first) story.

<Callout variant="info" icon="💡">

If a stories file contains only one story and `includePrimary={true}`, the `Stories` block will render nothing to avoid a potentially confusing situation.
If a stories file contains only one story and `includePrimaryStory={true}`, the `Stories` block will render nothing to avoid a potentially confusing situation.

</Callout>

### `of`

Type: CSF file exports

Specifies which meta's stories are displayed.

### `title`

Type: `string`

Default: `'Stories'`
Default: `parameters.docs.stories.title`

Sets the heading content preceding the collection of stories.

0 comments on commit 1e3558e

Please sign in to comment.