a1ui
6 new components shipped

Confirmation Button

A drag-to-confirm button with a dotted arrow, pending feedback, and a confirmed state.

Read agent guide

Demo

Drag the arrow to the right and release to confirm, or press Enter or Space. Press Escape to cancel a drag.

Release at the end to confirm. Let go early to return. You can also focus the arrow and press Enter or Space.

Installation

pnpm dlx shadcn@latest add https://ui.arjayby1.xyz/r/confirmation-button.json

Requires React 19.2 or later.

Code

"use client";

import { useState } from "react";
import { ConfirmationButton } from "@/components/ui/confirmation-button";

export function ConfirmationButtonExample() {
  const [confirmed, setConfirmed] = useState(false);

  return (
    <div className="flex max-w-sm flex-col gap-4">
      <ConfirmationButton label="Slide to confirm" onConfirm={() => setConfirmed(true)} />
      <p>{confirmed ? "Action confirmed." : "Waiting for confirmation."}</p>
    </div>
  );
}

API reference

PropTypeDefaultPurpose
onConfirm() => void | Promise<void>RequiredRuns once after a completed gesture or keyboard activation. Resolve to confirm; throw or reject to allow another attempt.
labelstring"Slide to confirm"Idle text and the handle's accessible name.
pendingLabelstring"Confirming..."Text while the callback is pending.
confirmedLabelstring"Confirmed"Text after the callback succeeds.
errorLabelstring"Couldn't confirm. Try again."Visible and announced feedback if the callback fails.
disabledbooleanfalsePrevents interaction and cancels an active drag.
classNamestringNoneOuter layout classes, such as max-w-xs.
styleCSSPropertiesNoneInline styles and component theme tokens.

Drag the dotted arrow from left to right with a mouse, pen, or touch. Releasing within the last 5% of the track runs onConfirm. Letting go early, losing pointer capture, or pressing Escape returns the handle without running the action. Clicking or tapping the handle does not confirm.

Keyboard users can focus the handle and press Enter or Space. Assistive-technology activation follows the same confirmation path. Pending and successful states prevent repeated submissions and announce their labels. Reduced motion disables the return animation and spinner rotation.

Return a promise from onConfirm for asynchronous work. The component shows success only after that promise resolves. A thrown error or rejection returns the handle to the start and displays errorLabel. Handle application-specific error reporting inside your callback and rethrow the error to keep the retry behavior.

Success stays visible until the component is remounted. Change its React key to start a new confirmation. The demo uses this to reset after its simulated action completes.

The component uses your --background, --foreground, and --border theme tokens, with neutral fallbacks. You can override --confirmation-background, --confirmation-foreground, --confirmation-border, and --confirmation-track through style. Give the control enough width for its label and the handle; 16rem or more works for the default text. Dragging always moves from left to right.