shadcn.io is an independent project built on shadcn/ui
Buttons
ProSlide To Confirm Button for Solid
A pill with a handle to drag across, so a stray tap can't trigger the action. For Solid with Ark UI, when a payment or delete needs a deliberate move.
Drag the handle along the track. The fill follows it and the label fades. Let go past threshold, 90% of the way by default, and onConfirm runs, the handle shows a check, and it slides back after a moment. Let go earlier and it slides back with nothing done.
Use it for high-stakes actions on touch screens, such as paying, sending to everyone or deleting, where a tap is too easy to make by accident. On a desktop page a Long Press Button or a confirmation dialog is often simpler. It wraps the Button, so variant works as usual and size sets the track's height; the handle is as tall as the track. Dragging writes one CSS variable, the progress from 0 to 1, and the handle and the fill follow it with a CSS translate while the label fades, with no animation library. The handle follows the finger even with reduced motion, but the slide back is a jump instead of a glide.
Installation
Usage
import {
SlideToConfirmButton,
} from "@/components/ui/slide-to-confirm-button";<SlideToConfirmButton onConfirm={pay}>Slide to pay</SlideToConfirmButton>Demos
Threshold
threshold is how much of the track the handle has to cross, from 0 to 1. Half the track is enough to unlock; 1 asks for the whole way, for something you'd rather people think about.
Destructive
The track takes any variant and size: the handle is drawn in the label's color, so it matches, and it's as tall as the track. Here a wider, taller track (className="w-72", size="xl") deletes files, and resetDelay keeps the handle at the end for 1.5 seconds so the result has time to register.
Accessibility
It's a button named by its label, such as Slide to pay $24.00. Dragging isn't the only way in: Enter and Space confirm it, and so does a screen reader's activate command, with the handle sliding across to show it. A mouse click on the track does nothing, so the gesture stays deliberate for pointers. The handle and its icons are hidden from assistive tech.
- Enter
- Confirm.
- Space
- Confirm.
FAQ
How do I change the words on the track?
Pass them as children: <SlideToConfirmButton>Slide to send</SlideToConfirmButton>. The default is Slide to confirm. The label is also the button's accessible name.
How far does someone have to slide?
90% of the track by default. Set threshold between 0 and 1: lower is easier, 1 needs the full length. The Threshold demo shows 0.5 and 1.
Can keyboard and screen reader users confirm it?
Yes. Enter, Space and a screen reader's activation confirm it without dragging, and the handle slides across to show it. The button tells them apart from a mouse click because their click has no pointer behind it (its detail is 0).
What happens after it confirms?
The handle moves to the end and shows a check, rests there for resetDelay (800 milliseconds by default), then slides back. Navigate or show a message from onConfirm. The track has data-state="confirmed" while it rests, for styling.
How do I make the track wider or narrower?
Pass a width in className, such as w-72; the default is w-64, and it never grows past its container. The height follows size. Keep it wide enough that the threshold can't be crossed by accident.
API Reference
SlideToConfirmButton
data-slot="slide-to-confirm-button-track"
children?JSX.Element
The label on the track; it fades as the handle crosses it.
- Default
"Slide to confirm"
clickEffect?boolean
Shrink a little on press, as the Button does. Off, so the track holds still under a drag.
- Default
false
isLoading?boolean
Show a loading indicator.
- Default
false
onConfirm?() โ void
Called when the handle is let go past threshold, or when the button
is pressed with Enter or Space. A click on the track doesn't confirm.
- Returns
void
resetDelay?number
How long the handle rests at the end after confirming, in milliseconds, before it slides back.
- Default
800
threshold?number
How much of the track the handle has to cross to confirm, from 0 to 1. Let go before it and the handle slides back.
- Default
0.9
asChild?(props: ParentProps) => JSX.Element
Render your own element: a function that gets the part's props to spread on it.
- Type
(props: ParentProps) => JSX.Element
class?string
Merged with the part's classes.
data-state?string
"confirmed" when confirmed is true, otherwise "idle".
--slide-to-confirm-button-progressstring
How far the handle is, 0 to 1 (set while dragging).





