Button

A clear, responsive action with quiet secondary states.

npm install https://animui.stracture.net/__local/package.tgz
Live · keyboard ready
  • Any single action on a page, form, or dialog, such as Save, Continue, or Cancel.
  • Actions whose label changes in place, like Save to Saved, where the width should spring instead of jump.
  • Short async work where a spinner on the button is enough feedback, via loading.
  • Use action-button when the button itself should show pending and success states after an async commit.
  • Use split-button when one default action has two to five close variants.
  • Use hold-to-confirm for destructive actions that need more than a single click.

Installation

Install animui once, then import any component or block from its typed package entry.

animui · 250 components and blocks

React 19 and React DOM 19 are required. The package includes Free and Pro entries, styles and TypeScript declarations.

npm install https://animui.stracture.net/__local/package.tgz

Load the stylesheet once at your app root, then use the typed component import:

import 'animui/styles.css';
import { Button } from 'animui/button';

Read the Code tab for the implementation files and the API reference below for required props.

Download animui 0.3.0 · Agent guide
example.tsx
import { Button } from "animui/button"; export function SaveBar() {  return (    <Button variant="primary" loading={saving} onClick={save}>      Save changes    </Button>  );}

Label that morphs after saving

example.tsx
<Button variant="secondary" loading={saving} onClick={save}>  {saved ? "Saved" : "Save draft"}</Button>

Button

A native button with press feedback and a label that morphs its width when the content changes.

PropTypeDefaultDescription
variant"primary" | "secondary" | "ghost" | "danger""primary"Visual weight. Use one primary action per surface.
size"sm" | "md" | "lg""md"Height and padding.
loadingbooleanfalseShows a spinner, sets aria-busy, and swallows clicks while keeping focus.
...propsButtonHTMLAttributes<HTMLButtonElement>–Forwarded to the underlying button, including ref, disabled, type, and onClick.
EnterorSpace
Activates the button.
  • Renders a native button, so role and focus come for free.
  • Loading uses aria-busy and aria-disabled instead of disabled, so keyboard focus is not lost mid-action.
  • Icon-only buttons need an aria-label.
  • Disabled primary buttons fade as a whole. Disabled secondary and danger buttons keep their border and take a muted fill and label, and disabled ghost buttons take a muted label, so an unavailable action still reads as a button.
  • Presses scale to about 0.97 on a snappy spring; icon-sized buttons press slightly deeper.
  • A new label crossfades with a short blur while the width springs to fit.
  • Reduced motion drops the press scale and swaps labels with a plain fade.
  • Size is fixed by the size prop; the button never changes layout by breakpoint, so pick lg for primary touch targets.
  • Hover styles apply only on hover-capable fine pointers, so taps on touch screens do not stick in a hover state.
  • A ResizeObserver measures the label so the width can spring; one per button is cheap, but avoid hundreds in a long list.
  • Label changes animate opacity, transform, and a small blur only, with no layout thrash beyond the width spring.

Notes for AI

Give your coding assistant the Markdown reference instead of screenshots.

  • Default choice for any single action. Use action-button for dense icon toolbars and split-button when one action has close alternatives.
  • Pass a changing label (Save → Saved) as children to get the width morph for free.
  • Wrap in a Radix trigger with asChild; the press scale turns off automatically for popup anchors.
/components/button/markdown

The full library index for assistants is at /llms.txt.