Shadcn Button
React button for forms, dialogs, and toolbar actions. Built with TypeScript and Tailwind CSS for Next.js using Base UI — variants, sizes, and buttonVariants for links.
A button is the click that commits — submit, delete, open a dialog. It is a native button. For a link that only needs the look, use buttonVariants on an <a> — Base UI’s render would force role="button" onto the anchor. One primary per view; the rest stay outline, secondary, or ghost.
Looking for a neobrutalism version for shadcn?
Same button, thicker borders. The NeoBrutalism button is the kit if you want that look.
Usage
import { Button } from "@/components/ui/button"<Button variant="outline">Save</Button>variant is default, outline, secondary, ghost, destructive, or link. size is xs through lg, plus the icon sizes.
Composition
buttonVariants is the class helper. Use it on an <a> or anything that should look like a button but is not one. Switch to Radix UI if you want render instead.
Size
xs in a chip, sm in a toolbar, lg for the main CTA. Pair each text size with the matching icon-* size.
Default
The solid primary. One per view — Save, Continue, Pay.
Outline
A border, no fill. The usual Cancel next to a primary.
Secondary
Filled but quiet. A second action that still needs weight.
Ghost
No chrome until hover. Toolbars, icon rows, overflow menus.
Destructive
The red one. Delete, remove, revoke — not a warning you can undo later.
Link
Looks like a text link, still a button. For a real navigation, use buttonVariants on an <a>.
Icon
size="icon" (or icon-xs / icon-sm / icon-lg). Give it an aria-label.
With Icon
data-icon="inline-start" or inline-end so padding matches the reading direction.
Rounded
rounded-full on the button. Common for a lone icon.
Spinner
Put a Spinner in the label and disable the button. Same data-icon attributes.
Button Group
A Button Group for fused actions. Same stack as the rest of this page.
As Link
buttonVariants on an <a>. Do not render a Base UI Button as a link — it keeps role="button".
RTL
Wrap with DirectionProvider and dir="rtl". Keep data-icon="inline-start" / inline-end so icons flip with the text.
API
Prop
Type
Native button props (disabled, type, onClick) pass through.
Keyboard
| Key | Action |
|---|---|
Space / Enter | Activate the focused button |
Tab | Move to the next control |
Notes
Name every icon button
aria-label="Submit" — a bare arrow reads as “button”. Same for size="icon-xs".
Put data-icon="inline-start" or inline-end on icons and Spinner so the padding matches.
With other components
Submit and reset
DialogConfirm and cancel
Dropdown MenuThe menu trigger
SpinnerLoading inside the label
TooltipName an icon button
InputSearch next to the field
Questions
Related
Was this page helpful?
Sign in to leave feedback.
Bubble
React chat bubble for sent and received messages. Built with TypeScript and Tailwind CSS for Next.js using Base UI — seven variants, alignment, grouping, and reactions.
Button Group
React button group for toolbars and split actions. Built with TypeScript and Tailwind CSS for Next.js using Base UI — fused borders, nested clusters, mixed inputs.