What is @storybook/preview-web?
The @storybook/preview-web package is a part of the Storybook ecosystem, which is an open-source tool for developing UI components in isolation for React, Vue, Angular, and more. It allows developers to create a development environment for showcasing components, enabling interactive testing and providing a platform for sharing and receiving feedback on UI implementations. The preview-web package specifically deals with rendering stories for the web and handling various aspects of the Storybook UI.
What are @storybook/preview-web's main functionalities?
Rendering stories
This feature allows developers to render stories within the Storybook environment. The code sample shows how to import the PreviewWeb class and initialize it with specific parameters such as storyId and viewMode.
import { PreviewWeb } from '@storybook/preview-web';
const preview = new PreviewWeb();
preview.initialize({ storyId, viewMode });
Handling URL changes
The package can respond to URL changes to update the displayed story accordingly. The code sample demonstrates how to use the onUrlChange method to handle changes in the story ID or view mode.
import { PreviewWeb } from '@storybook/preview-web';
const preview = new PreviewWeb();
preview.onUrlChange({ storyId, viewMode });
Customizing the Storybook UI
Developers can customize the Storybook UI by integrating with the addons package. The code sample illustrates how to set the preview instance in the addons registry.
import { addons } from '@storybook/addons';
import { PreviewWeb } from '@storybook/preview-web';
const preview = new PreviewWeb();
addons.setPreview(preview);
Other packages similar to @storybook/preview-web
react-cosmos
React Cosmos is a development tool for creating reusable React components. It scans your project for components and enables you to render them in different states while developing. It is similar to Storybook in that it provides an isolated environment for components, but it focuses more on the component 'playground' aspect rather than the storytelling aspect of Storybook.
docz
Docz leverages MDX to help you document your components with ease. It provides a similar experience to Storybook by allowing developers to write interactive documentation and examples, but it emphasizes simplicity and the use of Markdown for documentation over the more extensive plugin ecosystem and UI customization options that Storybook offers.
Preview (Web)
This is the main API for the (web) version of the Storybook Preview.
The preview's job is:
-
Read and update the URL (via the URL Store)
-
Listen to instructions on the channel and emit events as things occur.
-
Render the current selection to the web view in either story or docs mode.
V7 Store vs Legacy (V6)
The story store is designed to load stories 'on demand', and will operate in this fashion if the storyStoreV7
feature is enabled.
However, for back-compat reasons, in v6 mode, we need to load all stories, synchronously on bootup, emitting the SET_STORIES
event.
In V7 mode we do not emit that event, instead preferring the STORY_PREPARED
event, with the data for the single story being rendered.
Initialization
The preview is initialized
in two ways.
V7 Mode:
-
importFn
- is an async import()
function
-
getProjectAnnotations
- is a simple function that evaluations preview.js
and addon config files and combines them. If it errors, the Preview will show the error.
-
No getStoryIndex
function is passed, instead the preview creates a StoryIndexClient
that pulls stories.json
from node and watches the event stream for invalidation events.
V6 Mode
importFn
- is a simulated import()
function, that is synchronous, see client-api
for details.getProjectAnnotations
- also evaluates preview.js
et al, but watches for calls to setStories
, and passes them to the ClientApi
getStoryIndex
is a local function (that must be called after getProjectAnnotations
) that gets the list of stories added.
See client-api
for more details on this process.
Story Rendering and interruptions
A rendering story goes through these phases:
loading
- async loaders are runningrendering
- the renderToDom
function for the framework is runningplaying
- the play
function is runningcompleted
- the story is done.
It also has two error states:
aborted
- the story was stopped midway (see below)errored
- there was an error thrown somewhere along the way.
Re-rendering and aborting
A story may re-render due to various events, which can have implications if the story is not in the completed
phase:
UPDATE_STORY_ARGS
/ UPDATE_GLOBALS
-- change of inputsFORCE_RE_RENDER
- re-render unchanged
If these events happen during a render:
-
if the story is loading
, leave thing unchanged and let the new args
/globals
be picked up by the render phase
-
otherwise, use the result of the previous loaders
run, and simply re-render over the top
-
FORCE_REMOUNT
- remount (or equivalent) the component and re-render.
If this happens during a render, treat loading
similarly, but:
- if the story is
rendering
, start a new render and abort the previous render immediately afterwards - if the story is
playing
, attempt to abort the previous play function, and start a new render.
Also the SET_CURRENT_STORY
event may change the current story. If the old story is not completed
, we try to abort it immediately. If that fails (e.g. the play
function doesn't respond to the abort
event), then we reload the window.