# Action button

> A button that morphs through saving, saved and failed, right where you clicked.

Component · Free · https://lodeui.com/components/action-button

## When to use

- Save, publish, retry or pay actions where people should see the outcome where they clicked.

## When not to use

- Actions that navigate away immediately.
- Long jobs (over ~10s): show progress elsewhere.

## Installation

```bash
npx shadcn@latest add https://lodeui.com/r/action-button.json
```

npm dependencies: motion, lucide-react

## Usage

```tsx title="example.tsx"
import { ActionButton } from "@/components/ui/action-button";

export function Publish({ publish }: { publish: () => Promise<void> }) {
  return (
    <ActionButton onAction={publish} pendingLabel="Publishing" successLabel="Published" errorLabel="Try again">
      Publish
    </ActionButton>
  );
}
```

## API reference

### ActionButton

Runs a promise and morphs through pending, success and error, then returns to idle.

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| onAction | `() => Promise<unknown>` | – | Resolve for success, throw or reject for error. |
| children | `ReactNode` | – | Idle label. |
| pendingLabel / successLabel / errorLabel | `ReactNode` | `"Saving" / "Saved" / "Try again"` | Labels for each state. |
| resetAfter | `number` | `1800` | ms before returning to idle. |
| variant | `"primary" \| "secondary"` | `"primary"` | Visual weight. |

## Keyboard interactions

| Keys | Action |
| --- | --- |
| Enter / Space | Run the action |

## Accessibility

- aria-busy while pending and aria-live so state changes are announced.
- Clicks are ignored while pending, so actions never double-fire.

## Motion

- Width springs to fit each label; labels swap with a short blur and slide (300ms).
- Presses scale to 97%.

## Responsive behavior

- Width follows the label; add w-full on phones.

## Performance

- One timer per button, cleared on unmount.

## Notes for AI

- Throw from onAction to show the error state; don't catch silently.

## Related

- [Button](https://lodeui.com/components/button) — A clear, responsive action with quiet secondary states.
- [Toast](https://lodeui.com/components/toast) — Stacked notifications that fan out on hover, swipe to dismiss, and track promises.
- [Progress](https://lodeui.com/components/progress) — Linear bar, ring and segmented meter, all spring-driven.
