Skip to content
Template Empire
Browse components

Undo Grace

A free undo window button for Next.js and React with a truthful deadline and consumer-owned reversal link.

Draft editor · recent change

Draft removed from the review queue

Undo

Deadline

Deadline:

Gallery organiser · layout history

Summer collection arrangement changed

Undo

Deadline

Deadline:

Customise

Code

<BtnUndoGrace
  undoHref="/drafts/42/restore"
  expiresAt="2026-10-19T12:05:00.000Z"
  actionLabel="Draft removed"
/>

Undo Grace is a free button component for Next.js and React, styled with Tailwind, that presents a finite reversal window after a consumer action has already happened. Supply the real undo URL and absolute UTC deadline; the destination remains responsible for confirming availability.

The row keeps the native link usable after its deadline, shows the exact deadline without JavaScript, and updates a restrained indicator while visible. It pauses while hidden or offscreen, announces the initial window and expiry without reading every second aloud, and keeps a focused link stable as its accessible name changes after focus leaves.

Install

Add the @te registry to your components.json once:

{
  "registries": {
    "@te": "https://templateempire.io/r/{name}.json"
  }
}

Then install the component:

npx shadcn@latest add @te/btn-undo-grace

Usage

import { BtnUndoGrace } from "@/components/btn-undo-grace";

export function RemovedDraftNotice() {
  return (
    <BtnUndoGrace
      undoHref="/drafts/42/restore"
      expiresAt="2026-10-19T12:05:00.000Z"
      actionLabel="Draft removed from the review queue"
    />
  );
}

Props

PropTypeDefaultDescription
undoHrefstringrequiredConsumer-owned reversal destination. The server at that destination validates availability.
undoLabelstring"Undo"Native link label before and while the link is focused.
expiresAtstringrequiredAbsolute ISO 8601 UTC deadline supplied by the consumer.
actionLabelstringrequiredVisible description of the action that has already happened.
classNamestringundefinedAdditional classes merged onto the status row.

Customisation

Undo Grace exposes semantic ink, track and timing tokens. They change only the small deadline indicator and its transition, while the consumer continues to own the destination and deadline:

<div
  style={{
    "--undo-grace-ink": "var(--primary)",
    "--undo-grace-track": "var(--border)",
    "--undo-grace-duration": "120ms",
  }}
>
  <BtnUndoGrace
    undoHref="/drafts/42/restore"
    expiresAt="2026-10-19T12:05:00.000Z"
    actionLabel="Draft removed"
  />
</div>

Frequently asked questions

Is Undo Grace free for commercial use?
Yes. Undo Grace is MIT licensed and may be used in personal and commercial projects.
Does the countdown guarantee that undo will work?
No. It presents the consumer's UTC deadline and keeps the real link available after it. The destination must confirm whether reversal is still possible. Reduced motion removes the indicator transition, and the native link remains keyboard operable.
How do I customise the deadline indicator?
Override --undo-grace-ink, --undo-grace-track and --undo-grace-duration on the component or an ancestor. The consumer owns undoHref and expiresAt; there is no local rollback callback.

Related components

Want the full page this belongs to?Template Empire kits pair polished product states with complete Next.js pages. Browse the templates for a full interface around consumer actions like undo.Explore Template Empire templates