@crowdstrike/glide-core 0.12.1 → 0.12.3
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/checkbox-group.styles.js +1 -1
- package/dist/dropdown.d.ts +5 -1
- package/dist/dropdown.js +126 -58
- package/dist/dropdown.option.d.ts +3 -0
- package/dist/dropdown.option.js +1 -1
- package/dist/dropdown.option.styles.js +81 -16
- package/dist/dropdown.option.test.basics.js +4 -33
- package/dist/dropdown.option.test.basics.multiple.js +9 -0
- package/dist/dropdown.option.test.basics.single.js +8 -0
- package/dist/dropdown.option.test.interactions.multiple.js +12 -0
- package/dist/dropdown.option.test.interactions.single.js +11 -0
- package/dist/dropdown.styles.js +127 -29
- package/dist/dropdown.test.basics.filterable.js +11 -54
- package/dist/dropdown.test.basics.js +24 -244
- package/dist/dropdown.test.basics.multiple.js +13 -60
- package/dist/dropdown.test.basics.single.js +2 -8
- package/dist/dropdown.test.events.filterable.js +12 -54
- package/dist/dropdown.test.events.js +139 -46
- package/dist/dropdown.test.events.multiple.js +17 -87
- package/dist/dropdown.test.events.single.js +99 -60
- package/dist/dropdown.test.focus.filterable.js +13 -60
- package/dist/dropdown.test.focus.js +64 -11
- package/dist/dropdown.test.focus.multiple.js +36 -46
- package/dist/dropdown.test.focus.single.js +28 -23
- package/dist/dropdown.test.form.js +22 -0
- package/dist/dropdown.test.interactions.filterable.js +86 -72
- package/dist/dropdown.test.interactions.js +361 -207
- package/dist/dropdown.test.interactions.multiple.js +152 -279
- package/dist/dropdown.test.interactions.single.js +62 -98
- package/dist/dropdown.test.validity.js +12 -49
- package/dist/icons/pencil.d.ts +2 -0
- package/dist/icons/pencil.js +1 -0
- package/dist/label.js +1 -1
- package/dist/label.styles.js +7 -3
- package/dist/library/localize.d.ts +2 -0
- package/dist/menu.js +1 -1
- package/dist/menu.options.js +1 -1
- package/dist/menu.options.test.events.d.ts +1 -0
- package/dist/menu.options.test.events.js +19 -0
- package/dist/menu.test.interactions.d.ts +1 -0
- package/dist/menu.test.interactions.js +38 -0
- package/dist/radio-group.styles.js +1 -1
- package/dist/tab.group.d.ts +8 -1
- package/dist/tab.group.js +1 -1
- package/dist/tab.group.styles.js +4 -0
- package/dist/tab.group.test.basics.js +77 -1
- package/dist/tab.panel.js +1 -1
- package/dist/tab.panel.styles.js +15 -0
- package/dist/tag.d.ts +2 -0
- package/dist/tag.js +1 -1
- package/dist/tag.styles.js +46 -5
- package/dist/tag.test.basics.js +1 -1
- package/dist/tag.test.events.js +76 -3
- package/dist/tag.test.focus.js +1 -1
- package/dist/textarea.styles.js +1 -1
- package/dist/translations/en.js +1 -1
- package/dist/translations/fr.d.ts +1 -1
- package/dist/translations/fr.js +1 -1
- package/dist/translations/ja.d.ts +1 -1
- package/dist/translations/ja.js +1 -1
- package/package.json +1 -1
@@ -9,17 +9,14 @@ GlideCoreDropdown.shadowRootOptions.mode = 'open';
|
|
9
9
|
GlideCoreDropdownOption.shadowRootOptions.mode = 'open';
|
10
10
|
it('opens on click', async () => {
|
11
11
|
const component = await fixture(html `<glide-core-dropdown label="Label" placeholder="Placeholder">
|
12
|
-
<glide-core-dropdown-option
|
13
|
-
label="Label"
|
14
|
-
value="value"
|
15
|
-
></glide-core-dropdown-option>
|
12
|
+
<glide-core-dropdown-option label="Label"></glide-core-dropdown-option>
|
16
13
|
</glide-core-dropdown>`);
|
17
14
|
// Calling `click()` would be sweet. The problem is it sets `event.detail` to `0`,
|
18
15
|
// which puts us in a guard in the event handler. `Event` has no `detail` property
|
19
16
|
// and would work. `CustomEvent` is used for completeness and to get us as close as
|
20
17
|
// possible to a real click. See the comment in the handler for more information.
|
21
18
|
component.shadowRoot
|
22
|
-
?.querySelector('[data-test="button"]')
|
19
|
+
?.querySelector('[data-test="primary-button"]')
|
23
20
|
?.dispatchEvent(new CustomEvent('click', { bubbles: true, detail: 1 }));
|
24
21
|
// Wait for it to open.
|
25
22
|
await aTimeout(0);
|
@@ -27,19 +24,16 @@ it('opens on click', async () => {
|
|
27
24
|
expect(component.open).to.be.true;
|
28
25
|
expect(options?.checkVisibility()).to.be.true;
|
29
26
|
});
|
30
|
-
it('toggles open and closed when the button is clicked', async () => {
|
27
|
+
it('toggles open and closed when the primary button is clicked', async () => {
|
31
28
|
const component = await fixture(html `<glide-core-dropdown label="Label" placeholder="Placeholder" open>
|
32
|
-
<glide-core-dropdown-option
|
33
|
-
label="Label"
|
34
|
-
value="value"
|
35
|
-
></glide-core-dropdown-option>
|
29
|
+
<glide-core-dropdown-option label="Label"></glide-core-dropdown-option>
|
36
30
|
</glide-core-dropdown>`);
|
37
31
|
// Calling `click()` would be sweet. The problem is it sets `event.detail` to `0`,
|
38
32
|
// which puts us in a guard in the event handler. `Event` has no `detail` property
|
39
33
|
// and would work. `CustomEvent` is used for completeness and to get us as close as
|
40
34
|
// possible to a real click. See the comment in the handler for more information.
|
41
35
|
component.shadowRoot
|
42
|
-
?.querySelector('[data-test="button"]')
|
36
|
+
?.querySelector('[data-test="primary-button"]')
|
43
37
|
?.dispatchEvent(new CustomEvent('click', { bubbles: true, detail: 1 }));
|
44
38
|
await elementUpdated(component);
|
45
39
|
const options = component.shadowRoot?.querySelector('[data-test="options"]');
|
@@ -48,10 +42,7 @@ it('toggles open and closed when the button is clicked', async () => {
|
|
48
42
|
});
|
49
43
|
it('does not toggle open and closed when the button overflow text is clicked', async () => {
|
50
44
|
const component = await fixture(html `<glide-core-dropdown label="Label" placeholder="Placeholder" open>
|
51
|
-
<glide-core-dropdown-option
|
52
|
-
label="Label"
|
53
|
-
value="value"
|
54
|
-
></glide-core-dropdown-option>
|
45
|
+
<glide-core-dropdown-option label="Label"></glide-core-dropdown-option>
|
55
46
|
</glide-core-dropdown>`);
|
56
47
|
// Calling `click()` would be sweet. The problem is it sets `event.detail` to `0`,
|
57
48
|
// which puts us in a guard in the event handler. `Event` has no `detail` property
|
@@ -68,10 +59,7 @@ it('does not toggle open and closed when the button overflow text is clicked', a
|
|
68
59
|
});
|
69
60
|
it('selects an option on click', async () => {
|
70
61
|
const component = await fixture(html `<glide-core-dropdown label="Label" placeholder="Placeholder" open>
|
71
|
-
<glide-core-dropdown-option
|
72
|
-
label="One"
|
73
|
-
value="one"
|
74
|
-
></glide-core-dropdown-option>
|
62
|
+
<glide-core-dropdown-option label="One"></glide-core-dropdown-option>
|
75
63
|
</glide-core-dropdown>`);
|
76
64
|
// Wait for it to open.
|
77
65
|
await aTimeout(0);
|
@@ -139,10 +127,7 @@ it('does not deselect options on Space', async () => {
|
|
139
127
|
});
|
140
128
|
it('selects an option on Enter', async () => {
|
141
129
|
const component = await fixture(html `<glide-core-dropdown label="Label" placeholder="Placeholder" open>
|
142
|
-
<glide-core-dropdown-option
|
143
|
-
label="One"
|
144
|
-
value="one"
|
145
|
-
></glide-core-dropdown-option>
|
130
|
+
<glide-core-dropdown-option label="One"></glide-core-dropdown-option>
|
146
131
|
</glide-core-dropdown>`);
|
147
132
|
// Wait for it to open.
|
148
133
|
await aTimeout(0);
|
@@ -153,15 +138,9 @@ it('selects an option on Enter', async () => {
|
|
153
138
|
});
|
154
139
|
it('deactivates all other options on "mouseover"', async () => {
|
155
140
|
const component = await fixture(html `<glide-core-dropdown open>
|
156
|
-
<glide-core-dropdown-option
|
157
|
-
label="One"
|
158
|
-
value="one"
|
159
|
-
></glide-core-dropdown-option>
|
141
|
+
<glide-core-dropdown-option label="One"></glide-core-dropdown-option>
|
160
142
|
|
161
|
-
<glide-core-dropdown-option
|
162
|
-
label="Two"
|
163
|
-
value="two"
|
164
|
-
></glide-core-dropdown-option>
|
143
|
+
<glide-core-dropdown-option label="Two"></glide-core-dropdown-option>
|
165
144
|
</glide-core-dropdown>`);
|
166
145
|
const options = component.querySelectorAll('glide-core-dropdown-option');
|
167
146
|
options[0]?.dispatchEvent(new MouseEvent('mouseover', { bubbles: true }));
|
@@ -171,10 +150,7 @@ it('deactivates all other options on "mouseover"', async () => {
|
|
171
150
|
});
|
172
151
|
it('closes when an option is selected via click', async () => {
|
173
152
|
const component = await fixture(html `<glide-core-dropdown label="Label" placeholder="Placeholder" open>
|
174
|
-
<glide-core-dropdown-option
|
175
|
-
label="Label"
|
176
|
-
value="value"
|
177
|
-
></glide-core-dropdown-option>
|
153
|
+
<glide-core-dropdown-option label="Label"></glide-core-dropdown-option>
|
178
154
|
</glide-core-dropdown>`);
|
179
155
|
// Wait for it to open.
|
180
156
|
await aTimeout(0);
|
@@ -183,10 +159,7 @@ it('closes when an option is selected via click', async () => {
|
|
183
159
|
});
|
184
160
|
it('closes when an option is selected via Space', async () => {
|
185
161
|
const component = await fixture(html `<glide-core-dropdown label="Label" placeholder="Placeholder" open>
|
186
|
-
<glide-core-dropdown-option
|
187
|
-
label="Label"
|
188
|
-
value="value"
|
189
|
-
></glide-core-dropdown-option>
|
162
|
+
<glide-core-dropdown-option label="Label"></glide-core-dropdown-option>
|
190
163
|
</glide-core-dropdown>`);
|
191
164
|
// Wait for it to open.
|
192
165
|
await aTimeout(0);
|
@@ -196,10 +169,7 @@ it('closes when an option is selected via Space', async () => {
|
|
196
169
|
});
|
197
170
|
it('closes when an option is selected via Enter', async () => {
|
198
171
|
const component = await fixture(html `<glide-core-dropdown label="Label" placeholder="Placeholder" open>
|
199
|
-
<glide-core-dropdown-option
|
200
|
-
label="Label"
|
201
|
-
value="value"
|
202
|
-
></glide-core-dropdown-option>
|
172
|
+
<glide-core-dropdown-option label="Label"></glide-core-dropdown-option>
|
203
173
|
</glide-core-dropdown>`);
|
204
174
|
// Wait for it to open.
|
205
175
|
await aTimeout(0);
|
@@ -209,10 +179,7 @@ it('closes when an option is selected via Enter', async () => {
|
|
209
179
|
});
|
210
180
|
it('closes when an option is selected via Enter', async () => {
|
211
181
|
const component = await fixture(html `<glide-core-dropdown label="Label" placeholder="Placeholder" open>
|
212
|
-
<glide-core-dropdown-option
|
213
|
-
label="Label"
|
214
|
-
value="value"
|
215
|
-
></glide-core-dropdown-option>
|
182
|
+
<glide-core-dropdown-option label="Label"></glide-core-dropdown-option>
|
216
183
|
</glide-core-dropdown>`);
|
217
184
|
// Wait for it to open.
|
218
185
|
await aTimeout(0);
|
@@ -222,10 +189,7 @@ it('closes when an option is selected via Enter', async () => {
|
|
222
189
|
});
|
223
190
|
it('closes when an option is selected via Space', async () => {
|
224
191
|
const component = await fixture(html `<glide-core-dropdown label="Label" placeholder="Placeholder" open>
|
225
|
-
<glide-core-dropdown-option
|
226
|
-
label="Label"
|
227
|
-
value="value"
|
228
|
-
></glide-core-dropdown-option>
|
192
|
+
<glide-core-dropdown-option label="Label"></glide-core-dropdown-option>
|
229
193
|
</glide-core-dropdown>`);
|
230
194
|
// Wait for it to open.
|
231
195
|
await aTimeout(0);
|
@@ -246,26 +210,33 @@ it('closes when an already selected option is clicked', async () => {
|
|
246
210
|
component.querySelector('glide-core-dropdown-option')?.click();
|
247
211
|
expect(component.open).to.be.false;
|
248
212
|
});
|
213
|
+
it('closes on edit via click', async () => {
|
214
|
+
const component = await fixture(html `<glide-core-dropdown label="Label" placeholder="Placeholder" open>
|
215
|
+
<glide-core-dropdown-option
|
216
|
+
label="Label"
|
217
|
+
editable
|
218
|
+
selected
|
219
|
+
></glide-core-dropdown-option>
|
220
|
+
</glide-core-dropdown>`);
|
221
|
+
// Wait for it to open.
|
222
|
+
await aTimeout(0);
|
223
|
+
component.shadowRoot
|
224
|
+
?.querySelector('[data-test="edit-button"]')
|
225
|
+
?.click();
|
226
|
+
expect(component.open).to.be.false;
|
227
|
+
});
|
249
228
|
it('deselects all other options when one is newly selected', async () => {
|
250
229
|
const component = await fixture(html `<glide-core-dropdown label="Label" placeholder="Placeholder">
|
251
230
|
<glide-core-dropdown-option
|
252
231
|
label="One"
|
253
|
-
value="one"
|
254
232
|
selected
|
255
233
|
></glide-core-dropdown-option>
|
256
234
|
|
257
|
-
<glide-core-dropdown-option
|
258
|
-
|
259
|
-
value="two"
|
260
|
-
></glide-core-dropdown-option>
|
261
|
-
|
262
|
-
<glide-core-dropdown-option
|
263
|
-
label="Three"
|
264
|
-
value="three"
|
265
|
-
></glide-core-dropdown-option>
|
235
|
+
<glide-core-dropdown-option label="Two"></glide-core-dropdown-option>
|
236
|
+
<glide-core-dropdown-option label="Three"></glide-core-dropdown-option>
|
266
237
|
</glide-core-dropdown>`);
|
267
238
|
component.shadowRoot
|
268
|
-
?.querySelector('[data-test="button"]')
|
239
|
+
?.querySelector('[data-test="primary-button"]')
|
269
240
|
?.dispatchEvent(new Event('click'));
|
270
241
|
const options = component.querySelectorAll('glide-core-dropdown-option');
|
271
242
|
options[1].click();
|
@@ -273,7 +244,7 @@ it('deselects all other options when one is newly selected', async () => {
|
|
273
244
|
expect(options[1].selected).to.be.true;
|
274
245
|
expect(options[2].selected).to.be.false;
|
275
246
|
});
|
276
|
-
it('updates its internal label when
|
247
|
+
it('updates its internal label when `label` of the selected option is changed programmatically', async () => {
|
277
248
|
const component = await fixture(html `<glide-core-dropdown label="Label" placeholder="Placeholder">
|
278
249
|
<glide-core-dropdown-option
|
279
250
|
label="One"
|
@@ -287,6 +258,20 @@ it('updates its internal label when the `label` of a selected option is changed
|
|
287
258
|
const label = component.shadowRoot?.querySelector('[data-test="internal-label"]');
|
288
259
|
expect(label?.textContent?.trim()).to.equal(option?.label);
|
289
260
|
});
|
261
|
+
it('shows an Edit button when `editable` of the selected option is changed programmatically', async () => {
|
262
|
+
const component = await fixture(html `<glide-core-dropdown label="Label" placeholder="Placeholder">
|
263
|
+
<glide-core-dropdown-option
|
264
|
+
label="One"
|
265
|
+
selected
|
266
|
+
></glide-core-dropdown-option>
|
267
|
+
</glide-core-dropdown>`);
|
268
|
+
const option = component.querySelector('glide-core-dropdown-option');
|
269
|
+
assert(option);
|
270
|
+
option.editable = true;
|
271
|
+
await elementUpdated(component);
|
272
|
+
const editButton = component.shadowRoot?.querySelector('[data-test="edit-button"]');
|
273
|
+
expect(editButton?.checkVisibility()).to.be.true;
|
274
|
+
});
|
290
275
|
it('selects and deselects options when `value` is changed programmatically', async () => {
|
291
276
|
const component = await fixture(html `<glide-core-dropdown label="Label" placeholder="Placeholder">
|
292
277
|
<glide-core-dropdown-option
|
@@ -360,7 +345,7 @@ it('updates `value` when an option is selected via click', async () => {
|
|
360
345
|
expect(component.value).to.deep.equal(['two']);
|
361
346
|
// Reopen it.
|
362
347
|
component.shadowRoot
|
363
|
-
?.querySelector('[data-test="button"]')
|
348
|
+
?.querySelector('[data-test="primary-button"]')
|
364
349
|
?.dispatchEvent(new CustomEvent('click', { detail: 1 }));
|
365
350
|
// Wait for it to open.
|
366
351
|
await elementUpdated(component);
|
@@ -368,7 +353,7 @@ it('updates `value` when an option is selected via click', async () => {
|
|
368
353
|
expect(component.value).to.deep.equal(['two']);
|
369
354
|
// Reopen it.
|
370
355
|
component.shadowRoot
|
371
|
-
?.querySelector('[data-test="button"]')
|
356
|
+
?.querySelector('[data-test="primary-button"]')
|
372
357
|
?.dispatchEvent(new CustomEvent('click', { detail: 1 }));
|
373
358
|
// Wait for it to open.
|
374
359
|
await elementUpdated(component);
|
@@ -397,7 +382,7 @@ it('updates `value` when an option is selected via Enter', async () => {
|
|
397
382
|
expect(component.value).to.deep.equal(['one']);
|
398
383
|
// Reopen it.
|
399
384
|
component.shadowRoot
|
400
|
-
?.querySelector('[data-test="button"]')
|
385
|
+
?.querySelector('[data-test="primary-button"]')
|
401
386
|
?.dispatchEvent(new CustomEvent('click', { bubbles: true, detail: 1 }));
|
402
387
|
// Wait for it to open.
|
403
388
|
await aTimeout(0);
|
@@ -406,7 +391,7 @@ it('updates `value` when an option is selected via Enter', async () => {
|
|
406
391
|
expect(component.value).to.deep.equal(['two']);
|
407
392
|
// Reopen it.
|
408
393
|
component.shadowRoot
|
409
|
-
?.querySelector('[data-test="button"]')
|
394
|
+
?.querySelector('[data-test="primary-button"]')
|
410
395
|
?.dispatchEvent(new CustomEvent('click', { bubbles: true, detail: 1 }));
|
411
396
|
// Wait for it to open.
|
412
397
|
await aTimeout(0);
|
@@ -436,7 +421,7 @@ it('updates `value` when an option is selected via Space', async () => {
|
|
436
421
|
expect(component.value).to.deep.equal(['one']);
|
437
422
|
// Reopen it.
|
438
423
|
component.shadowRoot
|
439
|
-
?.querySelector('[data-test="button"]')
|
424
|
+
?.querySelector('[data-test="primary-button"]')
|
440
425
|
?.dispatchEvent(new CustomEvent('click', { bubbles: true, detail: 1 }));
|
441
426
|
// Wait for it to open.
|
442
427
|
await aTimeout(0);
|
@@ -445,7 +430,7 @@ it('updates `value` when an option is selected via Space', async () => {
|
|
445
430
|
expect(component.value).to.deep.equal(['two']);
|
446
431
|
// Reopen it.
|
447
432
|
component.shadowRoot
|
448
|
-
?.querySelector('[data-test="button"]')
|
433
|
+
?.querySelector('[data-test="primary-button"]')
|
449
434
|
?.dispatchEvent(new CustomEvent('click', { bubbles: true, detail: 1 }));
|
450
435
|
// Wait for it to open.
|
451
436
|
await aTimeout(0);
|
@@ -537,41 +522,27 @@ it('hides Select All', async () => {
|
|
537
522
|
>
|
538
523
|
<glide-core-dropdown-option
|
539
524
|
label="One"
|
540
|
-
value="one"
|
541
525
|
selected
|
542
526
|
></glide-core-dropdown-option>
|
543
527
|
|
544
|
-
<glide-core-dropdown-option
|
545
|
-
label="Two"
|
546
|
-
value="two"
|
547
|
-
></glide-core-dropdown-option>
|
528
|
+
<glide-core-dropdown-option label="Two"></glide-core-dropdown-option>
|
548
529
|
</glide-core-dropdown>`);
|
549
530
|
const selectAll = component.shadowRoot?.querySelector('[data-test="select-all"]');
|
550
531
|
expect(selectAll?.checkVisibility()).to.not.be.ok;
|
551
532
|
});
|
552
533
|
it('cannot be tabbed to when `disabled`', async () => {
|
553
534
|
await fixture(html `<glide-core-dropdown label="Label" placeholder="Placeholder" disabled>
|
554
|
-
<glide-core-dropdown-option
|
555
|
-
|
556
|
-
value="one"
|
557
|
-
></glide-core-dropdown-option>
|
558
|
-
|
559
|
-
<glide-core-dropdown-option
|
560
|
-
label="Two"
|
561
|
-
value="two"
|
562
|
-
></glide-core-dropdown-option>
|
535
|
+
<glide-core-dropdown-option label="One"></glide-core-dropdown-option>
|
536
|
+
<glide-core-dropdown-option label="Two"></glide-core-dropdown-option>
|
563
537
|
</glide-core-dropdown>`);
|
564
538
|
await sendKeys({ down: 'Tab' });
|
565
539
|
expect(document.activeElement).to.equal(document.body);
|
566
540
|
});
|
567
|
-
it('clicks the button when `click()` is called', async () => {
|
541
|
+
it('clicks the primary button when `click()` is called', async () => {
|
568
542
|
const component = await fixture(html `<glide-core-dropdown label="Label" placeholder="Placeholder">
|
569
|
-
<glide-core-dropdown-option
|
570
|
-
label="Label"
|
571
|
-
value="value"
|
572
|
-
></glide-core-dropdown-option>
|
543
|
+
<glide-core-dropdown-option label="Label"></glide-core-dropdown-option>
|
573
544
|
</glide-core-dropdown>`);
|
574
|
-
const button = component.shadowRoot?.querySelector('[data-test="button"]');
|
545
|
+
const button = component.shadowRoot?.querySelector('[data-test="primary-button"]');
|
575
546
|
assert(button);
|
576
547
|
setTimeout(() => {
|
577
548
|
component.click();
|
@@ -585,15 +556,8 @@ it('unhides its options when made unfilterable', async () => {
|
|
585
556
|
placeholder="Placeholder"
|
586
557
|
filterable
|
587
558
|
>
|
588
|
-
<glide-core-dropdown-option
|
589
|
-
|
590
|
-
value="one"
|
591
|
-
></glide-core-dropdown-option>
|
592
|
-
|
593
|
-
<glide-core-dropdown-option
|
594
|
-
label="Two"
|
595
|
-
value="two"
|
596
|
-
></glide-core-dropdown-option>
|
559
|
+
<glide-core-dropdown-option label="One"></glide-core-dropdown-option>
|
560
|
+
<glide-core-dropdown-option label="Two"></glide-core-dropdown-option>
|
597
561
|
</glide-core-dropdown>`);
|
598
562
|
component.focus();
|
599
563
|
await sendKeys({ type: 'one' });
|
@@ -7,7 +7,6 @@ it('is valid if not required and no option is selected', async () => {
|
|
7
7
|
const component = await fixture(html `<glide-core-dropdown label="Label" placeholder="Placeholder">
|
8
8
|
<glide-core-dropdown-option
|
9
9
|
label="Label"
|
10
|
-
value="value"
|
11
10
|
selected
|
12
11
|
></glide-core-dropdown-option>
|
13
12
|
</glide-core-dropdown>`);
|
@@ -18,10 +17,7 @@ it('is valid if not required and no option is selected', async () => {
|
|
18
17
|
});
|
19
18
|
it('is invalid if required and no option is selected', async () => {
|
20
19
|
const component = await fixture(html `<glide-core-dropdown label="Label" placeholder="Placeholder" required>
|
21
|
-
<glide-core-dropdown-option
|
22
|
-
label="Label"
|
23
|
-
value="value"
|
24
|
-
></glide-core-dropdown-option>
|
20
|
+
<glide-core-dropdown-option label="Label"></glide-core-dropdown-option>
|
25
21
|
</glide-core-dropdown>`);
|
26
22
|
expect(component.validity.valid).to.be.false;
|
27
23
|
expect(component.validity?.valueMissing).to.be.true;
|
@@ -35,10 +31,7 @@ it('is invalid if required and no option is selected when `filterable`', async (
|
|
35
31
|
filterable
|
36
32
|
required
|
37
33
|
>
|
38
|
-
<glide-core-dropdown-option
|
39
|
-
label="Label"
|
40
|
-
value="value"
|
41
|
-
></glide-core-dropdown-option>
|
34
|
+
<glide-core-dropdown-option label="Label"></glide-core-dropdown-option>
|
42
35
|
</glide-core-dropdown>`);
|
43
36
|
expect(component.validity.valid).to.be.false;
|
44
37
|
expect(component.validity?.valueMissing).to.be.true;
|
@@ -52,10 +45,7 @@ it('is both invalid and valid if required but disabled and no option is selected
|
|
52
45
|
disabled
|
53
46
|
required
|
54
47
|
>
|
55
|
-
<glide-core-dropdown-option
|
56
|
-
label="Label"
|
57
|
-
value="value"
|
58
|
-
></glide-core-dropdown-option>
|
48
|
+
<glide-core-dropdown-option label="Label"></glide-core-dropdown-option>
|
59
49
|
</glide-core-dropdown>`);
|
60
50
|
expect(component.validity.valid).to.be.false;
|
61
51
|
expect(component.validity?.valueMissing).to.be.true;
|
@@ -64,10 +54,7 @@ it('is both invalid and valid if required but disabled and no option is selected
|
|
64
54
|
});
|
65
55
|
it('sets the validity message with `setCustomValidity()`', async () => {
|
66
56
|
const component = await fixture(html `<glide-core-dropdown label="Label">
|
67
|
-
<glide-core-dropdown-option
|
68
|
-
label="Label"
|
69
|
-
value="value"
|
70
|
-
></glide-core-dropdown-option>
|
57
|
+
<glide-core-dropdown-option label="Label"></glide-core-dropdown-option>
|
71
58
|
</glide-core-dropdown>`);
|
72
59
|
component.setCustomValidity('validity message');
|
73
60
|
expect(component.validity?.valid).to.be.false;
|
@@ -84,10 +71,7 @@ it('sets the validity message with `setCustomValidity()`', async () => {
|
|
84
71
|
});
|
85
72
|
it('removes a validity message with an empty argument to `setCustomValidity()`', async () => {
|
86
73
|
const component = await fixture(html `<glide-core-dropdown label="Label">
|
87
|
-
<glide-core-dropdown-option
|
88
|
-
label="Label"
|
89
|
-
value="value"
|
90
|
-
></glide-core-dropdown-option>
|
74
|
+
<glide-core-dropdown-option label="Label"></glide-core-dropdown-option>
|
91
75
|
</glide-core-dropdown>`);
|
92
76
|
component.setCustomValidity('validity message');
|
93
77
|
component.reportValidity();
|
@@ -99,10 +83,7 @@ it('removes a validity message with an empty argument to `setCustomValidity()`',
|
|
99
83
|
});
|
100
84
|
it('is invalid when `setValidity()` is called', async () => {
|
101
85
|
const component = await fixture(html `<glide-core-dropdown label="Label">
|
102
|
-
<glide-core-dropdown-option
|
103
|
-
label="Label"
|
104
|
-
value="value"
|
105
|
-
></glide-core-dropdown-option>
|
86
|
+
<glide-core-dropdown-option label="Label"></glide-core-dropdown-option>
|
106
87
|
</glide-core-dropdown>`);
|
107
88
|
component.setValidity({ customError: true }, 'validity message');
|
108
89
|
expect(component.validity.valid).to.be.false;
|
@@ -118,10 +99,7 @@ it('is invalid when `setValidity()` is called', async () => {
|
|
118
99
|
});
|
119
100
|
it('is valid when `setValidity()` is called', async () => {
|
120
101
|
const component = await fixture(html `<glide-core-dropdown label="Label">
|
121
|
-
<glide-core-dropdown-option
|
122
|
-
label="Label"
|
123
|
-
value="value"
|
124
|
-
></glide-core-dropdown-option>
|
102
|
+
<glide-core-dropdown-option label="Label"></glide-core-dropdown-option>
|
125
103
|
</glide-core-dropdown>`);
|
126
104
|
component.setValidity({ customError: true }, 'validity message');
|
127
105
|
component.setValidity({});
|
@@ -135,10 +113,7 @@ it('is valid when `setValidity()` is called', async () => {
|
|
135
113
|
});
|
136
114
|
it('sets the validity message with `setCustomValidity()` when `filterable`', async () => {
|
137
115
|
const component = await fixture(html `<glide-core-dropdown label="Label" filterable>
|
138
|
-
<glide-core-dropdown-option
|
139
|
-
label="Label"
|
140
|
-
value="value"
|
141
|
-
></glide-core-dropdown-option>
|
116
|
+
<glide-core-dropdown-option label="Label"></glide-core-dropdown-option>
|
142
117
|
</glide-core-dropdown>`);
|
143
118
|
component.setCustomValidity('validity message');
|
144
119
|
expect(component.validity?.valid).to.be.false;
|
@@ -155,10 +130,7 @@ it('sets the validity message with `setCustomValidity()` when `filterable`', asy
|
|
155
130
|
});
|
156
131
|
it('removes a validity message with an empty argument to `setCustomValidity()` when `filterable`', async () => {
|
157
132
|
const component = await fixture(html `<glide-core-dropdown label="Label" filterable>
|
158
|
-
<glide-core-dropdown-option
|
159
|
-
label="Label"
|
160
|
-
value="value"
|
161
|
-
></glide-core-dropdown-option>
|
133
|
+
<glide-core-dropdown-option label="Label"></glide-core-dropdown-option>
|
162
134
|
</glide-core-dropdown>`);
|
163
135
|
component.setCustomValidity('validity message');
|
164
136
|
component.reportValidity();
|
@@ -170,10 +142,7 @@ it('removes a validity message with an empty argument to `setCustomValidity()` w
|
|
170
142
|
});
|
171
143
|
it('is invalid when `setValidity()` is called when `filterable`', async () => {
|
172
144
|
const component = await fixture(html `<glide-core-dropdown label="Label" filterable>
|
173
|
-
<glide-core-dropdown-option
|
174
|
-
label="Label"
|
175
|
-
value="value"
|
176
|
-
></glide-core-dropdown-option>
|
145
|
+
<glide-core-dropdown-option label="Label"></glide-core-dropdown-option>
|
177
146
|
</glide-core-dropdown>`);
|
178
147
|
component.setValidity({ customError: true }, 'validity message');
|
179
148
|
expect(component.validity.valid).to.be.false;
|
@@ -189,10 +158,7 @@ it('is invalid when `setValidity()` is called when `filterable`', async () => {
|
|
189
158
|
});
|
190
159
|
it('is valid when `setValidity()` is called when `filterable`', async () => {
|
191
160
|
const component = await fixture(html `<glide-core-dropdown label="Label" filterable>
|
192
|
-
<glide-core-dropdown-option
|
193
|
-
label="Label"
|
194
|
-
value="value"
|
195
|
-
></glide-core-dropdown-option>
|
161
|
+
<glide-core-dropdown-option label="Label"></glide-core-dropdown-option>
|
196
162
|
</glide-core-dropdown>`);
|
197
163
|
component.setValidity({ customError: true }, 'validity message');
|
198
164
|
component.setValidity({});
|
@@ -206,10 +172,7 @@ it('is valid when `setValidity()` is called when `filterable`', async () => {
|
|
206
172
|
});
|
207
173
|
it('retains existing validity state when `setCustomValidity()` is called', async () => {
|
208
174
|
const component = await fixture(html `<glide-core-dropdown label="Label" required>
|
209
|
-
<glide-core-dropdown-option
|
210
|
-
label="Label"
|
211
|
-
value="value"
|
212
|
-
></glide-core-dropdown-option>
|
175
|
+
<glide-core-dropdown-option label="Label"></glide-core-dropdown-option>
|
213
176
|
</glide-core-dropdown>`);
|
214
177
|
component.setCustomValidity('validity message');
|
215
178
|
expect(component.validity?.valid).to.be.false;
|
@@ -0,0 +1 @@
|
|
1
|
+
import{html}from"lit";export default html`<svg aria-hidden="true" width="14" height="14" viewBox="0 0 14 14" fill="none" style="height: var(--size, 0.875rem); width: var(--size, 0.875rem);"><path d="M10.0244 5.95031L8.0395 3.96536M2.06587 11.924L3.74532 11.7374C3.95051 11.7146 4.0531 11.7032 4.149 11.6721C4.23407 11.6446 4.31504 11.6057 4.38969 11.5564C4.47384 11.501 4.54683 11.428 4.69281 11.282L11.5132 4.4616C12.0613 3.91347 12.0613 3.02478 11.5132 2.47665C10.965 1.92852 10.0763 1.92852 9.52821 2.47665L2.70786 9.29703C2.56188 9.44302 2.48889 9.51601 2.4334 9.60015C2.38417 9.67481 2.34526 9.75577 2.31772 9.84085C2.28667 9.93674 2.27527 10.0393 2.25247 10.2445L2.06587 11.924Z" stroke="currentColor" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round"/></svg>`;
|
package/dist/label.js
CHANGED
@@ -1 +1 @@
|
|
1
|
-
var __decorate=this&&this.__decorate||function(e,t,o,l){var i,s=arguments.length,r=s<3?t:null===l?l=Object.getOwnPropertyDescriptor(t,o):l;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)r=Reflect.decorate(e,t,o,l);else for(var a=e.length-1;a>=0;a--)(i=e[a])&&(r=(s<3?i(r):s>3?i(t,o,r):i(t,o))||r);return s>3&&r&&Object.defineProperty(t,o,r),r};import"./tooltip.js";import{LitElement,html,svg}from"lit";import{LocalizeController}from"./library/localize.js";import{classMap}from"lit/directives/class-map.js";import{createRef,ref}from"lit/directives/ref.js";import{customElement,property,state}from"lit/decorators.js";import ow,{owSlot}from"./library/ow.js";import styles from"./label.styles.js";const infoCircleIcon=svg`<circle cx="12" cy="12" r="10" stroke="currentColor" stroke-width="2"><path d="M12 16L12 12" stroke="currentColor" stroke-width="2" stroke-linecap="round"><circle cx="12" cy="8" r="1" fill="currentColor">`;let GlideCoreLabel=class GlideCoreLabel extends LitElement{constructor(){super(...arguments),this.disabled=!1,this.error=!1,this.hide=!1,this.orientation="horizontal",this.required=!1,this.hasDescription=!1,this.hasSummarySlot=!1,this.hasTooltipSlot=!1,this.isLabelTooltip=!1,this.label="",this.#e=createRef(),this.#t=createRef(),this.#o=createRef(),this.#l=createRef(),this.#i=new LocalizeController(this),this.#s=createRef(),this.#r=createRef()}static{this.shadowRootOptions={...LitElement.shadowRootOptions,mode:"closed"}}static{this.styles=styles}firstUpdated(){owSlot(this.#t.value),owSlot(this.#e.value);const e=new ResizeObserver((()=>{this.hasDescription=Boolean(this.#o.value&&this.#o.value.offsetHeight>0)}));this.#o.value&&e.observe(this.#o.value)}render(){return html`<div class="${classMap({component:!0,horizontal:"horizontal"===this.orientation,vertical:"vertical"===this.orientation,left:"left"===this.split,middle:"middle"===this.split,"hidden-label":this.hide})}"><div class="${classMap({
|
1
|
+
var __decorate=this&&this.__decorate||function(e,t,o,l){var i,s=arguments.length,r=s<3?t:null===l?l=Object.getOwnPropertyDescriptor(t,o):l;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)r=Reflect.decorate(e,t,o,l);else for(var a=e.length-1;a>=0;a--)(i=e[a])&&(r=(s<3?i(r):s>3?i(t,o,r):i(t,o))||r);return s>3&&r&&Object.defineProperty(t,o,r),r};import"./tooltip.js";import{LitElement,html,svg}from"lit";import{LocalizeController}from"./library/localize.js";import{classMap}from"lit/directives/class-map.js";import{createRef,ref}from"lit/directives/ref.js";import{customElement,property,state}from"lit/decorators.js";import ow,{owSlot}from"./library/ow.js";import styles from"./label.styles.js";const infoCircleIcon=svg`<circle cx="12" cy="12" r="10" stroke="currentColor" stroke-width="2"><path d="M12 16L12 12" stroke="currentColor" stroke-width="2" stroke-linecap="round"><circle cx="12" cy="8" r="1" fill="currentColor">`;let GlideCoreLabel=class GlideCoreLabel extends LitElement{constructor(){super(...arguments),this.disabled=!1,this.error=!1,this.hide=!1,this.orientation="horizontal",this.required=!1,this.hasDescription=!1,this.hasSummarySlot=!1,this.hasTooltipSlot=!1,this.isLabelTooltip=!1,this.label="",this.#e=createRef(),this.#t=createRef(),this.#o=createRef(),this.#l=createRef(),this.#i=new LocalizeController(this),this.#s=createRef(),this.#r=createRef()}static{this.shadowRootOptions={...LitElement.shadowRootOptions,mode:"closed"}}static{this.styles=styles}firstUpdated(){owSlot(this.#t.value),owSlot(this.#e.value);const e=new ResizeObserver((()=>{this.hasDescription=Boolean(this.#o.value&&this.#o.value.offsetHeight>0)}));this.#o.value&&e.observe(this.#o.value)}render(){return html`<div class="${classMap({component:!0,horizontal:"horizontal"===this.orientation,vertical:"vertical"===this.orientation,left:"left"===this.split,middle:"middle"===this.split,"hidden-label":this.hide})}"><div class="${classMap({tooltips:!0,hidden:this.hide,left:"left"===this.split,middle:"middle"===this.split})}" part="private-tooltips"><glide-core-tooltip class="${classMap({"optional-tooltip":!0,vertical:"vertical"===this.orientation,visible:this.hasTooltipSlot})}" placement="${"vertical"===this.orientation?"right":"bottom"}"><span class="optional-tooltip-target" slot="target" tabindex="0"><svg aria-label="${this.#i.term("moreInformation")}" width="16" height="16" viewBox="0 0 24 24" fill="none">${infoCircleIcon}</svg></span><slot name="tooltip" @slotchange="${this.#a}" ${ref(this.#r)}></slot></glide-core-tooltip><glide-core-tooltip class="label-tooltip" placement="right" ?disabled="${!this.isLabelTooltip}"><div class="${classMap({label:!0,disabled:this.disabled})}" data-test="label" slot="target" ${ref(this.#l)}><slot @slotchange="${this.#n}" ${ref(this.#t)}></slot>${this.required?html`<span aria-hidden="true" class="required-symbol">*</span>`:""}</div><div aria-hidden="true">${this.label}</div></glide-core-tooltip></div><div class="control-and-summary" part="private-control-and-summary"><slot class="${classMap({control:!0,error:this.error,disabled:this.disabled,vertical:"vertical"===this.orientation,summaryless:!this.hasSummarySlot,"hidden-label":this.hide})}" name="control" @slotchange="${this.#d}" ${ref(this.#e)}></slot><slot class="${classMap({summary:!0,error:this.error})}" name="summary" @slotchange="${this.#c}" ${ref(this.#s)}></slot></div><slot class="${classMap({description:!0,content:this.hasDescription,error:this.error,tooltip:this.hasTooltipSlot})}" id="description" name="description" ${ref(this.#o)}></slot></div>`}#e;#t;#o;#l;#i;#s;#r;#d(){owSlot(this.#e.value)}#n(){owSlot(this.#t.value);const e=this.#t.value?.assignedElements().at(0),t=this.#l.value;ow(e,ow.object.instanceOf(Element)),ow(t,ow.object.instanceOf(HTMLElement)),e.textContent&&(this.label=e.textContent);new ResizeObserver((()=>{this.isLabelTooltip=e.getBoundingClientRect().width>t.getBoundingClientRect().width})).observe(t)}#c(){const e=this.#s.value?.assignedNodes({flatten:!0});this.hasSummarySlot=Boolean(e&&e.length>0)}#a(){const e=this.#r.value?.assignedNodes({flatten:!0});this.hasTooltipSlot=Boolean(e&&e.length>0)}};__decorate([property({reflect:!0,type:Boolean})],GlideCoreLabel.prototype,"disabled",void 0),__decorate([property({reflect:!0,type:Boolean})],GlideCoreLabel.prototype,"error",void 0),__decorate([property({reflect:!0,type:Boolean})],GlideCoreLabel.prototype,"hide",void 0),__decorate([property({reflect:!0})],GlideCoreLabel.prototype,"orientation",void 0),__decorate([property({reflect:!0,type:Boolean})],GlideCoreLabel.prototype,"required",void 0),__decorate([property()],GlideCoreLabel.prototype,"split",void 0),__decorate([state()],GlideCoreLabel.prototype,"hasDescription",void 0),__decorate([state()],GlideCoreLabel.prototype,"hasSummarySlot",void 0),__decorate([state()],GlideCoreLabel.prototype,"hasTooltipSlot",void 0),__decorate([state()],GlideCoreLabel.prototype,"isLabelTooltip",void 0),__decorate([state()],GlideCoreLabel.prototype,"label",void 0),GlideCoreLabel=__decorate([customElement("glide-core-private-label")],GlideCoreLabel);export default GlideCoreLabel;
|
package/dist/label.styles.js
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
import{css}from"lit";import focusOutline from"./styles/focus-outline.js";import visuallyHidden from"./styles/visually-hidden.js";export default[css`
|
2
2
|
${focusOutline(".optional-tooltip-target:focus-visible ")}
|
3
|
-
${visuallyHidden(".tooltips
|
3
|
+
${visuallyHidden(".tooltips.hidden")}
|
4
4
|
`,css`
|
5
5
|
.component {
|
6
6
|
&.horizontal {
|
@@ -8,7 +8,7 @@ import{css}from"lit";import focusOutline from"./styles/focus-outline.js";import
|
|
8
8
|
|
9
9
|
column-gap: var(--glide-core-spacing-sm);
|
10
10
|
display: grid;
|
11
|
-
grid-template-columns: auto minmax(
|
11
|
+
grid-template-columns: auto minmax(auto, 1fr);
|
12
12
|
}
|
13
13
|
|
14
14
|
&.vertical {
|
@@ -32,7 +32,7 @@ import{css}from"lit";import focusOutline from"./styles/focus-outline.js";import
|
|
32
32
|
}
|
33
33
|
}
|
34
34
|
|
35
|
-
.tooltips
|
35
|
+
.tooltips {
|
36
36
|
align-items: center;
|
37
37
|
column-gap: var(--glide-core-spacing-xs);
|
38
38
|
display: flex;
|
@@ -129,10 +129,14 @@ import{css}from"lit";import focusOutline from"./styles/focus-outline.js";import
|
|
129
129
|
align-items: center;
|
130
130
|
display: flex;
|
131
131
|
gap: var(--glide-core-spacing-sm);
|
132
|
+
|
133
|
+
/* https://css-tricks.com/flexbox-truncated-text/#aa-the-solution-is-min-width-0-on-the-flex-child */
|
134
|
+
min-inline-size: 0;
|
132
135
|
}
|
133
136
|
|
134
137
|
.control {
|
135
138
|
display: block;
|
139
|
+
max-inline-size: 100%;
|
136
140
|
|
137
141
|
&.summaryless {
|
138
142
|
flex-grow: 1;
|
@@ -17,6 +17,8 @@ export interface Translation extends DefaultTranslation {
|
|
17
17
|
announcedCharacterCount: (current: number, maximum: number) => string;
|
18
18
|
displayedCharacterCount: (current: number, maximum: number) => string;
|
19
19
|
clearEntry: (label: string) => string;
|
20
|
+
editOption: (name: string) => string;
|
21
|
+
editTag: (name: string) => string;
|
20
22
|
removeTag: (name: string) => string;
|
21
23
|
actionsFor: (label: string) => string;
|
22
24
|
}
|
package/dist/menu.js
CHANGED
@@ -1 +1 @@
|
|
1
|
-
var __decorate=this&&this.__decorate||function(e,t,i,o){var n,s=arguments.length,l=s<3?t:null===o?o=Object.getOwnPropertyDescriptor(t,i):o;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)l=Reflect.decorate(e,t,i,o);else for(var a=e.length-1;a>=0;a--)(n=e[a])&&(l=(s<3?n(l):s>3?n(t,i,l):n(t,i))||l);return s>3&&l&&Object.defineProperty(t,i,l),l};import{LitElement,html}from"lit";import{autoUpdate,computePosition,flip,offset}from"@floating-ui/dom";import{createRef,ref}from"lit/directives/ref.js";import{customElement,property}from"lit/decorators.js";import{nanoid}from"nanoid";import GlideCoreMenuButton from"./menu.button.js";import GlideCoreMenuLink from"./menu.link.js";import GlideCoreMenuOptions from"./menu.options.js";import ow,{owSlot,owSlotType}from"./library/ow.js";import styles from"./menu.styles.js";let GlideCoreMenu=class GlideCoreMenu extends LitElement{constructor(){super(...arguments),this.placement="bottom-start",this.#e=createRef(),this.#t=createRef(),this.#i=!1,this.#o=!1,this.#n=!1,this.#s="large",this.#l=createRef(),this.#a=()=>{this.#n?this.#n=!1:(this.open=!1,this.#r&&(this.#r.ariaActivedescendant=""))}}static{this.shadowRootOptions={...LitElement.shadowRootOptions,mode:"closed"}}static{this.styles=styles}get offset(){return this.#c??Number.parseFloat(window.getComputedStyle(document.body).getPropertyValue("--glide-core-spacing-xxs"))*Number.parseFloat(window.getComputedStyle(document.documentElement).fontSize)}set offset(e){this.#c=e}get open(){return this.#o}set open(e){this.#o=e,e&&!this.isTargetDisabled?this.#h():this.#p()}get size(){return this.#s}set size(e){this.#s=e,this.#r&&(this.#r.privateSize=e)}connectedCallback(){super.connectedCallback(),document.addEventListener("click",this.#a,{capture:!0})}createRenderRoot(){return this.#d=super.createRenderRoot(),this.#d}disconnectedCallback(){super.disconnectedCallback(),document.removeEventListener("click",this.#a,{capture:!0})}firstUpdated(){ow(this.#r,ow.object.instanceOf(GlideCoreMenuOptions)),owSlot(this.#t.value),owSlot(this.#l.value),owSlotType(this.#t.value,[GlideCoreMenuOptions]),this.#t.value.popover="manual";const e=this.#m?.at(0);this.open&&e&&!this.isTargetDisabled&&(e.privateActive=!0,this.#h()),this.#l.value.addEventListener("mouseup",(()=>{this.#n=!0}))}get isTargetDisabled(){const e=this.#u&&"disabled"in this.#u&&this.#u.disabled,t=this.#u&&"true"===this.#u.ariaDisabled;return Boolean(e)||Boolean(t)}render(){return html`<div class="component" @focusout="${this.#f}" ${ref(this.#e)}><slot class="target-slot" name="target" @click="${this.#E}" @keydown="${this.#v}" @slotchange="${this.#g}" ${ref(this.#l)}></slot><slot class="default-slot" @click="${this.#S}" @focusin="${this.#w}" @keydown="${this.#v}" @mouseover="${this.#C}" @
|
1
|
+
var __decorate=this&&this.__decorate||function(e,t,i,o){var n,s=arguments.length,l=s<3?t:null===o?o=Object.getOwnPropertyDescriptor(t,i):o;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)l=Reflect.decorate(e,t,i,o);else for(var a=e.length-1;a>=0;a--)(n=e[a])&&(l=(s<3?n(l):s>3?n(t,i,l):n(t,i))||l);return s>3&&l&&Object.defineProperty(t,i,l),l};import{LitElement,html}from"lit";import{autoUpdate,computePosition,flip,offset}from"@floating-ui/dom";import{createRef,ref}from"lit/directives/ref.js";import{customElement,property}from"lit/decorators.js";import{nanoid}from"nanoid";import GlideCoreMenuButton from"./menu.button.js";import GlideCoreMenuLink from"./menu.link.js";import GlideCoreMenuOptions from"./menu.options.js";import ow,{owSlot,owSlotType}from"./library/ow.js";import styles from"./menu.styles.js";let GlideCoreMenu=class GlideCoreMenu extends LitElement{constructor(){super(...arguments),this.placement="bottom-start",this.#e=createRef(),this.#t=createRef(),this.#i=!1,this.#o=!1,this.#n=!1,this.#s="large",this.#l=createRef(),this.#a=()=>{this.#n?this.#n=!1:(this.open=!1,this.#r&&(this.#r.ariaActivedescendant=""))}}static{this.shadowRootOptions={...LitElement.shadowRootOptions,mode:"closed"}}static{this.styles=styles}get offset(){return this.#c??Number.parseFloat(window.getComputedStyle(document.body).getPropertyValue("--glide-core-spacing-xxs"))*Number.parseFloat(window.getComputedStyle(document.documentElement).fontSize)}set offset(e){this.#c=e}get open(){return this.#o}set open(e){this.#o=e,e&&!this.isTargetDisabled?this.#h():this.#p()}get size(){return this.#s}set size(e){this.#s=e,this.#r&&(this.#r.privateSize=e)}connectedCallback(){super.connectedCallback(),document.addEventListener("click",this.#a,{capture:!0})}createRenderRoot(){return this.#d=super.createRenderRoot(),this.#d}disconnectedCallback(){super.disconnectedCallback(),document.removeEventListener("click",this.#a,{capture:!0})}firstUpdated(){ow(this.#r,ow.object.instanceOf(GlideCoreMenuOptions)),owSlot(this.#t.value),owSlot(this.#l.value),owSlotType(this.#t.value,[GlideCoreMenuOptions]),this.#t.value.popover="manual";const e=this.#m?.at(0);this.open&&e&&!this.isTargetDisabled&&(e.privateActive=!0,this.#h()),this.#l.value.addEventListener("mouseup",(()=>{this.#n=!0}))}get isTargetDisabled(){const e=this.#u&&"disabled"in this.#u&&this.#u.disabled,t=this.#u&&"true"===this.#u.ariaDisabled;return Boolean(e)||Boolean(t)}render(){return html`<div class="component" @focusout="${this.#f}" ${ref(this.#e)}><slot class="target-slot" name="target" @click="${this.#E}" @keydown="${this.#v}" @slotchange="${this.#g}" ${ref(this.#l)}></slot><slot class="default-slot" @click="${this.#S}" @focusin="${this.#w}" @keydown="${this.#v}" @mouseover="${this.#C}" @private-slot-change="${this.#y}" @slotchange="${this.#R}" ${ref(this.#t)}></slot></div>`}#k;#e;#t;#i;#o;#n;#c;#d;#s;#l;get#O(){return this.#m?.find((({privateActive:e})=>e))}#a;#b(e){this.#u&&"focus"in this.#u&&this.#u?.focus(e)}#p(){this.#k?.(),this.#r&&(this.#r.ariaActivedescendant=""),this.#u&&(this.#u.ariaExpanded="false"),this.#t.value?.hidePopover()}get#r(){const e=this.#t.value?.assignedElements().at(0);return e instanceof GlideCoreMenuOptions?e:null}#R(){ow(this.#r,ow.object.instanceOf(GlideCoreMenuOptions)),owSlot(this.#t.value),owSlotType(this.#t.value,[GlideCoreMenuOptions]),this.#r.privateSize=this.size}#S(){this.open=!1}#w(e){(e.target instanceof GlideCoreMenuButton||e.target instanceof GlideCoreMenuLink)&&this.#O&&this.#r&&(this.#O.privateActive=!1,e.target.privateActive=!0,this.#r.ariaActivedescendant=e.target.id)}#C(e){if(e.target instanceof GlideCoreMenuLink||e.target instanceof GlideCoreMenuButton){if(this.#m)for(const t of this.#m)t.privateActive=t===e.target;this.#r&&(this.#r.ariaActivedescendant=e.target.id)}}#f(e){const t=e.relatedTarget instanceof HTMLElement&&this.#d?.contains(e.relatedTarget),i=e.relatedTarget instanceof GlideCoreMenuOptions,o=e.relatedTarget instanceof GlideCoreMenuButton||e.relatedTarget instanceof GlideCoreMenuLink;t||i||o||(this.open=!1)}#y(){const e=this.#m?.find((({privateActive:e})=>e)),t=this.#m?.at(0);!e&&t&&(t.privateActive=!0)}#v(e){ow(this.#r,ow.object.instanceOf(GlideCoreMenuOptions));const t=this.#u instanceof HTMLSpanElement||this.#u instanceof HTMLDivElement;if([" ","Enter"].includes(e.key)&&this.open)return" "===e.key&&t&&e.preventDefault(),this.open=!1,this.#b(),this.#O?.click(),void(this.#i=!0);if([" ","Enter"].includes(e.key)&&t)return e.preventDefault(),void(this.open=!0);if(["Escape"].includes(e.key)&&this.open)return this.open=!1,void this.#b();if(["ArrowUp","ArrowDown"].includes(e.key)&&!this.open&&this.#O)return e.preventDefault(),this.open=!0,void(this.#r.ariaActivedescendant=this.#O.id);if(this.open){ow(this.#m,ow.array),ow(this.#r,ow.object.instanceOf(GlideCoreMenuOptions)),ow(this.#O,ow.object.is((e=>e instanceof GlideCoreMenuButton||e instanceof GlideCoreMenuLink)));const t=this.#m.indexOf(this.#O);if("ArrowUp"===e.key&&!e.metaKey){e.preventDefault();const i=this.#m.at(t-1);return void(i&&0!==t&&(this.#O.privateActive=!1,this.#r.ariaActivedescendant=i.id,i.privateActive=!0))}if("ArrowDown"===e.key&&!e.metaKey){e.preventDefault();const i=this.#m.at(t+1);return void(i&&(this.#O.privateActive=!1,this.#r.ariaActivedescendant=i.id,i.privateActive=!0))}if("ArrowUp"===e.key&&e.metaKey||"Home"===e.key||"PageUp"===e.key){e.preventDefault();const t=this.#m.at(0);return void(t&&(this.#O.privateActive=!1,this.#r.ariaActivedescendant=t.id,t.privateActive=!0))}if("ArrowDown"===e.key&&e.metaKey||"End"===e.key||"PageDown"===e.key){e.preventDefault();const t=this.#m.at(-1);return void(t&&(this.#O.privateActive=!1,this.#r.ariaActivedescendant=t.id,t.privateActive=!0))}}}#g(){owSlot(this.#l.value),ow(this.#u,ow.object.instanceOf(Element)),ow(this.#r,ow.object.instanceOf(GlideCoreMenuOptions));new MutationObserver((()=>{this.open&&!this.isTargetDisabled?this.#h():this.#p()})).observe(this.#u,{attributes:!0,attributeFilter:["aria-disabled","disabled"]}),this.#u.ariaHasPopup="true",this.#u.id=nanoid(),this.#u.setAttribute("aria-controls",this.#r.id),this.#r.ariaLabelledby=this.#u.id;(this.#u instanceof HTMLSpanElement||this.#u instanceof HTMLDivElement)&&this.#u instanceof HTMLElement&&(this.#u.tabIndex=0),this.open&&!this.isTargetDisabled?this.#h():this.#p()}#E(){this.isTargetDisabled?this.#p():this.#i?this.#i=!1:this.#m&&this.#m.length>0&&(this.open=!this.open)}get#m(){let e=this.#t.value?.assignedElements()?.at(0)?.children;const t=e?.[0];if(t instanceof HTMLSlotElement&&(e=t.assignedElements()),e)return[...e].filter((e=>e instanceof GlideCoreMenuLink||e instanceof GlideCoreMenuButton))}#h(){this.#k?.(),this.#u&&this.#t.value&&(this.#k=autoUpdate(this.#u,this.#t.value,(()=>{(async()=>{if(this.#u&&this.#t.value){const{x:e,y:t,placement:i}=await computePosition(this.#u,this.#t.value,{placement:this.placement,middleware:[offset(this.offset),flip()]});this.#t.value.dataset.placement=i,Object.assign(this.#t.value.style,{left:`${e}px`,top:`${t}px`})}this.#t.value?.showPopover(),this.#r&&this.#O?.id&&(this.#r.ariaActivedescendant=this.#O.id),this.#u&&(this.#u.ariaExpanded="true")})()})))}get#u(){return this.#l.value?.assignedElements().at(0)}};__decorate([property({reflect:!0,type:Number})],GlideCoreMenu.prototype,"offset",null),__decorate([property({reflect:!0,type:Boolean})],GlideCoreMenu.prototype,"open",null),__decorate([property({reflect:!0})],GlideCoreMenu.prototype,"placement",void 0),__decorate([property({reflect:!0})],GlideCoreMenu.prototype,"size",null),GlideCoreMenu=__decorate([customElement("glide-core-menu")],GlideCoreMenu);export default GlideCoreMenu;
|
package/dist/menu.options.js
CHANGED
@@ -1 +1 @@
|
|
1
|
-
var __decorate=this&&this.__decorate||function(e,t,o,i){var l
|
1
|
+
var __decorate=this&&this.__decorate||function(e,t,o,i){var r,l=arguments.length,s=l<3?t:null===i?i=Object.getOwnPropertyDescriptor(t,o):i;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(e,t,o,i);else for(var n=e.length-1;n>=0;n--)(r=e[n])&&(s=(l<3?r(s):l>3?r(t,o,s):r(t,o))||s);return l>3&&s&&Object.defineProperty(t,o,s),s};import{LitElement,html}from"lit";import{classMap}from"lit/directives/class-map.js";import{createRef,ref}from"lit/directives/ref.js";import{customElement,property,state}from"lit/decorators.js";import{nanoid}from"nanoid";import{owSlot,owSlotType}from"./library/ow.js";import GlideCoreMenuButton from"./menu.button.js";import GlideCoreMenuLink from"./menu.link.js";import styles from"./menu.options.styles.js";let GlideCoreMenuOptions=class GlideCoreMenuOptions extends LitElement{constructor(){super(...arguments),this.ariaActivedescendant="",this.ariaLabelledby="",this.privateSize="large",this.#e=nanoid(),this.#t=createRef()}static{this.shadowRootOptions={...LitElement.shadowRootOptions,mode:"closed"}}static{this.styles=styles}connectedCallback(){super.connectedCallback(),this.id=this.#e,this.role="menu",this.tabIndex=-1}firstUpdated(){owSlot(this.#t.value),owSlotType(this.#t.value,[GlideCoreMenuButton,GlideCoreMenuLink,Text])}render(){return html`<div class="${classMap({component:!0,large:"large"===this.privateSize,small:"small"===this.privateSize})}" role="none"><slot @slotchange="${this.#o}" ${ref(this.#t)}></slot></div>`}#e;#t;#o(){owSlot(this.#t.value),owSlotType(this.#t.value,[GlideCoreMenuButton,GlideCoreMenuLink,Text]),this.dispatchEvent(new Event("private-slot-change",{bubbles:!0}))}};__decorate([property({attribute:"aria-activedescendant",reflect:!0})],GlideCoreMenuOptions.prototype,"ariaActivedescendant",void 0),__decorate([property({attribute:"aria-labelledby",reflect:!0})],GlideCoreMenuOptions.prototype,"ariaLabelledby",void 0),__decorate([state()],GlideCoreMenuOptions.prototype,"privateSize",void 0),GlideCoreMenuOptions=__decorate([customElement("glide-core-menu-options")],GlideCoreMenuOptions);export default GlideCoreMenuOptions;
|
@@ -0,0 +1 @@
|
|
1
|
+
import './menu.button.js';
|