kempo-ui 0.1.6 → 0.2.2
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/.github/skills/highlight-code/SKILL.md +22 -6
- package/.github/skills/new-component/SKILL.md +68 -4
- package/AGENTS.md +11 -0
- package/bin/highlight_code.js +7 -15
- package/dist/components/Aside.js +326 -0
- package/dist/components/Dialog.js +1 -1
- package/dist/components/Dropdown.js +1 -1
- package/dist/components/Main.js +2 -2
- package/dist/components/Nav.js +27 -0
- package/dist/components/PhotoViewer.js +1 -1
- package/dist/components/ShadowComponent.js +1 -1
- package/dist/components/ThemeSwitcher.js +1 -0
- package/dist/components/Toast.js +1 -1
- package/docs/components/accordion.html +4 -3
- package/docs/components/aside-items.html +43 -0
- package/docs/components/aside-menu.html +43 -0
- package/docs/components/aside-push.html +26 -0
- package/docs/components/aside.html +567 -0
- package/docs/components/card.html +4 -3
- package/docs/components/color-picker.html +4 -3
- package/docs/components/content-slider.html +4 -3
- package/docs/components/dialog.html +4 -3
- package/docs/components/dropdown.html +4 -3
- package/docs/components/filter-list.html +4 -3
- package/docs/components/focus-capture.html +6 -5
- package/docs/components/html-editor.html +5 -4
- package/docs/components/hybrid-component.html +5 -4
- package/docs/components/icon.html +4 -3
- package/docs/components/import.html +5 -4
- package/docs/components/light-component.html +4 -3
- package/docs/components/nav.html +117 -0
- package/docs/components/photo-viewer.html +5 -4
- package/docs/components/resize.html +5 -4
- package/docs/components/shadow-component.html +4 -3
- package/docs/components/show-more.html +5 -4
- package/docs/components/sortable.html +4 -3
- package/docs/components/spinner.html +4 -3
- package/docs/components/split.html +5 -4
- package/docs/components/table.html +4 -3
- package/docs/components/tableControls.html +4 -3
- package/docs/components/tableCustomFields.html +4 -3
- package/docs/components/tableFetchRecords.html +5 -4
- package/docs/components/tableFieldSortHide.html +5 -4
- package/docs/components/tablePagination.html +4 -3
- package/docs/components/tableRecordEditing.html +4 -3
- package/docs/components/tableRecordFiltering.html +5 -4
- package/docs/components/tableRecordHiding.html +4 -3
- package/docs/components/tableRecordSearching.html +5 -4
- package/docs/components/tableRecordSelection.html +4 -3
- package/docs/components/tableRowControls.html +4 -3
- package/docs/components/tableServerSync.html +5 -4
- package/docs/components/tableSorting.html +5 -4
- package/docs/components/tabs.html +4 -3
- package/docs/components/tags.html +4 -3
- package/docs/components/theme-select.html +4 -3
- package/docs/components/theme-switcher.html +5 -4
- package/docs/components/timestamp.html +4 -3
- package/docs/components/toast.html +4 -3
- package/docs/components/toggle.html +5 -4
- package/docs/components/tree.html +5 -4
- package/docs/index.html +22 -21
- package/docs/nav-1.inc.html +18 -12
- package/docs/nav.inc.html +20 -13
- package/docs/nav.inc.js +1 -1
- package/docs/src/components/Aside.js +326 -0
- package/docs/src/components/Dialog.js +1 -1
- package/docs/src/components/Dropdown.js +1 -1
- package/docs/src/components/Main.js +2 -2
- package/docs/src/components/Nav.js +27 -0
- package/docs/src/components/PhotoViewer.js +1 -1
- package/docs/src/components/ShadowComponent.js +1 -1
- package/docs/src/components/ThemeSwitcher.js +1 -0
- package/docs/src/components/Toast.js +1 -1
- package/docs/utils/context.html +4 -3
- package/docs/utils/cookie.html +4 -3
- package/docs/utils/debounce.html +4 -3
- package/docs/utils/drag.html +4 -3
- package/docs/utils/elevation.html +156 -0
- package/docs/utils/formatTimestamp.html +4 -3
- package/docs/utils/object.html +4 -3
- package/docs/utils/propConverters.html +4 -3
- package/docs/utils/string.html +4 -3
- package/docs/utils/theme.html +4 -3
- package/docs/utils/toTitleCase.html +4 -3
- package/docs/utils/type.html +4 -3
- package/docs/utils/wait.html +4 -3
- package/llm.txt +247 -0
- package/package.json +3 -4
- package/src/components/Aside.js +726 -0
- package/src/components/Dialog.js +1 -1
- package/src/components/Dropdown.js +1 -1
- package/src/components/Main.js +34 -30
- package/src/components/Nav.js +53 -0
- package/src/components/PhotoViewer.js +1 -1
- package/src/components/ShadowComponent.js +1 -1
- package/src/components/ThemeSwitcher.js +1 -0
- package/src/components/Toast.js +1 -1
- package/tests/bin/get_icon.node-test.js +26 -0
- package/tests/bin/highlight_code.node-test.js +108 -0
- package/tests/bin/list_icons.node-test.js +26 -0
- package/tests/components/Aside.browser-test.js +778 -0
- package/tests/components/Main.browser-test.js +115 -283
- package/dist/components/SideMenu.js +0 -97
- package/dist/components/SidePanel.js +0 -236
- package/docs/components/side-menu.html +0 -189
- package/docs/components/side-panel-basic.html +0 -44
- package/docs/components/side-panel-dual.html +0 -70
- package/docs/components/side-panel-menu.html +0 -50
- package/docs/components/side-panel-persistent.html +0 -90
- package/docs/components/side-panel-scroll.html +0 -176
- package/docs/components/side-panel.html +0 -245
- package/docs/src/components/SideMenu.js +0 -97
- package/docs/src/components/SidePanel.js +0 -236
- package/scripts/update-kempo-css.js +0 -53
- package/src/components/SideMenu.js +0 -178
- package/src/components/SidePanel.js +0 -513
- package/tests/components/SideMenu.browser-test.js +0 -667
- package/tests/components/SidePanel.browser-test.js +0 -520
- package/tools/highlight.js +0 -51
|
@@ -1,667 +0,0 @@
|
|
|
1
|
-
import SideMenu from '../../src/components/SideMenu.js';
|
|
2
|
-
|
|
3
|
-
const createSideMenu = async (options = {}) => {
|
|
4
|
-
const container = document.createElement('div');
|
|
5
|
-
container.innerHTML = `
|
|
6
|
-
<k-side-menu
|
|
7
|
-
${options.opened ? 'opened' : ''}
|
|
8
|
-
${options.overlayClose === false ? 'overlay-close="false"' : ''}
|
|
9
|
-
${options.side ? `side="${options.side}"` : ''}
|
|
10
|
-
>
|
|
11
|
-
${options.content || '<nav><a href="#">Link 1</a><a href="#">Link 2</a></nav>'}
|
|
12
|
-
</k-side-menu>
|
|
13
|
-
`;
|
|
14
|
-
document.body.appendChild(container);
|
|
15
|
-
|
|
16
|
-
const sideMenu = container.querySelector('k-side-menu');
|
|
17
|
-
await sideMenu.updateComplete;
|
|
18
|
-
|
|
19
|
-
return { container, sideMenu };
|
|
20
|
-
};
|
|
21
|
-
|
|
22
|
-
const cleanup = container => {
|
|
23
|
-
if(container && container.parentNode){
|
|
24
|
-
container.parentNode.removeChild(container);
|
|
25
|
-
}
|
|
26
|
-
document.body.classList.remove('no-scroll');
|
|
27
|
-
};
|
|
28
|
-
|
|
29
|
-
export default {
|
|
30
|
-
/*
|
|
31
|
-
Element Creation Tests
|
|
32
|
-
*/
|
|
33
|
-
'should create side-menu element': async ({pass, fail}) => {
|
|
34
|
-
const { container, sideMenu } = await createSideMenu();
|
|
35
|
-
|
|
36
|
-
if(!sideMenu){
|
|
37
|
-
cleanup(container);
|
|
38
|
-
fail('SideMenu element should be created');
|
|
39
|
-
return;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
if(!(sideMenu instanceof SideMenu)){
|
|
43
|
-
cleanup(container);
|
|
44
|
-
fail('Element should be instance of SideMenu');
|
|
45
|
-
return;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
cleanup(container);
|
|
49
|
-
pass('SideMenu element created correctly');
|
|
50
|
-
},
|
|
51
|
-
|
|
52
|
-
'should have shadow root': async ({pass, fail}) => {
|
|
53
|
-
const { container, sideMenu } = await createSideMenu();
|
|
54
|
-
|
|
55
|
-
if(!sideMenu.shadowRoot){
|
|
56
|
-
cleanup(container);
|
|
57
|
-
fail('SideMenu should have shadow root');
|
|
58
|
-
return;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
cleanup(container);
|
|
62
|
-
pass('SideMenu has shadow root');
|
|
63
|
-
},
|
|
64
|
-
|
|
65
|
-
/*
|
|
66
|
-
Default Property Tests
|
|
67
|
-
*/
|
|
68
|
-
'should be closed by default': async ({pass, fail}) => {
|
|
69
|
-
const { container, sideMenu } = await createSideMenu();
|
|
70
|
-
|
|
71
|
-
if(sideMenu.opened !== false){
|
|
72
|
-
cleanup(container);
|
|
73
|
-
fail(`Expected opened false, got ${sideMenu.opened}`);
|
|
74
|
-
return;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
cleanup(container);
|
|
78
|
-
pass('SideMenu is closed by default');
|
|
79
|
-
},
|
|
80
|
-
|
|
81
|
-
'should have overlayClose true by default': async ({pass, fail}) => {
|
|
82
|
-
const { container, sideMenu } = await createSideMenu();
|
|
83
|
-
|
|
84
|
-
if(sideMenu.overlayClose !== true){
|
|
85
|
-
cleanup(container);
|
|
86
|
-
fail(`Expected overlayClose true, got ${sideMenu.overlayClose}`);
|
|
87
|
-
return;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
cleanup(container);
|
|
91
|
-
pass('overlayClose is true by default');
|
|
92
|
-
},
|
|
93
|
-
|
|
94
|
-
'should have side left by default': async ({pass, fail}) => {
|
|
95
|
-
const { container, sideMenu } = await createSideMenu();
|
|
96
|
-
|
|
97
|
-
if(sideMenu.side !== 'left'){
|
|
98
|
-
cleanup(container);
|
|
99
|
-
fail(`Expected side "left", got "${sideMenu.side}"`);
|
|
100
|
-
return;
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
cleanup(container);
|
|
104
|
-
pass('side is "left" by default');
|
|
105
|
-
},
|
|
106
|
-
|
|
107
|
-
/*
|
|
108
|
-
Rendering Tests
|
|
109
|
-
*/
|
|
110
|
-
'should render focus-capture element': async ({pass, fail}) => {
|
|
111
|
-
const { container, sideMenu } = await createSideMenu();
|
|
112
|
-
|
|
113
|
-
const focusCapture = sideMenu.shadowRoot.querySelector('k-focus-capture');
|
|
114
|
-
if(!focusCapture){
|
|
115
|
-
cleanup(container);
|
|
116
|
-
fail('Should render k-focus-capture element');
|
|
117
|
-
return;
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
cleanup(container);
|
|
121
|
-
pass('Focus capture element rendered');
|
|
122
|
-
},
|
|
123
|
-
|
|
124
|
-
'should render container element': async ({pass, fail}) => {
|
|
125
|
-
const { container, sideMenu } = await createSideMenu();
|
|
126
|
-
|
|
127
|
-
const containerEl = sideMenu.shadowRoot.querySelector('#container');
|
|
128
|
-
if(!containerEl){
|
|
129
|
-
cleanup(container);
|
|
130
|
-
fail('Should render #container element');
|
|
131
|
-
return;
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
cleanup(container);
|
|
135
|
-
pass('Container element rendered');
|
|
136
|
-
},
|
|
137
|
-
|
|
138
|
-
'should render overlay element': async ({pass, fail}) => {
|
|
139
|
-
const { container, sideMenu } = await createSideMenu();
|
|
140
|
-
|
|
141
|
-
const overlay = sideMenu.shadowRoot.querySelector('#overlay');
|
|
142
|
-
if(!overlay){
|
|
143
|
-
cleanup(container);
|
|
144
|
-
fail('Should render #overlay element');
|
|
145
|
-
return;
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
cleanup(container);
|
|
149
|
-
pass('Overlay element rendered');
|
|
150
|
-
},
|
|
151
|
-
|
|
152
|
-
'should render menu element': async ({pass, fail}) => {
|
|
153
|
-
const { container, sideMenu } = await createSideMenu();
|
|
154
|
-
|
|
155
|
-
const menu = sideMenu.shadowRoot.querySelector('#menu');
|
|
156
|
-
if(!menu){
|
|
157
|
-
cleanup(container);
|
|
158
|
-
fail('Should render #menu element');
|
|
159
|
-
return;
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
cleanup(container);
|
|
163
|
-
pass('Menu element rendered');
|
|
164
|
-
},
|
|
165
|
-
|
|
166
|
-
'should render overlay close icon': async ({pass, fail}) => {
|
|
167
|
-
const { container, sideMenu } = await createSideMenu();
|
|
168
|
-
|
|
169
|
-
const overlayX = sideMenu.shadowRoot.querySelector('#overlay-x');
|
|
170
|
-
if(!overlayX){
|
|
171
|
-
cleanup(container);
|
|
172
|
-
fail('Should render #overlay-x element');
|
|
173
|
-
return;
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
cleanup(container);
|
|
177
|
-
pass('Overlay close icon rendered');
|
|
178
|
-
},
|
|
179
|
-
|
|
180
|
-
'should render default slot': async ({pass, fail}) => {
|
|
181
|
-
const { container, sideMenu } = await createSideMenu();
|
|
182
|
-
|
|
183
|
-
const slot = sideMenu.shadowRoot.querySelector('slot');
|
|
184
|
-
if(!slot){
|
|
185
|
-
cleanup(container);
|
|
186
|
-
fail('Should have default slot');
|
|
187
|
-
return;
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
cleanup(container);
|
|
191
|
-
pass('Default slot rendered');
|
|
192
|
-
},
|
|
193
|
-
|
|
194
|
-
/*
|
|
195
|
-
Open/Close Method Tests
|
|
196
|
-
*/
|
|
197
|
-
'should open with open method': async ({pass, fail}) => {
|
|
198
|
-
const { container, sideMenu } = await createSideMenu();
|
|
199
|
-
|
|
200
|
-
sideMenu.open();
|
|
201
|
-
await sideMenu.updateComplete;
|
|
202
|
-
|
|
203
|
-
if(sideMenu.opened !== true){
|
|
204
|
-
cleanup(container);
|
|
205
|
-
fail(`Expected opened true, got ${sideMenu.opened}`);
|
|
206
|
-
return;
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
cleanup(container);
|
|
210
|
-
pass('open() opens menu');
|
|
211
|
-
},
|
|
212
|
-
|
|
213
|
-
'should close with close method': async ({pass, fail}) => {
|
|
214
|
-
const { container, sideMenu } = await createSideMenu({ opened: true });
|
|
215
|
-
|
|
216
|
-
sideMenu.close();
|
|
217
|
-
await sideMenu.updateComplete;
|
|
218
|
-
|
|
219
|
-
if(sideMenu.opened !== false){
|
|
220
|
-
cleanup(container);
|
|
221
|
-
fail(`Expected opened false, got ${sideMenu.opened}`);
|
|
222
|
-
return;
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
cleanup(container);
|
|
226
|
-
pass('close() closes menu');
|
|
227
|
-
},
|
|
228
|
-
|
|
229
|
-
'should toggle opened state': async ({pass, fail}) => {
|
|
230
|
-
const { container, sideMenu } = await createSideMenu();
|
|
231
|
-
|
|
232
|
-
sideMenu.toggle();
|
|
233
|
-
await sideMenu.updateComplete;
|
|
234
|
-
|
|
235
|
-
if(sideMenu.opened !== true){
|
|
236
|
-
cleanup(container);
|
|
237
|
-
fail(`Expected opened true after first toggle, got ${sideMenu.opened}`);
|
|
238
|
-
return;
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
sideMenu.toggle();
|
|
242
|
-
await sideMenu.updateComplete;
|
|
243
|
-
|
|
244
|
-
if(sideMenu.opened !== false){
|
|
245
|
-
cleanup(container);
|
|
246
|
-
fail(`Expected opened false after second toggle, got ${sideMenu.opened}`);
|
|
247
|
-
return;
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
cleanup(container);
|
|
251
|
-
pass('toggle() switches opened state');
|
|
252
|
-
},
|
|
253
|
-
|
|
254
|
-
/*
|
|
255
|
-
Overlay Close Tests
|
|
256
|
-
*/
|
|
257
|
-
'should close on overlay click when overlayClose is true': async ({pass, fail}) => {
|
|
258
|
-
const { container, sideMenu } = await createSideMenu({ opened: true });
|
|
259
|
-
|
|
260
|
-
const overlay = sideMenu.shadowRoot.querySelector('#overlay');
|
|
261
|
-
overlay.click();
|
|
262
|
-
await sideMenu.updateComplete;
|
|
263
|
-
|
|
264
|
-
if(sideMenu.opened !== false){
|
|
265
|
-
cleanup(container);
|
|
266
|
-
fail('Clicking overlay should close menu');
|
|
267
|
-
return;
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
cleanup(container);
|
|
271
|
-
pass('Overlay click closes menu');
|
|
272
|
-
},
|
|
273
|
-
|
|
274
|
-
'should not close on overlay click when overlayClose is false': async ({pass, fail}) => {
|
|
275
|
-
const { container, sideMenu } = await createSideMenu({ opened: true, overlayClose: false });
|
|
276
|
-
|
|
277
|
-
const overlay = sideMenu.shadowRoot.querySelector('#overlay');
|
|
278
|
-
overlay.click();
|
|
279
|
-
await sideMenu.updateComplete;
|
|
280
|
-
|
|
281
|
-
if(sideMenu.opened !== true){
|
|
282
|
-
cleanup(container);
|
|
283
|
-
fail('Clicking overlay should not close menu when overlayClose is false');
|
|
284
|
-
return;
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
cleanup(container);
|
|
288
|
-
pass('Overlay click does not close menu when overlayClose is false');
|
|
289
|
-
},
|
|
290
|
-
|
|
291
|
-
/*
|
|
292
|
-
Event Tests
|
|
293
|
-
*/
|
|
294
|
-
'should dispatch open event': async ({pass, fail}) => {
|
|
295
|
-
const { container, sideMenu } = await createSideMenu();
|
|
296
|
-
|
|
297
|
-
let eventFired = false;
|
|
298
|
-
sideMenu.addEventListener('open', () => {
|
|
299
|
-
eventFired = true;
|
|
300
|
-
});
|
|
301
|
-
|
|
302
|
-
sideMenu.open();
|
|
303
|
-
await sideMenu.updateComplete;
|
|
304
|
-
|
|
305
|
-
if(!eventFired){
|
|
306
|
-
cleanup(container);
|
|
307
|
-
fail('open event should be dispatched');
|
|
308
|
-
return;
|
|
309
|
-
}
|
|
310
|
-
|
|
311
|
-
cleanup(container);
|
|
312
|
-
pass('open event dispatched');
|
|
313
|
-
},
|
|
314
|
-
|
|
315
|
-
'should dispatch close event': async ({pass, fail}) => {
|
|
316
|
-
const { container, sideMenu } = await createSideMenu({ opened: true });
|
|
317
|
-
|
|
318
|
-
let eventFired = false;
|
|
319
|
-
sideMenu.addEventListener('close', () => {
|
|
320
|
-
eventFired = true;
|
|
321
|
-
});
|
|
322
|
-
|
|
323
|
-
sideMenu.close();
|
|
324
|
-
await sideMenu.updateComplete;
|
|
325
|
-
|
|
326
|
-
if(!eventFired){
|
|
327
|
-
cleanup(container);
|
|
328
|
-
fail('close event should be dispatched');
|
|
329
|
-
return;
|
|
330
|
-
}
|
|
331
|
-
|
|
332
|
-
cleanup(container);
|
|
333
|
-
pass('close event dispatched');
|
|
334
|
-
},
|
|
335
|
-
|
|
336
|
-
'should dispatch change event on open': async ({pass, fail}) => {
|
|
337
|
-
const { container, sideMenu } = await createSideMenu();
|
|
338
|
-
|
|
339
|
-
let eventDetail = null;
|
|
340
|
-
sideMenu.addEventListener('change', e => {
|
|
341
|
-
eventDetail = e.detail;
|
|
342
|
-
});
|
|
343
|
-
|
|
344
|
-
sideMenu.open();
|
|
345
|
-
await sideMenu.updateComplete;
|
|
346
|
-
|
|
347
|
-
if(eventDetail !== 'open'){
|
|
348
|
-
cleanup(container);
|
|
349
|
-
fail(`Expected change event detail "open", got "${eventDetail}"`);
|
|
350
|
-
return;
|
|
351
|
-
}
|
|
352
|
-
|
|
353
|
-
cleanup(container);
|
|
354
|
-
pass('change event dispatched on open');
|
|
355
|
-
},
|
|
356
|
-
|
|
357
|
-
'should dispatch change event on close': async ({pass, fail}) => {
|
|
358
|
-
const { container, sideMenu } = await createSideMenu({ opened: true });
|
|
359
|
-
|
|
360
|
-
let eventDetail = null;
|
|
361
|
-
sideMenu.addEventListener('change', e => {
|
|
362
|
-
eventDetail = e.detail;
|
|
363
|
-
});
|
|
364
|
-
|
|
365
|
-
sideMenu.close();
|
|
366
|
-
await sideMenu.updateComplete;
|
|
367
|
-
|
|
368
|
-
if(eventDetail !== 'close'){
|
|
369
|
-
cleanup(container);
|
|
370
|
-
fail(`Expected change event detail "close", got "${eventDetail}"`);
|
|
371
|
-
return;
|
|
372
|
-
}
|
|
373
|
-
|
|
374
|
-
cleanup(container);
|
|
375
|
-
pass('change event dispatched on close');
|
|
376
|
-
},
|
|
377
|
-
|
|
378
|
-
'should dispatch toggle event': async ({pass, fail}) => {
|
|
379
|
-
const { container, sideMenu } = await createSideMenu();
|
|
380
|
-
|
|
381
|
-
let eventFired = false;
|
|
382
|
-
sideMenu.addEventListener('toggle', () => {
|
|
383
|
-
eventFired = true;
|
|
384
|
-
});
|
|
385
|
-
|
|
386
|
-
sideMenu.toggle();
|
|
387
|
-
await sideMenu.updateComplete;
|
|
388
|
-
|
|
389
|
-
if(!eventFired){
|
|
390
|
-
cleanup(container);
|
|
391
|
-
fail('toggle event should be dispatched');
|
|
392
|
-
return;
|
|
393
|
-
}
|
|
394
|
-
|
|
395
|
-
cleanup(container);
|
|
396
|
-
pass('toggle event dispatched');
|
|
397
|
-
},
|
|
398
|
-
|
|
399
|
-
/*
|
|
400
|
-
Body Scroll Lock Tests
|
|
401
|
-
*/
|
|
402
|
-
'should add no-scroll class to body when opened': async ({pass, fail}) => {
|
|
403
|
-
const { container, sideMenu } = await createSideMenu();
|
|
404
|
-
|
|
405
|
-
sideMenu.open();
|
|
406
|
-
await sideMenu.updateComplete;
|
|
407
|
-
|
|
408
|
-
if(!document.body.classList.contains('no-scroll')){
|
|
409
|
-
cleanup(container);
|
|
410
|
-
fail('Body should have no-scroll class when menu is opened');
|
|
411
|
-
return;
|
|
412
|
-
}
|
|
413
|
-
|
|
414
|
-
cleanup(container);
|
|
415
|
-
pass('Body has no-scroll class when opened');
|
|
416
|
-
},
|
|
417
|
-
|
|
418
|
-
'should remove no-scroll class from body when closed': async ({pass, fail}) => {
|
|
419
|
-
const { container, sideMenu } = await createSideMenu({ opened: true });
|
|
420
|
-
|
|
421
|
-
// Ensure body has the class first
|
|
422
|
-
document.body.classList.add('no-scroll');
|
|
423
|
-
|
|
424
|
-
sideMenu.close();
|
|
425
|
-
await sideMenu.updateComplete;
|
|
426
|
-
|
|
427
|
-
if(document.body.classList.contains('no-scroll')){
|
|
428
|
-
cleanup(container);
|
|
429
|
-
fail('Body should not have no-scroll class when menu is closed');
|
|
430
|
-
return;
|
|
431
|
-
}
|
|
432
|
-
|
|
433
|
-
cleanup(container);
|
|
434
|
-
pass('Body no-scroll class removed when closed');
|
|
435
|
-
},
|
|
436
|
-
|
|
437
|
-
/*
|
|
438
|
-
Side Attribute Tests
|
|
439
|
-
*/
|
|
440
|
-
'should reflect side attribute': async ({pass, fail}) => {
|
|
441
|
-
const { container, sideMenu } = await createSideMenu({ side: 'right' });
|
|
442
|
-
|
|
443
|
-
if(sideMenu.getAttribute('side') !== 'right'){
|
|
444
|
-
cleanup(container);
|
|
445
|
-
fail('side attribute should reflect property');
|
|
446
|
-
return;
|
|
447
|
-
}
|
|
448
|
-
|
|
449
|
-
cleanup(container);
|
|
450
|
-
pass('side attribute reflects property');
|
|
451
|
-
},
|
|
452
|
-
|
|
453
|
-
'should accept left side': async ({pass, fail}) => {
|
|
454
|
-
const { container, sideMenu } = await createSideMenu({ side: 'left' });
|
|
455
|
-
|
|
456
|
-
if(sideMenu.side !== 'left'){
|
|
457
|
-
cleanup(container);
|
|
458
|
-
fail(`Expected side "left", got "${sideMenu.side}"`);
|
|
459
|
-
return;
|
|
460
|
-
}
|
|
461
|
-
|
|
462
|
-
cleanup(container);
|
|
463
|
-
pass('left side accepted');
|
|
464
|
-
},
|
|
465
|
-
|
|
466
|
-
'should accept right side': async ({pass, fail}) => {
|
|
467
|
-
const { container, sideMenu } = await createSideMenu({ side: 'right' });
|
|
468
|
-
|
|
469
|
-
if(sideMenu.side !== 'right'){
|
|
470
|
-
cleanup(container);
|
|
471
|
-
fail(`Expected side "right", got "${sideMenu.side}"`);
|
|
472
|
-
return;
|
|
473
|
-
}
|
|
474
|
-
|
|
475
|
-
cleanup(container);
|
|
476
|
-
pass('right side accepted');
|
|
477
|
-
},
|
|
478
|
-
|
|
479
|
-
/*
|
|
480
|
-
Attribute Reflection Tests
|
|
481
|
-
*/
|
|
482
|
-
'should reflect opened attribute': async ({pass, fail}) => {
|
|
483
|
-
const { container, sideMenu } = await createSideMenu();
|
|
484
|
-
|
|
485
|
-
sideMenu.open();
|
|
486
|
-
await sideMenu.updateComplete;
|
|
487
|
-
|
|
488
|
-
if(!sideMenu.hasAttribute('opened')){
|
|
489
|
-
cleanup(container);
|
|
490
|
-
fail('opened attribute should be reflected');
|
|
491
|
-
return;
|
|
492
|
-
}
|
|
493
|
-
|
|
494
|
-
sideMenu.close();
|
|
495
|
-
await sideMenu.updateComplete;
|
|
496
|
-
|
|
497
|
-
if(sideMenu.hasAttribute('opened')){
|
|
498
|
-
cleanup(container);
|
|
499
|
-
fail('opened attribute should be removed when closed');
|
|
500
|
-
return;
|
|
501
|
-
}
|
|
502
|
-
|
|
503
|
-
cleanup(container);
|
|
504
|
-
pass('opened attribute reflects property');
|
|
505
|
-
},
|
|
506
|
-
|
|
507
|
-
'should reflect overlay-close attribute': async ({pass, fail}) => {
|
|
508
|
-
const { container, sideMenu } = await createSideMenu({ overlayClose: false });
|
|
509
|
-
|
|
510
|
-
if(sideMenu.getAttribute('overlay-close') !== 'false'){
|
|
511
|
-
cleanup(container);
|
|
512
|
-
fail('overlay-close attribute should reflect property');
|
|
513
|
-
return;
|
|
514
|
-
}
|
|
515
|
-
|
|
516
|
-
cleanup(container);
|
|
517
|
-
pass('overlay-close attribute reflects property');
|
|
518
|
-
},
|
|
519
|
-
|
|
520
|
-
/*
|
|
521
|
-
Content Slot Tests
|
|
522
|
-
*/
|
|
523
|
-
'should slot content correctly': async ({pass, fail}) => {
|
|
524
|
-
const { container, sideMenu } = await createSideMenu({ content: '<nav id="test-nav"><a href="#">Test Link</a></nav>' });
|
|
525
|
-
|
|
526
|
-
const nav = sideMenu.querySelector('#test-nav');
|
|
527
|
-
if(!nav){
|
|
528
|
-
cleanup(container);
|
|
529
|
-
fail('Content should be slotted');
|
|
530
|
-
return;
|
|
531
|
-
}
|
|
532
|
-
|
|
533
|
-
cleanup(container);
|
|
534
|
-
pass('Content slotted correctly');
|
|
535
|
-
},
|
|
536
|
-
|
|
537
|
-
/*
|
|
538
|
-
Display Tests
|
|
539
|
-
*/
|
|
540
|
-
'should have fixed position': async ({pass, fail}) => {
|
|
541
|
-
const { container, sideMenu } = await createSideMenu();
|
|
542
|
-
|
|
543
|
-
const computedStyle = window.getComputedStyle(sideMenu);
|
|
544
|
-
if(computedStyle.position !== 'fixed'){
|
|
545
|
-
cleanup(container);
|
|
546
|
-
fail(`Expected position "fixed", got "${computedStyle.position}"`);
|
|
547
|
-
return;
|
|
548
|
-
}
|
|
549
|
-
|
|
550
|
-
cleanup(container);
|
|
551
|
-
pass('SideMenu has fixed position');
|
|
552
|
-
},
|
|
553
|
-
|
|
554
|
-
'should have pointer-events none when closed': async ({pass, fail}) => {
|
|
555
|
-
const { container, sideMenu } = await createSideMenu();
|
|
556
|
-
|
|
557
|
-
const computedStyle = window.getComputedStyle(sideMenu);
|
|
558
|
-
if(computedStyle.pointerEvents !== 'none'){
|
|
559
|
-
cleanup(container);
|
|
560
|
-
fail(`Expected pointer-events "none" when closed, got "${computedStyle.pointerEvents}"`);
|
|
561
|
-
return;
|
|
562
|
-
}
|
|
563
|
-
|
|
564
|
-
cleanup(container);
|
|
565
|
-
pass('Pointer-events none when closed');
|
|
566
|
-
},
|
|
567
|
-
|
|
568
|
-
'should have pointer-events auto when opened': async ({pass, fail}) => {
|
|
569
|
-
const { container, sideMenu } = await createSideMenu({ opened: true });
|
|
570
|
-
|
|
571
|
-
const computedStyle = window.getComputedStyle(sideMenu);
|
|
572
|
-
if(computedStyle.pointerEvents !== 'auto'){
|
|
573
|
-
cleanup(container);
|
|
574
|
-
fail(`Expected pointer-events "auto" when opened, got "${computedStyle.pointerEvents}"`);
|
|
575
|
-
return;
|
|
576
|
-
}
|
|
577
|
-
|
|
578
|
-
cleanup(container);
|
|
579
|
-
pass('Pointer-events auto when opened');
|
|
580
|
-
},
|
|
581
|
-
|
|
582
|
-
'should have high z-index': async ({pass, fail}) => {
|
|
583
|
-
const { container, sideMenu } = await createSideMenu();
|
|
584
|
-
|
|
585
|
-
const computedStyle = window.getComputedStyle(sideMenu);
|
|
586
|
-
const zIndex = parseInt(computedStyle.zIndex, 10);
|
|
587
|
-
|
|
588
|
-
if(isNaN(zIndex) || zIndex < 100){
|
|
589
|
-
cleanup(container);
|
|
590
|
-
fail(`Expected high z-index, got "${computedStyle.zIndex}"`);
|
|
591
|
-
return;
|
|
592
|
-
}
|
|
593
|
-
|
|
594
|
-
cleanup(container);
|
|
595
|
-
pass('SideMenu has high z-index');
|
|
596
|
-
},
|
|
597
|
-
|
|
598
|
-
/*
|
|
599
|
-
Overlay X Icon Visibility Tests
|
|
600
|
-
*/
|
|
601
|
-
'should hide overlay X when overlay-close is false': async ({pass, fail}) => {
|
|
602
|
-
const { container, sideMenu } = await createSideMenu({ overlayClose: false });
|
|
603
|
-
|
|
604
|
-
const overlayX = sideMenu.shadowRoot.querySelector('#overlay-x');
|
|
605
|
-
const computedStyle = window.getComputedStyle(overlayX);
|
|
606
|
-
|
|
607
|
-
if(computedStyle.display !== 'none'){
|
|
608
|
-
cleanup(container);
|
|
609
|
-
fail('Overlay X should be hidden when overlay-close is false');
|
|
610
|
-
return;
|
|
611
|
-
}
|
|
612
|
-
|
|
613
|
-
cleanup(container);
|
|
614
|
-
pass('Overlay X hidden when overlay-close is false');
|
|
615
|
-
},
|
|
616
|
-
|
|
617
|
-
/*
|
|
618
|
-
Container Opacity Tests
|
|
619
|
-
*/
|
|
620
|
-
'should have container opacity 0 when closed': async ({pass, fail}) => {
|
|
621
|
-
const { container, sideMenu } = await createSideMenu();
|
|
622
|
-
|
|
623
|
-
const containerEl = sideMenu.shadowRoot.querySelector('#container');
|
|
624
|
-
const computedStyle = window.getComputedStyle(containerEl);
|
|
625
|
-
|
|
626
|
-
if(computedStyle.opacity !== '0'){
|
|
627
|
-
cleanup(container);
|
|
628
|
-
fail(`Expected opacity "0" when closed, got "${computedStyle.opacity}"`);
|
|
629
|
-
return;
|
|
630
|
-
}
|
|
631
|
-
|
|
632
|
-
cleanup(container);
|
|
633
|
-
pass('Container opacity is 0 when closed');
|
|
634
|
-
},
|
|
635
|
-
|
|
636
|
-
'should have container opacity 1 when opened': async ({pass, fail}) => {
|
|
637
|
-
const { container, sideMenu } = await createSideMenu({ opened: true });
|
|
638
|
-
|
|
639
|
-
const containerEl = sideMenu.shadowRoot.querySelector('#container');
|
|
640
|
-
const computedStyle = window.getComputedStyle(containerEl);
|
|
641
|
-
|
|
642
|
-
if(computedStyle.opacity !== '1'){
|
|
643
|
-
cleanup(container);
|
|
644
|
-
fail(`Expected opacity "1" when opened, got "${computedStyle.opacity}"`);
|
|
645
|
-
return;
|
|
646
|
-
}
|
|
647
|
-
|
|
648
|
-
cleanup(container);
|
|
649
|
-
pass('Container opacity is 1 when opened');
|
|
650
|
-
},
|
|
651
|
-
|
|
652
|
-
/*
|
|
653
|
-
Initial State from Attribute Tests
|
|
654
|
-
*/
|
|
655
|
-
'should be opened when opened attribute is present': async ({pass, fail}) => {
|
|
656
|
-
const { container, sideMenu } = await createSideMenu({ opened: true });
|
|
657
|
-
|
|
658
|
-
if(sideMenu.opened !== true){
|
|
659
|
-
cleanup(container);
|
|
660
|
-
fail('Should be opened when opened attribute is present');
|
|
661
|
-
return;
|
|
662
|
-
}
|
|
663
|
-
|
|
664
|
-
cleanup(container);
|
|
665
|
-
pass('Opened attribute sets initial state');
|
|
666
|
-
}
|
|
667
|
-
};
|