Skip to content

Commit 11fa867

Browse files
committed
feat: auto create argTypes from jsdoc
1 parent c36d000 commit 11fa867

File tree

4 files changed

+78
-44
lines changed

4 files changed

+78
-44
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,4 @@ run
88
.DS_Store
99
.cache
1010
.eslintcache
11+
debug-storybook.log

.storybook/main.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@ const config: StorybookConfig = {
77
name: '@storybook/react-vite',
88
options: {},
99
},
10+
typescript: {
11+
reactDocgen: 'react-docgen-typescript',
12+
},
1013
};
1114

1215
export default config;

.storybook/preview.tsx

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import type { Preview, ReactRenderer } from '@storybook/react-vite';
44
import { App as AntdApp, ConfigProvider as AntdConfigProvider, theme } from 'antd';
55
import enUS from 'antd/es/locale/en_US';
66
import zhCN from 'antd/es/locale/zh_CN';
7-
import type { StoryContext } from 'storybook/internal/csf';
7+
import type { StoryContext, StoryContextForEnhancers } from 'storybook/internal/csf';
88
import { themes } from 'storybook/theming';
99
import ConfigProvider from '../src/components/ConfigProvider';
1010
import storyI18n from './locales';
@@ -85,6 +85,7 @@ const preview: Preview = {
8585
);
8686
},
8787
],
88+
argTypesEnhancers: [jsdocArgTypesEnhancer],
8889
};
8990

9091
function stripExampleBlock(input = '') {
@@ -96,4 +97,33 @@ function stripExampleBlock(input = '') {
9697
);
9798
}
9899

100+
function jsdocArgTypesEnhancer(context: StoryContextForEnhancers) {
101+
const component = context.component;
102+
const docProps = component?.__docgenInfo?.props;
103+
if (!docProps) return context.argTypes;
104+
105+
const next = { ...(context.argTypes || {}) };
106+
107+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
108+
Object.entries(docProps).forEach(([propName, propInfo]: [string, any]) => {
109+
next[propName] = {
110+
...(next[propName] || {}),
111+
// control: ?
112+
// The handwritten description will not be overwritten.
113+
description: next[propName]?.description ?? propInfo?.description ?? '',
114+
table: {
115+
...(next[propName]?.table || {}),
116+
type: next[propName]?.table?.type ?? {
117+
summary: propInfo?.type?.name || '',
118+
},
119+
defaultValue:
120+
next[propName]?.table?.defaultValue ??
121+
(propInfo?.defaultValue?.value ? { summary: String(propInfo.defaultValue.value) } : undefined),
122+
},
123+
};
124+
});
125+
console.log(next);
126+
return next;
127+
}
128+
99129
export default preview;

.storybook/stories/BreakLines.stories.tsx

Lines changed: 43 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import type { Meta, StoryObj } from '@storybook/react-vite';
2-
import BreakLines from '../../src/components/BreakLines';
2+
import BreakLines, { type BreakLinesProps } from '../../src/components/BreakLines';
33

44
const meta: Meta<typeof BreakLines> = {
55
title: 'Components/BreakLines',
@@ -10,49 +10,49 @@ const meta: Meta<typeof BreakLines> = {
1010
EOL: '\n',
1111
tagName: 'div',
1212
className: '',
13-
},
13+
} satisfies Partial<BreakLinesProps>,
1414
argTypes: {
15-
value: {
16-
control: 'text',
17-
description: `- **EN:** Text content
18-
- **CN:** 文本内容`,
19-
table: {
20-
defaultValue: { summary: '第一行\\n第二行\\n第三行(demo)' },
21-
},
22-
},
23-
enabled: {
24-
control: 'boolean',
25-
description: `- **EN:** Whether the line break conversion is enabled.
26-
- **CN:** 是否启用换行转换。`,
27-
table: {
28-
defaultValue: { summary: 'true' },
29-
},
30-
},
31-
EOL: {
32-
control: 'text',
33-
description: `- **EN:** The end-of-line character to use for splitting lines.
34-
- **CN:** 用于分割行的行结束字符。`,
35-
table: {
36-
defaultValue: { summary: '\\n' },
37-
},
38-
},
39-
tagName: {
40-
control: 'select',
41-
options: [false, 'span', 'div', 'i', 'pre'],
42-
description: `- **EN:** The HTML tag to use for rendering the content.
43-
- **CN:** 用于渲染内容的 HTML 标签。`,
44-
table: {
45-
defaultValue: { summary: 'false(组件默认) / div(demo)' },
46-
},
47-
},
48-
className: {
49-
control: 'text',
50-
description: `- **EN:** The CSS class name of the dom node, if \`tagName\` is set to false, this property is invalid.
51-
- **CN:** dom 节点的 css 类名,如果 \`tagName\` 设置为 false,则此属性无效。`,
52-
table: {
53-
defaultValue: { summary: '""(demo)' },
54-
},
55-
},
15+
// value: {
16+
// control: 'text',
17+
// description: `- **EN:** Text content
18+
// - **CN:** 文本内容`,
19+
// table: {
20+
// defaultValue: { summary: '第一行\\n第二行\\n第三行(demo)' },
21+
// },
22+
// },
23+
// enabled: {
24+
// control: 'boolean',
25+
// description: `- **EN:** Whether the line break conversion is enabled.
26+
// - **CN:** 是否启用换行转换。`,
27+
// table: {
28+
// defaultValue: { summary: 'true' },
29+
// },
30+
// },
31+
// EOL: {
32+
// control: 'text',
33+
// description: `- **EN:** The end-of-line character to use for splitting lines.
34+
// - **CN:** 用于分割行的行结束字符。`,
35+
// table: {
36+
// defaultValue: { summary: '\\n' },
37+
// },
38+
// },
39+
// tagName: {
40+
// control: 'select',
41+
// options: [false, 'span', 'div', 'i', 'pre'],
42+
// description: `- **EN:** The HTML tag to use for rendering the content.
43+
// - **CN:** 用于渲染内容的 HTML 标签。`,
44+
// table: {
45+
// defaultValue: { summary: 'false(组件默认) / div(demo)' },
46+
// },
47+
// },
48+
// className: {
49+
// control: 'text',
50+
// description: `- **EN:** The CSS class name of the dom node, if \`tagName\` is set to false, this property is invalid.
51+
// - **CN:** dom 节点的 css 类名,如果 \`tagName\` 设置为 false,则此属性无效。`,
52+
// table: {
53+
// defaultValue: { summary: '""(demo)' },
54+
// },
55+
// },
5656
},
5757
};
5858

0 commit comments

Comments
 (0)