@crowdstrike/glide-core 0.9.1 → 0.9.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/accordion.stories.d.ts +2 -4
- package/dist/accordion.styles.js +2 -4
- package/dist/button-group.button.styles.js +3 -8
- package/dist/button-group.stories.d.ts +2 -6
- package/dist/button-group.styles.js +2 -2
- package/dist/button.d.ts +12 -1
- package/dist/button.js +1 -1
- package/dist/button.stories.d.ts +2 -12
- package/dist/button.styles.js +2 -4
- package/dist/button.test.basics.js +47 -165
- package/dist/button.test.events.js +86 -10
- package/dist/checkbox-group.stories.d.ts +2 -3
- package/dist/checkbox.js +1 -1
- package/dist/checkbox.stories.d.ts +2 -6
- package/dist/checkbox.styles.js +43 -6
- package/dist/checkbox.test.form.js +16 -0
- package/dist/checkbox.test.interactions.js +8 -0
- package/dist/drawer.js +1 -1
- package/dist/drawer.stories.d.ts +1 -1
- package/dist/dropdown.d.ts +4 -2
- package/dist/dropdown.js +1 -1
- package/dist/dropdown.option.js +1 -1
- package/dist/dropdown.option.styles.js +2 -0
- package/dist/dropdown.stories.d.ts +4 -10
- package/dist/dropdown.styles.js +47 -29
- package/dist/dropdown.test.focus.filterable.js +20 -0
- package/dist/dropdown.test.focus.js +1 -0
- package/dist/dropdown.test.form.js +23 -112
- package/dist/dropdown.test.interactions.filterable.js +121 -17
- package/dist/dropdown.test.interactions.multiple.js +15 -22
- package/dist/dropdown.test.interactions.single.js +44 -22
- package/dist/form-controls-layout.stories.d.ts +1 -1
- package/dist/icon-button.d.ts +1 -1
- package/dist/icon-button.stories.d.ts +1 -3
- package/dist/icon-button.styles.js +2 -4
- package/dist/icons/checked.d.ts +5 -0
- package/dist/icons/checked.js +1 -1
- package/dist/input.d.ts +1 -1
- package/dist/input.js +1 -1
- package/dist/input.stories.d.ts +2 -13
- package/dist/input.styles.d.ts +1 -1
- package/dist/input.styles.js +93 -93
- package/dist/input.test.basics.js +45 -45
- package/dist/input.test.form.js +17 -0
- package/dist/label.styles.js +6 -11
- package/dist/library/localize.test.js +45 -0
- package/dist/menu.button.styles.js +1 -0
- package/dist/menu.js +1 -1
- package/dist/menu.link.styles.js +1 -0
- package/dist/menu.stories.d.ts +1 -1
- package/dist/menu.styles.js +3 -1
- package/dist/menu.test.events.js +1 -97
- package/dist/menu.test.focus.js +26 -3
- package/dist/menu.test.interactions.js +3 -0
- package/dist/modal.d.ts +0 -7
- package/dist/modal.icon-button.test.basics.js +9 -9
- package/dist/modal.stories.d.ts +3 -5
- package/dist/modal.styles.js +2 -4
- package/dist/modal.tertiary-icon.test.basics.js +14 -14
- package/dist/modal.test.accessibility.js +16 -27
- package/dist/modal.test.basics.js +64 -68
- package/dist/modal.test.close.js +12 -16
- package/dist/modal.test.events.js +32 -44
- package/dist/modal.test.lock-scroll.js +15 -25
- package/dist/modal.test.methods.js +8 -12
- package/dist/modal.test.scrollbars.js +2 -4
- package/dist/radio-group.js +1 -1
- package/dist/radio-group.stories.d.ts +2 -3
- package/dist/radio-group.test.basics.js +3 -3
- package/dist/radio-group.test.events.js +6 -6
- package/dist/radio-group.test.form.js +19 -0
- package/dist/radio.styles.js +2 -6
- package/dist/split-button.stories.d.ts +3 -8
- package/dist/split-button.styles.js +2 -4
- package/dist/split-container.styles.js +2 -4
- package/dist/status-indicator.stories.d.ts +1 -13
- package/dist/styles/focus-outline.d.ts +1 -1
- package/dist/styles/focus-outline.js +7 -1
- package/dist/styles/opacity-and-scale-animation.d.ts +2 -0
- package/dist/styles/opacity-and-scale-animation.js +24 -0
- package/dist/styles/variables.css +1 -1
- package/dist/styles/visually-hidden.d.ts +1 -1
- package/dist/styles/visually-hidden.js +14 -1
- package/dist/tab.group.d.ts +6 -6
- package/dist/tab.group.js +1 -1
- package/dist/tab.group.styles.js +46 -5
- package/dist/tab.group.test.basics.js +9 -2
- package/dist/tab.group.test.interactions.js +70 -93
- package/dist/tab.js +1 -1
- package/dist/tab.panel.styles.js +3 -9
- package/dist/tab.styles.js +6 -13
- package/dist/tab.test.basics.js +15 -17
- package/dist/tabs.stories.d.ts +2 -2
- package/dist/tag.js +1 -1
- package/dist/tag.stories.d.ts +2 -4
- package/dist/tag.styles.js +2 -4
- package/dist/tag.test.basics.js +28 -27
- package/dist/tag.test.events.js +3 -3
- package/dist/tag.test.focus.js +4 -4
- package/dist/textarea.d.ts +1 -1
- package/dist/textarea.stories.d.ts +1 -8
- package/dist/textarea.styles.d.ts +1 -1
- package/dist/textarea.styles.js +63 -67
- package/dist/textarea.test.basics.js +52 -52
- package/dist/toasts.d.ts +5 -0
- package/dist/toasts.stories.d.ts +1 -1
- package/dist/toasts.styles.js +1 -1
- package/dist/toggle.stories.d.ts +1 -4
- package/dist/toggle.styles.js +2 -1
- package/dist/toggle.test.interactions.js +11 -0
- package/dist/tooltip.js +1 -1
- package/dist/tooltip.styles.js +16 -30
- package/dist/tooltip.test.interactions.js +6 -6
- package/dist/translations/en.js +1 -1
- package/dist/translations/fr.d.ts +3 -1
- package/dist/translations/fr.js +1 -1
- package/dist/translations/ja.d.ts +3 -1
- package/dist/translations/ja.js +1 -1
- package/dist/tree.item.styles.js +11 -3
- package/dist/tree.item.test.basics.js +0 -30
- package/dist/tree.stories.d.ts +0 -9
- package/package.json +1 -3
- package/dist/button.test.form.d.ts +0 -1
- package/dist/button.test.form.js +0 -50
- package/dist/input.test.translations.js +0 -38
- package/dist/tag.test.translations.d.ts +0 -1
- package/dist/tag.test.translations.js +0 -25
- package/dist/textarea.test.translations.d.ts +0 -1
- package/dist/textarea.test.translations.js +0 -34
- /package/dist/{input.test.translations.d.ts → library/localize.test.d.ts} +0 -0
@@ -1,17 +1,16 @@
|
|
1
1
|
/* eslint-disable @typescript-eslint/no-unused-expressions */
|
2
2
|
import './dropdown.option.js';
|
3
|
-
import {
|
3
|
+
import { expect, fixture, html } from '@open-wc/testing';
|
4
|
+
import { sendKeys } from '@web/test-runner-commands';
|
4
5
|
import GlideCoreDropdown from './dropdown.js';
|
5
6
|
import GlideCoreDropdownOption from './dropdown.option.js';
|
7
|
+
import sinon from 'sinon';
|
6
8
|
GlideCoreDropdown.shadowRootOptions.mode = 'open';
|
7
9
|
GlideCoreDropdownOption.shadowRootOptions.mode = 'open';
|
8
10
|
it('exposes standard form control properties and methods', async () => {
|
9
11
|
const form = document.createElement('form');
|
10
12
|
const component = await fixture(html `<glide-core-dropdown label="Label" placeholder="Placeholder">
|
11
|
-
<glide-core-dropdown-option
|
12
|
-
label="Label"
|
13
|
-
value="value"
|
14
|
-
></glide-core-dropdown-option>
|
13
|
+
<glide-core-dropdown-option label="Label"></glide-core-dropdown-option>
|
15
14
|
</glide-core-dropdown>`, { parentNode: form });
|
16
15
|
expect(component.form).to.equal(form);
|
17
16
|
expect(component.validity instanceof ValidityState).to.be.true;
|
@@ -19,123 +18,35 @@ it('exposes standard form control properties and methods', async () => {
|
|
19
18
|
expect(component.checkValidity).to.be.a('function');
|
20
19
|
expect(component.reportValidity).to.be.a('function');
|
21
20
|
});
|
22
|
-
it('
|
21
|
+
it('submits its form on Enter when closed', async () => {
|
23
22
|
const form = document.createElement('form');
|
24
23
|
const component = await fixture(html `<glide-core-dropdown label="Label" placeholder="Placeholder">
|
25
|
-
<glide-core-dropdown-option
|
26
|
-
label="One"
|
27
|
-
value="one"
|
28
|
-
></glide-core-dropdown-option>
|
29
|
-
|
30
|
-
<glide-core-dropdown-option
|
31
|
-
label="Two"
|
32
|
-
value="two"
|
33
|
-
></glide-core-dropdown-option>
|
24
|
+
<glide-core-dropdown-option label="Label"></glide-core-dropdown-option>
|
34
25
|
</glide-core-dropdown>`, {
|
35
26
|
parentNode: form,
|
36
27
|
});
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
form.reset();
|
42
|
-
await elementUpdated(component);
|
43
|
-
const label = component.shadowRoot?.querySelector('[data-test="internal-label"]');
|
44
|
-
expect(label?.textContent?.trim()).to.equal('Placeholder');
|
45
|
-
expect(component.value).to.deep.equal([]);
|
46
|
-
});
|
47
|
-
it('can be reset to the initially selected option', async () => {
|
48
|
-
const form = document.createElement('form');
|
49
|
-
const component = await fixture(html `<glide-core-dropdown label="Label" placeholder="Placeholder">
|
50
|
-
<glide-core-dropdown-option
|
51
|
-
label="One"
|
52
|
-
value="one"
|
53
|
-
></glide-core-dropdown-option>
|
54
|
-
|
55
|
-
<glide-core-dropdown-option
|
56
|
-
label="Two"
|
57
|
-
value="two"
|
58
|
-
selected
|
59
|
-
></glide-core-dropdown-option>
|
60
|
-
</glide-core-dropdown>`, {
|
61
|
-
parentNode: form,
|
62
|
-
});
|
63
|
-
component
|
64
|
-
.querySelector('glide-core-dropdown-option')
|
65
|
-
?.shadowRoot?.querySelector('[data-test="component"]')
|
66
|
-
?.dispatchEvent(new Event('click'));
|
67
|
-
form.reset();
|
68
|
-
expect(component.value).to.deep.equal(['two']);
|
69
|
-
});
|
70
|
-
it('has `formData` value when an option is selected', async () => {
|
71
|
-
const form = document.createElement('form');
|
72
|
-
await fixture(html `<glide-core-dropdown
|
73
|
-
label="Label"
|
74
|
-
placeholder="Placeholder"
|
75
|
-
name="name"
|
76
|
-
>
|
77
|
-
<glide-core-dropdown-option
|
78
|
-
label="Label"
|
79
|
-
value="value"
|
80
|
-
selected
|
81
|
-
></glide-core-dropdown-option>
|
82
|
-
</glide-core-dropdown>
|
83
|
-
>`, {
|
84
|
-
parentNode: form,
|
28
|
+
const spy = sinon.spy();
|
29
|
+
form.addEventListener('submit', (event) => {
|
30
|
+
event.preventDefault();
|
31
|
+
spy();
|
85
32
|
});
|
86
|
-
|
87
|
-
|
33
|
+
component.focus();
|
34
|
+
await sendKeys({ press: 'Enter' });
|
35
|
+
expect(spy.callCount).to.equal(1);
|
88
36
|
});
|
89
|
-
it('
|
37
|
+
it('does not submit its form on Enter when open', async () => {
|
90
38
|
const form = document.createElement('form');
|
91
|
-
await fixture(html `<glide-core-dropdown
|
92
|
-
label="Label"
|
93
|
-
placeholder="Placeholder"
|
94
|
-
name="name"
|
95
|
-
>
|
96
|
-
<glide-core-dropdown-option
|
97
|
-
label=""
|
98
|
-
value="value"
|
99
|
-
></glide-core-dropdown-option>
|
39
|
+
const component = await fixture(html `<glide-core-dropdown label="Label" placeholder="Placeholder" open>
|
40
|
+
<glide-core-dropdown-option label="Label"></glide-core-dropdown-option>
|
100
41
|
</glide-core-dropdown>`, {
|
101
42
|
parentNode: form,
|
102
43
|
});
|
103
|
-
const
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
const form = document.createElement('form');
|
108
|
-
await fixture(html `<glide-core-dropdown
|
109
|
-
label="Label"
|
110
|
-
placeholder="Placeholder"
|
111
|
-
name="name"
|
112
|
-
disabled
|
113
|
-
>
|
114
|
-
<glide-core-dropdown-option
|
115
|
-
label="Label"
|
116
|
-
value="value"
|
117
|
-
selected
|
118
|
-
></glide-core-dropdown-option>
|
119
|
-
</glide-core-dropdown>`, {
|
120
|
-
parentNode: form,
|
121
|
-
});
|
122
|
-
const formData = new FormData(form);
|
123
|
-
expect(formData.get('name')).to.be.null;
|
124
|
-
});
|
125
|
-
it('has no `formData` value when an option is selected that has no `value`', async () => {
|
126
|
-
const form = document.createElement('form');
|
127
|
-
await fixture(html `<glide-core-dropdown
|
128
|
-
label="Label"
|
129
|
-
placeholder="Placeholder"
|
130
|
-
name="name"
|
131
|
-
>
|
132
|
-
<glide-core-dropdown-option
|
133
|
-
label="Label"
|
134
|
-
selected
|
135
|
-
></glide-core-dropdown-option>
|
136
|
-
</glide-core-dropdown>`, {
|
137
|
-
parentNode: form,
|
44
|
+
const spy = sinon.spy();
|
45
|
+
form.addEventListener('submit', (event) => {
|
46
|
+
event.preventDefault();
|
47
|
+
spy();
|
138
48
|
});
|
139
|
-
|
140
|
-
|
49
|
+
component.focus();
|
50
|
+
await sendKeys({ press: 'Enter' });
|
51
|
+
expect(spy.callCount).to.equal(0);
|
141
52
|
});
|
@@ -1,5 +1,5 @@
|
|
1
1
|
/* eslint-disable @typescript-eslint/no-unused-expressions */
|
2
|
-
import { aTimeout, assert, elementUpdated, expect, fixture, html, } from '@open-wc/testing';
|
2
|
+
import { aTimeout, assert, elementUpdated, expect, fixture, html, oneEvent, } from '@open-wc/testing';
|
3
3
|
import { sendKeys } from '@web/test-runner-commands';
|
4
4
|
import GlideCoreDropdown from './dropdown.js';
|
5
5
|
import GlideCoreDropdownOption from './dropdown.option.js';
|
@@ -97,15 +97,12 @@ it('unfilters when an option is selected via click', async () => {
|
|
97
97
|
await aTimeout(0);
|
98
98
|
component.focus();
|
99
99
|
await sendKeys({ type: ' one ' });
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
option?.click();
|
104
|
-
const input = component.shadowRoot?.querySelector('[data-test="input"]');
|
100
|
+
[...component.querySelectorAll('glide-core-dropdown-option')]
|
101
|
+
.find(({ hidden }) => !hidden)
|
102
|
+
?.click();
|
105
103
|
const options = [
|
106
104
|
...component.querySelectorAll('glide-core-dropdown-option'),
|
107
105
|
].filter(({ hidden }) => !hidden);
|
108
|
-
expect(input?.value).to.equal('');
|
109
106
|
expect(options.length).to.equal(11);
|
110
107
|
});
|
111
108
|
it('unfilters when an option is selected via Enter', async () => {
|
@@ -115,11 +112,9 @@ it('unfilters when an option is selected via Enter', async () => {
|
|
115
112
|
component.focus();
|
116
113
|
await sendKeys({ type: ' one ' });
|
117
114
|
await sendKeys({ press: 'Enter' });
|
118
|
-
const input = component.shadowRoot?.querySelector('[data-test="input"]');
|
119
115
|
const options = [
|
120
116
|
...component.querySelectorAll('glide-core-dropdown-option'),
|
121
117
|
].filter(({ hidden }) => !hidden);
|
122
|
-
expect(input?.value).to.equal('');
|
123
118
|
expect(options.length).to.equal(11);
|
124
119
|
});
|
125
120
|
it('shows the magnifying glass icon when there is a filter term', async () => {
|
@@ -154,6 +149,22 @@ it('hides the magnifying glass icon when an option is selected', async () => {
|
|
154
149
|
await elementUpdated(component);
|
155
150
|
expect(icon?.checkVisibility()).to.be.not.ok;
|
156
151
|
});
|
152
|
+
it('hides the magnifying glass icon when closed programmatically and an option is selected', async () => {
|
153
|
+
const component = await fixture(html `<glide-core-dropdown label="Label" placeholder="Placeholder" open>
|
154
|
+
${defaultSlot}
|
155
|
+
</glide-core-dropdown>`);
|
156
|
+
// Wait for it to open.
|
157
|
+
await aTimeout(0);
|
158
|
+
const option = component.querySelector('glide-core-dropdown-option');
|
159
|
+
assert(option);
|
160
|
+
option.selected = true;
|
161
|
+
component.focus();
|
162
|
+
await sendKeys({ type: 'two' });
|
163
|
+
const icon = component?.shadowRoot?.querySelector('[data-test="magnifying-glass-icon"]');
|
164
|
+
component.open = false;
|
165
|
+
await elementUpdated(component);
|
166
|
+
expect(icon?.checkVisibility()).to.be.not.ok;
|
167
|
+
});
|
157
168
|
it('does not filter on only whitespace', async () => {
|
158
169
|
const component = await fixture(html `<glide-core-dropdown label="Label" placeholder="Placeholder">
|
159
170
|
${defaultSlot}
|
@@ -234,31 +245,53 @@ it('does not select options on Space', async () => {
|
|
234
245
|
await sendKeys({ press: ' ' });
|
235
246
|
expect(options[0]?.selected).to.be.false;
|
236
247
|
});
|
237
|
-
it('deselects
|
248
|
+
it('deselects the last selected option on Backspace', async () => {
|
238
249
|
const component = await fixture(html `<glide-core-dropdown label="Label" placeholder="Placeholder" multiple>
|
239
250
|
${defaultSlot}
|
240
251
|
</glide-core-dropdown>`);
|
241
252
|
const options = component.querySelectorAll('glide-core-dropdown-option');
|
242
253
|
options[0].selected = true;
|
243
254
|
options[1].selected = true;
|
255
|
+
await elementUpdated(component);
|
244
256
|
component.focus();
|
257
|
+
component.shadowRoot
|
258
|
+
?.querySelector('[data-test="input"]')
|
259
|
+
?.setSelectionRange(0, 0);
|
260
|
+
await aTimeout(0);
|
245
261
|
await sendKeys({ press: 'Backspace' });
|
246
262
|
expect(options[1].selected).to.be.false;
|
247
263
|
expect(options[0].selected).to.be.true;
|
248
264
|
await sendKeys({ press: 'Backspace' });
|
249
265
|
expect(options[0].selected).to.be.false;
|
250
266
|
});
|
251
|
-
it('
|
267
|
+
it('deselects all options on Meta + Backspace', async () => {
|
268
|
+
const component = await fixture(html `<glide-core-dropdown label="Label" placeholder="Placeholder" multiple>
|
269
|
+
${defaultSlot}
|
270
|
+
</glide-core-dropdown>`);
|
271
|
+
const options = component.querySelectorAll('glide-core-dropdown-option');
|
272
|
+
options[0].selected = true;
|
273
|
+
options[1].selected = true;
|
274
|
+
await elementUpdated(component);
|
275
|
+
component.focus();
|
276
|
+
component.shadowRoot
|
277
|
+
?.querySelector('[data-test="input"]')
|
278
|
+
?.setSelectionRange(0, 0);
|
279
|
+
await sendKeys({ down: 'Meta' });
|
280
|
+
await sendKeys({ press: 'Backspace' });
|
281
|
+
await sendKeys({ up: 'Meta' });
|
282
|
+
expect(options[1].selected).to.be.false;
|
283
|
+
expect(options[0].selected).to.be.false;
|
284
|
+
});
|
285
|
+
it('set the `value` of the `<input>` to the label of the selected option when not `multiple`', async () => {
|
252
286
|
const component = await fixture(html `<glide-core-dropdown label="Label" placeholder="Placeholder">
|
253
287
|
${defaultSlot}
|
254
288
|
</glide-core-dropdown>`);
|
255
289
|
const option = component?.querySelector('glide-core-dropdown-option');
|
256
290
|
option?.click();
|
257
|
-
await elementUpdated(component);
|
258
291
|
const input = component.shadowRoot?.querySelector('[data-test="input"]');
|
259
|
-
expect(input?.
|
292
|
+
expect(input?.value).to.equal(option?.label);
|
260
293
|
});
|
261
|
-
it('uses `placeholder` as a placeholder when `multiple` and
|
294
|
+
it('uses `placeholder` as a placeholder when `multiple` and no option is selected', async () => {
|
262
295
|
const component = await fixture(html `<glide-core-dropdown label="Label" placeholder="Placeholder" multiple>
|
263
296
|
${defaultSlot}
|
264
297
|
</glide-core-dropdown>`);
|
@@ -286,10 +319,10 @@ it('sets `aria-activedescendant` on ArrowDown', async () => {
|
|
286
319
|
</glide-core-dropdown>`);
|
287
320
|
// Wait for it to open.
|
288
321
|
await aTimeout(0);
|
289
|
-
|
290
|
-
options[0]?.focus();
|
322
|
+
component.focus();
|
291
323
|
await sendKeys({ press: 'ArrowDown' });
|
292
324
|
const input = component.shadowRoot?.querySelector('[data-test="input"]');
|
325
|
+
const options = component.querySelectorAll('glide-core-dropdown-option');
|
293
326
|
expect(input?.getAttribute('aria-activedescendant')).to.equal(options[1].id);
|
294
327
|
});
|
295
328
|
it('sets `aria-activedescendant` on ArrowUp', async () => {
|
@@ -502,6 +535,77 @@ it('cannot be tabbed to when `disabled`', async () => {
|
|
502
535
|
>
|
503
536
|
${defaultSlot}
|
504
537
|
</glide-core-dropdown>`);
|
505
|
-
await sendKeys({
|
538
|
+
await sendKeys({ press: 'Tab' });
|
506
539
|
expect(document.activeElement).to.equal(document.body);
|
507
540
|
});
|
541
|
+
it('sets the `value` of the `<input>` back to the label of selected option when something else is clicked', async () => {
|
542
|
+
const component = await fixture(html `<glide-core-dropdown label="Label" placeholder="Placeholder" open>
|
543
|
+
${defaultSlot}
|
544
|
+
</glide-core-dropdown>`);
|
545
|
+
// Wait for it to open.
|
546
|
+
await aTimeout(0);
|
547
|
+
const option = component.querySelector('glide-core-dropdown-option');
|
548
|
+
assert(option);
|
549
|
+
option.selected = true;
|
550
|
+
// Now type something other than "One" so we can check that it's reverted
|
551
|
+
// back to "One" when something else is clicked.
|
552
|
+
component.focus();
|
553
|
+
await sendKeys({ type: 'o' });
|
554
|
+
document.body.click();
|
555
|
+
const input = component.shadowRoot?.querySelector('[data-test="input"]');
|
556
|
+
expect(input?.value).to.equal('One');
|
557
|
+
});
|
558
|
+
it('selects the filter text when `click()` is called', async () => {
|
559
|
+
const component = await fixture(html `<glide-core-dropdown label="Label" placeholder="Placeholder">
|
560
|
+
${defaultSlot}
|
561
|
+
</glide-core-dropdown>`);
|
562
|
+
component.focus();
|
563
|
+
await sendKeys({ type: 'one' });
|
564
|
+
component.click();
|
565
|
+
expect(window.getSelection()?.toString()).to.equal('one');
|
566
|
+
});
|
567
|
+
it('selects the filter text when the `<input>` is clicked', async () => {
|
568
|
+
const component = await fixture(html `<glide-core-dropdown label="Label" placeholder="Placeholder">
|
569
|
+
${defaultSlot}
|
570
|
+
</glide-core-dropdown>`);
|
571
|
+
component.focus();
|
572
|
+
await sendKeys({ type: 'one' });
|
573
|
+
// Calling `click()` would be sweet. The problem is it sets `event.detail` to `0`,
|
574
|
+
// which puts us in a guard in the event handler. `Event` has no `detail` property
|
575
|
+
// and would work. `CustomEvent` is used for completeness and to get us as close as
|
576
|
+
// possible to a real click. See the comment in the handler for more information.
|
577
|
+
component.shadowRoot
|
578
|
+
?.querySelector('[data-test="input"]')
|
579
|
+
?.dispatchEvent(new CustomEvent('click', { bubbles: true, detail: 1 }));
|
580
|
+
expect(window.getSelection()?.toString()).to.equal('one');
|
581
|
+
});
|
582
|
+
it('selects the filter text when closed and the button is clicked', async () => {
|
583
|
+
const component = await fixture(html `<glide-core-dropdown label="Label" placeholder="Placeholder">
|
584
|
+
${defaultSlot}
|
585
|
+
</glide-core-dropdown>`);
|
586
|
+
component.focus();
|
587
|
+
await sendKeys({ type: 'one' });
|
588
|
+
component.open = false;
|
589
|
+
await elementUpdated(component);
|
590
|
+
// Calling `click()` would be sweet. The problem is it sets `event.detail` to `0`,
|
591
|
+
// which puts us in a guard in the event handler. `Event` has no `detail` property
|
592
|
+
// and would work. `CustomEvent` is used for completeness and to get us as close as
|
593
|
+
// possible to a real click. See the comment in the handler for more information.
|
594
|
+
component.shadowRoot
|
595
|
+
?.querySelector('[data-test="button"]')
|
596
|
+
?.dispatchEvent(new CustomEvent('click', { bubbles: true, detail: 1 }));
|
597
|
+
await elementUpdated(component);
|
598
|
+
expect(window.getSelection()?.toString()).to.equal('one');
|
599
|
+
});
|
600
|
+
it('clicks the `<input>` when `click()` is called', async () => {
|
601
|
+
const component = await fixture(html `<glide-core-dropdown label="Label" placeholder="Placeholder">
|
602
|
+
${defaultSlot}
|
603
|
+
</glide-core-dropdown>`);
|
604
|
+
const button = component.shadowRoot?.querySelector('[data-test="input"]');
|
605
|
+
assert(button);
|
606
|
+
setTimeout(() => {
|
607
|
+
component.click();
|
608
|
+
});
|
609
|
+
const event = await oneEvent(button, 'click');
|
610
|
+
expect(event instanceof PointerEvent).to.be.true;
|
611
|
+
});
|
@@ -1,5 +1,5 @@
|
|
1
1
|
/* eslint-disable @typescript-eslint/no-unused-expressions */
|
2
|
-
import { aTimeout, assert, elementUpdated, expect, fixture, html, } from '@open-wc/testing';
|
2
|
+
import { aTimeout, assert, elementUpdated, expect, fixture, html, oneEvent, } from '@open-wc/testing';
|
3
3
|
import { sendKeys } from '@web/test-runner-commands';
|
4
4
|
import { sendMouse } from '@web/test-runner-commands';
|
5
5
|
import GlideCoreDropdown from './dropdown.js';
|
@@ -1056,11 +1056,11 @@ it('remains open when a tag is clicked', async () => {
|
|
1056
1056
|
await elementUpdated(component);
|
1057
1057
|
expect(component.open).to.be.true;
|
1058
1058
|
});
|
1059
|
-
it('
|
1060
|
-
|
1059
|
+
it('cannot be tabbed to when `disabled`', async () => {
|
1060
|
+
await fixture(html `<glide-core-dropdown
|
1061
1061
|
label="Label"
|
1062
1062
|
placeholder="Placeholder"
|
1063
|
-
|
1063
|
+
disabled
|
1064
1064
|
multiple
|
1065
1065
|
>
|
1066
1066
|
<glide-core-dropdown-option
|
@@ -1073,23 +1073,11 @@ it('does not select an option on Enter when the option is not focused', async ()
|
|
1073
1073
|
value="two"
|
1074
1074
|
></glide-core-dropdown-option>
|
1075
1075
|
</glide-core-dropdown>`);
|
1076
|
-
|
1077
|
-
|
1078
|
-
const option = component.querySelector('glide-core-dropdown-option');
|
1079
|
-
option?.focus();
|
1080
|
-
await sendKeys({ down: 'Tab' });
|
1081
|
-
await sendKeys({ down: 'Shift' });
|
1082
|
-
await sendKeys({ up: 'Tab' });
|
1083
|
-
await sendKeys({ press: 'Enter' });
|
1084
|
-
expect(option?.selected).to.be.false;
|
1076
|
+
await sendKeys({ press: 'Tab' });
|
1077
|
+
expect(document.activeElement).to.equal(document.body);
|
1085
1078
|
});
|
1086
|
-
it('
|
1087
|
-
await fixture(html `<glide-core-dropdown
|
1088
|
-
label="Label"
|
1089
|
-
placeholder="Placeholder"
|
1090
|
-
disabled
|
1091
|
-
multiple
|
1092
|
-
>
|
1079
|
+
it('clicks the button when `click()` is called', async () => {
|
1080
|
+
const component = await fixture(html `<glide-core-dropdown label="Label" placeholder="Placeholder" multiple>
|
1093
1081
|
<glide-core-dropdown-option
|
1094
1082
|
label="One"
|
1095
1083
|
value="one"
|
@@ -1100,6 +1088,11 @@ it('cannot be tabbed to when `disabled`', async () => {
|
|
1100
1088
|
value="two"
|
1101
1089
|
></glide-core-dropdown-option>
|
1102
1090
|
</glide-core-dropdown>`);
|
1103
|
-
|
1104
|
-
|
1091
|
+
const button = component.shadowRoot?.querySelector('[data-test="button"]');
|
1092
|
+
assert(button);
|
1093
|
+
setTimeout(() => {
|
1094
|
+
component.click();
|
1095
|
+
});
|
1096
|
+
const event = await oneEvent(button, 'click');
|
1097
|
+
expect(event instanceof PointerEvent).to.be.true;
|
1105
1098
|
});
|
@@ -1,6 +1,6 @@
|
|
1
1
|
/* eslint-disable @typescript-eslint/no-unused-expressions */
|
2
2
|
import { ArgumentError } from 'ow';
|
3
|
-
import { aTimeout, assert, elementUpdated, expect, fixture, html, } from '@open-wc/testing';
|
3
|
+
import { aTimeout, assert, elementUpdated, expect, fixture, html, oneEvent, } from '@open-wc/testing';
|
4
4
|
import { sendKeys } from '@web/test-runner-commands';
|
5
5
|
import GlideCoreDropdown from './dropdown.js';
|
6
6
|
import GlideCoreDropdownOption from './dropdown.option.js';
|
@@ -97,6 +97,35 @@ it('selects an option on Space', async () => {
|
|
97
97
|
await sendKeys({ press: ' ' });
|
98
98
|
expect(option?.selected).to.be.true;
|
99
99
|
});
|
100
|
+
it('selects an option when its icon is clicked', async () => {
|
101
|
+
const component = await fixture(html `<glide-core-dropdown label="Label" placeholder="Placeholder" open>
|
102
|
+
<glide-core-dropdown-option label="One" value="one">
|
103
|
+
<svg
|
104
|
+
slot="icon"
|
105
|
+
fill="none"
|
106
|
+
viewBox="0 0 24 24"
|
107
|
+
stroke-width="1.5"
|
108
|
+
stroke="currentColor"
|
109
|
+
style="height: 1rem; width: 1rem;"
|
110
|
+
>
|
111
|
+
<path
|
112
|
+
stroke-linecap="round"
|
113
|
+
stroke-linejoin="round"
|
114
|
+
d="M3.75 3.75v4.5m0-4.5h4.5m-4.5 0L9 9M3.75 20.25v-4.5m0 4.5h4.5m-4.5 0L9 15M20.25 3.75h-4.5m4.5 0v4.5m0-4.5L15 9m5.25 11.25h-4.5m4.5 0v-4.5m0 4.5L15 15"
|
115
|
+
/>
|
116
|
+
</svg>
|
117
|
+
</glide-core-dropdown-option>
|
118
|
+
</glide-core-dropdown>`);
|
119
|
+
// Wait for it to open.
|
120
|
+
await aTimeout(0);
|
121
|
+
const option = component.querySelector('glide-core-dropdown-option');
|
122
|
+
option?.shadowRoot
|
123
|
+
?.querySelector('[data-test="icon-slot"]')
|
124
|
+
?.assignedElements()
|
125
|
+
?.at(0)
|
126
|
+
?.dispatchEvent(new Event('click', { bubbles: true }));
|
127
|
+
expect(option?.selected).to.be.true;
|
128
|
+
});
|
100
129
|
it('does not deselect options on Space', async () => {
|
101
130
|
const component = await fixture(html `<glide-core-dropdown label="Label" placeholder="Placeholder" open>
|
102
131
|
<glide-core-dropdown-option
|
@@ -490,8 +519,8 @@ it('hides Select All', async () => {
|
|
490
519
|
const selectAll = component.shadowRoot?.querySelector('[data-test="select-all"]');
|
491
520
|
expect(selectAll?.checkVisibility()).to.not.be.ok;
|
492
521
|
});
|
493
|
-
it('
|
494
|
-
|
522
|
+
it('cannot be tabbed to when `disabled`', async () => {
|
523
|
+
await fixture(html `<glide-core-dropdown label="Label" placeholder="Placeholder" disabled>
|
495
524
|
<glide-core-dropdown-option
|
496
525
|
label="One"
|
497
526
|
value="one"
|
@@ -502,28 +531,21 @@ it('does not select an option on Enter when the option is not focused', async ()
|
|
502
531
|
value="two"
|
503
532
|
></glide-core-dropdown-option>
|
504
533
|
</glide-core-dropdown>`);
|
505
|
-
// Wait for it to open.
|
506
|
-
await aTimeout(0);
|
507
|
-
const option = component.querySelector('glide-core-dropdown-option');
|
508
|
-
option?.focus();
|
509
534
|
await sendKeys({ down: 'Tab' });
|
510
|
-
|
511
|
-
await sendKeys({ up: 'Tab' });
|
512
|
-
await sendKeys({ press: 'Enter' });
|
513
|
-
expect(option?.selected).to.be.false;
|
535
|
+
expect(document.activeElement).to.equal(document.body);
|
514
536
|
});
|
515
|
-
it('
|
516
|
-
await fixture(html `<glide-core-dropdown label="Label" placeholder="Placeholder"
|
517
|
-
<glide-core-dropdown-option
|
518
|
-
label="One"
|
519
|
-
value="one"
|
520
|
-
></glide-core-dropdown-option>
|
521
|
-
|
537
|
+
it('clicks the button when `click()` is called', async () => {
|
538
|
+
const component = await fixture(html `<glide-core-dropdown label="Label" placeholder="Placeholder">
|
522
539
|
<glide-core-dropdown-option
|
523
|
-
label="
|
524
|
-
value="
|
540
|
+
label="Label"
|
541
|
+
value="value"
|
525
542
|
></glide-core-dropdown-option>
|
526
543
|
</glide-core-dropdown>`);
|
527
|
-
|
528
|
-
|
544
|
+
const button = component.shadowRoot?.querySelector('[data-test="button"]');
|
545
|
+
assert(button);
|
546
|
+
setTimeout(() => {
|
547
|
+
component.click();
|
548
|
+
});
|
549
|
+
const event = await oneEvent(button, 'click');
|
550
|
+
expect(event instanceof PointerEvent).to.be.true;
|
529
551
|
});
|
package/dist/icon-button.d.ts
CHANGED
@@ -17,7 +17,7 @@ export default class GlideCoreIconButton extends LitElement {
|
|
17
17
|
ariaExpanded: 'true' | 'false' | null;
|
18
18
|
ariaHasPopup: 'true' | 'false' | 'menu' | 'listbox' | 'tree' | 'grid' | 'dialog' | null;
|
19
19
|
disabled: boolean;
|
20
|
-
/**
|
20
|
+
/** For screenreaders. Required. */
|
21
21
|
label: string;
|
22
22
|
variant: 'primary' | 'secondary' | 'tertiary';
|
23
23
|
firstUpdated(): void;
|
@@ -3,6 +3,4 @@ import './icons/storybook.js';
|
|
3
3
|
import type { Meta, StoryObj } from '@storybook/web-components';
|
4
4
|
declare const meta: Meta;
|
5
5
|
export default meta;
|
6
|
-
export declare const
|
7
|
-
export declare const Secondary: StoryObj;
|
8
|
-
export declare const Tertiary: StoryObj;
|
6
|
+
export declare const IconButton: StoryObj;
|
@@ -1,4 +1,6 @@
|
|
1
1
|
import{css}from"lit";import focusOutline from"./styles/focus-outline.js";export default[css`
|
2
|
+
${focusOutline(".component:focus-visible")}
|
3
|
+
`,css`
|
2
4
|
:host {
|
3
5
|
/* Contains elements with "padding" and "width". Inline by default. */
|
4
6
|
display: inline-flex;
|
@@ -24,10 +26,6 @@ import{css}from"lit";import focusOutline from"./styles/focus-outline.js";export
|
|
24
26
|
outline: none;
|
25
27
|
}
|
26
28
|
|
27
|
-
&:focus-visible {
|
28
|
-
${focusOutline};
|
29
|
-
}
|
30
|
-
|
31
29
|
&:disabled {
|
32
30
|
cursor: not-allowed;
|
33
31
|
opacity: 1;
|
package/dist/icons/checked.d.ts
CHANGED
@@ -1,2 +1,7 @@
|
|
1
|
+
/**
|
2
|
+
* The class="check" on the path below is used as a CSS selector
|
3
|
+
* in checkbox.styles.ts. Please be cautious when making changes
|
4
|
+
* here as to not break the Checkbox selectors.
|
5
|
+
*/
|
1
6
|
declare const _default: import("lit").TemplateResult<1>;
|
2
7
|
export default _default;
|
package/dist/icons/checked.js
CHANGED
@@ -1 +1 @@
|
|
1
|
-
import{html}from"lit";export default html`<svg fill="none" viewBox="0 0 24 24" style="height: var(--size, 0.875rem); width: var(--size, 0.875rem);"><path d="M20 6L9 17L4 12" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>`;
|
1
|
+
import{html}from"lit";export default html`<svg aria-hidden="true" fill="none" viewBox="0 0 24 24" style="height: var(--size, 0.875rem); width: var(--size, 0.875rem);"><path class="check" d="M20 6L9 17L4 12" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>`;
|
package/dist/input.d.ts
CHANGED
@@ -24,7 +24,7 @@ export default class GlideCoreInput extends LitElement {
|
|
24
24
|
#private;
|
25
25
|
static formAssociated: boolean;
|
26
26
|
static shadowRootOptions: ShadowRootInit;
|
27
|
-
static styles: import("lit").CSSResult;
|
27
|
+
static styles: import("lit").CSSResult[];
|
28
28
|
type: SupportedTypes;
|
29
29
|
name?: string;
|
30
30
|
value: string;
|