Docs
Storybook Docs

useOf

Storybook 提供的默认块并不适合所有用例,因此你可能需要编写自己的块。

¥The default blocks supplied by Storybook do not fit all use cases, so you might want to write your own blocks.

如果你自己的文档块需要与 Storybook 中的注释(即故事、元数据或组件)交互,则可以使用 useOf 钩子。传递故事、元或组件的模块导出,它将返回其注释形式(带有应用的参数、args、加载器、装饰器、播放函数),然后你可以将其用于任何你喜欢的东西。事实上,大多数现有块(如 DescriptionCanvas)都在后台使用 useOf

¥If your own doc blocks need to interface with annotations from Storybook—that is stories, meta or components—you can use the useOf hook. Pass in a module export of a story, meta, or component and it will return its annotated form (with applied parameters, args, loaders, decorators, play function) that you can then use for anything you like. In fact, most of the existing blocks like Description and Canvas use useOf under the hood.

以下是如何使用 useOf 钩子创建显示故事名称的自定义块的示例:

¥Here’s an example of how theuseOf hook could be used to create a custom block that displays the name of the story:

// .storybook/blocks/StoryName.jsx
 
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;
};
{/* ButtonDocs.mdx */}
 
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

类型

¥Type

(
  moduleExportOrType: ModuleExport | 'story' | 'meta' | 'component',
  validTypes?: Array<'story' | 'meta' | 'component'>
) => EnhancedResolvedModuleExportType

参数

¥Parameters

moduleExportOrType

(必需)

¥(Required)

类型:ModuleExport | 'story' | 'meta' | 'component'

¥Type: ModuleExport | 'story' | 'meta' | 'component'

提供故事导出、元导出、组件导出或 CSF 文件导出,你可以从中获取注释。

¥Provides the story export, meta export, component export, or CSF file exports from which you get annotations.

当自定义块位于 附加文档 中时,也可以通过传入字符串来获取主要(第一个)故事、元或组件。这可作为后备使用,因此可以在块中省略 of 属性。最常见的模式是将其用作 useOf(props.of || 'story'),如果没有定义 of 属性,它将回退到主要故事。

¥When the custom block is in an attached doc, it’s also possible to get the primary (first) story, meta, or component by passing in a string instead. This is useful as a fallback, so the of prop can be omitted in your block. The most common pattern is using this as useOf(props.of || 'story') which will fall back to the primary story if no of prop is defined.

  • useOf('story') 在附加模式下返回带注释的主要故事;独立模式下的错误

    ¥useOf('story') returns the annotated primary story in attached mode; error in unattached mode

  • useOf('meta') 在附加模式下返回带注释的元数据;独立模式下的错误

    ¥useOf('meta') returns the annotated meta in attached mode; error in unattached mode

  • useOf('component') 在附加模式下返回元数据中指定的带注释的组件;独立模式下的错误

    ¥useOf('component') returns the annotated component specified in the meta in attached mode; error in unattached mode

validTypes

类型:Array<'story' | 'meta' | 'component'>

¥Type: Array<'story' | 'meta' | 'component'>

可选择指定你的块接受的​​有效类型数组。传递除有效类型以外的任何内容都会导致错误。例如,Canvas 块使用 useOf(of, ['story']),这确保它只接受对故事的引用,而不是元或组件。

¥Optionally specify an array of valid types that your block accepts. Passing anything other than the valid type(s) will result in an error. For example, the Canvas block uses useOf(of, ['story']), which ensures it only accepts a reference to a story, not a meta or component.

返回

¥Return

返回值取决于匹配的类型:

¥The return value depends on the matched type:

EnhancedResolvedModuleExportType['type'] === 'story'

类型:{ type: 'story', story: PreparedStory }

¥Type: { type: 'story', story: PreparedStory }

对于故事,带注释的故事将按原样返回。它们已准备好,这意味着它们已经与项目和元注释合并。

¥For stories, annotated stories are returned as is. They are prepared, meaning that they are already merged with project and meta annotations.

EnhancedResolvedModuleExportType['type'] === 'meta'

类型:{ type: 'meta', csfFile: CSFFile, preparedMeta: PreparedMeta }

¥Type: { type: 'meta', csfFile: CSFFile, preparedMeta: PreparedMeta }

对于元,将返回解析后的 CSF 文件以及准备好的带注释的元。也就是说,项目注释与元注释合并,但没有故事注释。

¥For meta, the parsed CSF file is returned, along with prepared annotated meta. That is, project annotations merged with meta annotations, but no story annotations.

EnhancedResolvedModuleExportType['type'] === 'component'

类型:{ type: 'component', component: Component, projectAnnotations: NormalizedProjectAnnotations }

¥Type: { type: 'component', component: Component, projectAnnotations: NormalizedProjectAnnotations }

对于组件,组件与项目注释一起返回;没有元或故事注释。

¥For components, the component is returned along with project annotations; no meta or story annotations.

请注意,钩子通常无法确定传入的是组件还是任何其他对象,因此它的行为也像 unknown 类型。

¥Note that it’s often impossible for the hook to determine if a component is passed in or any other object, so it behaves like an unknown type as well.