DEV Community

Tasfia Islam
Tasfia Islam

Posted on • Edited on

4

Buttons with Tailwind CSS and React

Responsive button design with single React component with Tailwind CSS.

Here I'll show how you can design different types of buttons for both light and dark mode with tailwind. I have used Gatsby, TypeScript in my project.

Props

import { Link } from 'gatsby';
import React, { ReactNode } from 'react';

interface Props {
  type?: 'primary' | 'secondary' | 'text';
  children: ReactNode;
  onClick?: () => void;
  isBlock?: boolean;
  disabled?: boolean;
  className?: string;
  href?: string;
  target?: string;
  width?: string;
}
Enter fullscreen mode Exit fullscreen mode

Define the styles.

Added different text sizes and paddings for mobile and desktop devices. According to button type, text color, background and border are varied.

const textSize = 'text-base lg:text-lg';

const padding = 'px-7 lg:px-10 py-3 lg:py-4';

const color = {
  primary: 'text-white',
  secondary: 'text-slate-700 dark:text-slate-200',
  text: 'text-slate-700 hover:text-white dark:text-slate-200 dark:hover:text-white',
};

const backgroundColors = {
  primary: 'bg-blue-500',
  secondary: 'bg-transparent',
  text: 'bg-light-button hover:bg-blue-500 dark:bg-gray-800 dark:hover:bg-blue-500',
};

const border = {
  primary: 'border-none',
  secondary: 'border-2 border-gray-800 dark:border-white',
  text: 'border-none',
};
Enter fullscreen mode Exit fullscreen mode

Button Component

I have used custom google font here. Check out this link if you like to add a custom google font to your tailwind project.

For button with links or href, I have used Gatsby Link.

const Button = ({
  type = 'primary',
  children,
  onClick,
  className = '',
  disabled = false,
  href,
  target,
  isBlock = true,
  width,
}: Props): JSX.Element => {
  const disabledStyle = disabled
    ? 'opacity-50 cursor-not-allowed'
    : 'transition ease-in-out duration-300 hover:cursor-pointer';

  let baseClasses = [
    'uppercase',
    'font-oswald',
    textSize,
    border[type],
    backgroundColors[type],
    color[type],
    padding,
    disabledStyle,
  ];

  if (className) {
    baseClasses = [...baseClasses, ...className.split(' ')];
  }
  if (isBlock) {
    baseClasses = [...baseClasses, 'block w-full'];
  }
  if (!!width) {
    baseClasses = [...baseClasses, width];
  }

  if (href) {
    let linkClasses = [...baseClasses, 'flex items-center justify-center whitespace-nowrap'];
    return (
      <Link to={href} target={target} onClick={onClick} className={linkClasses.join(' ')}>
        {children}
      </Link>
    );
  }

  return (
    <button onClick={onClick} className={baseClasses.join(' ')} disabled={disabled}>
      {children}
    </button>
  );
};

export default Button;
Enter fullscreen mode Exit fullscreen mode

I have built the UI component with Storybook

Primary Light Button

Primary Dark Button

Secondary Light Button

Secondary Dark Button

Text Light Button

Text Dark Button

Top comments (0)

11 Tips That Make You a Better Typescript Programmer

typescript

1 Think in {Set}

Type is an everyday concept to programmers, but it’s surprisingly difficult to define it succinctly. I find it helpful to use Set as a conceptual model instead.

#2 Understand declared type and narrowed type

One extremely powerful typescript feature is automatic type narrowing based on control flow. This means a variable has two types associated with it at any specific point of code location: a declaration type and a narrowed type.

#3 Use discriminated union instead of optional fields

...

Read the whole post now!

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay