zero-hour 1.3.1 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +102 -104
- package/dist/index.cjs +607 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +75 -0
- package/dist/index.d.ts +69 -55
- package/dist/index.js +604 -0
- package/dist/index.js.map +1 -0
- package/dist/zero-hour.css +1 -1
- package/package.json +52 -24
- package/dist/index.cjs.js +0 -54
- package/dist/index.es.js +0 -375
- package/dist/index.umd.js +0 -54
package/README.md
CHANGED
|
@@ -1,42 +1,39 @@
|
|
|
1
|
-
|
|
1
|
+
# zero-hour
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
<p align="center">ZeroHour is a tiny countdown Web Component. It registers <code><countdown-timer></code> that renders a <code>DD:HH:MM:SS</code> countdown (with configurable visible units), counts down to a target date/time with an optional UTC offset, ticks on exact second boundaries, and fires a <code>done</code> event when it reaches zero.</p>
|
|
3
|
+
Tiny countdown Web Component that registers `<countdown-timer>` with a configurable DD:HH:MM:SS display.
|
|
5
4
|
|
|
6
5
|
[](https://www.npmjs.com/package/zero-hour)
|
|
7
|
-
[](https://www.npmjs.org/package/zero-hour)
|
|
6
|
+
[](https://www.npmjs.com/package/zero-hour)
|
|
9
7
|
|
|
10
|
-
|
|
11
|
-
</div>
|
|
12
|
-
<br>
|
|
8
|
+
[Demo](https://codepen.io/ux-ui/pen/MYyMpPw)
|
|
13
9
|
|
|
14
|
-
|
|
10
|
+
---
|
|
15
11
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
12
|
+
- Registers `<countdown-timer>` via `customElements.define` on import.
|
|
13
|
+
- Configurable visible units (`d`, `h`, `m`, `s`) and UTC offset for the target moment.
|
|
14
|
+
- Ticks on exact second boundaries; fires a `done` event once when the countdown reaches zero.
|
|
15
|
+
- Optional digit sprites with `static` or `scroll` transition mode.
|
|
16
|
+
- Built-in CSS sidecar and `zeroHourCssText` export for shadow-root styling.
|
|
20
17
|
|
|
21
|
-
|
|
18
|
+
---
|
|
22
19
|
|
|
23
|
-
|
|
24
|
-
// Registers <countdown-timer> via customElements.define(...)
|
|
25
|
-
import 'zero-hour';
|
|
20
|
+
## Installation
|
|
26
21
|
|
|
27
|
-
|
|
28
|
-
|
|
22
|
+
```bash
|
|
23
|
+
npm install zero-hour
|
|
29
24
|
```
|
|
30
|
-
<br>
|
|
31
25
|
|
|
32
|
-
|
|
26
|
+
Optional stylesheet (sidecar):
|
|
33
27
|
|
|
34
|
-
```
|
|
35
|
-
|
|
36
|
-
|
|
28
|
+
```bash
|
|
29
|
+
# import in your bundler entry, or link in HTML:
|
|
30
|
+
# import 'zero-hour/zero-hour.css';
|
|
37
31
|
```
|
|
38
32
|
|
|
39
|
-
|
|
33
|
+
## Quick Start
|
|
34
|
+
|
|
35
|
+
Import the package to register the element, then place it in your markup:
|
|
36
|
+
|
|
40
37
|
```html
|
|
41
38
|
<countdown-timer
|
|
42
39
|
digits-url="/sprites/digits.webp"
|
|
@@ -47,111 +44,112 @@ import { initCountdownTimers } from 'zero-hour';
|
|
|
47
44
|
></countdown-timer>
|
|
48
45
|
```
|
|
49
46
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
47
|
+
```js
|
|
48
|
+
import 'zero-hour';
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Subscribe to completion and apply optional styles:
|
|
52
|
+
|
|
53
|
+
```js
|
|
54
|
+
import { initCountdownTimers, zeroHourCssText } from 'zero-hour';
|
|
53
55
|
|
|
54
56
|
initCountdownTimers({
|
|
55
57
|
selector: 'countdown-timer',
|
|
56
58
|
onDone: (el) => {
|
|
57
|
-
// The component dispatches: el.dispatchEvent(new CustomEvent('done'))
|
|
58
|
-
// Note: if the timer is already complete (e.g. user opened the page after the target time),
|
|
59
|
-
// `initCountdownTimers` will call `onDone` immediately (catch-up).
|
|
60
59
|
el.classList.add('is-done');
|
|
61
60
|
},
|
|
62
|
-
|
|
63
|
-
// - CSSStyleSheet (constructable stylesheet)
|
|
64
|
-
// - string (e.g. imported via ?raw from your CSS/SCSS pipeline)
|
|
65
|
-
// stylesheet: myCssStyleSheet,
|
|
61
|
+
stylesheet: zeroHourCssText,
|
|
66
62
|
});
|
|
67
63
|
```
|
|
68
64
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
import
|
|
72
|
-
|
|
65
|
+
## API
|
|
66
|
+
|
|
67
|
+
- **`import 'zero-hour'`** — registers `<countdown-timer>` (side effect).
|
|
68
|
+
- **`initCountdownTimers(options?)`** — finds elements, optional `onDone` / `stylesheet` helpers.
|
|
69
|
+
- **`zeroHourCssText`** — minified default CSS text shipped with the package.
|
|
73
70
|
|
|
71
|
+
Element instance methods (on `<countdown-timer>` after import):
|
|
72
|
+
|
|
73
|
+
- **`start()`** — starts or restarts the countdown (`digits-url` required).
|
|
74
|
+
- **`stop()`** — stops the timer and clears the scheduled tick.
|
|
75
|
+
- **`reset()`** — clears the done flag; restarts when `autostart=true`.
|
|
76
|
+
- **`isRunning()`** — `true` when a tick is scheduled.
|
|
77
|
+
- **`isDone()`** — `true` when the target moment is in the past.
|
|
78
|
+
- **`adoptStylesheet(sheet)`** — replaces `adoptedStyleSheets` in the shadow root.
|
|
79
|
+
- **`adoptStyles(text)`** — applies CSS text via constructable stylesheet or `<style>` fallback.
|
|
80
|
+
|
|
81
|
+
## Options
|
|
82
|
+
|
|
83
|
+
| Option (attribute) | Type | Default | Description |
|
|
84
|
+
|:-------------------|:-----|:--------|:------------|
|
|
85
|
+
| `digits-url` | `string` | — | URL to the digits sprite sheet. Required for the graphical display. |
|
|
86
|
+
| `separator-url` | `string` | `null` | URL to the separator sprite (e.g. colon). Omit to hide separators. |
|
|
87
|
+
| `autostart` | `boolean` | `true` | Auto-start on connect (`autostart` or `autostart="false"`). |
|
|
88
|
+
| `date` | `YYYY-MM-DD` | — | Target date. Without `date` the timer resolves to zero. |
|
|
89
|
+
| `time` | `HH:MM[:SS]` | `00:00:00` | Target time. |
|
|
90
|
+
| `utc` | `UTC±H[:MM]` or `±H[:MM]` | `UTC+0` | UTC offset for the target moment (e.g. `UTC+03:00`, `UTC-5`). |
|
|
91
|
+
| `units` | `string` | `"d:h:m:s"` | Visible groups using `d`, `h`, `m`, `s` separated by `:` (e.g. `"h:m:s"`). |
|
|
92
|
+
| `mode` | `"static"` \| `"scroll"` | `"static"` | Digit transition mode (`scroll` = rolling effect). |
|
|
93
|
+
|
|
94
|
+
## Events
|
|
95
|
+
|
|
96
|
+
| Event | Description |
|
|
97
|
+
|:------|:------------|
|
|
98
|
+
| `done` | Fired once when the countdown reaches zero (again after `reset()`). |
|
|
99
|
+
|
|
100
|
+
## Methods
|
|
101
|
+
|
|
102
|
+
```js
|
|
74
103
|
initCountdownTimers({
|
|
75
|
-
|
|
76
|
-
|
|
104
|
+
selector?: string; // default: 'countdown-timer'
|
|
105
|
+
onDone?: (el: HTMLElement) => void;
|
|
106
|
+
stylesheet?: CSSStyleSheet | string | null;
|
|
107
|
+
}): HTMLElement[]
|
|
77
108
|
```
|
|
78
109
|
|
|
79
|
-
|
|
80
|
-
```javascript
|
|
81
|
-
import { initCountdownTimers, zeroHourCssText } from 'zero-hour';
|
|
110
|
+
If a timer is already complete at init time, `onDone` is called immediately (catch-up).
|
|
82
111
|
|
|
83
|
-
|
|
84
|
-
initCountdownTimers({
|
|
85
|
-
stylesheet: zeroHourCssText,
|
|
86
|
-
});
|
|
112
|
+
## Styling
|
|
87
113
|
|
|
88
|
-
|
|
89
|
-
// import ZeroHourCss from 'zero-hour/zero-hour.css?raw';
|
|
90
|
-
// initCountdownTimers({ stylesheet: ZeroHourCss });
|
|
91
|
-
```
|
|
114
|
+
Default package CSS:
|
|
92
115
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
const el = document.querySelector('countdown-timer');
|
|
96
|
-
// @ts-expect-error: methods exist on the custom element instance after import
|
|
97
|
-
el?.stop();
|
|
98
|
-
// @ts-expect-error
|
|
99
|
-
el?.reset();
|
|
100
|
-
// @ts-expect-error
|
|
101
|
-
el?.start();
|
|
102
|
-
```
|
|
116
|
+
```js
|
|
117
|
+
import { initCountdownTimers, zeroHourCssText } from 'zero-hour';
|
|
103
118
|
|
|
104
|
-
|
|
105
|
-
```html
|
|
106
|
-
<countdown-timer
|
|
107
|
-
digits-url="/sprites/digits.webp"
|
|
108
|
-
separator-url="/sprites/sep.webp"
|
|
109
|
-
date="2025-12-31"
|
|
110
|
-
time="23:59:59"
|
|
111
|
-
utc="+03:00"
|
|
112
|
-
units="h:m:s"
|
|
113
|
-
></countdown-timer>
|
|
119
|
+
initCountdownTimers({ stylesheet: zeroHourCssText });
|
|
114
120
|
```
|
|
115
|
-
<br>
|
|
116
121
|
|
|
117
|
-
|
|
122
|
+
Or import the sidecar file in your bundler:
|
|
118
123
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
| `separator-url` | `string` | `null` | URL to the separator sprite (e.g. a colon). If omitted, separators are hidden. |
|
|
123
|
-
| `autostart` | `boolean` | `true` | Auto-start on connect. Can be a boolean attribute (`autostart`) or a string (`autostart="false"`). |
|
|
124
|
-
| `date` | `YYYY-MM-DD` | — | Target date. Without `date` the timer resolves to zero. |
|
|
125
|
-
| `time` | `HH:MM[:SS]` | `00:00:00` | Target time. |
|
|
126
|
-
| `utc` | `UTC±H[:MM]` or `±H[:MM]` | `UTC+0` | UTC offset used to compute the target moment. Examples: `utc="UTC+03:00"`, `utc="UTC-5"`. |
|
|
127
|
-
| `units` | `string` | `"d:h:m:s"` | Visible groups pattern using `d`, `h`, `m`, `s` separated by `:` (e.g. `"h:m:s"`). Empty/invalid value falls back to showing all. |
|
|
124
|
+
```js
|
|
125
|
+
import 'zero-hour/zero-hour.css';
|
|
126
|
+
```
|
|
128
127
|
|
|
129
|
-
|
|
128
|
+
Custom CSS text from your pipeline:
|
|
130
129
|
|
|
131
|
-
|
|
130
|
+
```js
|
|
131
|
+
import { initCountdownTimers } from 'zero-hour';
|
|
132
|
+
import ZeroHourCss from './assets/scss/components/zero-hour.scss?raw';
|
|
132
133
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
| `initCountdownTimers({ selector?, onDone?, stylesheet? }): HTMLElement[]` | Finds elements by selector (default: `countdown-timer`), subscribes to the `done` event (when `onDone` is provided), and calls `onDone` immediately if a timer is already complete at init time (catch-up). Also optionally applies styles to each element (`stylesheet?: CSSStyleSheet \| string \| null`). When a string is provided, it is applied via `adoptedStyleSheets` when supported, otherwise via a `<style>` fallback inside the shadow root. |
|
|
136
|
-
| `start(): void` | Starts/restarts the countdown (only runs when `digits-url` is set). |
|
|
137
|
-
| `stop(): void` | Stops the timer and clears the scheduled tick. |
|
|
138
|
-
| `reset(): void` | Clears the “done fired” flag and either starts again (if `autostart=true`) or renders a static initial value. |
|
|
139
|
-
| `isRunning(): boolean` | Returns `true` if the timer is running and the next tick is scheduled. |
|
|
140
|
-
| `isDone(): boolean` | Returns `true` if the computed target moment is in the past (logically complete), regardless of whether a `done` event listener was attached in time. |
|
|
141
|
-
| `adoptStylesheet(sheet: CSSStyleSheet): void` | Replaces `adoptedStyleSheets` inside the component’s shadow root. |
|
|
134
|
+
initCountdownTimers({ stylesheet: ZeroHourCss });
|
|
135
|
+
```
|
|
142
136
|
|
|
143
|
-
|
|
137
|
+
Manual control:
|
|
144
138
|
|
|
145
|
-
|
|
139
|
+
```js
|
|
140
|
+
const el = document.querySelector('countdown-timer');
|
|
141
|
+
el?.stop();
|
|
142
|
+
el?.reset();
|
|
143
|
+
el?.start();
|
|
144
|
+
```
|
|
146
145
|
|
|
147
|
-
|
|
148
|
-
- Days render as **two digits** and are capped at **99**.
|
|
149
|
-
- `units` controls which groups (d/h/m/s) are visible. Separators are auto-hidden when `separator-url` is not set, or when a separator is not needed between visible groups.
|
|
150
|
-
- The `done` event fires once per run (after `reset()` it can fire again).
|
|
151
|
-
- Digit sprite must be horizontal, frames left-to-right: `0,1,2,3,4,5,6,7,8,9`. The frame index equals the digit.
|
|
146
|
+
## Notes
|
|
152
147
|
|
|
153
|
-
|
|
148
|
+
- Updates tick on exact second boundaries for a stable display.
|
|
149
|
+
- Days render as two digits, capped at 99.
|
|
150
|
+
- `units` controls visible d/h/m/s groups; separators hide when `separator-url` is unset.
|
|
151
|
+
- Digit sprite is horizontal, frames left-to-right `0–9`; frame index equals the digit value.
|
|
154
152
|
|
|
155
|
-
|
|
153
|
+
## License
|
|
156
154
|
|
|
157
|
-
|
|
155
|
+
MIT
|