@pyreon/kinetic 0.11.5 → 0.11.7

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,6 +1,6 @@
1
- import type { VNode } from "@pyreon/core"
2
- import StaggerRenderer from "../kinetic/StaggerRenderer"
3
- import type { KineticConfig } from "../kinetic/types"
1
+ import type { VNode } from '@pyreon/core'
2
+ import StaggerRenderer from '../kinetic/StaggerRenderer'
3
+ import type { KineticConfig } from '../kinetic/types'
4
4
 
5
5
  // Mock rAF for deterministic testing
6
6
  let rafCallbacks: (() => void)[] = []
@@ -12,37 +12,37 @@ beforeEach(() => {
12
12
  rafCallbacks = []
13
13
 
14
14
  vi.stubGlobal(
15
- "requestAnimationFrame",
15
+ 'requestAnimationFrame',
16
16
  vi.fn((cb: () => void) => {
17
17
  rafCallbacks.push(cb)
18
18
  return rafCallbacks.length
19
19
  }),
20
20
  )
21
21
 
22
- vi.stubGlobal("cancelAnimationFrame", vi.fn())
22
+ vi.stubGlobal('cancelAnimationFrame', vi.fn())
23
23
  })
24
24
 
25
25
  afterEach(() => {
26
26
  vi.useRealTimers()
27
- vi.stubGlobal("requestAnimationFrame", originalRaf)
28
- vi.stubGlobal("cancelAnimationFrame", originalCaf)
27
+ vi.stubGlobal('requestAnimationFrame', originalRaf)
28
+ vi.stubGlobal('cancelAnimationFrame', originalCaf)
29
29
  })
30
30
 
31
31
  const makeConfig = (overrides: Partial<KineticConfig> = {}): KineticConfig => ({
32
- tag: "div",
33
- mode: "stagger",
34
- enter: "s-enter",
35
- enterFrom: "s-enter-from",
36
- enterTo: "s-enter-to",
37
- leave: "s-leave",
38
- leaveFrom: "s-leave-from",
39
- leaveTo: "s-leave-to",
32
+ tag: 'div',
33
+ mode: 'stagger',
34
+ enter: 's-enter',
35
+ enterFrom: 's-enter-from',
36
+ enterTo: 's-enter-to',
37
+ leave: 's-leave',
38
+ leaveFrom: 's-leave-from',
39
+ leaveTo: 's-leave-to',
40
40
  ...overrides,
41
41
  })
42
42
 
43
43
  const makeChild = (key: string | number, text: string): VNode => ({
44
- type: "span",
45
- props: { "data-testid": `child-${key}` },
44
+ type: 'span',
45
+ props: { 'data-testid': `child-${key}` },
46
46
  children: [text],
47
47
  key,
48
48
  })
@@ -59,23 +59,23 @@ const extractStaggerChild = (tiVNode: VNode): VNode | null => {
59
59
  if (props?.children) {
60
60
  const pc = Array.isArray(props.children) ? props.children : [props.children]
61
61
  for (const c of pc) {
62
- if (c && typeof c === "object" && "type" in (c as object)) return c as VNode
62
+ if (c && typeof c === 'object' && 'type' in (c as object)) return c as VNode
63
63
  }
64
64
  }
65
65
  // Fallback: check vnode.children (classic runtime)
66
66
  if (tiVNode.children) {
67
67
  const ch = Array.isArray(tiVNode.children) ? tiVNode.children : [tiVNode.children]
68
68
  for (const c of ch) {
69
- if (c && typeof c === "object" && "type" in (c as object)) return c as VNode
69
+ if (c && typeof c === 'object' && 'type' in (c as object)) return c as VNode
70
70
  }
71
71
  }
72
72
  return null
73
73
  }
74
74
 
75
- describe("StaggerRenderer", () => {
76
- it("returns a VNode wrapping children in config.tag", () => {
75
+ describe('StaggerRenderer', () => {
76
+ it('returns a VNode wrapping children in config.tag', () => {
77
77
  const config = makeConfig()
78
- const children = [makeChild("a", "Alpha"), makeChild("b", "Beta")]
78
+ const children = [makeChild('a', 'Alpha'), makeChild('b', 'Beta')]
79
79
 
80
80
  const vnode = StaggerRenderer({
81
81
  config,
@@ -86,12 +86,12 @@ describe("StaggerRenderer", () => {
86
86
  })
87
87
 
88
88
  expect(vnode).not.toBeNull()
89
- expect(vnode?.type).toBe("div")
89
+ expect(vnode?.type).toBe('div')
90
90
  })
91
91
 
92
- it("uses custom tag from config", () => {
93
- const config = makeConfig({ tag: "ul" })
94
- const children = [makeChild("a", "Alpha")]
92
+ it('uses custom tag from config', () => {
93
+ const config = makeConfig({ tag: 'ul' })
94
+ const children = [makeChild('a', 'Alpha')]
95
95
 
96
96
  const vnode = StaggerRenderer({
97
97
  config,
@@ -101,29 +101,29 @@ describe("StaggerRenderer", () => {
101
101
  children,
102
102
  })
103
103
 
104
- expect(vnode?.type).toBe("ul")
104
+ expect(vnode?.type).toBe('ul')
105
105
  })
106
106
 
107
- it("passes htmlProps to the wrapper element", () => {
107
+ it('passes htmlProps to the wrapper element', () => {
108
108
  const config = makeConfig()
109
- const children = [makeChild("a", "Alpha")]
109
+ const children = [makeChild('a', 'Alpha')]
110
110
 
111
111
  const vnode = StaggerRenderer({
112
112
  config,
113
- htmlProps: { "data-testid": "stagger-wrapper", class: "my-stagger" },
113
+ htmlProps: { 'data-testid': 'stagger-wrapper', class: 'my-stagger' },
114
114
  show: () => true,
115
115
  callbacks: {},
116
116
  children,
117
117
  })
118
118
 
119
119
  const props = vnode?.props as Record<string, unknown>
120
- expect(props?.["data-testid"]).toBe("stagger-wrapper")
121
- expect(props?.class).toBe("my-stagger")
120
+ expect(props?.['data-testid']).toBe('stagger-wrapper')
121
+ expect(props?.class).toBe('my-stagger')
122
122
  })
123
123
 
124
- it("wraps each child in a TransitionItem", () => {
124
+ it('wraps each child in a TransitionItem', () => {
125
125
  const config = makeConfig()
126
- const children = [makeChild("a", "Alpha"), makeChild("b", "Beta"), makeChild("c", "Charlie")]
126
+ const children = [makeChild('a', 'Alpha'), makeChild('b', 'Beta'), makeChild('c', 'Charlie')]
127
127
 
128
128
  const vnode = StaggerRenderer({
129
129
  config,
@@ -139,13 +139,13 @@ describe("StaggerRenderer", () => {
139
139
 
140
140
  for (const child of childArray) {
141
141
  const childVNode = child as VNode
142
- expect(typeof childVNode.type).toBe("function")
142
+ expect(typeof childVNode.type).toBe('function')
143
143
  }
144
144
  })
145
145
 
146
- it("injects --stagger-index CSS custom property on each child", () => {
146
+ it('injects --stagger-index CSS custom property on each child', () => {
147
147
  const config = makeConfig()
148
- const children = [makeChild("a", "Alpha"), makeChild("b", "Beta"), makeChild("c", "Charlie")]
148
+ const children = [makeChild('a', 'Alpha'), makeChild('b', 'Beta'), makeChild('c', 'Charlie')]
149
149
 
150
150
  const vnode = StaggerRenderer({
151
151
  config,
@@ -162,13 +162,13 @@ describe("StaggerRenderer", () => {
162
162
  const childProps = clonedChild?.props as Record<string, unknown>
163
163
  const style = childProps?.style as Record<string, unknown>
164
164
 
165
- expect(style?.["--stagger-index"]).toBe(i)
165
+ expect(style?.['--stagger-index']).toBe(i)
166
166
  }
167
167
  })
168
168
 
169
- it("injects --stagger-interval CSS custom property on each child", () => {
169
+ it('injects --stagger-interval CSS custom property on each child', () => {
170
170
  const config = makeConfig({ interval: 100 })
171
- const children = [makeChild("a", "Alpha"), makeChild("b", "Beta")]
171
+ const children = [makeChild('a', 'Alpha'), makeChild('b', 'Beta')]
172
172
 
173
173
  const vnode = StaggerRenderer({
174
174
  config,
@@ -186,13 +186,13 @@ describe("StaggerRenderer", () => {
186
186
  const childProps = clonedChild?.props as Record<string, unknown>
187
187
  const style = childProps?.style as Record<string, unknown>
188
188
 
189
- expect(style?.["--stagger-interval"]).toBe("100ms")
189
+ expect(style?.['--stagger-interval']).toBe('100ms')
190
190
  }
191
191
  })
192
192
 
193
- it("applies transitionDelay based on interval * index", () => {
193
+ it('applies transitionDelay based on interval * index', () => {
194
194
  const config = makeConfig()
195
- const children = [makeChild("a", "Alpha"), makeChild("b", "Beta"), makeChild("c", "Charlie")]
195
+ const children = [makeChild('a', 'Alpha'), makeChild('b', 'Beta'), makeChild('c', 'Charlie')]
196
196
 
197
197
  const vnode = StaggerRenderer({
198
198
  config,
@@ -214,9 +214,9 @@ describe("StaggerRenderer", () => {
214
214
  }
215
215
  })
216
216
 
217
- it("uses default interval of 50ms when not specified", () => {
217
+ it('uses default interval of 50ms when not specified', () => {
218
218
  const config = makeConfig()
219
- const children = [makeChild("a", "Alpha"), makeChild("b", "Beta")]
219
+ const children = [makeChild('a', 'Alpha'), makeChild('b', 'Beta')]
220
220
 
221
221
  const vnode = StaggerRenderer({
222
222
  config,
@@ -233,13 +233,13 @@ describe("StaggerRenderer", () => {
233
233
  const childProps = clonedChild?.props as Record<string, unknown>
234
234
  const style = childProps?.style as Record<string, unknown>
235
235
 
236
- expect(style?.transitionDelay).toBe("50ms")
237
- expect(style?.["--stagger-interval"]).toBe("50ms")
236
+ expect(style?.transitionDelay).toBe('50ms')
237
+ expect(style?.['--stagger-interval']).toBe('50ms')
238
238
  })
239
239
 
240
- it("reverseLeave reverses stagger index order on leave", () => {
240
+ it('reverseLeave reverses stagger index order on leave', () => {
241
241
  const config = makeConfig()
242
- const children = [makeChild("a", "Alpha"), makeChild("b", "Beta"), makeChild("c", "Charlie")]
242
+ const children = [makeChild('a', 'Alpha'), makeChild('b', 'Beta'), makeChild('c', 'Charlie')]
243
243
 
244
244
  // show=false with reverseLeave=true
245
245
  const vnode = StaggerRenderer({
@@ -263,14 +263,14 @@ describe("StaggerRenderer", () => {
263
263
  const childProps = clonedChild?.props as Record<string, unknown>
264
264
  const style = childProps?.style as Record<string, unknown>
265
265
 
266
- expect(style?.["--stagger-index"]).toBe(expectedStaggerIndex)
266
+ expect(style?.['--stagger-index']).toBe(expectedStaggerIndex)
267
267
  expect(style?.transitionDelay).toBe(`${expectedStaggerIndex * 100}ms`)
268
268
  }
269
269
  })
270
270
 
271
- it("does not reverse stagger index when show is true even if reverseLeave is true", () => {
271
+ it('does not reverse stagger index when show is true even if reverseLeave is true', () => {
272
272
  const config = makeConfig()
273
- const children = [makeChild("a", "Alpha"), makeChild("b", "Beta")]
273
+ const children = [makeChild('a', 'Alpha'), makeChild('b', 'Beta')]
274
274
 
275
275
  const vnode = StaggerRenderer({
276
276
  config,
@@ -290,20 +290,20 @@ describe("StaggerRenderer", () => {
290
290
  const childProps = clonedChild?.props as Record<string, unknown>
291
291
  const style = childProps?.style as Record<string, unknown>
292
292
 
293
- expect(style?.["--stagger-index"]).toBe(i)
293
+ expect(style?.['--stagger-index']).toBe(i)
294
294
  }
295
295
  })
296
296
 
297
- it("passes transition class config to TransitionItem children", () => {
297
+ it('passes transition class config to TransitionItem children', () => {
298
298
  const config = makeConfig({
299
- enter: "custom-enter",
300
- enterFrom: "custom-from",
301
- enterTo: "custom-to",
302
- leave: "custom-leave",
303
- leaveFrom: "custom-lfrom",
304
- leaveTo: "custom-lto",
299
+ enter: 'custom-enter',
300
+ enterFrom: 'custom-from',
301
+ enterTo: 'custom-to',
302
+ leave: 'custom-leave',
303
+ leaveFrom: 'custom-lfrom',
304
+ leaveTo: 'custom-lto',
305
305
  })
306
- const children = [makeChild("a", "Alpha")]
306
+ const children = [makeChild('a', 'Alpha')]
307
307
 
308
308
  const vnode = StaggerRenderer({
309
309
  config,
@@ -316,24 +316,24 @@ describe("StaggerRenderer", () => {
316
316
  const wrapperChildren = vnode?.children as VNode[]
317
317
  const tiProps = wrapperChildren[0]?.props as Record<string, unknown>
318
318
 
319
- expect(tiProps.enter).toBe("custom-enter")
320
- expect(tiProps.enterFrom).toBe("custom-from")
321
- expect(tiProps.enterTo).toBe("custom-to")
322
- expect(tiProps.leave).toBe("custom-leave")
323
- expect(tiProps.leaveFrom).toBe("custom-lfrom")
324
- expect(tiProps.leaveTo).toBe("custom-lto")
319
+ expect(tiProps.enter).toBe('custom-enter')
320
+ expect(tiProps.enterFrom).toBe('custom-from')
321
+ expect(tiProps.enterTo).toBe('custom-to')
322
+ expect(tiProps.leave).toBe('custom-leave')
323
+ expect(tiProps.leaveFrom).toBe('custom-lfrom')
324
+ expect(tiProps.leaveTo).toBe('custom-lto')
325
325
  })
326
326
 
327
- it("passes style transition config to TransitionItem children", () => {
327
+ it('passes style transition config to TransitionItem children', () => {
328
328
  const config = makeConfig({
329
329
  enterStyle: { opacity: 0 },
330
330
  enterToStyle: { opacity: 1 },
331
- enterTransition: "opacity 300ms ease",
331
+ enterTransition: 'opacity 300ms ease',
332
332
  leaveStyle: { opacity: 1 },
333
333
  leaveToStyle: { opacity: 0 },
334
- leaveTransition: "opacity 200ms ease-in",
334
+ leaveTransition: 'opacity 200ms ease-in',
335
335
  })
336
- const children = [makeChild("a", "Alpha")]
336
+ const children = [makeChild('a', 'Alpha')]
337
337
 
338
338
  const vnode = StaggerRenderer({
339
339
  config,
@@ -348,15 +348,15 @@ describe("StaggerRenderer", () => {
348
348
 
349
349
  expect(tiProps.enterStyle).toEqual({ opacity: 0 })
350
350
  expect(tiProps.enterToStyle).toEqual({ opacity: 1 })
351
- expect(tiProps.enterTransition).toBe("opacity 300ms ease")
351
+ expect(tiProps.enterTransition).toBe('opacity 300ms ease')
352
352
  expect(tiProps.leaveStyle).toEqual({ opacity: 1 })
353
353
  expect(tiProps.leaveToStyle).toEqual({ opacity: 0 })
354
- expect(tiProps.leaveTransition).toBe("opacity 200ms ease-in")
354
+ expect(tiProps.leaveTransition).toBe('opacity 200ms ease-in')
355
355
  })
356
356
 
357
- it("adjusts timeout per child based on stagger delay", () => {
357
+ it('adjusts timeout per child based on stagger delay', () => {
358
358
  const config = makeConfig()
359
- const children = [makeChild("a", "Alpha"), makeChild("b", "Beta"), makeChild("c", "Charlie")]
359
+ const children = [makeChild('a', 'Alpha'), makeChild('b', 'Beta'), makeChild('c', 'Charlie')]
360
360
 
361
361
  const vnode = StaggerRenderer({
362
362
  config,
@@ -378,10 +378,10 @@ describe("StaggerRenderer", () => {
378
378
  }
379
379
  })
380
380
 
381
- it("only fires onAfterLeave on the last child (normal order)", () => {
381
+ it('only fires onAfterLeave on the last child (normal order)', () => {
382
382
  const onAfterLeave = vi.fn()
383
383
  const config = makeConfig()
384
- const children = [makeChild("a", "Alpha"), makeChild("b", "Beta"), makeChild("c", "Charlie")]
384
+ const children = [makeChild('a', 'Alpha'), makeChild('b', 'Beta'), makeChild('c', 'Charlie')]
385
385
 
386
386
  const vnode = StaggerRenderer({
387
387
  config,
@@ -404,10 +404,10 @@ describe("StaggerRenderer", () => {
404
404
  }
405
405
  })
406
406
 
407
- it("fires onAfterLeave on the first child when reverseLeave is true", () => {
407
+ it('fires onAfterLeave on the first child when reverseLeave is true', () => {
408
408
  const onAfterLeave = vi.fn()
409
409
  const config = makeConfig()
410
- const children = [makeChild("a", "Alpha"), makeChild("b", "Beta"), makeChild("c", "Charlie")]
410
+ const children = [makeChild('a', 'Alpha'), makeChild('b', 'Beta'), makeChild('c', 'Charlie')]
411
411
 
412
412
  const vnode = StaggerRenderer({
413
413
  config,
@@ -431,9 +431,9 @@ describe("StaggerRenderer", () => {
431
431
  }
432
432
  })
433
433
 
434
- it("uses config.interval when interval prop is not provided", () => {
434
+ it('uses config.interval when interval prop is not provided', () => {
435
435
  const config = makeConfig({ interval: 200 })
436
- const children = [makeChild("a", "Alpha"), makeChild("b", "Beta")]
436
+ const children = [makeChild('a', 'Alpha'), makeChild('b', 'Beta')]
437
437
 
438
438
  const vnode = StaggerRenderer({
439
439
  config,
@@ -448,13 +448,13 @@ describe("StaggerRenderer", () => {
448
448
  const childProps = clonedChild?.props as Record<string, unknown>
449
449
  const style = childProps?.style as Record<string, unknown>
450
450
 
451
- expect(style?.transitionDelay).toBe("200ms")
452
- expect(style?.["--stagger-interval"]).toBe("200ms")
451
+ expect(style?.transitionDelay).toBe('200ms')
452
+ expect(style?.['--stagger-interval']).toBe('200ms')
453
453
  })
454
454
 
455
- it("interval prop overrides config.interval", () => {
455
+ it('interval prop overrides config.interval', () => {
456
456
  const config = makeConfig({ interval: 200 })
457
- const children = [makeChild("a", "Alpha"), makeChild("b", "Beta")]
457
+ const children = [makeChild('a', 'Alpha'), makeChild('b', 'Beta')]
458
458
 
459
459
  const vnode = StaggerRenderer({
460
460
  config,
@@ -470,17 +470,17 @@ describe("StaggerRenderer", () => {
470
470
  const childProps = clonedChild?.props as Record<string, unknown>
471
471
  const style = childProps?.style as Record<string, unknown>
472
472
 
473
- expect(style?.transitionDelay).toBe("300ms")
474
- expect(style?.["--stagger-interval"]).toBe("300ms")
473
+ expect(style?.transitionDelay).toBe('300ms')
474
+ expect(style?.['--stagger-interval']).toBe('300ms')
475
475
  })
476
476
 
477
- it("preserves existing style on child when injecting stagger styles", () => {
477
+ it('preserves existing style on child when injecting stagger styles', () => {
478
478
  const config = makeConfig()
479
479
  const childWithStyle: VNode = {
480
- type: "span",
481
- props: { style: { color: "red", fontWeight: "bold" } },
482
- children: ["Styled"],
483
- key: "styled",
480
+ type: 'span',
481
+ props: { style: { color: 'red', fontWeight: 'bold' } },
482
+ children: ['Styled'],
483
+ key: 'styled',
484
484
  }
485
485
 
486
486
  const vnode = StaggerRenderer({
@@ -498,17 +498,17 @@ describe("StaggerRenderer", () => {
498
498
  const style = childProps?.style as Record<string, unknown>
499
499
 
500
500
  // Original styles preserved
501
- expect(style?.color).toBe("red")
502
- expect(style?.fontWeight).toBe("bold")
501
+ expect(style?.color).toBe('red')
502
+ expect(style?.fontWeight).toBe('bold')
503
503
  // Stagger styles injected
504
- expect(style?.["--stagger-index"]).toBe(0)
505
- expect(style?.["--stagger-interval"]).toBe("50ms")
506
- expect(style?.transitionDelay).toBe("0ms")
504
+ expect(style?.['--stagger-index']).toBe(0)
505
+ expect(style?.['--stagger-interval']).toBe('50ms')
506
+ expect(style?.transitionDelay).toBe('0ms')
507
507
  })
508
508
 
509
- it("filters out non-VNode children", () => {
509
+ it('filters out non-VNode children', () => {
510
510
  const config = makeConfig()
511
- const validChild = makeChild("a", "Alpha")
511
+ const validChild = makeChild('a', 'Alpha')
512
512
  // Simulate non-VNode values in children array
513
513
  const children = [validChild, null as unknown as VNode, undefined as unknown as VNode]
514
514