Are you an LLM? Read llms.txt for a summary of the docs, or llms-full.txt for the full context.
Skip to content

CountdownButton

A button that counts down a fixed number of seconds, then fires onComplete — for auto-dispatch confirmations ("auto-dispatch in 5s") or cooldown gating ("resend code in 10s"). A subtle fill sweeps the button as the timer drains, and self-disables under prefers-reduced-motion.

Import

import { CountdownButton } from "@roger-emerson/ploxum-primitives";

Usage

<CountdownButton
  label="Auto-dispatch"
  onComplete={() => dispatchCrew()}
  runningLabel={(s) => `Dispatching in ${s}s`}
  seconds={5}
/>

Pass autostart to begin the countdown on mount (e.g. an auto-closing confirmation), or leave it off so the first click arms the timer (e.g. a resend cooldown).

Props

PropTypeDefaultDescription
secondsnumberCountdown duration in seconds. Required.
labelstring"Start"Resting label before the countdown starts.
runningLabel(s: number) => string(s) => `${s}s`Label while counting; receives the remaining whole seconds.
onComplete() => voidFired once the countdown reaches zero.
autostartbooleanfalseBegin counting down on mount instead of on first click.
onClick() => voidClick handler; also starts the countdown if it isn't already running.
classNamestringMerged onto the underlying Button.

Design rules

  • The progress fill is decorative (aria-hidden) and animates with a 1s linear sweep. Under prefers-reduced-motion it snaps between empty and full instead of animating.
  • The remaining-seconds readout uses tabular-nums so the label width doesn't jitter as digits change.
  • Composes the ploxum Button (secondary variant) — focus ring, disabled, and sizing behavior come from Button, so the control stays consistent with the rest of the system.
  • onComplete fires exactly once per run when the timer hits zero; re-arming requires a fresh click (or remount with autostart).

Storybook

Open CountdownButton in Storybook ↗