Programs Used:
- React 18.1
- NextJS 12.1.6
- Tailwind 3.0.24
- Typescript 4.7.3
- Storybook 6.5.7
The Configuration
In your terminal, add next-js and typescript.
npx create-next-app@latest --typescript <project-name></project-name>
Change the directory.
cd <project-name>
Add Tailwind, PostCSS, and Autoprefixer.
npm install tailwindcss@latest postcss@latest autoprefixer@latest
Initialize Tailwind and PostCSS. (The “-p” creates a postCSS config file.)
npx tailwindcss init -p
Add an “.nvmrc” file to your project. Open the file and add your version number of node (example “14.17.6”).
14.17.6
Open tailwind.config.js and set content like this:
module.exports = {
content: [
"./pages/**/*.{ts,tsx}"
],
theme: {
extend: {},
},
plugins: [],
}
Open “styles/global.css” and add Tailwind.
@tailwind base;
@tailwind components;
@tailwind utilities;
Add Sass.
npm install --save-dev sass
Add Storybook.
npx sb init --builder webpack5
Reference the Tailwind CSS file and configure NextJS. Open “.storybook/preview.js” and import globals.css and NextJS configuration:
// .storybook/preview.js
import "../styles/globals.css";
export const parameters = {
actions: { argTypesRegex: "^on[A-Z].*" },
controls: {
matchers: {
color: /(background|color)$/i,
date: /Date$/,
},
},
}
import * as NextImage from "next/image";
const OriginalNextImage = NextImage.default;
Object.defineProperty(NextImage, "default", {
configurable: true,
value: (props) => typeof props.src === 'string' ? (
<OriginalNextImage {...props} unoptimized blurDataURL={props.src} />
) : (
<OriginalNextImage {...props} unoptimized />
),
});
Object.defineProperty(NextImage, "__esModule", {
configurable: true,
value: true
});
Update the tailwind.config.js file.Storybook adds a “stories” directory in your project. Add a reference to it in the config like this:
module.exports = {
content: [
"./pages/**/*.{ts,tsx}",
"./stories/**/*.{ts,tsx}",
],
theme: {
extend: {},
},
plugins: [],
}
Configure Storybook for postcss. Open “.storybook/main.js” and change code like this:
module.exports = {
"stories": [
"../stories/**/*.stories.mdx",
"../stories/**/*.stories.@(js|jsx|ts|tsx)"
],
"addons": [
"@storybook/addon-links",
"@storybook/addon-essentials",
"@storybook/addon-interactions",
// Add PostCSS into addons for compiling tailwind below
{
name: '@storybook/addon-postcss',
options: {
postcssLoaderOptions: {
implementation: require('postcss'),
},
},
},
// End PostCSS
],
"framework": "@storybook/react",
"core": {
"builder": "@storybook/builder-webpack5"
}
}
Add the @storybook/addon-postcss.
npm install --save-dev @storybook/addon-postcss
Now you’ll be able to add Tailwind styles to your Storybook components. Test by changing the “stories/Button.tsx” file to include a tailwind style like this (example “bg-yellow-500”).
import React from 'react';
import './button.css';
interface ButtonProps {
/**
* Is this the principal call to action on the page?
*/
primary?: boolean;
/**
* What background color to use
*/
backgroundColor?: string;
/**
* How large should the button be?
*/
size?: 'small' | 'medium' | 'large';
/**
* Button contents
*/
label: string;
/**
* Optional click handler
*/
onClick?: () => void;
}
/**
* Primary UI component for user interaction
*/
export const Button = ({
primary = false,
size = 'medium',
backgroundColor,
label,
...props
}: ButtonProps) => {
const mode = primary ? 'storybook-button--primary' : 'storybook-button--secondary';
return (
<button type="button" className={['bg-yellow-500', `storybook-button--${size}`].join(' ')}
style={{ backgroundColor }}
{...props}
>
{label}
</button>>
);
};
You should see the button background change to yellow after you run Storybook. Run Storybook:
npm run storybook