chnobli 0.1.10 → 0.1.12

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.
Files changed (120) hide show
  1. package/LICENSE.md +21 -0
  2. package/dist/animation/Animation.d.ts +2 -1
  3. package/dist/animation/Animation.d.ts.map +1 -1
  4. package/dist/animation/Animation.js +5 -3
  5. package/dist/animation/Animation.js.map +1 -1
  6. package/dist/animator/Animator.d.ts +30 -0
  7. package/dist/animator/Animator.d.ts.map +1 -0
  8. package/dist/animator/Animator.js +97 -0
  9. package/dist/animator/Animator.js.map +1 -0
  10. package/dist/animator/index.d.ts +5 -0
  11. package/dist/animator/index.d.ts.map +1 -0
  12. package/dist/animator/index.js +53 -0
  13. package/dist/animator/index.js.map +1 -0
  14. package/dist/animator/public.d.ts +16 -0
  15. package/dist/animator/public.d.ts.map +1 -0
  16. package/dist/animator/public.js +50 -0
  17. package/dist/animator/public.js.map +1 -0
  18. package/dist/chnobli.d.ts +3 -3
  19. package/dist/chnobli.d.ts.map +1 -1
  20. package/dist/chnobli.js.map +1 -1
  21. package/dist/property/ClassProperty.js +1 -1
  22. package/dist/property/ClassProperty.js.map +1 -1
  23. package/dist/property/TransformXYProperty.d.ts.map +1 -1
  24. package/dist/scroll/Scroll.d.ts +24 -3
  25. package/dist/scroll/Scroll.d.ts.map +1 -1
  26. package/dist/scroll/Scroll.js +157 -43
  27. package/dist/scroll/Scroll.js.map +1 -1
  28. package/dist/scroll/ScrollEvent.d.ts.map +1 -1
  29. package/dist/scroll/ScrollEvent.js +1 -0
  30. package/dist/scroll/ScrollEvent.js.map +1 -1
  31. package/dist/scroll/index.d.ts +2 -0
  32. package/dist/scroll/index.d.ts.map +1 -1
  33. package/dist/scroll/index.js +1 -0
  34. package/dist/scroll/index.js.map +1 -1
  35. package/dist/scroll/public.d.ts +19 -1
  36. package/dist/scroll/public.d.ts.map +1 -1
  37. package/dist/scroll/public.js +26 -1
  38. package/dist/scroll/public.js.map +1 -1
  39. package/dist/target/DomTarget.js +1 -1
  40. package/dist/target/DomTarget.js.map +1 -1
  41. package/dist/target/ObjectTarget.d.ts +11 -10
  42. package/dist/target/ObjectTarget.d.ts.map +1 -1
  43. package/dist/target/ObjectTarget.js +20 -13
  44. package/dist/target/ObjectTarget.js.map +1 -1
  45. package/dist/target/TestDomNode.d.ts.map +1 -1
  46. package/dist/timeline/Timeline.d.ts +2 -1
  47. package/dist/timeline/Timeline.d.ts.map +1 -1
  48. package/dist/timeline/Timeline.js +4 -4
  49. package/dist/timeline/Timeline.js.map +1 -1
  50. package/dist/timeline/public.d.ts +11 -4
  51. package/dist/timeline/public.d.ts.map +1 -1
  52. package/dist/timeline/public.js +19 -11
  53. package/dist/timeline/public.js.map +1 -1
  54. package/dist/timing/AnimationFrameTicker.d.ts.map +1 -1
  55. package/dist/timing/AnimationFrameTicker.js +5 -1
  56. package/dist/timing/AnimationFrameTicker.js.map +1 -1
  57. package/dist/timing/TestTicker.d.ts.map +1 -1
  58. package/dist/timing/TestTicker.js +5 -1
  59. package/dist/timing/TestTicker.js.map +1 -1
  60. package/dist/timing/Ticker.d.ts +4 -2
  61. package/dist/timing/Ticker.d.ts.map +1 -1
  62. package/dist/timing/Timing.d.ts +47 -2
  63. package/dist/timing/Timing.d.ts.map +1 -1
  64. package/dist/timing/Timing.js +118 -84
  65. package/dist/timing/Timing.js.map +1 -1
  66. package/dist/timing/easing.d.ts +1 -2
  67. package/dist/timing/easing.d.ts.map +1 -1
  68. package/dist/timing/easing.js.map +1 -1
  69. package/dist/utils/Events.js +1 -1
  70. package/dist/utils/Events.js.map +1 -1
  71. package/dist/utils/motionpath.js +5 -5
  72. package/dist/utils/motionpath.js.map +1 -1
  73. package/dist/utils/utils.d.ts.map +1 -1
  74. package/dist/utils/utils.js +0 -8
  75. package/dist/utils/utils.js.map +1 -1
  76. package/dist/values/ColorValue.d.ts.map +1 -1
  77. package/dist/values/ColorValue.js +1 -0
  78. package/dist/values/ColorValue.js.map +1 -1
  79. package/dist/values/StyleValue.d.ts.map +1 -1
  80. package/dist/values/Value.d.ts.map +1 -1
  81. package/dist/values/Value.js +1 -1
  82. package/dist/values/Value.js.map +1 -1
  83. package/eslint.config.js +23 -0
  84. package/jsr.json +16 -0
  85. package/package.json +12 -4
  86. package/src/animation/Animation.ts +6 -3
  87. package/src/animator/Animator.ts +130 -0
  88. package/src/animator/index.ts +56 -0
  89. package/src/animator/public.ts +66 -0
  90. package/src/chnobli.ts +3 -2
  91. package/src/property/ClassProperty.ts +1 -1
  92. package/src/property/TransformXYProperty.ts +1 -1
  93. package/src/scroll/Scroll.ts +204 -51
  94. package/src/scroll/ScrollEvent.ts +1 -0
  95. package/src/scroll/index.ts +3 -0
  96. package/src/scroll/public.ts +35 -2
  97. package/src/target/DomTarget.ts +1 -1
  98. package/src/target/ObjectTarget.ts +19 -13
  99. package/src/target/TestDomNode.ts +3 -3
  100. package/src/tests/properties.test.ts +86 -3
  101. package/src/tests/scroll.test.ts +36 -0
  102. package/src/tests/timeline.test.ts +1 -1
  103. package/src/tests/timing.test.ts +32 -0
  104. package/src/tests/usecases.test.ts +40 -2
  105. package/src/tests/values.test.ts +9 -9
  106. package/src/timeline/Timeline.ts +5 -4
  107. package/src/timeline/public.ts +34 -12
  108. package/src/timing/AnimationFrameTicker.ts +6 -1
  109. package/src/timing/TestTicker.ts +7 -1
  110. package/src/timing/Ticker.ts +5 -1
  111. package/src/timing/Timing.ts +133 -97
  112. package/src/timing/easing.ts +6 -1
  113. package/src/utils/Events.ts +1 -1
  114. package/src/utils/motionpath.ts +5 -5
  115. package/src/utils/utils.ts +13 -16
  116. package/src/values/ColorValue.ts +5 -4
  117. package/src/values/StyleValue.ts +4 -4
  118. package/src/values/Value.ts +8 -8
  119. package/.eslintrc.cjs +0 -39
  120. package/src/animator.js +0 -187
@@ -36,68 +36,85 @@ export type TimingProps = {
36
36
  * because it is like one frame, so it's an image
37
37
  */
38
38
  export default class Timing {
39
- // removes the relevant properties from the props
40
-
39
+ /**
40
+ * The duration of a single iteration
41
+ */
41
42
  iterDuration: number;
43
+
44
+ /**
45
+ * The total duration of the timing
46
+ */
42
47
  duration: number;
43
48
 
44
49
  ease: (t: number) => number;
50
+ /**
51
+ * The number of repeats
52
+ *
53
+ * -1 is infinite
54
+ */
45
55
  repeat: number;
56
+
57
+ /**
58
+ * If the iteration should alternate
59
+ */
46
60
  alternate: boolean;
61
+
62
+ /**
63
+ * If the iteration should be reversed
64
+ */
47
65
  reversed: boolean;
48
66
 
67
+ /**
68
+ * The position of the current iteration
69
+ *
70
+ * will never be outside of the range 0-1 (inclusive)
71
+ */
49
72
  position: number;
73
+ /**
74
+ * The state of the timing
75
+ */
50
76
  state: number;
51
77
 
52
- private _progress: number;
53
-
54
- /*
55
- seeking
56
- if repeat is infinite
57
- seek will only control the current iteration
58
- if repeat is finite
59
- seek will control the entire time
60
-
78
+ /**
79
+ * Progress is a value which always counts up
80
+ * does not take alternate or easing into account
81
+ */
82
+ private progress: number;
61
83
 
62
- {
63
- duration: in ms
64
- ease: easeFunction
65
- repeat: -1 - x,
66
- alternate
67
- }
68
- */
69
84
  constructor(props: TimingProps) {
70
85
  // these vars are only readonly
71
86
  // use functions to update them
72
87
 
73
- this.iterDuration = props.duration;
74
- this.duration = props.duration;
75
-
76
88
  this.ease = props.ease ?? (t => t);
77
89
  this.repeat = props.repeat ?? 0;
78
90
  this.alternate = props.alternate ?? true;
79
91
  this.reversed = props.reversed ?? false;
80
92
 
81
- this.position = this.duration > 0 ? 0 : 1;
82
- this.state = STATE_BEFORE;
83
-
84
- // progress does not take alternation into account and has no easing
85
- // this always increments up
86
- this._progress = 0;
93
+ this.iterDuration = 0;
94
+ this.duration = 0;
95
+ this.setDuration(props.duration);
87
96
 
88
- // scrub
97
+ this.position = 0;
98
+ this.state = STATE_BEFORE;
99
+ this.progress = 0;
100
+ this.seek(-1);
89
101
  }
90
102
 
91
103
  setDuration(iterDuration: number) {
92
104
  this.iterDuration = iterDuration;
93
105
 
94
106
  this.duration = this.iterDuration;
95
- if (this.repeat > -1) {
107
+ if (this.isFinite()) {
96
108
  this.duration = (this.repeat + 1) * this.iterDuration;
97
109
  }
98
110
  }
99
111
 
100
- positionMs() {
112
+ /**
113
+ * Returns the current position in milliseconds
114
+ *
115
+ * This is equivalent to position * iteration duration
116
+ */
117
+ positionMs(): number {
101
118
  // todo should this not return pos * duration?
102
119
  return this.position * this.iterDuration;
103
120
  }
@@ -109,17 +126,23 @@ export default class Timing {
109
126
  * If the state is before or after the position might be more/less than
110
127
  * required
111
128
  */
112
- positionMsUnbounded() {
113
- const outOfBounds =
114
- this.state <= STATE_BEFORE || this.state >= STATE_AFTER;
129
+ positionMsUnbounded(): number {
130
+ let reversed = this.reversed;
131
+
132
+ if (this._shouldInvert()) reversed = !reversed;
115
133
 
116
- if (!outOfBounds) return this.position * this.iterDuration;
134
+ let pos = this.position;
135
+
136
+ if (this.state <= STATE_BEFORE) {
137
+ pos = reversed ? 2 : -1;
138
+ } else if (this.state >= STATE_AFTER) {
139
+ pos = reversed ? -1 : 2;
140
+ }
117
141
 
118
- if (this.position === 0) return -1;
119
- return this.position * this.iterDuration + 1;
142
+ return pos * this.iterDuration;
120
143
  }
121
144
 
122
- isFinite() {
145
+ isFinite(): boolean {
123
146
  return this.repeat > -1;
124
147
  }
125
148
 
@@ -131,56 +154,60 @@ export default class Timing {
131
154
  return;
132
155
  }
133
156
 
134
- this._updateProgress(this._progress + change / this.iterDuration);
135
- }
136
-
137
- seekMs(ms: number) {
138
- if (this.iterDuration <= 0) {
139
- this._updateProgress(Math.sign(ms));
140
- return;
157
+ if (this.isFinite()) {
158
+ this._updateProgress(
159
+ this.positionAbsolute() + change / this.iterDuration,
160
+ );
161
+ } else {
162
+ // to make sure we don't mess up the alternate
163
+ this._updateProgress(
164
+ Math.max(0, this.progress) + change / this.iterDuration,
165
+ );
141
166
  }
167
+ }
142
168
 
143
- this._updateProgress(ms / this.iterDuration);
144
-
145
- // return this.seek(this.normalizeMs(ms));
169
+ seekMs(ms: number): void {
170
+ return this.seek(this.normalizeMs(ms));
146
171
  }
147
172
 
148
- normalizeMs(ms: number) {
173
+ /**
174
+ * Returns the position of time (ms) position
175
+ */
176
+ normalizeMs(ms: number): number {
149
177
  if (this.iterDuration <= 0) {
150
178
  return Math.sign(ms);
151
179
  }
152
180
 
153
- const pos = ms / this.iterDuration;
154
-
155
- if (this.isFinite()) {
156
- return pos / (this.repeat + 1);
157
- }
158
-
159
- return pos;
181
+ return ms / this.duration;
160
182
  }
161
183
 
162
- // todo how to call this
163
- positionLinear(): number {
184
+ // Returns the position without easing or reversing
185
+ //
186
+ // Returns 0..=(repeat + 1)
187
+ positionAbsolute(): number {
164
188
  if (this.isFinite()) {
165
- return this._progress / (this.repeat + 1);
189
+ return Math.min(this.repeat + 1, Math.max(0, this.progress));
166
190
  }
167
191
 
168
- return this._progress;
192
+ // the iterations should be inclusive
193
+ const prog = Math.max(0, this.progress) % 1;
194
+ if (prog === 0 && this.progress > 0) return 1;
195
+ return prog;
169
196
  }
170
197
 
171
198
  // should be between 0-1 if outside might change the state
172
199
  seek(pos: number) {
173
- if (this.repeat <= 0) {
174
- this._updateProgress(pos);
175
- } else {
176
- // finite
200
+ if (this.isFinite()) {
177
201
  this._updateProgress(pos * (this.repeat + 1));
202
+ } else {
203
+ // to make sure we don't mess up the alternate
204
+ this._updateProgress(Math.floor(this.progress) + pos);
178
205
  }
179
206
  }
180
207
 
181
208
  savePosition(): Position {
182
209
  return {
183
- progress: this._progress,
210
+ progress: this.progress,
184
211
  };
185
212
  }
186
213
 
@@ -188,48 +215,46 @@ export default class Timing {
188
215
  this._updateProgress(pos.progress);
189
216
  }
190
217
 
218
+ /**
219
+ * Sets the alternate
220
+ */
191
221
  setAlternate(alternate: boolean) {
192
222
  if (this.alternate == alternate) return;
193
223
 
194
- // make sure the reversed is updated according to the current inversion
195
- this.reversed = alternate == this._shouldInvert();
224
+ this.reversed = !this.reversed;
196
225
  this.alternate = alternate;
197
226
  }
198
227
 
199
228
  reverse() {
200
229
  this.reversed = !this.reversed;
201
230
 
202
- const wrapAround = (p: number) => {
203
- if (this.repeat > -1) return p % (this.repeat + 1);
204
- return p;
205
- };
206
-
207
- let p;
208
- if (this.state <= STATE_BEFORE) {
209
- p = 2;
210
- } else if (this.state >= STATE_AFTER) {
211
- p = -1;
212
- // check if the values should be reversed
213
- } else if (this.reversed != this._shouldInvert()) {
214
- let decimal = 1 - (this._progress % 1);
215
- p = wrapAround(Math.floor(this._progress) + decimal);
231
+ if (this.isFinite()) {
232
+ this._updateProgress(this.repeat + 1 - this.progress);
216
233
  } else {
217
- p = wrapAround(this._progress);
234
+ const fract = this.progress % 1;
235
+ this._updateProgress(Math.floor(this.progress) + 1 - fract);
218
236
  }
219
-
220
- this._updateProgress(p);
221
237
  }
222
238
 
223
- _shouldInvert() {
224
- return this.alternate && Math.floor(this._progress) % 2 === 1;
239
+ _shouldInvert(): boolean {
240
+ return (
241
+ this.alternate &&
242
+ Math.floor(this.progress) % 2 === 1 &&
243
+ this.progress % 1 !== 0
244
+ );
225
245
  }
226
246
 
247
+ /**
248
+ * Updates the progress and the state
249
+ *
250
+ * newProgress should follow the same rules as _progress
251
+ */
227
252
  _updateProgress(newProgress: number) {
228
253
  // if duration is zero the position is always 1
229
254
  // and the state is either BEFORE or AFTER
230
255
  if (this.iterDuration <= 0) {
231
256
  newProgress = Math.sign(newProgress);
232
- this._progress = newProgress;
257
+ this.progress = newProgress;
233
258
  this.position = 1;
234
259
 
235
260
  if (newProgress < 0) this.state = STATE_BEFORE;
@@ -238,15 +263,19 @@ export default class Timing {
238
263
  return;
239
264
  }
240
265
 
241
- this._progress = newProgress;
266
+ this.progress = newProgress;
242
267
 
268
+ // update state
269
+ //
270
+ // is this not wrong if we are in reversed?
271
+ //
243
272
  // since infinite repeat can never end let's ignore it
244
- if (this.repeat > -1) {
273
+ if (this.isFinite()) {
245
274
  const end = this.repeat + 1;
246
- if (this._progress > end) {
247
- this._progress = end;
275
+ if (this.progress > end) {
276
+ this.progress = end + 1;
248
277
  this.state = STATE_AFTER;
249
- } else if (this._progress === end) {
278
+ } else if (this.progress === end) {
250
279
  this.state = STATE_ENDED;
251
280
  } else {
252
281
  this.state = STATE_RUNNING;
@@ -256,20 +285,27 @@ export default class Timing {
256
285
  }
257
286
 
258
287
  // override state if not running
259
- if (this._progress < 0) {
260
- this._progress = 0;
288
+ if (this.progress < 0) {
289
+ this.progress = -1;
261
290
  this.state = STATE_BEFORE;
262
- } else if (this._progress === 0) {
291
+ } else if (this.progress === 0) {
263
292
  this.state = STATE_START;
264
293
  }
265
294
 
266
295
  // now calculate the position
267
- this.position = this._progress % 1;
296
+ this.position = this.positionAbsolute() % 1;
297
+
298
+ // the iterations should be inclusive
299
+ if (this.position === 0 && this.progress > 0) {
300
+ this.position = 1;
301
+ }
302
+
303
+ // alternate
304
+ if (this._shouldInvert()) this.position = 1 - this.position;
268
305
 
269
306
  // calc if we are in a reversed iteration or not
270
307
  // and we are we should invert the position
271
- if (this.reversed != this._shouldInvert())
272
- this.position = 1 - this.position;
308
+ if (this.reversed) this.position = 1 - this.position;
273
309
 
274
310
  this.position = this.ease(this.position);
275
311
  }
@@ -296,6 +296,11 @@ export function sineOut(t: number): number {
296
296
  return Math.sin((t * Math.PI) / 2);
297
297
  }
298
298
 
299
- export function cubicBezier(x1: number, y1: number, x2: number, y2: number) {
299
+ export function cubicBezier(
300
+ x1: number,
301
+ y1: number,
302
+ x2: number,
303
+ y2: number,
304
+ ): (t: number) => number {
300
305
  return bezierEasing(x1, y1, x2, y2);
301
306
  }
@@ -29,7 +29,7 @@ export default class Events {
29
29
  }
30
30
 
31
31
  trigger(event: string, ...args: any[]) {
32
- let list = this.listeners.get(event);
32
+ const list = this.listeners.get(event);
33
33
  if (!list) return;
34
34
  list.trigger(...args);
35
35
  }
@@ -7,10 +7,10 @@ function catmullRom(
7
7
  p1Tension: number,
8
8
  p2Tension: number,
9
9
  ) {
10
- let v0 = (p2 - p0) * p1Tension;
11
- let v1 = (p3 - p1) * p2Tension;
12
- let t2 = t * t;
13
- let t3 = t2 * t;
10
+ const v0 = (p2 - p0) * p1Tension;
11
+ const v1 = (p3 - p1) * p2Tension;
12
+ const t2 = t * t;
13
+ const t3 = t2 * t;
14
14
 
15
15
  return (
16
16
  (2 * p1 - 2 * p2 + v0 + v1) * t3 +
@@ -40,7 +40,7 @@ export function curve(
40
40
  ): (t: number) => { x: number; y: number } {
41
41
  if (points.length <= 1) throw new Error('curve expects at least 2 points');
42
42
 
43
- let startEndStraight = opts.startEndStraight ?? true;
43
+ const startEndStraight = opts.startEndStraight ?? true;
44
44
  if (startEndStraight) {
45
45
  points[0].straight = true;
46
46
  points[points.length - 1].straight = true;
@@ -1,4 +1,3 @@
1
- import { Callback } from '../responsive/ResponsiveEvent.js';
2
1
  import { curve } from './motionpath.js';
3
2
 
4
3
  export { curve };
@@ -6,21 +5,21 @@ export { curve };
6
5
  /**
7
6
  * Explicitly tells a property to animate the to value
8
7
  */
9
- export function to(to: any) {
8
+ export function to(to: any): { to: any } {
10
9
  return { to };
11
10
  }
12
11
 
13
12
  /**
14
13
  * Explicitly tells a property to animate the from value
15
14
  */
16
- export function from(from: any) {
15
+ export function from(from: any): { from: any } {
17
16
  return { from };
18
17
  }
19
18
 
20
19
  /**
21
20
  * Explicitly tells a property to animate with the from and to values
22
21
  */
23
- export function fromTo(from: any, to: any) {
22
+ export function fromTo(from: any, to: any): { from: any; to: any } {
24
23
  return { from, to };
25
24
  }
26
25
 
@@ -34,7 +33,9 @@ export function responsive(fn: (target: any) => void): any {
34
33
  /**
35
34
  * Converts an element with text into span with chars
36
35
  */
37
- export function chars(element: HTMLElement) {
36
+ export function chars(
37
+ element: HTMLElement,
38
+ ): Element[] | (HTMLSpanElement | null)[] {
38
39
  if (element.dataset.processedChars) return Array.from(element.children);
39
40
 
40
41
  const chars = element.textContent!.split('');
@@ -76,7 +77,7 @@ function defWordCallback(element: HTMLElement, word: string): HTMLElement {
76
77
  export function words(
77
78
  element: HTMLElement,
78
79
  cb: WordCallback = defWordCallback,
79
- ) {
80
+ ): Element[] | (HTMLElement | null)[] {
80
81
  if (element.dataset.processedWords) return Array.from(element.children);
81
82
 
82
83
  const words = element.textContent!.split(/(\s+)/);
@@ -99,16 +100,12 @@ export function words(
99
100
  /**
100
101
  * get the offset to the current page page
101
102
  */
102
- export function pageOffset(el: HTMLElement) {
103
- if ('offsetTop' in el) {
104
- return {
105
- top: el.offsetTop,
106
- left: el.offsetLeft,
107
- width: el.offsetWidth,
108
- height: el.offsetHeight,
109
- };
110
- }
111
-
103
+ export function pageOffset(el: HTMLElement): {
104
+ top: number;
105
+ left: number;
106
+ width: number;
107
+ height: number;
108
+ } {
112
109
  const rect = (el as HTMLElement).getBoundingClientRect();
113
110
  return {
114
111
  top: window.scrollY + rect.top,
@@ -17,7 +17,7 @@ export default class ColorValue {
17
17
  this.values = v;
18
18
  }
19
19
 
20
- static parse(v: string | number[]) {
20
+ static parse(v: string | number[]): ColorValue {
21
21
  if (Array.isArray(v)) {
22
22
  if (v.length < 3 || v.length > 4)
23
23
  throw new Error('expected array [r, g, b, a]');
@@ -40,7 +40,7 @@ export default class ColorValue {
40
40
  }
41
41
 
42
42
  // v needs to be a string
43
- static mightBeAColor(v: string) {
43
+ static mightBeAColor(v: string): boolean {
44
44
  v = v.trim();
45
45
 
46
46
  return (
@@ -51,11 +51,11 @@ export default class ColorValue {
51
51
  );
52
52
  }
53
53
 
54
- clone() {
54
+ clone(): ColorValue {
55
55
  return new ColorValue(this.values.slice() as any);
56
56
  }
57
57
 
58
- toString() {
58
+ toString(): string {
59
59
  const [r, g, b, a] = this.values;
60
60
  return `rgba(${[r, g, b].map(v => Math.round(v)).join(', ')}, ${a.toFixed(
61
61
  3,
@@ -134,6 +134,7 @@ function parseHsl(hsl: string): RGBA {
134
134
 
135
135
  /// expects [h, s, l, a]
136
136
  function hslToRgba(hsla: HSLA): RGBA {
137
+ // eslint-disable-next-line prefer-const
137
138
  let [h, s, l, a] = hsla;
138
139
 
139
140
  // normalize
@@ -77,7 +77,7 @@ export default class StyleValue {
77
77
  : false;
78
78
  }
79
79
 
80
- static parse(v: string | number | (string | number)[]) {
80
+ static parse(v: string | number | (string | number)[]): StyleValue {
81
81
  if (typeof v === 'number') return new StyleValue(v);
82
82
 
83
83
  if (Array.isArray(v)) {
@@ -120,7 +120,7 @@ export default class StyleValue {
120
120
  }
121
121
 
122
122
  /// only works if the kind is values
123
- get length() {
123
+ get length(): number {
124
124
  if (this.inner.kind !== 'values')
125
125
  throw new Error('only works with kind values');
126
126
 
@@ -145,7 +145,7 @@ export default class StyleValue {
145
145
  return (this.inner.values as Value[])[0];
146
146
  }
147
147
 
148
- clone() {
148
+ clone(): StyleValue {
149
149
  if (this.inner.kind === 'text')
150
150
  return new StyleValue(this.inner.values);
151
151
 
@@ -156,7 +156,7 @@ export default class StyleValue {
156
156
  }
157
157
 
158
158
  /// if this is called with a text value nothing happens
159
- withDefaultUnit(unit: string | null) {
159
+ withDefaultUnit(unit: string | null): StyleValue {
160
160
  if (this.inner.kind === 'text')
161
161
  return new StyleValue(this.inner.values);
162
162
 
@@ -1,4 +1,4 @@
1
- const REGEX = /^(\d+\.?\d*|\.\d+)(\w*|%)$/;
1
+ const REGEX = /^(-?\d+\.?\d*|\.\d+)(\w*|%)$/;
2
2
 
3
3
  export default class Value {
4
4
  num: number;
@@ -9,7 +9,7 @@ export default class Value {
9
9
  this.unit = unit;
10
10
  }
11
11
 
12
- static parse(v: string | number) {
12
+ static parse(v: string | number): Value {
13
13
  if (typeof v === 'number') {
14
14
  return new Value(v);
15
15
  }
@@ -20,29 +20,29 @@ export default class Value {
20
20
  return new Value(parseFloat(num), unit ? unit : null);
21
21
  }
22
22
 
23
- eq(other: Value) {
23
+ eq(other: Value): boolean {
24
24
  return this.unit === other.unit && this.num === other.num;
25
25
  }
26
26
 
27
- clone(newNum: number | null = null) {
27
+ clone(newNum: number | null = null): Value {
28
28
  if (newNum !== null) return new Value(newNum, this.unit);
29
29
 
30
30
  return new Value(this.num, this.unit);
31
31
  }
32
32
 
33
- cloneAdd(add: number) {
33
+ cloneAdd(add: number): Value {
34
34
  return new Value(this.num + add, this.unit);
35
35
  }
36
36
 
37
- cloneMul(mul: number) {
37
+ cloneMul(mul: number): Value {
38
38
  return new Value(this.num * mul, this.unit);
39
39
  }
40
40
 
41
- withDefaultUnit(unit: string | null) {
41
+ withDefaultUnit(unit: string | null): Value {
42
42
  return new Value(this.num, this.unit ?? unit);
43
43
  }
44
44
 
45
- toString() {
45
+ toString(): string {
46
46
  return this.num.toFixed(3) + (this.unit ?? '');
47
47
  }
48
48
  }
package/.eslintrc.cjs DELETED
@@ -1,39 +0,0 @@
1
- module.exports = {
2
- "env": {
3
- "browser": true,
4
- "es2021": true
5
- },
6
- "extends": "eslint:recommended",
7
- "overrides": [
8
- {
9
- "env": {
10
- "node": true
11
- },
12
- "files": [
13
- ".eslintrc.{js,cjs}"
14
- ],
15
- "parserOptions": {
16
- "sourceType": "script"
17
- }
18
- }
19
- ],
20
- "parserOptions": {
21
- "ecmaVersion": "latest",
22
- "sourceType": "module"
23
- },
24
- "rules": {
25
- "no-unused-vars": [
26
- "error",
27
- {
28
- "varsIgnorePattern": "^_",
29
- "argsIgnorePattern": "^_"
30
- }
31
- ],
32
- "no-constant-condition": [
33
- "error",
34
- {
35
- "checkLoops": false
36
- }
37
- ]
38
- }
39
- }