Button Design System with React and Tailwind
This button design system is built with 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.
The component supports an as prop that lets you render it as any HTML element, such as an anchor tag or custom link component, while keeping the same styling and behavior. This makes the button more adaptable across different use cases like navigation links or call-to-action buttons.
React Button Component with Tailwind
If you want to learn how to build a button design system using the Polymorphic UI pattern step by step, this guide will show you how.
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 (
Loader2from 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
Link Button
Style like button but act like link.
Link Button
API
| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
| as | ElementType | No | 'button' | Specifies the HTML element or React component to render as. Useful for polymorphic behavior, e.g., rendering as an `<a>` or `<Link>`. |
| children | ReactNode | Yes | — | The content inside the button, such as text or icons. |
| variant | 'primary' | 'secondary' | 'outline' | No | 'primary' | Defines the visual style of the button. |
| loading | boolean | No | false | Displays a loading spinner when set to true. |
| disabled | boolean | No | false | Disables the button when set to true. Applies only when rendered as a `<button>`. |
| className | string | No | undefined | Additional Tailwind CSS classes for customization. |
| ...rest | Omit<ComponentPropsWithoutRef<E>, keyof ButtonProps> | No | — | Includes all valid props for the rendered element type. For example, `href` when `as="a"`, or `to` when using a `Link`. |
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.
