Button
BaseVersatile button with multiple variants, sizes, and states.
Preview
Variants
Sizes
Disabled
Usage
example.jsx
import { Button, buttonVariants, getButtonClasses } from "@/components/ui/button";
export default function Example() {
return <Button />;
}Source Code
Copy this file into components/ui/button.jsx in your project.
button.jsx
"use client";
import { forwardRef } from "react";
import { cn } from "@/lib/utils";
const buttonVariants = {
variant: {
default: "bg-primary text-primary-foreground shadow-sm hover:bg-primary/90",
destructive:
"bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90",
outline:
"border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground",
secondary:
"bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80",
ghost: "hover:bg-accent hover:text-accent-foreground",
link: "text-primary underline-offset-4 hover:underline",
},
size: {
default: "h-9 px-4 py-2",
sm: "h-8 rounded-md px-3 text-xs",
lg: "h-10 rounded-md px-8",
icon: "h-9 w-9",
},
};
function getButtonClasses({ variant = "default", size = "default" }) {
return cn(
"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium",
"transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring",
"disabled:pointer-events-none disabled:opacity-50",
"[&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
"cursor-pointer",
buttonVariants.variant[variant],
buttonVariants.size[size]
);
}
const Button = forwardRef(
({ className, variant = "default", size = "default", ...props }, ref) => {
return (
<button
className={cn(getButtonClasses({ variant, size }), className)}
ref={ref}
{...props}
/>
);
}
);
Button.displayName = "Button";
export { Button, buttonVariants, getButtonClasses };
Quick Install
Make sure you have the cn() utility set up. It requires clsx and tailwind-merge.
npm install clsx tailwind-merge