Triggers an action. Sixteen variants — solid, soft, outline, ghost and link — four sizes, each with a square one for an icon alone, a loading state, and can render as a link.
$ pnpm dlx shadcn@latest add https://dashral.com/r/button.jsonInstallation
$ pnpm dlx shadcn@latest add https://dashral.com/r/button.jsonAdds the component, the components it builds on, its npm packages and the theme tokens it uses. Using Dashral often? Add the registry to components.json once:
{
"registries": {
"@dashral": "https://dashral.com/r/{name}.json"
}
}Then add components by name:
$ pnpm dlx shadcn@latest add @dashral/buttonUsage
import { Button } from "@/components/dashral/button"
<>
<Button variant="outline">Cancel</Button>
<Button loading={saving} onClick={() => api.save()}>
Save changes
</Button>
</>Examples
Colors
Every variant comes in every color. Outline and ghost default to neutral, the rest to primary.
Sizes
xs, sm, default and lg, each with a square icon size at the same height: icon-xs, icon-sm, icon and icon-lg.
Loading
loading shows a spinner in place of the label (with loadingText beside it), keeping the button's width, and ignores clicks without losing focus.
As a link
Use asChild to apply button styles to another element.
API reference
Button
Also takes every prop of <button>(opens in a new tab).
| Prop | Type | Default |
|---|---|---|
variant | "solid" | "soft" | "outline" | "ghost" | "link"How much it stands out. | "solid" |
color | "primary" | "neutral" | "info" | "success" | "warning" | "destructive" | "highlight"What it means. | "primary" (outline, ghost: "neutral") |
glow | booleanA soft colored shadow under a solid button. | false |
size | "xs" | "sm" | "default" | "lg" | "icon-xs" | "icon-sm" | "icon" | "icon-lg" | "inline"Height and padding; each icon size is square, as tall as the size it's named after; inline has neither, for a link-style button in a sentence. | "default" |
loading | booleanShows a spinner in place of the label, which stays (hidden) so the button keeps its width, and ignores clicks, but stays focusable. | false |
loadingText | ReactNodeBeside the spinner while loading, e.g. "Saving…"; the button is as wide as the wider of it and the label. Not with asChild. | — |
asChild | booleanRender the child element instead (e.g. a Next.js Link), passing these styles and props to it. | false |
className | stringExtra classes, merged with cn() so yours win. | — |
buttonVariants
The class builder, to style a link or another element like a button: buttonVariants({ variant, color, size }).
Keyboard
| Keys | Action |
|---|---|
| EnterorSpace | Activate |
Accessibility
- A native button, so focus, Enter and Space come built in. Give icon-only buttons an aria-label.
- loading sets aria-busy and aria-disabled instead of disabled, so focus isn't lost mid-action and a submit button doesn't submit its form twice.
Motion
- Presses in to 97% while held (--duration-fast, --ease-standard). Off with reduced motion, for disabled buttons, while loading, and on a button that opens a menu, popover or tooltip (Radix places the layer from it as it opens).