Components
Button
Use for actions that trigger a mutation or event. Not for labels, navigation, or status.
Preview
Rendered with live Folio tokens -- toggle the theme and it remaps, no dark: classes.
Variants
<Button>Button</Button><Button variant="outline">Outline</Button><Button variant="destructive">Delete</Button><Button variant="ghost">Ghost</Button><Button variant="link">Link</Button>Sizes
<Button size="default"><Check />Default</Button>
<Button size="sm"><Check />Small</Button><Button size="icon"><Plus /></Button>
<Button size="icon-sm"><Plus /></Button>
<Button size="icon-xs"><Plus /></Button><Button loading loadingText="Saving…">Save</Button>
<Button size="sm" loading loadingText="Saving…">Save</Button>Icons and the loading spinner scale with the button size -- no per-instance sizing. default is the top of the scale. The API also has xs, xxs, and icon-xxs for dense toolbars.
States
<Button disabled>Disabled</Button><Button loading loadingText="Saving…">Save</Button>loading is a built-in prop -- it shows a spinner and disables the button. Don't add an external spinner.
API
Prop
Type
Default
Description
variant
"default" | "destructive" | "outline" | "secondary" | "ghost" | "link"
"default"
Visual style of the button. Prefer outline over secondary for a bordered button.
size
"default" | "sm" | "xs" | "xxs" | "icon" | "icon-sm" | "icon-xs" | "icon-xxs"
"default"
Height and padding; icons scale with the size. Icon sizes are square.
asChild
boolean
false
Render the child element as the button (e.g. a link), keeping the styles.
disabled
boolean
false
Dims to 50% and blocks interaction (native button prop).
loading
boolean
false
Shows a spinner in place of the children and disables the button.
loadingText
string
--
Label shown next to the spinner while loading is true.
tooltipText
string
--
Wraps the button in a Tooltip that shows on hover, enabled or disabled.
disabledTooltipText
string
--
Replaces tooltipText while the button is disabled. Use it to explain why.
Don't and Do
Don't
Don't use a Button as a non-interactive label, category, or status pill -- that's a Tag or a Badge.
Do
// Triggers a mutation or event
<Button onClick={save}>Save changes</Button>
<Button variant="destructive" onClick={remove}>
Delete
</Button>import { Button } from "@/components/shadcn/button";
export function SaveChanges() {
return <Button onClick={handleSave}>Save changes</Button>;
}Drop-in ready. Variants and Folio tokens are baked into the component -- no className needed for standard usage.