Hold Button Demo
loomui/hold-button-demoFreeExample
A destructive action that only goes through if you keep holding.
Install it
npx shadcn@latest add https://loomui.design/r/hold-button-demo.jsonSource
1"use client"23import * as React from "react"45import { HoldButton } from "@/registry/loomui/hold-button"67const CONFIRM_MS = 15008/** Exits run shorter than entrances. */9const EXIT_MS = 15010const ENTER_MS = 20011/** Enough that the two are never both half there, smearing together. */12const ENTER_DELAY = 1201314/** One grid cell for both halves, so the swap is opacity and nothing else. */15const SWAP =16 "col-start-1 row-start-1 will-change-[opacity] transition-opacity ease-[var(--ease-out-quart)] motion-reduce:transition-none"1718export default function HoldButtonDemo() {19 const [done, setDone] = React.useState(false)20 const button = React.useRef<HTMLButtonElement>(null)21 const hadFocus = React.useRef(false)22 const timers = React.useRef<ReturnType<typeof setTimeout>[]>([])2324 React.useEffect(25 () => () => timers.current.forEach((timer) => clearTimeout(timer)),26 []27 )2829 const handleHold = () => {30 // Held with Space? Hand focus back, or the swap drops them on the body.31 hadFocus.current = document.activeElement === button.current32 setDone(true)3334 timers.current = [35 setTimeout(() => setDone(false), CONFIRM_MS),36 setTimeout(37 () => {38 // Focusing scrolls by default, which yanks the page mid swap.39 if (hadFocus.current) button.current?.focus({ preventScroll: true })40 },41 CONFIRM_MS + ENTER_DELAY + ENTER_MS42 ),43 ]44 }4546 return (47 <div className="grid place-items-center">48 <span49 className={`${SWAP} ${done ? "opacity-0" : "opacity-100 delay-[120ms]"}`}50 style={{ transitionDuration: `${done ? EXIT_MS : ENTER_MS}ms` }}51 >52 <HoldButton53 ref={button}54 duration={1100}55 onHold={handleHold}56 color="color-mix(in oklch, var(--destructive) 22%, transparent)"57 className="text-destructive px-4 py-2 text-sm font-medium"58 tabIndex={done ? -1 : undefined}59 inert={done}60 >61 Hold to delete62 </HoldButton>63 </span>6465 <span66 aria-hidden="true"67 className={`${SWAP} text-muted-foreground pointer-events-none flex items-center gap-2 text-sm ${68 done ? "opacity-100 delay-[120ms]" : "opacity-0"69 }`}70 style={{ transitionDuration: `${done ? ENTER_MS : EXIT_MS}ms` }}71 >72 <svg73 viewBox="0 0 24 24"74 fill="none"75 stroke="currentColor"76 strokeWidth="2.5"77 strokeLinecap="round"78// … truncated
What it pulls in
Other registry items
Files it writes
More from loomui
All 91 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| Aurora Backdrop Demoaurora-backdrop-demo | loomui | Examples | Free | no deps | |
| Bento Grid Demobento-grid-demo | loomui | Examples | Free | no deps | |
| Card Stack Democard-stack-demo | loomui | Examples | Free | no deps | |
| Compare Slider Democompare-slider-demo | loomui | Examples | Free | no deps | |
| Confetti Button Democonfetti-button-demo | loomui | Examples | Free | no deps | |
| Count Up Democount-up-demo | loomui | Examples | Free | no deps | |
| Credit Card Democredit-card-demo | loomui | Examples | Free | no deps | |
| Drawer Demodrawer-demo | loomui | Examples | Free | no deps |
