kempo-ui 0.0.39 → 0.0.41
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/Dropdown.js +123 -0
- package/dist/components/ShadowComponent.js +1 -1
- package/dist/components/Spinner.js +113 -0
- package/docs/components/accordion.html +1 -1
- package/docs/components/card.html +1 -1
- package/docs/components/color-picker.html +1 -1
- package/docs/components/content-slider.html +1 -1
- package/docs/components/dialog.html +1 -1
- package/docs/components/dropdown.html +282 -0
- package/docs/components/focus-capture.html +1 -1
- package/docs/components/hybrid-component.html +1 -1
- package/docs/components/icon.html +1 -1
- package/docs/components/import.html +1 -1
- package/docs/components/light-component.html +1 -1
- package/docs/components/photo-viewer.html +1 -1
- package/docs/components/resize.html +1 -1
- package/docs/components/shadow-component.html +1 -1
- package/docs/components/show-more.html +1 -1
- package/docs/components/side-menu.html +1 -1
- package/docs/components/sortable.html +1 -1
- package/docs/components/spinner.html +214 -0
- package/docs/components/split.html +1 -1
- package/docs/components/table.html +1 -1
- package/docs/components/tableControls.html +1 -1
- package/docs/components/tableCustomFields.html +1 -1
- package/docs/components/tableFetchRecords.html +1 -1
- package/docs/components/tableFieldSortHide.html +1 -1
- package/docs/components/tablePagination.html +1 -1
- package/docs/components/tableRecordEditing.html +1 -1
- package/docs/components/tableRecordFiltering.html +1 -1
- package/docs/components/tableRecordHiding.html +1 -1
- package/docs/components/tableRecordSearching.html +1 -1
- package/docs/components/tableRecordSelection.html +1 -1
- package/docs/components/tableRowControls.html +1 -1
- package/docs/components/tableSorting.html +1 -1
- package/docs/components/tabs.html +1 -1
- package/docs/components/tags.html +1 -1
- package/docs/components/theme-switcher.html +1 -1
- package/docs/components/timestamp.html +1 -1
- package/docs/components/toast.html +1 -1
- package/docs/components/toggle.html +1 -1
- package/docs/components/tree.html +1 -1
- package/docs/index.html +13 -1
- package/docs/nav-1.inc.html +2 -0
- package/docs/src/components/Dropdown.js +123 -0
- package/docs/src/components/ShadowComponent.js +1 -1
- package/docs/src/components/Spinner.js +113 -0
- package/docs/utils/context.html +1 -1
- package/docs/utils/cookie.html +1 -1
- package/docs/utils/debounce.html +1 -1
- package/docs/utils/drag.html +1 -1
- package/docs/utils/formatTimestamp.html +1 -1
- package/docs/utils/object.html +1 -1
- package/docs/utils/propConverters.html +1 -1
- package/docs/utils/string.html +1 -1
- package/docs/utils/theme.html +1 -1
- package/docs/utils/toTitleCase.html +1 -1
- package/docs/utils/type.html +1 -1
- package/docs/utils/wait.html +1 -1
- package/package.json +1 -1
- package/src/components/Dropdown.js +358 -0
- package/src/components/ShadowComponent.js +1 -1
- package/src/components/Spinner.js +152 -0
- package/tests/components/Dropdown.browser-test.js +557 -0
- package/tests/components/HybridComponent.browser-test.js +8 -2
- package/tests/components/ShadowComponent.browser-test.js +6 -6
- package/tests/components/Spinner.browser-test.js +335 -0
|
@@ -0,0 +1,335 @@
|
|
|
1
|
+
import Spinner from '../../src/components/Spinner.js';
|
|
2
|
+
|
|
3
|
+
const createSpinner = async (options = {}) => {
|
|
4
|
+
const container = document.createElement('div');
|
|
5
|
+
container.innerHTML = `
|
|
6
|
+
<k-spinner
|
|
7
|
+
${options.size ? `size="${options.size}"` : ''}
|
|
8
|
+
${options.variant ? `variant="${options.variant}"` : ''}
|
|
9
|
+
${options.style ? `style="${options.style}"` : ''}
|
|
10
|
+
></k-spinner>
|
|
11
|
+
`;
|
|
12
|
+
document.body.appendChild(container);
|
|
13
|
+
const spinner = container.querySelector('k-spinner');
|
|
14
|
+
await spinner.updateComplete;
|
|
15
|
+
return { container, spinner };
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
const cleanup = (container) => {
|
|
19
|
+
if(container && container.parentNode) {
|
|
20
|
+
container.parentNode.removeChild(container);
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
export default {
|
|
25
|
+
/*
|
|
26
|
+
Element Creation
|
|
27
|
+
*/
|
|
28
|
+
'should create spinner element': async ({pass, fail}) => {
|
|
29
|
+
const { container, spinner } = await createSpinner();
|
|
30
|
+
if(!spinner) {
|
|
31
|
+
cleanup(container);
|
|
32
|
+
return fail('Spinner element should be created');
|
|
33
|
+
}
|
|
34
|
+
if(!(spinner instanceof Spinner)) {
|
|
35
|
+
cleanup(container);
|
|
36
|
+
return fail('Element should be instance of Spinner');
|
|
37
|
+
}
|
|
38
|
+
cleanup(container);
|
|
39
|
+
pass('Spinner element created correctly');
|
|
40
|
+
},
|
|
41
|
+
|
|
42
|
+
'should have shadow root': async ({pass, fail}) => {
|
|
43
|
+
const { container, spinner } = await createSpinner();
|
|
44
|
+
if(!spinner.shadowRoot) {
|
|
45
|
+
cleanup(container);
|
|
46
|
+
return fail('Spinner should have shadow root');
|
|
47
|
+
}
|
|
48
|
+
cleanup(container);
|
|
49
|
+
pass('Spinner has shadow root');
|
|
50
|
+
},
|
|
51
|
+
|
|
52
|
+
'should have default size of md': async ({pass, fail}) => {
|
|
53
|
+
const { container, spinner } = await createSpinner();
|
|
54
|
+
if(spinner.size !== 'md') {
|
|
55
|
+
cleanup(container);
|
|
56
|
+
return fail(`Expected size to be 'md', got ${spinner.size}`);
|
|
57
|
+
}
|
|
58
|
+
cleanup(container);
|
|
59
|
+
pass('Default size is md');
|
|
60
|
+
},
|
|
61
|
+
|
|
62
|
+
'should have default variant of spinner': async ({pass, fail}) => {
|
|
63
|
+
const { container, spinner } = await createSpinner();
|
|
64
|
+
if(spinner.variant !== 'spinner') {
|
|
65
|
+
cleanup(container);
|
|
66
|
+
return fail(`Expected variant to be 'spinner', got ${spinner.variant}`);
|
|
67
|
+
}
|
|
68
|
+
cleanup(container);
|
|
69
|
+
pass('Default variant is spinner');
|
|
70
|
+
},
|
|
71
|
+
|
|
72
|
+
/*
|
|
73
|
+
Property Reflection
|
|
74
|
+
*/
|
|
75
|
+
'should reflect size attribute': async ({pass, fail}) => {
|
|
76
|
+
const { container, spinner } = await createSpinner({ size: 'lg' });
|
|
77
|
+
if(spinner.getAttribute('size') !== 'lg') {
|
|
78
|
+
cleanup(container);
|
|
79
|
+
return fail('Size attribute should be lg');
|
|
80
|
+
}
|
|
81
|
+
cleanup(container);
|
|
82
|
+
pass('Size attribute reflects correctly');
|
|
83
|
+
},
|
|
84
|
+
|
|
85
|
+
'should reflect variant attribute': async ({pass, fail}) => {
|
|
86
|
+
const { container, spinner } = await createSpinner({ variant: 'dots' });
|
|
87
|
+
if(spinner.getAttribute('variant') !== 'dots') {
|
|
88
|
+
cleanup(container);
|
|
89
|
+
return fail('Variant attribute should be dots');
|
|
90
|
+
}
|
|
91
|
+
cleanup(container);
|
|
92
|
+
pass('Variant attribute reflects correctly');
|
|
93
|
+
},
|
|
94
|
+
|
|
95
|
+
'should update attribute when size property changes': async ({pass, fail}) => {
|
|
96
|
+
const { container, spinner } = await createSpinner();
|
|
97
|
+
spinner.size = 'xl';
|
|
98
|
+
await spinner.updateComplete;
|
|
99
|
+
if(spinner.getAttribute('size') !== 'xl') {
|
|
100
|
+
cleanup(container);
|
|
101
|
+
return fail('Size attribute should update when property changes');
|
|
102
|
+
}
|
|
103
|
+
cleanup(container);
|
|
104
|
+
pass('Attribute updates when size property changes');
|
|
105
|
+
},
|
|
106
|
+
|
|
107
|
+
'should update attribute when variant property changes': async ({pass, fail}) => {
|
|
108
|
+
const { container, spinner } = await createSpinner();
|
|
109
|
+
spinner.variant = 'bars';
|
|
110
|
+
await spinner.updateComplete;
|
|
111
|
+
if(spinner.getAttribute('variant') !== 'bars') {
|
|
112
|
+
cleanup(container);
|
|
113
|
+
return fail('Variant attribute should update when property changes');
|
|
114
|
+
}
|
|
115
|
+
cleanup(container);
|
|
116
|
+
pass('Attribute updates when variant property changes');
|
|
117
|
+
},
|
|
118
|
+
|
|
119
|
+
/*
|
|
120
|
+
Sizes
|
|
121
|
+
*/
|
|
122
|
+
'should render xs size': async ({pass, fail}) => {
|
|
123
|
+
const { container, spinner } = await createSpinner({ size: 'xs' });
|
|
124
|
+
if(spinner.size !== 'xs') {
|
|
125
|
+
cleanup(container);
|
|
126
|
+
return fail('Spinner size should be xs');
|
|
127
|
+
}
|
|
128
|
+
cleanup(container);
|
|
129
|
+
pass('Spinner renders xs size');
|
|
130
|
+
},
|
|
131
|
+
|
|
132
|
+
'should render sm size': async ({pass, fail}) => {
|
|
133
|
+
const { container, spinner } = await createSpinner({ size: 'sm' });
|
|
134
|
+
if(spinner.size !== 'sm') {
|
|
135
|
+
cleanup(container);
|
|
136
|
+
return fail('Spinner size should be sm');
|
|
137
|
+
}
|
|
138
|
+
cleanup(container);
|
|
139
|
+
pass('Spinner renders sm size');
|
|
140
|
+
},
|
|
141
|
+
|
|
142
|
+
'should render md size': async ({pass, fail}) => {
|
|
143
|
+
const { container, spinner } = await createSpinner({ size: 'md' });
|
|
144
|
+
if(spinner.size !== 'md') {
|
|
145
|
+
cleanup(container);
|
|
146
|
+
return fail('Spinner size should be md');
|
|
147
|
+
}
|
|
148
|
+
cleanup(container);
|
|
149
|
+
pass('Spinner renders md size');
|
|
150
|
+
},
|
|
151
|
+
|
|
152
|
+
'should render lg size': async ({pass, fail}) => {
|
|
153
|
+
const { container, spinner } = await createSpinner({ size: 'lg' });
|
|
154
|
+
if(spinner.size !== 'lg') {
|
|
155
|
+
cleanup(container);
|
|
156
|
+
return fail('Spinner size should be lg');
|
|
157
|
+
}
|
|
158
|
+
cleanup(container);
|
|
159
|
+
pass('Spinner renders lg size');
|
|
160
|
+
},
|
|
161
|
+
|
|
162
|
+
'should render xl size': async ({pass, fail}) => {
|
|
163
|
+
const { container, spinner } = await createSpinner({ size: 'xl' });
|
|
164
|
+
if(spinner.size !== 'xl') {
|
|
165
|
+
cleanup(container);
|
|
166
|
+
return fail('Spinner size should be xl');
|
|
167
|
+
}
|
|
168
|
+
cleanup(container);
|
|
169
|
+
pass('Spinner renders xl size');
|
|
170
|
+
},
|
|
171
|
+
|
|
172
|
+
/*
|
|
173
|
+
Variants - Spinner
|
|
174
|
+
*/
|
|
175
|
+
'should render spinner variant': async ({pass, fail}) => {
|
|
176
|
+
const { container, spinner } = await createSpinner({ variant: 'spinner' });
|
|
177
|
+
const spinnerEl = spinner.shadowRoot.querySelector('.spinner');
|
|
178
|
+
if(!spinnerEl) {
|
|
179
|
+
cleanup(container);
|
|
180
|
+
return fail('Spinner variant should render .spinner element');
|
|
181
|
+
}
|
|
182
|
+
cleanup(container);
|
|
183
|
+
pass('Spinner variant renders correctly');
|
|
184
|
+
},
|
|
185
|
+
|
|
186
|
+
/*
|
|
187
|
+
Variants - Dots
|
|
188
|
+
*/
|
|
189
|
+
'should render dots variant': async ({pass, fail}) => {
|
|
190
|
+
const { container, spinner } = await createSpinner({ variant: 'dots' });
|
|
191
|
+
const dotsEl = spinner.shadowRoot.querySelector('.dots');
|
|
192
|
+
if(!dotsEl) {
|
|
193
|
+
cleanup(container);
|
|
194
|
+
return fail('Dots variant should render .dots element');
|
|
195
|
+
}
|
|
196
|
+
cleanup(container);
|
|
197
|
+
pass('Dots variant renders correctly');
|
|
198
|
+
},
|
|
199
|
+
|
|
200
|
+
'dots variant should have 3 spans': async ({pass, fail}) => {
|
|
201
|
+
const { container, spinner } = await createSpinner({ variant: 'dots' });
|
|
202
|
+
const spans = spinner.shadowRoot.querySelectorAll('.dots span');
|
|
203
|
+
if(spans.length !== 3) {
|
|
204
|
+
cleanup(container);
|
|
205
|
+
return fail(`Dots variant should have 3 spans, got ${spans.length}`);
|
|
206
|
+
}
|
|
207
|
+
cleanup(container);
|
|
208
|
+
pass('Dots variant has 3 spans');
|
|
209
|
+
},
|
|
210
|
+
|
|
211
|
+
/*
|
|
212
|
+
Variants - Bars
|
|
213
|
+
*/
|
|
214
|
+
'should render bars variant': async ({pass, fail}) => {
|
|
215
|
+
const { container, spinner } = await createSpinner({ variant: 'bars' });
|
|
216
|
+
const barsEl = spinner.shadowRoot.querySelector('.bars');
|
|
217
|
+
if(!barsEl) {
|
|
218
|
+
cleanup(container);
|
|
219
|
+
return fail('Bars variant should render .bars element');
|
|
220
|
+
}
|
|
221
|
+
cleanup(container);
|
|
222
|
+
pass('Bars variant renders correctly');
|
|
223
|
+
},
|
|
224
|
+
|
|
225
|
+
'bars variant should have 4 spans': async ({pass, fail}) => {
|
|
226
|
+
const { container, spinner } = await createSpinner({ variant: 'bars' });
|
|
227
|
+
const spans = spinner.shadowRoot.querySelectorAll('.bars span');
|
|
228
|
+
if(spans.length !== 4) {
|
|
229
|
+
cleanup(container);
|
|
230
|
+
return fail(`Bars variant should have 4 spans, got ${spans.length}`);
|
|
231
|
+
}
|
|
232
|
+
cleanup(container);
|
|
233
|
+
pass('Bars variant has 4 spans');
|
|
234
|
+
},
|
|
235
|
+
|
|
236
|
+
/*
|
|
237
|
+
Variants - Pulse
|
|
238
|
+
*/
|
|
239
|
+
'should render pulse variant': async ({pass, fail}) => {
|
|
240
|
+
const { container, spinner } = await createSpinner({ variant: 'pulse' });
|
|
241
|
+
const pulseEl = spinner.shadowRoot.querySelector('.pulse');
|
|
242
|
+
if(!pulseEl) {
|
|
243
|
+
cleanup(container);
|
|
244
|
+
return fail('Pulse variant should render .pulse element');
|
|
245
|
+
}
|
|
246
|
+
cleanup(container);
|
|
247
|
+
pass('Pulse variant renders correctly');
|
|
248
|
+
},
|
|
249
|
+
|
|
250
|
+
/*
|
|
251
|
+
Variants - Ring
|
|
252
|
+
*/
|
|
253
|
+
'should render ring variant': async ({pass, fail}) => {
|
|
254
|
+
const { container, spinner } = await createSpinner({ variant: 'ring' });
|
|
255
|
+
const ringEl = spinner.shadowRoot.querySelector('.ring');
|
|
256
|
+
if(!ringEl) {
|
|
257
|
+
cleanup(container);
|
|
258
|
+
return fail('Ring variant should render .ring element');
|
|
259
|
+
}
|
|
260
|
+
cleanup(container);
|
|
261
|
+
pass('Ring variant renders correctly');
|
|
262
|
+
},
|
|
263
|
+
|
|
264
|
+
/*
|
|
265
|
+
Variant Switching
|
|
266
|
+
*/
|
|
267
|
+
'should switch variants dynamically': async ({pass, fail}) => {
|
|
268
|
+
const { container, spinner } = await createSpinner({ variant: 'spinner' });
|
|
269
|
+
spinner.variant = 'dots';
|
|
270
|
+
await spinner.updateComplete;
|
|
271
|
+
const dotsEl = spinner.shadowRoot.querySelector('.dots');
|
|
272
|
+
const spinnerEl = spinner.shadowRoot.querySelector('.spinner');
|
|
273
|
+
if(!dotsEl || spinnerEl) {
|
|
274
|
+
cleanup(container);
|
|
275
|
+
return fail('Spinner should switch to dots variant');
|
|
276
|
+
}
|
|
277
|
+
cleanup(container);
|
|
278
|
+
pass('Spinner switches variants dynamically');
|
|
279
|
+
},
|
|
280
|
+
|
|
281
|
+
/*
|
|
282
|
+
Shadow DOM Structure
|
|
283
|
+
*/
|
|
284
|
+
'default variant should render spinner element': async ({pass, fail}) => {
|
|
285
|
+
const { container, spinner } = await createSpinner();
|
|
286
|
+
const spinnerEl = spinner.shadowRoot.querySelector('.spinner');
|
|
287
|
+
if(!spinnerEl) {
|
|
288
|
+
cleanup(container);
|
|
289
|
+
return fail('Default should render .spinner element');
|
|
290
|
+
}
|
|
291
|
+
cleanup(container);
|
|
292
|
+
pass('Default renders spinner element');
|
|
293
|
+
},
|
|
294
|
+
|
|
295
|
+
/*
|
|
296
|
+
Edge Cases
|
|
297
|
+
*/
|
|
298
|
+
'should handle invalid variant gracefully': async ({pass, fail}) => {
|
|
299
|
+
const { container, spinner } = await createSpinner({ variant: 'invalid' });
|
|
300
|
+
// Should fall back to default spinner variant
|
|
301
|
+
const spinnerEl = spinner.shadowRoot.querySelector('.spinner');
|
|
302
|
+
if(!spinnerEl) {
|
|
303
|
+
cleanup(container);
|
|
304
|
+
return fail('Invalid variant should fall back to default spinner');
|
|
305
|
+
}
|
|
306
|
+
cleanup(container);
|
|
307
|
+
pass('Invalid variant falls back to default');
|
|
308
|
+
},
|
|
309
|
+
|
|
310
|
+
'should handle disconnection and reconnection': async ({pass, fail}) => {
|
|
311
|
+
const { container, spinner } = await createSpinner({ variant: 'dots' });
|
|
312
|
+
spinner.remove();
|
|
313
|
+
document.body.appendChild(spinner);
|
|
314
|
+
await spinner.updateComplete;
|
|
315
|
+
const dotsEl = spinner.shadowRoot.querySelector('.dots');
|
|
316
|
+
if(!dotsEl) {
|
|
317
|
+
cleanup(container);
|
|
318
|
+
return fail('Spinner should maintain state after reconnection');
|
|
319
|
+
}
|
|
320
|
+
spinner.remove();
|
|
321
|
+
cleanup(container);
|
|
322
|
+
pass('Handles disconnection and reconnection');
|
|
323
|
+
},
|
|
324
|
+
|
|
325
|
+
'should render with custom CSS variable': async ({pass, fail}) => {
|
|
326
|
+
const { container, spinner } = await createSpinner({ style: '--spinner-color: red' });
|
|
327
|
+
// Just verify it renders without error
|
|
328
|
+
if(!spinner.shadowRoot) {
|
|
329
|
+
cleanup(container);
|
|
330
|
+
return fail('Spinner should render with custom CSS variable');
|
|
331
|
+
}
|
|
332
|
+
cleanup(container);
|
|
333
|
+
pass('Spinner renders with custom CSS variable');
|
|
334
|
+
}
|
|
335
|
+
};
|