# Button

Primary or secondary button that steps through idle, hover, press, loading and success. The loading spinner and success check crossfade in place, so the button never resizes.

```bash
npx shadcn add https://www.reelcn.dev/r/button.json
```

Usage:

```tsx
<Center>
  <Button
    id="pay-button"
    label="Pay $48.20"
    steps={[{ at: 0, state: "idle" }, { at: 1, state: "press" }, { at: 1.4, state: "loading" }, { at: 2.4, state: "success" }]}
  />
</Center>
```

Use for:

- A UI-sim walkthrough where a cursor clicks a real, named button
- A `ui` scene's `component: "button"`

Avoid:

- A static call-to-action with no interaction. Use plain text instead


## Props

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| delay? | `number` | — | Frames to wait before entering. |
| duration? | `number` | — | Enter duration in frames. Defaults to 0.6s. Some items reuse `duration` for an unrelated local timing. See that item's own prop docs. |
| exit? | `number \| boolean` | — | Exit at the end of the parent `<Sequence>`. `false` keeps it on screen, a number sets the exit length in frames. |
| motion? | `MotionPersonality` | — | Override the theme's motion personality. |
| poster? | `boolean` | — | Renders fully entered, with no exit: for a still frame or thumbnail. Defaults to `false`. |
| holdFrames? | `number` | — | Delays the start of the exit window by this many frames, for a minimum on-screen hold. Defaults to `0`. |
| id? | `string` | — | Anchor id (`useButtonAnchors`' key, and a cursor's `target.id`). Required for `place`/anchors to resolve. |
| label | `string` | — |  |
| steps? | `Step<ButtonState>[]` | — | Timeline of states, `at` in seconds. Omitted renders a static `idle` button. |
| variant? | `"primary" \| "secondary"` | `"primary"` |  |
| size? | `number` | — | Label font size in design units. |
| place? | `Place` | — | Absolute position, % of canvas, this button's center. Omitted lays out in normal flow. |
| style? | `CSSProperties` | — |  |
| className? | `string` | — |  |