How to add multiple components into one story using Storybook?
Asked Answered
S

2

7

I just started using storybook, and I need your help. I've four components for the different icons, and I want to create one story for all of them instead of creating story for each of them.

I've AllIcons.stories.tsx file and in this file I've this:

The problem is that I don't know what component I need to add in my export default object.

export default {
  title: "Icon",
  component: ListIcons,
} as Meta;

export const InterviewEndIconStory = (args: InterviewEndIconProps) => (
  <InterviewEndIcon {...args} />
);

export const RunCodeIconStory = (args: RunCodeIconProps) => (
  <RunCodeIcon {...args} />
);

export const TemplateEditIconStory = (args: TemplateEditIconProps) => (
  <TemplateEditIcon {...args} />
);

export const VideoOffIconStory = (args: VideoOffIconProps) => (
  <VideoOffIcon {...args} />
);
Saadi answered 27/1, 2022 at 12:36 Comment(3)
You probably need to show us how you're creating those stories? If you're creating a story in the form of a *.stories.tsx file, then it is just a matter of rendering the different icons in the same story container.Vermicular
i added some code in my question, could you check it out, pleaseSaadi
You can refer to the documentation by Storybook if that helps. storybook.js.org/docs/react/writing-stories/…Quintuplet
V
7

You can simply render all the buttons into a single react fragment, so that all buttons are bundled into a single story:

export default {
  title: "Icon",
  component: ListIcons,
} as Meta;

export const BaseStory = (args: InterviewEndIconProps) => (
  <>
    <InterviewEndIcon {...args} />
    <RunCodeIcon {...args} />
    <TemplateEditIcon {...args} />
    <VideoOffIcon {...args} />
  </>
);

If you foresee addition arbitrary number of icons in the future, you can instead store those components name in an array and iterate through them, so you don't have to repeat {...args} all the time. Probably a micro-optimisation at this point though ;)

const iconComponents = [
  'InterviewEndIcon',
  'RunCodeIcon',
  'TemplateEditIcon',
  'VideoOffIcon'
];

export const BaseStory = (args: InterviewEndIconProps) => (
  <>
    {iconComponents.map(IconComponent => {
      return <IconComponent key={IconComponent} {...args} />
    })}
  </>
);
Vermicular answered 27/1, 2022 at 13:18 Comment(0)
N
1

This was just what I was looking for. Another possible optimization here building off what @Terry suggested where you wouldn't need to list out each icon component by name could be:

import * as Icons from '../icons';
const icons = Object.values(Icons);

export const Icon: Story = (args: InterviewEndIconProps) => (
  <>
    {icons.map((IconComponent) => (
      <IconComponent key={IconComponent.name} {...args} />
    ))}
  </>
);

Assuming all your icon components are in the icons directory imported at the top of this snippet.

Nett answered 20/10, 2023 at 16:35 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.