Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

CSF-tools: Parse stories using typescript keywords 'satisfies' and 'as' #23638

Merged
merged 3 commits into from
Jul 28, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
54 changes: 45 additions & 9 deletions code/lib/csf-tools/src/CsfFile.test.ts
Expand Up @@ -228,21 +228,57 @@ describe('CsfFile', () => {
expect(
parse(
dedent`
import type { Meta, StoryFn } from '@storybook/react';
import type { Meta, StoryFn, StoryObj } from '@storybook/react';
type PropTypes = {};
export default { title: 'foo/bar/baz' } as Meta<PropTypes>;
export const A: StoryFn<PropTypes> = () => <>A</>;
export const B: StoryFn<PropTypes> = () => <>B</>;
`
export default { title: 'foo/bar' } satisfies Meta<PropTypes>;
export const A = { name: 'AA' } satisfies StoryObj<PropTypes>;
export const B = ((args) => {}) satisfies StoryFn<PropTypes>;
`,
true
)
).toMatchInlineSnapshot(`
meta:
title: foo/bar/baz
title: foo/bar
stories:
- id: foo-bar-baz--a
name: A
- id: foo-bar-baz--b
- id: foo-bar--a
name: AA
parameters:
__isArgsStory: true
__id: foo-bar--a
- id: foo-bar--b
name: B
parameters:
__isArgsStory: true
__id: foo-bar--b
`);
});

it('typescript as', () => {
expect(
parse(
dedent`
import type { Meta, StoryFn, StoryObj } from '@storybook/react';
type PropTypes = {};
export default { title: 'foo/bar' } as Meta<PropTypes>;
export const A = { name: 'AA' } as StoryObj<PropTypes>;
export const B = ((args) => {}) as StoryFn<PropTypes>;
`,
true
)
).toMatchInlineSnapshot(`
meta:
title: foo/bar
stories:
- id: foo-bar--a
name: AA
parameters:
__isArgsStory: true
__id: foo-bar--a
- id: foo-bar--b
name: B
parameters:
__isArgsStory: true
__id: foo-bar--b
`);
});

Expand Down
16 changes: 12 additions & 4 deletions code/lib/csf-tools/src/CsfFile.ts
Expand Up @@ -315,12 +315,21 @@ export class CsfFile {
} else {
self._storyAnnotations[exportName] = {};
}
let storyNode;
if (t.isVariableDeclarator(decl)) {
storyNode =
t.isTSAsExpression(decl.init) || t.isTSSatisfiesExpression(decl.init)
? decl.init.expression
: decl.init;
} else {
storyNode = decl;
}
let parameters;
if (t.isVariableDeclarator(decl) && t.isObjectExpression(decl.init)) {
if (t.isObjectExpression(storyNode)) {
// eslint-disable-next-line @typescript-eslint/naming-convention
let __isArgsStory = true; // assume default render is an args story
// CSF3 object export
(decl.init.properties as t.ObjectProperty[]).forEach((p) => {
(storyNode.properties as t.ObjectProperty[]).forEach((p) => {
if (t.isIdentifier(p.key)) {
if (p.key.name === 'render') {
__isArgsStory = isArgsStory(p.value as t.Expression, parent, self);
Expand All @@ -336,11 +345,10 @@ export class CsfFile {
});
parameters = { __isArgsStory };
} else {
const fn = t.isVariableDeclarator(decl) ? decl.init : decl;
parameters = {
// __id: toId(self._meta.title, name),
// FIXME: Template.bind({});
__isArgsStory: isArgsStory(fn as t.Node, parent, self),
__isArgsStory: isArgsStory(storyNode as t.Node, parent, self),
};
}
self._stories[exportName] = {
Expand Down