kempo-ui 0.3.14 → 0.3.16

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 (82) hide show
  1. package/dist/components/Combobox.js +97 -0
  2. package/dist/components/Option.js +1 -0
  3. package/dist/components/ThemeSwitcher.js +77 -14
  4. package/docs/components/accordion.html +282 -94
  5. package/docs/components/aside.html +282 -94
  6. package/docs/components/card.html +282 -94
  7. package/docs/components/code-editor.html +282 -94
  8. package/docs/components/color-picker.html +282 -94
  9. package/docs/components/combobox.html +798 -0
  10. package/docs/components/content-slider.html +282 -94
  11. package/docs/components/context.html +282 -94
  12. package/docs/components/dialog.html +282 -94
  13. package/docs/components/dropdown.html +282 -94
  14. package/docs/components/filter-list.html +282 -94
  15. package/docs/components/focus-capture.html +282 -94
  16. package/docs/components/html-editor.html +282 -94
  17. package/docs/components/hybrid-component.html +282 -94
  18. package/docs/components/icon.html +282 -94
  19. package/docs/components/import.html +282 -94
  20. package/docs/components/light-component.html +282 -94
  21. package/docs/components/nav-spacer.html +282 -94
  22. package/docs/components/nav.html +282 -94
  23. package/docs/components/photo-viewer.html +282 -94
  24. package/docs/components/resize.html +282 -94
  25. package/docs/components/shadow-component.html +282 -94
  26. package/docs/components/show-more.html +282 -94
  27. package/docs/components/sortable.html +282 -94
  28. package/docs/components/spinner.html +282 -94
  29. package/docs/components/split.html +282 -94
  30. package/docs/components/table.html +282 -94
  31. package/docs/components/tableControls.html +282 -94
  32. package/docs/components/tableCustomFields.html +282 -94
  33. package/docs/components/tableFetchRecords.html +282 -94
  34. package/docs/components/tableFieldSortHide.html +282 -94
  35. package/docs/components/tablePagination.html +282 -94
  36. package/docs/components/tablePlaceholder.html +282 -94
  37. package/docs/components/tableRecordEditing.html +282 -94
  38. package/docs/components/tableRecordFiltering.html +282 -94
  39. package/docs/components/tableRecordHiding.html +282 -94
  40. package/docs/components/tableRecordSearching.html +282 -94
  41. package/docs/components/tableRecordSelection.html +282 -94
  42. package/docs/components/tableRowControls.html +282 -94
  43. package/docs/components/tableServerSync.html +282 -94
  44. package/docs/components/tableSorting.html +282 -94
  45. package/docs/components/tabs.html +282 -94
  46. package/docs/components/tags.html +282 -94
  47. package/docs/components/theme-select.html +282 -94
  48. package/docs/components/theme-switcher-aside.html +47 -0
  49. package/docs/components/theme-switcher.html +441 -101
  50. package/docs/components/timestamp.html +282 -94
  51. package/docs/components/toast.html +282 -94
  52. package/docs/components/toggle.html +282 -94
  53. package/docs/components/tree.html +282 -94
  54. package/docs/index.html +288 -94
  55. package/docs/src/components/Combobox.js +97 -0
  56. package/docs/src/components/Option.js +1 -0
  57. package/docs/src/components/ThemeSwitcher.js +77 -14
  58. package/docs/utils/context.html +282 -94
  59. package/docs/utils/cookie.html +282 -94
  60. package/docs/utils/debounce.html +282 -94
  61. package/docs/utils/drag.html +282 -94
  62. package/docs/utils/elevation.html +282 -94
  63. package/docs/utils/formatTimestamp.html +282 -94
  64. package/docs/utils/object.html +282 -94
  65. package/docs/utils/propConverters.html +282 -94
  66. package/docs/utils/string.html +282 -94
  67. package/docs/utils/theme.html +282 -94
  68. package/docs/utils/toTitleCase.html +282 -94
  69. package/docs/utils/type.html +282 -94
  70. package/docs/utils/wait.html +282 -94
  71. package/docs-src/components/combobox.page.html +358 -0
  72. package/docs-src/components/theme-switcher-aside.page.html +35 -0
  73. package/docs-src/components/theme-switcher.page.html +159 -7
  74. package/docs-src/index.page.html +6 -0
  75. package/docs-src/nav.fragment.html +283 -95
  76. package/llms.txt +2 -1
  77. package/package.json +1 -1
  78. package/src/components/Combobox.js +338 -0
  79. package/src/components/Option.js +19 -0
  80. package/src/components/ThemeSwitcher.js +171 -24
  81. package/tests/components/Combobox.browser-test.js +790 -0
  82. package/tests/components/ThemeSwitcher.browser-test.js +361 -33
@@ -1,9 +1,9 @@
1
1
  import ThemeSwitcher from '../../src/components/ThemeSwitcher.js';
2
2
  import theme from '../../src/utils/theme.js';
3
3
 
4
- const createThemeSwitcher = async () => {
4
+ const createThemeSwitcher = async (attrs = '') => {
5
5
  const container = document.createElement('div');
6
- container.innerHTML = `<k-theme-switcher></k-theme-switcher>`;
6
+ container.innerHTML = `<k-theme-switcher ${attrs}></k-theme-switcher>`;
7
7
  document.body.appendChild(container);
8
8
 
9
9
  const switcher = container.querySelector('k-theme-switcher');
@@ -16,7 +16,6 @@ const cleanup = (container) => {
16
16
  if(container && container.parentNode){
17
17
  container.parentNode.removeChild(container);
18
18
  }
19
- // Reset theme to auto after each test
20
19
  theme.set('auto');
21
20
  };
22
21
 
@@ -111,6 +110,80 @@ export default {
111
110
  pass('ThemeSwitcher renders k-icon');
112
111
  },
113
112
 
113
+ 'should default to segmented mode': async ({pass, fail}) => {
114
+ const { container, switcher } = await createThemeSwitcher();
115
+
116
+ const segmented = switcher.shadowRoot.querySelector('.segmented');
117
+ if(!segmented){
118
+ cleanup(container);
119
+ fail('Default mode should render segmented control');
120
+ return;
121
+ }
122
+
123
+ cleanup(container);
124
+ pass('Default mode renders segmented control');
125
+ },
126
+
127
+ 'segmented should render 3 buttons by default': async ({pass, fail}) => {
128
+ const { container, switcher } = await createThemeSwitcher();
129
+
130
+ const buttons = switcher.shadowRoot.querySelectorAll('.segmented button');
131
+ if(buttons.length !== 3){
132
+ cleanup(container);
133
+ fail(`Expected 3 buttons, got ${buttons.length}`);
134
+ return;
135
+ }
136
+
137
+ cleanup(container);
138
+ pass('Segmented renders 3 buttons by default');
139
+ },
140
+
141
+ 'segmented should highlight active theme': async ({pass, fail}) => {
142
+ const { container, switcher } = await createThemeSwitcher();
143
+
144
+ theme.set('light');
145
+ await new Promise(r => setTimeout(r, 50));
146
+ await switcher.updateComplete;
147
+
148
+ const active = switcher.shadowRoot.querySelector('.segmented button.active');
149
+ if(!active){
150
+ cleanup(container);
151
+ fail('Segmented should have an active button');
152
+ return;
153
+ }
154
+
155
+ const icon = active.querySelector('k-icon');
156
+ if(icon.getAttribute('name') !== 'mode-light'){
157
+ cleanup(container);
158
+ fail(`Expected active icon "mode-light", got "${icon.getAttribute('name')}"`);
159
+ return;
160
+ }
161
+
162
+ cleanup(container);
163
+ pass('Segmented highlights active theme');
164
+ },
165
+
166
+ 'segmented button click should set theme': async ({pass, fail}) => {
167
+ const { container, switcher } = await createThemeSwitcher();
168
+
169
+ theme.set('auto');
170
+ await new Promise(r => setTimeout(r, 50));
171
+ await switcher.updateComplete;
172
+
173
+ const buttons = switcher.shadowRoot.querySelectorAll('.segmented button');
174
+ buttons[2].click();
175
+ await new Promise(r => setTimeout(r, 50));
176
+
177
+ if(theme.get() !== 'dark'){
178
+ cleanup(container);
179
+ fail(`Expected theme "dark", got "${theme.get()}"`);
180
+ return;
181
+ }
182
+
183
+ cleanup(container);
184
+ pass('Segmented button click sets theme');
185
+ },
186
+
114
187
  'should have inline display': async ({pass, fail}) => {
115
188
  const { container, switcher } = await createThemeSwitcher();
116
189
 
@@ -127,30 +200,30 @@ export default {
127
200
  pass('ThemeSwitcher has correct display');
128
201
  },
129
202
 
130
- 'should cycle theme on click: auto to light': async ({pass, fail}) => {
131
- const { container, switcher } = await createThemeSwitcher();
203
+ 'should cycle theme on click in toggle mode: light to auto': async ({pass, fail}) => {
204
+ const { container, switcher } = await createThemeSwitcher('mode="toggle"');
132
205
 
133
- theme.set('auto');
206
+ theme.set('light');
134
207
  await switcher.updateComplete;
135
208
 
136
209
  const button = switcher.shadowRoot.querySelector('button');
137
210
  button.click();
138
211
  await switcher.updateComplete;
139
212
 
140
- if(theme.get() !== 'light'){
213
+ if(theme.get() !== 'auto'){
141
214
  cleanup(container);
142
- fail(`Expected theme "light", got "${theme.get()}"`);
215
+ fail(`Expected theme "auto", got "${theme.get()}"`);
143
216
  return;
144
217
  }
145
218
 
146
219
  cleanup(container);
147
- pass('Theme cycles from auto to light');
220
+ pass('Theme cycles from light to auto');
148
221
  },
149
222
 
150
- 'should cycle theme on click: light to dark': async ({pass, fail}) => {
151
- const { container, switcher } = await createThemeSwitcher();
223
+ 'should cycle theme on click in toggle mode: auto to dark': async ({pass, fail}) => {
224
+ const { container, switcher } = await createThemeSwitcher('mode="toggle"');
152
225
 
153
- theme.set('light');
226
+ theme.set('auto');
154
227
  await switcher.updateComplete;
155
228
 
156
229
  const button = switcher.shadowRoot.querySelector('button');
@@ -164,11 +237,11 @@ export default {
164
237
  }
165
238
 
166
239
  cleanup(container);
167
- pass('Theme cycles from light to dark');
240
+ pass('Theme cycles from auto to dark');
168
241
  },
169
242
 
170
- 'should cycle theme on click: dark to auto': async ({pass, fail}) => {
171
- const { container, switcher } = await createThemeSwitcher();
243
+ 'should cycle theme on click in toggle mode: dark to light': async ({pass, fail}) => {
244
+ const { container, switcher } = await createThemeSwitcher('mode="toggle"');
172
245
 
173
246
  theme.set('dark');
174
247
  await switcher.updateComplete;
@@ -177,14 +250,14 @@ export default {
177
250
  button.click();
178
251
  await switcher.updateComplete;
179
252
 
180
- if(theme.get() !== 'auto'){
253
+ if(theme.get() !== 'light'){
181
254
  cleanup(container);
182
- fail(`Expected theme "auto", got "${theme.get()}"`);
255
+ fail(`Expected theme "light", got "${theme.get()}"`);
183
256
  return;
184
257
  }
185
258
 
186
259
  cleanup(container);
187
- pass('Theme cycles from dark to auto');
260
+ pass('Theme cycles from dark to light');
188
261
  },
189
262
 
190
263
  'should update currentTheme when theme changes': async ({pass, fail}) => {
@@ -204,17 +277,17 @@ export default {
204
277
  pass('currentTheme updates when theme changes');
205
278
  },
206
279
 
207
- 'should show mode-auto icon when auto': async ({pass, fail}) => {
208
- const { container, switcher } = await createThemeSwitcher();
280
+ 'should show mode-auto icon in toggle mode when auto': async ({pass, fail}) => {
281
+ const { container, switcher } = await createThemeSwitcher('mode="toggle"');
209
282
 
210
283
  theme.set('auto');
211
284
  await new Promise(r => setTimeout(r, 50));
212
285
  await switcher.updateComplete;
213
286
 
214
287
  const icon = switcher.shadowRoot.querySelector('k-icon');
215
- if(icon.name !== 'mode-auto'){
288
+ if(icon.getAttribute('name') !== 'mode-auto'){
216
289
  cleanup(container);
217
- fail(`Expected icon name "mode-auto", got "${icon.name}"`);
290
+ fail(`Expected icon name "mode-auto", got "${icon.getAttribute('name')}"`);
218
291
  return;
219
292
  }
220
293
 
@@ -222,17 +295,17 @@ export default {
222
295
  pass('Shows mode-auto icon when auto');
223
296
  },
224
297
 
225
- 'should show mode-light icon when light': async ({pass, fail}) => {
226
- const { container, switcher } = await createThemeSwitcher();
298
+ 'should show mode-light icon in toggle mode when light': async ({pass, fail}) => {
299
+ const { container, switcher } = await createThemeSwitcher('mode="toggle"');
227
300
 
228
301
  theme.set('light');
229
302
  await new Promise(r => setTimeout(r, 50));
230
303
  await switcher.updateComplete;
231
304
 
232
305
  const icon = switcher.shadowRoot.querySelector('k-icon');
233
- if(icon.name !== 'mode-light'){
306
+ if(icon.getAttribute('name') !== 'mode-light'){
234
307
  cleanup(container);
235
- fail(`Expected icon name "mode-light", got "${icon.name}"`);
308
+ fail(`Expected icon name "mode-light", got "${icon.getAttribute('name')}"`);
236
309
  return;
237
310
  }
238
311
 
@@ -240,17 +313,17 @@ export default {
240
313
  pass('Shows mode-light icon when light');
241
314
  },
242
315
 
243
- 'should show mode-dark icon when dark': async ({pass, fail}) => {
244
- const { container, switcher } = await createThemeSwitcher();
316
+ 'should show mode-dark icon in toggle mode when dark': async ({pass, fail}) => {
317
+ const { container, switcher } = await createThemeSwitcher('mode="toggle"');
245
318
 
246
319
  theme.set('dark');
247
320
  await new Promise(r => setTimeout(r, 50));
248
321
  await switcher.updateComplete;
249
322
 
250
323
  const icon = switcher.shadowRoot.querySelector('k-icon');
251
- if(icon.name !== 'mode-dark'){
324
+ if(icon.getAttribute('name') !== 'mode-dark'){
252
325
  cleanup(container);
253
- fail(`Expected icon name "mode-dark", got "${icon.name}"`);
326
+ fail(`Expected icon name "mode-dark", got "${icon.getAttribute('name')}"`);
254
327
  return;
255
328
  }
256
329
 
@@ -379,8 +452,8 @@ export default {
379
452
  pass('ThemeSwitcher unsubscribes on disconnect');
380
453
  },
381
454
 
382
- 'button should have no-btn class': async ({pass, fail}) => {
383
- const { container, switcher } = await createThemeSwitcher();
455
+ 'toggle button should have no-btn class': async ({pass, fail}) => {
456
+ const { container, switcher } = await createThemeSwitcher('mode="toggle"');
384
457
 
385
458
  const button = switcher.shadowRoot.querySelector('button');
386
459
  if(!button.classList.contains('no-btn')){
@@ -396,7 +469,6 @@ export default {
396
469
  'should sync with external theme changes': async ({pass, fail}) => {
397
470
  const { container, switcher } = await createThemeSwitcher();
398
471
 
399
- // Change theme externally
400
472
  theme.set('dark');
401
473
  await new Promise(r => setTimeout(r, 50));
402
474
  await switcher.updateComplete;
@@ -409,5 +481,261 @@ export default {
409
481
 
410
482
  cleanup(container);
411
483
  pass('ThemeSwitcher syncs with external theme changes');
484
+ },
485
+
486
+ /*
487
+ Mode Property Tests
488
+ */
489
+ 'should have mode property defaulting to auto': async ({pass, fail}) => {
490
+ const { container, switcher } = await createThemeSwitcher();
491
+
492
+ if(switcher.mode !== 'auto'){
493
+ cleanup(container);
494
+ fail(`Expected mode "auto", got "${switcher.mode}"`);
495
+ return;
496
+ }
497
+
498
+ cleanup(container);
499
+ pass('Mode defaults to auto');
500
+ },
501
+
502
+ 'should render toggle mode when mode=toggle': async ({pass, fail}) => {
503
+ const { container, switcher } = await createThemeSwitcher('mode="toggle"');
504
+
505
+ const segmented = switcher.shadowRoot.querySelector('.segmented');
506
+ const button = switcher.shadowRoot.querySelector('button.no-btn');
507
+ if(segmented){
508
+ cleanup(container);
509
+ fail('Toggle mode should not render segmented control');
510
+ return;
511
+ }
512
+ if(!button){
513
+ cleanup(container);
514
+ fail('Toggle mode should render a single no-btn button');
515
+ return;
516
+ }
517
+
518
+ cleanup(container);
519
+ pass('Toggle mode renders correctly');
520
+ },
521
+
522
+ 'should render segmented mode when mode=segmented': async ({pass, fail}) => {
523
+ const { container, switcher } = await createThemeSwitcher('mode="segmented"');
524
+
525
+ const segmented = switcher.shadowRoot.querySelector('.segmented');
526
+ if(!segmented){
527
+ cleanup(container);
528
+ fail('Segmented mode should render segmented control');
529
+ return;
530
+ }
531
+
532
+ cleanup(container);
533
+ pass('Segmented mode renders correctly');
534
+ },
535
+
536
+ /*
537
+ Options Property Tests
538
+ */
539
+ 'should have options property defaulting to light, auto, dark': async ({pass, fail}) => {
540
+ const { container, switcher } = await createThemeSwitcher();
541
+
542
+ if(switcher.options !== 'light, auto, dark'){
543
+ cleanup(container);
544
+ fail(`Expected options "light, auto, dark", got "${switcher.options}"`);
545
+ return;
546
+ }
547
+
548
+ cleanup(container);
549
+ pass('Options defaults to "light, auto, dark"');
550
+ },
551
+
552
+ 'custom options should limit segmented buttons': async ({pass, fail}) => {
553
+ const { container, switcher } = await createThemeSwitcher('options="dark, light"');
554
+
555
+ const buttons = switcher.shadowRoot.querySelectorAll('.segmented button');
556
+ if(buttons.length !== 2){
557
+ cleanup(container);
558
+ fail(`Expected 2 buttons, got ${buttons.length}`);
559
+ return;
560
+ }
561
+
562
+ cleanup(container);
563
+ pass('Custom options limits segmented buttons');
564
+ },
565
+
566
+ 'toggle should cycle through custom options only': async ({pass, fail}) => {
567
+ const { container, switcher } = await createThemeSwitcher('mode="toggle" options="dark, light"');
568
+
569
+ theme.set('dark');
570
+ await new Promise(r => setTimeout(r, 50));
571
+ await switcher.updateComplete;
572
+
573
+ const button = switcher.shadowRoot.querySelector('button');
574
+ button.click();
575
+ await switcher.updateComplete;
576
+
577
+ if(theme.get() !== 'light'){
578
+ cleanup(container);
579
+ fail(`Expected theme "light" after cycling from dark, got "${theme.get()}"`);
580
+ return;
581
+ }
582
+
583
+ button.click();
584
+ await switcher.updateComplete;
585
+
586
+ if(theme.get() !== 'dark'){
587
+ cleanup(container);
588
+ fail(`Expected theme "dark" after cycling from light, got "${theme.get()}"`);
589
+ return;
590
+ }
591
+
592
+ cleanup(container);
593
+ pass('Toggle cycles through custom options only');
594
+ },
595
+
596
+ 'options with no spaces should parse correctly': async ({pass, fail}) => {
597
+ const { container, switcher } = await createThemeSwitcher('options="dark,light,auto"');
598
+
599
+ const buttons = switcher.shadowRoot.querySelectorAll('.segmented button');
600
+ if(buttons.length !== 3){
601
+ cleanup(container);
602
+ fail(`Expected 3 buttons, got ${buttons.length}`);
603
+ return;
604
+ }
605
+
606
+ cleanup(container);
607
+ pass('Options without spaces parse correctly');
608
+ },
609
+
610
+ /*
611
+ Auto Mode Aside Detection Tests
612
+ */
613
+ 'auto mode without aside should resolve to segmented': async ({pass, fail}) => {
614
+ const { container, switcher } = await createThemeSwitcher();
615
+
616
+ if(switcher.resolvedMode !== 'segmented'){
617
+ cleanup(container);
618
+ fail(`Expected resolvedMode "segmented", got "${switcher.resolvedMode}"`);
619
+ return;
620
+ }
621
+
622
+ cleanup(container);
623
+ pass('Auto mode without aside resolves to segmented');
624
+ },
625
+
626
+ /*
627
+ Labels Tests
628
+ */
629
+ 'should have labels property defaulting to null': async ({pass, fail}) => {
630
+ const { container, switcher } = await createThemeSwitcher();
631
+
632
+ if(switcher.labels !== null){
633
+ cleanup(container);
634
+ fail(`Expected labels null, got ${switcher.labels}`);
635
+ return;
636
+ }
637
+
638
+ cleanup(container);
639
+ pass('labels defaults to null');
640
+ },
641
+
642
+ 'labels attribute (no value) shows capitalized option names in segmented mode': async ({pass, fail}) => {
643
+ const { container, switcher } = await createThemeSwitcher('labels');
644
+
645
+ await switcher.updateComplete;
646
+ const spans = switcher.shadowRoot.querySelectorAll('.segmented button span');
647
+ if(spans.length !== 3){
648
+ cleanup(container);
649
+ fail(`Expected 3 label spans, got ${spans.length}`);
650
+ return;
651
+ }
652
+
653
+ cleanup(container);
654
+ pass('labels (no value) shows 3 label spans in segmented mode');
655
+ },
656
+
657
+ 'labels attribute (no value) uses capitalized option text': async ({pass, fail}) => {
658
+ const { container, switcher } = await createThemeSwitcher('labels');
659
+
660
+ theme.set('light');
661
+ await new Promise(r => setTimeout(r, 50));
662
+ await switcher.updateComplete;
663
+
664
+ const spans = switcher.shadowRoot.querySelectorAll('.segmented button span');
665
+ const texts = Array.from(spans).map(s => s.textContent.trim());
666
+ if(!texts.includes('Light') || !texts.includes('Auto') || !texts.includes('Dark')){
667
+ cleanup(container);
668
+ fail(`Expected labels Light/Auto/Dark, got: ${texts.join(', ')}`);
669
+ return;
670
+ }
671
+
672
+ cleanup(container);
673
+ pass('labels (no value) shows capitalized text');
674
+ },
675
+
676
+ 'labels attribute with custom values uses those labels': async ({pass, fail}) => {
677
+ const { container, switcher } = await createThemeSwitcher('labels="Sun, System, Moon"');
678
+
679
+ await switcher.updateComplete;
680
+ const spans = switcher.shadowRoot.querySelectorAll('.segmented button span');
681
+ const texts = Array.from(spans).map(s => s.textContent.trim());
682
+ if(texts[0] !== 'Sun' || texts[1] !== 'System' || texts[2] !== 'Moon'){
683
+ cleanup(container);
684
+ fail(`Expected labels Sun/System/Moon, got: ${texts.join(', ')}`);
685
+ return;
686
+ }
687
+
688
+ cleanup(container);
689
+ pass('labels uses custom label values');
690
+ },
691
+
692
+ 'labels attribute shows label in toggle mode': async ({pass, fail}) => {
693
+ const { container, switcher } = await createThemeSwitcher('mode="toggle" labels');
694
+
695
+ theme.set('dark');
696
+ await new Promise(r => setTimeout(r, 50));
697
+ await switcher.updateComplete;
698
+
699
+ const span = switcher.shadowRoot.querySelector('button span');
700
+ if(!span || span.textContent.trim() !== 'Dark'){
701
+ cleanup(container);
702
+ fail(`Expected label span with "Dark", got ${span ? span.textContent : 'null'}`);
703
+ return;
704
+ }
705
+
706
+ cleanup(container);
707
+ pass('labels shows label in toggle mode');
708
+ },
709
+
710
+ 'custom labels with toggle mode shows correct label for active theme': async ({pass, fail}) => {
711
+ const { container, switcher } = await createThemeSwitcher('mode="toggle" labels="Sun, System, Moon"');
712
+
713
+ theme.set('dark');
714
+ await new Promise(r => setTimeout(r, 50));
715
+ await switcher.updateComplete;
716
+
717
+ const span = switcher.shadowRoot.querySelector('button span');
718
+ if(!span || span.textContent.trim() !== 'Moon'){
719
+ cleanup(container);
720
+ fail(`Expected label span with "Moon", got ${span ? span.textContent : 'null'}`);
721
+ return;
722
+ }
723
+
724
+ cleanup(container);
725
+ pass('custom labels toggle shows correct label for active theme');
726
+ },
727
+
728
+ 'without labels attribute no spans are rendered': async ({pass, fail}) => {
729
+ const { container, switcher } = await createThemeSwitcher();
730
+
731
+ const spans = switcher.shadowRoot.querySelectorAll('button span');
732
+ if(spans.length !== 0){
733
+ cleanup(container);
734
+ fail(`Expected 0 label spans without labels attr, got ${spans.length}`);
735
+ return;
736
+ }
737
+
738
+ cleanup(container);
739
+ pass('No label spans without labels attribute');
412
740
  }
413
741
  };