Form
Button
Six variants and four sizes. Supports icons, loading state, and asChild composition.
Install
pnpm add @codefast/ui
Import path
@codefast/ui/button
Examples
Anatomy
How the parts compose. Copy this skeleton and fill in the slots.
import { Button } from "@codefast/ui/button";
<Button variant="default" size="default">
Label
</Button>
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.
| Prop | Type | Default | Description |
|---|---|---|---|
| variant | "default" | "secondary" | "outline" | "ghost" | "destructive" | "link" | "default" | Visual style of the button. |
| size | "xs" | "sm" | "default" | "lg" | "icon" | "icon-xs" | "icon-sm" | "icon-lg" | "default" | Controls height and horizontal padding. Use icon sizes for icon-only buttons. |
| asChild | boolean | false | Merge props onto the single child instead of rendering a <button>. |
| disabled | boolean | false | Disables interaction and removes the button from the tab order. |
| type | "button" | "submit" | "reset" | "button" | Native button type. Defaults to button to avoid accidental form submits. |
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.