Slide to Confirm

Requires the thumb to travel the whole track before confirming, so accidental taps and pocket presses don't send payments.

StopsPocket tap sent a payment

Installation

pnpm dlx shadcn@latest add https://bollard-ui.vercel.app/r/slide-to-confirm.json

The files land in your project. They're yours to edit.

Usage

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

<SlideToConfirm
  label="Slide to pay ₹499"
  pendingLabel="Paying…"
  confirmedLabel="Paid ₹499"
  resetAfter={2500}
  onConfirm={() =>
    new Promise<void>((resolve) =>
      setTimeout(() => {
        setLog("Payment sent to Chai Point.")
        resolve()
      }, 900),
    )
  }
/>

What it catches

  • Taps and short drags that don't reach the threshold
  • Held arrow keys (auto-repeat) that would otherwise complete it
  • Repeat confirms while an async confirm is pending
  • Failed confirms, which slide back

Props

SlideToConfirm props
PropTypeDefault
onConfirm* (required)

Runs once the thumb reaches the end. Return a promise to show a pending state; a rejection slides it back.

() => void | Promise<void>—
label

Text shown in the track, and the slider's accessible name.

string"Slide to confirm"
pendingLabel

Text shown while an async `onConfirm` is running.

string"Working…"
confirmedLabel

Text shown once confirmed.

string"Done"
threshold

How far (0 to 1) the thumb must travel before it counts.

number0.9
resetAfter

Milliseconds before resetting after confirm. 0 keeps it confirmed.

number0
variant

Visual style.

keyof typeof variants"default"
size

Size of the track.

keyof typeof sizes"default"
disabled

Disables the slider.

boolean—

* required. Also accepts the native props of <div> (className, aria-*, data-*…), passed through to it.

Accessibility

  • role=slider with aria-valuenow/valuetext and an aria-label from label
  • Keyboard operable; holding a key won't complete the slide
  • Phase text in a polite live region; aria-disabled while locked
  • Spring animation respects reduced motion

Only what the source does. Test with your own screen reader and content before shipping.

Limitations

This is a UX guard rail. Enforce on the server: For payments, keep server-side idempotency and authorization; this only reduces accidental triggers.

  • An accidental full slide still confirms
  • A UX guard, not authorization

What it stops

Pocket tap sent a payment

Also known as

swipe to pay · slide to confirm · swipe button · upi pay · slider · mobile checkout · end ride · pay now

Field type

Dependencies

Pairs well with