This repo is the example of adoption storybook for solid-js.
Thanks to guys from this thread: solidjs/solid-docs#35
Everything works out of the box. Don't forget to render JSX component in your story file to make HMR work (see Counter.stories.tsx
file).
You need to change the following files.
1. .storybook/main.js
module.exports = {
stories: ["../src/**/*.mdx", "../src/**/*.stories.@(js|jsx|ts|tsx)"],
addons: [
"@storybook/addon-links",
"@storybook/addon-essentials",
"@storybook/addon-interactions",
],
framework: {
name: "@storybook/html-vite",
options: {},
},
docs: {
autodocs: "tag",
},
};
2. .storybook/preview.js
If you want HMR works for solid you need to add /* @refresh reload */
to the beginning of this file however it's not the only change.
See the details below.
/* @refresh reload */
/**
* Don't forget the line above for HMR!
*
* Note: for some reason HMR breaks if you change .stories file,
* however reloading the page fixes this issue
*/
import { render } from "solid-js/web";
export const decorators = [
(Story) => {
const solidRoot = document.createElement("div");
render(Story, solidRoot);
return solidRoot;
},
];
/** Autogenerated by Storybook */
export const parameters = {
actions: { argTypesRegex: "^on[A-Z].*" },
controls: {
matchers: {
color: /(background|color)$/i,
date: /Date$/,
},
},
};
That's it!
To make HMR work for your component you need to render it as JSX:
// Correct! HMR works!
// Let's assume that this is storybook meta object
export default {
// ...
render: (props) => <Counter {...props} />,
// ...
} as Meta<ComponentProps<typeof Counter>>;
If you write the code like this, it won't work:
// Wrong! HMR doesn't work!
// Let's assume that this is storybook meta object
export default {
// ...
render: Counter,
// ...
} as Meta<ComponentProps<typeof Counter>>;
Here's an example story for Counter
component.
import { Counter, CounterProps } from "../Counter";
import type { Meta, StoryObj } from "@storybook/html";
import type { ComponentProps } from "solid-js";
type Story = StoryObj<CounterProps>;
export const Default: Story = {
args: {
initialValue: 12,
theme: "default",
},
};
export default {
title: "Example/Counter",
tags: ["autodocs"],
/**
* Here you need to render JSX for HMR work!
*
* render: Counter won't trigger HMR updates
*/
render: (props) => <Counter {...props} />,
argTypes: {
initialValue: { control: "number" },
theme: {
options: ["default", "red"],
control: { type: "radio" },
},
},
} as Meta<ComponentProps<typeof Counter>>;
To see the files for the storybook v6 see THIS.
1. Initialize storybook in your repo as html project:
npx storybook init --type html
main.js
Add vite-plugin-solid
to storybook config.
const Solid = require("vite-plugin-solid");
module.exports = {
stories: ["../src/**/*.stories.mdx", "../src/**/*.stories.@(js|jsx|ts|tsx)"],
addons: [
"@storybook/addon-links",
"@storybook/addon-essentials",
"@storybook/addon-interactions",
],
framework: "@storybook/html",
core: {
builder: "@storybook/builder-vite",
},
features: {
storyStoreV7: true,
},
// Add solid plugin here
async viteFinal(config, { configType }) {
config.plugins.unshift(Solid({ hot: false }));
return config;
},
};
preview.js
Customize your preview.js
file as follows.
import { render } from "solid-js/web";
export const parameters = {
actions: { argTypesRegex: "^on[A-Z].*" },
controls: {
matchers: {
color: /(background|color)$/i,
date: /Date$/,
},
},
};
export const decorators = [
(Story) => {
const root = document.getElementById("root");
const solidRoot = document.createElement("div");
solidRoot.setAttribute("id", "solid-root");
root.appendChild(solidRoot);
render(Story, solidRoot);
return solidRoot;
// return createRoot(() => Story()); // do not work correctly https://github.com/solidjs/solid/issues/553
},
];
- .npmrc file is necessary because I use npm v8, however storybook doesn't support it, and that's why it requires this file.