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.
- package/dist/components/Combobox.js +97 -0
- package/dist/components/Option.js +1 -0
- package/dist/components/ThemeSwitcher.js +77 -14
- package/docs/components/accordion.html +282 -94
- package/docs/components/aside.html +282 -94
- package/docs/components/card.html +282 -94
- package/docs/components/code-editor.html +282 -94
- package/docs/components/color-picker.html +282 -94
- package/docs/components/combobox.html +798 -0
- package/docs/components/content-slider.html +282 -94
- package/docs/components/context.html +282 -94
- package/docs/components/dialog.html +282 -94
- package/docs/components/dropdown.html +282 -94
- package/docs/components/filter-list.html +282 -94
- package/docs/components/focus-capture.html +282 -94
- package/docs/components/html-editor.html +282 -94
- package/docs/components/hybrid-component.html +282 -94
- package/docs/components/icon.html +282 -94
- package/docs/components/import.html +282 -94
- package/docs/components/light-component.html +282 -94
- package/docs/components/nav-spacer.html +282 -94
- package/docs/components/nav.html +282 -94
- package/docs/components/photo-viewer.html +282 -94
- package/docs/components/resize.html +282 -94
- package/docs/components/shadow-component.html +282 -94
- package/docs/components/show-more.html +282 -94
- package/docs/components/sortable.html +282 -94
- package/docs/components/spinner.html +282 -94
- package/docs/components/split.html +282 -94
- package/docs/components/table.html +282 -94
- package/docs/components/tableControls.html +282 -94
- package/docs/components/tableCustomFields.html +282 -94
- package/docs/components/tableFetchRecords.html +282 -94
- package/docs/components/tableFieldSortHide.html +282 -94
- package/docs/components/tablePagination.html +282 -94
- package/docs/components/tablePlaceholder.html +282 -94
- package/docs/components/tableRecordEditing.html +282 -94
- package/docs/components/tableRecordFiltering.html +282 -94
- package/docs/components/tableRecordHiding.html +282 -94
- package/docs/components/tableRecordSearching.html +282 -94
- package/docs/components/tableRecordSelection.html +282 -94
- package/docs/components/tableRowControls.html +282 -94
- package/docs/components/tableServerSync.html +282 -94
- package/docs/components/tableSorting.html +282 -94
- package/docs/components/tabs.html +282 -94
- package/docs/components/tags.html +282 -94
- package/docs/components/theme-select.html +282 -94
- package/docs/components/theme-switcher-aside.html +47 -0
- package/docs/components/theme-switcher.html +441 -101
- package/docs/components/timestamp.html +282 -94
- package/docs/components/toast.html +282 -94
- package/docs/components/toggle.html +282 -94
- package/docs/components/tree.html +282 -94
- package/docs/index.html +288 -94
- package/docs/src/components/Combobox.js +97 -0
- package/docs/src/components/Option.js +1 -0
- package/docs/src/components/ThemeSwitcher.js +77 -14
- package/docs/utils/context.html +282 -94
- package/docs/utils/cookie.html +282 -94
- package/docs/utils/debounce.html +282 -94
- package/docs/utils/drag.html +282 -94
- package/docs/utils/elevation.html +282 -94
- package/docs/utils/formatTimestamp.html +282 -94
- package/docs/utils/object.html +282 -94
- package/docs/utils/propConverters.html +282 -94
- package/docs/utils/string.html +282 -94
- package/docs/utils/theme.html +282 -94
- package/docs/utils/toTitleCase.html +282 -94
- package/docs/utils/type.html +282 -94
- package/docs/utils/wait.html +282 -94
- package/docs-src/components/combobox.page.html +358 -0
- package/docs-src/components/theme-switcher-aside.page.html +35 -0
- package/docs-src/components/theme-switcher.page.html +159 -7
- package/docs-src/index.page.html +6 -0
- package/docs-src/nav.fragment.html +283 -95
- package/llms.txt +2 -1
- package/package.json +1 -1
- package/src/components/Combobox.js +338 -0
- package/src/components/Option.js +19 -0
- package/src/components/ThemeSwitcher.js +171 -24
- package/tests/components/Combobox.browser-test.js +790 -0
- 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:
|
|
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('
|
|
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() !== '
|
|
213
|
+
if(theme.get() !== 'auto'){
|
|
141
214
|
cleanup(container);
|
|
142
|
-
fail(`Expected theme "
|
|
215
|
+
fail(`Expected theme "auto", got "${theme.get()}"`);
|
|
143
216
|
return;
|
|
144
217
|
}
|
|
145
218
|
|
|
146
219
|
cleanup(container);
|
|
147
|
-
pass('Theme cycles from
|
|
220
|
+
pass('Theme cycles from light to auto');
|
|
148
221
|
},
|
|
149
222
|
|
|
150
|
-
'should cycle theme on click:
|
|
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('
|
|
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
|
|
240
|
+
pass('Theme cycles from auto to dark');
|
|
168
241
|
},
|
|
169
242
|
|
|
170
|
-
'should cycle theme on click: dark to
|
|
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() !== '
|
|
253
|
+
if(theme.get() !== 'light'){
|
|
181
254
|
cleanup(container);
|
|
182
|
-
fail(`Expected theme "
|
|
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
|
|
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
|
};
|