import { Button } from "@nodus/design-system"Loading demo…
Props
| Prop | Type | Default | Description |
|---|---|---|---|
variant | "primary" | "secondary" | "ghost" | "danger" | "primary" | Visual style variant |
size | "sm" | "md" | "lg" | "md" | Button size |
loading | boolean | — | Show spinner and disable. Auto-detects from React 19 useFormStatus when omitted. |
variantType
"primary" | "secondary" | "ghost" | "danger"Default "primary"Visual style variant
sizeType
"sm" | "md" | "lg"Default "md"Button size
loadingType
booleanDefault —Show spinner and disable. Auto-detects from React 19 useFormStatus when omitted.
Accessibility
- Renders a native <button> element — keyboard focusable and operable via Enter/Space by default.
- The loading spinner is aria-hidden; the button remains focusable and retains its label for screen readers.
- Pass aria-label when the button contains only an icon or non-descriptive text.
- The disabled prop maps to the native disabled attribute, which removes the element from tab order — use aria-disabled + onClick guard if you need it focusable while inactive.
- Supports all ButtonHTMLAttributes including aria-describedby, aria-expanded, aria-pressed.
MobileTouch Target
The sm size (28px) falls below the 44px minimum touch target. Use md or lg for primary CTAs on mobile. For icon+label buttons, the label expands the tap area naturally.
Design Rationale
This component was designed to express:
Explore Related
Was this helpful?