Button
General-purpose trigger for in-page actions (toolbars, forms, cards, action bars).
// Radix — @radix-ui/react-slot
import { Button } from "@shavin/ui";Variants (tone=accent)
<Button variant="solid">Solid</Button>
<Button variant="soft">Soft</Button>
<Button variant="outline">Outline</Button>
<Button variant="ghost">Ghost</Button>Tone=danger
<Button variant="solid" tone="danger">Solid</Button>
<Button variant="soft" tone="danger">Soft</Button>
<Button variant="outline" tone="danger">Outline</Button>
<Button variant="ghost" tone="danger">Ghost</Button>Sizes
<Button size="sm">Small</Button>
<Button size="md">Medium</Button>
<Button size="lg">Large</Button>Disabled
<Button disabled>Solid</Button>
<Button variant="soft" disabled>Soft</Button>
<Button variant="outline" disabled>Outline</Button>
<Button variant="ghost" disabled>Ghost</Button>With icons
<Button iconLeft={<PlusIcon />}>New</Button>
<Button variant="outline" iconRight={<ArrowRightIcon />}>Continue</Button>
<Button variant="soft" iconLeft={<DownloadIcon />}>Download</Button>Text Truncation (truncate=true vs false)
truncate=true (default):
truncate=false (wraps):
<div className="w-36">
<Button truncate iconLeft={<PlusIcon />}>Very Long Action Label Here</Button>
</div>Best Practices
| [Do] | Use variant='solid' tone='accent' for primary action in a container or form. |
| [Do] | Use variant='ghost' or variant='soft' for secondary/toolbar actions to preserve visual hierarchy. |
| [Don't] | Do not place two solid accent buttons adjacent to each other in the same action bar. |
Props
| Prop | Type | Default |
|---|---|---|
| asChild | boolean | — |
| truncate | boolean | — |
| iconLeft | ReactNode | — |
| iconRight | ReactNode | — |
| variant | "solid" | "soft" | "outline" | "ghost" | "solid" |
| tone | "accent" | "danger" | "accent" |
| size | "sm" | "md" | "lg" | "md" |