## Submit Button (S—116)

A button that holds its width through idle, loading, success and error, with a spinner, a drawn tick and a shake.

- URL: https://sundaeui.dev/components/submit-button
- Category: UI components · Art direction: Refined
- Access: Free (no account needed)
- Stack: React 18+, TypeScript, plain CSS; dependencies: none
- Install: `npx shadcn@latest add https://sundaeui.dev/r/submit-button.json`
- Tags: form, submit, spinner, error, loading, success, button

Width is locked to the widest label so nothing around it jumps. Loading swaps the label for a spinner; success draws a tick; error shakes once and shows a short reason, then returns to idle.
It is driven by a status prop, so it works with any async handler or form library.

### Usage

```tsx
import { SubmitButton } from '@/components/sundae/submit-button'

<SubmitButton />
```

### Props

- `status` (`'idle' | 'loading' | 'success' | 'error'`, required): Current state.
- `labels` (`Partial<Record<Status, string>>`): Label per state.
- `onClick` (`() => void`): Click handler.
- `fill` (`'dark' | 'light'`, default `'dark'`): Surface: dark or light.

### When to use

- Forms, saves, payments, any async action.

### When not to use

- Instant actions with no network round trip.

### Accessibility

- aria-busy while loading and aria-disabled so focus is not lost; state text is announced politely.
- Reduced motion removes the movement and keeps every state change.
