Skip to main content
Version: 3.x

Add a component to Storybook

Our goal with Front-Commerce is to give you the tools you need to develop a delightful user experience within your e-commerce shop. One of these tools is a Design System.

The concept lying behind a Design System is to document how your brand communicates with its users. This goes from global guides such as "Voice and tone", "Code Convention", "Accessibility"… to components documentation that focus on where and how to use a specific component.

Such a Design System should be customized to the way your team(s) work and should evolve according to your needs. But with Front-Commerce, we provide you a base you can iterate on.

Technically, we use Storybook which is a tool that references stories for each component you want to document. With these stories, it will launch for you a website that allows you to browse through your components.

In this guide we will go through a basic tutorial that gets you started with writing stories within Front-Commerce. But if you want to learn more about Storybook, please refer to its documentation.

Add your own story

In order to add your own story, you need to create a new file, that will document how to use a component and will reference each edge case for this component. Each case will be what we call a story.

As explained in Storybook's documentation:

A story captures the rendered state of a UI component.

To do this, you will create a .stories.tsx file next to your component. In this example, we will use the same component as in Create a UI Component: IllustratedContent.tsx. Hence, your stories file will be IllustratedContent.stories.tsx and will look like this:

app/theme/components/molecules/IllustratedContent/IllustratedContent.stories.tsx
import type { Meta, StoryObj } from "@storybook/react";
import IllustratedContent from "./IllustratedContent";
import Icon from "theme/components/atoms/Icon";
import { H3 } from "theme/components/atoms/Typography/Heading";

const meta: Meta<typeof IllustratedContent> = {
component: IllustratedContent,
};

export default meta;

type Story = StoryObj<typeof IllustratedContent>;

export const Default: Story = {
render: () => (
<IllustratedContent media={<Icon title="calendar" icon="calendar-full" />}>
<H3>Shipping within 48h</H3>
</IllustratedContent>
),
};

Thanks to this file, when you launch Storybook (pnpm run styleguide), it will register the stories for the component IllustratedContent. It will make it accessible in the Storybook's website under app > theme > components > molecules > IllustratedContent. And if you click on the Default story in the navigation, it will display a default story which will show the standard usecase of the IllustratedContent component.

Storybook interface with the IllustratedContent&#39;s default story selected

note

As you might have noticed, once you have added the above IllustratedContent story, if you edit the story or the component itself, it will update automatically in Storybook (this feature is called hot reloading). It greatly improves the experience of authoring UI components.

For now, we've registered only one story for the IllustratedContent. But you can add more to better explain edge cases of your component. For instance you could add a story with a very long content or with an <Image /> instead of an <Icon /> in order to better see how it will behave.

app/theme/components/molecules/IllustratedContent/IllustratedContent.stories.tsx
import type { Meta, StoryObj } from "@storybook/react";
import IllustratedContent from "./IllustratedContent";
import Icon from "theme/components/atoms/Icon";
import { H3 } from "theme/components/atoms/Typography/Heading";
import { BodyParagraph } from "theme/components/atoms/Typography/Body";
import Image from "theme/components/atoms/Image";

const meta: Meta<typeof IllustratedContent> = {
title: "My App/Components/Molecules/IllustratedContent",
component: IllustratedContent,
};

export default meta;

type Story = StoryObj<typeof IllustratedContent>;

export const Default: Story = {
render: () => (
<IllustratedContent media={<Icon title="calendar" icon="calendar-full" />}>
<H3>Shipping within 48h</H3>
</IllustratedContent>
),
};

export const WithContent: Story = {
name: "With a lot of content",
render: () => (
<IllustratedContent media={<Icon title="calendar" icon="calendar-full" />}>
<H3>Shipping within 48h</H3>
<BodyParagraph>
We are using many delivery services to let you choose what is best for
you!
</BodyParagraph>
</IllustratedContent>
),
};

export const WithImage: Story = {
name: "With an image",
render: () => (
<IllustratedContent
media={<Image src="https://placehold.co/600x400" alt="Placeholder" />}
>
<H3>Shipping within 48h</H3>
</IllustratedContent>
),
};

Storybook interface with many IllustratedContent&#39;s stories

This can be a nice and efficient way to show your designer how the implementation will behave and ask for feedback to improve the User Experience.

info

You can see that we added a title key in the meta object. This is a way to organize your stories in Storybook. It will create a new section in the navigation with the title you provided. In this example, the IllustratedContent stories will be displayed under My App > Components > Molecules > IllustratedContent.

We recommend organizing your stories, especially because we will explain something later that will require having an organized structure.

More information about the title key can be found in the Storybook's documentation.

Add a new usecase to an existing story

There are some cases where the story already exists but you want to add a new edge case. This will usually happen when you override a core component of Front-Commerce and you want to update its story to document the new use case.

In this example, we will consider that you have overridden and updated the Money component (as explained in Override a component) to add a new property hasBorder.

To add this story, you will need to override the Money.stories.tsx in the same way you overrode the Money.tsx. This means that you should copy the existing story from node_modules/@front-commerce/theme-chocolatine/theme/components/atoms/Typography/Money/Money.stories.tsx to app/theme/components/atoms/Typography/Money/Money.stories.tsx.

Once you have copied the file, you need to change the title key in the meta object. In our example, you can either modify the base title (e.g., title: "Components/Atoms/Typography/MoneyOverride",) or change the organization to fit your application (e.g., title: "My App/Components/Atoms/Typography/Money",).

app/theme/components/atoms/Typography/Money/Money.stories.tsx
// ... existing code
const meta: Meta<MoneyWithFlatProps> = {
title: "My App/Components/Atoms/Typography/Money",
tags: ["autodocs"],
component: Money,
// ... existing code
};

Then, you can add override stories to document the new use case. In this example, we will add the new hasBorder property to the Money component.

app/theme/components/atoms/Typography/Money/Money.stories.tsx
// ... existing code
argTypes: {
"value.amount": {
control: "number",
},
"value.currency": {
control: "select",
options: currenciesAllowedList as any as CurrencyType[],
},
hasBorder: {
control: "boolean",
},
},
args: {
"value.amount": 19999,
"value.currency": currenciesAllowedList[0],
hasBorder: false,
},
// ... existing code

Create stories for complex components

WIP

This section is currently being migrated.

Display only the relevant stories to your Design System

If you run the styleguide for your own project, you may notice that Front-Commerce comes with a lot of stories. This is what serves as documentation Front-Commerce base theme's core components.

However, you might not use each one of them in your final theme, and some stories might become irrelevant in your design system. To choose which ones to display, you need to update the .storybook/main.ts configuration file, and add the key stories.

.storybook/main.ts
# ...existing code
export default {
- stories: ["../**/*.stories.@(js|jsx|mjs|ts|tsx)", ...extensionThemeStories],
+ stories: ["../app/**/*.stories.@(js|jsx|mjs|ts|tsx)"],
addons: [
# ...existing code
],
}

This configuration ensures that Storybook does not load unnecessary files, improving performance and organization. Additionally, you can exclude certain folders by adjusting the glob patterns.

Automatic documentation

Storybook provides automatic documentation for your components. It can display description, prop tables, usage examples and interactive controls automatically.

Here is the way to add automatic documentation to your stories based on our IllustratedContent example:

app/theme/components/molecules/IllustratedContent/IllustratedContent.stories.tsx
const meta: Meta<typeof IllustratedContent> = {
title: "My App/Components/Molecules/IllustratedContent",
component: IllustratedContent,
tags: ["autodocs"],
parameters: {
docs: {
description: {
component: "A component that displays an image or an icon with text.",
},
},
},
};

You can now see the documentation of your component in Storybook:

Storybook interface with the IllustratedContent&#39;s default story selected*

For a more detailed documentation example, you can refer to the Money story example.

For further details, please check the official Storybook documentation.