Delete with undo, no confirm dialog

Hold to delete, then five seconds to undo. The server action only runs when that window closes, so undo never has to restore anything.

Get the code · $3React · Tailwind · TypeScript
Hold to Delete, preview

Use it in Next.js

app/projects/DeleteProject.tsx

"use client";
import HoldToDelete from "@/components/HoldToDelete";
import { deleteProject } from "./actions";

export function DeleteProject({ id, name }: { id: string; name: string }) {
  return (
    <HoldToDelete
      fileName={name}
      fileMeta="Project"
      fileType="APP"
      tags={[]}
      restoreLabel={null}
      onCommit={() => deleteProject(id)}
    />
  );
}

app/projects/actions.ts

"use server";
import { revalidatePath } from "next/cache";

export async function deleteProject(id: string) {
  // your real delete: Supabase, Prisma, Drizzle or an API call
  await fetch(`${process.env.API_URL}/projects/${id}`, { method: "DELETE" });
  revalidatePath("/projects");
}

Good to know

  • The component has three callbacks. onDelete fires when the hold completes, onUndo if they change their mind, and onCommit when the undo window runs out. Delete for real in onCommit only.
  • If the tab closes during the undo window, onCommit never fires and nothing is deleted. That's the safe way to fail, but tell your users if it matters.
  • Holding is slower than clicking. For things people delete twenty times a day, a plain button with undo may be kinder.
  • Keyboard users can hold Space or Enter on the button.

Install

  1. Copy from the zipPut react/src/components into src/, then npm i framer-motion.
  2. Or ask your AIPaste PROMPT.md into Cursor, Lovable or v0.

Props

onCommit
the undo window ran out: delete here
onUndo
undo was pressed
holdMs / undoMs
1200 ms hold, 5000 ms undo by default
fileName / fileMeta / fileType
what the card shows

How qodesign compares

  • qodesign vs UiverseUiverse is best for: single small elements: buttons, loaders, toggles, checkboxes, inputs.
  • qodesign vs AnimataAnimata is best for: free animated building blocks you copy and adapt.

All comparisons, with prices read on each library's own site.

Questions

Why not just use confirm()?

People click through confirm boxes without reading. A hold plus undo stops the accident and still lets them fix it.

Can I change the 5 seconds?

Yes, with undoMs.

Can Cursor or v0 add it for me?

Yes. Each download has a PROMPT.md. Paste it into Cursor, Lovable, v0 or Claude Code and it fits the piece into your app.

Can I use it in client work?

Yes, in personal and client projects. You can't resell the code itself as a kit.