Button
You know, those things you click to do just about anything in a web application.
Preview
Basic usage
import { Button } from '@/registry/ui-kit/tailwind-buttons/react'
function Example() {
return <Button>Save changes</Button>
}With color variants
Use the variant prop to change the button color.
import { Button } from '@/registry/ui-kit/tailwind-buttons/react'
function Example() {
return (
<div className="flex gap-2">
<Button variant="primary">Primary</Button>
<Button variant="secondary">Secondary</Button>
<Button variant="success">Success</Button>
<Button variant="danger">Danger</Button>
</div>
)
}Outline buttons
Use the outline prop for a bordered variant that fills on hover.
import { Button } from '@/registry/ui-kit/tailwind-buttons/react'
function Example() {
return (
<div className="flex gap-2">
<Button outline>Primary</Button>
<Button variant="danger" outline>Danger</Button>
</div>
)
}With icon
Pass an SVG icon as a child alongside text.
import { Button } from '@/registry/ui-kit/tailwind-buttons/react'
import { Plus, Trash2 } from 'lucide-react'
function Example() {
return (
<div className="flex gap-2">
<Button><Plus size={16} /> New item</Button>
<Button variant="danger"><Trash2 size={16} /> Delete</Button>
</div>
)
}Icon only
Use the icon prop for a compact square button. Combine with pill for a circle.
import { Button } from '@/registry/ui-kit/tailwind-buttons/react'
import { Plus, Heart, Settings } from 'lucide-react'
function Example() {
return (
<div className="flex gap-2">
<Button icon><Plus size={16} /></Button>
<Button icon pill><Heart size={16} /></Button>
<Button icon pill outline><Settings size={16} /></Button>
</div>
)
}Pill buttons
Use the pill prop for fully rounded buttons.
import { Button } from '@/registry/ui-kit/tailwind-buttons/react'
function Example() {
return <Button pill>Get started</Button>
}Component API
| Prop | Default | Description |
|---|---|---|
variant | "primary" | The color variant the button should use. |
size | "md" | The size of the button. |
outline | false | Renders an outline style with transparent background. |
pill | false | Renders a fully rounded pill shape. |
icon | false | Renders a square icon-only button. Combine with pill for a circle. |
disabled | false | Disables the button and reduces opacity. |
className | "" | Additional CSS classes. |
Source Code
"use client";
import { forwardRef } from "react";
type ButtonVariant =
| "primary"
| "secondary"
| "success"
| "danger"
| "warning"
| "info"
| "light"
| "dark";
type ButtonSize = "sm" | "md" | "lg";
interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
variant?: ButtonVariant;
size?: ButtonSize;
outline?: boolean;
pill?: boolean;
icon?: boolean;
children: React.ReactNode;
}
const solidStyles: Record<ButtonVariant, string> = {
primary: "bg-indigo-600 text-white hover:bg-indigo-500 shadow-sm shadow-indigo-600/20",
secondary: "bg-zinc-600 text-white hover:bg-zinc-500 shadow-sm shadow-zinc-600/20",
success: "bg-emerald-600 text-white hover:bg-emerald-500 shadow-sm shadow-emerald-600/20",
danger: "bg-rose-600 text-white hover:bg-rose-500 shadow-sm shadow-rose-600/20",
warning: "bg-amber-500 text-white hover:bg-amber-400 shadow-sm shadow-amber-500/20",
info: "bg-sky-600 text-white hover:bg-sky-500 shadow-sm shadow-sky-600/20",
light: "bg-zinc-100 text-zinc-700 hover:bg-zinc-200/80 shadow-sm border border-zinc-200",
dark: "bg-zinc-900 text-zinc-100 hover:bg-zinc-800 shadow-sm shadow-zinc-900/20",
};
const outlineStyles: Record<ButtonVariant, string> = {
primary: "border border-indigo-300 text-indigo-600 hover:bg-indigo-50 dark:border-indigo-800 dark:text-indigo-400 dark:hover:bg-indigo-950",
secondary: "border border-zinc-300 text-zinc-600 hover:bg-zinc-50 dark:border-zinc-700 dark:text-zinc-400 dark:hover:bg-zinc-900",
success: "border border-emerald-300 text-emerald-600 hover:bg-emerald-50 dark:border-emerald-800 dark:text-emerald-400 dark:hover:bg-emerald-950",
danger: "border border-rose-300 text-rose-600 hover:bg-rose-50 dark:border-rose-800 dark:text-rose-400 dark:hover:bg-rose-950",
warning: "border border-amber-300 text-amber-600 hover:bg-amber-50 dark:border-amber-800 dark:text-amber-400 dark:hover:bg-amber-950",
info: "border border-sky-300 text-sky-600 hover:bg-sky-50 dark:border-sky-800 dark:text-sky-400 dark:hover:bg-sky-950",
light: "border border-zinc-200 text-zinc-500 hover:bg-zinc-50 dark:border-zinc-700 dark:text-zinc-400 dark:hover:bg-zinc-900",
dark: "border border-zinc-800 text-zinc-800 hover:bg-zinc-900 hover:text-white dark:border-zinc-300 dark:text-zinc-300 dark:hover:bg-zinc-100 dark:hover:text-zinc-900",
};
const sizeStyles: Record<ButtonSize, string> = {
sm: "px-3 py-1.5 text-sm gap-1.5",
md: "px-4 py-2 text-sm gap-2",
lg: "px-5 py-2.5 text-base gap-2",
};
const iconSizeStyles: Record<ButtonSize, string> = {
sm: "h-8 w-8 p-0",
md: "h-9 w-9 p-0",
lg: "h-10 w-10 p-0",
};
const Button = forwardRef<HTMLButtonElement, ButtonProps>(
({ variant = "primary", size = "md", outline = false, pill = false, icon = false, className = "", children, ...props }, ref) => {
const shape = icon
? pill ? "rounded-full" : "rounded-lg"
: pill ? "rounded-full" : "rounded-lg";
return (
<button
ref={ref}
className={`inline-flex items-center justify-center font-medium transition-all duration-150 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-500 disabled:pointer-events-none disabled:opacity-50 ${shape} ${outline ? outlineStyles[variant] : solidStyles[variant]} ${icon ? iconSizeStyles[size] : sizeStyles[size]} ${className}`}
{...props}
>
{children}
</button>
);
}
);
Button.displayName = "Button";
export { Button };
export type { ButtonProps, ButtonVariant, ButtonSize };
export default Button;