Countdown
The time left until a moment, in tabular figures, turning urgent under a threshold.
Web et mobile — le même composant pour React et React Native. Stable : son API ne change qu’à une version majeure.
Quand l’utiliser
- For a deadline the user acts against: an auction, an offer, a live event about to start.
- With the server's clock (
skewMs) when the end is decided by the server.
Quand ne pas l’utiliser
- For a date far away: write the date (“Ends on 12 May”).
- For the progress of a task.À la place : Progress
- For an elapsed time that keeps growing: format a duration in the text.
Installation
Installer
npm install @krizaka/ui@beta @krizaka/tailwind@beta @krizaka/tokens@beta tailwindcssStyles
@import "tailwindcss";
@import "@krizaka/tailwind";
@import "@krizaka/ui/tailwind.css";Importer
import { Countdown } from "@krizaka/ui/countdown";Exemples
Hours
Hours, minutes and seconds.
"use client";
import { Countdown } from "@krizaka/ui/countdown";
import { useState } from "react";
export default function CountdownHours() {
// One hour, two minutes and three seconds from the first render.
const [target] = useState(() => Date.now() + 3_723_000);
return <Countdown target={target} units={{ d: "d", h: "h", m: "m", s: "s" }} label="Ends in" />;
}Days
Days appear when there are some.
"use client";
import { Countdown } from "@krizaka/ui/countdown";
import { useState } from "react";
// Days appear when there are some: days, hours, minutes.
export default function CountdownDays() {
const [target] = useState(() => Date.now() + ((2 * 24 + 4) * 3600 + 13 * 60) * 1000);
return <Countdown target={target} units={{ d: "d", h: "h", m: "m", s: "s" }} label="Ends in" />;
}Sizes
sm, md (default), lg.
"use client";
import { Countdown } from "@krizaka/ui/countdown";
import { useState } from "react";
const units = { d: "d", h: "h", m: "m", s: "s" };
export default function CountdownSizes() {
const [target] = useState(() => Date.now() + 3_723_000);
return (
<div className="flex flex-col items-start gap-3">
<Countdown target={target} units={units} label="Ends in" size="sm" />
<Countdown target={target} units={units} label="Ends in" size="md" />
<Countdown target={target} units={units} label="Ends in" size="lg" />
</div>
);
}Urgent
Under a minute: the danger role, the last segment pulses.
"use client";
import { Countdown } from "@krizaka/ui/countdown";
import { useState } from "react";
// Under `urgentBelowMs` (one minute by default): the danger role, the last segment pulses.
export default function CountdownUrgent() {
const [target] = useState(() => Date.now() + 42_000);
return <Countdown target={target} units={{ d: "d", h: "h", m: "m", s: "s" }} label="Ends in" />;
}Ended
Past the target: zeros and data-ended.
"use client";
import { Countdown } from "@krizaka/ui/countdown";
import { useState } from "react";
// Past the target: zeros and `data-ended`. Say what happens next next to it.
export default function CountdownEnded() {
const [target] = useState(() => Date.now() - 1000);
return <Countdown target={target} units={{ d: "d", h: "h", m: "m", s: "s" }} label="Ended" />;
}Props
Time left until a moment, as segments (2d 04h 13m 09s — days only when there are some) in tabular figures. Under
urgentBelowMs it turns to the danger role and its last segment pulses (no motion under prefers-reduced-motion).
Words come from the app: units are the short unit labels. role="timer" without live announcements — the app
announces what matters. State: data-urgent, data-ended.
The danger role is large-text safe (≥ 3:1) from size="md"; at size="sm" an urgent countdown in light mode is
under the 4.5:1 of small text.
| Prop | Type | Défaut | Description |
|---|---|---|---|
labelrequis | string | — | Accessible name, e.g. "Ends in". |
targetrequis | string | number | Date | — | The moment it counts down to: a Date, an ISO string or epoch milliseconds. |
unitsrequis | CountdownUnits | — | The short unit labels, passed translated. |
className | string | — | Classes merged last, over the primitive's. |
size | "sm" | "md" | "lg" | md | sm · md · lg (the danger role is large-text safe from md). |
skewMs | number | 0 | Server clock − this clock, in milliseconds. |
urgentBelowMs | number | 60000 | Below this many milliseconds it turns urgent (text-danger, the last segment pulses). Default 60 s. |
Accessibilité
role="timer"named bylabel, without live announcements: a screen reader is not interrupted every second.- Announce the end yourself (a toast, a status) if it matters.
- The pulse of the last segment stops under
prefers-reduced-motion.
Bonnes pratiques
- Pass
unitsandlabeltranslated: they are the app's words. - Use
size="md"or larger when it can turn urgent: the danger colour is large-text safe frommd. - Say what happens at zero next to it: the countdown only shows zeros.
Composants liés
Générée depuis le code de @krizaka/ui 2.0.0-beta.6 : son meta.ts, ses exemples et ses types.Modifier cette documentation sur GitHub