Button

Buttons trigger explicit product actions. Choose a clear label and the least visual emphasis that still matches the decision.

Overview and decision boundary

Use Button for explicit product actions that submit, save, create, continue, or trigger a workflow.

Do not use a button render target when the interaction navigates to a destination.

import { ArrowUp } from "@nerio-ui/adapters/icons";import { Button } from "@nerio-ui/ui/client";<Button>Button</Button><Button icon={ArrowUp} aria-label="Move up" tooltip="Move up" />

Installation and imports

Install the editable registry source, or use the matching package entrypoint when the product keeps Nerio as a workspace dependency.

pnpm dlx nerio add buttonimport { Save, Settings } from '@nerio-ui/adapters/icons';import { Badge, Kbd } from '@nerio-ui/ui';import { Button } from '@nerio-ui/ui/client';

Usage

import { Save, Settings } from '@nerio-ui/adapters/icons';import { Badge, Kbd } from '@nerio-ui/ui';import { Button } from '@nerio-ui/ui/client';<Button leadingIcon={Save} badge={<Badge size="sm" tone="info">24</Badge>} kbd={<Kbd>S</Kbd>}>Save project</Button><Button icon={Settings} aria-label="Workspace settings" tooltip="Workspace settings" />

Variants

Link
VariantUse
primaryLead one clear local decision.
secondarySupport the primary action without competing with it.
outlineOffer a bounded secondary action on a quiet surface.
ghostKeep repeated or low-emphasis actions visually calm.
linkUse for navigation with an anchor render target; it has no control padding and underlines on hover or focus-visible.
dangerSignal a destructive action that needs explicit intent.

Anatomy

leading iconlabelbadgekbdtrailing icon

For an icon-only action, use icon and an aria-label. Button uses that accessible name as the required Tooltip label unless an explicit tooltip is provided; label, kbd, and directional icon slots are intentionally omitted.

SlotPurpose
buttonBase UI button primitive with variant, size, disabled, loading, and focus states.
button-iconOptional leading or trailing icon rendered through the Nerio icon adapter.
button-labelVisible action text that remains available while loading.
button-badgeOptional Badge count or status placed after the visible action label.
button-kbdOptional quiet keyboard shortcut hint placed between the label and trailing icon.

States

StateBehavior
Default, hover, and activeVariant tokens control interaction feedback.
FocusFocus-visible uses the shared Nerio focus ring.
LoadingDisables repeat activation and exposes aria-busy.
DisabledPrevents activation while preserving layout.

Motion

Hover, press, and focus use the shared motion tokens and respect reduced-motion preferences.

  • Hover transitions background, border, color, and opacity through motion tokens.
  • Press uses a subtle tokenized scale transform and is removed for reduced motion.
  • Focus-visible animates the shared focus ring without moving layout.

Accessibility

Hover or focus an icon-only button to see its Tooltip. The tooltip is supplementary: aria-label still supplies the action name.

A Button Badge remains in the accessible name, so use a concise count or status that refines the action.

  • Uses the Base UI Button primitive and renders a native button by default.
  • For navigation, set nativeButton={false} and render Button as a native anchor with variant link; it has no control padding and underlines on hover or focus-visible.
  • Custom render elements receive Button-owned content, state hooks, caller props, event handlers, classes, and refs without losing their chosen native semantics; function renders retain the Base UI button interaction contract.
  • Provide concise visible text or an accessible name.
  • Loading preserves the action name, disables repeat activation, and exposes aria-busy; loadingLabel is deprecated.
  • Disabled and loading states prevent repeat activation.
  • Icons render through the Nerio icon adapter and remain decorative by default.
  • For an icon-only Button, provide icon and an aria-label; Button uses that accessible name as the Tooltip label unless an explicit tooltip is provided.
  • Shortcut display is supplemental; add aria-keyshortcuts yourself when a keyboard shortcut is functional.
  • Badge content remains part of the Button accessible name; use a concise count or status that refines the action.
  • Deprecated subtle and destructive variants normalize to secondary and danger; use the canonical variants in new code.
  • Keep the visible focus treatment enabled.

API

PropValuesPurpose
variantprimary | secondary | outline | ghost | link | dangerSets action emphasis.
sizesm | md | lgUses density-aware height tokens.
leadingIcon / trailingIconIconComponentPlaces a decorative icon before or after the label.
icon + aria-labelIconComponent + stringCreates an accessible icon-only action.
badge<Badge>Adds a concise count or status after the visible label at sm size.
kbd<Kbd>Displays a quiet shortcut hint after the label.
tooltipReactNodeAdds supplemental hover and focus help.
loadingbooleanShows Spinner, disables activation, and sets aria-busy.

Implementation contract

ContractValue
Registry itembutton installs Button with its Badge, Kbd, and Tooltip dependencies.
Base UIbutton
Registry dependenciesbadge, tooltip, kbd
Package dependencies@base-ui/react, @nerio-ui/adapters, clsx, react, tailwind-merge, tailwindcss

Styling contract

ContractValue
AuthoringComplete, statically detectable Tailwind CSS v4 recipes own component visuals.
ValuesSemantic and component --n-* variables remain the canonical customization layer.
OverridesCustomizable slots merge consumer className values with tailwindCn so conflicting utilities resolve deterministically.
Residual CSSOnly shared keyframes and scoped no-Preflight compatibility rules remain; there is no parallel visual selector layer.

Design notes

  • Use one primary Button per local decision.
  • Use danger for destructive actions and pair it with explicit copy.
  • Use the link variant with a native anchor render target for navigation.

Do / do not

Do

Use one primary action per local decision and keep labels action-oriented.

Do not

Use the link variant with an anchor render target for a destination.

Tokens

GroupTokensControls
Sizing--n-button-height-sm / md / lgControl heights across density modes.
Shape--n-button-radiusCorner radius for text and icon-only Buttons.
Primary--n-button-background-primary / hover / activePrimary action surface.
Secondary--n-button-background-secondary / hover / border / foregroundSupporting action treatment.
Ghost--n-button-background-ghost / hover / foregroundLow-emphasis action treatment.
Link--n-link-color / hover / underline-offset / underline-thicknessText-level navigation with an underline on hover and focus-visible.
Danger--n-button-background-destructive / foreground-destructiveDestructive action treatment.
Button Kbd--n-button-kbd-background / border-color / foreground / opacityQuiet shortcut treatment inside a Button.
Button Badge--n-badge-height-sm / radius / padding-inline-smCompact count or status treatment inside a Button.
Icon-only--n-icon-button-size-sm / md / lg / radiusSquare Button sizing when icon is used.
Interaction--n-motion-hover-duration / --n-motion-press-duration / --n-focus-ringMotion and focus feedback.