Open sregg opened 11 months ago
I just found this: https://storybook.js.org/addons/storybook-addon-variants It'd be great to support this on mobile or build something similar.
You can pretty easily make something like this happen with csf, excuse the formatting I'm just doing this from memory.
const meta = {
title: "Button",
component: Button,
}
export const Story1 = {
args: {
text: "text1"
}
}
export const Story2 = {
args: {
text: "text2"
}
}
export const AllStory = {
render ()=>{
return (<>
<Button {...Story1.args}>
<Button {...Story2.args}>
</>)
}
}
Nice! I didn't know about this render()
function 🎉
Looks like we could automatize this though.
import React from 'react';
import { CookStats } from './CookStats';
import type { Meta, StoryObj } from '@storybook/react-native';
import type { CookStatsProps } from './types';
import { InlineStorySectionHeader } from '~/storybook/components/InlineStorySectionHeader';
const CookStatsMeta = {
title: 'Components/CookStats',
component: CookStats,
args: {
size: 'large',
distanceFromCustomer: '3.8mi',
},
argTypes: {
size: {
type: { name: 'enum', value: ['small', 'large'] },
},
},
} as Meta<CookStatsProps>;
export default CookStatsMeta;
export const WithEverything: StoryObj<CookStatsProps> = {
args: {
orderCount: 1126,
averageRating: 4.7,
ratingCount: 304,
},
};
export const NoOrderCount: StoryObj<CookStatsProps> = {
args: {
averageRating: 4.2,
ratingCount: 304,
},
};
export const NoRating: StoryObj<CookStatsProps> = {
args: {
orderCount: 19,
},
};
export const NoOrderCountNoRating: StoryObj<CookStatsProps> = {
args: {},
};
export const All: StoryObj<CookStatsProps> = {
render: () => (
<>
<InlineStorySectionHeader title="WithEverything" />
<CookStats
{...(CookStatsMeta.args as CookStatsProps)}
{...WithEverything.args}
/>
<InlineStorySectionHeader title="NoOrderCount" />
<CookStats
{...(CookStatsMeta.args as CookStatsProps)}
{...NoOrderCount.args}
/>
<InlineStorySectionHeader title="NoRating" />
<CookStats
{...(CookStatsMeta.args as CookStatsProps)}
{...NoRating.args}
/>
<InlineStorySectionHeader title="NoOrderCountNoRating" />
<CookStats
{...(CookStatsMeta.args as CookStatsProps)}
{...NoOrderCountNoRating.args}
/>
</>
),
};
I can create a util function that I can reuse in my project:
export function renderAllStories<T>(meta: Meta<T>, stories: StoryObj<T>[]) {
return (
<>
{stories.map((story, index) => (
<Fragment key={index}>
<InlineStorySectionHeader title={story.name ?? ''} />
{meta.component && <meta.component {...meta.args} {...story.args} />}
</Fragment>
))}
</>
);
}
and use it like so:
export const All: StoryObj<CookStatsProps> = {
render: () =>
renderAllStories(CookStatsMeta, [
WithEverything,
NoOrderCount,
NoRating,
NoOrderCountNoRating,
]),
};
Small question: how does Storybook get the name of the story objects (e.g. WithEverything
)?
when you import/require a module it has all the named exports and the default export in there like
module.exports = {
Name1: { stuff here}
default: {meta stuff here}
}
so when you import that file its like
const file = require("location")
this file has all of those things
so yeah you could actually do this more automated yet probably by getting the current module and looping through it
@sregg since you can get the current module from just accessing "module", you should be able to do this:
export const AllStory = {
render: () => {
return (
<>
{Object.entries(module.exports)
.filter(([key, _val]) => key !== "default")
.map(([key, val]) => {
if (val.args) {
return <Icon key={key} {...val.args} />;
}
})}
</>
);
},
};
Sounds good. I'll see if I have time to build that into this package itself.
Maybe with a showAllStoriesStory
flag in Meta
.
Is your feature request related to a problem? Please describe. When I have a lot of stories for a given component, it can be tedious to switch stories (i.e. side bar, click story, side bar, click story, etc...). I'd like to be able to see all stories in one screen. Especially for small components like buttons or list items.
Describe the solution you'd like It'd be great to have the ability to automatically add an "All" story where all stories are rendered after an other with their title.
Describe alternatives you've considered Infinite Red's Ignite had some cool components like
UseCase
for achieving this (see PR when they removed all that here) but the new CSF format doesn't support this (i.e. you can't easily render multiple components in one story).Are you able to assist bring the feature to reality? Yes!
Additional context Example of Story in Ignite:
Something similar but automated would be awesome.