Storybook Sidebar Roots Grouping

When your application grows, you may find yourself short on taxonomy with the default tools Storybook provides.

For example, you may want an extra layer of titles on top of roots for grouping.

As per Storybook@9.1.6 or Storybook@10.0.0-beta.5, this is not possible out of the box and there are no plugins available.
So, in this tutorial, we’ll see how to circumvent that and add an extra title on top of the roots in the sidebar.

Approach

To simulate a grouping UI with an extra title on top of the roots in the sidebar, we’ll use:

  1. add an MDX file to create the title
  2. custom styles in manager-head.html
  3. sorting the stories in preview.ts

Assumptions and wanted result

Let’s assume we have the following.

└──src
     └── components
          ├── button
          │    ├── Button.stories.tsx
          │    └── Button.tsx
          ├── list
          │    ├── List.stories.tsx
          │    └── List.tsx
          ├── navigation
          │    ├── Navigation.stories.tsx
          │    └── Navigation.tsx
          ├── single-column
          │    ├── SingleColumn.stories.tsx
          │    └── SingleColumn.tsx
          └── top-bar
               ├── TopBar.stories.tsx
               └── TopBar.tsx

And the taxonomy we want to achieve is:

╔═ Components ══════╗
║                   ║ 
║  ├── Content      ║ 
║  ├── Navigation   ║ 
║  └── Layouts      ║ 
║                   ║ 
╚═══════════════════╝

1. add an MDX file to create the title

touch src/components/Components.mdx and in there we add:

import { Meta } from '@storybook/addon-docs/blocks';
 
<Meta title="Components/Home" />

This will create the Root component and the sub-item home.

2. custom styles in manager-head.html

touch .storybook/manager-head.html and in there we add:

<style>
#components {
    border-top: 1px solid #ddd;
    padding-top: 5px;
    color: black;
    padding-bottom: 0;
    margin-bottom: -10px;
}

div#components div {
    display: none;
}

div#components button {
    font-weight: bold;
    color: black;
    font-size: 12px;
}

div#components .sidebar-subheading-action {
    display: none;
}

#components + .sidebar-item {
    display: none;
}
</style>

This will turn the Root into a different style, it will hide the Home sub-item and the collapse expand button.

You can change this as you need.

3. sorting the stories in preview.ts

In preview, we’ll have Components to be on top.

import type { Preview } from "@storybook/react-vite";

const preview: Preview = {
    parameters: {
        controls: {
            matchers: {
                color: /(background|color)$/i,
                date: /Date$/i,
            },
        },
        options: {
            storySort: {
                method: "",
                order: [
                    "Components",
                    "Content",
                    "Navigation",
                    "Layout",
                ],
                locales: "",
            }
        }
    },
};

export default preview;

After this, we’ll still need to reorganise the taxonomy in our stories.
Eg, for List:

import { Meta, StoryObj } from "@storybook/react-vite";
import { action } from "storybook/actions";

import List from "./List";

const meta: Meta<typeof List> = {
    title: "Content/List",
    component: List,
    decorators: [
        (Story) =>
            <body className="bg-light h-100">
                <Story />
            </body>
    ]
};

export default meta;

type Story = StoryObj<typeof List>;

Considerations

Some last words.

Please consider that this is a quick hack to have a group title. As such, there is the risk of Storybook changing the classname or any of the items used in this tutorial. However, this approach is currently working on versions 9 and 10.0.0-beta.5.

Anyway, even a plugin would be subject to the same risk if there were any, with the difference that it would be a black box, and you would not have control over it.

Lastly, note that some work is involved in scaling, as you’ll need to replicate this procedure for each new group title.