- Install Storybook 10 with @storybook/react-vite framework - Fix React Router Vite plugin conflict by filtering it out in viteFinal (reactRouter() returns a plugin array, so the filter must flatten first) - Integrate Storybook stories as a vitest browser project via @storybook/addon-vitest - Point stories glob at app/ instead of scaffold stories/ dir - Remove unused @chromatic-com/storybook and @storybook/addon-onboarding addons - Clean up duplicate __dirname in vitest.config.ts Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
41 lines
No EOL
1.4 KiB
TypeScript
41 lines
No EOL
1.4 KiB
TypeScript
import type { StorybookConfig } from '@storybook/react-vite';
|
|
import type { PluginOption } from 'vite';
|
|
|
|
const sbConfig: StorybookConfig = {
|
|
"stories": [
|
|
"../app/**/*.mdx",
|
|
"../app/**/*.stories.@(js|jsx|mjs|ts|tsx)"
|
|
],
|
|
"addons": [
|
|
"@storybook/addon-vitest",
|
|
"@storybook/addon-a11y",
|
|
"@storybook/addon-docs",
|
|
"storybook-addon-remix-react-router"
|
|
],
|
|
"framework": "@storybook/react-vite",
|
|
async viteFinal(config) {
|
|
// React Router's Vite plugin throws if not used with a vite config file,
|
|
// so we must remove it (and the Sentry wrapper that includes it) from the
|
|
// Storybook build. reactRouter() returns an array of plugins, so we need
|
|
// to flatten before filtering.
|
|
const EXCLUDED_PREFIXES = ["react-router", "sentry-react-router"];
|
|
|
|
function flatFilter(plugins: PluginOption[]): PluginOption[] {
|
|
return plugins
|
|
.filter((p) => p !== null && p !== undefined)
|
|
.flatMap((p) => (Array.isArray(p) ? flatFilter(p) : [p]))
|
|
.filter((p) => {
|
|
if (typeof p === "object" && p !== null && "name" in p && typeof p.name === "string") {
|
|
return !EXCLUDED_PREFIXES.some(
|
|
(prefix) => p.name === prefix || (p.name as string).startsWith(prefix + ":")
|
|
);
|
|
}
|
|
return true;
|
|
});
|
|
}
|
|
|
|
config.plugins = flatFilter(config.plugins ?? []);
|
|
return config;
|
|
},
|
|
};
|
|
export default sbConfig; |