Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Docs: Adds table of contents documentation #23439

Merged
merged 2 commits into from
Jul 13, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions docs/snippets/angular/my-component-disable-toc.ts.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
```ts
// MyComponent.stories.ts

import type { Meta } from '@storybook/angular';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why does angular need its own snippet?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We ran into some issues in the past, with some users reporting that the examples weren't being depicted accurately for Angular, and we've adopted this strategy to avoid further confusion. I'm aware that it introduces a maintenance burden, but we're managing it and hopefully in the future this will no longer be required.


import { MyComponent } from './MyComponent.component';

const meta: Meta<MyComponent> = {
component: MyComponent,
tags: ['autodocs'],
parameters: {
docs: {
toc: {
disable: true, // 👈 Disables the table of contents
},
},
},
};

export default meta;
```
17 changes: 17 additions & 0 deletions docs/snippets/common/my-component-disable-toc.js.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
```js
// MyComponent.stories.js|jsx

import { MyComponent } from './MyComponent';

export default {
component: MyComponent,
tags: ['autodocs'],
parameters: {
docs: {
toc: {
disable: true, // 👈 Disables the table of contents
},
},
},
};
```
22 changes: 22 additions & 0 deletions docs/snippets/common/my-component-disable-toc.ts-4-9.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
```ts
// MyComponent.stories.ts|tsx

// Replace your-framework with the name of your framework
import type { Meta } from '@storybook/your-framework';

import { MyComponent } from './MyComponent';

const meta = {
component: MyComponent,
tags: ['autodocs'],
parameters: {
docs: {
toc: {
disable: true, // 👈 Disables the table of contents
},
},
},
} satisfies Meta<typeof MyComponent>;

export default meta;
```
22 changes: 22 additions & 0 deletions docs/snippets/common/my-component-disable-toc.ts.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
```ts
// MyComponent.stories.ts|tsx

// Replace your-framework with the name of your framework
import type { Meta } from '@storybook/your-framework';

import { MyComponent } from './MyComponent';

const meta: Meta<typeof MyComponent> = {
component: MyComponent,
tags: ['autodocs'],
parameters: {
docs: {
toc: {
disable: true, // 👈 Disables the table of contents
},
},
},
};

export default meta;
```
20 changes: 20 additions & 0 deletions docs/snippets/common/storybook-preview-custom-toc.js.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
```js
// .storybook/preview.js

export default {
parameters: {
docs: {
toc: {
contentsSelector: '.sbdocs-content',
headingSelector: 'h1, h2, h3',
ignoreSelector: '#primary',
title: 'Table of Contents',
disable: false,
unsafeTocbotOptions: {
orderedList: false,
},
},
},
},
};
```
25 changes: 25 additions & 0 deletions docs/snippets/common/storybook-preview-custom-toc.ts.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
```ts
// .storybook/preview.ts

// Replace your-framework with the framework you are using (e.g., react, vue3)
import { Preview } from '@storybook/your-framework';

const preview: Preview = {
parameters: {
docs: {
toc: {
contentsSelector: '.sbdocs-content',
headingSelector: 'h1, h2, h3',
ignoreSelector: '#primary',
title: 'Table of Contents',
disable: false,
unsafeTocbotOptions: {
orderedList: false,
},
},
},
},
};

export default preview;
```
11 changes: 11 additions & 0 deletions docs/snippets/common/storybook-preview-enable-toc.js.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
```js
// .storybook/preview.js

export default {
parameters: {
docs: {
toc: true, // 👈 Enables the table of contents
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you sure this typechecks?

Copy link
Contributor Author

@jonniebigodes jonniebigodes Jul 13, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Was able to get it running without any issues based on this TS reproduction and JS reproduction, and I was surprised that there weren't any typecheck issues.

},
},
};
```
16 changes: 16 additions & 0 deletions docs/snippets/common/storybook-preview-enable-toc.ts.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
```ts
// .storybook/preview.ts

// Replace your-framework with the framework you are using (e.g., react, vue3)
import { Preview } from '@storybook/your-framework';

const preview: Preview = {
parameters: {
docs: {
toc: true, // 👈 Enables the table of contents
},
},
};

export default preview;
```
15 changes: 15 additions & 0 deletions docs/snippets/web-components/my-component-disable-toc.js.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
```js
// MyComponent.stories.js

export default {
component: 'my-component',
tags: ['autodocs'],
parameters: {
docs: {
toc: {
disable: true, // 👈 Disables the table of contents
},
},
},
};
```
18 changes: 18 additions & 0 deletions docs/snippets/web-components/my-component-disable-toc.ts.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
```ts
// MyComponent.stories.ts

import type { Meta } from '@storybook/web-components';

const meta: Meta = {
component: 'my-component',
tags: ['autodocs'],
parameters: {
docs: {
toc: {
disable: true, // 👈 Disables the table of contents
},
},
},
};
export default meta;
```
87 changes: 83 additions & 4 deletions docs/writing-docs/autodocs.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,10 @@ By default, Storybook offers zero-config support for documentation and automatic

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

| Option | Description |
| ------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Option | Description |
| ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `autodocs` | Configures auto-generated documentation pages. Available options: `true`, `false`,`tag` (default). `true`/`false` enable/disable autodocs globally. `tag` allows you to opt in per component by adding the `tags: ['autodocs']` annotation in the component's default export. <br/> Default: `docs: { autodocs: false }` |
| `defaultName` | Renames the auto-generated documentation page<br/> Default: `docs: { defaultName: 'Documentation' }` |
| `defaultName` | Renames the auto-generated documentation page<br/> Default: `docs: { defaultName: 'Documentation' }` |

### Write a custom template

Expand All @@ -68,7 +68,7 @@ To replace the default documentation template used by Storybook, you can extend

<div class="aside">

💡 Internally, Storybook uses a similar implementation to generate the default template. See the Doc Blocks [API reference](./doc-blocks.md#available-blocks) if you want to learn more about how Doc Blocks work.
💡 Internally, Storybook uses a similar implementation to generate the default template. See the Doc Blocks [API reference](./doc-blocks.md#available-blocks) to learn more about how Doc Blocks work.

</div>

Expand Down Expand Up @@ -111,6 +111,69 @@ Then you can use it in your `.storybook/preview.js` or an individual story file

</div>

### Generate a table of contents

Storybook's auto-generated documentation pages can be quite long and difficult to navigate. To help with this, you can enable the table of contents feature to provide a quick overview of the documentation page and allow users to jump to a specific section. To enable it, extend your Storybook UI configuration file (i.e., `.storybook/preview.js`) and provide a `docs` [parameter](../writing-stories/parameters.md#global-parameters) with a `toc` property.

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

<CodeSnippets
paths={[
'common/storybook-preview-enable-toc.js.mdx',
'common/storybook-preview-enable-toc.ts.mdx',
]}
/>

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

### Configure the table of contents

To simplify navigation, the table of contents on the documentation page will only show the `h3` headings that are automatically generated. However, if you want to customize the table of contents, you can add more parameters to the `toc` property. The following options and examples of how to use them are available.
jonniebigodes marked this conversation as resolved.
Show resolved Hide resolved

| Option | Description |
| --------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
| `contentsSelector` | Defines the container's CSS selector for search for the headings <br/> `toc: { contentsSelector: '.sbdocs-content' }` |
| `disable` | Hides the table of contents for the documentation pages <br/> `toc: { disable: true }` |
| `headingSelector` | Defines the list of headings to feature in the table of contents <br/> `toc: { headingSelector: 'h1, h2, h3' }` |
| `ignoreSelector` | Configures the table of contents to ignore specific headings or stories <br/> `toc: { ignoreSelector: 'h2' }` |
| `title` | Defines a title caption for the table of contents. <br/>Accepts one of: `string`, `null`, React element <br/> `toc: { title: 'Table of Contents' }` |
| `unsafeTocbotOptions` | Provides additional [`TocBot`](https://tscanlin.github.io/tocbot/) configuration options <br/> `toc: { unsafeTocbotOptions: { orderedList: true } }` |

<div class="aside">

ℹ️ The `contentsSelector`, `headingSelector`, and `ignoreSelector` properties allow additional customization. For more information on using them, see the [`Tocbot` documentation](https://tscanlin.github.io/tocbot/).

</div>

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

<CodeSnippets
paths={[
'common/storybook-preview-custom-toc.js.mdx',
'common/storybook-preview-custom-toc.ts.mdx',
]}
/>

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

#### Component-level configuration

If you want to customize the table of contents for a specific story, you can include a `toc` property in the story's default export and provide the required [configuration](#configure-the-table-of-contents). For example, if you need to hide the table of contents for a specific story, adjust your story as follows:

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

<CodeSnippets
paths={[
'angular/my-component-disable-toc.ts.mdx',
'web-components/my-component-disable-toc.js.mdx',
'web-components/my-component-disable-toc.ts.mdx',
'common/my-component-disable-toc.js.mdx',
'common/my-component-disable-toc.ts.mdx',
]}
/>

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

### Customize component documentation

Creating automated documentation with Storybook's Autodocs provides you with the starting point to build a sustainable documentation pattern. Nevertheless, it may not be suited for every case, and you may want to extend it and provide additional information. We recommend combining [MDX](./mdx.md) alongside Storybook's [Doc Blocks](./doc-blocks.md) for such cases to author your documentation.
Expand Down Expand Up @@ -170,6 +233,22 @@ Out of the box, Storybook has a set of components that you can use to customize

## Troubleshooting

### The table of contents doesn't render as expected
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be under a Known limitations section?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I went with this approach to surface the issues that we're aware of and clearly mention them to the users without having them buried in that section of the documentation.


When using Autodocs's table of contents, you may encounter situations where it appears differently than expected. To help you resolve these problems, we have compiled a list of possible scenarios that may cause issues. If you've run into any of the items listed below and you're interested in helping us improve the support for this feature, we encourage you to reach out to the maintainers using the default communication channels (e.g., [Discord server](https://discord.com/channels/486522875931656193/570426522528382976), [GitHub issues](https://github.com/storybookjs/storybook/issues)).

#### With simple documentation pages

If you have a documentation page with only one matching heading and create a table of contents for it, the table of contents will not be hidden by default. A potential solution for this issue would be to add a second heading or turn it off entirely.

#### With small screens

If the screen width is less than 1200px, the table of contents will be hidden by default. Currently, there's no built-in solution for this issue that doesn't impact the documentation page's style compatibility.

#### With MDX

If you're writing [unattached documentation](./mdx.md#writing-unattached-documentation) using MDX, you cannot customize the table of contents primarily due to the lack of support for defining parameters based on the current implementation. As a result, the table of contents will always revert to the default [configuration](#configure-the-table-of-contents) provided globally.

### The auto-generated documentation is not showing up in a monorepo setup

Out of the box, Storybook's Autodocs feature is built to generate documentation for your stories automatically. Nevertheless, if you're working with a monorepo setup (e.g., [`Yarn Workspaces`](https://yarnpkg.com/features/workspaces), [`pnpm Workspaces`](https://pnpm.io/workspaces)), you may run into issues where part of the documentation may not be generated for you. To help you troubleshoot those issues, we've prepared some recommendations that might help you.
Expand Down