@uibit/number-increment 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.
@@ -1,80 +1,89 @@
1
- import { Component, ChangeDetectionStrategy, ElementRef, input, effect, output, booleanAttribute, numberAttribute } from '@angular/core';
1
+ import { Component, ChangeDetectionStrategy, ElementRef, model, input, effect, output, booleanAttribute, numberAttribute } from '@angular/core';
2
2
  import '@uibit/number-increment';
3
3
  import type { NumberIncrement as HTMLElementClass } from '@uibit/number-increment';
4
-
5
4
  @Component({
6
- selector: 'uibit-number-increment',
7
- template: '<ng-content></ng-content>',
8
- changeDetection: ChangeDetectionStrategy.OnPush,
9
- standalone: true,
10
- host: {
11
- '(void)': 'void.emit($event)'
12
- }
5
+ selector: 'uibit-number-increment',
6
+ template: '<ng-content></ng-content>',
7
+ changeDetection: ChangeDetectionStrategy.OnPush,
8
+ standalone: true,
9
+ host: {
10
+ '(void)': 'void.emit($event)'
11
+ }
13
12
  })
14
13
  export class NgxNumberIncrement {
15
- constructor(private el: ElementRef<HTMLElementClass>) {
16
- effect(() => {
17
- if (this.el.nativeElement) {
18
- this.el.nativeElement.value = this.value();
19
- }
14
+ constructor(private el: ElementRef<HTMLElementClass>){
15
+ effect(()=>{
16
+ if (this.el.nativeElement) {
17
+ this.el.nativeElement.value = this.value();
18
+ }
19
+ });
20
+ effect(()=>{
21
+ if (this.el.nativeElement) {
22
+ this.el.nativeElement.from = this.from();
23
+ }
24
+ });
25
+ effect(()=>{
26
+ if (this.el.nativeElement) {
27
+ this.el.nativeElement.duration = this.duration();
28
+ }
29
+ });
30
+ effect(()=>{
31
+ if (this.el.nativeElement) {
32
+ this.el.nativeElement.decimals = this.decimals();
33
+ }
34
+ });
35
+ effect(()=>{
36
+ if (this.el.nativeElement) {
37
+ this.el.nativeElement.options = this.options();
38
+ }
39
+ });
40
+ effect(()=>{
41
+ if (this.el.nativeElement) {
42
+ this.el.nativeElement.formatter = this.formatter();
43
+ }
44
+ });
45
+ effect(()=>{
46
+ if (this.el.nativeElement) {
47
+ this.el.nativeElement.easing = this.easing();
48
+ }
49
+ });
50
+ effect(()=>{
51
+ if (this.el.nativeElement) {
52
+ this.el.nativeElement.threshold = this.threshold();
53
+ }
54
+ });
55
+ effect(()=>{
56
+ if (this.el.nativeElement) {
57
+ this.el.nativeElement.repeat = this.repeat();
58
+ }
59
+ });
60
+ effect(()=>{
61
+ if (this.el.nativeElement) {
62
+ this.el.nativeElement.locale = this.locale();
63
+ }
64
+ });
65
+ }
66
+ readonly value = model<number>(0);
67
+ readonly from = input<number, any>(0, {
68
+ transform: numberAttribute
20
69
  });
21
- effect(() => {
22
- if (this.el.nativeElement) {
23
- this.el.nativeElement.from = this.from();
24
- }
70
+ readonly duration = input<number, any>(1800, {
71
+ transform: numberAttribute
25
72
  });
26
- effect(() => {
27
- if (this.el.nativeElement) {
28
- this.el.nativeElement.duration = this.duration();
29
- }
73
+ readonly decimals = input<number, any>(0, {
74
+ transform: numberAttribute
30
75
  });
31
- effect(() => {
32
- if (this.el.nativeElement) {
33
- this.el.nativeElement.decimals = this.decimals();
34
- }
76
+ readonly options = input<Intl.NumberFormatOptions | undefined>(undefined);
77
+ readonly formatter = input<(value: number) => string | undefined, any>(undefined, {
78
+ transform: numberAttribute
35
79
  });
36
- effect(() => {
37
- if (this.el.nativeElement) {
38
- this.el.nativeElement.locale = this.locale();
39
- }
80
+ readonly easing = input<'ease-out' | 'ease-in-out' | 'linear'>('ease-out');
81
+ readonly threshold = input<number, any>(0.2, {
82
+ transform: numberAttribute
40
83
  });
41
- effect(() => {
42
- if (this.el.nativeElement) {
43
- this.el.nativeElement.options = this.options();
44
- }
84
+ readonly repeat = input<boolean, any>(false, {
85
+ transform: booleanAttribute
45
86
  });
46
- effect(() => {
47
- if (this.el.nativeElement) {
48
- this.el.nativeElement.formatter = this.formatter();
49
- }
50
- });
51
- effect(() => {
52
- if (this.el.nativeElement) {
53
- this.el.nativeElement.easing = this.easing();
54
- }
55
- });
56
- effect(() => {
57
- if (this.el.nativeElement) {
58
- this.el.nativeElement.threshold = this.threshold();
59
- }
60
- });
61
- effect(() => {
62
- if (this.el.nativeElement) {
63
- this.el.nativeElement.repeat = this.repeat();
64
- }
65
- });
66
- }
67
-
68
- readonly value = input<number, any>(0, { transform: numberAttribute });
69
- readonly from = input<number, any>(0, { transform: numberAttribute });
70
- readonly duration = input<number, any>(1800, { transform: numberAttribute });
71
- readonly decimals = input<number, any>(0, { transform: numberAttribute });
72
- readonly locale = input<string, any>('');
73
- readonly options = input<Intl.NumberFormatOptions | undefined, any>(undefined);
74
- readonly formatter = input<(value: number) => string | undefined, any>(0, { transform: numberAttribute });
75
- readonly easing = input<'ease-out' | 'ease-in-out' | 'linear', any>('ease-out');
76
- readonly threshold = input<number, any>(0.2, { transform: numberAttribute });
77
- readonly repeat = input<boolean, any>(false, { transform: booleanAttribute });
78
-
79
- readonly void = output<CustomEvent<any>>();
87
+ readonly locale = input<string>('');
88
+ readonly void = output<CustomEvent<any>>();
80
89
  }
@@ -4,7 +4,19 @@ import '@uibit/number-increment';
4
4
  declare global {
5
5
  namespace astroHTML.JSX {
6
6
  interface IntrinsicElements {
7
- 'uibit-number-increment': Partial<HTMLElementClass> & astroHTML.JSX.HTMLAttributes;
7
+ 'uibit-number-increment': Partial<HTMLElementClass> & astroHTML.JSX.HTMLAttributes & {
8
+ value?: number;
9
+ from?: number;
10
+ duration?: number;
11
+ decimals?: number;
12
+ options?: Intl.NumberFormatOptions | undefined;
13
+ formatter?: (value: number) => string | undefined;
14
+ easing?: 'ease-out' | 'ease-in-out' | 'linear';
15
+ threshold?: number;
16
+ repeat?: boolean;
17
+ locale?: string;
18
+ "on:void"?: (event: Event) => void;
19
+ };
8
20
  }
9
21
  }
10
22
  }
@@ -10,12 +10,14 @@ declare module 'preact' {
10
10
  from?: number;
11
11
  duration?: number;
12
12
  decimals?: number;
13
- locale?: string;
14
13
  options?: Intl.NumberFormatOptions | undefined;
15
14
  formatter?: (value: number) => string | undefined;
16
15
  easing?: 'ease-out' | 'ease-in-out' | 'linear';
17
16
  threshold?: number;
18
17
  repeat?: boolean;
18
+ locale?: string;
19
+ onVoid?: (event: Event) => void;
20
+ "on:void"?: (event: Event) => void;
19
21
  };
20
22
  }
21
23
  }
@@ -0,0 +1,165 @@
1
+ import React, { useRef, useEffect, useLayoutEffect, useImperativeHandle } from 'react';
2
+ import type { NumberIncrement as HTMLElementClass } from '@uibit/number-increment';
3
+ import '@uibit/number-increment';
4
+ const useTypeOfLayoutEffect = typeof window !== 'undefined' ? useLayoutEffect : useEffect;
5
+ export interface NumberIncrementProps extends Omit<React.HTMLAttributes<HTMLElementClass>, 'value' | 'from' | 'duration' | 'decimals' | 'options' | 'formatter' | 'easing' | 'threshold' | 'repeat' | 'locale' | 'onVoid'> {
6
+ children?: React.ReactNode;
7
+ value?: number;
8
+ from?: number;
9
+ duration?: number;
10
+ decimals?: number;
11
+ options?: Intl.NumberFormatOptions | undefined;
12
+ formatter?: (value: number) => string | undefined;
13
+ easing?: 'ease-out' | 'ease-in-out' | 'linear';
14
+ threshold?: number;
15
+ repeat?: boolean;
16
+ locale?: string;
17
+ onVoid?: (event: Event) => void;
18
+ }
19
+ export const NumberIncrement = ({ ref, children, ...props }: NumberIncrementProps & {
20
+ ref?: React.Ref<HTMLElementClass>;
21
+ })=>{
22
+ const innerRef = useRef<HTMLElementClass>(null);
23
+ const propsRef = useRef(props);
24
+ propsRef.current = props;
25
+ useImperativeHandle(ref, ()=>innerRef.current!);
26
+ useTypeOfLayoutEffect(()=>{
27
+ const element = innerRef.current;
28
+ if (element && props.value !== undefined) {
29
+ (element as any).value = props.value;
30
+ }
31
+ }, [
32
+ props.value
33
+ ]);
34
+ useTypeOfLayoutEffect(()=>{
35
+ const element = innerRef.current;
36
+ if (element && props.from !== undefined) {
37
+ (element as any).from = props.from;
38
+ }
39
+ }, [
40
+ props.from
41
+ ]);
42
+ useTypeOfLayoutEffect(()=>{
43
+ const element = innerRef.current;
44
+ if (element && props.duration !== undefined) {
45
+ (element as any).duration = props.duration;
46
+ }
47
+ }, [
48
+ props.duration
49
+ ]);
50
+ useTypeOfLayoutEffect(()=>{
51
+ const element = innerRef.current;
52
+ if (element && props.decimals !== undefined) {
53
+ (element as any).decimals = props.decimals;
54
+ }
55
+ }, [
56
+ props.decimals
57
+ ]);
58
+ useTypeOfLayoutEffect(()=>{
59
+ const element = innerRef.current;
60
+ if (element && props.options !== undefined) {
61
+ (element as any).options = props.options;
62
+ }
63
+ }, [
64
+ props.options
65
+ ]);
66
+ useTypeOfLayoutEffect(()=>{
67
+ const element = innerRef.current;
68
+ if (element && props.formatter !== undefined) {
69
+ (element as any).formatter = props.formatter;
70
+ }
71
+ }, [
72
+ props.formatter
73
+ ]);
74
+ useTypeOfLayoutEffect(()=>{
75
+ const element = innerRef.current;
76
+ if (element && props.easing !== undefined) {
77
+ (element as any).easing = props.easing;
78
+ }
79
+ }, [
80
+ props.easing
81
+ ]);
82
+ useTypeOfLayoutEffect(()=>{
83
+ const element = innerRef.current;
84
+ if (element && props.threshold !== undefined) {
85
+ (element as any).threshold = props.threshold;
86
+ }
87
+ }, [
88
+ props.threshold
89
+ ]);
90
+ useTypeOfLayoutEffect(()=>{
91
+ const element = innerRef.current;
92
+ if (element && props.repeat !== undefined) {
93
+ (element as any).repeat = props.repeat;
94
+ }
95
+ }, [
96
+ props.repeat
97
+ ]);
98
+ useTypeOfLayoutEffect(()=>{
99
+ const element = innerRef.current;
100
+ if (element && props.locale !== undefined) {
101
+ (element as any).locale = props.locale;
102
+ }
103
+ }, [
104
+ props.locale
105
+ ]);
106
+ useTypeOfLayoutEffect(()=>{
107
+ const element = innerRef.current;
108
+ if (!element) return;
109
+ const handleEvent = (event: Event)=>{
110
+ if (propsRef.current.onVoid) {
111
+ propsRef.current.onVoid(event as any);
112
+ }
113
+ };
114
+ element.addEventListener('void', handleEvent);
115
+ return ()=>{
116
+ element.removeEventListener('void', handleEvent);
117
+ };
118
+ }, []);
119
+ const domProps = {
120
+ ...props
121
+ };
122
+ const customPropNames = [
123
+ 'value',
124
+ 'from',
125
+ 'duration',
126
+ 'decimals',
127
+ 'options',
128
+ 'formatter',
129
+ 'easing',
130
+ 'threshold',
131
+ 'repeat',
132
+ 'locale',
133
+ 'onVoid'
134
+ ];
135
+ for (const key of customPropNames){
136
+ delete (domProps as any)[key];
137
+ }
138
+ return React.createElement('uibit-number-increment', {
139
+ ref: innerRef,
140
+ ...domProps
141
+ }, children);
142
+ };
143
+ declare global {
144
+ namespace React {
145
+ namespace JSX {
146
+ interface IntrinsicElements {
147
+ 'uibit-number-increment': React.ClassAttributes<HTMLElementClass> & React.HTMLAttributes<HTMLElementClass> & {
148
+ children?: React.ReactNode;
149
+ class?: string;
150
+ value?: number;
151
+ from?: number;
152
+ duration?: number;
153
+ decimals?: number;
154
+ options?: Intl.NumberFormatOptions | undefined;
155
+ formatter?: (value: number) => string | undefined;
156
+ easing?: 'ease-out' | 'ease-in-out' | 'linear';
157
+ threshold?: number;
158
+ repeat?: boolean;
159
+ locale?: string;
160
+ onVoid?: (event: CustomEvent<any>) => void;
161
+ };
162
+ }
163
+ }
164
+ }
165
+ }
@@ -10,13 +10,13 @@ declare module 'solid-js' {
10
10
  from?: number;
11
11
  duration?: number;
12
12
  decimals?: number;
13
- locale?: string;
14
13
  options?: Intl.NumberFormatOptions | undefined;
15
14
  formatter?: (value: number) => string | undefined;
16
15
  easing?: 'ease-out' | 'ease-in-out' | 'linear';
17
16
  threshold?: number;
18
17
  repeat?: boolean;
19
- "on:void"?: (event: CustomEvent) => void;
18
+ locale?: string;
19
+ "on:void"?: (event: Event) => void;
20
20
  };
21
21
  }
22
22
  }
@@ -9,12 +9,14 @@ declare module '@stencil/core' {
9
9
  from?: number;
10
10
  duration?: number;
11
11
  decimals?: number;
12
- locale?: string;
13
12
  options?: Intl.NumberFormatOptions | undefined;
14
13
  formatter?: (value: number) => string | undefined;
15
14
  easing?: 'ease-out' | 'ease-in-out' | 'linear';
16
15
  threshold?: number;
17
16
  repeat?: boolean;
17
+ locale?: string;
18
+ onVoid?: (event: Event) => void;
19
+ "on:void"?: (event: Event) => void;
18
20
  };
19
21
  }
20
22
  }
@@ -1,72 +1,122 @@
1
1
  <script lang="ts">
2
2
  import '@uibit/number-increment';
3
3
  import type { NumberIncrement as HTMLElementClass } from '@uibit/number-increment';
4
-
5
- let {
6
- value = undefined,
7
- from = undefined,
8
- duration = undefined,
9
- decimals = undefined,
10
- locale = undefined,
11
- options = undefined,
12
- formatter = undefined,
13
- easing = undefined,
14
- threshold = undefined,
15
- repeat = undefined,
16
- children
4
+
5
+ let {
6
+ value = $bindable(),
7
+ from = $bindable(),
8
+ duration = $bindable(),
9
+ decimals = $bindable(),
10
+ options = $bindable(),
11
+ formatter = $bindable(),
12
+ easing = $bindable(),
13
+ threshold = $bindable(),
14
+ repeat = $bindable(),
15
+ locale = $bindable(),
16
+ children,
17
+ ...restProps
17
18
  } = $props<{
18
- children?: any;
19
+ children?: import('svelte').Snippet;
19
20
  value?: number;
20
21
  from?: number;
21
22
  duration?: number;
22
23
  decimals?: number;
23
- locale?: string;
24
24
  options?: Intl.NumberFormatOptions | undefined;
25
25
  formatter?: (value: number) => string | undefined;
26
26
  easing?: 'ease-out' | 'ease-in-out' | 'linear';
27
27
  threshold?: number;
28
28
  repeat?: boolean;
29
-
29
+ locale?: string;
30
+
31
+ [key: string]: any;
30
32
  }>();
31
-
32
- let elementRef: HTMLElementClass | null = $state(null);
33
-
34
- $effect(() => {
35
- if (elementRef && value !== undefined) {
33
+
34
+ let elementRef: HTMLElementClass | null = $state(null);
35
+
36
+ $effect(() => {
37
+ if (elementRef && value !== undefined && elementRef.value !== value) {
36
38
  elementRef.value = value;
37
39
  }
38
- if (elementRef && from !== undefined) {
40
+ if (elementRef && from !== undefined && elementRef.from !== from) {
39
41
  elementRef.from = from;
40
42
  }
41
- if (elementRef && duration !== undefined) {
43
+ if (elementRef && duration !== undefined && elementRef.duration !== duration) {
42
44
  elementRef.duration = duration;
43
45
  }
44
- if (elementRef && decimals !== undefined) {
46
+ if (elementRef && decimals !== undefined && elementRef.decimals !== decimals) {
45
47
  elementRef.decimals = decimals;
46
48
  }
47
- if (elementRef && locale !== undefined) {
48
- elementRef.locale = locale;
49
- }
50
- if (elementRef && options !== undefined) {
49
+ if (elementRef && options !== undefined && elementRef.options !== options) {
51
50
  elementRef.options = options;
52
51
  }
53
- if (elementRef && formatter !== undefined) {
52
+ if (elementRef && formatter !== undefined && elementRef.formatter !== formatter) {
54
53
  elementRef.formatter = formatter;
55
54
  }
56
- if (elementRef && easing !== undefined) {
55
+ if (elementRef && easing !== undefined && elementRef.easing !== easing) {
57
56
  elementRef.easing = easing;
58
57
  }
59
- if (elementRef && threshold !== undefined) {
58
+ if (elementRef && threshold !== undefined && elementRef.threshold !== threshold) {
60
59
  elementRef.threshold = threshold;
61
60
  }
62
- if (elementRef && repeat !== undefined) {
61
+ if (elementRef && repeat !== undefined && elementRef.repeat !== repeat) {
63
62
  elementRef.repeat = repeat;
64
63
  }
64
+ if (elementRef && locale !== undefined && elementRef.locale !== locale) {
65
+ elementRef.locale = locale;
66
+ }
67
+ });
68
+
69
+ $effect(() => {
70
+ const element = elementRef;
71
+ if (!element) return;
72
+
73
+ const handleEvent = () => {
74
+ if (value !== element.value) {
75
+ value = element.value as any;
76
+ }
77
+ if (from !== element.from) {
78
+ from = element.from as any;
79
+ }
80
+ if (duration !== element.duration) {
81
+ duration = element.duration as any;
82
+ }
83
+ if (decimals !== element.decimals) {
84
+ decimals = element.decimals as any;
85
+ }
86
+ if (options !== element.options) {
87
+ options = element.options as any;
88
+ }
89
+ if (formatter !== element.formatter) {
90
+ formatter = element.formatter as any;
91
+ }
92
+ if (easing !== element.easing) {
93
+ easing = element.easing as any;
94
+ }
95
+ if (threshold !== element.threshold) {
96
+ threshold = element.threshold as any;
97
+ }
98
+ if (repeat !== element.repeat) {
99
+ repeat = element.repeat as any;
100
+ }
101
+ if (locale !== element.locale) {
102
+ locale = element.locale as any;
103
+ }
104
+ };
105
+
106
+ const events = ['change', 'input', 'void'];
107
+ for (const event of events) {
108
+ element.addEventListener(event, handleEvent);
109
+ }
110
+ return () => {
111
+ for (const event of events) {
112
+ element.removeEventListener(event, handleEvent);
113
+ }
114
+ };
65
115
  });
66
-
116
+
67
117
  </script>
68
118
 
69
- <uibit-number-increment bind:this={elementRef} {...$$restProps}>
119
+ <uibit-number-increment bind:this={elementRef} {...restProps}>
70
120
 
71
121
  {#if children}
72
122
  {@render children()}