@pyreon/kinetic 0.13.0 → 0.14.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pyreon/kinetic",
3
- "version": "0.13.0",
3
+ "version": "0.14.0",
4
4
  "description": "CSS-transition-based animation components for Pyreon",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -41,18 +41,18 @@
41
41
  "typecheck": "tsc --noEmit"
42
42
  },
43
43
  "devDependencies": {
44
- "@pyreon/core": "^0.13.0",
45
- "@pyreon/reactivity": "^0.13.0",
46
- "@pyreon/runtime-dom": "^0.13.0",
47
- "@pyreon/test-utils": "^0.13.0",
48
- "@pyreon/typescript": "^0.13.0",
44
+ "@pyreon/core": "^0.14.0",
45
+ "@pyreon/reactivity": "^0.14.0",
46
+ "@pyreon/runtime-dom": "^0.14.0",
47
+ "@pyreon/test-utils": "^0.13.2",
48
+ "@pyreon/typescript": "^0.14.0",
49
49
  "@vitest/browser-playwright": "^4.1.4",
50
50
  "@vitus-labs/tools-rolldown": "^1.15.3"
51
51
  },
52
52
  "peerDependencies": {
53
- "@pyreon/core": "^0.13.0",
54
- "@pyreon/reactivity": "^0.13.0",
55
- "@pyreon/runtime-dom": "^0.13.0"
53
+ "@pyreon/core": "^0.14.0",
54
+ "@pyreon/reactivity": "^0.14.0",
55
+ "@pyreon/runtime-dom": "^0.14.0"
56
56
  },
57
57
  "engines": {
58
58
  "node": ">= 22"
@@ -1,4 +1,5 @@
1
1
  import type { VNode } from '@pyreon/core'
2
+ import { h } from '@pyreon/core'
2
3
  import { signal } from '@pyreon/reactivity'
3
4
  import Collapse from '../Collapse'
4
5
  import CollapseRenderer from '../kinetic/CollapseRenderer'
@@ -95,7 +96,7 @@ describe('Collapse', () => {
95
96
 
96
97
  it('returns a VNode', () => {
97
98
  const show = signal(true)
98
- const child = { type: 'div', props: {}, children: ['Hello'], key: undefined }
99
+ const child = h('div', null, 'Hello') as VNode
99
100
  const vnode = Collapse({ show, children: child } as any)
100
101
  expect(vnode).not.toBeNull()
101
102
  })
@@ -107,7 +108,7 @@ describe('Collapse', () => {
107
108
  setupCollapse({
108
109
  show,
109
110
  onEnter,
110
- children: { type: 'div', props: {}, children: ['Hello'], key: undefined },
111
+ children: h('div', null, 'Hello') as VNode,
111
112
  })
112
113
 
113
114
  show.set(true)
@@ -121,7 +122,7 @@ describe('Collapse', () => {
121
122
  const { wrapperEl } = setupCollapse({
122
123
  show,
123
124
  onAfterEnter,
124
- children: { type: 'div', props: {}, children: ['Hello'], key: undefined },
125
+ children: h('div', null, 'Hello') as VNode,
125
126
  })
126
127
 
127
128
  show.set(true)
@@ -138,7 +139,7 @@ describe('Collapse', () => {
138
139
  setupCollapse({
139
140
  show,
140
141
  onLeave,
141
- children: { type: 'div', props: {}, children: ['Hello'], key: undefined },
142
+ children: h('div', null, 'Hello') as VNode,
142
143
  })
143
144
 
144
145
  show.set(false)
@@ -152,7 +153,7 @@ describe('Collapse', () => {
152
153
  const { wrapperEl } = setupCollapse({
153
154
  show,
154
155
  onAfterLeave,
155
- children: { type: 'div', props: {}, children: ['Hello'], key: undefined },
156
+ children: h('div', null, 'Hello') as VNode,
156
157
  })
157
158
 
158
159
  show.set(false)
@@ -167,7 +168,7 @@ describe('Collapse', () => {
167
168
 
168
169
  const { wrapperEl } = setupCollapse({
169
170
  show,
170
- children: { type: 'div', props: {}, children: ['Hello'], key: undefined },
171
+ children: h('div', null, 'Hello') as VNode,
171
172
  })
172
173
 
173
174
  show.set(true)
@@ -181,7 +182,7 @@ describe('Collapse', () => {
181
182
 
182
183
  const { wrapperEl } = setupCollapse({
183
184
  show,
184
- children: { type: 'div', props: {}, children: ['Hello'], key: undefined },
185
+ children: h('div', null, 'Hello') as VNode,
185
186
  })
186
187
 
187
188
  show.set(true)
@@ -197,7 +198,7 @@ describe('Collapse', () => {
197
198
 
198
199
  const { wrapperEl } = setupCollapse({
199
200
  show,
200
- children: { type: 'div', props: {}, children: ['Hello'], key: undefined },
201
+ children: h('div', null, 'Hello') as VNode,
201
202
  })
202
203
 
203
204
  show.set(false)
@@ -212,7 +213,7 @@ describe('Collapse', () => {
212
213
  const { wrapperEl } = setupCollapse({
213
214
  show,
214
215
  transition: 'height 500ms ease-in-out',
215
- children: { type: 'div', props: {}, children: ['Hello'], key: undefined },
216
+ children: h('div', null, 'Hello') as VNode,
216
217
  })
217
218
 
218
219
  show.set(true)
@@ -228,7 +229,7 @@ describe('Collapse', () => {
228
229
  show,
229
230
  appear: true,
230
231
  onEnter,
231
- children: { type: 'div', props: {}, children: ['Hello'], key: undefined },
232
+ children: h('div', null, 'Hello') as VNode,
232
233
  })
233
234
 
234
235
  // appear defers via queueMicrotask so all refs are wired first
@@ -246,7 +247,7 @@ describe('Collapse', () => {
246
247
  show,
247
248
  timeout: 800,
248
249
  onAfterLeave,
249
- children: { type: 'div', props: {}, children: ['Hello'], key: undefined },
250
+ children: h('div', null, 'Hello') as VNode,
250
251
  })
251
252
 
252
253
  show.set(false)
@@ -266,7 +267,7 @@ describe('Collapse', () => {
266
267
  show,
267
268
  onEnter,
268
269
  onLeave,
269
- children: { type: 'div', props: {}, children: ['Hello'], key: undefined },
270
+ children: h('div', null, 'Hello') as VNode,
270
271
  })
271
272
 
272
273
  // Start leaving
@@ -288,7 +289,7 @@ describe('Collapse', () => {
288
289
  show,
289
290
  onEnter,
290
291
  onLeave,
291
- children: { type: 'div', props: {}, children: ['Hello'], key: undefined },
292
+ children: h('div', null, 'Hello') as VNode,
292
293
  })
293
294
 
294
295
  // Start entering
@@ -307,7 +308,7 @@ describe('Collapse', () => {
307
308
  const { wrapperEl } = setupCollapse({
308
309
  show,
309
310
  onEnter,
310
- children: { type: 'div', props: {}, children: ['Hello'], key: undefined },
311
+ children: h('div', null, 'Hello') as VNode,
311
312
  })
312
313
 
313
314
  show.set(true)
@@ -329,7 +330,7 @@ describe('Collapse', () => {
329
330
  const { wrapperEl } = setupCollapse({
330
331
  show,
331
332
  onLeave,
332
- children: { type: 'div', props: {}, children: ['Hello'], key: undefined },
333
+ children: h('div', null, 'Hello') as VNode,
333
334
  })
334
335
 
335
336
  show.set(false)
@@ -350,7 +351,7 @@ describe('Collapse', () => {
350
351
  show,
351
352
  appear: true,
352
353
  onAfterEnter,
353
- children: { type: 'div', props: {}, children: ['Hello'], key: undefined },
354
+ children: h('div', null, 'Hello') as VNode,
354
355
  })
355
356
 
356
357
  await Promise.resolve()
@@ -365,7 +366,7 @@ describe('Collapse', () => {
365
366
 
366
367
  const { wrapperEl } = setupCollapse({
367
368
  show,
368
- children: { type: 'div', props: {}, children: ['Hello'], key: undefined },
369
+ children: h('div', null, 'Hello') as VNode,
369
370
  })
370
371
 
371
372
  show.set(false)
@@ -443,7 +444,7 @@ const setupCollapseRenderer = (props: {
443
444
  })
444
445
 
445
446
  const config = props.config ?? makeCollapseConfig()
446
- const child: VNode = { type: 'p', props: {}, children: ['Content'], key: null }
447
+ const child = h('p', null, 'Content') as VNode
447
448
 
448
449
  const vnode = CollapseRenderer({
449
450
  config,
@@ -473,7 +474,7 @@ describe('CollapseRenderer', () => {
473
474
  it('returns a VNode with the config.tag', () => {
474
475
  const show = signal(true)
475
476
  const config = makeCollapseConfig({ tag: 'section' })
476
- const child: VNode = { type: 'p', props: {}, children: ['Content'], key: null }
477
+ const child = h('p', null, 'Content') as VNode
477
478
 
478
479
  const vnode = CollapseRenderer({
479
480
  config,
@@ -748,7 +749,7 @@ describe('Collapse — reduced motion', () => {
748
749
  show,
749
750
  onEnter,
750
751
  onAfterEnter,
751
- children: { type: 'div', props: {}, children: ['Hello'], key: undefined },
752
+ children: h('div', null, 'Hello') as VNode,
752
753
  })
753
754
 
754
755
  show.set(true)
@@ -768,7 +769,7 @@ describe('Collapse — reduced motion', () => {
768
769
  show,
769
770
  onLeave,
770
771
  onAfterLeave,
771
- children: { type: 'div', props: {}, children: ['Hello'], key: undefined },
772
+ children: h('div', null, 'Hello') as VNode,
772
773
  })
773
774
 
774
775
  show.set(false)
@@ -1,4 +1,5 @@
1
1
  import type { VNode } from '@pyreon/core'
2
+ import { h } from '@pyreon/core'
2
3
  import GroupRenderer from '../kinetic/GroupRenderer'
3
4
  import type { KineticConfig } from '../kinetic/types'
4
5
 
@@ -47,12 +48,13 @@ const unwrap = (val: any): any => {
47
48
  return result
48
49
  }
49
50
 
50
- const makeKeyedChild = (key: string | number, text: string): VNode => ({
51
- type: 'span',
52
- props: { 'data-testid': `child-${key}` },
53
- children: [text],
54
- key,
55
- })
51
+ // Real h() instead of a hand-built `{ type, props, children, key }`
52
+ // literal — same VNode shape as production, so any test running the
53
+ // returned node through the runtime sees real h()-normalised output.
54
+ const makeKeyedChild = (key: string | number, text: string): VNode => {
55
+ const vnode = h('span', { 'data-testid': `child-${key}` }, text) as VNode
56
+ return { ...vnode, key }
57
+ }
56
58
 
57
59
  describe('GroupRenderer', () => {
58
60
  it('returns a VNode wrapping children in config.tag', () => {
@@ -285,7 +287,8 @@ describe('GroupRenderer', () => {
285
287
  it('ignores children without keys', () => {
286
288
  const config = makeConfig()
287
289
  const keyedChild = makeKeyedChild('a', 'Alpha')
288
- const unkeyedChild: VNode = { type: 'span', props: {}, children: ['No key'], key: null }
290
+ // Real h() output instead of a mock literal same shape, real path.
291
+ const unkeyedChild: VNode = h('span', null, 'No key') as VNode
289
292
 
290
293
  const vnode = unwrap(
291
294
  GroupRenderer({
@@ -1,4 +1,5 @@
1
1
  import type { VNode } from '@pyreon/core'
2
+ import { h } from '@pyreon/core'
2
3
  import StaggerRenderer from '../kinetic/StaggerRenderer'
3
4
  import type { KineticConfig } from '../kinetic/types'
4
5
 
@@ -40,12 +41,12 @@ const makeConfig = (overrides: Partial<KineticConfig> = {}): KineticConfig => ({
40
41
  ...overrides,
41
42
  })
42
43
 
43
- const makeChild = (key: string | number, text: string): VNode => ({
44
- type: 'span',
45
- props: { 'data-testid': `child-${key}` },
46
- children: [text],
47
- key,
48
- })
44
+ // Real h() instead of a hand-built `{ type, props, children, key }`
45
+ // literal — same VNode shape as production.
46
+ const makeChild = (key: string | number, text: string): VNode => {
47
+ const vnode = h('span', { 'data-testid': `child-${key}` }, text) as VNode
48
+ return { ...vnode, key }
49
+ }
49
50
 
50
51
  /**
51
52
  * Extract the cloned child VNode from a TransitionItem VNode.
@@ -476,12 +477,8 @@ describe('StaggerRenderer', () => {
476
477
 
477
478
  it('preserves existing style on child when injecting stagger styles', () => {
478
479
  const config = makeConfig()
479
- const childWithStyle: VNode = {
480
- type: 'span',
481
- props: { style: { color: 'red', fontWeight: 'bold' } },
482
- children: ['Styled'],
483
- key: 'styled',
484
- }
480
+ const realVnode = h('span', { style: { color: 'red', fontWeight: 'bold' } }, 'Styled') as VNode
481
+ const childWithStyle: VNode = { ...realVnode, key: 'styled' }
485
482
 
486
483
  const vnode = StaggerRenderer({
487
484
  config,
@@ -1,4 +1,5 @@
1
1
  import type { VNode } from '@pyreon/core'
2
+ import { h } from '@pyreon/core'
2
3
  import { signal } from '@pyreon/reactivity'
3
4
 
4
5
  let _reducedMotion = false
@@ -88,12 +89,9 @@ const wireRef = (vnode: VNode | null, el: HTMLElement) => {
88
89
  */
89
90
  const setupTransition = (props: Record<string, unknown>) => {
90
91
  const el = document.createElement('div')
91
- const child: VNode = {
92
- type: 'div',
93
- props: { 'data-testid': 'child' },
94
- children: ['Hello'],
95
- key: null,
96
- }
92
+ // Real h() instead of a mock literal — same VNode shape as
93
+ // production, so the runtime sees real h()-normalised output.
94
+ const child = h('div', { 'data-testid': 'child' }, 'Hello') as VNode
97
95
 
98
96
  const vnode = Transition({
99
97
  ...props,
@@ -108,14 +106,14 @@ const setupTransition = (props: Record<string, unknown>) => {
108
106
  describe('Transition', () => {
109
107
  it('returns a VNode when show=true', () => {
110
108
  const show = signal(true)
111
- const child: VNode = { type: 'div', props: {}, children: ['Hello'], key: null }
109
+ const child = h('div', null, 'Hello') as VNode
112
110
  const vnode = Transition({ show, children: child })
113
111
  expect(vnode).not.toBeNull()
114
112
  })
115
113
 
116
114
  it('returns a VNode with Show component', () => {
117
115
  const show = signal(true)
118
- const child: VNode = { type: 'div', props: {}, children: ['Hello'], key: null }
116
+ const child = h('div', null, 'Hello') as VNode
119
117
  const vnode = Transition({ show, children: child })
120
118
  expect(vnode).not.toBeNull()
121
119
  // The outermost VNode should be a Show component
@@ -1,4 +1,5 @@
1
1
  import type { VNode } from '@pyreon/core'
2
+ import { h } from '@pyreon/core'
2
3
  import { signal } from '@pyreon/reactivity'
3
4
 
4
5
  let _reducedMotion = false
@@ -88,12 +89,8 @@ const wireRef = (vnode: VNode | null, el: HTMLElement) => {
88
89
  */
89
90
  const setupTransitionItem = (props: Record<string, unknown>) => {
90
91
  const el = document.createElement('div')
91
- const child: VNode = {
92
- type: 'div',
93
- props: { 'data-testid': 'child' },
94
- children: ['Hello'],
95
- key: null,
96
- }
92
+ // Real h() instead of a mock literal — same VNode shape as production.
93
+ const child = h('div', { 'data-testid': 'child' }, 'Hello') as VNode
97
94
 
98
95
  const vnode = TransitionItem({
99
96
  ...props,
@@ -108,14 +105,14 @@ const setupTransitionItem = (props: Record<string, unknown>) => {
108
105
  describe('TransitionItem', () => {
109
106
  it('returns a VNode when show returns true', () => {
110
107
  const show = () => true
111
- const child: VNode = { type: 'div', props: {}, children: ['Hello'], key: null }
108
+ const child = h('div', null, 'Hello') as VNode
112
109
  const vnode = TransitionItem({ show, children: child })
113
110
  expect(vnode).not.toBeNull()
114
111
  })
115
112
 
116
113
  it('wraps child in a Show component', () => {
117
114
  const show = () => true
118
- const child: VNode = { type: 'div', props: {}, children: ['Hello'], key: null }
115
+ const child = h('div', null, 'Hello') as VNode
119
116
  const vnode = TransitionItem({ show, children: child })
120
117
  expect(vnode).not.toBeNull()
121
118
  expect(typeof vnode?.type).toBe('function')
@@ -123,7 +120,7 @@ describe('TransitionItem', () => {
123
120
 
124
121
  it('clones child VNode with merged ref', () => {
125
122
  const show = () => true
126
- const child: VNode = { type: 'div', props: {}, children: ['Hello'], key: null }
123
+ const child = h('div', null, 'Hello') as VNode
127
124
  const vnode = TransitionItem({ show, children: child })
128
125
 
129
126
  // The Show component's children (or fallback) should have a ref prop
@@ -358,7 +355,7 @@ describe('TransitionItem', () => {
358
355
 
359
356
  it('unmount=false keeps element with display:none when hidden', () => {
360
357
  const show = () => false
361
- const child: VNode = { type: 'div', props: {}, children: ['Hello'], key: null }
358
+ const child = h('div', null, 'Hello') as VNode
362
359
  const vnode = TransitionItem({ show, unmount: false, children: child })
363
360
 
364
361
  expect(vnode).not.toBeNull()
@@ -374,7 +371,7 @@ describe('TransitionItem', () => {
374
371
 
375
372
  it('unmount=false fallback has a merged ref', () => {
376
373
  const show = () => false
377
- const child: VNode = { type: 'div', props: {}, children: ['Hello'], key: null }
374
+ const child = h('div', null, 'Hello') as VNode
378
375
  const vnode = TransitionItem({ show, unmount: false, children: child })
379
376
 
380
377
  const showProps = vnode?.props as Record<string, unknown>
@@ -388,12 +385,7 @@ describe('TransitionItem', () => {
388
385
 
389
386
  it('unmount=false merges existing child style with display:none', () => {
390
387
  const show = () => false
391
- const child: VNode = {
392
- type: 'div',
393
- props: { style: { color: 'red', opacity: 1 } },
394
- children: ['Hello'],
395
- key: null,
396
- }
388
+ const child = h('div', { style: { color: 'red', opacity: 1 } }, 'Hello') as VNode
397
389
  const vnode = TransitionItem({ show, unmount: false, children: child })
398
390
 
399
391
  const showProps = vnode?.props as Record<string, unknown>
@@ -1,4 +1,5 @@
1
1
  import type { VNode, VNodeChild } from '@pyreon/core'
2
+ import { h } from '@pyreon/core'
2
3
  import { signal } from '@pyreon/reactivity'
3
4
 
4
5
  let _reducedMotion = false
@@ -353,7 +354,11 @@ describe('kinetic() — collapse mode', () => {
353
354
  show,
354
355
  onEnter,
355
356
  onAfterEnter,
356
- children: { type: 'p', props: {}, children: ['Content'], key: null },
357
+ // Real h() instead of a mock literal same VNode shape as
358
+ // production, so the test exercises whatever flattening /
359
+ // normalisation h() applies (instead of asserting the
360
+ // hand-built shape always matches).
361
+ children: h('p', null, 'Content'),
357
362
  }),
358
363
  )
359
364