Skip to content

Commit

Permalink
Merge pull request storybookjs#18214 from storybookjs/chore_docs_upda…
Browse files Browse the repository at this point in the history
…te_sidebar_csf3_auto_title

Chore: (Docs) Adds CSF 3.0 docs on auto title feature
  • Loading branch information
jonniebigodes authored May 13, 2022
2 parents 9e0a65d + 369e6a2 commit 385b7d7
Show file tree
Hide file tree
Showing 8 changed files with 119 additions and 29 deletions.
62 changes: 43 additions & 19 deletions docs/configure/sidebar-and-urls.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@
title: 'Sidebar & URLS'
---

Storybook’s sidebar lists all your stories grouped by component. When you have many components, you may also wish to group those components. To do so, you can add the `/` separator to the `title` of your CSF file and Storybook will group the stories into groups based on common prefixes:
Storybook’s sidebar lists all your stories grouped by component. When you have many components, you may also wish to group those components. To do so, you can add the `/` separator to the `title` of your CSF file, and Storybook will group the stories into groups based on common prefixes:

![Storybook sidebar anatomy](./sidebar-anatomy.jpg)

We recommend using a nesting scheme that mirrors the filesystem path of the components. For example, if you have a file `components/modals/Alert.js` name the CSF file `components/modals/Alert.stories.js` and title it `Components/Modals/Alert`.
We recommend using a nesting scheme that mirrors the filesystem path of the components. For example, if you have a file `components/modals/Alert.js`, name the CSF file `components/modals/Alert.stories.js` and title it `Components/Modals/Alert`.

## Roots

Expand All @@ -26,76 +26,100 @@ If you’d prefer to show top-level nodes as folders rather than roots, you can

<!-- prettier-ignore-end -->

## Automatically generate titles
## Permalink to stories

With CSF 3.0 files, you can choose to leave out a title and let it be inferred from the story's path on disk instead:
By default, Storybook generates an `id` for each story based on the component title and the story name. This `id` in particular is used in the URL for each story, and that URL can serve as a permalink (primarily when you [publish](../sharing/publish-storybook.md) your Storybook).

Consider the following story:

<!-- prettier-ignore-start -->

<CodeSnippets
paths={[
'common/component-story-auto-title.js.mdx',
'common/foo-bar-baz-story.js.mdx',
]}
/>

<!-- prettier-ignore-end -->

This is controlled by the way your stories are configured:
Storybook's ID-generation logic will give this the `id` `foo-bar--baz`, so the link would be `?path=/story/foo-bar--baz`.

It is possible to manually set the story's id, which is helpful if you want to rename stories without breaking permalinks. Suppose you want to change the position in the hierarchy to `OtherFoo/Bar` and the story name to `Moo`. Here's how to do that:

<!-- prettier-ignore-start -->

<CodeSnippets
paths={[
'common/component-story-configuration.js.mdx',
'common/other-foo-bar-story.js.mdx',
]}
/>

<!-- prettier-ignore-end -->

Given this configuration, the stories file `../src/components/MyComponent.stories.tsx` will get the title `components/MyComponent`.
Storybook will prioritize the `id` over the title for ID generation if provided and prioritize the `story.name` over the export key for display.

You can further customize the generated title by modifying the stories configuration.
## CSF 3.0 auto-titles

Storybook 6.4 introduced [CSF 3.0](https://storybook.js.org/blog/component-story-format-3-0/) as an experimental feature, allowing you to write stories more compactly. Suppose you're already using this format to write your stories. In that case, you can omit the `title` element from the default export and allow Storybook automatically infer it based on the file's physical location. For example, given the following configuration and story:

<!-- prettier-ignore-start -->

<CodeSnippets
paths={[
'common/component-story-configuration-custom.js.mdx',
'common/storybook-main-configuration-src-dir.main-js.js.mdx',
'common/component-story-auto-title.csf3-story.js.mdx',
]}
/>

<!-- prettier-ignore-end -->

This configuration would match a custom file pattern, and add a custom prefix of Foo to each generated title.
When Storybook loads, the story can show up in the sidebar as `components/My Component`.

## Permalinking to stories
### Auto-title filename case

By default, Storybook generates an `id` for each story based on the component title and the story name. This `id` in particular is used in the URL for each story, and that URL can serve as a permalink (primarily when you [publish](../sharing/publish-storybook.md) your Storybook).
Starting with Storybook 6.5, story titles generated automatically no longer rely on Lodash's [startCase](https://lodash.com/docs/#startCase).
Instead, the file name casing is preserved, allowing additional control over the story title. For example, `components/My Component` will be defined as `components/MyComponent`.

Consider the following story:
If you need, you can revert to the previous pattern by adding the following configuration:

<!-- prettier-ignore-start -->

<CodeSnippets
paths={[
'common/foo-bar-baz-story.js.mdx',
'common/storybook-manager-render-label-stories.js.mdx',
]}
/>

<!-- prettier-ignore-end -->

Storybook's ID-generation logic will give this the `id` `foo-bar--baz`, so the link would be `?path=/story/foo-bar--baz`.
### Auto-title redundant filenames

In addition to improvements to the story file name casing, a new heuristic was introduced, removing redundant names in case the filename has the same name as the directory name, or if it's called `index.stories.js|ts`. For example, before `components/MyComponent/MyComponent.stories.js` was defined as `Components/MyComponent/MyComponent` in the sidebar. Now it will be defined as `Components/MyComponent`.

It is possible to manually set the id of a story, which is helpful if you want to rename stories without breaking permalinks. Suppose you want to change the position in the hierarchy to `OtherFoo/Bar` and the story name to `Moo`. Here's how to do that:
If you need to preserve the naming scheme, you can add the `title` element to the default export. For example:

<!-- prettier-ignore-start -->

<CodeSnippets
paths={[
'common/other-foo-bar-story.js.mdx',
'common/storybook-csf-3-auto-title-redundant.js.mdx',
]}
/>

<!-- prettier-ignore-end -->

### Auto-title prefixes

Additionally, if you customize your Storybook to load your stories based on a [configuration object](./overview.md#with-a-configuration-object), including a `titlePrefix`, Storybook automatically prefixes all titles to matching stories. For example, assuming you have the following configuration:

<!-- prettier-ignore-start -->

<CodeSnippets
paths={[
'common/storybook-main-auto-title-custom.js.mdx',
]}
/>

<!-- prettier-ignore-end -->

Storybook will prioritize the `id` over the title for ID generation if provided and prioritize the `story.name` over the export key for display.
When Storybook generates the titles for all matching stories, they'll retain the `Custom` prefix.
16 changes: 16 additions & 0 deletions docs/snippets/common/component-story-auto-title.csf3-story.js.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
```js
// src/components/MyComponent.stories.js|jsx

import { MyComponent } from './MyComponent';

/**
* Story written in CSF 3.0 with auto title generation
* See https://storybook.js.org/docs/7.0/react/api/csf
* to learn more about it.
*/
export default { component: MyComponent };

export const Default = {
args: { message: 'Hello world!' },
};
```
4 changes: 0 additions & 4 deletions docs/snippets/common/component-story-auto-title.js.mdx

This file was deleted.

6 changes: 0 additions & 6 deletions docs/snippets/common/component-story-configuration.js.mdx

This file was deleted.

17 changes: 17 additions & 0 deletions docs/snippets/common/storybook-csf-3-auto-title-redundant.js.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
```js
// components/MyComponent/MyComponent.stories.js|jsx|ts|tsx

import { MyComponent } from './MyComponent.js'

export default {
component: MyComponent,
title: 'components/MyComponent/MyComponent',
};

export const Default = {
args: {
something: 'Something else',
},
};

```
15 changes: 15 additions & 0 deletions docs/snippets/common/storybook-main-auto-title-custom.js.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
```js
// .storybook/main.js

module.exports = {
stories: [{ directory: '../src', titlePrefix: 'Custom' }],
addons: [
'@storybook/addon-links',
'@storybook/addon-essentials',
'@storybook/addon-interactions',
],
core: {
builder: 'webpack5',
},
};
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
```js
// ./storybook/main.js

module.exports = {
stories: ['../src'],
addons: [
'@storybook/addon-links',
'@storybook/addon-essentials',
'@storybook/addon-interactions',
],
core: {
builder: 'webpack5'
},
};
```
13 changes: 13 additions & 0 deletions docs/snippets/common/storybook-manager-render-label-stories.js.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
```js
// .storybook/manager.js

import { addons } from '@storybook/addons';

import startCase from 'lodash/startCase';

addons.setConfig({
sidebar: {
renderLabel: ({ name, type }) => (type === 'story' ? name : startCase(name)),
},
});
```

0 comments on commit 385b7d7

Please sign in to comment.