diff --git a/code/ui/blocks/src/blocks/Stories.stories.tsx b/code/ui/blocks/src/blocks/Stories.stories.tsx index 0c91aec638e6..e7dd12454761 100644 --- a/code/ui/blocks/src/blocks/Stories.stories.tsx +++ b/code/ui/blocks/src/blocks/Stories.stories.tsx @@ -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 = { component: Stories, - parameters: { docsStyles: true }, -} satisfies Meta; + 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; @@ -15,7 +31,7 @@ export const Default: Story = { relativeCsfPaths: ['../examples/Button.stories'], }, }; -export const WithoutPrimary: Story = { +export const WithoutPrimaryStory: Story = { args: { includePrimary: false }, parameters: { relativeCsfPaths: ['../examples/Button.stories'], @@ -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: { + includePrimary: 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 }, +}; diff --git a/code/ui/blocks/src/blocks/Stories.tsx b/code/ui/blocks/src/blocks/Stories.tsx index c2b5c53dc729..7f5973e5c5ee 100644 --- a/code/ui/blocks/src/blocks/Stories.tsx +++ b/code/ui/blocks/src/blocks/Stories.tsx @@ -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; + /** + * Specify where to get the stories from. + */ + of?: Of; } const StyledHeading: typeof Heading = styled(Heading)(({ theme }) => ({ @@ -26,7 +32,12 @@ const StyledHeading: typeof Heading = styled(Heading)(({ theme }) => ({ }, })); -export const Stories: FC = ({ title = 'Stories', includePrimary = true }) => { +export const Stories: FC = (props = { title: 'Stories', includePrimary: 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(); @@ -46,6 +57,12 @@ export const Stories: FC = ({ title = 'Stories', includePrimary = stories = stories.filter((story) => story.tags?.includes('autodocs')); } + const { preparedMeta } = useOf(of || 'meta', ['meta']); + + const title = props.title ?? preparedMeta.parameters.docs?.stories?.title; + const includePrimary = + props.includePrimary ?? preparedMeta.parameters.docs?.stories?.includePrimary; + if (!includePrimary) stories = stories.slice(1); if (!stories || stories.length === 0) { diff --git a/code/ui/blocks/src/examples/Button.stories.tsx b/code/ui/blocks/src/examples/Button.stories.tsx index a49f88f5d8f8..a748eeeadb73 100644 --- a/code/ui/blocks/src/examples/Button.stories.tsx +++ b/code/ui/blocks/src/examples/Button.stories.tsx @@ -18,6 +18,10 @@ const meta = { info: 'This is info for the Button stories', jsx: { useBooleanShorthandSyntax: false }, docs: { + stories: { + title: 'Stories', + includePrimary: true, + }, subtitle: 'This is the subtitle for the Button stories', }, }, diff --git a/code/ui/blocks/src/examples/ButtonNoAutodocs.stories.tsx b/code/ui/blocks/src/examples/ButtonNoAutodocs.stories.tsx index c934e70753f2..86889c516ddc 100644 --- a/code/ui/blocks/src/examples/ButtonNoAutodocs.stories.tsx +++ b/code/ui/blocks/src/examples/ButtonNoAutodocs.stories.tsx @@ -9,6 +9,12 @@ const meta = { }, parameters: { chromatic: { disable: true }, + docs: { + stories: { + title: 'Stories', + includePrimary: true, + }, + }, }, } satisfies Meta; diff --git a/code/ui/blocks/src/examples/ButtonSomeAutodocs.stories.tsx b/code/ui/blocks/src/examples/ButtonSomeAutodocs.stories.tsx index dd5f7d227f49..1040cfa43ed3 100644 --- a/code/ui/blocks/src/examples/ButtonSomeAutodocs.stories.tsx +++ b/code/ui/blocks/src/examples/ButtonSomeAutodocs.stories.tsx @@ -9,6 +9,12 @@ const meta = { }, parameters: { chromatic: { disable: true }, + docs: { + stories: { + title: 'Stories', + includePrimary: true, + }, + }, }, } satisfies Meta; diff --git a/code/ui/blocks/src/examples/StoriesParameters.stories.tsx b/code/ui/blocks/src/examples/StoriesParameters.stories.tsx index 731291ad75f7..a37496b6ed27 100644 --- a/code/ui/blocks/src/examples/StoriesParameters.stories.tsx +++ b/code/ui/blocks/src/examples/StoriesParameters.stories.tsx @@ -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', + includePrimary: true, + }, + }, + }, } satisfies Meta; export default meta; diff --git a/docs/api/doc-block-stories.md b/docs/api/doc-block-stories.md index b20a3496ae61..9f50107f44fd 100644 --- a/docs/api/doc-block-stories.md +++ b/docs/api/doc-block-stories.md @@ -33,7 +33,7 @@ import { Stories } from '@storybook/blocks'; Type: `boolean` -Default: `true` +Default: `parameters.docs.stories.includePrimary` Determines if the collection of stories includes the primary (first) story. @@ -43,10 +43,16 @@ If a stories file contains only one story and `includePrimary={true}`, the `Stor +### `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.