Skip to content

Commit 4785d5d

Browse files
kasperpeulenvalentinpalkovic
authored andcommitted
Merge pull request #33878 from storybookjs/kasper/fix-manifest-stories-no-title
React: Fix manifest stories empty when meta has no explicit title (cherry picked from commit a5282fc)
1 parent a78f690 commit 4785d5d

File tree

2 files changed

+84
-1
lines changed

2 files changed

+84
-1
lines changed

code/renderers/react/src/componentManifest/generator.test.ts

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -575,6 +575,89 @@ test('should create component manifest when only attached-mdx docs have manifest
575575
`);
576576
});
577577

578+
test('stories are populated when meta has no explicit title', async () => {
579+
vol.fromJSON(
580+
{
581+
['./package.json']: JSON.stringify({ name: 'some-package' }),
582+
['./src/stories/Card.stories.ts']: dedent`
583+
import type { Meta, StoryObj } from '@storybook/react';
584+
import { Card } from './Card';
585+
586+
const meta: Meta<typeof Card> = {
587+
component: Card,
588+
};
589+
export default meta;
590+
type Story = StoryObj<typeof meta>;
591+
592+
export const Default: Story = { args: { label: 'Click me' } };
593+
export const Large: Story = { args: { label: 'Big button', size: 'large' } };
594+
`,
595+
['./src/stories/Card.tsx']: dedent`
596+
import React from 'react';
597+
export interface CardProps {
598+
label: string;
599+
size?: 'small' | 'large';
600+
}
601+
602+
/** A simple card component */
603+
export const Card = ({ label, size }: CardProps) => {
604+
return <div className={size}>{label}</div>;
605+
};
606+
`,
607+
},
608+
'/app'
609+
);
610+
611+
const manifestEntries = [
612+
{
613+
type: 'story',
614+
subtype: 'story',
615+
id: 'card--default',
616+
name: 'Default',
617+
title: 'Card',
618+
importPath: './src/stories/Card.stories.ts',
619+
componentPath: './src/stories/Card.tsx',
620+
tags: [Tag.DEV, Tag.TEST, Tag.MANIFEST],
621+
exportName: 'Default',
622+
},
623+
{
624+
type: 'story',
625+
subtype: 'story',
626+
id: 'card--large',
627+
name: 'Large',
628+
title: 'Card',
629+
importPath: './src/stories/Card.stories.ts',
630+
componentPath: './src/stories/Card.tsx',
631+
tags: [Tag.DEV, Tag.TEST, Tag.MANIFEST],
632+
exportName: 'Large',
633+
},
634+
];
635+
636+
const result = await manifests(undefined, { manifestEntries } as any);
637+
const component = result?.components?.components?.['card'];
638+
639+
// When no explicit title is in the meta, stories should still be populated
640+
// because the generator should use the index entry's title as fallback
641+
expect(component?.stories).toMatchInlineSnapshot(`
642+
[
643+
{
644+
"description": undefined,
645+
"id": "card--default",
646+
"name": "Default",
647+
"snippet": "const Default = () => <Card label="Click me" />;",
648+
"summary": undefined,
649+
},
650+
{
651+
"description": undefined,
652+
"id": "card--large",
653+
"name": "Large",
654+
"snippet": "const Large = () => <Card label="Big button" size="large" />;",
655+
"summary": undefined,
656+
},
657+
]
658+
`);
659+
});
660+
578661
test('should extract story description and summary from JSDoc comments', async () => {
579662
const code = withCSF3(dedent`
580663
/**

code/renderers/react/src/componentManifest/generator.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ export const manifests: PresetPropertyFn<
130130
(entry as DocsIndexEntry).storiesImports[0];
131131
const absoluteImportPath = path.join(process.cwd(), storyFilePath);
132132
const storyFile = cachedReadFileSync(absoluteImportPath, 'utf-8') as string;
133-
const csf = loadCsf(storyFile, { makeTitle: (title) => title ?? 'No title' }).parse();
133+
const csf = loadCsf(storyFile, { makeTitle: () => entry.title }).parse();
134134

135135
const componentName = csf._meta?.component;
136136
const id = entry.id.split('--')[0];

0 commit comments

Comments
 (0)