Button Design System with React and Tailwind
Buttons are fundamental UI elements in web development, serving as key interaction points for users. Designing a flexible, reusable button component can significantly enhance the consistency and scalability of your React application.
In this button design system guide, I’ll walk you through creating a button component using React and Tailwind CSS with three distinct variants Primary, Secondary, and Outline as well as a disabled state and a loading spinner for better user feedback.
React Button Design System UI Preview
Button Component Variants
- Primary - The default attention-grabbing color for main actions.
- Secondary - A softer, muted color for secondary actions.
- Outline - A minimalist style with a transparent background and border.
React Button Component with Tailwind
Here’s the complete code for the button component with live preview.
Copy paste this into your ui components
folder.
1import React, { MouseEventHandler, ReactNode } from 'react' 2import { cn } from '../utils/functions' 3 4interface ButtonProps { 5 children: ReactNode 6 variant?: 'primary' | 'secondary' | 'outline' 7 loading?: boolean 8 disabled?: boolean 9 type?: 'button' | 'submit' | 'reset' 10 onClick?: MouseEventHandler<HTMLButtonElement> 11 className?: string 12} 13 14const Button: React.FC<ButtonProps> = ({ 15 children, 16 variant = 'primary', 17 loading = false, 18 disabled = false, 19 type = 'button', 20 onClick, 21 className, 22}) => { 23 const baseStyles = 24 'h-9 rounded-lg py-2 px-4 font-medium transition duration-300 ease-in-out inline-flex items-center justify-center gap-2 disabled:bg-gray-200 disabled:text-gray-500 disabled:cursor-not-allowed disabled:border-gray-300' 25 26 const variantStyles: Record<string, string> = { 27 primary: 'bg-[#00AAFF] text-white hover:bg-sky-600 border border-transparent', 28 secondary: 'bg-[#EBEEF7] text-[#191F33] hover:bg-violet-200 border border-transparent', 29 outline: 'bg-transparent text-[#7D8592] border border-[#D8E0F0] hover:bg-[#D8E0F0]', 30 } 31 32 return ( 33 <button 34 className={cn(baseStyles, !disabled && variantStyles[variant], className)} 35 disabled={disabled || loading} 36 onClick={onClick} 37 type={type} 38 > 39 {children} 40 </button> 41 ) 42} 43 44export default Button
Here are some of the variants we created using the button component code above. I coded it with a design system in mind.
Button Variants
You can easily adjust the primary, secondary, and other variants by changing the color names by matching it with your theme in button.tsx
file.
Button Variants
Disabled State
Loading Spinner Button
Loading State
Features of the Loading Spinner Button
- Dynamic Spinner Animation
- Displays a spinning loader icon (
Loader2
from Lucide React) when in the loading state.
- Displays a spinning loader icon (
- Disabled State Handling
- Automatically disables the button during loading to prevent duplicate submissions.
Custom Style Button
You can easily customize and override the default styling by passing className props.
Custom Styles
Continue with Google Button
Login with Google
API
Prop | Type | Required | Default | Description |
---|---|---|---|---|
children | ReactNode | Yes | — | The content inside the button, such as text or icons. |
variant | 'primary' | 'secondary' | 'outline' | No | 'primary' | Defines the button style variant. |
loading | boolean | No | false | Displays a loading spinner when set to true. |
disabled | boolean | No | false | Disables the button when set to true. |
type | 'button' | 'submit' | 'reset' | No | 'button' | Specifies the button type attribute. |
onClick | MouseEventHandler<HTMLButtonElement> | No | undefined | Function triggered when the button is clicked. |
className | string | No | undefined | Additional Tailwind classes for customization. |
This component is a great starting point for building more complex UI systems and can be extended to include additional variants and functionality as needed.