Replies: 6 comments 14 replies
-
This sounds like a very good proposal! I also like that it will be possible to index docs and not only stories. As far as I can see, it fulfills all requirements I have on it in the context of native Vue SFC. If you like, I can test early prototypes of the indexer api in this setting. Concerning the half-sentence, "the addon will provide a vite and webpack plugin to transform those SFCs into CSF at load time" - why is it still necessary to generate CSF? Wouldn't it be better/more flexible/... if the second step would be a loader that returns the story object for a given storyid, without necessarily going through CSF. I understand that this may be more related to #23177, then the Indexer API in itself, but it is one of the main pain points I've encountered while working on the vue addon. |
Beta Was this translation helpful? Give feedback.
-
How about generating stories from dynamic fixture data (say an API call)? I’ve been hoping to do this for a while, it would simplify my integration a lot, but I’ve always put this off due to the uncertainty about edit: I see #23177 does specifically say Fixture data. Some users have fixture data in JSON, YAML, databases, or API servers and want to automatically turn this data into stories.. So I take it that this would still be possible, but only from API calls at build time? (since the Indexer API has async support)
I’m concerned to see this called out with this language, as to me it seems #23177 clearly states this Indexer API is intended as a replacement for people currently stuck with
This is the first time I see this formally described so apologies if this is obvious – is the presence of this index representation and its structure something that’s part of the stable API, that other tools could rely on? Again from my perspective for the purpose of integration with other pattern library tools, it’d be really useful to have control over adding entries to Storybook’s index (what this RFC solves), but also at other points inspecting what stories are defined in Storybook according to its parsing of CSF and Indexer API calls that happened at build time. |
Beta Was this translation helpful? Give feedback.
-
One more small remark: while implementing the indexer for the vue stories, I encountered the problem how to calculate the id of a story (based on the story name and some meta info), see tobiasdiez/storybook-vue-addon#38 (comment). If I read the proposal correctly, the indexer doesn't need to do this anymore and this is very good. |
Beta Was this translation helpful? Give feedback.
-
Thanks for your work on this proposal. I am trying to play around with the new Indexer API but I am confused about its usage (I know you are working on providing some documentation soon). I am using the addon manager API with the new experimental config // export of the addon for clients to add to their `addons: []` in `.storybook/main.ts`
const vueSFCIndexer: Indexer = {
test: /\.stories\.vue$/,
index,
}
export const experimental_indexers: StorybookConfig['experimental_indexers'] = existingIndexers => [
vueSFCIndexer,
].concat(existingIndexers || []) The export async function index(
fileName: string,
{ makeTitle }: IndexerOptions,
): Promise<IndexInput[]> {
const code = fs.readFileSync(fileName, { encoding: 'utf-8' }).toString()
const { meta, stories } = parseSFCStory(code)
return stories.map(({ title }) => ({
type: 'story',
importPath: fileName,
exportName: title,
title: makeTitle(meta.title),
}))
} If I am understanding correctly the
Will be up to our custom loader to make sure that Story will be transformed to CSF format (in this case the filename is pointing at
So for example, if my Is my understanding correct? |
Beta Was this translation helpful? Give feedback.
-
I just wanted to chime in, and I apologize if this isn't exactly what the Indexer API is meant to support (but it sounds closest to what I want). I haven't done a wide search yet on other issues/discussions. I am currently hacking Storybook into the Docusaurus lifecycle as a plugin. You can see it here as a WIP: Currently it's not ideal: I have to basically run the Storybook dev server side by side while Docusaurus is running and then embed the dev server URL to iframe stories into our docs. For a static build, it's a little easier, it's mainly dev that is sub-optimal. But in the end, we still are getting a separate "site" that isn't natively integrated with our own. What I "want" is a "headless" Storybook API so I can create a native Docusaurus integration. That's the long and short of it. For example, we use Typedoc and it's relatively easy to call their Node API and get a JSON data structure you can use to render your own UI. It's more work in userland but you get a native integration. That's exactly how the Docusaurus Typedoc plugin works and it's awesome. But AFAIK, before seeing this Indexing RFC, there's no way to call a core API and get all the data we'd need back to render a custom UI. Even the RFC specifies here that we'd need to still go through a builder/loader to get story metadata. This is the first time I have seen this but I did notice the indexing code when I was trying to figure this out last night, so I will be diving into this more. Perhaps what's there is enough I can piece together something, since the Indexer API gives me the import path which may be just enough + the builder. I'm happy to move this to a dedicated discussion but this seems like the type of use case this is meant to (at least partially) address. |
Beta Was this translation helpful? Give feedback.
-
I think currently the |
Beta Was this translation helpful? Give feedback.
-
Status: accepted
Tracked in: #23457
Summary
This proposes a new API for indexing stories and documents in Storybook. This makes it possible to support alternative syntaxes for stories and documents. For example, if somebody from the community wanted to support story authoring as Vue SFCs or docs in Markdown or Markdoc.
Problem Statement
Component Story Format (CSF) is a portable standard for capturing UI component examples. It is based on ECMAScript Modules (ESM), where the default export contains metadata about the component being documented, and each named export captures a key state of that component.
CSF has been incredibly successful in Storybook and has even been adopted by other tools in the frontend ecosystem. However, it has some key criticisms as well:
We want an API that makes it possible to solve these problems in a flexible way.
Non-goals
storiesOf
backwards compatibility. We are betting on static analysis and the solution described here is a “load-time” solution. We may provide a more dynamic solution in the future for dynamic “run-time” generating variants within a story and handling them sensibly across our tools.Implementation
To solve these problems, we propose a public indexer API for Storybook. The API would make it possible to extend Storybook in a variety of ways.
Existing architecture
Before introducing the API, let’s review Storybook’s architecture:
Config. Users define the files to index in
.storybook/main.js
. (The field is calledstories
, but should be renamed toindex
since it can contain docs as well, and potentially other types of entries in the future):Index. The index is a global listing of all the entries in your storybook. It’s an in-memory data structure that gets updated dynamically as the user updates the file system, and is also served at the URL endpoint
/index.json
in v7 storybooks. It also defines what appears in Storybook’s sidebar.Each file results in one or more entries in the index and in the sidebar. For example, consider this button example and its corresponding
index.json
entry and sidebar visualization.Implementation
The indexer is a function that generates zero or more index entries from an input file.
Note that this API only covers how to add
story
/docs
entries to the index. It does not specify how to load those files. For that, your addon or preset would need to provide some other kind of configuration, such as a webpack/vite plugin, to load theimportPath
using whatever builder the user has configured in their project. For example, if you are creating an addon for writing stories as Vue SFCs, the indexer will tell Storybook the list of stories available in each Vue SFC story file, and the addon will provide a vite and webpack plugin (possibly using unplugin for convenience) to transform those SFCs into CSF at load time. We will elaborate on this more as needed.Users can register the indexers in their
.storybook/main.js
config file and addons can register indexers using the presets API (which is the same asmain.js
).Examples
Fixture data
Consider the following addon that generates stories for components based on JSON fixture data. It looks for
jsonstories.js
files in the project and then for each such file, looks for.json
files in the same directory, each of which is added as a story.Combinatorial testing
Consider the following addon that supports combinatorial testing via an extra parameter
combos
in the default export which specifies the arg values to permute. It generates extra named exports of the formCombo0 ... ComboN
for each combination of args.Markdown docs
Consider the following addon that supports pure Markdown docs and uses the headmatter to optionally control the sidebar:
Prior Art
There is already an experimental indexer API in Storybook, it’s just not publicly documented. The primary difference in this proposal:
CSFFile
object, which is an implementation detail. The new API is a simple interface that doesn’t dictate an implementation.storyIndexers
. The new API isindexers
to reflect that it can also producedocs
entries.Deliverables
Risks
Unresolved Questions
CSFFile
does this, but is not ergonomic and we wouldn’t want to commit to this as a public API.Alternatives considered / Abandoned Ideas
No response
Beta Was this translation helpful? Give feedback.
All reactions