@furystack/shades 11.1.0 → 12.0.1

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 (166) hide show
  1. package/CHANGELOG.md +312 -0
  2. package/README.md +13 -13
  3. package/esm/component-factory.spec.js +13 -5
  4. package/esm/component-factory.spec.js.map +1 -1
  5. package/esm/components/index.d.ts +4 -1
  6. package/esm/components/index.d.ts.map +1 -1
  7. package/esm/components/index.js +4 -1
  8. package/esm/components/index.js.map +1 -1
  9. package/esm/components/lazy-load.d.ts +2 -4
  10. package/esm/components/lazy-load.d.ts.map +1 -1
  11. package/esm/components/lazy-load.js +40 -24
  12. package/esm/components/lazy-load.js.map +1 -1
  13. package/esm/components/lazy-load.spec.js +57 -50
  14. package/esm/components/lazy-load.spec.js.map +1 -1
  15. package/esm/components/link-to-route.d.ts +2 -0
  16. package/esm/components/link-to-route.d.ts.map +1 -1
  17. package/esm/components/link-to-route.js +3 -2
  18. package/esm/components/link-to-route.js.map +1 -1
  19. package/esm/components/link-to-route.spec.js +13 -9
  20. package/esm/components/link-to-route.spec.js.map +1 -1
  21. package/esm/components/nested-route-link.d.ts +62 -0
  22. package/esm/components/nested-route-link.d.ts.map +1 -0
  23. package/esm/components/nested-route-link.js +66 -0
  24. package/esm/components/nested-route-link.js.map +1 -0
  25. package/esm/components/nested-route-link.spec.d.ts +2 -0
  26. package/esm/components/nested-route-link.spec.d.ts.map +1 -0
  27. package/esm/components/nested-route-link.spec.js +179 -0
  28. package/esm/components/nested-route-link.spec.js.map +1 -0
  29. package/esm/components/nested-route-types.d.ts +37 -0
  30. package/esm/components/nested-route-types.d.ts.map +1 -0
  31. package/esm/components/nested-route-types.js +2 -0
  32. package/esm/components/nested-route-types.js.map +1 -0
  33. package/esm/components/nested-router.d.ts +103 -0
  34. package/esm/components/nested-router.d.ts.map +1 -0
  35. package/esm/components/nested-router.js +183 -0
  36. package/esm/components/nested-router.js.map +1 -0
  37. package/esm/components/nested-router.spec.d.ts +2 -0
  38. package/esm/components/nested-router.spec.d.ts.map +1 -0
  39. package/esm/components/nested-router.spec.js +737 -0
  40. package/esm/components/nested-router.spec.js.map +1 -0
  41. package/esm/components/route-link.d.ts +4 -0
  42. package/esm/components/route-link.d.ts.map +1 -1
  43. package/esm/components/route-link.js +5 -5
  44. package/esm/components/route-link.js.map +1 -1
  45. package/esm/components/route-link.spec.js +16 -12
  46. package/esm/components/route-link.spec.js.map +1 -1
  47. package/esm/components/router.d.ts +20 -2
  48. package/esm/components/router.d.ts.map +1 -1
  49. package/esm/components/router.js +12 -7
  50. package/esm/components/router.js.map +1 -1
  51. package/esm/components/router.spec.js +141 -74
  52. package/esm/components/router.spec.js.map +1 -1
  53. package/esm/initialize.d.ts +11 -0
  54. package/esm/initialize.d.ts.map +1 -1
  55. package/esm/initialize.js +5 -0
  56. package/esm/initialize.js.map +1 -1
  57. package/esm/jsx.d.ts +83 -2
  58. package/esm/jsx.d.ts.map +1 -1
  59. package/esm/models/children-list.d.ts +5 -1
  60. package/esm/models/children-list.d.ts.map +1 -1
  61. package/esm/models/partial-element.d.ts +12 -2
  62. package/esm/models/partial-element.d.ts.map +1 -1
  63. package/esm/models/render-options.d.ts +89 -3
  64. package/esm/models/render-options.d.ts.map +1 -1
  65. package/esm/models/selection-state.d.ts +4 -0
  66. package/esm/models/selection-state.d.ts.map +1 -1
  67. package/esm/services/location-service.d.ts +11 -0
  68. package/esm/services/location-service.d.ts.map +1 -1
  69. package/esm/services/location-service.js +11 -0
  70. package/esm/services/location-service.js.map +1 -1
  71. package/esm/services/resource-manager.d.ts +24 -0
  72. package/esm/services/resource-manager.d.ts.map +1 -1
  73. package/esm/services/resource-manager.js +36 -1
  74. package/esm/services/resource-manager.js.map +1 -1
  75. package/esm/services/resource-manager.spec.js +102 -0
  76. package/esm/services/resource-manager.spec.js.map +1 -1
  77. package/esm/services/screen-service.d.ts +81 -4
  78. package/esm/services/screen-service.d.ts.map +1 -1
  79. package/esm/services/screen-service.js +75 -4
  80. package/esm/services/screen-service.js.map +1 -1
  81. package/esm/services/screen-service.spec.js +91 -7
  82. package/esm/services/screen-service.spec.js.map +1 -1
  83. package/esm/shade-component.d.ts +17 -4
  84. package/esm/shade-component.d.ts.map +1 -1
  85. package/esm/shade-component.js +67 -5
  86. package/esm/shade-component.js.map +1 -1
  87. package/esm/shade-host-props-ref.integration.spec.d.ts +2 -0
  88. package/esm/shade-host-props-ref.integration.spec.d.ts.map +1 -0
  89. package/esm/shade-host-props-ref.integration.spec.js +381 -0
  90. package/esm/shade-host-props-ref.integration.spec.js.map +1 -0
  91. package/esm/shade-resources.integration.spec.js +208 -39
  92. package/esm/shade-resources.integration.spec.js.map +1 -1
  93. package/esm/shade.d.ts +20 -17
  94. package/esm/shade.d.ts.map +1 -1
  95. package/esm/shade.js +172 -33
  96. package/esm/shade.js.map +1 -1
  97. package/esm/shade.spec.js +31 -30
  98. package/esm/shade.spec.js.map +1 -1
  99. package/esm/shades.integration.spec.js +135 -72
  100. package/esm/shades.integration.spec.js.map +1 -1
  101. package/esm/style-manager.d.ts +2 -2
  102. package/esm/style-manager.js +2 -2
  103. package/esm/svg-types.d.ts +389 -0
  104. package/esm/svg-types.d.ts.map +1 -0
  105. package/esm/svg-types.js +9 -0
  106. package/esm/svg-types.js.map +1 -0
  107. package/esm/svg.d.ts +15 -0
  108. package/esm/svg.d.ts.map +1 -0
  109. package/esm/svg.js +76 -0
  110. package/esm/svg.js.map +1 -0
  111. package/esm/svg.spec.d.ts +2 -0
  112. package/esm/svg.spec.d.ts.map +1 -0
  113. package/esm/svg.spec.js +80 -0
  114. package/esm/svg.spec.js.map +1 -0
  115. package/esm/vnode.d.ts +103 -0
  116. package/esm/vnode.d.ts.map +1 -0
  117. package/esm/vnode.integration.spec.d.ts +2 -0
  118. package/esm/vnode.integration.spec.d.ts.map +1 -0
  119. package/esm/vnode.integration.spec.js +494 -0
  120. package/esm/vnode.integration.spec.js.map +1 -0
  121. package/esm/vnode.js +453 -0
  122. package/esm/vnode.js.map +1 -0
  123. package/esm/vnode.spec.d.ts +2 -0
  124. package/esm/vnode.spec.d.ts.map +1 -0
  125. package/esm/vnode.spec.js +473 -0
  126. package/esm/vnode.spec.js.map +1 -0
  127. package/package.json +8 -9
  128. package/src/component-factory.spec.tsx +18 -5
  129. package/src/components/index.ts +4 -1
  130. package/src/components/lazy-load.spec.tsx +82 -75
  131. package/src/components/lazy-load.tsx +49 -27
  132. package/src/components/link-to-route.spec.tsx +25 -21
  133. package/src/components/link-to-route.tsx +4 -2
  134. package/src/components/nested-route-link.spec.tsx +303 -0
  135. package/src/components/nested-route-link.tsx +100 -0
  136. package/src/components/nested-route-types.ts +42 -0
  137. package/src/components/nested-router.spec.tsx +918 -0
  138. package/src/components/nested-router.tsx +260 -0
  139. package/src/components/route-link.spec.tsx +22 -18
  140. package/src/components/route-link.tsx +6 -5
  141. package/src/components/router.spec.tsx +196 -108
  142. package/src/components/router.tsx +21 -8
  143. package/src/initialize.ts +12 -0
  144. package/src/jsx.ts +129 -2
  145. package/src/models/children-list.ts +7 -1
  146. package/src/models/partial-element.ts +13 -2
  147. package/src/models/render-options.ts +90 -3
  148. package/src/models/selection-state.ts +4 -0
  149. package/src/services/location-service.tsx +11 -0
  150. package/src/services/resource-manager.spec.ts +128 -0
  151. package/src/services/resource-manager.ts +36 -1
  152. package/src/services/screen-service.spec.ts +109 -7
  153. package/src/services/screen-service.ts +81 -4
  154. package/src/shade-component.ts +72 -6
  155. package/src/shade-host-props-ref.integration.spec.tsx +460 -0
  156. package/src/shade-resources.integration.spec.tsx +276 -52
  157. package/src/shade.spec.tsx +40 -39
  158. package/src/shade.ts +186 -58
  159. package/src/shades.integration.spec.tsx +154 -80
  160. package/src/style-manager.ts +2 -2
  161. package/src/svg-types.ts +437 -0
  162. package/src/svg.spec.ts +89 -0
  163. package/src/svg.ts +78 -0
  164. package/src/vnode.integration.spec.tsx +657 -0
  165. package/src/vnode.spec.ts +579 -0
  166. package/src/vnode.ts +508 -0
@@ -4,7 +4,7 @@ import { sleepAsync, usingAsync } from '@furystack/utils'
4
4
  import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
5
5
  import { initializeShadeRoot } from './initialize.js'
6
6
  import { createComponent } from './shade-component.js'
7
- import { Shade } from './shade.js'
7
+ import { flushUpdates, Shade } from './shade.js'
8
8
 
9
9
  describe('Shades integration tests', () => {
10
10
  beforeEach(() => {
@@ -14,34 +14,38 @@ describe('Shades integration tests', () => {
14
14
  document.body.innerHTML = ''
15
15
  })
16
16
 
17
- it('Should mount a custom component to a Shade root', () => {
18
- const injector = new Injector()
19
- const rootElement = document.getElementById('root') as HTMLDivElement
17
+ it('Should mount a custom component to a Shade root', async () => {
18
+ await usingAsync(new Injector(), async (injector) => {
19
+ const rootElement = document.getElementById('root') as HTMLDivElement
20
20
 
21
- const ExampleComponent = Shade({ render: () => <div>Hello</div>, shadowDomName: 'shades-example' })
21
+ const ExampleComponent = Shade({ render: () => <div>Hello</div>, shadowDomName: 'shades-example' })
22
22
 
23
- initializeShadeRoot({
24
- injector,
25
- rootElement,
26
- jsxElement: <ExampleComponent />,
23
+ initializeShadeRoot({
24
+ injector,
25
+ rootElement,
26
+ jsxElement: <ExampleComponent />,
27
+ })
28
+ await flushUpdates()
29
+ expect(document.body.innerHTML).toBe('<div id="root"><shades-example><div>Hello</div></shades-example></div>')
27
30
  })
28
- expect(document.body.innerHTML).toBe('<div id="root"><shades-example><div>Hello</div></shades-example></div>')
29
31
  })
30
32
 
31
- it('Should mount a custom component with a string render result', () => {
32
- const injector = new Injector()
33
- const rootElement = document.getElementById('root') as HTMLDivElement
33
+ it('Should mount a custom component with a string render result', async () => {
34
+ await usingAsync(new Injector(), async (injector) => {
35
+ const rootElement = document.getElementById('root') as HTMLDivElement
34
36
 
35
- const ExampleComponent = Shade({ render: () => 'Hello', shadowDomName: 'shades-string-render-result' })
37
+ const ExampleComponent = Shade({ render: () => 'Hello', shadowDomName: 'shades-string-render-result' })
36
38
 
37
- initializeShadeRoot({
38
- injector,
39
- rootElement,
40
- jsxElement: <ExampleComponent />,
39
+ initializeShadeRoot({
40
+ injector,
41
+ rootElement,
42
+ jsxElement: <ExampleComponent />,
43
+ })
44
+ await flushUpdates()
45
+ expect(document.body.innerHTML).toBe(
46
+ '<div id="root"><shades-string-render-result>Hello</shades-string-render-result></div>',
47
+ )
41
48
  })
42
- expect(document.body.innerHTML).toBe(
43
- '<div id="root"><shades-string-render-result>Hello</shades-string-render-result></div>',
44
- )
45
49
  })
46
50
 
47
51
  it('Should mount a custom component with null render result', async () => {
@@ -55,6 +59,7 @@ describe('Shades integration tests', () => {
55
59
  rootElement,
56
60
  jsxElement: <ExampleComponent />,
57
61
  })
62
+ await flushUpdates()
58
63
  expect(document.body.innerHTML).toBe(
59
64
  '<div id="root"><shades-null-render-result></shades-null-render-result></div>',
60
65
  )
@@ -80,6 +85,7 @@ describe('Shades integration tests', () => {
80
85
  rootElement,
81
86
  jsxElement: <ExampleComponent />,
82
87
  })
88
+ await flushUpdates()
83
89
  expect(document.body.innerHTML).toBe(
84
90
  '<div id="root"><shades-fragment-render-result><p>1</p><p>2</p></shades-fragment-render-result></div>',
85
91
  )
@@ -107,6 +113,7 @@ describe('Shades integration tests', () => {
107
113
  rootElement,
108
114
  jsxElement: <ExampleComponent />,
109
115
  })
116
+ await flushUpdates()
110
117
  expect(document.body.innerHTML).toBe(
111
118
  '<div id="root"><shades-fragment-render-result-nested><p><p>1</p><p>2</p></p></shades-fragment-render-result-nested></div>',
112
119
  )
@@ -137,6 +144,7 @@ describe('Shades integration tests', () => {
137
144
  rootElement,
138
145
  jsxElement: <ExampleComponent />,
139
146
  })
147
+ await flushUpdates()
140
148
  expect(document.body.innerHTML).toBe(
141
149
  '<div id="root"><shades-fragment-render-result-2><shades-fragment-test-custom-component><p>Hello</p></shades-fragment-test-custom-component><shades-fragment-test-custom-component><p>Hello</p></shades-fragment-test-custom-component></shades-fragment-render-result-2></div>',
142
150
  )
@@ -168,22 +176,28 @@ describe('Shades integration tests', () => {
168
176
  </ExampleComponent>
169
177
  ),
170
178
  })
179
+ await flushUpdates()
171
180
  expect(document.body.innerHTML).toBe(
172
181
  '<div id="root"><shades-example-2><div><shades-example-sub><div>1</div></shades-example-sub><shades-example-sub><div>2</div></shades-example-sub><shades-example-sub><div>3</div></shades-example-sub></div></shades-example-2></div>',
173
182
  )
174
183
  })
175
184
  })
176
185
 
177
- it("Should execute the constructed and constructed's cleanup callback", async () => {
186
+ it('Should execute useDisposable cleanup on component disconnection', async () => {
178
187
  await usingAsync(new Injector(), async (injector) => {
179
188
  const rootElement = document.getElementById('root') as HTMLDivElement
180
189
  const cleanup = vi.fn()
181
- const constructed = vi.fn(() => cleanup)
190
+ const setup = vi.fn()
182
191
 
183
192
  const ExampleComponent = Shade({
184
- constructed,
185
193
  shadowDomName: 'example-component-1',
186
- render: () => <div>Hello</div>,
194
+ render: ({ useDisposable }) => {
195
+ useDisposable('test', () => {
196
+ setup()
197
+ return { [Symbol.dispose]: cleanup }
198
+ })
199
+ return <div>Hello</div>
200
+ },
187
201
  })
188
202
 
189
203
  initializeShadeRoot({
@@ -191,7 +205,8 @@ describe('Shades integration tests', () => {
191
205
  rootElement,
192
206
  jsxElement: <ExampleComponent />,
193
207
  })
194
- expect(constructed).toBeCalled()
208
+ await flushUpdates()
209
+ expect(setup).toBeCalled()
195
210
  expect(cleanup).not.toBeCalled()
196
211
  document.body.innerHTML = ''
197
212
  await sleepAsync(10) // Dispose can be async
@@ -199,31 +214,6 @@ describe('Shades integration tests', () => {
199
214
  })
200
215
  })
201
216
 
202
- it('Should execute the onAttach and onDetach callbacks', async () => {
203
- await usingAsync(new Injector(), async (injector) => {
204
- const rootElement = document.getElementById('root') as HTMLDivElement
205
- const onAttach = vi.fn()
206
- const onDetach = vi.fn()
207
-
208
- const ExampleComponent = Shade({
209
- onAttach,
210
- onDetach,
211
- shadowDomName: 'example-component-2',
212
- render: () => <div>Hello</div>,
213
- })
214
-
215
- initializeShadeRoot({
216
- injector,
217
- rootElement,
218
- jsxElement: <ExampleComponent />,
219
- })
220
- expect(onAttach).toBeCalled()
221
- expect(onDetach).not.toBeCalled()
222
- document.body.innerHTML = ''
223
- expect(onDetach).toBeCalled()
224
- })
225
- })
226
-
227
217
  it('Should update state', async () => {
228
218
  await usingAsync(new Injector(), async (injector) => {
229
219
  const rootElement = document.getElementById('root') as HTMLDivElement
@@ -250,19 +240,26 @@ describe('Shades integration tests', () => {
250
240
  rootElement,
251
241
  jsxElement: <ExampleComponent />,
252
242
  })
253
-
254
- const plus = () => document.getElementById('plus')?.click()
255
- const minus = () => document.getElementById('minus')?.click()
243
+ await flushUpdates()
244
+
245
+ const plus = async () => {
246
+ document.getElementById('plus')?.click()
247
+ await flushUpdates()
248
+ }
249
+ const minus = async () => {
250
+ document.getElementById('minus')?.click()
251
+ await flushUpdates()
252
+ }
256
253
  const expectCount = (count: number) => expect(document.body.innerHTML).toContain(`Count is ${count}`)
257
254
 
258
255
  expectCount(0)
259
- plus()
256
+ await plus()
260
257
  expectCount(1)
261
- plus()
258
+ await plus()
262
259
  expectCount(2)
263
260
 
264
- minus()
265
- minus()
261
+ await minus()
262
+ await minus()
266
263
  expectCount(0)
267
264
  })
268
265
  })
@@ -314,9 +311,16 @@ describe('Shades integration tests', () => {
314
311
  rootElement,
315
312
  jsxElement: <ExampleComponent />,
316
313
  })
317
-
318
- const plus = () => document.getElementById('plus')?.click()
319
- const minus = () => document.getElementById('minus')?.click()
314
+ await flushUpdates()
315
+
316
+ const plus = async () => {
317
+ document.getElementById('plus')?.click()
318
+ await flushUpdates()
319
+ }
320
+ const minus = async () => {
321
+ document.getElementById('minus')?.click()
322
+ await flushUpdates()
323
+ }
320
324
  const expectCount = (count: number) => expect(document.body.innerHTML).toContain(`Count is ${count}`)
321
325
 
322
326
  await sleepAsync(100)
@@ -324,16 +328,16 @@ describe('Shades integration tests', () => {
324
328
  expectCount(0)
325
329
 
326
330
  await sleepAsync(100)
327
- plus()
331
+ await plus()
328
332
  expectCount(1)
329
333
  expect(store.getItem('count')).toBe('1')
330
334
 
331
- plus()
335
+ await plus()
332
336
  expectCount(2)
333
337
  expect(store.getItem('count')).toBe('2')
334
338
 
335
- minus()
336
- minus()
339
+ await minus()
340
+ await minus()
337
341
  expectCount(0)
338
342
  expect(store.getItem('count')).toBe('0')
339
343
  })
@@ -365,24 +369,31 @@ describe('Shades integration tests', () => {
365
369
  rootElement,
366
370
  jsxElement: <ExampleComponent />,
367
371
  })
368
-
369
- const plus = () => document.getElementById('plus')?.click()
370
- const minus = () => document.getElementById('minus')?.click()
372
+ await flushUpdates()
373
+
374
+ const plus = async () => {
375
+ document.getElementById('plus')?.click()
376
+ await flushUpdates()
377
+ }
378
+ const minus = async () => {
379
+ document.getElementById('minus')?.click()
380
+ await flushUpdates()
381
+ }
371
382
  const expectCount = (count: number) => expect(document.body.innerHTML).toContain(`Count is ${count}`)
372
383
 
373
384
  expectCount(0)
374
385
 
375
386
  await sleepAsync(100)
376
- plus()
387
+ await plus()
377
388
  expectCount(1)
378
389
  expect(location.search).toBe(`?${serializeToQueryString({ count: 1 })}`)
379
390
 
380
- plus()
391
+ await plus()
381
392
  expectCount(2)
382
393
  expect(location.search).toBe(`?${serializeToQueryString({ count: 2 })}`)
383
394
 
384
- minus()
385
- minus()
395
+ await minus()
396
+ await minus()
386
397
  expectCount(0)
387
398
  expect(location.search).toBe(`?${serializeToQueryString({ count: 0 })}`)
388
399
  })
@@ -439,31 +450,94 @@ describe('Shades integration tests', () => {
439
450
  </Parent>
440
451
  ),
441
452
  })
453
+ await flushUpdates()
442
454
 
443
- const plus = () => document.getElementById('plus')?.click()
444
- const minus = () => document.getElementById('minus')?.click()
455
+ const plus = async () => {
456
+ document.getElementById('plus')?.click()
457
+ await flushUpdates()
458
+ }
459
+ const minus = async () => {
460
+ document.getElementById('minus')?.click()
461
+ await flushUpdates()
462
+ }
445
463
 
446
464
  const expectCount = (count: number) => expect(document.body.innerHTML).toContain(`Count is ${count}`)
447
- const toggleChildren = () => document.getElementById('showHideChildren')?.click()
465
+ const toggleChildren = async () => {
466
+ document.getElementById('showHideChildren')?.click()
467
+ await flushUpdates()
468
+ }
448
469
 
449
470
  expectCount(0)
450
- plus()
471
+ await plus()
451
472
  expectCount(1)
452
473
 
453
- toggleChildren()
474
+ await toggleChildren()
454
475
 
455
476
  expect(document.getElementById('plus')).toBeNull()
456
477
 
457
478
  await sleepAsync(10) // Dispose can be async
458
479
 
459
- toggleChildren()
480
+ await toggleChildren()
460
481
  expect(document.getElementById('plus')).toBeDefined()
461
482
 
462
483
  expectCount(0)
463
- plus()
484
+ await plus()
464
485
  expectCount(1)
465
- minus()
486
+ await minus()
466
487
  expectCount(0)
467
488
  })
468
489
  })
490
+
491
+ it('Should propagate changed props from parent to child Shade component', async () => {
492
+ await usingAsync(new Injector(), async (injector) => {
493
+ const rootElement = document.getElementById('root') as HTMLDivElement
494
+
495
+ const ChildComponent = Shade<{ isDisabled: boolean }>({
496
+ shadowDomName: 'shade-prop-child',
497
+ render: ({ props }) => {
498
+ return <input type="checkbox" disabled={props.isDisabled} data-testid="inner-input" />
499
+ },
500
+ })
501
+
502
+ const ParentComponent = Shade({
503
+ shadowDomName: 'shade-prop-parent',
504
+ render: ({ useState }) => {
505
+ const [isDisabled, setIsDisabled] = useState('isDisabled', false)
506
+ return (
507
+ <div>
508
+ <button id="toggle-disabled" onclick={() => setIsDisabled(!isDisabled)}>
509
+ Toggle
510
+ </button>
511
+ <ChildComponent isDisabled={isDisabled} />
512
+ </div>
513
+ )
514
+ },
515
+ })
516
+
517
+ initializeShadeRoot({
518
+ injector,
519
+ rootElement,
520
+ jsxElement: <ParentComponent />,
521
+ })
522
+
523
+ await flushUpdates()
524
+ await flushUpdates()
525
+
526
+ const innerInput = document.querySelector('[data-testid="inner-input"]') as HTMLInputElement
527
+ expect(innerInput).toBeTruthy()
528
+ expect(innerInput.disabled).toBe(false)
529
+
530
+ // Click the toggle button
531
+ const toggleBtn = document.getElementById('toggle-disabled') as HTMLButtonElement
532
+ toggleBtn.click()
533
+
534
+ // Wait for parent re-render + child re-render (two microtask levels)
535
+ await flushUpdates()
536
+ await flushUpdates()
537
+ await flushUpdates()
538
+
539
+ const updatedInput = document.querySelector('[data-testid="inner-input"]') as HTMLInputElement
540
+ expect(updatedInput.disabled).toBe(true)
541
+ })
542
+ })
469
543
  })
@@ -25,9 +25,9 @@ class StyleManagerClass {
25
25
 
26
26
  /**
27
27
  * Registers CSS styles for a component.
28
- * Styles are only injected once per component (based on shadowDomName).
28
+ * Styles are only injected once per component (based on the custom element name).
29
29
  *
30
- * @param shadowDomName - The unique component identifier (used as CSS selector)
30
+ * @param shadowDomName - The custom element tag name (used as CSS selector)
31
31
  * @param cssObject - The CSSObject containing styles and nested selectors
32
32
  * @param elementBaseName - Optional base element name for customized built-in elements (e.g., 'a', 'button').
33
33
  * When provided, generates selector like `a[is="component-name"]` instead of `component-name`