DEV Community

Cover image for Connecting Tailwind CSS, NextJS, and Storybook
Aiaru / 아야루
Aiaru / 아야루

Posted on

Connecting Tailwind CSS, NextJS, and Storybook

Short summary of how to connect NextJS, TailwindCSS and Storybook.

The connection is showed by making a simple button.

Step 1: Create NextJS app

npx create-next-app --typescript
If you need detailed steps of creating NextJS app, please check its documentation here.

Step 2: Make a button

You can edit the src/pages/index.tsx file for the purpose of testing. We will create a simple button, which can change its background color when clicked. Color is generated randomly, and updated using state in React. Thus, add import {useState} from 'react' at the top of the file and edit the Home function as follows:

export default function Home() {
  const [ccolor, setCcolor] = useState<string>("");

  function changeColor() {
    const randomColor = Math.floor(Math.random()*16777215).toString(16);
    setCcolor(randomColor);
  }

  return (
        <div>
          <p> get a random color &#128071;</p>
          <button onClick={changeColor} style ={{backgroundColor: "#" + `${ccolor}`}}> 👏 </button>
        </div>
  )
}
Enter fullscreen mode Exit fullscreen mode

You can check the result by running the app (npm run dev). Button background color changes when clicked.
Simple button

Step 3: Install Tailwind CSS

Now we can add Tailwind CSS by following its documentation.
In the created app folder, install Tailwind CSS.

npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init -p
Enter fullscreen mode Exit fullscreen mode

According to your current folder structure, modify the content pathways in the tailwind.config.js file.

module.exports = {
  content: [
    "./src/**/*.{js,ts,jsx,tsx,mdx}",
  ],
  theme: {
    extend: {},
  },
  plugins: [],
}
Enter fullscreen mode Exit fullscreen mode

Add Tailwind CSS directives to the top of your styles/global.css file.

@tailwind base;
@tailwind components;
@tailwind utilities;
Enter fullscreen mode Exit fullscreen mode

Try running the app to check if everything is working without errors.

Step 4: Add Tailwind CSS to the button

import { use, useState } from "react";


export default function Home() {
  const [ccolor, setCcolor] = useState<string>("");

  function changeColor() {
    const randomColor = Math.floor(Math.random()*16777215).toString(16);
    setCcolor(randomColor);
  }

  return (
    <div className="flex flex-col justify-center items-center 
                                        w-screen h-screen bg-gray-300">
      <p className="font-mono text-xl text-center"> get a random color </p>
        <button className = "rounded-full text-5xl m-4 p-8 shadow-xl" onClick={changeColor} style ={{backgroundColor: "#" + `${ccolor}`}}> 👏 </button>
    </div>
  )
}
Enter fullscreen mode Exit fullscreen mode

The code above changes the background color of the page, changes the text properties and makes the button round and shadowed.

Button with Tailwind

Up to this point, you connected NextJS with Tailwind CSS.

Step 5: Install Storybook

In the same folder, install Storybook:

npx storybook@latest init
Enter fullscreen mode Exit fullscreen mode

And try running it to check if it is working properly: npm run storybook

Modify .storybook/main.js as follows:

import type { StorybookConfig } from "@storybook/nextjs";
const config: StorybookConfig = {
  stories: ["../src/**/*.mdx", "../src/**/*.stories.@(js|jsx|ts|tsx)"],
  **staticDirs: ['../public'],**
  addons: [
    "@storybook/addon-links",
    "@storybook/addon-essentials",
    "@storybook/addon-interactions",
    **"@storybook/addon-postcss",**
  ],
  framework: {
    name: "@storybook/nextjs",
    options: {},
  },
  docs: {
    autodocs: "tag",
  },
};
export default config;
Enter fullscreen mode Exit fullscreen mode

Edit .storybook/preview.js by adding this line at the top of the file:

import '../src/styles/globals.css';
Enter fullscreen mode Exit fullscreen mode

Now as the folder structure changed, we should edit the content path for tailwind.config.js file as well:

content: [
    "./src/stories/**/*.{js,ts,jsx,tsx,mdx}",
],
Enter fullscreen mode Exit fullscreen mode

Step 6: Create story for the button

We want to create a button component, which will have 2 templates: default button and round button. The component has 3 arguments to play with: border radius, background color, and the emoji of the button.

arguments

Following the Storybook’s documentation, added our button in Button.tsx file.

import {useState} from 'react';
import './button.css';

interface ButtonProps {
  radius?: number; //border radius
  backgroundColor?: string; //background color
  emoji: 'clap' | 'heart' | 'star'; //emoji on the button
}
const emojiStyles = {
  clap: "👏",
  heart: "💔",
  star: "🌟",
};

export const Button = ({
  radius = 50,
  backgroundColor,
  emoji = 'clap'
}: ButtonProps) => {
//here comes our button
  const [ccolor, setCcolor] = useState<string>("");

  const ButtonClass = "text-5xl m-4 p-8 shadow-xl bg-gray-400 ";
  return (
    <button 
      className = {ButtonClass}
      style = {{backgroundColor, borderRadius: radius}}
      >
      {emojiStyles[emoji]}
    </button>
  );
};
Enter fullscreen mode Exit fullscreen mode

Also, we create its story in Button.stories.ts as follows:

import { StoryObj, Meta } from '@storybook/react';
import { Button } from './Button';

const meta: Meta<typeof Button> = {
  title: 'Example/Button',
  component: Button,
};

export default meta;

//create a “template” of how args map to rendering (from SB)
type Template = StoryObj<typeof Button>;

//created two variations of the button
export const Default:  Template = {
  args :{
    radius: 50,
    backgroundColor: '#ff8b8b',
    emoji: 'clap'
  },
};


export const Circle: Template = {
  args: {
    radius: 100,
    backgroundColor: 'blue',
    emoji: 'clap'
  },
};
Enter fullscreen mode Exit fullscreen mode

Image description

In this simple tutorial we used NextJS with TailwindCSS by utilizing Storybook. The example is very simple and can be further developed. Please feel free to check GitHub repository with this project here.

Thank you for reading up to this point ✨

Top comments (0)