Hold button
A hold-to-confirm button for React: a fill runs across it along the slant while it is held, for what should not happen by accident.
Install
# once per project: where @zeroui items come frompnpm dlx shadcn@latest registry add @zeroui=https://zeroui.catforest.dev/r/{name}.jsonpnpm dlx shadcn@latest add @zeroui/hold-buttonExamples
Hold to scrap
Crates scrapped: 0
import { useState } from "react";import { HoldButton } from "@/components/zero/hold-button";import { Kbd } from "@/components/zero/kbd";export default function HoldButtonScrap() { const [scrapped, setScrapped] = useState(0); return ( <div className="grid justify-items-start gap-4"> <div className="flex flex-wrap gap-3"> <HoldButton hotkey="x" onConfirm={() => setScrapped((n) => n + 1)}> <Kbd>X</Kbd> Hold to scrap </HoldButton> <HoldButton variant="danger" duration={2000}> Abandon the run </HoldButton> </div> <p className="font-medium font-zero-text text-zero-sm text-zero-text-2"> Crates scrapped: <span className="text-zero-text">{scrapped}</span> </p> </div> );}Behaviour
Hold it with the pointer, Enter or Space, or its hotkey from anywhere on the page (not while typing in a field). Let go early and the fill drains back; hold it to the end and onConfirm fires and the button flashes the accent. The fill keeps its pace under reduced motion: it tells you how long to hold.
It is a Button with every Button variant and size, secondary by default. Screen readers are told to press and hold. Put a Kbd inside to show the key.
Props
HoldButton
| Prop | Type | Default | Description |
|---|---|---|---|
| onConfirm | () => void | — | Fired once the hold is complete. |
| duration | number | 1200 | How long to hold, in ms. |
| hotkey | string | — | A key (KeyboardEvent.key) that holds it from anywhere. |
| variant / size / cut | Button's | "secondary" | As Button. |