Comments (5)
Our rationale for moving away from storiesOf
in Storybook is that we can statically analyze CSF, which allows us to (1) generate a list of all the stories without needing to evaluate them, (2) bundle / evaluate stories on demand.
This enables significant optimizations, especially for large storybooks. It also allows us to extract story metadata in Node, which can be brittle in JSDom.
We're also looking at several different alternative approaches to satisfy the use cases listed here and in Storybook's corresponding issue storybookjs/storybook#9828, and will be creating an RFC once we think we've got a suitable answer to storiesOf
users.
Here are a few different directions we're considering:
- programmatically generated stories using a stylized syntax
- programmatically generated visual tests against a story, similar to how today it's possible to test with multiple viewports, you could also test it in different themes, locales, etc.
- a stylized way to generate a grid of variants within a single story
- a programmatic loader similar to @probablyup 's suggestion above, so that e.g. it would be possible to generate stories based on JSON data in fixture files
I'd also love to hear @tajo 's take on things!
from ladle.
@tajo That makes a ton of sense. I mentioned collaborating on future iterations of CSF before--perhaps this is an area we can improve in a future iteration. It would be a disruptive change, but if it solves a key architectural problem in both tools and we had a clean solution & migration path, I could definitely be convinced. I think we'll be revisiting argTypes in 7.x, so I'll loop you in once we have something worth discussing.
from ladle.
Came to say the same thing; we have a setup where we autogenerate story variants with different themes, color modes, and sometimes combinations of props that don't need a proper story but should be snapshotted:
export function snapshotVariantsForVisualTesting(stories: DSIStories, options: DSIStoryConfig<any>) {
stories.forEach(([name, Story]) => {
// create unique suite instances for each so we can compose decorators per-story
const suite = storiesOf('Variants', module);
Story.decorators?.forEach((decorator) => suite.addDecorator(decorator));
options.decorators?.forEach((decorator) => suite.addDecorator(decorator));
const baseProps = {
...(options.argTypes
? Object.entries(options.argTypes).reduce(
// @ts-ignore
(map, [key, value]) => ((map[key as keyof Props] = 'action' in value ? value : value.defaultValue), map),
{} as Record<string, unknown>
)
: undefined),
...options.args!,
...Story.args!,
};
const argTypes = { ...options.argTypes, ...Story.argTypes };
const shouldSnapshotAlternateThemes =
Story.snapshotAlternateThemes !== undefined ? Story.snapshotAlternateThemes : options.snapshotAlternateThemes;
const shouldSnapshotDarkMode =
Story.snapshotDarkMode !== undefined ? Story.snapshotDarkMode : options.snapshotDarkMode;
const shouldSnapshotPropVariants = (
Story.snapshotPropVariants !== undefined
? { ...options.snapshotPropVariants, ...Story.snapshotPropVariants }
: options.snapshotPropVariants
) as { [key: string]: any[] };
if (shouldSnapshotPropVariants) {
Object.entries(shouldSnapshotPropVariants).forEach(([key, value]) => {
value.forEach((propValue) => {
suite.add(
`${name} [prop "${key}" ${propValue}]`,
(props: any) => (
<Story
{...merge(baseProps, props, {
[key]: argTypes[key]?.mapping ? argTypes[key]?.mapping[propValue] : propValue,
})}
/>
),
Story.parameters
);
});
});
}
if (shouldSnapshotDarkMode) {
suite.add(
`${name} [Dark Mode]`,
(props: any) => (
<DarkMode>
<Story {...merge(baseProps, props)} />
</DarkMode>
),
Story.parameters
);
if (shouldSnapshotPropVariants) {
Object.entries(shouldSnapshotPropVariants).forEach(([key, value]) => {
const variants = Array.isArray(value) ? value : ([] as any[]).concat(value);
variants.forEach((propValue) => {
suite.add(
`${name} [Dark Mode] [prop "${key}" ${propValue}]`,
(props: any) => (
<DarkMode>
<Story
{...merge(baseProps, props, {
[key]: argTypes[key]?.mapping ? argTypes[key]?.mapping[propValue] : propValue,
})}
/>
</DarkMode>
),
Story.parameters
);
});
});
}
}
if (shouldSnapshotAlternateThemes) {
otherThemes.forEach(([themeName, theme]) => {
suite.add(
`${name} [${themeName} Theme]`,
(props: any) => (
<DSStyleProvider theme={theme}>
<Story {...merge(baseProps, props)} />
</DSStyleProvider>
),
Story.parameters
);
if (shouldSnapshotDarkMode) {
suite.add(
`${name} [${themeName} Theme] [Dark Mode]`,
(props: any) => (
<DSStyleProvider theme={theme}>
<DarkMode>
<Story {...merge(baseProps, props)} />
</DarkMode>
</DSStyleProvider>
),
Story.parameters
);
}
});
}
});
}
A first-party way to do this inside CSF would be fantastic, perhaps an optional transformer on the default export that allows for generation of variants?
from ladle.
Our rationale for moving away from storiesOf in Storybook is that we can statically analyze CSF, which allows us to (1) generate a list of all the stories without needing to evaluate them, (2) bundle / evaluate stories on demand.
This enables significant optimizations, especially for large storybooks. It also allows us to extract story metadata in Node, which can be brittle in JSDom.
💯 This is exactly the reason why Ladle doesn't and can't have storiesOf
like syntax.
When it comes to snapshot testing including different variants of your stories, you can do it already.
Ladle serializes all its state into the URL including things like controls, theme and RTL. So if you are running some Playwright script opening stories and taking their screenshots, your real problem is to generate URLs exhausting all the stories and their variants - we could provide some utilities for that.
There is one obstacle - args
/ argTypes
are not statically analyzable. I really wish they would be because we could export them as a part of meta.json and that would make it really easy to create those testing URLs. @shilman I guess that's why storybook is exploring some of the mentioned options?
from ladle.
There will be some new development when it comes to test automation with Ladle. Not using storiesOf
though.
from ladle.
Related Issues (20)
- Version 3 supports only React 18+, it's an undocumented breaking change HOT 1
- Deno support HOT 1
- Allow duplicate story name HOT 2
- Missing Accessibility Report button with @ladle/react v3.1.0 and up HOT 2
- ladle.css leaks on @reach/dialog inside stories HOT 1
- Internal server error: Header name must be a valid HTTP token [":path"] HOT 2
- ladle build error HOT 3
- Should the msw implementation be created as an independent plugin? HOT 2
- RTL config using MDX code block breaks formatting HOT 1
- Stylesheet ordering bug with @mui/material and styled-components HOT 9
- Range control with a default value of zero does not adopt default value
- Source maps are broken
- MDX anchor links do not work
- Allow exports in `export` block HOT 5
- Toggling view should retail the filter query
- Vite HMR config does not override Ladle default config HOT 2
- Ladle seems to conflict with remix vite plugin HOT 4
- Allow export function which are not in the same file HOT 2
- Code blocks in .mdx files display warnings in browser console HOT 1
- Embeddable Isolated Story HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from ladle.