Button
Six variants and four sizes. Supports icons, loading state, and asChild composition.
Examples
Anatomy
How the parts nest — every slot the component exposes, in composition order.
Features
- Six variants (default, secondary, outline, ghost, destructive, link) and eight sizes, including icon-only sizes.
- asChild renders the child element in place of a <button> — turn a link or custom trigger into a styled button.
- A child marked data-icon="inline-start" or "inline-end" (an icon or a Spinner) automatically tightens its padding.
- Styles itself as active via aria-expanded when used as a menu or popover trigger.
API reference
Props for each part of the component. All native element props are also forwarded.
Button
Renders a native <button>, or its child element when asChild is set.
variant"default" | "secondary" | "outline" | "ghost" | "destructive" | "link"Visual style of the button.
Default
"default"size"xs" | "sm" | "default" | "lg" | "icon" | "icon-xs" | "icon-sm" | "icon-lg"Controls height and horizontal padding. Use icon sizes for icon-only buttons.
Default
"default"asChildbooleanMerge props onto the single child instead of rendering a <button>.
Default
falsedisabledbooleanDisables interaction and removes the button from the tab order.
Default
falsetype"button" | "submit" | "reset"Native button type. Defaults to button to avoid accidental form submits.
Default
"button"
Accessibility
Built to be keyboard-navigable and screen-reader friendly out of the box.
| Key | Function |
|---|---|
| Tab | Moves focus to and from the button. |
| Space | Activates the button. |
| Enter | Activates the button. |
- Renders a native <button>, so it is focusable and announced as a button with no extra ARIA.
- Icon-only buttons must set an aria-label — the visible icon carries no accessible name.
- A visible focus ring is shown only for keyboard focus via :focus-visible.
Guidelines
Conventions that keep usage consistent across an app.
Do
- Lead with the most important action using the default variant — one primary per view.
- Use the destructive variant for irreversible actions like delete.
- Keep labels to a verb or verb + noun: “Save”, “Add member”.
Don’t
- Don’t stack multiple default (primary) buttons next to each other.
- Don’t use a Button for navigation — use a link (or asChild with an anchor) instead.
- Don’t rely on colour alone for destructive intent; keep an explicit label.
Explore further
Ready to integrate?
Follow the Getting Started guide to install @codefast/ui, or browse the full component gallery.