@crowdstrike/glide-core 0.12.2 → 0.13.0
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/accordion.d.ts +1 -1
- package/dist/accordion.styles.js +2 -1
- package/dist/button-group.js +1 -1
- package/dist/button-group.stories.d.ts +0 -1
- package/dist/button-group.test.events.js +2 -0
- package/dist/checkbox-group.styles.js +1 -1
- package/dist/checkbox.styles.js +6 -3
- package/dist/drawer.js +1 -1
- package/dist/dropdown.d.ts +8 -1
- package/dist/dropdown.js +140 -74
- package/dist/dropdown.option.js +1 -1
- package/dist/dropdown.option.styles.js +39 -7
- package/dist/dropdown.option.test.interactions.multiple.js +2 -2
- package/dist/dropdown.option.test.interactions.single.js +2 -2
- package/dist/dropdown.styles.js +121 -16
- package/dist/dropdown.test.basics.filterable.js +19 -57
- 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 -66
- package/dist/dropdown.test.events.js +75 -49
- package/dist/dropdown.test.events.multiple.js +17 -87
- package/dist/dropdown.test.events.single.js +12 -60
- package/dist/dropdown.test.focus.filterable.js +11 -58
- package/dist/dropdown.test.focus.js +62 -9
- package/dist/dropdown.test.focus.multiple.js +22 -38
- package/dist/dropdown.test.focus.single.js +5 -16
- package/dist/dropdown.test.interactions.filterable.js +167 -69
- package/dist/dropdown.test.interactions.js +226 -244
- package/dist/dropdown.test.interactions.multiple.js +78 -274
- package/dist/dropdown.test.interactions.single.js +20 -85
- package/dist/dropdown.test.validity.js +12 -49
- package/dist/input.d.ts +1 -1
- package/dist/input.js +2 -1
- package/dist/input.styles.js +44 -30
- 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.stories.d.ts +1 -0
- package/dist/menu.styles.js +1 -1
- package/dist/menu.test.interactions.js +1 -1
- package/dist/modal.d.ts +1 -1
- package/dist/modal.js +1 -1
- package/dist/radio-group.stories.d.ts +0 -1
- package/dist/radio-group.styles.js +1 -1
- package/dist/styles/variables.css +1 -1
- package/dist/tab.group.d.ts +0 -1
- package/dist/tab.group.js +1 -1
- package/dist/tab.group.styles.js +5 -13
- package/dist/tab.panel.styles.js +0 -3
- package/dist/tabs.stories.d.ts +0 -1
- package/dist/tag.js +1 -1
- package/dist/tag.styles.js +5 -3
- package/dist/tag.test.interactions.js +8 -8
- 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/dist/tree.stories.d.ts +0 -1
- package/package.json +18 -18
@@ -6,60 +6,17 @@ import GlideCoreDropdownOption from './dropdown.option.js';
|
|
6
6
|
GlideCoreDropdown.shadowRootOptions.mode = 'open';
|
7
7
|
GlideCoreDropdownOption.shadowRootOptions.mode = 'open';
|
8
8
|
const defaultSlot = html `
|
9
|
-
<glide-core-dropdown-option
|
10
|
-
|
11
|
-
|
12
|
-
></glide-core-dropdown-option>
|
13
|
-
|
14
|
-
<glide-core-dropdown-option
|
15
|
-
|
16
|
-
|
17
|
-
></glide-core-dropdown-option>
|
18
|
-
|
19
|
-
<glide-core-dropdown-option
|
20
|
-
label="Three"
|
21
|
-
value="three"
|
22
|
-
></glide-core-dropdown-option>
|
23
|
-
|
24
|
-
<glide-core-dropdown-option
|
25
|
-
label="Four"
|
26
|
-
value="four"
|
27
|
-
></glide-core-dropdown-option>
|
28
|
-
|
29
|
-
<glide-core-dropdown-option
|
30
|
-
label="Five"
|
31
|
-
value="five"
|
32
|
-
></glide-core-dropdown-option>
|
33
|
-
|
34
|
-
<glide-core-dropdown-option
|
35
|
-
label="Six"
|
36
|
-
value="six"
|
37
|
-
></glide-core-dropdown-option>
|
38
|
-
|
39
|
-
<glide-core-dropdown-option
|
40
|
-
label="Seven"
|
41
|
-
value="seven"
|
42
|
-
></glide-core-dropdown-option>
|
43
|
-
|
44
|
-
<glide-core-dropdown-option
|
45
|
-
label="Eight"
|
46
|
-
value="eight"
|
47
|
-
></glide-core-dropdown-option>
|
48
|
-
|
49
|
-
<glide-core-dropdown-option
|
50
|
-
label="Nine"
|
51
|
-
value="nine"
|
52
|
-
></glide-core-dropdown-option>
|
53
|
-
|
54
|
-
<glide-core-dropdown-option
|
55
|
-
label="Ten"
|
56
|
-
value="ten"
|
57
|
-
></glide-core-dropdown-option>
|
58
|
-
|
59
|
-
<glide-core-dropdown-option
|
60
|
-
label="Eleven"
|
61
|
-
value="eleven"
|
62
|
-
></glide-core-dropdown-option>
|
9
|
+
<glide-core-dropdown-option label="One"></glide-core-dropdown-option>
|
10
|
+
<glide-core-dropdown-option label="Two"></glide-core-dropdown-option>
|
11
|
+
<glide-core-dropdown-option label="Three"></glide-core-dropdown-option>
|
12
|
+
<glide-core-dropdown-option label="Four"></glide-core-dropdown-option>
|
13
|
+
<glide-core-dropdown-option label="Five"></glide-core-dropdown-option>
|
14
|
+
<glide-core-dropdown-option label="Six"></glide-core-dropdown-option>
|
15
|
+
<glide-core-dropdown-option label="Seven"></glide-core-dropdown-option>
|
16
|
+
<glide-core-dropdown-option label="Eight"></glide-core-dropdown-option>
|
17
|
+
<glide-core-dropdown-option label="Nine"></glide-core-dropdown-option>
|
18
|
+
<glide-core-dropdown-option label="Ten"></glide-core-dropdown-option>
|
19
|
+
<glide-core-dropdown-option label="Eleven"></glide-core-dropdown-option>
|
63
20
|
`;
|
64
21
|
it('opens on click', async () => {
|
65
22
|
const component = await fixture(html `<glide-core-dropdown label="Label" placeholder="Placeholder">
|
@@ -218,6 +175,56 @@ it('hides its magnifying glass icon when multiselect and not filtering', async (
|
|
218
175
|
const icon = component?.shadowRoot?.querySelector('[data-test="magnifying-glass-icon"]');
|
219
176
|
expect(icon?.checkVisibility()).to.be.not.ok;
|
220
177
|
});
|
178
|
+
it('does not clear its filter when a tag is removed via Backspace', async () => {
|
179
|
+
const component = await fixture(html `<glide-core-dropdown
|
180
|
+
label="Label"
|
181
|
+
placeholder="Placeholder"
|
182
|
+
filterable
|
183
|
+
multiple
|
184
|
+
>
|
185
|
+
<glide-core-dropdown-option
|
186
|
+
label="One"
|
187
|
+
selected
|
188
|
+
></glide-core-dropdown-option>
|
189
|
+
|
190
|
+
<glide-core-dropdown-option label="Two"></glide-core-dropdown-option>
|
191
|
+
</glide-core-dropdown>`);
|
192
|
+
// Wait for it to open.
|
193
|
+
await aTimeout(0);
|
194
|
+
const input = component.shadowRoot?.querySelector('[data-test="input"]');
|
195
|
+
input?.select();
|
196
|
+
input?.focus();
|
197
|
+
await sendKeys({ type: 'o' });
|
198
|
+
await sendKeys({ press: 'ArrowLeft' });
|
199
|
+
await sendKeys({ press: 'Backspace' });
|
200
|
+
expect(input?.value).to.equal('o');
|
201
|
+
});
|
202
|
+
it('does not clear its filter when every tag is removed via Meta + Backspace', async () => {
|
203
|
+
const component = await fixture(html `<glide-core-dropdown
|
204
|
+
label="Label"
|
205
|
+
placeholder="Placeholder"
|
206
|
+
filterable
|
207
|
+
multiple
|
208
|
+
>
|
209
|
+
<glide-core-dropdown-option
|
210
|
+
label="One"
|
211
|
+
selected
|
212
|
+
></glide-core-dropdown-option>
|
213
|
+
|
214
|
+
<glide-core-dropdown-option label="Two"></glide-core-dropdown-option>
|
215
|
+
</glide-core-dropdown>`);
|
216
|
+
// Wait for it to open.
|
217
|
+
await aTimeout(0);
|
218
|
+
const input = component.shadowRoot?.querySelector('[data-test="input"]');
|
219
|
+
input?.select();
|
220
|
+
input?.focus();
|
221
|
+
await sendKeys({ type: 'o' });
|
222
|
+
await sendKeys({ press: 'ArrowLeft' });
|
223
|
+
await sendKeys({ down: 'Meta' });
|
224
|
+
await sendKeys({ press: 'Backspace' });
|
225
|
+
await sendKeys({ up: 'Meta' });
|
226
|
+
expect(input?.value).to.equal('o');
|
227
|
+
});
|
221
228
|
it('does not filter on only whitespace', async () => {
|
222
229
|
const component = await fixture(html `<glide-core-dropdown label="Label" placeholder="Placeholder">
|
223
230
|
${defaultSlot}
|
@@ -257,6 +264,34 @@ it('hides Select All when filtering', async () => {
|
|
257
264
|
const selectAll = component.shadowRoot?.querySelector('[data-test="select-all"]');
|
258
265
|
expect(selectAll?.checkVisibility()).to.not.be.ok;
|
259
266
|
});
|
267
|
+
it('unhides every option after filtering when one is selected and Dropdown is reopened', async () => {
|
268
|
+
const component = await fixture(html `<glide-core-dropdown
|
269
|
+
label="Label"
|
270
|
+
placeholder="Placeholder"
|
271
|
+
open
|
272
|
+
filterable
|
273
|
+
>
|
274
|
+
<glide-core-dropdown-option
|
275
|
+
label="One"
|
276
|
+
selected
|
277
|
+
></glide-core-dropdown-option>
|
278
|
+
|
279
|
+
<glide-core-dropdown-option label="Two"></glide-core-dropdown-option>
|
280
|
+
</glide-core-dropdown>`);
|
281
|
+
// Wait for it to open.
|
282
|
+
await aTimeout(0);
|
283
|
+
component.focus();
|
284
|
+
await sendKeys({ type: 'two' });
|
285
|
+
component.blur();
|
286
|
+
await elementUpdated(component);
|
287
|
+
component.open = true;
|
288
|
+
// Wait for it to open.
|
289
|
+
await aTimeout(0);
|
290
|
+
const options = [
|
291
|
+
...component.querySelectorAll('glide-core-dropdown-option'),
|
292
|
+
].filter(({ hidden }) => !hidden);
|
293
|
+
expect(options.length).to.equal(2);
|
294
|
+
});
|
260
295
|
it('sets the first unfiltered option as active when the previously active option is filtered out', async () => {
|
261
296
|
const component = await fixture(html `<glide-core-dropdown
|
262
297
|
label="Label"
|
@@ -308,14 +343,10 @@ it('sets the `value` of its `<input>` when made filterable', async () => {
|
|
308
343
|
const component = await fixture(html `<glide-core-dropdown label="Label" placeholder="Placeholder">
|
309
344
|
<glide-core-dropdown-option
|
310
345
|
label="One"
|
311
|
-
value="one"
|
312
346
|
selected
|
313
347
|
></glide-core-dropdown-option>
|
314
348
|
|
315
|
-
<glide-core-dropdown-option
|
316
|
-
label="Two"
|
317
|
-
value="two"
|
318
|
-
></glide-core-dropdown-option>
|
349
|
+
<glide-core-dropdown-option label="Two"></glide-core-dropdown-option>
|
319
350
|
</glide-core-dropdown>`);
|
320
351
|
component.filterable = true;
|
321
352
|
await elementUpdated(component);
|
@@ -350,7 +381,6 @@ it('deselects the last selected option on Backspace', async () => {
|
|
350
381
|
component.shadowRoot
|
351
382
|
?.querySelector('[data-test="input"]')
|
352
383
|
?.setSelectionRange(0, 0);
|
353
|
-
await aTimeout(0);
|
354
384
|
await sendKeys({ press: 'Backspace' });
|
355
385
|
expect(options[1].selected).to.be.false;
|
356
386
|
expect(options[0].selected).to.be.true;
|
@@ -395,6 +425,22 @@ it('clears the `value` of its `<input>` when multiselect and an option is select
|
|
395
425
|
const input = component.shadowRoot?.querySelector('[data-test="input"]');
|
396
426
|
expect(input?.value).to.be.empty.string;
|
397
427
|
});
|
428
|
+
it('does not clear its filter when a tag is removed', async () => {
|
429
|
+
const component = await fixture(html `<glide-core-dropdown label="Label" placeholder="Placeholder" multiple>
|
430
|
+
${defaultSlot}
|
431
|
+
</glide-core-dropdown>`);
|
432
|
+
const option = component.querySelector('glide-core-dropdown-option');
|
433
|
+
assert(option);
|
434
|
+
option.selected = true;
|
435
|
+
component.focus();
|
436
|
+
await sendKeys({ type: 'one' });
|
437
|
+
component.shadowRoot
|
438
|
+
?.querySelector('[data-test="tag"]')
|
439
|
+
?.click();
|
440
|
+
await elementUpdated(component);
|
441
|
+
const input = component.shadowRoot?.querySelector('[data-test="input"]');
|
442
|
+
expect(input?.value).to.equal('one');
|
443
|
+
});
|
398
444
|
it('uses `placeholder` as a placeholder when multiselect and no option is selected', async () => {
|
399
445
|
const component = await fixture(html `<glide-core-dropdown label="Label" placeholder="Placeholder" multiple>
|
400
446
|
${defaultSlot}
|
@@ -601,7 +647,7 @@ it('sets `aria-activedescendant` when closed via click', async () => {
|
|
601
647
|
?.click();
|
602
648
|
await elementUpdated(component);
|
603
649
|
const input = component.shadowRoot?.querySelector('[data-test="input"]');
|
604
|
-
expect(input?.getAttribute('aria-activedescendant')).to.
|
650
|
+
expect(input?.getAttribute('aria-activedescendant')).to.be.empty.string;
|
605
651
|
});
|
606
652
|
it('sets `aria-activedescendant` when closed because it lost focus', async () => {
|
607
653
|
const component = await fixture(html `<glide-core-dropdown label="Label" placeholder="Placeholder" open>
|
@@ -610,7 +656,7 @@ it('sets `aria-activedescendant` when closed because it lost focus', async () =>
|
|
610
656
|
component.focus();
|
611
657
|
await sendKeys({ press: 'Tab' });
|
612
658
|
const input = component.shadowRoot?.querySelector('[data-test="input"]');
|
613
|
-
expect(input?.getAttribute('aria-activedescendant')).to.
|
659
|
+
expect(input?.getAttribute('aria-activedescendant')).to.be.empty.string;
|
614
660
|
});
|
615
661
|
it('sets `aria-activedescendant` when closed because something outside of it was clicked', async () => {
|
616
662
|
const component = await fixture(html `<glide-core-dropdown label="Label" placeholder="Placeholder" open>
|
@@ -619,7 +665,7 @@ it('sets `aria-activedescendant` when closed because something outside of it was
|
|
619
665
|
document.body.click();
|
620
666
|
await elementUpdated(component);
|
621
667
|
const input = component.shadowRoot?.querySelector('[data-test="input"]');
|
622
|
-
expect(input?.getAttribute('aria-activedescendant')).to.
|
668
|
+
expect(input?.getAttribute('aria-activedescendant')).to.be.empty.string;
|
623
669
|
});
|
624
670
|
it('sets `aria-activedescendant` when closed via Escape', async () => {
|
625
671
|
const component = await fixture(html `<glide-core-dropdown label="Label" placeholder="Placeholder" open>
|
@@ -628,7 +674,7 @@ it('sets `aria-activedescendant` when closed via Escape', async () => {
|
|
628
674
|
component.focus();
|
629
675
|
await sendKeys({ press: 'Escape' });
|
630
676
|
const input = component.shadowRoot?.querySelector('[data-test="input"]');
|
631
|
-
expect(input?.getAttribute('aria-activedescendant')).to.
|
677
|
+
expect(input?.getAttribute('aria-activedescendant')).to.be.empty.string;
|
632
678
|
});
|
633
679
|
it('cannot be tabbed to when `disabled`', async () => {
|
634
680
|
await fixture(html `<glide-core-dropdown
|
@@ -691,17 +737,69 @@ it('has no icon when filtering and an option is selected', async () => {
|
|
691
737
|
|
692
738
|
<glide-core-dropdown-option
|
693
739
|
label="One"
|
694
|
-
value="one"
|
695
740
|
selected
|
696
741
|
></glide-core-dropdown-option>
|
697
742
|
|
698
|
-
<glide-core-dropdown-option
|
699
|
-
label="Two"
|
700
|
-
value="two"
|
701
|
-
></glide-core-dropdown-option>
|
743
|
+
<glide-core-dropdown-option label="Two"></glide-core-dropdown-option>
|
702
744
|
</glide-core-dropdown>`);
|
703
745
|
component.focus();
|
704
746
|
await sendKeys({ type: 'one' });
|
705
747
|
const iconSlot = component.shadowRoot?.querySelector('[data-test="single-select-icon-slot"]');
|
706
748
|
expect(iconSlot).to.be.null;
|
707
749
|
});
|
750
|
+
it('supports custom filtering', async () => {
|
751
|
+
const component = await fixture(html `<glide-core-dropdown
|
752
|
+
label="Label"
|
753
|
+
placeholder="Placeholder"
|
754
|
+
filterable
|
755
|
+
>
|
756
|
+
<glide-core-dropdown-option label="One"></glide-core-dropdown-option>
|
757
|
+
<glide-core-dropdown-option label="Two"></glide-core-dropdown-option>
|
758
|
+
</glide-core-dropdown>`);
|
759
|
+
component.filter = async (filter) => {
|
760
|
+
const options = [
|
761
|
+
...component.querySelectorAll('glide-core-dropdown-option'),
|
762
|
+
];
|
763
|
+
return options.filter(({ label }) => label.includes(filter));
|
764
|
+
};
|
765
|
+
component.focus();
|
766
|
+
await sendKeys({ type: 'O' });
|
767
|
+
const options = [
|
768
|
+
...component.querySelectorAll('glide-core-dropdown-option'),
|
769
|
+
].filter(({ hidden }) => !hidden);
|
770
|
+
expect(options.length).to.equal(1);
|
771
|
+
expect(options[0].label).to.equal('One');
|
772
|
+
});
|
773
|
+
it('does nothing when filtering fails', async () => {
|
774
|
+
const component = await fixture(html `<glide-core-dropdown
|
775
|
+
label="Label"
|
776
|
+
placeholder="Placeholder"
|
777
|
+
filterable
|
778
|
+
>
|
779
|
+
<glide-core-dropdown-option label="One"></glide-core-dropdown-option>
|
780
|
+
<glide-core-dropdown-option label="Two"></glide-core-dropdown-option>
|
781
|
+
</glide-core-dropdown>`);
|
782
|
+
component.filter = () => {
|
783
|
+
return Promise.reject();
|
784
|
+
};
|
785
|
+
component.focus();
|
786
|
+
await sendKeys({ type: 'O' });
|
787
|
+
const options = [
|
788
|
+
...component.querySelectorAll('glide-core-dropdown-option'),
|
789
|
+
].filter(({ hidden }) => !hidden);
|
790
|
+
expect(options.length).to.equal(2);
|
791
|
+
});
|
792
|
+
it('updates its item count after filtering', async () => {
|
793
|
+
const component = await fixture(html `<glide-core-dropdown
|
794
|
+
label="Label"
|
795
|
+
placeholder="Placeholder"
|
796
|
+
filterable
|
797
|
+
>
|
798
|
+
<glide-core-dropdown-option label="One"></glide-core-dropdown-option>
|
799
|
+
<glide-core-dropdown-option label="Two"></glide-core-dropdown-option>
|
800
|
+
</glide-core-dropdown>`);
|
801
|
+
component.focus();
|
802
|
+
await sendKeys({ type: 'one' });
|
803
|
+
const itemCount = component.shadowRoot?.querySelector('[data-test="item-count"]');
|
804
|
+
expect(itemCount?.ariaLabel).to.equal('1 items');
|
805
|
+
});
|