SlideToDetonate

A slide-to-confirm safety gate that makes you drag a handle across a fuse before the real action detonates.

SlideToDetonate guards destructive actions behind a deliberate drag gesture. A raised handle sits in a recessed track (dark or light), a soft white trail fills in behind it as you drag, and the handle glows once the fuse is armed. Let go too early and it springs back; release past the threshold and onConfirm fires. Tune how hard the fuse pushes back with resistance and how softly the handle follows your finger with smoothness.

Preview

Slide to detonate

Props

Install

Add the item with the shadcn CLI.

npx shadcn@latest add @evilbuttons/slide-to-detonate

Usage

import { SlideToDetonate } from "@/components/evil-buttons/slide-to-detonate";

export function ButtonDemo() {
  return (
    <SlideToDetonate onConfirm={() => launchTheMissiles()}>
      Slide to detonate
    </SlideToDetonate>
  );
}

Variants

Light

variant="light" swaps the dark groove for a light one with a white handle.

Slide to detonate

Heavy fuse

High resistance makes the handle lag further behind the pointer the closer it gets to the end.

Push through

Locked to the pointer

smoothness={0} and resistance={0} give a direct, one-to-one drag with no spring.

Slide to detonate

Floaty

High smoothness lets the handle glide behind the pointer on a loose spring.

Slide to detonate

Props

The component spreads native button props onto the handle, except onClick and style.

PropTypeDefaultDescription
childrenReact.ReactNode-Track label shown while idle. Falls back to label.
labelReact.ReactNode"Slide to detonate"Idle label used when no children are provided.
onConfirm() => void-Fired once the handle is released past the threshold.
thresholdnumber0.9Fraction of the track (0-1) the handle must cross to arm the action.
resistancenumber0.35How hard the fuse pushes back (0-1). 0 tracks the pointer one to one; higher values make the handle lag further behind toward the end.
smoothnessnumber0.4How softly the handle follows the pointer (0-1). 0 locks it to the pointer; higher values glide behind on a looser spring.
variant"dark" | "light""dark"Surface style: a recessed dark groove or a light one.
resetAfternumber1600Milliseconds to stay in the success state before resetting. Set to 0 to stay.
disabledbooleanfalseLocks the handle and dims the track.
classNamestring-Extra classes passed to the track.

Notes

  • Resistance bends the pointer-to-handle curve rather than capping it, so a heavy fuse still reaches the end if you drag all the way.
  • Smoothness maps to the follow spring: 0 sets the position directly, and higher values lower the stiffness and damping so the handle trails and settles.
  • Pulling back past the start rubber-bands a few pixels instead of stopping dead.
  • The handle is a role="slider" with live aria-valuenow. ←/→ step by 10%, Home resets, and End or stepping past the threshold detonates. Keyboard progress snaps back when focus leaves.
  • Crossing the threshold arms the fuse: the handle glows, the trail brightens, and phones get a short vibration where supported. data-state (idle | sliding | success) and data-armed are exposed on both the track and the handle.
  • A ResizeObserver re-measures the track so the drag range stays correct across layout changes.
  • With reduced motion, springs and the label shimmer are skipped; the handle moves directly.

Registry

The registry item includes components/evil-buttons/slide-to-detonate.tsx and installs clsx, tailwind-merge, and motion.

Search docs

Jump to a button documentation page