@uibit/countdown 0.1.0 → 0.2.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 CHANGED
@@ -1,7 +1,17 @@
1
1
  # Countdown
2
2
 
3
+ [![NPM Version](https://img.shields.io/npm/v/@uibit/countdown.svg?style=flat-square&color=black)](https://www.npmjs.com/package/@uibit/countdown)
4
+
5
+
3
6
  [Interactive Demonstration](https://rawlings.github.io/uibit/components/countdown)
4
7
 
8
+ ## Installation
9
+
10
+ ```bash
11
+ npm install @uibit/countdown
12
+ ```
13
+
14
+
5
15
  Countdown provides a highly customizable visual timer designed to communicate time sensitivity and build anticipation. Whether highlighting a product launch, event deadline, or limited-time campaign, it offers clear, real-time feedback that drives user action.
6
16
 
7
17
  ## Value Delivery
@@ -8,7 +8,7 @@
8
8
  "declarations": [
9
9
  {
10
10
  "kind": "class",
11
- "description": "Countdown timer to a target date/time or a fixed duration. Supports\nconfigurable display formats and fires events on each tick and on completion.",
11
+ "description": "Countdown timer to a target date/time or a fixed duration. Supports",
12
12
  "name": "Countdown",
13
13
  "cssProperties": [
14
14
  {
@@ -175,7 +175,8 @@
175
175
  },
176
176
  {
177
177
  "kind": "method",
178
- "name": "start"
178
+ "name": "start",
179
+ "description": "\n\nStarts or resumes the countdown timer."
179
180
  },
180
181
  {
181
182
  "kind": "method",
@@ -190,6 +191,211 @@
190
191
  "kind": "method",
191
192
  "name": "getFormattedUnits",
192
193
  "privacy": "private"
194
+ },
195
+ {
196
+ "kind": "field",
197
+ "name": "locale",
198
+ "type": {
199
+ "text": "string"
200
+ },
201
+ "default": "''",
202
+ "description": "BCP 47 locale string for formatting and localization. Defaults to inherited document language.",
203
+ "attribute": "locale",
204
+ "inheritedFrom": {
205
+ "name": "UIBitElement",
206
+ "module": "../../platform/core/src/element.ts"
207
+ }
208
+ },
209
+ {
210
+ "kind": "field",
211
+ "name": "resolvedLocale",
212
+ "type": {
213
+ "text": "string | undefined"
214
+ },
215
+ "description": "Resolves the active locale for formatting and localization.\nChecks the `locale` property first, then traverses up the DOM to find\nthe nearest ancestor with a `lang` attribute, and finally falls back\nto undefined (which defaults to browser locale).",
216
+ "readonly": true,
217
+ "inheritedFrom": {
218
+ "name": "UIBitElement",
219
+ "module": "../../platform/core/src/element.ts"
220
+ }
221
+ },
222
+ {
223
+ "kind": "field",
224
+ "name": "_disposables",
225
+ "type": {
226
+ "text": "Set<() => void>"
227
+ },
228
+ "privacy": "private",
229
+ "default": "new Set()",
230
+ "inheritedFrom": {
231
+ "name": "UIBitElement",
232
+ "module": "../../platform/core/src/element.ts"
233
+ }
234
+ },
235
+ {
236
+ "kind": "method",
237
+ "name": "createProperty",
238
+ "static": true,
239
+ "parameters": [
240
+ {
241
+ "name": "name",
242
+ "type": {
243
+ "text": "PropertyKey"
244
+ }
245
+ },
246
+ {
247
+ "name": "options",
248
+ "optional": true,
249
+ "type": {
250
+ "text": "PropertyDeclaration"
251
+ }
252
+ }
253
+ ],
254
+ "description": "Overrides createProperty to automatically map camelCase property names\nto kebab-case attribute names by default.",
255
+ "inheritedFrom": {
256
+ "name": "UIBitElement",
257
+ "module": "../../platform/core/src/element.ts"
258
+ }
259
+ },
260
+ {
261
+ "kind": "method",
262
+ "name": "finalizeStyles",
263
+ "static": true,
264
+ "return": {
265
+ "type": {
266
+ "text": "Array<any>"
267
+ }
268
+ },
269
+ "parameters": [
270
+ {
271
+ "name": "styles",
272
+ "optional": true,
273
+ "type": {
274
+ "text": "CSSResultGroup"
275
+ }
276
+ }
277
+ ],
278
+ "description": "Automatically prepends basic layout resets (border-box) to the\ncomponent's final styles.",
279
+ "inheritedFrom": {
280
+ "name": "UIBitElement",
281
+ "module": "../../platform/core/src/element.ts"
282
+ }
283
+ },
284
+ {
285
+ "kind": "method",
286
+ "name": "dispatchCustomEvent",
287
+ "return": {
288
+ "type": {
289
+ "text": "boolean"
290
+ }
291
+ },
292
+ "parameters": [
293
+ {
294
+ "name": "name",
295
+ "type": {
296
+ "text": "string"
297
+ }
298
+ },
299
+ {
300
+ "name": "detail",
301
+ "optional": true,
302
+ "type": {
303
+ "text": "T"
304
+ }
305
+ },
306
+ {
307
+ "name": "options",
308
+ "optional": true,
309
+ "type": {
310
+ "text": "Omit<CustomEventInit<T>, 'detail'>"
311
+ }
312
+ }
313
+ ],
314
+ "description": "Helper to dispatch a custom event with standard bubbles and composed options.",
315
+ "inheritedFrom": {
316
+ "name": "UIBitElement",
317
+ "module": "../../platform/core/src/element.ts"
318
+ }
319
+ },
320
+ {
321
+ "kind": "method",
322
+ "name": "getCssPropertyValue",
323
+ "return": {
324
+ "type": {
325
+ "text": "string"
326
+ }
327
+ },
328
+ "parameters": [
329
+ {
330
+ "name": "propertyName",
331
+ "type": {
332
+ "text": "string"
333
+ }
334
+ }
335
+ ],
336
+ "description": "Helper to retrieve a computed CSS custom property value from the element.",
337
+ "inheritedFrom": {
338
+ "name": "UIBitElement",
339
+ "module": "../../platform/core/src/element.ts"
340
+ }
341
+ },
342
+ {
343
+ "kind": "method",
344
+ "name": "registerDisposable",
345
+ "parameters": [
346
+ {
347
+ "name": "cleanup",
348
+ "type": {
349
+ "text": "() => void"
350
+ }
351
+ }
352
+ ],
353
+ "description": "Register a cleanup function to be executed when the element is disconnected from the DOM.",
354
+ "inheritedFrom": {
355
+ "name": "UIBitElement",
356
+ "module": "../../platform/core/src/element.ts"
357
+ }
358
+ },
359
+ {
360
+ "kind": "method",
361
+ "name": "listen",
362
+ "return": {
363
+ "type": {
364
+ "text": "() => void"
365
+ }
366
+ },
367
+ "parameters": [
368
+ {
369
+ "name": "target",
370
+ "type": {
371
+ "text": "EventTarget"
372
+ }
373
+ },
374
+ {
375
+ "name": "type",
376
+ "type": {
377
+ "text": "K"
378
+ }
379
+ },
380
+ {
381
+ "name": "listener",
382
+ "type": {
383
+ "text": "(this: EventTarget, ev: HTMLElementEventMap[K]) => any"
384
+ }
385
+ },
386
+ {
387
+ "name": "options",
388
+ "optional": true,
389
+ "type": {
390
+ "text": "boolean | AddEventListenerOptions"
391
+ }
392
+ }
393
+ ],
394
+ "description": "Utility to add an event listener that is automatically cleaned up when the element is disconnected.",
395
+ "inheritedFrom": {
396
+ "name": "UIBitElement",
397
+ "module": "../../platform/core/src/element.ts"
398
+ }
193
399
  }
194
400
  ],
195
401
  "events": [
@@ -239,12 +445,32 @@
239
445
  "default": "'HH:MM:SS'",
240
446
  "description": "Display format. Tokens: `DD` days, `HH` hours, `MM` minutes, `SS` seconds.",
241
447
  "fieldName": "format"
448
+ },
449
+ {
450
+ "name": "locale",
451
+ "type": {
452
+ "text": "string"
453
+ },
454
+ "default": "''",
455
+ "description": "BCP 47 locale string for formatting and localization. Defaults to inherited document language.",
456
+ "fieldName": "locale",
457
+ "inheritedFrom": {
458
+ "name": "UIBitElement",
459
+ "module": "../../platform/core/src/element.ts"
460
+ }
461
+ }
462
+ ],
463
+ "cssStates": [
464
+ {
465
+ "name": "finished",
466
+ "description": "Active when the countdown timer reaches zero."
242
467
  }
243
468
  ],
244
469
  "superclass": {
245
470
  "name": "UIBitElement",
246
471
  "package": "@uibit/core"
247
472
  },
473
+ "summary": "A responsive and customizable digital timer and countdown clock component.\nconfigurable display formats and fires events on each tick and on completion.",
248
474
  "tagName": "uibit-countdown",
249
475
  "customElement": true
250
476
  }
@@ -341,6 +567,250 @@
341
567
  "path": "src/types.ts",
342
568
  "declarations": [],
343
569
  "exports": []
570
+ },
571
+ {
572
+ "kind": "javascript-module",
573
+ "path": "../../platform/core/src/element.ts",
574
+ "declarations": [
575
+ {
576
+ "kind": "class",
577
+ "description": "A foundational base class for all UIBit web components.\nProvides custom event helpers, default kebab-case attribute mapping,\nautomatic cleanup/disposable tracking, and auto-injected reset styles.",
578
+ "name": "UIBitElement",
579
+ "members": [
580
+ {
581
+ "kind": "field",
582
+ "name": "locale",
583
+ "type": {
584
+ "text": "string"
585
+ },
586
+ "default": "''",
587
+ "description": "BCP 47 locale string for formatting and localization. Defaults to inherited document language.",
588
+ "attribute": "locale"
589
+ },
590
+ {
591
+ "kind": "field",
592
+ "name": "resolvedLocale",
593
+ "type": {
594
+ "text": "string | undefined"
595
+ },
596
+ "description": "Resolves the active locale for formatting and localization.\nChecks the `locale` property first, then traverses up the DOM to find\nthe nearest ancestor with a `lang` attribute, and finally falls back\nto undefined (which defaults to browser locale).",
597
+ "readonly": true
598
+ },
599
+ {
600
+ "kind": "field",
601
+ "name": "_disposables",
602
+ "type": {
603
+ "text": "Set<() => void>"
604
+ },
605
+ "privacy": "private",
606
+ "default": "new Set()"
607
+ },
608
+ {
609
+ "kind": "method",
610
+ "name": "createProperty",
611
+ "static": true,
612
+ "parameters": [
613
+ {
614
+ "name": "name",
615
+ "type": {
616
+ "text": "PropertyKey"
617
+ }
618
+ },
619
+ {
620
+ "name": "options",
621
+ "optional": true,
622
+ "type": {
623
+ "text": "PropertyDeclaration"
624
+ }
625
+ }
626
+ ],
627
+ "description": "Overrides createProperty to automatically map camelCase property names\nto kebab-case attribute names by default."
628
+ },
629
+ {
630
+ "kind": "method",
631
+ "name": "finalizeStyles",
632
+ "static": true,
633
+ "return": {
634
+ "type": {
635
+ "text": "Array<any>"
636
+ }
637
+ },
638
+ "parameters": [
639
+ {
640
+ "name": "styles",
641
+ "optional": true,
642
+ "type": {
643
+ "text": "CSSResultGroup"
644
+ }
645
+ }
646
+ ],
647
+ "description": "Automatically prepends basic layout resets (border-box) to the\ncomponent's final styles."
648
+ },
649
+ {
650
+ "kind": "method",
651
+ "name": "dispatchCustomEvent",
652
+ "return": {
653
+ "type": {
654
+ "text": "boolean"
655
+ }
656
+ },
657
+ "parameters": [
658
+ {
659
+ "name": "name",
660
+ "type": {
661
+ "text": "string"
662
+ }
663
+ },
664
+ {
665
+ "name": "detail",
666
+ "optional": true,
667
+ "type": {
668
+ "text": "T"
669
+ }
670
+ },
671
+ {
672
+ "name": "options",
673
+ "optional": true,
674
+ "type": {
675
+ "text": "Omit<CustomEventInit<T>, 'detail'>"
676
+ }
677
+ }
678
+ ],
679
+ "description": "Helper to dispatch a custom event with standard bubbles and composed options."
680
+ },
681
+ {
682
+ "kind": "method",
683
+ "name": "getCssPropertyValue",
684
+ "return": {
685
+ "type": {
686
+ "text": "string"
687
+ }
688
+ },
689
+ "parameters": [
690
+ {
691
+ "name": "propertyName",
692
+ "type": {
693
+ "text": "string"
694
+ }
695
+ }
696
+ ],
697
+ "description": "Helper to retrieve a computed CSS custom property value from the element."
698
+ },
699
+ {
700
+ "kind": "method",
701
+ "name": "registerDisposable",
702
+ "parameters": [
703
+ {
704
+ "name": "cleanup",
705
+ "type": {
706
+ "text": "() => void"
707
+ }
708
+ }
709
+ ],
710
+ "description": "Register a cleanup function to be executed when the element is disconnected from the DOM."
711
+ },
712
+ {
713
+ "kind": "method",
714
+ "name": "listen",
715
+ "return": {
716
+ "type": {
717
+ "text": "() => void"
718
+ }
719
+ },
720
+ "parameters": [
721
+ {
722
+ "name": "target",
723
+ "type": {
724
+ "text": "EventTarget"
725
+ }
726
+ },
727
+ {
728
+ "name": "type",
729
+ "type": {
730
+ "text": "K"
731
+ }
732
+ },
733
+ {
734
+ "name": "listener",
735
+ "type": {
736
+ "text": "(this: EventTarget, ev: HTMLElementEventMap[K]) => any"
737
+ }
738
+ },
739
+ {
740
+ "name": "options",
741
+ "optional": true,
742
+ "type": {
743
+ "text": "boolean | AddEventListenerOptions"
744
+ }
745
+ }
746
+ ],
747
+ "description": "Utility to add an event listener that is automatically cleaned up when the element is disconnected."
748
+ },
749
+ {
750
+ "kind": "method",
751
+ "name": "listen",
752
+ "return": {
753
+ "type": {
754
+ "text": "() => void"
755
+ }
756
+ },
757
+ "parameters": [
758
+ {
759
+ "name": "target",
760
+ "type": {
761
+ "text": "EventTarget"
762
+ }
763
+ },
764
+ {
765
+ "name": "type",
766
+ "type": {
767
+ "text": "string"
768
+ }
769
+ },
770
+ {
771
+ "name": "listener",
772
+ "type": {
773
+ "text": "EventListenerOrEventListenerObject"
774
+ }
775
+ },
776
+ {
777
+ "name": "options",
778
+ "optional": true,
779
+ "type": {
780
+ "text": "boolean | AddEventListenerOptions"
781
+ }
782
+ }
783
+ ]
784
+ }
785
+ ],
786
+ "attributes": [
787
+ {
788
+ "name": "locale",
789
+ "type": {
790
+ "text": "string"
791
+ },
792
+ "default": "''",
793
+ "description": "BCP 47 locale string for formatting and localization. Defaults to inherited document language.",
794
+ "fieldName": "locale"
795
+ }
796
+ ],
797
+ "superclass": {
798
+ "name": "LitElement",
799
+ "package": "lit"
800
+ },
801
+ "customElement": true
802
+ }
803
+ ],
804
+ "exports": [
805
+ {
806
+ "kind": "js",
807
+ "name": "UIBitElement",
808
+ "declaration": {
809
+ "name": "UIBitElement",
810
+ "module": "../../platform/core/src/element.ts"
811
+ }
812
+ }
813
+ ]
344
814
  }
345
815
  ]
346
816
  }
@@ -1,6 +1,8 @@
1
1
  import { UIBitElement } from '@uibit/core';
2
2
  /**
3
3
  * Countdown timer to a target date/time or a fixed duration. Supports
4
+
5
+ * @summary A responsive and customizable digital timer and countdown clock component.
4
6
  * configurable display formats and fires events on each tick and on completion.
5
7
  *
6
8
  * @fires {{ days: number, hours: number, minutes: number, seconds: number, remaining: number }} countdown-tick - Fired every second while the countdown is running
@@ -18,7 +20,8 @@ import { UIBitElement } from '@uibit/core';
18
20
  * @cssprop [--uibit-countdown-label-color=#6b7280] - Color for unit labels
19
21
  * @cssprop [--uibit-countdown-separator-font-size=2.25rem] - Font size of the colon separator
20
22
  * @cssprop [--uibit-countdown-separator-color=#d1d5db] - Color of the colon separator
21
- */
23
+
24
+ * @cssstate finished - Active when the countdown timer reaches zero.*/
22
25
  export declare class Countdown extends UIBitElement {
23
26
  static styles: import("lit").CSSResult;
24
27
  /** ISO 8601 date/time string for the countdown target (e.g. `"2025-12-31T00:00:00"`). Takes precedence over `duration`. */
@@ -39,6 +42,13 @@ export declare class Countdown extends UIBitElement {
39
42
  connectedCallback(): void;
40
43
  disconnectedCallback(): void;
41
44
  updated(changedProperties: Map<string, unknown>): void;
45
+ /**
46
+
47
+
48
+ * Starts or resumes the countdown timer.
49
+
50
+
51
+ */
42
52
  start(): void;
43
53
  stop(): void;
44
54
  private tick;
@@ -1 +1 @@
1
- {"version":3,"file":"countdown.d.ts","sourceRoot":"","sources":["../src/countdown.ts"],"names":[],"mappings":"AACA,OAAO,EAAsB,YAAY,EAAE,MAAM,aAAa,CAAC;AAI/D;;;;;;;;;;;;;;;;;;;GAmBG;AACH,qBACa,SAAU,SAAQ,YAAY;IACzC,MAAM,CAAC,MAAM,0BAAU;IAEvB,2HAA2H;IAC/F,MAAM,CAAC,EAAE,MAAM,CAAC;IAC5C,+EAA+E;IACnD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC9C,oDAAoD;IACE,SAAS,UAAQ;IACvE,iFAAiF;IACrD,MAAM,SAAc;IAEvC,OAAO,CAAC,SAAS,CAAK;IACtB,OAAO,CAAC,IAAI,CAAK;IACjB,OAAO,CAAC,KAAK,CAAK;IAClB,OAAO,CAAC,OAAO,CAAK;IACpB,OAAO,CAAC,OAAO,CAAK;IAE7B,OAAO,CAAC,KAAK,CAAC,CAAS;IACvB,OAAO,CAAC,kBAAkB,CAAK;IAE/B,iBAAiB,SAKhB;IAED,oBAAoB,SAGnB;IAED,OAAO,CAAC,iBAAiB,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,QAY9C;IAED,KAAK,SASJ;IAED,IAAI,SAKH;IAED,OAAO,CAAC,IAAI;IAuBZ,OAAO,CAAC,iBAAiB;IAoDzB,MAAM,oCAeL;CACF;eAEc,SAAS"}
1
+ {"version":3,"file":"countdown.d.ts","sourceRoot":"","sources":["../src/countdown.ts"],"names":[],"mappings":"AACA,OAAO,EAAsB,YAAY,EAAE,MAAM,aAAa,CAAC;AAI/D;;;;;;;;;;;;;;;;;;;;;;uEAsBuE;AACvE,qBACa,SAAU,SAAQ,YAAY;IACzC,MAAM,CAAC,MAAM,0BAAU;IAEvB,2HAA2H;IAC/F,MAAM,CAAC,EAAE,MAAM,CAAC;IAC5C,+EAA+E;IACnD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC9C,oDAAoD;IACE,SAAS,UAAQ;IACvE,iFAAiF;IACrD,MAAM,SAAc;IAEvC,OAAO,CAAC,SAAS,CAAK;IACtB,OAAO,CAAC,IAAI,CAAK;IACjB,OAAO,CAAC,KAAK,CAAK;IAClB,OAAO,CAAC,OAAO,CAAK;IACpB,OAAO,CAAC,OAAO,CAAK;IAE7B,OAAO,CAAC,KAAK,CAAC,CAAS;IACvB,OAAO,CAAC,kBAAkB,CAAK;IAE/B,iBAAiB,SAKhB;IAED,oBAAoB,SAGnB;IAED,OAAO,CAAC,iBAAiB,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,QAY9C;IAED;;;;;;OAMG;IAGH,KAAK,SASJ;IAED,IAAI,SAKH;IAED,OAAO,CAAC,IAAI;IAuBZ,OAAO,CAAC,iBAAiB;IAoDzB,MAAM,oCAeL;CACF;eAEc,SAAS"}
package/dist/countdown.js CHANGED
@@ -10,6 +10,8 @@ import { property, state } from 'lit/decorators.js';
10
10
  import { styles } from './styles';
11
11
  /**
12
12
  * Countdown timer to a target date/time or a fixed duration. Supports
13
+
14
+ * @summary A responsive and customizable digital timer and countdown clock component.
13
15
  * configurable display formats and fires events on each tick and on completion.
14
16
  *
15
17
  * @fires {{ days: number, hours: number, minutes: number, seconds: number, remaining: number }} countdown-tick - Fired every second while the countdown is running
@@ -27,7 +29,8 @@ import { styles } from './styles';
27
29
  * @cssprop [--uibit-countdown-label-color=#6b7280] - Color for unit labels
28
30
  * @cssprop [--uibit-countdown-separator-font-size=2.25rem] - Font size of the colon separator
29
31
  * @cssprop [--uibit-countdown-separator-color=#d1d5db] - Color of the colon separator
30
- */
32
+
33
+ * @cssstate finished - Active when the countdown timer reaches zero.*/
31
34
  let Countdown = class Countdown extends UIBitElement {
32
35
  constructor() {
33
36
  super(...arguments);
@@ -65,6 +68,13 @@ let Countdown = class Countdown extends UIBitElement {
65
68
  }
66
69
  }
67
70
  }
71
+ /**
72
+
73
+
74
+ * Starts or resumes the countdown timer.
75
+
76
+
77
+ */
68
78
  start() {
69
79
  this.stop();
70
80
  const now = Date.now();
@@ -1 +1 @@
1
- {"version":3,"file":"countdown.js","sourceRoot":"","sources":["../src/countdown.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"countdown.js","sourceRoot":"","sources":["../src/countdown.ts"],"names":[],"mappings":"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"}
@@ -1,46 +1,59 @@
1
1
  import { Component, ChangeDetectionStrategy, ElementRef, input, effect, output, booleanAttribute, numberAttribute } from '@angular/core';
2
2
  import '@uibit/countdown';
3
3
  import type { Countdown as HTMLElementClass } from '@uibit/countdown';
4
-
5
4
  @Component({
6
- selector: 'uibit-countdown',
7
- template: '<ng-content></ng-content>',
8
- changeDetection: ChangeDetectionStrategy.OnPush,
9
- standalone: true,
10
- host: {
11
- '(countdown-tick)': 'countdownTick.emit($event)',
12
- '(void)': 'void.emit($event)'
13
- }
5
+ selector: 'uibit-countdown',
6
+ template: '<ng-content></ng-content>',
7
+ changeDetection: ChangeDetectionStrategy.OnPush,
8
+ standalone: true,
9
+ host: {
10
+ '(countdown-tick)': 'countdownTick.emit($event)',
11
+ '(void)': 'void.emit($event)'
12
+ }
14
13
  })
15
14
  export class NgxCountdown {
16
- constructor(private el: ElementRef<HTMLElementClass>) {
17
- effect(() => {
18
- if (this.el.nativeElement) {
19
- this.el.nativeElement.target = this.target();
20
- }
15
+ constructor(private el: ElementRef<HTMLElementClass>){
16
+ effect(()=>{
17
+ if (this.el.nativeElement) {
18
+ this.el.nativeElement.target = this.target();
19
+ }
20
+ });
21
+ effect(()=>{
22
+ if (this.el.nativeElement) {
23
+ this.el.nativeElement.duration = this.duration();
24
+ }
25
+ });
26
+ effect(()=>{
27
+ if (this.el.nativeElement) {
28
+ this.el.nativeElement.autoStart = this.autoStart();
29
+ }
30
+ });
31
+ effect(()=>{
32
+ if (this.el.nativeElement) {
33
+ this.el.nativeElement.format = this.format();
34
+ }
35
+ });
36
+ effect(()=>{
37
+ if (this.el.nativeElement) {
38
+ this.el.nativeElement.locale = this.locale();
39
+ }
40
+ });
41
+ }
42
+ readonly target = input<string | undefined>(undefined);
43
+ readonly duration = input<number | undefined, any>(undefined, {
44
+ transform: numberAttribute
21
45
  });
22
- effect(() => {
23
- if (this.el.nativeElement) {
24
- this.el.nativeElement.duration = this.duration();
25
- }
46
+ readonly autoStart = input<boolean, any>(true, {
47
+ transform: booleanAttribute
26
48
  });
27
- effect(() => {
28
- if (this.el.nativeElement) {
29
- this.el.nativeElement.autoStart = this.autoStart();
30
- }
31
- });
32
- effect(() => {
33
- if (this.el.nativeElement) {
34
- this.el.nativeElement.format = this.format();
35
- }
36
- });
37
- }
38
-
39
- readonly target = input<string | undefined, any>('');
40
- readonly duration = input<number | undefined, any>(0, { transform: numberAttribute });
41
- readonly autoStart = input<boolean, any>(true, { transform: booleanAttribute });
42
- readonly format = input<string, any>('HH:MM:SS');
43
-
44
- readonly countdownTick = output<CustomEvent<{ days: number, hours: number, minutes: number, seconds: number, remaining: number }>>();
45
- readonly void = output<CustomEvent<any>>();
49
+ readonly format = input<string>('HH:MM:SS');
50
+ readonly locale = input<string>('');
51
+ readonly countdownTick = output<CustomEvent<{
52
+ days: number;
53
+ hours: number;
54
+ minutes: number;
55
+ seconds: number;
56
+ remaining: number;
57
+ }>>();
58
+ readonly void = output<CustomEvent<any>>();
46
59
  }
@@ -4,7 +4,15 @@ import '@uibit/countdown';
4
4
  declare global {
5
5
  namespace astroHTML.JSX {
6
6
  interface IntrinsicElements {
7
- 'uibit-countdown': Partial<HTMLElementClass> & astroHTML.JSX.HTMLAttributes;
7
+ 'uibit-countdown': Partial<HTMLElementClass> & astroHTML.JSX.HTMLAttributes & {
8
+ target?: string | undefined;
9
+ duration?: number | undefined;
10
+ autoStart?: boolean;
11
+ format?: string;
12
+ locale?: string;
13
+ "on:countdown-tick"?: (event: CustomEvent<{ days: number, hours: number, minutes: number, seconds: number, remaining: number }>) => void;
14
+ "on:void"?: (event: Event) => void;
15
+ };
8
16
  }
9
17
  }
10
18
  }
@@ -10,6 +10,11 @@ declare module 'preact' {
10
10
  duration?: number | undefined;
11
11
  autoStart?: boolean;
12
12
  format?: string;
13
+ locale?: string;
14
+ onCountdownTick?: (event: CustomEvent<{ days: number, hours: number, minutes: number, seconds: number, remaining: number }>) => void;
15
+ "on:countdown-tick"?: (event: CustomEvent<{ days: number, hours: number, minutes: number, seconds: number, remaining: number }>) => void;
16
+ onVoid?: (event: Event) => void;
17
+ "on:void"?: (event: Event) => void;
13
18
  };
14
19
  }
15
20
  }
@@ -0,0 +1,138 @@
1
+ import React, { useRef, useEffect, useLayoutEffect, useImperativeHandle } from 'react';
2
+ import type { Countdown as HTMLElementClass } from '@uibit/countdown';
3
+ import '@uibit/countdown';
4
+ const useTypeOfLayoutEffect = typeof window !== 'undefined' ? useLayoutEffect : useEffect;
5
+ export interface CountdownProps extends Omit<React.HTMLAttributes<HTMLElementClass>, 'target' | 'duration' | 'autoStart' | 'format' | 'locale' | 'onCountdownTick' | 'onVoid'> {
6
+ children?: React.ReactNode;
7
+ target?: string | undefined;
8
+ duration?: number | undefined;
9
+ autoStart?: boolean;
10
+ format?: string;
11
+ locale?: string;
12
+ onCountdownTick?: (event: CustomEvent<{
13
+ days: number;
14
+ hours: number;
15
+ minutes: number;
16
+ seconds: number;
17
+ remaining: number;
18
+ }>) => void;
19
+ onVoid?: (event: Event) => void;
20
+ }
21
+ export const Countdown = ({ ref, children, ...props }: CountdownProps & {
22
+ ref?: React.Ref<HTMLElementClass>;
23
+ })=>{
24
+ const innerRef = useRef<HTMLElementClass>(null);
25
+ const propsRef = useRef(props);
26
+ propsRef.current = props;
27
+ useImperativeHandle(ref, ()=>innerRef.current!);
28
+ useTypeOfLayoutEffect(()=>{
29
+ const element = innerRef.current;
30
+ if (element && props.target !== undefined) {
31
+ (element as any).target = props.target;
32
+ }
33
+ }, [
34
+ props.target
35
+ ]);
36
+ useTypeOfLayoutEffect(()=>{
37
+ const element = innerRef.current;
38
+ if (element && props.duration !== undefined) {
39
+ (element as any).duration = props.duration;
40
+ }
41
+ }, [
42
+ props.duration
43
+ ]);
44
+ useTypeOfLayoutEffect(()=>{
45
+ const element = innerRef.current;
46
+ if (element && props.autoStart !== undefined) {
47
+ (element as any).autoStart = props.autoStart;
48
+ }
49
+ }, [
50
+ props.autoStart
51
+ ]);
52
+ useTypeOfLayoutEffect(()=>{
53
+ const element = innerRef.current;
54
+ if (element && props.format !== undefined) {
55
+ (element as any).format = props.format;
56
+ }
57
+ }, [
58
+ props.format
59
+ ]);
60
+ useTypeOfLayoutEffect(()=>{
61
+ const element = innerRef.current;
62
+ if (element && props.locale !== undefined) {
63
+ (element as any).locale = props.locale;
64
+ }
65
+ }, [
66
+ props.locale
67
+ ]);
68
+ useTypeOfLayoutEffect(()=>{
69
+ const element = innerRef.current;
70
+ if (!element) return;
71
+ const handleEvent = (event: Event)=>{
72
+ if (propsRef.current.onCountdownTick) {
73
+ propsRef.current.onCountdownTick(event as any);
74
+ }
75
+ };
76
+ element.addEventListener('countdown-tick', handleEvent);
77
+ return ()=>{
78
+ element.removeEventListener('countdown-tick', handleEvent);
79
+ };
80
+ }, []);
81
+ useTypeOfLayoutEffect(()=>{
82
+ const element = innerRef.current;
83
+ if (!element) return;
84
+ const handleEvent = (event: Event)=>{
85
+ if (propsRef.current.onVoid) {
86
+ propsRef.current.onVoid(event as any);
87
+ }
88
+ };
89
+ element.addEventListener('void', handleEvent);
90
+ return ()=>{
91
+ element.removeEventListener('void', handleEvent);
92
+ };
93
+ }, []);
94
+ const domProps = {
95
+ ...props
96
+ };
97
+ const customPropNames = [
98
+ 'target',
99
+ 'duration',
100
+ 'autoStart',
101
+ 'format',
102
+ 'locale',
103
+ 'onCountdownTick',
104
+ 'onVoid'
105
+ ];
106
+ for (const key of customPropNames){
107
+ delete (domProps as any)[key];
108
+ }
109
+ return React.createElement('uibit-countdown', {
110
+ ref: innerRef,
111
+ ...domProps
112
+ }, children);
113
+ };
114
+ declare global {
115
+ namespace React {
116
+ namespace JSX {
117
+ interface IntrinsicElements {
118
+ 'uibit-countdown': React.ClassAttributes<HTMLElementClass> & React.HTMLAttributes<HTMLElementClass> & {
119
+ children?: React.ReactNode;
120
+ class?: string;
121
+ target?: string | undefined;
122
+ duration?: number | undefined;
123
+ autoStart?: boolean;
124
+ format?: string;
125
+ locale?: string;
126
+ onCountdownTick?: (event: CustomEvent<{
127
+ days: number;
128
+ hours: number;
129
+ minutes: number;
130
+ seconds: number;
131
+ remaining: number;
132
+ }>) => void;
133
+ onVoid?: (event: CustomEvent<any>) => void;
134
+ };
135
+ }
136
+ }
137
+ }
138
+ }
@@ -10,8 +10,9 @@ declare module 'solid-js' {
10
10
  duration?: number | undefined;
11
11
  autoStart?: boolean;
12
12
  format?: string;
13
- "on:countdown-tick"?: (event: CustomEvent) => void;
14
- "on:void"?: (event: CustomEvent) => void;
13
+ locale?: string;
14
+ "on:countdown-tick"?: (event: CustomEvent<{ days: number, hours: number, minutes: number, seconds: number, remaining: number }>) => void;
15
+ "on:void"?: (event: Event) => void;
15
16
  };
16
17
  }
17
18
  }
@@ -9,6 +9,11 @@ declare module '@stencil/core' {
9
9
  duration?: number | undefined;
10
10
  autoStart?: boolean;
11
11
  format?: string;
12
+ locale?: string;
13
+ onCountdownTick?: (event: CustomEvent<{ days: number, hours: number, minutes: number, seconds: number, remaining: number }>) => void;
14
+ "on:countdown-tick"?: (event: CustomEvent<{ days: number, hours: number, minutes: number, seconds: number, remaining: number }>) => void;
15
+ onVoid?: (event: Event) => void;
16
+ "on:void"?: (event: Event) => void;
12
17
  };
13
18
  }
14
19
  }
@@ -1,42 +1,82 @@
1
1
  <script lang="ts">
2
2
  import '@uibit/countdown';
3
3
  import type { Countdown as HTMLElementClass } from '@uibit/countdown';
4
-
5
- let {
6
- target = undefined,
7
- duration = undefined,
8
- autoStart = undefined,
9
- format = undefined,
10
- children
4
+
5
+ let {
6
+ target = $bindable(),
7
+ duration = $bindable(),
8
+ autoStart = $bindable(),
9
+ format = $bindable(),
10
+ locale = $bindable(),
11
+ children,
12
+ ...restProps
11
13
  } = $props<{
12
- children?: any;
14
+ children?: import('svelte').Snippet;
13
15
  target?: string | undefined;
14
16
  duration?: number | undefined;
15
17
  autoStart?: boolean;
16
18
  format?: string;
17
-
19
+ locale?: string;
20
+
21
+ [key: string]: any;
18
22
  }>();
19
-
20
- let elementRef: HTMLElementClass | null = $state(null);
21
-
22
- $effect(() => {
23
- if (elementRef && target !== undefined) {
23
+
24
+ let elementRef: HTMLElementClass | null = $state(null);
25
+
26
+ $effect(() => {
27
+ if (elementRef && target !== undefined && elementRef.target !== target) {
24
28
  elementRef.target = target;
25
29
  }
26
- if (elementRef && duration !== undefined) {
30
+ if (elementRef && duration !== undefined && elementRef.duration !== duration) {
27
31
  elementRef.duration = duration;
28
32
  }
29
- if (elementRef && autoStart !== undefined) {
33
+ if (elementRef && autoStart !== undefined && elementRef.autoStart !== autoStart) {
30
34
  elementRef.autoStart = autoStart;
31
35
  }
32
- if (elementRef && format !== undefined) {
36
+ if (elementRef && format !== undefined && elementRef.format !== format) {
33
37
  elementRef.format = format;
34
38
  }
39
+ if (elementRef && locale !== undefined && elementRef.locale !== locale) {
40
+ elementRef.locale = locale;
41
+ }
35
42
  });
36
-
43
+
44
+ $effect(() => {
45
+ const element = elementRef;
46
+ if (!element) return;
47
+
48
+ const handleEvent = () => {
49
+ if (target !== element.target) {
50
+ target = element.target as any;
51
+ }
52
+ if (duration !== element.duration) {
53
+ duration = element.duration as any;
54
+ }
55
+ if (autoStart !== element.autoStart) {
56
+ autoStart = element.autoStart as any;
57
+ }
58
+ if (format !== element.format) {
59
+ format = element.format as any;
60
+ }
61
+ if (locale !== element.locale) {
62
+ locale = element.locale as any;
63
+ }
64
+ };
65
+
66
+ const events = ['change', 'input', 'countdown-tick', 'void'];
67
+ for (const event of events) {
68
+ element.addEventListener(event, handleEvent);
69
+ }
70
+ return () => {
71
+ for (const event of events) {
72
+ element.removeEventListener(event, handleEvent);
73
+ }
74
+ };
75
+ });
76
+
37
77
  </script>
38
78
 
39
- <uibit-countdown bind:this={elementRef} {...$$restProps}>
79
+ <uibit-countdown bind:this={elementRef} {...restProps}>
40
80
 
41
81
  {#if children}
42
82
  {@render children()}
@@ -1,30 +1,115 @@
1
- import { defineComponent, h } from 'vue';
1
+ import { defineComponent, h, ref, watch } from 'vue';
2
2
  import type { Countdown as HTMLElementClass } from '@uibit/countdown';
3
3
  import '@uibit/countdown';
4
-
5
4
  export const Countdown = defineComponent({
6
- name: 'Countdown',
7
- props: {
8
- target: { type: [String, Number, Boolean, Array, Object] as any },
9
- duration: { type: [String, Number, Boolean, Array, Object] as any },
10
- autoStart: { type: [String, Number, Boolean, Array, Object] as any },
11
- format: { type: [String, Number, Boolean, Array, Object] as any }
12
- },
13
- emits: ['countdown-tick', 'void'],
14
- setup(props, { slots, emit }) {
15
- return () => {
16
- const eventListeners: Record<string, any> = {};
17
- eventListeners['onCountdown-tick'] = (event: Event) => {
18
- emit('countdown-tick', event);
19
- };
20
- eventListeners['onVoid'] = (event: Event) => {
21
- emit('void', event);
22
- };
23
-
24
- return h('uibit-countdown', {
25
- ...props,
26
- ...eventListeners
27
- }, slots.default?.());
28
- };
29
- }
5
+ name: 'Countdown',
6
+ props: {
7
+ target: {
8
+ type: [
9
+ String,
10
+ Number,
11
+ Boolean,
12
+ Array,
13
+ Object
14
+ ] as any
15
+ },
16
+ duration: {
17
+ type: [
18
+ String,
19
+ Number,
20
+ Boolean,
21
+ Array,
22
+ Object
23
+ ] as any
24
+ },
25
+ autoStart: {
26
+ type: [
27
+ String,
28
+ Number,
29
+ Boolean,
30
+ Array,
31
+ Object
32
+ ] as any
33
+ },
34
+ format: {
35
+ type: [
36
+ String,
37
+ Number,
38
+ Boolean,
39
+ Array,
40
+ Object
41
+ ] as any
42
+ },
43
+ locale: {
44
+ type: [
45
+ String,
46
+ Number,
47
+ Boolean,
48
+ Array,
49
+ Object
50
+ ] as any
51
+ }
52
+ },
53
+ emits: [
54
+ 'countdown-tick',
55
+ 'void'
56
+ ],
57
+ setup (props, { slots, emit }) {
58
+ const elementRef = ref<HTMLElementClass | null>(null);
59
+ if (false) {
60
+ watch(()=>props.modelValue, (newVal)=>{
61
+ if (elementRef.value && newVal !== undefined && elementRef.value.value !== newVal) {
62
+ elementRef.value.value = newVal;
63
+ }
64
+ });
65
+ watch(()=>props.value, (newVal)=>{
66
+ if (elementRef.value && newVal !== undefined && elementRef.value.value !== newVal) {
67
+ elementRef.value.value = newVal;
68
+ }
69
+ });
70
+ }
71
+ watch(()=>props.target, (newVal)=>{
72
+ if (elementRef.value && newVal !== undefined) {
73
+ (elementRef.value as any).target = newVal;
74
+ }
75
+ });
76
+ watch(()=>props.duration, (newVal)=>{
77
+ if (elementRef.value && newVal !== undefined) {
78
+ (elementRef.value as any).duration = newVal;
79
+ }
80
+ });
81
+ watch(()=>props.autoStart, (newVal)=>{
82
+ if (elementRef.value && newVal !== undefined) {
83
+ (elementRef.value as any).autoStart = newVal;
84
+ }
85
+ });
86
+ watch(()=>props.format, (newVal)=>{
87
+ if (elementRef.value && newVal !== undefined) {
88
+ (elementRef.value as any).format = newVal;
89
+ }
90
+ });
91
+ watch(()=>props.locale, (newVal)=>{
92
+ if (elementRef.value && newVal !== undefined) {
93
+ (elementRef.value as any).locale = newVal;
94
+ }
95
+ });
96
+ return ()=>{
97
+ const eventListeners: Record<string, any> = {};
98
+ eventListeners['onCountdown-tick'] = (event: Event)=>{
99
+ emit('countdown-tick', event);
100
+ };
101
+ eventListeners['onVoid'] = (event: Event)=>{
102
+ emit('void', event);
103
+ };
104
+ const mergedProps = {
105
+ ...props,
106
+ ...eventListeners,
107
+ ref: elementRef
108
+ };
109
+ if (false && props.modelValue !== undefined) {
110
+ (mergedProps as any).value = props.modelValue;
111
+ }
112
+ return h('uibit-countdown', mergedProps, slots.default?.());
113
+ };
114
+ }
30
115
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@uibit/countdown",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "Highly customizable countdown timer. Supports target date markers or set durations, reactive timers, and custom format templates.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -12,7 +12,7 @@
12
12
  },
13
13
  "./countdown.css": "./dist/countdown.css",
14
14
  "./custom-elements.json": "./custom-elements.json",
15
- "./react": "./dist/frameworks/react/index.d.ts",
15
+ "./react": "./dist/frameworks/react/index.ts",
16
16
  "./vue": "./dist/frameworks/vue/index.ts",
17
17
  "./svelte": "./dist/frameworks/svelte/index.svelte",
18
18
  "./angular": "./dist/frameworks/angular/index.ts",
@@ -45,13 +45,13 @@
45
45
  "directory": "packages/components/countdown"
46
46
  },
47
47
  "dependencies": {
48
- "@uibit/core": "0.1.0"
48
+ "@uibit/core": "0.2.0"
49
49
  },
50
50
  "devDependencies": {
51
51
  "@types/node": "^20.19.43",
52
52
  "lit": "^3.3.3",
53
53
  "typescript": "7.0.2",
54
- "@uibit/codegen": "0.1.0"
54
+ "@uibit/codegen": "0.2.0"
55
55
  },
56
56
  "peerDependencies": {
57
57
  "lit": "^3.0.0",
@@ -82,9 +82,9 @@
82
82
  "tagName": "uibit-countdown"
83
83
  },
84
84
  "scripts": {
85
- "build": "cem analyze --globs 'src/**/*.ts' --litelement && uibit-codegen --package . && tsc",
86
- "dev": "concurrently \"cem analyze --globs 'src/**/*.ts' --litelement --watch\" \"tsc --watch\"",
87
- "analyze": "cem analyze --globs 'src/**/*.ts' --litelement",
85
+ "build": "cem analyze --config ../custom-elements-manifest.config.js && uibit-codegen --package . && tsc",
86
+ "dev": "concurrently \"cem analyze --config ../custom-elements-manifest.config.js --watch\" \"tsc --watch\"",
87
+ "analyze": "cem analyze --config ../custom-elements-manifest.config.js",
88
88
  "typecheck": "tsc --noEmit"
89
89
  }
90
90
  }
@@ -1,22 +0,0 @@
1
- import type { HTMLAttributes, ClassAttributes } from 'react';
2
- import type { Countdown as HTMLElementClass } from '@uibit/countdown';
3
- import '@uibit/countdown';
4
-
5
- declare global {
6
- namespace React {
7
- namespace JSX {
8
- interface IntrinsicElements {
9
- 'uibit-countdown': ClassAttributes<HTMLElementClass> & HTMLAttributes<HTMLElementClass> & {
10
- children?: React.ReactNode;
11
- class?: string;
12
- target?: string | undefined;
13
- duration?: number | undefined;
14
- autoStart?: boolean;
15
- format?: string;
16
- onCountdownTick?: (event: any) => void;
17
- onVoid?: (event: any) => void;
18
- };
19
- }
20
- }
21
- }
22
- }