Creating a Customizable React Button Component Using Tailwind CSS

October 04, 2020

Today we’re going to create a customizable React Button component using Tailwind CSS. Tailwind, as you have probably heard, is a utility-first CSS framework. That means that Tailwind provides low level classes that serve as the building blocks for more complex designs. For this component, we want to make it reusable and pass in props to change its properties dynamically.

Start by creating a new functional component with four props, “buttonStyle”, “type”, “text” and “onClick”.“Type” corresponds to the type of button we will use, “text” will be the button text, “onClick” will be the function we run whenever we click on the button and “buttonStyle” will be the particular style we want to apply.

import React from "react";
import PropTypes from "prop-types";

const Button = ({ buttonStyle, type, text, onClick }) => {
  return (
    <div className="p-1">
      <button
        className={}
        onClick={handleClick}
        type={type}
      >
        {text}
      </button>
    </div>
};

export default Button;

Above the return statement, add variables that store a string of the Tailwind classes we want to apply. In this example, I’ve added three types – rounded, outline and disabled buttons.

const roundedButtonClassNames =
  "bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded-full"

const outlineButtonClassNames =
  "bg-transparent hover:bg-blue-500 text-blue-700 font-semibold hover:text-white py-2 px-4 border border-blue-500 hover:border-transparent rounded"

const disabledButtonClassNames =
  "bg-blue-500 text-white font-bold py-2 px-4 rounded opacity-50 cursor-not-allowed"

Then on the className attribute, add a ternary function that applies the classes we want depending on the buttonStyle prop we pass from the parent component.

return (
  <div className="p-1">
    <button
      className={
        buttonStyle === "rounded"
          ? roundedButtonClassNames
          : buttonStyle === "outline"
          ? outlineButtonClassNames
          : buttonStyle === "disabled"
          ? disabledButtonClassNames
          : null
      }
      onClick={handleClick}
      type={type}
    >
      {text}
    </button>
  </div>
)

In the parent component, import the new Button component and pass in the props you want.

import React from "react"
import "./styles/app.css"
import Button from "./components/Button"

function App() {
  return (
    <div className="flex items-center justify-center h-screen">
      <Button
        text="Round Button"
        type="button"
        buttonStyle="rounded"
        handleClick={() => console.log("Clicked!")}
      />
      <Button
        text="Outline Button"
        type="button"
        buttonStyle="outline"
        handleClick={() => console.log("Clicked!")}
      />
      <Button
        text="Disabled Button"
        type="button"
        buttonStyle="disabled"
        handleClick={() => console.log("Clicked!")}
      />
    </div>
  )
}

export default App

The finished product will look something like this:

tailwindbuttons

This way, I don’t clutter up my JSX with a bunch of Tailwind classes and I have a standardized button component that I can use across my app.