From cc003b3c06140de7cf7f4cc3412cec3854024a11 Mon Sep 17 00:00:00 2001 From: Martin Veith Date: Sun, 14 Jun 2026 21:20:59 +0200 Subject: [PATCH 1/2] docs: Add refresh() method and update changelog --- CHANGELOG.md | 1 + README.md | 16 ++++++++++++++++ 2 files changed, 17 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index fa7b407..d11bdd2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,6 +23,7 @@ A full rewrite of the internals: all countdown logic now lives in a framework-ag - **`resetKey` prop** to restart the countdown without remounting (React's `key` still works to remount). - **`freezeProps` prop** to opt out of prop tracking after mount. - **`CountdownStatus` enum is now exported**, plus a **`getStatus()`** method on the API. +- **`refresh()`** method on the API to force an immediate recompute and re-render against the current clock (e.g. from a `visibilitychange` listener after the interval was throttled in a background tab). - Dual **ESM + CJS** build with bundled type definitions and `sideEffects: false` for tree-shaking. ### Migrating from 2.x diff --git a/README.md b/README.md index 871cdc0..962b764 100644 --- a/README.md +++ b/README.md @@ -344,6 +344,22 @@ Pauses the running countdown. This only works as expected if the [`controlled`]( Stops the countdown. This only works as expected if the [`controlled`](#controlled) prop is set to `false` because [`calcTimeDelta`](#calctimedelta) calculates an offset time internally. +### `refresh()` + +Forces an immediate recompute of the [time delta](#calctimedelta) and a re-render against the current clock, without changing the countdown's status or offsets. This is useful when the internal interval has been throttled (for example, while the tab was in the background) and you want the displayed value to update right away instead of waiting for the next tick, e.g. from a `visibilitychange` listener: + +```jsx +React.useEffect(() => { + const onVisible = () => { + if (!document.hidden) ref.current?.api.refresh(); + }; + document.addEventListener('visibilitychange', onVisible); + return () => document.removeEventListener('visibilitychange', onVisible); +}, []); +``` + +Like a regular tick, it triggers [`onTick`](#ontick); and if the recomputed time has crossed zero, it fires [`onComplete`](#oncomplete) just as the final interval tick would. + ### `isStarted()` Returns a `boolean` for whether the countdown is currently started (running) or not. From 9dff65b0e16ca945a3b117157afce8db1350a46d Mon Sep 17 00:00:00 2001 From: Martin Veith Date: Sun, 14 Jun 2026 21:23:03 +0200 Subject: [PATCH 2/2] docs: Update README with visibility change handling and type annotations --- README.md | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 962b764..24fde88 100644 --- a/README.md +++ b/README.md @@ -353,6 +353,7 @@ React.useEffect(() => { const onVisible = () => { if (!document.hidden) ref.current?.api.refresh(); }; + document.addEventListener('visibilitychange', onVisible); return () => document.removeEventListener('visibilitychange', onVisible); }, []); @@ -414,7 +415,13 @@ const renderer = ({ hours, minutes, seconds }) => ( ```js { - total, days, hours, minutes, seconds, milliseconds, completed; + total: number; + days: number; + hours: number; + minutes: number; + seconds: number; + milliseconds: number; + completed: boolean; } ```