# Hold to confirm

> 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.

- Type: Component (actions)
- Access: Free, open source (MIT)
- Page: https://goodui.dev/native/components/hold-to-confirm
- Markdown: https://goodui.dev/native/components/hold-to-confirm.md
- Registry item: https://goodui.dev/native/r/hold-to-confirm.json
- Dependencies: react-native-reanimated
- Keywords: hold to delete, press and hold button, long press confirm, destructive confirmation, hold to confirm react native

## When to use

- Irreversible or costly actions: delete a project, send money, cancel a subscription.
- Places where a confirmation dialog would interrupt more than it helps.

## When not to use

- Frequent, reversible actions: use button, and offer Undo through toast.
- Actions that must be reachable with one quick tap.

## 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/hold-to-confirm.json
npx expo install --fix
```

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

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 { HoldToConfirm } from "@/components/goodui-native/hold-to-confirm/hold-to-confirm";

<HoldToConfirm confirmedLabel="Project deleted" onConfirm={() => api.deleteProject(id)}>
  Delete project
</HoldToConfirm>
```

## API reference

### HoldToConfirm

`import { HoldToConfirm } from "@/components/goodui-native/hold-to-confirm/hold-to-confirm";`

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `children` (required) | `string` | – | What happens, as a verb: "Delete project". |
| `onConfirm` (required) | `() => unknown` | – | Runs when the hold completes. Return a promise to show a spinner until it settles. |
| `duration` | `number` | `1200` | How long to hold, in ms. Default 1200. |
| `tone` | `"danger" \| "accent"` | `"danger"` | `danger` for destructive actions, `accent` for costly but positive ones such as sending money. |
| `confirmedLabel` | `string` | – | Shown with the check once confirmed, for example "Deleted". |
| `hint` | `string` | – | Hint under the hold, read by screen readers too. Same as `labels.hint`. |
| `disabled` | `boolean` | `false` | Dims the control and ignores presses. |
| `resetAfter` | `number \| false` | `1800` | Return to the idle state this many ms after confirming. `false` keeps the confirmed state. |
| `labels` | `Partial<HoldToConfirmLabels>` | – | Overrides for the built-in strings; a GooduiLocaleProvider pack sets them app-wide. |
| `style` | `StyleProp<ViewStyle>` | – | Style for the outer container. |
| `testID` | `string` | – | Identifier for end-to-end tests. |

## Accessibility

- Screen reader users cannot hold: a double tap runs the action directly, and the hint says what happens.
- Busy state while a returned promise is pending; the result is announced.

## Motion

- The ink fills linearly over the duration. Letting go early drains it on the smooth spring.
- The label exists twice, in the base and ink colors, clipped by the ink, so it inverts exactly where the ink is.

## Haptics

- select at 25, 50 and 75 percent
- warning at the end of the hold
- confirm when confirmed, error when the promise rejects

## Performance

- Progress runs on the UI thread; the early-release decision is made there so a release at the last moment never cancels a completed hold.

## Notes for AI

- Label with a verb and the object: 'Delete project', not 'Delete'.
- Return a promise from onConfirm to show a spinner until it settles.
- Pass resetAfter={false} when the screen navigates away after confirming.

## Related

- [Button](https://goodui.dev/native/components/button.md): A press-responsive button with haptics that runs async actions on its own: it gathers into a spinner, then opens into a success or error state.
- [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

Hold to confirm: 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. 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
