@crowdstrike/glide-core 0.9.1 → 0.9.2
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.styles.js +2 -4
- package/dist/button-group.button.styles.js +3 -8
- package/dist/button-group.styles.js +2 -2
- package/dist/button.d.ts +1 -0
- package/dist/button.js +1 -1
- package/dist/button.styles.js +2 -4
- package/dist/button.test.events.js +86 -10
- package/dist/checkbox.js +1 -1
- 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/dropdown.d.ts +4 -2
- package/dist/dropdown.js +1 -1
- package/dist/dropdown.option.js +1 -1
- package/dist/dropdown.option.styles.js +1 -0
- package/dist/dropdown.styles.js +47 -26
- 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/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 +0 -4
- 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.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.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.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.styles.js +2 -4
- package/dist/split-container.styles.js +2 -4
- package/dist/styles/focus-outline.d.ts +1 -1
- package/dist/styles/focus-outline.js +7 -1
- package/dist/styles/menu-opening-animation.d.ts +2 -0
- package/dist/styles/menu-opening-animation.js +26 -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/tag.js +1 -1
- 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 +0 -4
- 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.styles.js +1 -1
- 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 +22 -18
- 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/package.json +1 -1
- 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
package/dist/textarea.styles.js
CHANGED
@@ -1,81 +1,77 @@
|
|
1
|
-
import{css,unsafeCSS}from"lit";import visuallyHidden from"./styles/visually-hidden.js";const fieldSizingContent=unsafeCSS("\n field-sizing: content;\n");export default
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
display: flex;
|
9
|
-
}
|
1
|
+
import{css,unsafeCSS}from"lit";import visuallyHidden from"./styles/visually-hidden.js";const fieldSizingContent=unsafeCSS("\n field-sizing: content;\n");export default[css`
|
2
|
+
${visuallyHidden(".character-count .hidden")}
|
3
|
+
`,css`
|
4
|
+
glide-core-private-label::part(tooltips-and-label) {
|
5
|
+
align-items: flex-start;
|
6
|
+
margin-block-start: var(--glide-core-spacing-sm);
|
7
|
+
}
|
10
8
|
|
11
|
-
|
12
|
-
|
13
|
-
|
9
|
+
.textarea-container {
|
10
|
+
display: flex;
|
11
|
+
}
|
14
12
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
border: 1px solid var(--glide-core-border-base-light);
|
19
|
-
border-radius: 0.5rem;
|
20
|
-
color: var(--glide-core-text-body-1);
|
21
|
-
cursor: inherit;
|
22
|
-
display: block;
|
23
|
-
flex-grow: 1;
|
24
|
-
font-family: var(--glide-core-body-xs-font-family);
|
25
|
-
font-size: var(--glide-core-body-sm-font-size);
|
26
|
-
font-weight: var(--glide-core-body-xs-font-weight);
|
27
|
-
max-block-size: 5lh;
|
28
|
-
min-block-size: 3lh;
|
29
|
-
padding: var(--glide-core-spacing-xs) var(--glide-core-spacing-sm);
|
30
|
-
resize: vertical;
|
31
|
-
transition: border-color 200ms ease-in-out;
|
13
|
+
.description {
|
14
|
+
display: block;
|
15
|
+
}
|
32
16
|
|
33
|
-
|
17
|
+
textarea {
|
18
|
+
appearance: none;
|
19
|
+
background-color: var(--glide-core-surface-base-lighter);
|
20
|
+
border: 1px solid var(--glide-core-border-base);
|
21
|
+
border-radius: 0.5rem;
|
22
|
+
color: var(--glide-core-text-body-1);
|
23
|
+
cursor: inherit;
|
24
|
+
display: block;
|
25
|
+
flex-grow: 1;
|
26
|
+
font-family: var(--glide-core-body-xs-font-family);
|
27
|
+
font-size: var(--glide-core-body-sm-font-size);
|
28
|
+
font-weight: var(--glide-core-body-xs-font-weight);
|
29
|
+
max-block-size: 5lh;
|
30
|
+
min-block-size: 3lh;
|
31
|
+
padding: var(--glide-core-spacing-xs) var(--glide-core-spacing-sm);
|
32
|
+
resize: vertical;
|
33
|
+
transition: border-color 200ms ease-in-out;
|
34
34
|
|
35
|
-
|
36
|
-
border-color: var(--glide-core-border-base);
|
37
|
-
}
|
35
|
+
${fieldSizingContent};
|
38
36
|
|
39
|
-
|
40
|
-
|
41
|
-
|
37
|
+
&:focus {
|
38
|
+
outline: none;
|
39
|
+
}
|
42
40
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
41
|
+
&:focus-visible,
|
42
|
+
&:focus-visible[readonly],
|
43
|
+
&:hover {
|
44
|
+
border-color: var(--glide-core-border-focus);
|
45
|
+
}
|
47
46
|
|
48
|
-
|
49
|
-
|
50
|
-
|
47
|
+
&.error {
|
48
|
+
border-color: var(--glide-core-status-error);
|
49
|
+
}
|
51
50
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
51
|
+
&[readonly] {
|
52
|
+
border-color: transparent;
|
53
|
+
outline: none;
|
54
|
+
resize: none;
|
55
|
+
transition: none;
|
56
|
+
}
|
57
57
|
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
58
|
+
&[disabled] {
|
59
|
+
background-color: var(--glide-core-surface-disabled);
|
60
|
+
border: 0.0625rem solid var(--glide-core-border-base-light);
|
61
|
+
color: var(--glide-core-text-tertiary-disabled);
|
62
|
+
}
|
62
63
|
}
|
63
|
-
}
|
64
|
-
|
65
|
-
.meta {
|
66
|
-
column-gap: var(--glide-core-spacing-xs);
|
67
|
-
display: flex;
|
68
|
-
font-size: var(--glide-core-body-xs-font-size);
|
69
|
-
justify-content: space-between;
|
70
|
-
}
|
71
64
|
|
72
|
-
|
73
|
-
|
74
|
-
|
65
|
+
.meta {
|
66
|
+
column-gap: var(--glide-core-spacing-xs);
|
67
|
+
display: flex;
|
68
|
+
font-size: var(--glide-core-body-xs-font-size);
|
69
|
+
justify-content: space-between;
|
75
70
|
}
|
76
71
|
|
77
|
-
.
|
78
|
-
|
72
|
+
.character-count {
|
73
|
+
&.error {
|
74
|
+
font-weight: var(--glide-core-font-weight-bold);
|
75
|
+
}
|
79
76
|
}
|
80
|
-
|
81
|
-
`;
|
77
|
+
`];
|
@@ -7,171 +7,171 @@ it('registers', async () => {
|
|
7
7
|
expect(window.customElements.get('glide-core-textarea')).to.equal(GlideCoreTextarea);
|
8
8
|
});
|
9
9
|
it('is accessible', async () => {
|
10
|
-
const
|
10
|
+
const component = await fixture(html `<glide-core-textarea
|
11
11
|
value="value"
|
12
12
|
label="label"
|
13
13
|
></glide-core-textarea>`);
|
14
|
-
await expect(
|
14
|
+
await expect(component).to.be.accessible();
|
15
15
|
});
|
16
16
|
it('renders a textarea with two rows and value when attribute `value` is set ', async () => {
|
17
|
-
const
|
17
|
+
const component = await fixture(html `<glide-core-textarea
|
18
18
|
value="value"
|
19
19
|
label="label"
|
20
20
|
></glide-core-textarea>`);
|
21
|
-
const textarea =
|
22
|
-
expect(
|
23
|
-
expect(
|
21
|
+
const textarea = component.shadowRoot.querySelector('textarea');
|
22
|
+
expect(component);
|
23
|
+
expect(component).to.have.attribute('rows', '2');
|
24
24
|
expect(textarea).to.exist;
|
25
25
|
expect(textarea).to.have.attribute('rows', '2');
|
26
26
|
});
|
27
27
|
it('renders the `rows` attribute on the textarea when set', async () => {
|
28
|
-
const
|
28
|
+
const component = await fixture(html `<glide-core-textarea
|
29
29
|
value="value"
|
30
30
|
label="label"
|
31
31
|
rows="5"
|
32
32
|
></glide-core-textarea>`);
|
33
|
-
const textarea =
|
33
|
+
const textarea = component.shadowRoot.querySelector('textarea');
|
34
34
|
expect(textarea).to.have.attribute('rows', '5');
|
35
35
|
});
|
36
36
|
it('renders a label when attribute `label` is set', async () => {
|
37
|
-
const
|
37
|
+
const component = await fixture(html `<glide-core-textarea
|
38
38
|
value="value"
|
39
39
|
label="label"
|
40
40
|
></glide-core-textarea>`);
|
41
|
-
const label =
|
41
|
+
const label = component.shadowRoot.querySelector('label');
|
42
42
|
expect(label).to.exist;
|
43
43
|
expect(label?.textContent?.trim()).to.be.equal('label');
|
44
44
|
});
|
45
45
|
it('renders the textarea as readonly when attribute `readonly` is set', async () => {
|
46
|
-
const
|
46
|
+
const component = await fixture(html `<glide-core-textarea
|
47
47
|
value="value"
|
48
48
|
label="label"
|
49
49
|
readonly
|
50
50
|
></glide-core-textarea>`);
|
51
|
-
const textarea =
|
51
|
+
const textarea = component.shadowRoot.querySelector('textarea');
|
52
52
|
expect(textarea).to.have.attribute('readonly');
|
53
53
|
});
|
54
54
|
it('renders the textarea as disabled when attribute `disabled` is set', async () => {
|
55
|
-
const
|
55
|
+
const component = await fixture(html `<glide-core-textarea
|
56
56
|
value="value"
|
57
57
|
label="label"
|
58
58
|
disabled
|
59
59
|
></glide-core-textarea>`);
|
60
|
-
const textarea =
|
60
|
+
const textarea = component.shadowRoot.querySelector('textarea');
|
61
61
|
expect(textarea).to.have.attribute('disabled');
|
62
62
|
});
|
63
63
|
it('renders the textarea with a placeholder when attribute `placeholder` is set', async () => {
|
64
|
-
const
|
64
|
+
const component = await fixture(html `<glide-core-textarea
|
65
65
|
value=""
|
66
66
|
label="label"
|
67
67
|
placeholder="placeholder"
|
68
68
|
></glide-core-textarea>`);
|
69
|
-
const textarea =
|
69
|
+
const textarea = component.shadowRoot.querySelector('textarea');
|
70
70
|
expect(textarea).to.have.attribute('placeholder', 'placeholder');
|
71
71
|
});
|
72
72
|
it('renders `required` on textarea when set', async () => {
|
73
|
-
const
|
73
|
+
const component = await fixture(html `<glide-core-textarea
|
74
74
|
value="value"
|
75
75
|
label="label"
|
76
76
|
required
|
77
77
|
></glide-core-textarea>`);
|
78
|
-
const textarea =
|
78
|
+
const textarea = component.shadowRoot.querySelector('textarea');
|
79
79
|
expect(textarea).to.have.attribute('required');
|
80
80
|
});
|
81
81
|
it('renders a `name` attribute on the textarea when set', async () => {
|
82
|
-
const
|
82
|
+
const component = await fixture(html `<glide-core-textarea
|
83
83
|
value="value"
|
84
84
|
label="label"
|
85
85
|
name="test-name"
|
86
86
|
></glide-core-textarea>`);
|
87
|
-
const textarea =
|
87
|
+
const textarea = component.shadowRoot.querySelector('textarea');
|
88
88
|
expect(textarea).to.have.attribute('name', 'test-name');
|
89
89
|
});
|
90
90
|
it('supports a "tooltip" slot', async () => {
|
91
|
-
const
|
91
|
+
const component = await fixture(html `
|
92
92
|
<glide-core-textarea value="value" label="label" required>
|
93
93
|
<div slot="tooltip">Tooltip</div>
|
94
94
|
</glide-core-textarea>
|
95
95
|
`);
|
96
|
-
const assignedElements =
|
96
|
+
const assignedElements = component.shadowRoot
|
97
97
|
?.querySelector('slot[name="tooltip"]')
|
98
98
|
?.assignedElements();
|
99
99
|
expect(assignedElements?.at(0)?.textContent).to.equal('Tooltip');
|
100
100
|
});
|
101
101
|
it('renders a slot with description', async () => {
|
102
|
-
const
|
102
|
+
const component = await fixture(html `<glide-core-textarea value="value" label="label"
|
103
103
|
><span slot="description" data-test-content
|
104
104
|
>Description</span
|
105
105
|
></glide-core-textarea
|
106
106
|
>`);
|
107
|
-
expect(
|
108
|
-
const contentRendered =
|
107
|
+
expect(component).to.exist;
|
108
|
+
const contentRendered = component.querySelector('[data-test-content]');
|
109
109
|
expect(contentRendered).to.exist;
|
110
110
|
expect(contentRendered?.textContent).to.be.equal('Description');
|
111
111
|
});
|
112
112
|
it('displays visually hidden character count text for screenreaders', async () => {
|
113
|
-
const
|
113
|
+
const component = await fixture(html `<glide-core-textarea
|
114
114
|
label="label"
|
115
115
|
maxlength="10"
|
116
116
|
></glide-core-textarea>`);
|
117
|
-
const maxCharacterCountAnnouncement =
|
117
|
+
const maxCharacterCountAnnouncement = component.shadowRoot?.querySelector('[data-test="character-count-announcement"]');
|
118
118
|
expect(maxCharacterCountAnnouncement?.textContent?.trim()).to.equal('Character count 0 of 10');
|
119
119
|
});
|
120
120
|
it('renders a character count when attribute `maxlength` is set greater than zero', async () => {
|
121
|
-
const
|
121
|
+
const component = await fixture(html `<glide-core-textarea value="value" label="label" maxlength="10"
|
122
122
|
><span slot="description">Description</span></glide-core-textarea
|
123
123
|
>`);
|
124
|
-
const container =
|
124
|
+
const container = component.shadowRoot.querySelector('[data-test="character-count-text"]');
|
125
125
|
expect(container?.textContent?.trim()).to.be.equal('5/10');
|
126
126
|
});
|
127
127
|
it('does not render a character count when attribute `maxlength` is set less than than zero', async () => {
|
128
|
-
const
|
128
|
+
const component = await fixture(html `<glide-core-textarea value="value" label="label" maxlength="0"
|
129
129
|
><span slot="description">Description</span></glide-core-textarea
|
130
130
|
>`);
|
131
|
-
const container =
|
131
|
+
const container = component.shadowRoot?.querySelector('[data-test="character-count-container"]');
|
132
132
|
expect(container).to.be.null;
|
133
133
|
});
|
134
134
|
it('focuses the textarea when the label is clicked', async () => {
|
135
|
-
const
|
135
|
+
const component = await fixture(html `<glide-core-textarea
|
136
136
|
value="value"
|
137
137
|
label="label"
|
138
138
|
></glide-core-textarea>`);
|
139
|
-
const label =
|
139
|
+
const label = component.shadowRoot.querySelector('label');
|
140
140
|
label?.click();
|
141
|
-
expect(
|
142
|
-
await expect(
|
141
|
+
expect(component).to.have.focus;
|
142
|
+
await expect(component.shadowRoot?.activeElement?.tagName.toLocaleLowerCase()).to.be.equal('textarea');
|
143
143
|
});
|
144
144
|
it('has tabbable textarea', async () => {
|
145
|
-
const
|
145
|
+
const component = await fixture(html `<glide-core-textarea
|
146
146
|
value="value"
|
147
147
|
label="label"
|
148
148
|
></glide-core-textarea>`);
|
149
149
|
await sendKeys({ press: 'Tab' });
|
150
|
-
expect(
|
151
|
-
await expect(
|
150
|
+
expect(component).to.have.focus;
|
151
|
+
await expect(component.shadowRoot?.activeElement?.tagName.toLocaleLowerCase()).to.be.equal('textarea');
|
152
152
|
});
|
153
153
|
it('renders text when typed into text area', async () => {
|
154
|
-
const
|
155
|
-
const textarea =
|
156
|
-
|
154
|
+
const component = await fixture(html `<glide-core-textarea value="" label="label"></glide-core-textarea>`);
|
155
|
+
const textarea = component.shadowRoot.querySelector('textarea');
|
156
|
+
component.focus();
|
157
157
|
await sendKeys({ type: 'test text' });
|
158
158
|
expect(textarea?.value).to.equal('test text');
|
159
159
|
});
|
160
160
|
it('returns the content of the textarea when getting the `value` property', async () => {
|
161
|
-
const
|
162
|
-
|
161
|
+
const component = await fixture(html `<glide-core-textarea value="" label="label"></glide-core-textarea>`);
|
162
|
+
component.focus();
|
163
163
|
await sendKeys({ type: 'test text' });
|
164
|
-
expect(
|
164
|
+
expect(component.value).to.equal('test text');
|
165
165
|
});
|
166
166
|
it('focuses the textarea when `focus()` is called', async () => {
|
167
|
-
const
|
168
|
-
|
169
|
-
await expect(
|
167
|
+
const component = await fixture(html `<glide-core-textarea value="" label="label"></glide-core-textarea>`);
|
168
|
+
component.focus();
|
169
|
+
await expect(component.shadowRoot?.activeElement?.tagName.toLocaleLowerCase()).to.be.equal('textarea');
|
170
170
|
});
|
171
171
|
it('blurs the textarea when `blur` is called', async () => {
|
172
|
-
const
|
173
|
-
|
174
|
-
await expect(
|
175
|
-
|
176
|
-
await expect(
|
172
|
+
const component = await fixture(html `<glide-core-textarea value="" label="label"></glide-core-textarea>`);
|
173
|
+
component.focus();
|
174
|
+
await expect(component.shadowRoot?.activeElement?.tagName.toLocaleLowerCase()).to.be.equal('textarea');
|
175
|
+
component.blur();
|
176
|
+
await expect(component.shadowRoot?.activeElement?.tagName.toLocaleLowerCase()).to.not.equal('textarea');
|
177
177
|
});
|
package/dist/toasts.d.ts
CHANGED
@@ -19,6 +19,11 @@ export default class GlideCoreToasts extends LitElement {
|
|
19
19
|
#private;
|
20
20
|
static shadowRootOptions: ShadowRootInit;
|
21
21
|
static styles: import("lit").CSSResult[];
|
22
|
+
/**
|
23
|
+
* @param {number} [toast.duration=5000]
|
24
|
+
* Optional: Number of milliseconds before the Toast auto-hides.
|
25
|
+
* Minimum: `5000`. Default: `5000`. For a Toast that never auto-hides, set to `Infinity`
|
26
|
+
* */
|
22
27
|
add(toast: Toast): import("./toasts.toast.js").default & {
|
23
28
|
variant: "success" | "informational";
|
24
29
|
label: string;
|
package/dist/toasts.styles.js
CHANGED
package/dist/toggle.styles.js
CHANGED
@@ -1,4 +1,6 @@
|
|
1
1
|
import{css}from"lit";import focusOutline from"./styles/focus-outline.js";export default[css`
|
2
|
+
${focusOutline(".toggle-and-input:has(input:focus-visible)")}
|
3
|
+
`,css`
|
2
4
|
/*
|
3
5
|
Most states are handled on the host. But ":checked" is handled on the input
|
4
6
|
because browsers don't support that class on the host. And using attribute
|
@@ -30,7 +32,6 @@ Use the ":checked" pseudo class on the host and throughout when browsers support
|
|
30
32
|
position: relative;
|
31
33
|
|
32
34
|
&:has(input:focus-visible) {
|
33
|
-
${focusOutline};
|
34
35
|
outline-offset: 4px;
|
35
36
|
}
|
36
37
|
|
@@ -68,3 +68,14 @@ it('is unchecked after being clicked then forcibly unchecked via an "input" list
|
|
68
68
|
const input = component.shadowRoot?.querySelector('[data-test="input"]');
|
69
69
|
expect(input?.getAttribute('aria-checked')).to.equal('false');
|
70
70
|
});
|
71
|
+
it('remains unchecked when its "click" event is canceled', async () => {
|
72
|
+
const component = await fixture(html `<glide-core-toggle label="Label"></glide-core-toggle>`);
|
73
|
+
component.addEventListener('click', async (event) => {
|
74
|
+
event.preventDefault();
|
75
|
+
});
|
76
|
+
component.click();
|
77
|
+
expect(component.hasAttribute('checked')).to.be.false;
|
78
|
+
expect(component.checked).to.equal(false);
|
79
|
+
const input = component.shadowRoot?.querySelector('[data-test="input"]');
|
80
|
+
expect(input?.getAttribute('aria-checked')).to.equal('false');
|
81
|
+
});
|
package/dist/tooltip.js
CHANGED
@@ -1 +1 @@
|
|
1
|
-
var __decorate=this&&this.__decorate||function(e,t,o,l){var i,s=arguments.length,a=s<3?t:null===l?l=Object.getOwnPropertyDescriptor(t,o):l;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)a=Reflect.decorate(e,t,o,l);else for(var n=e.length-1;n>=0;n--)(i=e[n])&&(a=(s<3?i(a):s>3?i(t,o,a):i(t,o))||a);return s>3&&a&&Object.defineProperty(t,o,a),a};import{LitElement,html}from"lit";import{arrow,autoUpdate,computePosition,flip,limitShift,offset,shift}from"@floating-ui/dom";import{choose}from"lit/directives/choose.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{ifDefined}from"lit/directives/if-defined.js";import ow,{owSlot}from"./library/ow.js";import styles from"./tooltip.styles.js";let GlideCoreTooltip=class GlideCoreTooltip extends LitElement{constructor(){super(...arguments),this.offset=4,this.effectivePlacement=this.placement??"bottom",this.#e=createRef(),this.#t=createRef(),this.#o=!1,this.#l=!1,this.#i=createRef(),this.#s=createRef(),this.#a=createRef()}static{this.shadowRootOptions={...LitElement.shadowRootOptions,delegatesFocus:!0,mode:"closed"}}static{this.styles=styles}get disabled(){return this.#o}set disabled(e){this.#o=e,this.open&&!e?this.#n():this.#r()}get open(){return this.#l}set open(e){this.#l=e,e&&!this.disabled?this.#n():this.#r()}disconnectedCallback(){super.disconnectedCallback(),clearTimeout(this.#f),clearTimeout(this.#p)}firstUpdated(){owSlot(this.#t.value),owSlot(this.#s.value),ow(this.#a.value,ow.object.instanceOf(HTMLElement)),this.#a.value.popover="manual",this.open&&!this.disabled&&this.#n()}render(){return html`<div class="component" @mouseover="${this.#
|
1
|
+
var __decorate=this&&this.__decorate||function(e,t,o,l){var i,s=arguments.length,a=s<3?t:null===l?l=Object.getOwnPropertyDescriptor(t,o):l;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)a=Reflect.decorate(e,t,o,l);else for(var n=e.length-1;n>=0;n--)(i=e[n])&&(a=(s<3?i(a):s>3?i(t,o,a):i(t,o))||a);return s>3&&a&&Object.defineProperty(t,o,a),a};import{LitElement,html}from"lit";import{arrow,autoUpdate,computePosition,flip,limitShift,offset,shift}from"@floating-ui/dom";import{choose}from"lit/directives/choose.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{ifDefined}from"lit/directives/if-defined.js";import ow,{owSlot}from"./library/ow.js";import styles from"./tooltip.styles.js";let GlideCoreTooltip=class GlideCoreTooltip extends LitElement{constructor(){super(...arguments),this.offset=4,this.effectivePlacement=this.placement??"bottom",this.#e=createRef(),this.#t=createRef(),this.#o=!1,this.#l=!1,this.#i=createRef(),this.#s=createRef(),this.#a=createRef()}static{this.shadowRootOptions={...LitElement.shadowRootOptions,delegatesFocus:!0,mode:"closed"}}static{this.styles=styles}get disabled(){return this.#o}set disabled(e){this.#o=e,this.open&&!e?this.#n():this.#r()}get open(){return this.#l}set open(e){this.#l=e,e&&!this.disabled?this.#n():this.#r()}disconnectedCallback(){super.disconnectedCallback(),clearTimeout(this.#f),clearTimeout(this.#p)}firstUpdated(){owSlot(this.#t.value),owSlot(this.#s.value),ow(this.#a.value,ow.object.instanceOf(HTMLElement)),this.#a.value.popover="manual",this.open&&!this.disabled&&this.#n()}render(){return html`<div class="component" data-test="component" @mouseover="${this.#d}" @mouseout="${this.#h}"><div aria-labelledby="${ifDefined(this.disabled?void 0:"tooltip")}" class="target" data-test="target" slot="target" @focusin="${this.#c}" @focusout="${this.#m}" @keydown="${this.#u}" ${ref(this.#i)}><slot @slotchange="${this.#v}" ${ref(this.#s)} name="target"></slot></div><div class="${classMap({tooltip:!0,[this.effectivePlacement]:!0})}" id="tooltip" data-test="tooltip" data-open-delay="300" data-close-delay="200" role="${ifDefined(this.disabled?void 0:"tooltip")}" ${ref(this.#a)}><div class="${classMap({arrow:!0,[this.effectivePlacement]:!0})}" data-test="arrow" ${ref(this.#e)}>${choose(this.effectivePlacement,[["top",()=>html`<svg viewBox="0 0 10 6" fill="none"><path d="M4.23178 5.07814C4.63157 5.55789 5.36843 5.55789 5.76822 5.07813L10 -7.9486e-08L-2.62268e-07 3.57628e-07L4.23178 5.07814Z" fill="#212121"/></svg>`],["right",()=>html`<svg viewBox="0 0 6 10" fill="none"><path d="M0.921865 4.23178C0.442111 4.63157 0.442112 5.36843 0.921866 5.76822L6 10L6 -2.62268e-07L0.921865 4.23178Z" fill="#212121"/></svg>`],["bottom",()=>html`<svg viewBox="0 0 10 6" fill="none"><path d="M4.23178 0.921865C4.63157 0.442111 5.36843 0.442112 5.76822 0.921866L10 6L-2.62268e-07 6L4.23178 0.921865Z" fill="#212121"/></svg>`],["left",()=>html`<svg viewBox="0 0 6 10" fill="none"><path d="M5.07814 4.23178C5.55789 4.63157 5.55789 5.36843 5.07813 5.76822L-4.37114e-07 10L0 -2.62268e-07L5.07814 4.23178Z" fill="#212121"/></svg>`]])}</div><span aria-label="${ifDefined(this.disabled?void 0:"Tooltip: ")}"></span><slot class="default-slot" @slotchange="${this.#R}" ${ref(this.#t)}></slot></div></div>`}#e;#g;#f;#t;#o;#l;#p;#i;#s;#a;#E(){clearTimeout(this.#f)}#r(){this.#a.value?.hidePopover(),this.#g&&this.#g()}#R(){owSlot(this.#t.value)}#c(){this.open=!0}#m(){this.open=!1}#u(e){"Escape"===e.key&&(this.open=!1)}#h(){this.#w(),clearTimeout(this.#p)}#d(){ow(this.#a.value,ow.object.instanceOf(HTMLElement)),this.#E(),this.#p=setTimeout((()=>{this.open=!0}),Number(this.#a.value.dataset.openDelay))}#v(){owSlot(this.#s.value)}#w(){ow(this.#a.value,ow.object.instanceOf(HTMLElement)),this.#f=setTimeout((()=>{this.open=!1}),Number(this.#a.value.dataset.closeDelay))}#n(){this.disabled||(this.#g?.(),this.#i.value&&this.#a.value&&(this.#g=autoUpdate(this.#i.value,this.#a.value,(()=>{(async()=>{if(this.#i.value&&this.#a.value&&this.#e.value){const{x:e,y:t,placement:o,middlewareData:l}=await computePosition(this.#i.value,this.#a.value,{placement:this.placement,middleware:[offset(this.offset),flip({fallbackStrategy:"initialPlacement"}),shift({limiter:limitShift({offset:20})}),arrow({element:this.#e.value})]});Object.assign(this.#a.value.style,{left:`${e}px`,top:`${t}px`}),Object.assign(this.#e.value.style,{left:l.arrow?.x?`${l.arrow.x}px`:null,top:l.arrow?.y?`${l.arrow.y}px`:null}),this.effectivePlacement=o,this.#a.value.showPopover()}})()}))))}};__decorate([property({reflect:!0,type:Boolean})],GlideCoreTooltip.prototype,"disabled",null),__decorate([property({reflect:!0,type:Number})],GlideCoreTooltip.prototype,"offset",void 0),__decorate([property({reflect:!0,type:Boolean})],GlideCoreTooltip.prototype,"open",null),__decorate([property()],GlideCoreTooltip.prototype,"placement",void 0),__decorate([state()],GlideCoreTooltip.prototype,"effectivePlacement",void 0),GlideCoreTooltip=__decorate([customElement("glide-core-tooltip")],GlideCoreTooltip);export default GlideCoreTooltip;
|
package/dist/tooltip.styles.js
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
import{css}from"lit";import focusOutline from"./styles/focus-outline.js";export default[css`
|
2
|
-
|
2
|
+
${focusOutline(".target:focus-visible")}
|
3
|
+
`,css`
|
4
|
+
@keyframes opacity-and-scale {
|
3
5
|
from {
|
4
6
|
opacity: 0;
|
5
7
|
transform: scale(0.95);
|
@@ -11,6 +13,12 @@ import{css}from"lit";import focusOutline from"./styles/focus-outline.js";export
|
|
11
13
|
}
|
12
14
|
}
|
13
15
|
|
16
|
+
@media (prefers-reduced-motion: reduce) {
|
17
|
+
.tooltip:popover-open {
|
18
|
+
animation: none !important;
|
19
|
+
}
|
20
|
+
}
|
21
|
+
|
14
22
|
:host {
|
15
23
|
display: inline-block;
|
16
24
|
}
|
@@ -28,9 +36,9 @@ import{css}from"lit";import focusOutline from"./styles/focus-outline.js";export
|
|
28
36
|
background-color: transparent;
|
29
37
|
border-width: 0;
|
30
38
|
|
31
|
-
/*
|
32
|
-
Additional whitespace from line height and the tooltip won't be vertically
|
33
|
-
centered against its target.
|
39
|
+
/*
|
40
|
+
Additional whitespace from line height and the tooltip won't be vertically
|
41
|
+
centered against its target.
|
34
42
|
*/
|
35
43
|
display: flex;
|
36
44
|
|
@@ -43,10 +51,6 @@ import{css}from"lit";import focusOutline from"./styles/focus-outline.js";export
|
|
43
51
|
outline: none;
|
44
52
|
}
|
45
53
|
|
46
|
-
&:focus-visible {
|
47
|
-
${focusOutline};
|
48
|
-
}
|
49
|
-
|
50
54
|
::slotted svg {
|
51
55
|
display: block;
|
52
56
|
}
|
@@ -68,19 +72,19 @@ import{css}from"lit";import focusOutline from"./styles/focus-outline.js";export
|
|
68
72
|
}
|
69
73
|
|
70
74
|
&:popover-open {
|
71
|
-
animation:
|
75
|
+
animation: opacity-and-scale 250ms cubic-bezier(0.25, 0, 0.3, 1);
|
72
76
|
display: flex;
|
73
77
|
|
74
|
-
/*
|
78
|
+
/*
|
75
79
|
Elements with a "popover" attribute don't allow overflow. So the arrow can't
|
76
|
-
be positioned with "position: absolute". Relative positioning is used instead.
|
77
|
-
Flex is used to get the arrow on the correct side of the tooltip. Floating UI
|
78
|
-
handles the rest.
|
79
|
-
|
80
|
-
A simple "transform" could replace Floating UI for the arrow if not for a Chrome
|
81
|
-
bug with "popover" when "scale()" is animated on the popover or a container within
|
82
|
-
it. With "transform" on the arrow, the arrow is initially offset by a couple pixels
|
83
|
-
before landing in the correct position when the animation finishes. It only happens
|
80
|
+
be positioned with "position: absolute". Relative positioning is used instead.
|
81
|
+
Flex is used to get the arrow on the correct side of the tooltip. Floating UI
|
82
|
+
handles the rest.
|
83
|
+
|
84
|
+
A simple "transform" could replace Floating UI for the arrow if not for a Chrome
|
85
|
+
bug with "popover" when "scale()" is animated on the popover or a container within
|
86
|
+
it. With "transform" on the arrow, the arrow is initially offset by a couple pixels
|
87
|
+
before landing in the correct position when the animation finishes. It only happens
|
84
88
|
when the tooltip is left or right of its target.
|
85
89
|
*/
|
86
90
|
|
@@ -117,7 +117,7 @@ it('is visible on "mouseover"', async () => {
|
|
117
117
|
assert(tooltip);
|
118
118
|
tooltip.dataset.openDelay = '0';
|
119
119
|
component.shadowRoot
|
120
|
-
?.querySelector('
|
120
|
+
?.querySelector('[data-test="component"')
|
121
121
|
?.dispatchEvent(new MouseEvent('mouseover'));
|
122
122
|
// Wait for Floating UI and the open delay.
|
123
123
|
await aTimeout(0);
|
@@ -132,7 +132,7 @@ it('is hidden on "mouseover" when disabled', async () => {
|
|
132
132
|
assert(tooltip);
|
133
133
|
tooltip.dataset.openDelay = '0';
|
134
134
|
component.shadowRoot
|
135
|
-
?.querySelector('
|
135
|
+
?.querySelector('[data-test="component"')
|
136
136
|
?.dispatchEvent(new MouseEvent('mouseover'));
|
137
137
|
// Wait for Floating UI.
|
138
138
|
await aTimeout(0);
|
@@ -147,13 +147,13 @@ it('is hidden on "mouseout"', async () => {
|
|
147
147
|
assert(tooltip);
|
148
148
|
tooltip.dataset.openDelay = '0';
|
149
149
|
component.shadowRoot
|
150
|
-
?.querySelector('
|
150
|
+
?.querySelector('[data-test="component"')
|
151
151
|
?.dispatchEvent(new MouseEvent('mouseover'));
|
152
152
|
// Wait for Floating UI and the open delay.
|
153
153
|
await aTimeout(0);
|
154
154
|
tooltip.dataset.closeDelay = '0';
|
155
155
|
component.shadowRoot
|
156
|
-
?.querySelector('
|
156
|
+
?.querySelector('[data-test="component"')
|
157
157
|
?.dispatchEvent(new MouseEvent('mouseout'));
|
158
158
|
// Wait for the close delay.
|
159
159
|
await aTimeout(0);
|
@@ -169,11 +169,11 @@ it('remains hidden if "mouseout" fires before the "mouseover" delay', async () =
|
|
169
169
|
tooltip.dataset.openDelay = '1';
|
170
170
|
tooltip.dataset.closeDelay = '0';
|
171
171
|
component.shadowRoot
|
172
|
-
?.querySelector('
|
172
|
+
?.querySelector('[data-test="component"')
|
173
173
|
?.dispatchEvent(new MouseEvent('mouseover'));
|
174
174
|
expect(tooltip?.checkVisibility()).to.be.false;
|
175
175
|
component.shadowRoot
|
176
|
-
?.querySelector('
|
176
|
+
?.querySelector('[data-test="component"')
|
177
177
|
?.dispatchEvent(new MouseEvent('mouseout'));
|
178
178
|
await aTimeout(1);
|
179
179
|
expect(tooltip.checkVisibility()).to.be.false;
|
package/dist/translations/en.js
CHANGED
@@ -1 +1 @@
|
|
1
|
-
const translation={$code:"en",$name:"English",$dir:"ltr",close:"Close",dismiss:"Dismiss",open:"Open",selectAll:"Select all",moreInformation:"More information",nextTab:"Next tab",
|
1
|
+
const translation={$code:"en",$name:"English",$dir:"ltr",close:"Close",dismiss:"Dismiss",open:"Open",selectAll:"Select all",moreInformation:"More information",notifications:"Notifications",nextTab:"Next tab",previousTab:"Previous tab",announcedCharacterCount:(e,o)=>`Character count ${e} of ${o}`,displayedCharacterCount:(e,o)=>`${e}/${o}`,clearEntry:e=>`Clear ${e} entry`,removeTag:e=>`Remove tag: ${e}`,actionsFor:e=>`Actions for ${e}`};export default translation;
|
@@ -1,3 +1,5 @@
|
|
1
1
|
import type { Translation } from '../library/localize.js';
|
2
|
-
declare const
|
2
|
+
export declare const PENDING_STRINGS: readonly [];
|
3
|
+
type PendingTranslation = (typeof PENDING_STRINGS)[number];
|
4
|
+
declare const translation: Omit<Translation, PendingTranslation>;
|
3
5
|
export default translation;
|
package/dist/translations/fr.js
CHANGED
@@ -1 +1 @@
|
|
1
|
-
const translation={$code:"fr",$name:"French",$dir:"ltr",close:"Fermer",dismiss:"Congédier",open:"Ouvrir",selectAll:"Tout sélectionner",moreInformation:"Plus d’informations",notifications:"Notifications",nextTab:"
|
1
|
+
export const PENDING_STRINGS=[];const translation={$code:"fr",$name:"French",$dir:"ltr",close:"Fermer",dismiss:"Congédier",open:"Ouvrir",selectAll:"Tout sélectionner",moreInformation:"Plus d’informations",notifications:"Notifications",nextTab:"Onglet suivant",previousTab:"Onglet précédent",announcedCharacterCount:(e,r)=>`Nombre de caractères ${e} de ${r}`,displayedCharacterCount:(e,r)=>`${e}/${r}`,clearEntry:e=>`Effacer l'entrée ${e}`,removeTag:e=>`Supprimer la balise : ${e}`,actionsFor:e=>`Actions pour ${e}`};export default translation;
|
@@ -1,3 +1,5 @@
|
|
1
1
|
import type { Translation } from '../library/localize.js';
|
2
|
-
declare const
|
2
|
+
export declare const PENDING_STRINGS: readonly [];
|
3
|
+
type PendingTranslation = (typeof PENDING_STRINGS)[number];
|
4
|
+
declare const translation: Omit<Translation, PendingTranslation>;
|
3
5
|
export default translation;
|
package/dist/translations/ja.js
CHANGED
@@ -1 +1 @@
|
|
1
|
-
const translation={$code:"ja",$name:"Japanese",$dir:"ltr",close:"閉じる",dismiss:"無視",open:"オープン",selectAll:"すべて選択",moreInformation:"詳細情報",notifications:"通知",nextTab:"
|
1
|
+
export const PENDING_STRINGS=[];const translation={$code:"ja",$name:"Japanese",$dir:"ltr",close:"閉じる",dismiss:"無視",open:"オープン",selectAll:"すべて選択",moreInformation:"詳細情報",notifications:"通知",nextTab:"Onglet suivant",previousTab:"Onglet précédent",announcedCharacterCount:(n,t)=>`${t} 文字数の${n}`,displayedCharacterCount:(n,t)=>`${n}/${t}`,clearEntry:n=>`${n}エントリのクリア`,removeTag:n=>`タグを削除: ${n}`,actionsFor:n=>`${n}のアクション`};export default translation;
|