Skip to main content

Button

A polymorphic, accessible, and composable action component designed for primary interactions. Supports visual variants, sizes, loading states, icons, and router integration via slot-based polymorphism.


Usage

Basic usage

import { Button } from '@nofinite/nui';

<Button>Click me</Button>;

Variants

<Button variant="default">Default</Button>
<Button variant="primary">Primary</Button>
<Button variant="outline">Outline</Button>
<Button variant="ghost">Ghost</Button>
<Button variant="danger">Danger</Button>

Sizes

<Button size="sm">Small</Button>
<Button size="md">Medium</Button>
<Button size="lg">Large</Button>
<Button size="icon"></Button>

With icons

<Button iconLeft={<FaPlus />}>Create</Button>
<Button iconRight={<FaArrowRight />} variant="primary">Continue</Button>

Loading state

<Button isLoading>Processing</Button>
<Button asChild variant="primary">
<NextLink href="/dashboard">Go to Dashboard</NextLink>
</Button>

Props

PropTypeDefaultDescription
variant'default' | 'primary' | 'outline' | 'ghost' | 'danger' | 'link'defaultVisual style
size'sm' | 'md' | 'lg' | 'icon'mdDimensional size
isLoadingbooleanfalseShows spinner and disables interaction
iconLeftReactNodeIcon before content
iconRightReactNodeIcon after content
asChildbooleanfalseEnables polymorphic rendering
disabledbooleanDisables interaction
classNamestringCustom styles
...propsButtonHTMLAttributesNative button attributes

Variants

Visual variants

  • Default (secondary surface)
  • Primary (brand emphasis)
  • Outline (border only)
  • Ghost (minimal UI)
  • Danger (destructive action)
  • Link (text-like action)

Size variants

  • Small (compact UI)
  • Medium (default)
  • Large (emphasis)
  • Icon (square button)

Guidelines

  • Use primary for main CTA
  • Use danger only for destructive actions
  • Use ghost for dense UI toolbars
  • Use outline for secondary emphasis
  • Use icon size for icon-only actions

States

  • Default
  • Hover
  • Focus-visible
  • Disabled
  • Loading (spinner replaces left icon)

Keyboard Interaction

KeyBehavior
EnterActivates button
SpaceActivates button
TabFocus navigation
Shift+TabReverse navigation

Accessibility

  • Native button semantics preserved
  • Automatic disabled state when loading
  • aria-hidden spinner prevents duplicate announcements
  • Focus-visible ring for keyboard navigation
  • Supports polymorphic rendering while preserving semantics
  • Compatible with screen readers

Design Tokens

TokenUsage
--nui-bg-surfaceDefault background
--nui-bg-subtleHover background
--nui-border-defaultOutline border
--nui-border-hoverOutline hover border
--nui-brand-600Primary background
--nui-brand-700Primary hover
--nui-color-dangerDanger background
--nui-radius-mdBorder radius
--nui-font-sansTypography
--nui-text-xsSmall size text
--nui-text-smMedium size text
--nui-text-baseLarge size text
--nui-space-2Icon spacing
--nui-space-3Small padding
--nui-space-4Medium padding
--nui-space-6Large padding

Best Practices

Do

  • Use loading state for async actions
  • Provide accessible labels for icon-only buttons
  • Use asChild for router links
  • Keep icon alignment consistent
  • Use primary variant sparingly for emphasis

Don’t

  • Use danger variant for non-destructive actions
  • Place multiple primary buttons in the same section
  • Use icon-only buttons without aria-label
  • Override disabled state during loading
  • Nest interactive elements inside button content