# Slide To Confirm

> A React slide to confirm control: drag the thumb to the end to approve a payment or risky action.

- Type: React component (Mobile)
- Access: Pro (the source needs a Wingo UI Pro plan, see https://wingo-ui.com/pricing)
- Version: 1.0.0
- Install: `npx wingo-ui@latest add slide-to-confirm`
- Docs: https://wingo-ui.com/components/slide-to-confirm

## Interaction

Drag the thumb along the track with a finger or the mouse: the fill grows behind it and the label fades as the thumb passes. Past the threshold the thumb grows a little, the fill deepens and the phone ticks; let go there (or flick hard past 60%) and it glides to the end and confirms, let go earlier and it springs home. A promise from onConfirm shows a spinner on the parked thumb, then a bouncing check with the fill covering the track, or a short shake, the thumb back home and the error text for 2 seconds. Tap the track (or click the thumb) and the thumb hops forward and the label lights up, to teach the gesture. Vertical swipes that start on the track still scroll the page. Keyboard: Tab to the thumb, Enter, Space or End glide it to the end and confirm, Left / Right preview the travel in 10% steps and it springs back after a moment, Home returns it. With a screen reader, activating the thumb (a double tap in VoiceOver or TalkBack) confirms, and loading, success and error are announced. In RTL the thumb starts on the right.

## Installation

```bash
npx wingo-ui@latest add slide-to-confirm
```

Pro item: run `npx wingo-ui@latest login` once with a Pro account. The CLI adds the files, their dependencies and a version record for updates.

With shadcn: `npx shadcn@latest add @wingo-ui/slide-to-confirm` (needs the @wingo-ui registry with your API key in components.json)

Files:

- `components/ui/slide-to-confirm.tsx`

npm dependencies: `npm i lucide-react motion`

Wingo UI dependencies (installed automatically):

- [Spinner](https://wingo-ui.com/components/spinner) ([Markdown](https://wingo-ui.com/components/spinner.md))
- [useControllableState](https://wingo-ui.com/components/use-controllable-state) ([Markdown](https://wingo-ui.com/components/use-controllable-state.md))
- [Haptics](https://wingo-ui.com/components/haptics) ([Markdown](https://wingo-ui.com/components/haptics.md))
- [Motion presets](https://wingo-ui.com/components/motion) ([Markdown](https://wingo-ui.com/components/motion.md))
- [Tones](https://wingo-ui.com/components/tones) ([Markdown](https://wingo-ui.com/components/tones.md))
- [UIProvider](https://wingo-ui.com/components/ui-config) ([Markdown](https://wingo-ui.com/components/ui-config.md))

## Usage

```tsx
import { SlideToConfirm } from "@/components/ui/slide-to-confirm"

export function ConfirmDelivery({ orderId }: { orderId: string }) {
  return (
    <SlideToConfirm
      label="Slide to confirm delivery"
      labels={{ loading: "Confirming…", success: "Delivery confirmed", error: "Could not confirm. Try again." }}
      onConfirm={() => fetch(`/api/orders/${orderId}/delivered`, { method: "POST" }).then((res) => {
        if (!res.ok) throw new Error("failed")
      })}
    />
  )
}
```

## Props

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `label?` | `string` | `"Slide to confirm"` | The track text and the thumb's accessible name. Keep it short, it truncates on narrow tracks. |
| `variant?` | `"soft" \| "solid" \| "outline"` | `"soft"` | soft: a tinted track with a toned thumb. solid: the track in the tone fill with a contrasting thumb, for the one hero action. outline: a hairline track in the tone border. |
| `tone?` | `"neutral" \| "brand" \| "success" \| "warning" \| "danger" \| "info"` | `"neutral"` | Thumb and fill color from the design tokens. neutral is black in light mode and white in dark mode. |
| `color?` | `string` | `""` | Any CSS color. Replaces the tone; icons on the fill turn black or white by lightness. |
| `size?` | `"sm" \| "md" \| "lg"` | `"md"` | Track height 48 / 56 / 64px, thumb 40 / 48 / 56px, label 14 / 15 / 16px. Every size is a comfortable touch target. |
| `radius?` | `"none" \| "sm" \| "md" \| "lg" \| "full"` | `"full"` | Track radius 0 / 10 / 14 / 18px or a pill; the thumb and fill take the track radius minus their 4px inset. |
| `shimmer?` | `boolean` | `true` | A highlight that sweeps across the label while idle. Off when disabled, under reduced motion and off screen. |
| `disabled?` | `boolean` | `false` | Dims the control and blocks dragging and keys. The thumb stays focusable with aria-disabled, so a screen reader still finds it. |
| `defaultStatus?` | `"idle" \| "loading" \| "success" \| "error"` | `"idle"` | Starting status while uncontrolled. success parks the thumb at the end without calling onConfirm. |
| `status?` | `"idle" \| "loading" \| "success" \| "error"` |  | Controlled status for server-driven flows. Set it to "idle" to reset; set "success" and the thumb moves to the end without calling onConfirm. |
| `onStatusChange?` | `(status: SlideToConfirmStatus) => void` |  | Fires with every status change: loading when a promise starts, success / error when it settles, idle on reset. |
| `onConfirm?` | `() => (void \| Promise<unknown>)` |  | Runs when the thumb reaches the end or on Enter. Return a promise to show loading, then success when it resolves or error when it rejects (a synchronous throw counts as a rejection). Never runs twice for one slide. |
| `threshold?` | `number` | `0.9` | Share of the travel past which a release confirms. Deliberately harder than other swipes: a flick counts only past 0.6. 1 means the very end. |
| `resetAfter?` | `number` | `0` | Milliseconds after success before it slides back to idle. 0 keeps it confirmed until you reset the status. |
| `haptics?` | `boolean` | `true` | A medium tick when the thumb arms, success / error patterns on the outcome (through lib/haptics, phones only). |
| `icon?` | `ReactNode` |  | The thumb icon, a ChevronsRight by default. Unsized svgs follow the size (18 / 20 / 22px); mirrored in RTL. |
| `successIcon?` | `ReactNode` |  | Shown on the thumb after success, a Check by default; pops in on a bouncy spring. |
| `labels?` | `Partial<SlideToConfirmLabels>` |  | Status texts: loading "Processing…", success "Confirmed", error "Something went wrong. Try again.", hint "Drag to the end, or press Enter" (the thumb's screen reader description). Defaults in DEFAULT_SLIDE_TO_CONFIRM_LABELS. |
| `classNames?` | `Partial<Record<"track" \| "fill" \| "label" \| "thumb" \| "icon" \| "spinner" \| "check", string>>` |  | Extra classes for the inner parts. |
| `className?` | `string` |  | Classes for the root, merged last. It is full width by default; cap it here, e.g. max-w-sm. |

## Parts

### DEFAULT_SLIDE_TO_CONFIRM_LABELS (constant)

The English status texts: loading, success, error and the screen reader hint for the thumb. Spread it and override what you translate.

## Examples

- **Slide to pay**: Brand tone for a checkout's one hero action; resets 2.5s after success.
- **Clock in**: The solid variant with a success tone and custom icons.
- **Error path**: A rejected promise shakes the track, sends the thumb home and shows the error for 2s.
- **Sizes and radius**: 48, 56 and 64px tracks; radius md instead of the default pill.
- **Outline on a card**: A hairline track in the tone border, with the shimmer turned off.
- **Disabled with a reason**: Dimmed and blocked, with the reason spelled out under it.
- **Controlled status**: The status lives outside: reset it, or mark it done without calling onConfirm.

## See also

- [Button](https://wingo-ui.com/components/button) ([Markdown](https://wingo-ui.com/components/button.md))
- [Haptic Button](https://wingo-ui.com/components/haptic-button) ([Markdown](https://wingo-ui.com/components/haptic-button.md))
- [Sticky CTA Bar](https://wingo-ui.com/components/sticky-cta-bar) ([Markdown](https://wingo-ui.com/components/sticky-cta-bar.md))
- [Haptics](https://wingo-ui.com/components/haptics) ([Markdown](https://wingo-ui.com/components/haptics.md))
- [Spinner](https://wingo-ui.com/components/spinner) ([Markdown](https://wingo-ui.com/components/spinner.md))

---

Canonical: https://wingo-ui.com/components/slide-to-confirm
More components: https://wingo-ui.com/components · Index for agents: https://wingo-ui.com/llms.txt
