useOf
The default blocks supplied by Storybook do not fit all use cases, so you might want to write your own blocks.
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.
Here’s an example of how theuseOf
hook could be used to create a custom block that displays the name of the story:
useOf
Type
Parameters
moduleExportOrType
(Required)
Type: ModuleExport | 'story' | 'meta' | 'component'
Provides the story export, meta export, component export, or CSF file exports from which you get annotations.
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')
returns the annotated primary story in attached mode; error in unattached modeuseOf('meta')
returns the annotated meta in attached mode; error in unattached modeuseOf('component')
returns the annotated component specified in the meta in attached mode; error in unattached mode
validTypes
Type: Array<'story' | 'meta' | 'component'>
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: { 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: { type: 'meta', csfFile: CSFFile, preparedMeta: PreparedMeta }
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: { type: 'component', component: Component, projectAnnotations: NormalizedProjectAnnotations }
For components, the component is returned along with project annotations; no meta or story annotations.
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.