Button

Component

Highly customizable Tailwind button components and Tailwind button groups for Next.js and React. Features primary, ghost, and glass variants.

A beautiful Tailwind button is the core interactive element of any modern web application. Whether you need an isolated call-to-action or a cohesive Tailwind button group, these buttons come packed with ultra-smooth hover states, focus rings, and premium aesthetics.

Buttons are frequently used alongside Dropdowns for hidden actions, or coupled with Badges for notification displays.

Implementation

interface ButtonProps {
  variant?: "primary" | "secondary" | "outlined" | "ghost" | "glass" | "danger" | "icon";
  size?: "small" | "regular" | "large";
  icon?: "upload" | "edit";
  children: React.ReactNode;
  onClick?: () => void;
  className?: string;
}

export const Button: React.FC<ButtonProps> = ({
  variant = "primary",
  size = "regular",
  icon,
  children,
  onClick,
  className = "",
}) => {
  const baseClass =
    "inline-flex items-center justify-center font-medium rounded-lg transition-all duration-300 ease-out focus:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-neutral-900 dark:focus-visible:ring-white dark:focus-visible:ring-offset-neutral-950 active:scale-[0.98] ";
    
  const sizeClasses = {
    small: "px-3 py-1.5 text-xs",
    regular: "px-4 py-2 text-sm",
    large: "px-6 py-3 text-base"
  };

  const variantClasses = {
    primary:
      "bg-neutral-900 text-white hover:bg-neutral-800 shadow-[0_1px_2px_rgba(0,0,0,0.05)] " +
      "dark:bg-white dark:text-neutral-900 dark:hover:bg-neutral-200",
    secondary:
      "bg-neutral-100 text-neutral-900 hover:bg-neutral-200 " +
      "dark:bg-neutral-800 dark:text-neutral-50 dark:hover:bg-neutral-700",
    outlined:
      "bg-transparent border border-neutral-200 text-neutral-900 hover:bg-neutral-50 " +
      "dark:border-neutral-800 dark:text-neutral-50 dark:hover:bg-neutral-800/50",
    ghost:
      "bg-transparent text-neutral-700 hover:bg-neutral-100 hover:text-neutral-900 " +
      "dark:text-neutral-300 dark:hover:bg-neutral-800 dark:hover:text-neutral-50",
    glass:
      "bg-white/20 backdrop-blur-md border border-white/20 text-neutral-900 hover:bg-white/30 " +
      "shadow-[0_8px_32px_0_rgba(0,0,0,0.04)] " +
      "dark:bg-black/20 dark:border-white/10 dark:text-white dark:hover:bg-black/30",
    danger:
      "bg-red-50 text-red-600 hover:bg-red-100 " +
      "dark:bg-red-500/10 dark:text-red-500 dark:hover:bg-red-500/20",
    icon:
      "bg-neutral-900 text-white hover:bg-neutral-800 shadow-[0_1px_2px_rgba(0,0,0,0.05)] " +
      "dark:bg-white dark:text-neutral-900 dark:hover:bg-neutral-200",
  };

  return (
    <button
      type="button"
      className={`
        ${baseClass} 
        ${variant === "icon" ? "p-2.5" : sizeClasses[size]} 
        ${variantClasses[variant]} 
        ${className}
      `}
      onClick={onClick}
    >
      <div className="flex items-center justify-center gap-2">
        {icon === "upload" && <Upload className="h-4 w-4" />}
        {children}
      </div>
    </button>
  );
};

Usage

Button Sizes

<div className="flex gap-4 items-center">
    <Button size="small">Small</Button>
    <Button size="regular">Regular</Button>
    <Button size="large">Large</Button>
</div>

Button Variants

<div className="flex flex-wrap gap-3 p-4 bg-neutral-50/50 dark:bg-neutral-900/50 rounded-xl border border-neutral-100 dark:border-neutral-800/60">
    <Button variant="primary">Primary</Button>
    <Button variant="secondary">Secondary</Button>
    <Button variant="outlined">Outlined</Button>
    <Button variant="ghost">Ghost</Button>
    <div className="p-2 bg-gradient-to-tr from-blue-100 to-purple-100 dark:from-blue-900/40 dark:to-purple-900/40 rounded-lg">
      <Button variant="glass">Glass Component</Button>
    </div>
    <Button variant="danger">Danger</Button>
    <Button variant="icon" icon="upload">
      Upload
    </Button>
</div>

Example Usage

Button Groups

<div
    className="inline-flex rounded-lg shadow-sm"
    role="group"
  >
    <Button variant="outlined" className="rounded-r-none border-r-0 focus:z-10 focus:ring-1">Prev</Button>
    <Button variant="outlined" className="rounded-none border-r-0 focus:z-10 focus:ring-1">1</Button>
    <Button variant="outlined" className="rounded-none border-r-0 focus:z-10 focus:ring-1 bg-neutral-50 dark:bg-neutral-800/50">2</Button>
    <Button variant="outlined" className="rounded-none border-r-0 focus:z-10 focus:ring-1">3</Button>
    <Button variant="outlined" className="rounded-l-none focus:z-10 focus:ring-1">Next</Button>
  </div>

Floating Action Button

<div className="fixed bottom-4 right-4 z-50">
    <Button
      variant="primary"
      className="rounded-full !p-3 shadow-xl hover:shadow-2xl hover:-translate-y-1"
    >
      <Plus className="h-6 w-6" />
    </Button>
</div>