useOf
Storybook 提供的默认区块并不适用于所有用例,因此你可能需要编写自己的区块。
如果你的自定义 doc blocks 需要与来自 Storybook 的注解(即 stories、meta 或 components)交互,你可以使用 useOf
hook。传入 story、meta 或 component 的模块导出,它将返回其带注解的形式(应用了 parameters、args、loaders、decorators、play 函数),然后你可以将其用于任何你喜欢的事情。实际上,大多数现有的区块,例如 Description
和 Canvas
都在底层使用了 useOf
。
这是一个如何使用 useOf
hook 创建自定义区块来显示 story 名称的示例
import { useOf } from '@storybook/blocks';
/**
* A block that displays the story name or title from the of prop
* - if a story reference is passed, it renders the story name
* - if a meta reference is passed, it renders the stories' title
* - if nothing is passed, it defaults to the primary story
*/
export const StoryName = ({ of }) => {
const resolvedOf = useOf(of || 'story', ['story', 'meta']);
switch (resolvedOf.type) {
case 'story': {
return <h1>{resolvedOf.story.name}</h1>;
}
case 'meta': {
return <h1>{resolvedOf.preparedMeta.title}</h1>;
}
}
return null;
};
import { Meta } from '@storybook/blocks';
import { StoryName } from '../.storybook/blocks/StoryName';
import * as ButtonStories from './Button.stories';
<Meta of={ButtonStories} />
{/* Renders "Secondary" */}
<StoryName of={ButtonStories.Secondary} />
{/* Renders "Primary" */}
<StoryName />
{/* Renders "Button" */}
<StoryName of={ButtonStories} />
useOf
类型
(
moduleExportOrType: ModuleExport | 'story' | 'meta' | 'component',
validTypes?: Array<'story' | 'meta' | 'component'>
) => EnhancedResolvedModuleExportType
参数
moduleExportOrType
(必需)
类型: ModuleExport | 'story' | 'meta' | 'component'
提供 story 导出、meta 导出、component 导出或 CSF 文件导出,你可以从中获取注解。
当自定义区块位于附加文档中时,也可以通过传入字符串来获取主要的(第一个)story、meta 或 component。这可以用作回退,因此可以在你的区块中省略 of
属性。最常见的模式是使用 useOf(props.of || 'story')
,如果未定义 of
属性,它将回退到主要的 story。
useOf('story')
在附加模式下返回带注解的主要 story;在未附加模式下报错useOf('meta')
在附加模式下返回带注解的 meta;在未附加模式下报错useOf('component')
在附加模式下返回 meta 中指定的带注解的 component;在未附加模式下报错
validTypes
类型: Array<'story' | 'meta' | 'component'>
可选地指定你的区块接受的有效类型数组。传递任何有效类型以外的内容都会导致错误。例如,Canvas
区块使用 useOf(of, ['story'])
,这确保了它只接受对 story 的引用,而不是 meta 或 component。
返回
返回值取决于匹配的类型
EnhancedResolvedModuleExportType['type'] === 'story'
类型: { type: 'story', story: PreparedStory }
对于 stories,带注解的 stories 按原样返回。它们是预处理的,这意味着它们已经与项目和 meta 注解合并。
EnhancedResolvedModuleExportType['type'] === 'meta'
类型: { type: 'meta', csfFile: CSFFile, preparedMeta: PreparedMeta }
对于 meta,将返回解析后的 CSF 文件,以及预处理的带注解的 meta。也就是说,项目注解与 meta 注解合并,但不包含 story 注解。
EnhancedResolvedModuleExportType['type'] === 'component'
类型: { type: 'component', component: Component, projectAnnotations: NormalizedProjectAnnotations }
对于 components,将返回 component 以及项目注解;不包含 meta 或 story 注解。
请注意,hook 通常无法确定传入的是 component 还是任何其他对象,因此它的行为也类似于 unknown
类型。