Button

A soft, rounded action primitive with composable anatomy, eight visual variants, seven sizes, loading behavior and optional hover motion recipes.

Import

import {
  Button,
  ButtonIcon,
  ButtonLabel,
  buttonVariants,
} from "@/components/ui/button";

Playground

Compose the public Button props and copy the resulting JSX. The page-level surface preview remains active.

variant
size
radius
effect
fillDirection
<Button variant="default" size="default" radius="md" effect="none">Continue</Button>

Variants

Brand red remains the primary action; neutral, tinted, outline and translucent treatments provide quieter hierarchy.

<Button variant="default">default</Button>
<Button variant="secondary">secondary</Button>
<Button variant="soft">soft</Button>
<Button variant="outline">outline</Button>
<Button variant="glass">glass</Button>
<Button variant="ghost">ghost</Button>
<Button variant="destructive">destructive</Button>
<Button variant="link">link</Button>

Sizes and radius

Size and corner radius are independent. Choose none through full; icon controls always need an accessible name.

<Button size="xs">Extra small</Button>
<Button size="sm">Small</Button>
<Button>Default</Button>
<Button size="lg" radius="full">Large pill</Button>
<Button size="icon-sm" aria-label="Favorite"><Heart /></Button>
<Button size="icon" radius="full" aria-label="Notifications"><Bell /></Button>
<Button size="icon-lg" aria-label="Download"><Download /></Button>

Hover effects

Motion is opt-in and independent from visual variant. Fill can travel in four directions; swap can target icon, label or both.

<Button effect="shine">Shine sweep</Button>
<Button effect="fill">Fill right</Button>
<Button effect="fill" fillDirection="left">Fill left</Button>
<Button effect="fill" fillDirection="up">Fill up</Button>
<Button effect="fill" fillDirection="down">Fill down</Button>
<Button effect="swap" swapTarget="both">
  <ButtonLabel>Swap content</ButtonLabel>
  <ButtonIcon><ArrowRight /></ButtonIcon>
</Button>
<Button effect="border-draw">Border draw</Button>

Glass on light and dark surfaces

The same glass recipe uses semantic transparency and a solid fallback when backdrop filtering is unavailable or reduced.

<Button variant="glass"><Sparkles /> AI Generate</Button>

States

Loading keeps the label in flow to prevent width shift, exposes aria-busy and blocks repeated actions.

<Button loading>Saving changes</Button>
<Button disabled>Disabled</Button>
<Button variant="outline" className="w-full sm:w-auto">Consumer override</Button>

As child

Use asChild when link navigation needs Button styling while preserving anchor semantics.

<Button asChild effect="swap" radius="full">
  <a href="/docs">
    <ButtonLabel>Explore docs</ButtonLabel>
    <ButtonIcon><ArrowRight /></ButtonIcon>
  </a>
</Button>
pnpm dlx shadcn@latest add @poyraz/button

Runtime dependencies

@radix-ui/react-slot@^1.2.4, class-variance-authority@^0.7.1

Registry dependencies

@poyraz/poyraz-utils, @poyraz/poyraz-theme

Installed files

@ui/atoms/button.tsx