zero-hour
v2.0.1
Published
Tiny countdown Web Component. Registers <countdown-timer> that renders a configurable DD:HH:MM:SS countdown to a target date/time (optional UTC offset) and fires a done event at zero.
Maintainers
Readme
zero-hour
Tiny countdown Web Component that registers <countdown-timer> with a configurable DD:HH:MM:SS display.
- Registers
<countdown-timer>viacustomElements.defineon import. - Configurable visible units (
d,h,m,s) and UTC offset for the target moment. - Ticks on exact second boundaries; fires a
doneevent once when the countdown reaches zero. - Optional digit sprites with
staticorscrolltransition mode. - Built-in CSS sidecar and
zeroHourCssTextexport for shadow-root styling.
Installation
npm install zero-hourOptional stylesheet (sidecar):
# import in your bundler entry, or link in HTML:
# import 'zero-hour/zero-hour.css';Quick Start
Import the package to register the element, then place it in your markup:
<countdown-timer
digits-url="/sprites/digits.webp"
separator-url="/sprites/sep.webp"
date="2025-12-31"
time="23:59:59"
utc="+03:00"
></countdown-timer>import 'zero-hour';Subscribe to completion and apply optional styles:
import { initCountdownTimers, zeroHourCssText } from 'zero-hour';
initCountdownTimers({
selector: 'countdown-timer',
onDone: (el) => {
el.classList.add('is-done');
},
stylesheet: zeroHourCssText,
});API
import 'zero-hour'— registers<countdown-timer>(side effect).initCountdownTimers(options?)— finds elements, optionalonDone/stylesheethelpers.zeroHourCssText— minified default CSS text shipped with the package.
Element instance methods (on <countdown-timer> after import):
start()— starts or restarts the countdown (digits-urlrequired).stop()— stops the timer and clears the scheduled tick.reset()— clears the done flag; restarts whenautostart=true.isRunning()—truewhen a tick is scheduled.isDone()—truewhen the target moment is in the past.adoptStylesheet(sheet)— replacesadoptedStyleSheetsin the shadow root.adoptStyles(text)— applies CSS text via constructable stylesheet or<style>fallback.
Options
| Option (attribute) | Type | Default | Description |
|:-------------------|:-----|:--------|:------------|
| digits-url | string | — | URL to the digits sprite sheet. Required for the graphical display. |
| separator-url | string | null | URL to the separator sprite (e.g. colon). Omit to hide separators. |
| autostart | boolean | true | Auto-start on connect (autostart or autostart="false"). |
| date | YYYY-MM-DD | — | Target date. Without date the timer resolves to zero. |
| time | HH:MM[:SS] | 00:00:00 | Target time. |
| utc | UTC±H[:MM] or ±H[:MM] | UTC+0 | UTC offset for the target moment (e.g. UTC+03:00, UTC-5). |
| units | string | "d:h:m:s" | Visible groups using d, h, m, s separated by : (e.g. "h:m:s"). |
| mode | "static" | "scroll" | "static" | Digit transition mode (scroll = rolling effect). |
Events
| Event | Description |
|:------|:------------|
| done | Fired once when the countdown reaches zero (again after reset()). |
Methods
initCountdownTimers({
selector?: string; // default: 'countdown-timer'
onDone?: (el: HTMLElement) => void;
stylesheet?: CSSStyleSheet | string | null;
}): HTMLElement[]If a timer is already complete at init time, onDone is called immediately (catch-up).
Styling
Default package CSS:
import { initCountdownTimers, zeroHourCssText } from 'zero-hour';
initCountdownTimers({ stylesheet: zeroHourCssText });Or import the sidecar file in your bundler:
import 'zero-hour/zero-hour.css';Custom CSS text from your pipeline:
import { initCountdownTimers } from 'zero-hour';
import ZeroHourCss from './assets/scss/components/zero-hour.scss?raw';
initCountdownTimers({ stylesheet: ZeroHourCss });Manual control:
const el = document.querySelector('countdown-timer');
el?.stop();
el?.reset();
el?.start();Notes
- Updates tick on exact second boundaries for a stable display.
- Days render as two digits, capped at 99.
unitscontrols visible d/h/m/s groups; separators hide whenseparator-urlis unset.- Digit sprite is horizontal, frames left-to-right
0–9; frame index equals the digit value.
License
MIT
