# Alert dialog

> A centered alert that springs in from slightly larger; touch an action and slide across the others with a tick per action, tap outside and it nudges, and async actions keep it open with a spinner until they settle.

- Type: Component (overlays)
- Access: Free, open source (MIT)
- Page: https://goodui.dev/native/components/alert-dialog
- Markdown: https://goodui.dev/native/components/alert-dialog.md
- Registry item: https://goodui.dev/native/r/alert-dialog.json
- Dependencies: react-native-gesture-handler, react-native-reanimated
- Keywords: react native alert dialog, expo alert, confirm dialog, custom alert with text input, async confirm dialog, ios alert react native

## When to use

- A decision the person must make before continuing: sign out everywhere, cancel a plan, leave without saving.
- Asking for one short value, such as a new name.
- A confirmation whose request can fail: return the promise and the alert shows pending and error itself.

## When not to use

- Deleting items: confirm in place with hold-to-confirm or offer Undo through toast.
- Several unrelated choices: use action-sheet.
- Telling someone an action worked: use the button's own success state or a toast.
- Forms with more than one field: use bottom-sheet.

## Installation

With the shadcn CLI (needs a components.json in the Expo app), then `npx expo install --fix` so native dependencies match your Expo SDK. The foundation comes along the first time.

```bash
npx shadcn@latest add https://goodui.dev/native/r/alert-dialog.json
npx expo install --fix
```

The component lands in `components/goodui-native/alert-dialog/` and imports the foundation from `components/goodui-native/foundation/` with relative paths; it also installs locale.

### Setup

- Wrap the app in GestureHandlerRootView and ThemeProvider (the alert renders in its overlay layer).

Built-in strings follow `<GooduiLocaleProvider>` (one [language pack](https://goodui.dev/native/r/locale-tr.json) translates the whole kit); the `labels` prop overrides them for one instance.

## Usage

```tsx
import { AlertDialog } from "@/components/goodui-native/alert-dialog/alert-dialog";

export function CancelPlan({ open, onOpenChange }: { open: boolean; onOpenChange: (open: boolean) => void }) {
  return (
    <AlertDialog
      open={open}
      onOpenChange={onOpenChange}
      tone="warning"
      title="Cancel your Pro plan?"
      message="You keep Pro features until Dec 1."
      actions={[
        { label: "Keep Pro", style: "cancel" },
        { label: "Cancel plan", style: "destructive", onPress: () => api.cancelPlan() },
      ]}
    />
  );
}
```

## Examples

### With a text field

```tsx
<AlertDialog
  open={open}
  onOpenChange={setOpen}
  title="Rename workout"
  input={{ defaultValue: workout.name, placeholder: "Workout name" }}
  errorLabel="Give the workout a name."
  actions={[
    { label: "Cancel", style: "cancel" },
    { label: "Save", onPress: (name) => (name.trim() ? api.rename(workout.id, name) : Promise.reject()) },
  ]}
/>
```

### Filled buttons, three actions stack

```tsx
<AlertDialog
  open={open}
  onOpenChange={setOpen}
  variant="filled"
  title="Save changes to “Q3 report”?"
  actions={[
    { label: "Save", onPress: save },
    { label: "Do not save", style: "destructive" },
    { label: "Cancel", style: "cancel" },
  ]}
/>
```

## API reference

### AlertDialog

`import { AlertDialog } from "@/components/goodui-native/alert-dialog/alert-dialog";`

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `open` (required) | `boolean` | – | Whether the alert is shown. Closing animates out before it unmounts. |
| `onOpenChange` (required) | `(open: boolean) => void` | – | Called with false after an action runs, or when the alert is dismissed. |
| `title` (required) | `string` | – | One short question or statement. |
| `message` | `string` | – | What happens and why, in one or two sentences. |
| `actions` | `AlertAction[]` | – | Default: a single "OK". Two actions sit side by side; three or more stack. |
| `actionsLayout` | `"auto" \| "row" \| "stacked"` | – | `auto` puts two short actions side by side and stacks everything else. |
| `variant` | `"plain" \| "filled"` | – | `plain` is the platform alert with hairline-separated text actions; `filled` uses rounded buttons. |
| `tone` | `"default" \| "danger" \| "warning" \| "success"` | – | Adds an icon badge above the title for a status. |
| `input` | `AlertInput` | – | Adds a text field, such as a name or a password. |
| `dismissible` | `boolean` | – | Allow closing by tapping outside or pressing back. Default `false`: an alert needs an answer, and a tap outside nudges it. |
| `errorLabel` | `string` | – | Shown when an action's promise rejects. Same as `labels.error`. |
| `haptic` | `boolean` | – | Haptics on commit and on async results. Default `true`. |
| `labels` | `Partial<AlertDialogLabels>` | – | Overrides for the built-in strings; a GooduiLocaleProvider pack sets them app-wide. |
| `testID` | `string` | – | Identifier for end-to-end tests. |

## Accessibility

- The card has accessibilityRole alert and is modal; the title and message are announced when it opens.
- Each action is a button with busy and disabled states; double tap activates it. On the web actions are focusable buttons (Enter or Space).
- A failed action announces errorLabel and shows it under the message.
- Android back runs the cancel action when there is one (or closes a dismissible alert); otherwise it nudges.

## Motion

- Enter: scales from 1.1 to 1 on the bouncy spring while it fades in; exit fades and shrinks to 0.96.
- Actions follow the finger: the highlight moves to whichever action is under it, and releasing outside every action chooses nothing.
- Tap outside a non-dismissible alert: it nudges to 1.035 and springs back on the bouncy spring.
- Async failure: the card shakes and the error appears; filled buttons also scale to 0.97 under the finger.
- With a text field the card rises by half the keyboard height so it stays centered in the free space (native).
- Reduced motion: no scale-in, nudge, shake or button scale; the alert fades in and out.

## Haptics

- tap when an action is chosen
- select each time the finger slides onto another action
- success when an action's promise resolves, error when it rejects

## Performance

- Highlight and hit testing run on the UI thread; the alert mounts only while open or closing.

## Notes for AI

- Label actions with verbs; mark the safe way out with style 'cancel' and the risky one with 'destructive'.
- Return a promise from onPress to keep the alert open with a spinner; it closes on success and shakes with errorLabel on failure. Do not add your own loading state.
- onPress receives the text field's value when input is set.
- Alerts are not dismissible by default; pass dismissible for purely informational alerts.
- Two short actions (14 characters or fewer) sit side by side; set actionsLayout to force a row or a stack.

## Related

- [Action sheet](https://goodui.dev/native/components/action-sheet.md): An iOS-style list of choices that springs up from the bottom edge in grouped cards; it follows the finger to be dragged away, and pulling it up stretches the gap between the cards before they spring back together.
- [Bottom sheet](https://goodui.dev/native/components/bottom-sheet.md): A sheet that rests at detents, follows the finger 1:1, settles with velocity and hands drags off to its scroll view.
- [Hold to confirm](https://goodui.dev/native/components/hold-to-confirm.md): Confirms an irreversible action by holding: ink fills from the leading edge, the label inverts where the ink passes, and haptics tick at every quarter.
- [Toast](https://goodui.dev/native/components/toast.md): Background confirmations that stack at the top, fan out on tap, swipe away up or sideways, and pause their timers while touched.

## Guidance for AI tools

Alert dialog: A centered alert that springs in from slightly larger; touch an action and slide across the others with a tick per action, tap outside and it nudges, and async actions keep it open with a spinner until they settle. Use only the documented props. Keep accessibility, reduced motion and both color schemes intact when adapting it.

Full library index: https://goodui.dev/native/llms.txt
