Skip to content
nexubDesign System
v2.4.0

Components · Actions

Button

Stablev0.0.1 → v1.7.0

Triggers an action or event. Supports multiple variants, sizes, and semantic tones.

import { Button } from '@nexub/react';

Usage

Use it for
  • Triggering a primary or secondary action (submit, save, confirm)

  • Navigating users to another page or step in a flow

  • Opening a dialog, drawer, or modal overlay

  • Destructive actions that need a visible, labelled control

Use something else for
  • Inline text navigation — use a Link instead

  • Icon-only controls — use IconButton for touch target compliance

  • Selecting among multiple options — use ToggleGroup or SegmentedControl

  • Passive information display with no action

Playground

Playground

Live
<Button variant="primary" size="md">Click me</Button>

Examples

Default

Variants

Sizes

States

Async

Drive `status` from the request. Each click here moves to the next status.

Variant matrix

Variants × variant / size5 × 5
variant ↓ / size →xssmmdlgxl
primary
outline
ghost
subtle
link

Props

Props
PropTypeDefaultDescription
variant'filled' | 'tonal' | 'outlined' | 'text' | 'glass' | 'subtle' | 'link' | 'destructive' | 'accent''primary'Visual style of the button. Legacy aliases still work: primary = filled, secondary = tonal, outline = outlined, ghost = text.
size'xs' | 'sm' | 'md' | 'lg' | 'xl''md'Control height and padding.
status'idle' | 'loading' | 'success' | 'error''idle'Async feedback (beta, 1.7.0). loading shows a spinner and blocks clicks but keeps focus; success draws a check; error shakes once. The label stays in flow, so the width holds.
loadingbooleanfalseAlias for status="loading".
loadingLabelstring'Loading'Announced when status becomes loading.
successLabelstring'Done'Announced on success. When set, it also replaces the visible label (with a check) instead of showing the check alone.
errorLabelstring'Something went wrong'Announced on error.
disabledbooleanfalseDisables the button.
fullWidthbooleanfalseStretches the button to fill its container.
leadingIconReact.ReactNode—Icon rendered before the label.
trailingIconReact.ReactNode—Icon rendered after the label.
tone'neutral' | 'info' | 'success' | 'warning' | 'danger'—Semantic colour tone — overrides the variant colour with a semantic palette.
asChildbooleanfalseMerges props onto the immediate child element (Radix Slot). status and loading have no effect with asChild.

Accessibility

ARIA roles

button

Keyboard

  • Space

    Activates the focused button.

  • Enter

    Activates the focused button.

  • Tab

    Moves focus to the button in document order.

Focus

  • Receives focus in document order; `disabled` removes it from the tab sequence.

  • Visible focus ring uses `--color-border-focus` and meets WCAG 2.4.7 contrast.

Screen reader

  • Announces the visible label plus the implicit "button" role.

  • While loading the button sets `aria-busy` and `aria-disabled` (not `disabled`), so focus stays on it and clicks are ignored.

  • A button with `status` or `loading` renders a polite `role="status"` region next to it that announces `loadingLabel`, `successLabel` or `errorLabel` as the status changes.

Notes

  • Pair icon-only triggers with `IconButton` for a 44×44 touch target.