@crowdstrike/glide-core 0.9.6 → 0.11.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/README.md +17 -53
- package/dist/accordion.d.ts +10 -10
- package/dist/accordion.js +1 -1
- package/dist/accordion.stories.d.ts +0 -1
- package/dist/accordion.styles.js +36 -38
- package/dist/accordion.test.basics.js +13 -95
- package/dist/accordion.test.events.js +21 -33
- package/dist/accordion.test.focus.d.ts +1 -0
- package/dist/accordion.test.focus.js +11 -0
- package/dist/accordion.test.interactions.d.ts +1 -0
- package/dist/accordion.test.interactions.js +75 -0
- package/dist/button-group.button.d.ts +2 -4
- package/dist/button-group.button.js +1 -1
- package/dist/button-group.button.styles.js +6 -14
- package/dist/button-group.button.test.basics.js +8 -17
- package/dist/button-group.button.test.interactions.js +4 -4
- package/dist/button-group.d.ts +0 -2
- package/dist/button-group.test.basics.js +10 -10
- package/dist/button-group.test.events.js +2 -2
- package/dist/button-group.test.interactions.js +1 -1
- package/dist/button.d.ts +7 -10
- package/dist/button.js +1 -1
- package/dist/button.styles.js +4 -7
- package/dist/button.test.basics.js +10 -26
- package/dist/button.test.events.js +9 -9
- package/dist/checkbox-group.d.ts +3 -4
- package/dist/checkbox-group.js +1 -1
- package/dist/checkbox-group.styles.js +13 -1
- package/dist/checkbox-group.test.basics.js +8 -12
- package/dist/checkbox-group.test.focus.js +7 -7
- package/dist/checkbox-group.test.interactions.d.ts +1 -0
- package/dist/checkbox-group.test.interactions.js +82 -0
- package/dist/checkbox.d.ts +5 -4
- package/dist/checkbox.js +1 -1
- package/dist/checkbox.styles.js +35 -15
- package/dist/checkbox.test.basics.js +6 -15
- package/dist/checkbox.test.events.js +9 -0
- package/dist/checkbox.test.focus.js +4 -2
- package/dist/checkbox.test.interactions.js +11 -11
- package/dist/drawer.d.ts +2 -5
- package/dist/drawer.js +1 -1
- package/dist/drawer.test.accessibility.js +8 -8
- package/dist/drawer.test.basics.js +16 -16
- package/dist/drawer.test.closing.js +18 -16
- package/dist/drawer.test.events.js +13 -24
- package/dist/drawer.test.methods.js +22 -22
- package/dist/dropdown.d.ts +7 -5
- package/dist/dropdown.js +1 -1
- package/dist/dropdown.option.d.ts +2 -3
- package/dist/dropdown.option.js +1 -1
- package/dist/dropdown.option.styles.js +31 -19
- package/dist/dropdown.option.test.basics.js +4 -4
- package/dist/dropdown.option.test.events.js +9 -1
- package/dist/dropdown.option.test.interactions.single.js +2 -2
- package/dist/dropdown.styles.js +39 -3
- package/dist/dropdown.test.basics.d.ts +1 -1
- package/dist/dropdown.test.basics.js +27 -14
- package/dist/dropdown.test.basics.multiple.js +65 -32
- package/dist/dropdown.test.basics.single.js +49 -0
- package/dist/dropdown.test.events.filterable.js +13 -2
- package/dist/dropdown.test.focus.filterable.js +12 -3
- package/dist/dropdown.test.focus.js +18 -2
- package/dist/dropdown.test.form.multiple.js +3 -2
- package/dist/dropdown.test.interactions.filterable.js +141 -45
- package/dist/dropdown.test.interactions.js +24 -0
- package/dist/dropdown.test.interactions.multiple.js +87 -30
- package/dist/dropdown.test.interactions.single.js +40 -4
- package/dist/form-controls-layout.d.ts +0 -2
- package/dist/icon-button.d.ts +2 -4
- package/dist/icon-button.js +1 -1
- package/dist/icon-button.test.basics.js +14 -82
- package/dist/icon-button.test.focus.d.ts +1 -0
- package/dist/icon-button.test.focus.js +13 -0
- package/dist/input.d.ts +4 -5
- package/dist/input.js +1 -1
- package/dist/input.styles.js +4 -4
- package/dist/input.test.basics.js +0 -52
- package/dist/input.test.events.js +27 -27
- package/dist/input.test.focus.js +27 -26
- package/dist/input.test.form.js +6 -6
- package/dist/input.test.validity.js +130 -130
- package/dist/label.d.ts +1 -3
- package/dist/label.js +1 -1
- package/dist/label.styles.js +5 -6
- package/dist/label.test.basics.js +4 -4
- package/dist/library/ow.js +1 -1
- package/dist/menu.button.d.ts +0 -2
- package/dist/menu.button.test.basics.js +3 -3
- package/dist/menu.d.ts +1 -4
- package/dist/menu.js +1 -1
- package/dist/menu.link.d.ts +1 -2
- package/dist/menu.link.js +1 -1
- package/dist/menu.options.d.ts +0 -2
- package/dist/menu.test.events.js +6 -6
- package/dist/menu.test.focus.js +5 -18
- package/dist/menu.test.interactions.js +48 -24
- package/dist/modal.d.ts +6 -17
- package/dist/modal.icon-button.d.ts +0 -2
- package/dist/modal.icon-button.test.basics.js +3 -3
- package/dist/modal.js +1 -1
- package/dist/modal.styles.js +13 -19
- package/dist/modal.tertiary-icon.d.ts +0 -3
- package/dist/modal.tertiary-icon.test.basics.js +3 -3
- package/dist/modal.test.basics.js +9 -5
- package/dist/modal.test.close.js +2 -2
- package/dist/modal.test.events.js +2 -2
- package/dist/radio-group.d.ts +0 -3
- package/dist/radio-group.js +1 -1
- package/dist/radio-group.test.basics.js +61 -61
- package/dist/radio-group.test.events.js +13 -13
- package/dist/radio-group.test.focus.js +1 -1
- package/dist/radio-group.test.form.js +2 -2
- package/dist/radio-group.test.validity.js +12 -12
- package/dist/radio.d.ts +0 -3
- package/dist/radio.styles.js +4 -12
- package/dist/split-button.d.ts +8 -11
- package/dist/split-button.js +1 -1
- package/dist/split-button.primary-button.d.ts +21 -0
- package/dist/split-button.primary-button.js +1 -0
- package/dist/split-button.primary-button.styles.js +96 -0
- package/dist/split-button.primary-button.test.basics.d.ts +1 -0
- package/dist/split-button.primary-button.test.basics.js +31 -0
- package/dist/split-button.primary-button.test.focus.d.ts +1 -0
- package/dist/split-button.primary-button.test.focus.js +14 -0
- package/dist/split-button.primary-link.d.ts +19 -0
- package/dist/split-button.primary-link.js +1 -0
- package/dist/split-button.primary-link.test.basics.d.ts +1 -0
- package/dist/split-button.primary-link.test.basics.js +30 -0
- package/dist/split-button.primary-link.test.focus.d.ts +1 -0
- package/dist/split-button.primary-link.test.focus.js +15 -0
- package/dist/split-button.secondary-button.d.ts +25 -0
- package/dist/split-button.secondary-button.js +1 -0
- package/dist/split-button.secondary-button.styles.js +103 -0
- package/dist/split-button.secondary-button.test.basics.d.ts +1 -0
- package/dist/split-button.secondary-button.test.basics.js +58 -0
- package/dist/split-button.secondary-button.test.focus.d.ts +1 -0
- package/dist/split-button.secondary-button.test.focus.js +14 -0
- package/dist/split-button.secondary-button.test.interactions.d.ts +2 -0
- package/dist/split-button.secondary-button.test.interactions.js +30 -0
- package/dist/split-button.stories.d.ts +4 -3
- package/dist/split-button.styles.js +1 -94
- package/dist/split-button.test.basics.d.ts +2 -1
- package/dist/split-button.test.basics.js +67 -80
- package/dist/split-button.test.interactions.d.ts +4 -0
- package/dist/split-button.test.interactions.js +51 -0
- package/dist/styles/opacity-and-scale-animation.js +2 -6
- package/dist/styles/variables.css +1 -1
- package/dist/tab.d.ts +2 -11
- package/dist/tab.group.d.ts +3 -5
- package/dist/tab.group.js +1 -1
- package/dist/tab.group.styles.js +18 -15
- package/dist/tab.group.test.basics.js +49 -34
- package/dist/tab.group.test.interactions.js +17 -14
- package/dist/tab.panel.d.ts +0 -3
- package/dist/tab.test.basics.js +6 -5
- package/dist/tag.d.ts +5 -4
- package/dist/tag.js +1 -1
- package/dist/tag.styles.js +47 -38
- package/dist/tag.test.basics.js +18 -110
- package/dist/tag.test.events.js +12 -8
- package/dist/tag.test.focus.js +2 -3
- package/dist/tag.test.interactions.d.ts +1 -0
- package/dist/tag.test.interactions.js +36 -0
- package/dist/textarea.d.ts +2 -3
- package/dist/textarea.js +2 -2
- package/dist/textarea.test.basics.js +8 -8
- package/dist/textarea.test.events.js +55 -55
- package/dist/textarea.test.form.js +9 -9
- package/dist/textarea.test.validity.js +167 -135
- package/dist/toasts.d.ts +1 -5
- package/dist/toasts.test.basics.js +2 -1
- package/dist/toasts.toast.d.ts +1 -4
- package/dist/toasts.toast.js +1 -1
- package/dist/toasts.toast.styles.js +12 -0
- package/dist/toggle.d.ts +0 -2
- package/dist/toggle.styles.js +1 -5
- package/dist/toggle.test.basics.js +2 -2
- package/dist/toggle.test.interactions.js +7 -7
- package/dist/tooltip.d.ts +2 -1
- package/dist/tooltip.js +1 -1
- package/dist/tooltip.styles.js +37 -13
- package/dist/tooltip.test.basics.d.ts +1 -1
- package/dist/tooltip.test.basics.js +19 -19
- package/dist/tree.d.ts +0 -2
- package/dist/tree.item.d.ts +5 -7
- package/dist/tree.item.icon-button.d.ts +1 -4
- package/dist/tree.item.js +1 -1
- package/dist/tree.item.menu.d.ts +1 -2
- package/dist/tree.item.menu.js +1 -1
- package/dist/tree.item.menu.test.basics.js +31 -10
- package/dist/tree.item.styles.js +7 -9
- package/dist/tree.item.test.basics.js +43 -31
- package/dist/tree.test.basics.js +29 -29
- package/dist/tree.test.focus.js +77 -74
- package/package.json +12 -14
- package/dist/split-container.d.ts +0 -31
- package/dist/split-container.js +0 -1
- package/dist/split-container.styles.js +0 -132
- package/dist/split-container.test.basics.d.ts +0 -3
- package/dist/split-container.test.basics.js +0 -445
- package/dist/split-container.test.interactions.d.ts +0 -1
- package/dist/split-container.test.interactions.js +0 -20
- package/dist/split-link.d.ts +0 -25
- package/dist/split-link.js +0 -1
- package/dist/split-link.test.basics.d.ts +0 -1
- package/dist/split-link.test.basics.js +0 -93
- package/dist/split-link.test.interactions.d.ts +0 -1
- package/dist/split-link.test.interactions.js +0 -20
- package/dist/status-indicator.d.ts +0 -30
- package/dist/status-indicator.js +0 -1
- package/dist/status-indicator.stories.d.ts +0 -5
- package/dist/status-indicator.styles.js +0 -58
- package/dist/status-indicator.test.basics.d.ts +0 -1
- package/dist/status-indicator.test.basics.js +0 -102
- /package/dist/{split-container.styles.d.ts → split-button.primary-button.styles.d.ts} +0 -0
- /package/dist/{status-indicator.styles.d.ts → split-button.secondary-button.styles.d.ts} +0 -0
@@ -9,90 +9,90 @@ import { sendKeys } from '@web/test-runner-commands';
|
|
9
9
|
// configured. But waiting a turn of the event loop, after which the event
|
10
10
|
// will have been dispatched, gets the job done as well.
|
11
11
|
it('dispatches a "change" event when typed in', async () => {
|
12
|
-
const
|
12
|
+
const component = await fixture(html `<glide-core-input></glide-core-input>`);
|
13
13
|
setTimeout(async () => {
|
14
|
-
|
14
|
+
component.focus();
|
15
15
|
await sendKeys({ type: 'testing' });
|
16
|
-
|
16
|
+
component.blur();
|
17
17
|
});
|
18
|
-
const event = await oneEvent(
|
18
|
+
const event = await oneEvent(component, 'change');
|
19
19
|
expect(event instanceof Event).to.be.true;
|
20
20
|
expect(event.bubbles).to.be.true;
|
21
21
|
});
|
22
22
|
it('dispatches an "input" event when typed in', async () => {
|
23
|
-
const
|
23
|
+
const component = await fixture(html `<glide-core-input></glide-core-input>`);
|
24
24
|
setTimeout(() => {
|
25
|
-
|
25
|
+
component.focus();
|
26
26
|
sendKeys({ type: 'testing' });
|
27
27
|
});
|
28
|
-
const event = await oneEvent(
|
28
|
+
const event = await oneEvent(component, 'input');
|
29
29
|
expect(event instanceof Event).to.be.true;
|
30
30
|
expect(event.bubbles).to.be.true;
|
31
31
|
});
|
32
32
|
it('dispatches an "invalid" event on submit when required and no value', async () => {
|
33
33
|
const form = document.createElement('form');
|
34
|
-
const
|
34
|
+
const component = await fixture(html `<glide-core-input required></glide-core-input>`, {
|
35
35
|
parentNode: form,
|
36
36
|
});
|
37
37
|
setTimeout(() => form.requestSubmit());
|
38
|
-
const event = await oneEvent(
|
38
|
+
const event = await oneEvent(component, 'invalid');
|
39
39
|
expect(event instanceof Event).to.be.true;
|
40
40
|
});
|
41
41
|
it('dispatches an "invalid" event after `checkValidity` is called when required and no value', async () => {
|
42
42
|
const form = document.createElement('form');
|
43
|
-
const
|
43
|
+
const component = await fixture(html `<glide-core-input required></glide-core-input>`, {
|
44
44
|
parentNode: form,
|
45
45
|
});
|
46
|
-
setTimeout(() =>
|
47
|
-
const event = await oneEvent(
|
46
|
+
setTimeout(() => component.checkValidity());
|
47
|
+
const event = await oneEvent(component, 'invalid');
|
48
48
|
expect(event instanceof Event).to.be.true;
|
49
49
|
});
|
50
50
|
it('dispatches an "invalid" event after `reportValidity` is called when required and no value', async () => {
|
51
51
|
const form = document.createElement('form');
|
52
|
-
const
|
52
|
+
const component = await fixture(html `<glide-core-input required></glide-core-input>`, {
|
53
53
|
parentNode: form,
|
54
54
|
});
|
55
|
-
setTimeout(() =>
|
56
|
-
const event = await oneEvent(
|
55
|
+
setTimeout(() => component.reportValidity());
|
56
|
+
const event = await oneEvent(component, 'invalid');
|
57
57
|
expect(event instanceof Event).to.be.true;
|
58
58
|
});
|
59
59
|
it('does not dispatch an "invalid" event after `checkValidity` is called when not required', async () => {
|
60
60
|
const form = document.createElement('form');
|
61
|
-
const
|
61
|
+
const component = await fixture(html `<glide-core-input></glide-core-input>`, {
|
62
62
|
parentNode: form,
|
63
63
|
});
|
64
64
|
const spy = sinon.spy();
|
65
|
-
|
66
|
-
|
65
|
+
component.addEventListener('invalid', spy);
|
66
|
+
component.checkValidity();
|
67
67
|
await aTimeout(0);
|
68
68
|
expect(spy.callCount).to.equal(0);
|
69
69
|
});
|
70
70
|
it('does not dispatch an "invalid" event after `checkValidity` is called when required and no value but disabled', async () => {
|
71
71
|
const form = document.createElement('form');
|
72
|
-
const
|
72
|
+
const component = await fixture(html `<glide-core-input disabled required></glide-core-input>`, { parentNode: form });
|
73
73
|
const spy = sinon.spy();
|
74
|
-
|
75
|
-
|
74
|
+
component.addEventListener('invalid', spy);
|
75
|
+
component.checkValidity();
|
76
76
|
await aTimeout(0);
|
77
77
|
expect(spy.callCount).to.equal(0);
|
78
78
|
});
|
79
79
|
it('does not dispatch an "invalid" event when `reportValidity` is called when not required,', async () => {
|
80
80
|
const form = document.createElement('form');
|
81
|
-
const
|
81
|
+
const component = await fixture(html `<glide-core-input></glide-core-input>`, {
|
82
82
|
parentNode: form,
|
83
83
|
});
|
84
84
|
const spy = sinon.spy();
|
85
|
-
|
86
|
-
|
85
|
+
component.addEventListener('invalid', spy);
|
86
|
+
component.reportValidity();
|
87
87
|
await aTimeout(0);
|
88
88
|
expect(spy.callCount).to.equal(0);
|
89
89
|
});
|
90
90
|
it('does not dispatch an "invalid" event when `reportValidity` is called when required and no value but disabled', async () => {
|
91
91
|
const form = document.createElement('form');
|
92
|
-
const
|
92
|
+
const component = await fixture(html `<glide-core-input disabled required></glide-core-input>`, { parentNode: form });
|
93
93
|
const spy = sinon.spy();
|
94
|
-
|
95
|
-
|
94
|
+
component.addEventListener('invalid', spy);
|
95
|
+
component.reportValidity();
|
96
96
|
await aTimeout(0);
|
97
97
|
expect(spy.callCount).to.equal(0);
|
98
98
|
});
|
package/dist/input.test.focus.js
CHANGED
@@ -4,54 +4,55 @@ import { expect, fixture, html } from '@open-wc/testing';
|
|
4
4
|
import GlideCoreInput from './input.js';
|
5
5
|
GlideCoreInput.shadowRootOptions.mode = 'open';
|
6
6
|
it('focuses the input when `focus()` is called', async () => {
|
7
|
-
const
|
8
|
-
|
9
|
-
const inputElement =
|
10
|
-
expect(
|
7
|
+
const component = await fixture(html `<glide-core-input required></glide-core-input>`);
|
8
|
+
component.focus();
|
9
|
+
const inputElement = component.shadowRoot?.querySelector('input');
|
10
|
+
expect(component.shadowRoot?.activeElement).to.equal(inputElement);
|
11
11
|
});
|
12
12
|
it('focuses the input after submit when required and no value', async () => {
|
13
13
|
const form = document.createElement('form');
|
14
|
-
const
|
14
|
+
const component = await fixture(html `<glide-core-input required></glide-core-input>`, {
|
15
15
|
parentNode: form,
|
16
16
|
});
|
17
17
|
form.requestSubmit();
|
18
|
-
const inputElement =
|
19
|
-
expect(
|
18
|
+
const inputElement = component.shadowRoot?.querySelector('input');
|
19
|
+
expect(component.shadowRoot?.activeElement).to.be.equal(inputElement);
|
20
20
|
});
|
21
21
|
it('blurs the input and reports validity if `blur` is called', async () => {
|
22
|
-
const
|
23
|
-
|
24
|
-
const inputElement =
|
25
|
-
expect(
|
26
|
-
|
27
|
-
await
|
28
|
-
expect(
|
29
|
-
expect(
|
30
|
-
expect(
|
22
|
+
const component = await fixture(html `<glide-core-input required></glide-core-input>`);
|
23
|
+
component.focus();
|
24
|
+
const inputElement = component.shadowRoot?.querySelector('input');
|
25
|
+
expect(component.shadowRoot?.activeElement).to.equal(inputElement);
|
26
|
+
component.blur();
|
27
|
+
await component.updateComplete;
|
28
|
+
expect(component.shadowRoot?.activeElement).to.equal(null);
|
29
|
+
expect(component.validity.valid).to.be.false;
|
30
|
+
expect(component.shadowRoot?.querySelector('glide-core-private-label')?.error)
|
31
|
+
.to.be.true;
|
31
32
|
});
|
32
33
|
it('focuses the input after `reportValidity` is called when required and no value', async () => {
|
33
34
|
const form = document.createElement('form');
|
34
|
-
const
|
35
|
+
const component = await fixture(html `<glide-core-input required></glide-core-input>`, {
|
35
36
|
parentNode: form,
|
36
37
|
});
|
37
|
-
|
38
|
-
const inputElement =
|
39
|
-
expect(
|
38
|
+
component.reportValidity();
|
39
|
+
const inputElement = component.shadowRoot?.querySelector('input');
|
40
|
+
expect(component.shadowRoot?.activeElement).to.equal(inputElement);
|
40
41
|
});
|
41
42
|
it('focuses the input after `requestSubmit` is called when required and no value', async () => {
|
42
43
|
const form = document.createElement('form');
|
43
|
-
const
|
44
|
+
const component = await fixture(html `<glide-core-input required></glide-core-input>`, {
|
44
45
|
parentNode: form,
|
45
46
|
});
|
46
47
|
form.requestSubmit();
|
47
|
-
const inputElement =
|
48
|
-
expect(
|
48
|
+
const inputElement = component.shadowRoot?.querySelector('input');
|
49
|
+
expect(component.shadowRoot?.activeElement === inputElement).to.be.true;
|
49
50
|
});
|
50
51
|
it('does not focus the input after `checkValidity` is called', async () => {
|
51
52
|
const form = document.createElement('form');
|
52
|
-
const
|
53
|
+
const component = await fixture(html `<glide-core-input required></glide-core-input>`, {
|
53
54
|
parentNode: form,
|
54
55
|
});
|
55
|
-
|
56
|
-
expect(
|
56
|
+
component.checkValidity();
|
57
|
+
expect(component.shadowRoot?.activeElement === null).to.be.true;
|
57
58
|
});
|
package/dist/input.test.form.js
CHANGED
@@ -6,21 +6,21 @@ import GlideCoreInput from './input.js';
|
|
6
6
|
import sinon from 'sinon';
|
7
7
|
it('can be reset to initial value', async () => {
|
8
8
|
const form = document.createElement('form');
|
9
|
-
const
|
9
|
+
const component = await fixture(html `<glide-core-input value="value"></glide-core-input>`, {
|
10
10
|
parentNode: form,
|
11
11
|
});
|
12
|
-
|
12
|
+
component.value = '';
|
13
13
|
form.reset();
|
14
|
-
expect(
|
14
|
+
expect(component.value).to.equal('value');
|
15
15
|
});
|
16
16
|
it('can be reset if there was no initial value', async () => {
|
17
17
|
const form = document.createElement('form');
|
18
|
-
const
|
18
|
+
const component = await fixture(html `<glide-core-input></glide-core-input>`, {
|
19
19
|
parentNode: form,
|
20
20
|
});
|
21
|
-
|
21
|
+
component.value = 'value';
|
22
22
|
form.reset();
|
23
|
-
expect(
|
23
|
+
expect(component.value).to.equal('');
|
24
24
|
});
|
25
25
|
it('has `formData` value when it has a value', async () => {
|
26
26
|
const form = document.createElement('form');
|
@@ -5,176 +5,176 @@ import { sendKeys } from '@web/test-runner-commands';
|
|
5
5
|
import GlideCoreInput from './input.js';
|
6
6
|
GlideCoreInput.shadowRootOptions.mode = 'open';
|
7
7
|
it('is valid if empty but not required', async () => {
|
8
|
-
const
|
9
|
-
expect(
|
10
|
-
expect(
|
11
|
-
expect(
|
12
|
-
expect(
|
13
|
-
await elementUpdated(
|
14
|
-
expect(
|
8
|
+
const component = await fixture(html `<glide-core-input></glide-core-input>`);
|
9
|
+
expect(component.validity?.valid).to.be.true;
|
10
|
+
expect(component.validity?.valueMissing).to.be.false;
|
11
|
+
expect(component.checkValidity()).to.be.true;
|
12
|
+
expect(component.reportValidity()).to.be.true;
|
13
|
+
await elementUpdated(component);
|
14
|
+
expect(component.shadowRoot?.querySelector('input')?.getAttribute('aria-invalid')).to.equal('false');
|
15
15
|
});
|
16
16
|
it('is valid after being filled in when empty and required', async () => {
|
17
|
-
const
|
18
|
-
|
17
|
+
const component = await fixture(html `<glide-core-input required></glide-core-input>`);
|
18
|
+
component.focus();
|
19
19
|
await sendKeys({ type: 'value' });
|
20
|
-
expect(
|
21
|
-
expect(
|
22
|
-
expect(
|
23
|
-
expect(
|
24
|
-
await elementUpdated(
|
25
|
-
expect(
|
20
|
+
expect(component.validity?.valid).to.be.true;
|
21
|
+
expect(component.validity?.valueMissing).to.be.false;
|
22
|
+
expect(component.checkValidity()).to.be.true;
|
23
|
+
expect(component.reportValidity()).to.be.true;
|
24
|
+
await elementUpdated(component);
|
25
|
+
expect(component.shadowRoot?.querySelector('input')?.getAttribute('aria-invalid')).to.equal('false');
|
26
26
|
});
|
27
27
|
it('is invalid if no value and required', async () => {
|
28
|
-
const
|
29
|
-
expect(
|
30
|
-
expect(
|
31
|
-
expect(
|
32
|
-
expect(
|
33
|
-
expect(
|
34
|
-
await elementUpdated(
|
35
|
-
expect(
|
28
|
+
const component = await fixture(html `<glide-core-input required></glide-core-input>`);
|
29
|
+
expect(component.validity?.valid).to.be.false;
|
30
|
+
expect(component.validity?.valueMissing).to.be.true;
|
31
|
+
expect(component.willValidate).to.be.true;
|
32
|
+
expect(component.checkValidity()).to.be.false;
|
33
|
+
expect(component.reportValidity()).to.be.false;
|
34
|
+
await elementUpdated(component);
|
35
|
+
expect(component.shadowRoot?.querySelector('input')?.getAttribute('aria-invalid')).to.equal('true');
|
36
36
|
});
|
37
37
|
it('is invalid after value is cleared when required', async () => {
|
38
|
-
const
|
38
|
+
const component = await fixture(html `<glide-core-input
|
39
39
|
clearable
|
40
40
|
value="value"
|
41
41
|
required
|
42
42
|
></glide-core-input>`);
|
43
|
-
const clearButton =
|
43
|
+
const clearButton = component.shadowRoot?.querySelector('[data-test="clear-button"]');
|
44
44
|
clearButton?.click();
|
45
|
-
await
|
46
|
-
expect(
|
47
|
-
expect(
|
48
|
-
expect(
|
49
|
-
expect(
|
50
|
-
await elementUpdated(
|
51
|
-
expect(
|
45
|
+
await component.updateComplete;
|
46
|
+
expect(component.validity?.valid).to.be.false;
|
47
|
+
expect(component.validity?.valueMissing).to.be.true;
|
48
|
+
expect(component.checkValidity()).to.be.false;
|
49
|
+
expect(component.reportValidity()).to.be.false;
|
50
|
+
await elementUpdated(component);
|
51
|
+
expect(component.shadowRoot?.querySelector('input')?.getAttribute('aria-invalid')).to.equal('true');
|
52
52
|
});
|
53
53
|
it('is valid when empty and does not exceed `maxlength`', async () => {
|
54
|
-
const
|
55
|
-
expect(
|
56
|
-
expect(
|
57
|
-
expect(
|
58
|
-
expect(
|
59
|
-
expect(
|
60
|
-
await elementUpdated(
|
61
|
-
expect(
|
54
|
+
const component = await fixture(html `<glide-core-input maxlength="3"></glide-core-input>`);
|
55
|
+
expect(component.validity?.valid).to.be.true;
|
56
|
+
expect(component.validity?.valueMissing).to.be.false;
|
57
|
+
expect(component.validity?.tooLong).to.be.false;
|
58
|
+
expect(component.checkValidity()).to.be.true;
|
59
|
+
expect(component.reportValidity()).to.be.true;
|
60
|
+
await elementUpdated(component);
|
61
|
+
expect(component.shadowRoot?.querySelector('input')?.getAttribute('aria-invalid')).to.equal('false');
|
62
62
|
});
|
63
63
|
it('is valid when filled in and does not exceed `maxlength`', async () => {
|
64
|
-
const
|
65
|
-
|
64
|
+
const component = await fixture(html `<glide-core-input maxlength="3"></glide-core-input>`);
|
65
|
+
component.focus();
|
66
66
|
await sendKeys({ type: 'val' });
|
67
|
-
expect(
|
68
|
-
expect(
|
69
|
-
expect(
|
70
|
-
expect(
|
71
|
-
expect(
|
72
|
-
await elementUpdated(
|
73
|
-
expect(
|
67
|
+
expect(component.validity?.valid).to.be.true;
|
68
|
+
expect(component.validity?.valueMissing).to.be.false;
|
69
|
+
expect(component.validity?.tooLong).to.be.false;
|
70
|
+
expect(component.checkValidity()).to.be.true;
|
71
|
+
expect(component.reportValidity()).to.be.true;
|
72
|
+
await elementUpdated(component);
|
73
|
+
expect(component.shadowRoot?.querySelector('input')?.getAttribute('aria-invalid')).to.equal('false');
|
74
74
|
});
|
75
75
|
it('is valid when filled in, disabled, and value exceeds `maxlength`', async () => {
|
76
|
-
const
|
76
|
+
const component = await fixture(html `<glide-core-input
|
77
77
|
value="value"
|
78
78
|
maxlength="3"
|
79
79
|
disabled
|
80
80
|
></glide-core-input>`);
|
81
|
-
expect(
|
82
|
-
expect(
|
83
|
-
expect(
|
84
|
-
expect(
|
85
|
-
expect(
|
86
|
-
await elementUpdated(
|
87
|
-
expect(
|
81
|
+
expect(component.validity?.valid).to.be.true;
|
82
|
+
expect(component.validity?.valueMissing).to.be.false;
|
83
|
+
expect(component.validity?.tooLong).to.be.false;
|
84
|
+
expect(component.checkValidity()).to.be.true;
|
85
|
+
expect(component.reportValidity()).to.be.true;
|
86
|
+
await elementUpdated(component);
|
87
|
+
expect(component.shadowRoot?.querySelector('input')?.getAttribute('aria-invalid')).to.equal('false');
|
88
88
|
});
|
89
89
|
it('is valid when filled in, readonly, and value exceeds `maxlength`', async () => {
|
90
|
-
const
|
90
|
+
const component = await fixture(html `<glide-core-input
|
91
91
|
value="value"
|
92
92
|
maxlength="3"
|
93
93
|
readonly
|
94
94
|
></glide-core-input>`);
|
95
|
-
expect(
|
96
|
-
expect(
|
97
|
-
expect(
|
98
|
-
expect(
|
99
|
-
expect(
|
100
|
-
await elementUpdated(
|
101
|
-
expect(
|
95
|
+
expect(component.validity?.valid).to.be.true;
|
96
|
+
expect(component.validity?.valueMissing).to.be.false;
|
97
|
+
expect(component.validity?.tooLong).to.be.false;
|
98
|
+
expect(component.checkValidity()).to.be.true;
|
99
|
+
expect(component.reportValidity()).to.be.true;
|
100
|
+
await elementUpdated(component);
|
101
|
+
expect(component.shadowRoot?.querySelector('input')?.getAttribute('aria-invalid')).to.equal('false');
|
102
102
|
});
|
103
103
|
it('is invalid when filled in and exceeds `maxlength`', async () => {
|
104
|
-
const
|
105
|
-
|
104
|
+
const component = await fixture(html `<glide-core-input maxlength="3"></glide-core-input>`);
|
105
|
+
component.focus();
|
106
106
|
await sendKeys({ type: 'value' });
|
107
|
-
expect(
|
108
|
-
expect(
|
109
|
-
expect(
|
110
|
-
expect(
|
111
|
-
await elementUpdated(
|
112
|
-
expect(
|
107
|
+
expect(component.validity?.valid).to.be.false;
|
108
|
+
expect(component.validity?.tooLong).to.be.true;
|
109
|
+
expect(component.checkValidity()).to.be.false;
|
110
|
+
expect(component.reportValidity()).to.be.false;
|
111
|
+
await elementUpdated(component);
|
112
|
+
expect(component.shadowRoot?.querySelector('input')?.getAttribute('aria-invalid')).to.equal('true');
|
113
113
|
});
|
114
114
|
it('is valid if no value and required but disabled', async () => {
|
115
|
-
const
|
116
|
-
expect(
|
117
|
-
expect(
|
118
|
-
expect(
|
119
|
-
expect(
|
120
|
-
await elementUpdated(
|
121
|
-
expect(
|
115
|
+
const component = await fixture(html `<glide-core-input disabled required></glide-core-input>`);
|
116
|
+
expect(component.validity?.valid).to.be.true;
|
117
|
+
expect(component.validity?.valueMissing).to.be.false;
|
118
|
+
expect(component.checkValidity()).to.be.true;
|
119
|
+
expect(component.reportValidity()).to.be.true;
|
120
|
+
await elementUpdated(component);
|
121
|
+
expect(component.shadowRoot?.querySelector('input')?.getAttribute('aria-invalid')).to.equal('false');
|
122
122
|
});
|
123
123
|
it('updates validity when `required` and `value` is changed programmatically', async () => {
|
124
|
-
const
|
125
|
-
expect(
|
126
|
-
expect(
|
127
|
-
expect(
|
128
|
-
expect(
|
129
|
-
await elementUpdated(
|
130
|
-
expect(
|
131
|
-
|
132
|
-
await elementUpdated(
|
133
|
-
expect(
|
134
|
-
expect(
|
135
|
-
expect(
|
136
|
-
expect(
|
137
|
-
await elementUpdated(
|
138
|
-
expect(
|
124
|
+
const component = await fixture(html `<glide-core-input label="Label" required></glide-core-input>`);
|
125
|
+
expect(component.validity?.valid).to.be.false;
|
126
|
+
expect(component.validity?.valueMissing).to.be.true;
|
127
|
+
expect(component.checkValidity()).to.be.false;
|
128
|
+
expect(component.reportValidity()).to.be.false;
|
129
|
+
await elementUpdated(component);
|
130
|
+
expect(component.shadowRoot?.querySelector('input')?.getAttribute('aria-invalid')).to.equal('true');
|
131
|
+
component.value = 'text';
|
132
|
+
await elementUpdated(component);
|
133
|
+
expect(component.validity?.valid).to.be.true;
|
134
|
+
expect(component.validity?.valueMissing).to.be.false;
|
135
|
+
expect(component.checkValidity()).to.be.true;
|
136
|
+
expect(component.reportValidity()).to.be.true;
|
137
|
+
await elementUpdated(component);
|
138
|
+
expect(component.shadowRoot?.querySelector('input')?.getAttribute('aria-invalid')).to.equal('false');
|
139
139
|
// Resetting the value to empty to ensure it goes
|
140
140
|
// back to an invalid state
|
141
|
-
|
142
|
-
await elementUpdated(
|
143
|
-
expect(
|
144
|
-
expect(
|
145
|
-
expect(
|
146
|
-
expect(
|
147
|
-
expect(
|
141
|
+
component.value = '';
|
142
|
+
await elementUpdated(component);
|
143
|
+
expect(component.validity?.valid).to.be.false;
|
144
|
+
expect(component.validity?.valueMissing).to.be.true;
|
145
|
+
expect(component.checkValidity()).to.be.false;
|
146
|
+
expect(component.reportValidity()).to.be.false;
|
147
|
+
expect(component.shadowRoot?.querySelector('input')?.getAttribute('aria-invalid')).to.equal('true');
|
148
148
|
});
|
149
149
|
it('is invalid when `value` is empty and `required` is set to `true` programmatically', async () => {
|
150
|
-
const
|
151
|
-
expect(
|
152
|
-
expect(
|
153
|
-
expect(
|
154
|
-
expect(
|
155
|
-
await elementUpdated(
|
156
|
-
expect(
|
157
|
-
|
158
|
-
await elementUpdated(
|
159
|
-
expect(
|
160
|
-
expect(
|
161
|
-
expect(
|
162
|
-
expect(
|
163
|
-
expect(
|
150
|
+
const component = await fixture(html `<glide-core-input label="Label"></glide-core-input>`);
|
151
|
+
expect(component.validity?.valid).to.be.true;
|
152
|
+
expect(component.validity?.valueMissing).to.be.false;
|
153
|
+
expect(component.checkValidity()).to.be.true;
|
154
|
+
expect(component.reportValidity()).to.be.true;
|
155
|
+
await elementUpdated(component);
|
156
|
+
expect(component.shadowRoot?.querySelector('input')?.getAttribute('aria-invalid')).to.equal('false');
|
157
|
+
component.required = true;
|
158
|
+
await elementUpdated(component);
|
159
|
+
expect(component.validity?.valid).to.be.false;
|
160
|
+
expect(component.validity?.valueMissing).to.be.true;
|
161
|
+
expect(component.checkValidity()).to.be.false;
|
162
|
+
expect(component.reportValidity()).to.be.false;
|
163
|
+
expect(component.shadowRoot?.querySelector('input')?.getAttribute('aria-invalid')).to.equal('true');
|
164
164
|
});
|
165
165
|
it('is valid when `value` is empty and `required` is set to `false` programmatically', async () => {
|
166
|
-
const
|
167
|
-
expect(
|
168
|
-
expect(
|
169
|
-
expect(
|
170
|
-
expect(
|
171
|
-
await elementUpdated(
|
172
|
-
expect(
|
173
|
-
|
174
|
-
await elementUpdated(
|
175
|
-
expect(
|
176
|
-
expect(
|
177
|
-
expect(
|
178
|
-
expect(
|
179
|
-
expect(
|
166
|
+
const component = await fixture(html `<glide-core-input label="Label" required></glide-core-input>`);
|
167
|
+
expect(component.validity?.valid).to.be.false;
|
168
|
+
expect(component.validity?.valueMissing).to.be.true;
|
169
|
+
expect(component.checkValidity()).to.be.false;
|
170
|
+
expect(component.reportValidity()).to.be.false;
|
171
|
+
await elementUpdated(component);
|
172
|
+
expect(component.shadowRoot?.querySelector('input')?.getAttribute('aria-invalid')).to.equal('true');
|
173
|
+
component.required = false;
|
174
|
+
await elementUpdated(component);
|
175
|
+
expect(component.validity?.valid).to.be.true;
|
176
|
+
expect(component.validity?.valueMissing).to.be.false;
|
177
|
+
expect(component.checkValidity()).to.be.true;
|
178
|
+
expect(component.reportValidity()).to.be.true;
|
179
|
+
expect(component.shadowRoot?.querySelector('input')?.getAttribute('aria-invalid')).to.equal('false');
|
180
180
|
});
|
package/dist/label.d.ts
CHANGED
@@ -8,8 +8,6 @@ declare global {
|
|
8
8
|
/**
|
9
9
|
* @private
|
10
10
|
*
|
11
|
-
* @description A label with a required control and optional description and tooltip.
|
12
|
-
*
|
13
11
|
* @slot - The label.
|
14
12
|
* @slot control - The control with which the label is associated.
|
15
13
|
* @slot summary - Additional information or context.
|
@@ -28,7 +26,7 @@ export default class GlideCoreLabel extends LitElement {
|
|
28
26
|
split?: 'left' | 'middle';
|
29
27
|
firstUpdated(): void;
|
30
28
|
render(): import("lit").TemplateResult<1>;
|
31
|
-
private
|
29
|
+
private hasDescription;
|
32
30
|
private hasSummarySlot;
|
33
31
|
private hasTooltipSlot;
|
34
32
|
private isLabelTooltip;
|
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.
|
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-and-label":!0,hidden:this.hide,left:"left"===this.split,middle:"middle"===this.split})}" part="tooltips-and-label"><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"><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
@@ -160,21 +160,20 @@ import{css}from"lit";import focusOutline from"./styles/focus-outline.js";import
|
|
160
160
|
|
161
161
|
.description {
|
162
162
|
color: var(--glide-core-text-body-1);
|
163
|
-
display:
|
163
|
+
display: block;
|
164
164
|
font-family: var(--glide-core-body-xs-font-family);
|
165
165
|
font-size: var(--glide-core-body-xs-font-size);
|
166
166
|
font-style: var(--glide-core-body-xs-font-style);
|
167
167
|
font-weight: var(--glide-core-body-xs-font-weight);
|
168
168
|
grid-column: 2;
|
169
169
|
line-height: var(--glide-core-body-xs-line-height);
|
170
|
-
margin-block-start: var(--glide-core-spacing-xxs);
|
171
170
|
|
172
|
-
&.
|
173
|
-
|
171
|
+
&.content {
|
172
|
+
margin-block-start: var(--glide-core-spacing-xxs);
|
174
173
|
}
|
175
174
|
|
176
|
-
&.
|
177
|
-
|
175
|
+
&.error {
|
176
|
+
color: var(--glide-core-status-error);
|
178
177
|
}
|
179
178
|
}
|
180
179
|
`];
|