How to switch theme mode with TailwindCSS & Storybook
When working on a web application with Tailwind and Storybook you may want to add stories with the toggle theme feature for your components. This is a simple way to add it in a Vite + React Application.
Create the project
For this example, you can run the following command to scaffold the project.
npm create vite@latest my-project -- --template react
You will need to fill in the prompts with your project information.
Install TailwindCSS
Run the following commands to install the dependencies and init the TailwindCSS:
npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init -p
Add the file extension TailwindCSS should look for
/** @type {import('tailwindcss').Config} */ export default { content: ['./index.html', './src/**/*.{js,ts,jsx,tsx}'], theme: { extend: {}, }, plugins: [], };
Add the @tailwind directives for each of Tailwind’s layers to your ./src/index.css file.
@tailwind base; @tailwind components; @tailwind utilities; @layer base { body { @apply dark:bg-black dark:text-white min-h-screen relative; } }
Install Storybook
Use the Storybook CLI to install it in a single command.
npx storybook@latest init
Now we need to add Tailwind to the Storybook project.
Install the dependencies:
npm i -D @storybook/addon-styling postcss autoprefixer
Add the @storybook/addon-styling addon to your .storybook/main.js file.
Now you can import the tailwind.css file into your .storybook/preview.js file.
Now, use classes in your components used by the stories.
// Button.tsx export const Button = () => { return ( <button className='bg-blue-500 dark:bg-pink-600 text-white p-4 rounded-md shadow-2xl'> Click me </button> ); };
// Button.stories.tsx import type { Story, Meta } from '@storybook/react'; import { Button } from './Button'; const Story: Meta = { component: Button, title: 'Components/Button', }; export default Story; const Template: Story = (args) => <Button {...args} />; export const Default = Template.bind({});
Add the Dark Mode Switcher
First, add the darkMode option to the tailwind.config.js file
/** @type {import('tailwindcss').Config} */ export default { content: ['./index.html', './src/**/*.{js,ts,jsx,tsx}'], theme: { extend: {}, }, plugins: [], darkMode: ['class', '[data-mode="dark"]'], };
Then add the withThemeByDataAttribute decorator to your storybook from @storybook/addon-styling.
// .storybook/preview.js import { withThemeByDataAttribute } from '@storybook/addon-styling'; export const decorators = [ withThemeByDataAttribute({ themes: { light: 'light', dark: 'dark', }, defaultTheme: 'light', attributeName: 'data-mode', }), ];
Enjoy.