@pyreon/runtime-dom 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,74 +1,74 @@
1
- import type { ComponentFn } from "@pyreon/core"
2
- import { h } from "@pyreon/core"
3
- import { signal } from "@pyreon/reactivity"
1
+ import type { ComponentFn } from '@pyreon/core'
2
+ import { h } from '@pyreon/core'
3
+ import { signal } from '@pyreon/reactivity'
4
4
  import {
5
5
  KeepAlive as _KeepAlive,
6
6
  Transition as _Transition,
7
7
  TransitionGroup as _TransitionGroup,
8
8
  mount,
9
- } from "../index"
9
+ } from '../index'
10
10
 
11
11
  const Transition = _Transition as unknown as ComponentFn<Record<string, unknown>>
12
12
  const TransitionGroup = _TransitionGroup as unknown as ComponentFn<Record<string, unknown>>
13
13
  const KeepAlive = _KeepAlive as unknown as ComponentFn<Record<string, unknown>>
14
14
 
15
15
  function container(): HTMLElement {
16
- const el = document.createElement("div")
16
+ const el = document.createElement('div')
17
17
  document.body.appendChild(el)
18
18
  return el
19
19
  }
20
20
 
21
21
  // ─── Transition ──────────────────────────────────────────────────────────────
22
22
 
23
- describe("Transition", () => {
24
- test("renders child when show is true", () => {
23
+ describe('Transition', () => {
24
+ test('renders child when show is true', () => {
25
25
  const el = container()
26
26
  const show = signal(true)
27
27
  mount(
28
- h(Transition, { name: "fade", show: () => show() }, h("div", { class: "child" }, "hello")),
28
+ h(Transition, { name: 'fade', show: () => show() }, h('div', { class: 'child' }, 'hello')),
29
29
  el,
30
30
  )
31
- expect(el.querySelector(".child")?.textContent).toBe("hello")
31
+ expect(el.querySelector('.child')?.textContent).toBe('hello')
32
32
  })
33
33
 
34
- test("does not render child when show is false initially", () => {
34
+ test('does not render child when show is false initially', () => {
35
35
  const el = container()
36
36
  const show = signal(false)
37
37
  mount(
38
- h(Transition, { name: "fade", show: () => show() }, h("div", { class: "child" }, "hello")),
38
+ h(Transition, { name: 'fade', show: () => show() }, h('div', { class: 'child' }, 'hello')),
39
39
  el,
40
40
  )
41
- expect(el.querySelector(".child")).toBeNull()
41
+ expect(el.querySelector('.child')).toBeNull()
42
42
  })
43
43
 
44
44
  test("uses default name 'pyreon' when no name provided", () => {
45
45
  const el = container()
46
46
  const show = signal(true)
47
- mount(h(Transition, { show: () => show() }, h("div", { class: "child" }, "content")), el)
48
- expect(el.querySelector(".child")?.textContent).toBe("content")
47
+ mount(h(Transition, { show: () => show() }, h('div', { class: 'child' }, 'content')), el)
48
+ expect(el.querySelector('.child')?.textContent).toBe('content')
49
49
  })
50
50
 
51
- test("applies enter classes when show transitions from false to true", async () => {
51
+ test('applies enter classes when show transitions from false to true', async () => {
52
52
  const el = container()
53
53
  const show = signal(false)
54
54
  mount(
55
- h(Transition, { name: "fade", show: () => show() }, h("div", { class: "target" }, "text")),
55
+ h(Transition, { name: 'fade', show: () => show() }, h('div', { class: 'target' }, 'text')),
56
56
  el,
57
57
  )
58
- expect(el.querySelector(".target")).toBeNull()
58
+ expect(el.querySelector('.target')).toBeNull()
59
59
 
60
60
  show.set(true)
61
61
  // Wait for microtask (queueMicrotask in handleVisibilityChange)
62
62
  await new Promise<void>((r) => setTimeout(r, 20))
63
63
 
64
- const target = el.querySelector(".target") as HTMLElement
64
+ const target = el.querySelector('.target') as HTMLElement
65
65
  expect(target).not.toBeNull()
66
66
  // After the enter animation starts, the element should have enter classes
67
67
  // Classes will be in transition — at minimum the element should exist
68
- expect(target.textContent).toBe("text")
68
+ expect(target.textContent).toBe('text')
69
69
  })
70
70
 
71
- test("applies custom enter/leave class overrides", async () => {
71
+ test('applies custom enter/leave class overrides', async () => {
72
72
  const el = container()
73
73
  const show = signal(true)
74
74
  mount(
@@ -76,21 +76,21 @@ describe("Transition", () => {
76
76
  Transition,
77
77
  {
78
78
  show: () => show(),
79
- enterFrom: "my-enter-from",
80
- enterActive: "my-enter-active",
81
- enterTo: "my-enter-to",
82
- leaveFrom: "my-leave-from",
83
- leaveActive: "my-leave-active",
84
- leaveTo: "my-leave-to",
79
+ enterFrom: 'my-enter-from',
80
+ enterActive: 'my-enter-active',
81
+ enterTo: 'my-enter-to',
82
+ leaveFrom: 'my-leave-from',
83
+ leaveActive: 'my-leave-active',
84
+ leaveTo: 'my-leave-to',
85
85
  },
86
- h("div", { class: "custom-target" }, "custom"),
86
+ h('div', { class: 'custom-target' }, 'custom'),
87
87
  ),
88
88
  el,
89
89
  )
90
- expect(el.querySelector(".custom-target")).not.toBeNull()
90
+ expect(el.querySelector('.custom-target')).not.toBeNull()
91
91
  })
92
92
 
93
- test("calls lifecycle callbacks on enter", async () => {
93
+ test('calls lifecycle callbacks on enter', async () => {
94
94
  const el = container()
95
95
  const show = signal(false)
96
96
  const onBeforeEnter = vi.fn()
@@ -100,12 +100,12 @@ describe("Transition", () => {
100
100
  h(
101
101
  Transition,
102
102
  {
103
- name: "fade",
103
+ name: 'fade',
104
104
  show: () => show(),
105
105
  onBeforeEnter,
106
106
  onAfterEnter,
107
107
  },
108
- h("div", { class: "lifecycle" }, "enter"),
108
+ h('div', { class: 'lifecycle' }, 'enter'),
109
109
  ),
110
110
  el,
111
111
  )
@@ -115,15 +115,15 @@ describe("Transition", () => {
115
115
  expect(onBeforeEnter).toHaveBeenCalled()
116
116
 
117
117
  // Trigger the transitionend to complete the enter
118
- const target = el.querySelector(".lifecycle") as HTMLElement
118
+ const target = el.querySelector('.lifecycle') as HTMLElement
119
119
  if (target) {
120
- target.dispatchEvent(new Event("transitionend"))
120
+ target.dispatchEvent(new Event('transitionend'))
121
121
  await new Promise<void>((r) => setTimeout(r, 10))
122
122
  expect(onAfterEnter).toHaveBeenCalled()
123
123
  }
124
124
  })
125
125
 
126
- test("calls lifecycle callbacks on leave", async () => {
126
+ test('calls lifecycle callbacks on leave', async () => {
127
127
  const el = container()
128
128
  const show = signal(true)
129
129
  const onBeforeLeave = vi.fn()
@@ -133,12 +133,12 @@ describe("Transition", () => {
133
133
  h(
134
134
  Transition,
135
135
  {
136
- name: "fade",
136
+ name: 'fade',
137
137
  show: () => show(),
138
138
  onBeforeLeave,
139
139
  onAfterLeave,
140
140
  },
141
- h("div", { class: "leave-target" }, "leave"),
141
+ h('div', { class: 'leave-target' }, 'leave'),
142
142
  ),
143
143
  el,
144
144
  )
@@ -151,15 +151,15 @@ describe("Transition", () => {
151
151
  expect(onBeforeLeave).toHaveBeenCalled()
152
152
 
153
153
  // Trigger transitionend to complete leave
154
- const target = el.querySelector(".leave-target") as HTMLElement
154
+ const target = el.querySelector('.leave-target') as HTMLElement
155
155
  if (target) {
156
- target.dispatchEvent(new Event("transitionend"))
156
+ target.dispatchEvent(new Event('transitionend'))
157
157
  await new Promise<void>((r) => setTimeout(r, 20))
158
158
  expect(onAfterLeave).toHaveBeenCalled()
159
159
  }
160
160
  })
161
161
 
162
- test("appear option triggers enter animation on initial mount", async () => {
162
+ test('appear option triggers enter animation on initial mount', async () => {
163
163
  const el = container()
164
164
  const show = signal(true)
165
165
  const onBeforeEnter = vi.fn()
@@ -168,12 +168,12 @@ describe("Transition", () => {
168
168
  h(
169
169
  Transition,
170
170
  {
171
- name: "fade",
171
+ name: 'fade',
172
172
  show: () => show(),
173
173
  appear: true,
174
174
  onBeforeEnter,
175
175
  },
176
- h("div", { class: "appear-target" }, "appear"),
176
+ h('div', { class: 'appear-target' }, 'appear'),
177
177
  ),
178
178
  el,
179
179
  )
@@ -182,34 +182,34 @@ describe("Transition", () => {
182
182
  expect(onBeforeEnter).toHaveBeenCalled()
183
183
  })
184
184
 
185
- test("warns when child is a component (not a DOM element)", () => {
185
+ test('warns when child is a component (not a DOM element)', () => {
186
186
  const el = container()
187
187
  const show = signal(true)
188
- const warnSpy = vi.spyOn(console, "warn").mockImplementation(() => {})
189
- const ChildComp = () => h("div", null, "comp-child")
188
+ const warnSpy = vi.spyOn(console, 'warn').mockImplementation(() => {})
189
+ const ChildComp = () => h('div', null, 'comp-child')
190
190
 
191
- mount(h(Transition, { name: "fade", show: () => show() }, h(ChildComp, null)), el)
191
+ mount(h(Transition, { name: 'fade', show: () => show() }, h(ChildComp, null)), el)
192
192
 
193
- expect(warnSpy).toHaveBeenCalledWith(expect.stringContaining("Transition child is a component"))
193
+ expect(warnSpy).toHaveBeenCalledWith(expect.stringContaining('Transition child is a component'))
194
194
  warnSpy.mockRestore()
195
195
  })
196
196
 
197
- test("handles null/undefined children gracefully", () => {
197
+ test('handles null/undefined children gracefully', () => {
198
198
  const el = container()
199
199
  const show = signal(true)
200
200
  // No children
201
- expect(() => mount(h(Transition, { name: "fade", show: () => show() }), el)).not.toThrow()
201
+ expect(() => mount(h(Transition, { name: 'fade', show: () => show() }), el)).not.toThrow()
202
202
  })
203
203
 
204
- test("cancels pending leave when re-entering", async () => {
204
+ test('cancels pending leave when re-entering', async () => {
205
205
  const el = container()
206
206
  const show = signal(true)
207
207
 
208
208
  mount(
209
209
  h(
210
210
  Transition,
211
- { name: "fade", show: () => show() },
212
- h("div", { class: "cancel-test" }, "toggle"),
211
+ { name: 'fade', show: () => show() },
212
+ h('div', { class: 'cancel-test' }, 'toggle'),
213
213
  ),
214
214
  el,
215
215
  )
@@ -225,11 +225,11 @@ describe("Transition", () => {
225
225
  await new Promise<void>((r) => setTimeout(r, 30))
226
226
 
227
227
  // Element should be visible again
228
- const target = el.querySelector(".cancel-test")
228
+ const target = el.querySelector('.cancel-test')
229
229
  expect(target).not.toBeNull()
230
230
  })
231
231
 
232
- test("handles animationend event (CSS animations)", async () => {
232
+ test('handles animationend event (CSS animations)', async () => {
233
233
  const el = container()
234
234
  const show = signal(false)
235
235
  const onAfterEnter = vi.fn()
@@ -237,8 +237,8 @@ describe("Transition", () => {
237
237
  mount(
238
238
  h(
239
239
  Transition,
240
- { name: "anim", show: () => show(), onAfterEnter },
241
- h("div", { class: "anim-target" }, "anim"),
240
+ { name: 'anim', show: () => show(), onAfterEnter },
241
+ h('div', { class: 'anim-target' }, 'anim'),
242
242
  ),
243
243
  el,
244
244
  )
@@ -246,10 +246,10 @@ describe("Transition", () => {
246
246
  show.set(true)
247
247
  await new Promise<void>((r) => setTimeout(r, 30))
248
248
 
249
- const target = el.querySelector(".anim-target") as HTMLElement
249
+ const target = el.querySelector('.anim-target') as HTMLElement
250
250
  if (target) {
251
251
  // Fire animationend instead of transitionend
252
- target.dispatchEvent(new Event("animationend"))
252
+ target.dispatchEvent(new Event('animationend'))
253
253
  await new Promise<void>((r) => setTimeout(r, 10))
254
254
  expect(onAfterEnter).toHaveBeenCalled()
255
255
  }
@@ -258,26 +258,26 @@ describe("Transition", () => {
258
258
 
259
259
  // ─── TransitionGroup ─────────────────────────────────────────────────────────
260
260
 
261
- describe("TransitionGroup", () => {
262
- test("renders items inside a wrapper element", async () => {
261
+ describe('TransitionGroup', () => {
262
+ test('renders items inside a wrapper element', async () => {
263
263
  const el = container()
264
264
  const items = signal([{ id: 1 }, { id: 2 }, { id: 3 }])
265
265
 
266
266
  mount(
267
267
  h(TransitionGroup, {
268
- tag: "ul",
269
- name: "list",
268
+ tag: 'ul',
269
+ name: 'list',
270
270
  items: () => items(),
271
271
  keyFn: (item: { id: number }) => item.id,
272
- render: (item: { id: number }) => h("li", null, `item-${item.id}`),
272
+ render: (item: { id: number }) => h('li', null, `item-${item.id}`),
273
273
  }),
274
274
  el,
275
275
  )
276
276
 
277
277
  await new Promise<void>((r) => setTimeout(r, 50))
278
- const lis = el.querySelectorAll("li")
278
+ const lis = el.querySelectorAll('li')
279
279
  expect(lis.length).toBe(3)
280
- expect(lis[0]?.textContent).toBe("item-1")
280
+ expect(lis[0]?.textContent).toBe('item-1')
281
281
  })
282
282
 
283
283
  test("uses default tag 'div' and name 'pyreon'", async () => {
@@ -288,70 +288,70 @@ describe("TransitionGroup", () => {
288
288
  h(TransitionGroup, {
289
289
  items: () => items(),
290
290
  keyFn: (item: { id: number }) => item.id,
291
- render: (item: { id: number }) => h("span", null, `s-${item.id}`),
291
+ render: (item: { id: number }) => h('span', null, `s-${item.id}`),
292
292
  }),
293
293
  el,
294
294
  )
295
295
 
296
296
  await new Promise<void>((r) => setTimeout(r, 50))
297
- expect(el.querySelector("div")).not.toBeNull()
298
- expect(el.querySelector("span")?.textContent).toBe("s-1")
297
+ expect(el.querySelector('div')).not.toBeNull()
298
+ expect(el.querySelector('span')?.textContent).toBe('s-1')
299
299
  })
300
300
 
301
- test("handles item additions", async () => {
301
+ test('handles item additions', async () => {
302
302
  const el = container()
303
303
  const items = signal([{ id: 1 }])
304
304
 
305
305
  mount(
306
306
  h(TransitionGroup, {
307
- tag: "div",
308
- name: "list",
307
+ tag: 'div',
308
+ name: 'list',
309
309
  items: () => items(),
310
310
  keyFn: (item: { id: number }) => item.id,
311
- render: (item: { id: number }) => h("span", null, `item-${item.id}`),
311
+ render: (item: { id: number }) => h('span', null, `item-${item.id}`),
312
312
  }),
313
313
  el,
314
314
  )
315
315
 
316
316
  await new Promise<void>((r) => setTimeout(r, 50))
317
- expect(el.querySelectorAll("span").length).toBe(1)
317
+ expect(el.querySelectorAll('span').length).toBe(1)
318
318
 
319
319
  items.set([{ id: 1 }, { id: 2 }])
320
320
  await new Promise<void>((r) => setTimeout(r, 50))
321
- expect(el.querySelectorAll("span").length).toBe(2)
321
+ expect(el.querySelectorAll('span').length).toBe(2)
322
322
  })
323
323
 
324
- test("handles item removals with leave animation", async () => {
324
+ test('handles item removals with leave animation', async () => {
325
325
  const el = container()
326
326
  const items = signal([{ id: 1 }, { id: 2 }])
327
327
 
328
328
  mount(
329
329
  h(TransitionGroup, {
330
- tag: "div",
331
- name: "list",
330
+ tag: 'div',
331
+ name: 'list',
332
332
  items: () => items(),
333
333
  keyFn: (item: { id: number }) => item.id,
334
- render: (item: { id: number }) => h("span", null, `item-${item.id}`),
334
+ render: (item: { id: number }) => h('span', null, `item-${item.id}`),
335
335
  }),
336
336
  el,
337
337
  )
338
338
 
339
339
  await new Promise<void>((r) => setTimeout(r, 50))
340
- expect(el.querySelectorAll("span").length).toBe(2)
340
+ expect(el.querySelectorAll('span').length).toBe(2)
341
341
 
342
342
  items.set([{ id: 1 }])
343
343
  await new Promise<void>((r) => setTimeout(r, 10))
344
344
 
345
345
  // The removed item gets leave animation classes.
346
346
  // After transitionend it would be removed. Simulate that.
347
- const spans = el.querySelectorAll("span")
347
+ const spans = el.querySelectorAll('span')
348
348
  for (const span of spans) {
349
- span.dispatchEvent(new Event("transitionend"))
349
+ span.dispatchEvent(new Event('transitionend'))
350
350
  }
351
351
  await new Promise<void>((r) => setTimeout(r, 50))
352
352
  })
353
353
 
354
- test("calls lifecycle callbacks on enter/leave", async () => {
354
+ test('calls lifecycle callbacks on enter/leave', async () => {
355
355
  const el = container()
356
356
  const items = signal([{ id: 1 }])
357
357
  const onBeforeEnter = vi.fn()
@@ -360,11 +360,11 @@ describe("TransitionGroup", () => {
360
360
 
361
361
  mount(
362
362
  h(TransitionGroup, {
363
- tag: "div",
364
- name: "list",
363
+ tag: 'div',
364
+ name: 'list',
365
365
  items: () => items(),
366
366
  keyFn: (item: { id: number }) => item.id,
367
- render: (item: { id: number }) => h("span", null, `item-${item.id}`),
367
+ render: (item: { id: number }) => h('span', null, `item-${item.id}`),
368
368
  onBeforeEnter,
369
369
  onAfterEnter,
370
370
  onBeforeLeave,
@@ -381,10 +381,10 @@ describe("TransitionGroup", () => {
381
381
  expect(onBeforeEnter).toHaveBeenCalled()
382
382
 
383
383
  // Trigger transitionend on the new item to fire onAfterEnter
384
- const spans = el.querySelectorAll("span")
384
+ const spans = el.querySelectorAll('span')
385
385
  const newSpan = spans[spans.length - 1]
386
386
  if (newSpan) {
387
- newSpan.dispatchEvent(new Event("transitionend"))
387
+ newSpan.dispatchEvent(new Event('transitionend'))
388
388
  await new Promise<void>((r) => setTimeout(r, 10))
389
389
  expect(onAfterEnter).toHaveBeenCalled()
390
390
  }
@@ -395,19 +395,19 @@ describe("TransitionGroup", () => {
395
395
  expect(onBeforeLeave).toHaveBeenCalled()
396
396
  })
397
397
 
398
- test("appear option animates items on initial mount", async () => {
398
+ test('appear option animates items on initial mount', async () => {
399
399
  const el = container()
400
400
  const items = signal([{ id: 1 }])
401
401
  const onBeforeEnter = vi.fn()
402
402
 
403
403
  mount(
404
404
  h(TransitionGroup, {
405
- tag: "div",
406
- name: "list",
405
+ tag: 'div',
406
+ name: 'list',
407
407
  appear: true,
408
408
  items: () => items(),
409
409
  keyFn: (item: { id: number }) => item.id,
410
- render: (item: { id: number }) => h("span", null, `item-${item.id}`),
410
+ render: (item: { id: number }) => h('span', null, `item-${item.id}`),
411
411
  onBeforeEnter,
412
412
  }),
413
413
  el,
@@ -417,51 +417,51 @@ describe("TransitionGroup", () => {
417
417
  expect(onBeforeEnter).toHaveBeenCalled()
418
418
  })
419
419
 
420
- test("supports custom class overrides", async () => {
420
+ test('supports custom class overrides', async () => {
421
421
  const el = container()
422
422
  const items = signal([{ id: 1 }])
423
423
 
424
424
  mount(
425
425
  h(TransitionGroup, {
426
- tag: "div",
426
+ tag: 'div',
427
427
  items: () => items(),
428
428
  keyFn: (item: { id: number }) => item.id,
429
- render: (item: { id: number }) => h("span", null, `item-${item.id}`),
430
- enterFrom: "custom-enter-from",
431
- enterActive: "custom-enter-active",
432
- enterTo: "custom-enter-to",
433
- leaveFrom: "custom-leave-from",
434
- leaveActive: "custom-leave-active",
435
- leaveTo: "custom-leave-to",
436
- moveClass: "custom-move",
429
+ render: (item: { id: number }) => h('span', null, `item-${item.id}`),
430
+ enterFrom: 'custom-enter-from',
431
+ enterActive: 'custom-enter-active',
432
+ enterTo: 'custom-enter-to',
433
+ leaveFrom: 'custom-leave-from',
434
+ leaveActive: 'custom-leave-active',
435
+ leaveTo: 'custom-leave-to',
436
+ moveClass: 'custom-move',
437
437
  }),
438
438
  el,
439
439
  )
440
440
 
441
441
  await new Promise<void>((r) => setTimeout(r, 50))
442
- expect(el.querySelector("span")).not.toBeNull()
442
+ expect(el.querySelector('span')).not.toBeNull()
443
443
  })
444
444
  })
445
445
 
446
446
  // ─── KeepAlive ───────────────────────────────────────────────────────────────
447
447
 
448
- describe("KeepAlive", () => {
449
- test("renders children when active is true", async () => {
448
+ describe('KeepAlive', () => {
449
+ test('renders children when active is true', async () => {
450
450
  const el = container()
451
451
  const active = signal(true)
452
452
 
453
- mount(h(KeepAlive, { active: () => active() }, h("span", { class: "kept" }, "alive")), el)
453
+ mount(h(KeepAlive, { active: () => active() }, h('span', { class: 'kept' }, 'alive')), el)
454
454
 
455
455
  await new Promise<void>((r) => setTimeout(r, 50))
456
- const kept = el.querySelector(".kept")
457
- expect(kept?.textContent).toBe("alive")
456
+ const kept = el.querySelector('.kept')
457
+ expect(kept?.textContent).toBe('alive')
458
458
  })
459
459
 
460
- test("hides children but keeps them mounted when active is false", async () => {
460
+ test('hides children but keeps them mounted when active is false', async () => {
461
461
  const el = container()
462
462
  const active = signal(true)
463
463
 
464
- mount(h(KeepAlive, { active: () => active() }, h("span", { class: "kept" }, "alive")), el)
464
+ mount(h(KeepAlive, { active: () => active() }, h('span', { class: 'kept' }, 'alive')), el)
465
465
 
466
466
  await new Promise<void>((r) => setTimeout(r, 50))
467
467
 
@@ -469,19 +469,19 @@ describe("KeepAlive", () => {
469
469
  await new Promise<void>((r) => setTimeout(r, 20))
470
470
 
471
471
  // The container div should have display: none, but the child should still be in DOM
472
- const wrapperDiv = el.querySelector("[style]") as HTMLElement
472
+ const wrapperDiv = el.querySelector('[style]') as HTMLElement
473
473
  if (wrapperDiv) {
474
- expect(wrapperDiv.style.display).toBe("none")
474
+ expect(wrapperDiv.style.display).toBe('none')
475
475
  }
476
476
  // Child should still exist in the DOM (kept alive)
477
- expect(el.querySelector(".kept")).not.toBeNull()
477
+ expect(el.querySelector('.kept')).not.toBeNull()
478
478
  })
479
479
 
480
- test("restores display when re-activated", async () => {
480
+ test('restores display when re-activated', async () => {
481
481
  const el = container()
482
482
  const active = signal(true)
483
483
 
484
- mount(h(KeepAlive, { active: () => active() }, h("span", { class: "kept" }, "alive")), el)
484
+ mount(h(KeepAlive, { active: () => active() }, h('span', { class: 'kept' }, 'alive')), el)
485
485
 
486
486
  await new Promise<void>((r) => setTimeout(r, 50))
487
487
  active.set(false)
@@ -490,32 +490,32 @@ describe("KeepAlive", () => {
490
490
  await new Promise<void>((r) => setTimeout(r, 20))
491
491
 
492
492
  // The container's display should be restored (empty string = visible)
493
- const wrapperDivs = el.querySelectorAll("div")
493
+ const wrapperDivs = el.querySelectorAll('div')
494
494
  let foundVisible = false
495
495
  for (const div of wrapperDivs) {
496
- if (div.style.display === "" || div.style.display === "contents") {
496
+ if (div.style.display === '' || div.style.display === 'contents') {
497
497
  foundVisible = true
498
498
  }
499
499
  }
500
500
  expect(foundVisible).toBe(true)
501
501
  })
502
502
 
503
- test("defaults to active=true when no active prop provided", async () => {
503
+ test('defaults to active=true when no active prop provided', async () => {
504
504
  const el = container()
505
505
 
506
- mount(h(KeepAlive, {}, h("span", { class: "default" }, "default")), el)
506
+ mount(h(KeepAlive, {}, h('span', { class: 'default' }, 'default')), el)
507
507
 
508
508
  await new Promise<void>((r) => setTimeout(r, 50))
509
- expect(el.querySelector(".default")?.textContent).toBe("default")
509
+ expect(el.querySelector('.default')?.textContent).toBe('default')
510
510
  })
511
511
 
512
- test("mounts children only once (not re-created on toggle)", async () => {
512
+ test('mounts children only once (not re-created on toggle)', async () => {
513
513
  const el = container()
514
514
  const active = signal(true)
515
515
  let mountCount = 0
516
516
  const Counter = () => {
517
517
  mountCount++
518
- return h("span", null, "counter")
518
+ return h('span', null, 'counter')
519
519
  }
520
520
 
521
521
  mount(h(KeepAlive, { active: () => active() }, h(Counter, null)), el)
@@ -532,17 +532,17 @@ describe("KeepAlive", () => {
532
532
  expect(mountCount).toBe(1)
533
533
  })
534
534
 
535
- test("uses display: contents wrapper for transparent layout", async () => {
535
+ test('uses display: contents wrapper for transparent layout', async () => {
536
536
  const el = container()
537
- mount(h(KeepAlive, {}, h("span", null, "child")), el)
537
+ mount(h(KeepAlive, {}, h('span', null, 'child')), el)
538
538
 
539
539
  await new Promise<void>((r) => setTimeout(r, 20))
540
540
  // KeepAlive renders a div with style="display: contents"
541
- const wrapper = el.querySelector("div")
541
+ const wrapper = el.querySelector('div')
542
542
  expect(wrapper).not.toBeNull()
543
543
  })
544
544
 
545
- test("handles null children gracefully", async () => {
545
+ test('handles null children gracefully', async () => {
546
546
  const el = container()
547
547
  expect(() => mount(h(KeepAlive, {}), el)).not.toThrow()
548
548
  await new Promise<void>((r) => setTimeout(r, 50))