@crowdstrike/glide-core 0.8.0 → 0.9.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.
Files changed (152) hide show
  1. package/dist/button-group.button.d.ts +14 -15
  2. package/dist/button-group.button.js +1 -1
  3. package/dist/button-group.button.styles.js +75 -52
  4. package/dist/button-group.button.test.basics.d.ts +1 -1
  5. package/dist/button-group.button.test.basics.js +83 -147
  6. package/dist/button-group.button.test.events.js +8 -67
  7. package/dist/button-group.button.test.focus.js +13 -0
  8. package/dist/button-group.button.test.interactions.d.ts +1 -0
  9. package/dist/button-group.button.test.interactions.js +42 -0
  10. package/dist/button-group.d.ts +7 -10
  11. package/dist/button-group.js +1 -1
  12. package/dist/button-group.stories.d.ts +1 -5
  13. package/dist/button-group.styles.js +18 -6
  14. package/dist/button-group.test.basics.js +113 -234
  15. package/dist/button-group.test.events.js +210 -263
  16. package/dist/button-group.test.focus.d.ts +1 -0
  17. package/dist/button-group.test.focus.js +39 -0
  18. package/dist/button-group.test.interactions.d.ts +1 -0
  19. package/dist/button-group.test.interactions.js +91 -0
  20. package/dist/button.test.basics.js +1 -1
  21. package/dist/checkbox-group.js +1 -1
  22. package/dist/checkbox-group.styles.js +1 -1
  23. package/dist/checkbox-group.test.basics.js +1 -1
  24. package/dist/checkbox-group.test.events.js +4 -4
  25. package/dist/checkbox-group.test.focus.js +4 -3
  26. package/dist/checkbox.d.ts +7 -1
  27. package/dist/checkbox.js +1 -1
  28. package/dist/checkbox.styles.js +10 -0
  29. package/dist/checkbox.test.events.js +4 -4
  30. package/dist/checkbox.test.focus.js +2 -2
  31. package/dist/{checkbox.test.states.js → checkbox.test.interactions.js} +24 -1
  32. package/dist/drawer.js +1 -1
  33. package/dist/dropdown.d.ts +6 -4
  34. package/dist/dropdown.js +1 -1
  35. package/dist/dropdown.option.d.ts +6 -2
  36. package/dist/dropdown.option.js +1 -1
  37. package/dist/dropdown.option.styles.js +13 -0
  38. package/dist/dropdown.option.test.basics.js +6 -3
  39. package/dist/dropdown.option.test.events.js +1 -1
  40. package/dist/dropdown.option.test.focus.js +1 -1
  41. package/dist/dropdown.option.test.interactions.multiple.js +1 -54
  42. package/dist/dropdown.option.test.interactions.single.js +51 -9
  43. package/dist/dropdown.styles.js +20 -19
  44. package/dist/dropdown.test.basics.js +143 -2
  45. package/dist/dropdown.test.basics.multiple.js +5 -2
  46. package/dist/dropdown.test.events.filterable.js +74 -0
  47. package/dist/dropdown.test.events.js +49 -160
  48. package/dist/dropdown.test.events.multiple.js +265 -8
  49. package/dist/dropdown.test.events.single.js +199 -2
  50. package/dist/dropdown.test.focus.filterable.js +9 -5
  51. package/dist/dropdown.test.focus.js +1 -1
  52. package/dist/dropdown.test.focus.multiple.js +1 -1
  53. package/dist/dropdown.test.focus.single.js +1 -1
  54. package/dist/dropdown.test.interactions.filterable.js +68 -11
  55. package/dist/dropdown.test.interactions.js +94 -5
  56. package/dist/dropdown.test.interactions.multiple.js +202 -5
  57. package/dist/dropdown.test.interactions.single.js +68 -6
  58. package/dist/form-controls-layout.test.basics.js +1 -1
  59. package/dist/icon-button.test.basics.js +1 -1
  60. package/dist/icons/checked.d.ts +1 -1
  61. package/dist/icons/checked.js +1 -1
  62. package/dist/icons/magnifying-glass.js +1 -1
  63. package/dist/input.d.ts +0 -6
  64. package/dist/input.js +1 -1
  65. package/dist/input.styles.js +7 -2
  66. package/dist/input.test.basics.js +19 -5
  67. package/dist/input.test.events.js +4 -4
  68. package/dist/input.test.focus.js +4 -4
  69. package/dist/input.test.translations.d.ts +1 -0
  70. package/dist/input.test.translations.js +38 -0
  71. package/dist/input.test.validity.js +133 -4
  72. package/dist/label.d.ts +1 -1
  73. package/dist/label.js +1 -1
  74. package/dist/label.styles.js +22 -13
  75. package/dist/label.test.basics.js +26 -24
  76. package/dist/library/expect-argument-error.js +1 -1
  77. package/dist/library/localize.d.ts +3 -1
  78. package/dist/menu.d.ts +3 -5
  79. package/dist/menu.js +1 -1
  80. package/dist/menu.options.test.basics.js +2 -2
  81. package/dist/menu.styles.js +1 -15
  82. package/dist/menu.test.basics.d.ts +1 -2
  83. package/dist/menu.test.basics.js +22 -6
  84. package/dist/menu.test.focus.d.ts +1 -0
  85. package/dist/menu.test.focus.js +13 -6
  86. package/dist/menu.test.interactions.js +212 -56
  87. package/dist/modal.icon-button.test.basics.js +1 -1
  88. package/dist/modal.js +1 -1
  89. package/dist/modal.styles.js +18 -13
  90. package/dist/modal.tertiary-icon.d.ts +0 -1
  91. package/dist/modal.tertiary-icon.js +1 -1
  92. package/dist/modal.tertiary-icon.test.basics.js +1 -1
  93. package/dist/modal.test.basics.js +1 -1
  94. package/dist/modal.test.events.js +10 -10
  95. package/dist/radio-group.js +1 -1
  96. package/dist/radio-group.styles.js +1 -1
  97. package/dist/radio-group.test.focus.js +3 -3
  98. package/dist/radio.d.ts +1 -0
  99. package/dist/radio.js +1 -1
  100. package/dist/radio.styles.js +33 -0
  101. package/dist/split-container.test.basics.js +4 -0
  102. package/dist/split-link.test.interactions.js +1 -1
  103. package/dist/styles/variables.css +1 -1
  104. package/dist/tab.d.ts +1 -1
  105. package/dist/tab.group.js +1 -1
  106. package/dist/tab.group.test.basics.js +1 -1
  107. package/dist/tab.group.test.interactions.js +198 -2
  108. package/dist/tab.js +1 -1
  109. package/dist/tab.panel.d.ts +1 -0
  110. package/dist/tab.panel.js +1 -1
  111. package/dist/tab.panel.styles.js +11 -1
  112. package/dist/tag.test.basics.js +2 -2
  113. package/dist/textarea.d.ts +0 -1
  114. package/dist/textarea.js +2 -2
  115. package/dist/textarea.stories.d.ts +3 -4
  116. package/dist/textarea.styles.js +14 -3
  117. package/dist/textarea.test.basics.js +80 -44
  118. package/dist/textarea.test.events.js +56 -41
  119. package/dist/textarea.test.translations.d.ts +1 -0
  120. package/dist/textarea.test.translations.js +34 -0
  121. package/dist/textarea.test.validity.js +104 -20
  122. package/dist/toasts.js +1 -1
  123. package/dist/toasts.styles.js +8 -1
  124. package/dist/toasts.test.basics.js +20 -0
  125. package/dist/toggle.js +1 -1
  126. package/dist/toggle.test.focus.js +1 -1
  127. package/dist/toggle.test.interactions.d.ts +1 -0
  128. package/dist/tooltip.d.ts +7 -5
  129. package/dist/tooltip.js +1 -1
  130. package/dist/tooltip.styles.js +90 -25
  131. package/dist/tooltip.test.basics.js +38 -3
  132. package/dist/tooltip.test.interactions.js +136 -34
  133. package/dist/translations/en.js +1 -1
  134. package/dist/translations/fr.js +1 -1
  135. package/dist/translations/ja.js +1 -1
  136. package/dist/tree.d.ts +0 -1
  137. package/dist/tree.item.d.ts +1 -2
  138. package/dist/tree.item.js +1 -1
  139. package/dist/tree.item.menu.d.ts +0 -1
  140. package/dist/tree.item.menu.js +1 -1
  141. package/dist/tree.js +1 -1
  142. package/dist/tree.test.basics.js +1 -1
  143. package/package.json +2 -4
  144. package/dist/drawer.test.floating-components.d.ts +0 -1
  145. package/dist/drawer.test.floating-components.js +0 -52
  146. package/dist/library/set-containing-block.d.ts +0 -15
  147. package/dist/library/set-containing-block.js +0 -1
  148. package/dist/modal.test.floating-components.js +0 -63
  149. /package/dist/{checkbox.test.states.d.ts → button-group.button.test.focus.d.ts} +0 -0
  150. /package/dist/{modal.test.floating-components.d.ts → checkbox.test.interactions.d.ts} +0 -0
  151. /package/dist/{toggle.test.states.d.ts → dropdown.test.events.filterable.d.ts} +0 -0
  152. /package/dist/{toggle.test.states.js → toggle.test.interactions.js} +0 -0
@@ -1,11 +1,10 @@
1
1
  /* eslint-disable @typescript-eslint/no-unused-expressions */
2
2
  import './textarea.js';
3
3
  import * as sinon from 'sinon';
4
- import { aTimeout, expect, fixture, oneEvent } from '@open-wc/testing';
4
+ import { aTimeout, expect, fixture, html, oneEvent } from '@open-wc/testing';
5
5
  import { sendKeys } from '@web/test-runner-commands';
6
6
  it('dispatches a `input` event when typed in', async () => {
7
- const template = `<glide-core-textarea label="label"></glide-core-textarea>`;
8
- const textarea = await fixture(template);
7
+ const textarea = await fixture(html `<glide-core-textarea label="label"></glide-core-textarea>`);
9
8
  setTimeout(async () => {
10
9
  textarea.focus();
11
10
  await sendKeys({ type: 'testing' });
@@ -16,8 +15,7 @@ it('dispatches a `input` event when typed in', async () => {
16
15
  expect(event.bubbles).to.be.true;
17
16
  });
18
17
  it('dispatches an `change` event when typed in', async () => {
19
- const template = `<glide-core-textarea label="label"></glide-core-textarea>`;
20
- const textarea = await fixture(template);
18
+ const textarea = await fixture(html `<glide-core-textarea label="label"></glide-core-textarea>`);
21
19
  setTimeout(async () => {
22
20
  textarea.focus();
23
21
  await sendKeys({ type: 'testing' });
@@ -29,8 +27,7 @@ it('dispatches an `change` event when typed in', async () => {
29
27
  });
30
28
  it('dispatches an `invalid` event on submit when required and no value', async () => {
31
29
  const form = document.createElement('form');
32
- const template = `<glide-core-textarea label="label" required></glide-core-textarea>`;
33
- const textarea = await fixture(template, {
30
+ const textarea = await fixture(html `<glide-core-textarea label="label" required></glide-core-textarea>`, {
34
31
  parentNode: form,
35
32
  });
36
33
  setTimeout(() => form.requestSubmit());
@@ -39,8 +36,7 @@ it('dispatches an `invalid` event on submit when required and no value', async (
39
36
  });
40
37
  it('dispatches an `invalid` event after `checkValidity` is called when required and no value', async () => {
41
38
  const form = document.createElement('form');
42
- const template = `<glide-core-textarea label="label" required></glide-core-textarea>`;
43
- const textarea = await fixture(template, {
39
+ const textarea = await fixture(html `<glide-core-textarea label="label" required></glide-core-textarea>`, {
44
40
  parentNode: form,
45
41
  });
46
42
  setTimeout(() => textarea.checkValidity());
@@ -49,8 +45,7 @@ it('dispatches an `invalid` event after `checkValidity` is called when required
49
45
  });
50
46
  it('dispatches an `invalid` event after `reportValidity` is called when required and no value', async () => {
51
47
  const form = document.createElement('form');
52
- const template = `<glide-core-textarea label="label" required></glide-core-textarea>`;
53
- const textarea = await fixture(template, {
48
+ const textarea = await fixture(html `<glide-core-textarea label="label" required></glide-core-textarea>`, {
54
49
  parentNode: form,
55
50
  });
56
51
  setTimeout(() => textarea.reportValidity());
@@ -59,56 +54,62 @@ it('dispatches an `invalid` event after `reportValidity` is called when required
59
54
  });
60
55
  it('does not dispatch an `invalid` event after `checkValidity` is called when not required', async () => {
61
56
  const form = document.createElement('form');
62
- const template = `<glide-core-textarea label="label"></glide-core-textarea>`;
63
- const textarea = await fixture(template, {
57
+ const textarea = await fixture(html `<glide-core-textarea label="label"></glide-core-textarea>`, {
64
58
  parentNode: form,
65
59
  });
66
60
  const spy = sinon.spy();
67
61
  textarea.addEventListener('invalid', spy);
68
62
  textarea.checkValidity();
69
63
  await aTimeout(0);
70
- expect(spy.notCalled).to.be.true;
64
+ expect(spy.callCount).to.equal(0);
71
65
  });
72
66
  it('does not dispatch an `invalid` event after `checkValidity` is called when required, no value, and disabled', async () => {
73
67
  const form = document.createElement('form');
74
- const template = `<glide-core-textarea label="label" required disabled></glide-core-textarea>`;
75
- const textarea = await fixture(template, {
68
+ const textarea = await fixture(html `<glide-core-textarea
69
+ label="label"
70
+ required
71
+ disabled
72
+ ></glide-core-textarea>`, {
76
73
  parentNode: form,
77
74
  });
78
75
  const spy = sinon.spy();
79
76
  textarea.addEventListener('invalid', spy);
80
77
  textarea.checkValidity();
81
78
  await aTimeout(0);
82
- expect(spy.notCalled).to.be.true;
79
+ expect(spy.callCount).to.equal(0);
83
80
  });
84
81
  it('does not dispatch an `invalid` event when `reportValidity` is called when not required,', async () => {
85
82
  const form = document.createElement('form');
86
- const template = `<glide-core-textarea label="label"></glide-core-textarea>`;
87
- const textarea = await fixture(template, {
83
+ const textarea = await fixture(html `<glide-core-textarea label="label"></glide-core-textarea>`, {
88
84
  parentNode: form,
89
85
  });
90
86
  const spy = sinon.spy();
91
87
  textarea.addEventListener('invalid', spy);
92
88
  textarea.reportValidity();
93
89
  await aTimeout(0);
94
- expect(spy.notCalled).to.be.true;
90
+ expect(spy.callCount).to.equal(0);
95
91
  });
96
92
  it('does not dispatch an `invalid` event when `reportValidity` is called when required, no value, and disabled', async () => {
97
93
  const form = document.createElement('form');
98
- const template = `<glide-core-textarea label="label" required disabled></glide-core-textarea>`;
99
- const textarea = await fixture(template, {
94
+ const textarea = await fixture(html `<glide-core-textarea
95
+ label="label"
96
+ required
97
+ disabled
98
+ ></glide-core-textarea>`, {
100
99
  parentNode: form,
101
100
  });
102
101
  const spy = sinon.spy();
103
102
  textarea.addEventListener('invalid', spy);
104
103
  textarea.reportValidity();
105
104
  await aTimeout(0);
106
- expect(spy.notCalled).to.be.true;
105
+ expect(spy.callCount).to.equal(0);
107
106
  });
108
107
  it('dispatches an `invalid` event after `requestSubmit` is called when `maxlength` exceeded', async () => {
109
108
  const form = document.createElement('form');
110
- const template = `<glide-core-textarea label="label" maxlength="3"></glide-core-textarea>`;
111
- const textarea = await fixture(template, {
109
+ const textarea = await fixture(html `<glide-core-textarea
110
+ label="label"
111
+ maxlength="3"
112
+ ></glide-core-textarea>`, {
112
113
  parentNode: form,
113
114
  });
114
115
  setTimeout(async () => {
@@ -121,8 +122,10 @@ it('dispatches an `invalid` event after `requestSubmit` is called when `maxlengt
121
122
  });
122
123
  it('dispatches an `invalid` event after `checkValidity` is called when `maxlength` exceeded', async () => {
123
124
  const form = document.createElement('form');
124
- const template = `<glide-core-textarea label="label" maxlength="3"></glide-core-textarea>`;
125
- const textarea = await fixture(template, {
125
+ const textarea = await fixture(html `<glide-core-textarea
126
+ label="label"
127
+ maxlength="3"
128
+ ></glide-core-textarea>`, {
126
129
  parentNode: form,
127
130
  });
128
131
  setTimeout(async () => {
@@ -135,8 +138,10 @@ it('dispatches an `invalid` event after `checkValidity` is called when `maxlengt
135
138
  });
136
139
  it('dispatches an `invalid` event after `reportValidity` is called when `maxlength` exceeded', async () => {
137
140
  const form = document.createElement('form');
138
- const template = `<glide-core-textarea label="label" maxlength="3"></glide-core-textarea>`;
139
- const textarea = await fixture(template, {
141
+ const textarea = await fixture(html `<glide-core-textarea
142
+ label="label"
143
+ maxlength="3"
144
+ ></glide-core-textarea>`, {
140
145
  parentNode: form,
141
146
  });
142
147
  setTimeout(async () => {
@@ -149,8 +154,10 @@ it('dispatches an `invalid` event after `reportValidity` is called when `maxleng
149
154
  });
150
155
  it('does not dispatch an `invalid` event after `checkValidity` is called when `maxlength` not exceeded', async () => {
151
156
  const form = document.createElement('form');
152
- const template = `<glide-core-textarea label="label" maxlength="3"></glide-core-textarea>`;
153
- const textarea = await fixture(template, {
157
+ const textarea = await fixture(html `<glide-core-textarea
158
+ label="label"
159
+ maxlength="3"
160
+ ></glide-core-textarea>`, {
154
161
  parentNode: form,
155
162
  });
156
163
  const spy = sinon.spy();
@@ -159,12 +166,15 @@ it('does not dispatch an `invalid` event after `checkValidity` is called when `m
159
166
  await sendKeys({ type: 'ab' });
160
167
  textarea.checkValidity();
161
168
  await aTimeout(0);
162
- expect(spy.notCalled).to.be.true;
169
+ expect(spy.callCount).to.equal(0);
163
170
  });
164
171
  it('does not dispatch an `invalid` event after `checkValidity` is called when `maxlength` exceeded and disabled', async () => {
165
172
  const form = document.createElement('form');
166
- const template = `<glide-core-textarea label="label" maxlength="3" disabled></glide-core-textarea>`;
167
- const textarea = await fixture(template, {
173
+ const textarea = await fixture(html `<glide-core-textarea
174
+ label="label"
175
+ maxlength="3"
176
+ disabled
177
+ ></glide-core-textarea>`, {
168
178
  parentNode: form,
169
179
  });
170
180
  const spy = sinon.spy();
@@ -173,12 +183,14 @@ it('does not dispatch an `invalid` event after `checkValidity` is called when `m
173
183
  await sendKeys({ type: 'test' });
174
184
  textarea.checkValidity();
175
185
  await aTimeout(0);
176
- expect(spy.notCalled).to.be.true;
186
+ expect(spy.callCount).to.equal(0);
177
187
  });
178
188
  it('does not dispatch an `invalid` event when `reportValidity` is called and `maxlength` is not exceeded,', async () => {
179
189
  const form = document.createElement('form');
180
- const template = `<glide-core-textarea label="label" maxlength="3"></glide-core-textarea>`;
181
- const textarea = await fixture(template, {
190
+ const textarea = await fixture(html `<glide-core-textarea
191
+ label="label"
192
+ maxlength="3"
193
+ ></glide-core-textarea>`, {
182
194
  parentNode: form,
183
195
  });
184
196
  const spy = sinon.spy();
@@ -187,12 +199,15 @@ it('does not dispatch an `invalid` event when `reportValidity` is called and `ma
187
199
  await sendKeys({ type: 'ab' });
188
200
  textarea.reportValidity();
189
201
  await aTimeout(0);
190
- expect(spy.notCalled).to.be.true;
202
+ expect(spy.callCount).to.equal(0);
191
203
  });
192
204
  it('does not dispatch an `invalid` event when `reportValidity` is called `maxlength` exceeded and disabled,', async () => {
193
205
  const form = document.createElement('form');
194
- const template = `<glide-core-textarea label="label" maxlength="3" disabled></glide-core-textarea>`;
195
- const textarea = await fixture(template, {
206
+ const textarea = await fixture(html `<glide-core-textarea
207
+ label="label"
208
+ maxlength="3"
209
+ disabled
210
+ ></glide-core-textarea>`, {
196
211
  parentNode: form,
197
212
  });
198
213
  const spy = sinon.spy();
@@ -201,5 +216,5 @@ it('does not dispatch an `invalid` event when `reportValidity` is called `maxlen
201
216
  await sendKeys({ type: 'test' });
202
217
  textarea.reportValidity();
203
218
  await aTimeout(0);
204
- expect(spy.notCalled).to.be.true;
219
+ expect(spy.callCount).to.equal(0);
205
220
  });
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,34 @@
1
+ /* eslint-disable @typescript-eslint/no-unused-expressions */
2
+ import { elementUpdated, expect, fixture, html } from '@open-wc/testing';
3
+ import GlideCoreTextarea from './textarea.js';
4
+ GlideCoreTextarea.shadowRootOptions.mode = 'open';
5
+ it('renders dynamic strings in Japanese', async () => {
6
+ const element = await fixture(html `
7
+ <glide-core-textarea
8
+ label="Test"
9
+ value="lorem"
10
+ maxlength="40"
11
+ ></glide-core-textarea>
12
+ `);
13
+ document.documentElement.setAttribute('lang', 'ja');
14
+ await elementUpdated(element);
15
+ const maxCharacterCountText = element.shadowRoot?.querySelector('[data-test="character-count-text"]');
16
+ expect(maxCharacterCountText?.textContent?.trim()).to.equal('5/40');
17
+ const maxCharacterCountAnnouncement = element.shadowRoot?.querySelector('[data-test="character-count-announcement"]');
18
+ expect(maxCharacterCountAnnouncement?.textContent?.trim()).to.equal('Character count 5 of 40');
19
+ });
20
+ it('renders dynamic strings in French', async () => {
21
+ const element = await fixture(html `
22
+ <glide-core-textarea
23
+ label="Test"
24
+ value="lorem"
25
+ maxlength="40"
26
+ ></glide-core-textarea>
27
+ `);
28
+ document.documentElement.setAttribute('lang', 'fr');
29
+ await elementUpdated(element);
30
+ const maxCharacterCountText = element.shadowRoot?.querySelector('[data-test="character-count-text"]');
31
+ expect(maxCharacterCountText?.textContent?.trim()).to.equal('5/40');
32
+ const maxCharacterCountAnnouncement = element.shadowRoot?.querySelector('[data-test="character-count-announcement"]');
33
+ expect(maxCharacterCountAnnouncement?.textContent?.trim()).to.equal('Character count 5 of 40');
34
+ });
@@ -1,20 +1,20 @@
1
1
  /* eslint-disable @typescript-eslint/no-unused-expressions */
2
- import { expect, fixture, html } from '@open-wc/testing';
2
+ import { elementUpdated, expect, fixture, html } from '@open-wc/testing';
3
3
  import { sendKeys } from '@web/test-runner-commands';
4
4
  import GlideCoreTextarea from './textarea.js';
5
5
  GlideCoreTextarea.shadowRootOptions.mode = 'open';
6
6
  it('is valid by default', async () => {
7
- const template = '<glide-core-textarea></glide-core-textarea>';
8
- const textarea = await fixture(template);
7
+ const textarea = await fixture(html `<glide-core-textarea></glide-core-textarea>`);
9
8
  expect(textarea.validity?.valid).to.be.true;
10
9
  expect(textarea.validity?.valueMissing).to.be.false;
11
10
  expect(textarea.validity?.tooLong).to.be.false;
12
11
  expect(textarea.checkValidity()).to.be.true;
13
12
  expect(textarea.reportValidity()).to.be.true;
13
+ await elementUpdated(textarea);
14
+ expect(textarea.shadowRoot?.querySelector('textarea')).to.have.attribute('aria-invalid', 'false');
14
15
  });
15
16
  it('is valid after being filled in and required', async () => {
16
- const template = '<glide-core-textarea required></glide-core-textarea>';
17
- const textarea = await fixture(template);
17
+ const textarea = await fixture(html `<glide-core-textarea required></glide-core-textarea>`);
18
18
  textarea.focus();
19
19
  await sendKeys({ type: 'value' });
20
20
  expect(textarea.validity?.valid).to.be.true;
@@ -22,29 +22,32 @@ it('is valid after being filled in and required', async () => {
22
22
  expect(textarea.validity?.tooLong).to.be.false;
23
23
  expect(textarea.checkValidity()).to.be.true;
24
24
  expect(textarea.reportValidity()).to.be.true;
25
+ await elementUpdated(textarea);
26
+ expect(textarea.shadowRoot?.querySelector('textarea')).to.have.attribute('aria-invalid', 'false');
25
27
  });
26
28
  it('is invalid if no value and required', async () => {
27
- const template = '<glide-core-textarea required></glide-core-textarea>';
28
- const textarea = await fixture(template);
29
+ const textarea = await fixture(html `<glide-core-textarea required></glide-core-textarea>`);
29
30
  expect(textarea.validity?.valid).to.be.false;
30
31
  expect(textarea.validity?.valueMissing).to.be.true;
31
32
  expect(textarea.validity?.tooLong).to.be.false;
32
33
  expect(textarea.willValidate).to.be.true;
33
34
  expect(textarea.checkValidity()).to.be.false;
34
35
  expect(textarea.reportValidity()).to.be.false;
36
+ await elementUpdated(textarea);
37
+ expect(textarea.shadowRoot?.querySelector('textarea')).to.have.attribute('aria-invalid', 'true');
35
38
  });
36
39
  it('is valid when empty and does not exceed `maxlength`', async () => {
37
- const template = '<glide-core-textarea maxlength="3"></glide-core-textarea>';
38
- const textarea = await fixture(template);
40
+ const textarea = await fixture(html `<glide-core-textarea maxlength="3"></glide-core-textarea>`);
39
41
  expect(textarea.validity?.valid).to.be.true;
40
42
  expect(textarea.validity?.valueMissing).to.be.false;
41
43
  expect(textarea.validity?.tooLong).to.be.false;
42
44
  expect(textarea.checkValidity()).to.be.true;
43
45
  expect(textarea.reportValidity()).to.be.true;
46
+ await elementUpdated(textarea);
47
+ expect(textarea.shadowRoot?.querySelector('textarea')).to.have.attribute('aria-invalid', 'false');
44
48
  });
45
49
  it('is valid when filled in and does not exceed `maxlength`', async () => {
46
- const template = '<glide-core-textarea maxlength="3"></glide-core-textarea>';
47
- const textarea = await fixture(template);
50
+ const textarea = await fixture(html `<glide-core-textarea maxlength="3"></glide-core-textarea>`);
48
51
  textarea.focus();
49
52
  await sendKeys({ type: 'abc' });
50
53
  expect(textarea.validity?.valid).to.be.true;
@@ -52,10 +55,11 @@ it('is valid when filled in and does not exceed `maxlength`', async () => {
52
55
  expect(textarea.validity?.tooLong).to.be.false;
53
56
  expect(textarea.checkValidity()).to.be.true;
54
57
  expect(textarea.reportValidity()).to.be.true;
58
+ await elementUpdated(textarea);
59
+ expect(textarea.shadowRoot?.querySelector('textarea')).to.have.attribute('aria-invalid', 'false');
55
60
  });
56
61
  it('is invalid when filled in and exceeds `maxlength`', async () => {
57
- const template = '<glide-core-textarea maxlength="3"></glide-core-textarea>';
58
- const textarea = await fixture(template);
62
+ const textarea = await fixture(html `<glide-core-textarea maxlength="3"></glide-core-textarea>`);
59
63
  textarea.focus();
60
64
  await sendKeys({ type: 'value' });
61
65
  expect(textarea.validity?.valid).to.be.false;
@@ -63,24 +67,104 @@ it('is invalid when filled in and exceeds `maxlength`', async () => {
63
67
  expect(textarea.validity?.tooLong).to.be.true;
64
68
  expect(textarea.checkValidity()).to.be.false;
65
69
  expect(textarea.reportValidity()).to.be.false;
70
+ await elementUpdated(textarea);
71
+ expect(textarea.shadowRoot?.querySelector('textarea')).to.have.attribute('aria-invalid', 'true');
66
72
  });
67
73
  it('is valid if no value but required and disabled', async () => {
68
- const template = '<glide-core-textarea required disabled></glide-core-textarea>';
69
- const textarea = await fixture(template);
74
+ const textarea = await fixture(html `<glide-core-textarea required disabled></glide-core-textarea>`);
75
+ expect(textarea.validity?.valid).to.be.true;
76
+ expect(textarea.validity?.valueMissing).to.be.false;
77
+ expect(textarea.validity?.tooLong).to.be.false;
78
+ expect(textarea.checkValidity()).to.be.true;
79
+ expect(textarea.reportValidity()).to.be.true;
80
+ await elementUpdated(textarea);
81
+ expect(textarea.shadowRoot?.querySelector('textarea')).to.have.attribute('aria-invalid', 'false');
82
+ });
83
+ it('updates validity when `required` and `value` is changed programmatically', async () => {
84
+ const textarea = await fixture(html `<glide-core-textarea label="Label" required></glide-core-textarea>`);
85
+ expect(textarea.validity?.valid).to.be.false;
86
+ expect(textarea.validity?.valueMissing).to.be.true;
87
+ expect(textarea.checkValidity()).to.be.false;
88
+ expect(textarea.reportValidity()).to.be.false;
89
+ await elementUpdated(textarea);
90
+ expect(textarea.shadowRoot?.querySelector('textarea')).to.have.attribute('aria-invalid', 'true');
91
+ textarea.value = 'text';
92
+ await elementUpdated(textarea);
93
+ expect(textarea.validity?.valid).to.be.true;
94
+ expect(textarea.validity?.valueMissing).to.be.false;
95
+ expect(textarea.checkValidity()).to.be.true;
96
+ expect(textarea.reportValidity()).to.be.true;
97
+ await elementUpdated(textarea);
98
+ expect(textarea.shadowRoot?.querySelector('textarea')).to.have.attribute('aria-invalid', 'false');
99
+ // Resetting the value to empty to ensure it goes
100
+ // back to an invalid state
101
+ textarea.value = '';
102
+ await elementUpdated(textarea);
103
+ expect(textarea.validity?.valid).to.be.false;
104
+ expect(textarea.validity?.valueMissing).to.be.true;
105
+ expect(textarea.checkValidity()).to.be.false;
106
+ expect(textarea.reportValidity()).to.be.false;
107
+ expect(textarea.shadowRoot?.querySelector('textarea')).to.have.attribute('aria-invalid', 'true');
108
+ });
109
+ it('is invalid when `value` is empty and `required` is set to `true` programmatically', async () => {
110
+ const textarea = await fixture(html `<glide-core-textarea label="Label"></glide-core-textarea>`);
111
+ expect(textarea.validity?.valid).to.be.true;
112
+ expect(textarea.validity?.valueMissing).to.be.false;
113
+ expect(textarea.checkValidity()).to.be.true;
114
+ expect(textarea.reportValidity()).to.be.true;
115
+ await elementUpdated(textarea);
116
+ expect(textarea.shadowRoot?.querySelector('textarea')).to.have.attribute('aria-invalid', 'false');
117
+ textarea.required = true;
118
+ await elementUpdated(textarea);
119
+ expect(textarea.validity?.valid).to.be.false;
120
+ expect(textarea.validity?.valueMissing).to.be.true;
121
+ expect(textarea.checkValidity()).to.be.false;
122
+ expect(textarea.reportValidity()).to.be.false;
123
+ expect(textarea.shadowRoot?.querySelector('textarea')).to.have.attribute('aria-invalid', 'true');
124
+ });
125
+ it('is valid when `value` is empty and `required` is set to `false` programmatically', async () => {
126
+ const textarea = await fixture(html `<glide-core-textarea label="Label" required></glide-core-textarea>`);
127
+ expect(textarea.validity?.valid).to.be.false;
128
+ expect(textarea.validity?.valueMissing).to.be.true;
129
+ expect(textarea.checkValidity()).to.be.false;
130
+ expect(textarea.reportValidity()).to.be.false;
131
+ await elementUpdated(textarea);
132
+ expect(textarea.shadowRoot?.querySelector('textarea')).to.have.attribute('aria-invalid', 'true');
133
+ textarea.required = false;
134
+ await elementUpdated(textarea);
135
+ expect(textarea.validity?.valid).to.be.true;
136
+ expect(textarea.validity?.valueMissing).to.be.false;
137
+ expect(textarea.checkValidity()).to.be.true;
138
+ expect(textarea.reportValidity()).to.be.true;
139
+ expect(textarea.shadowRoot?.querySelector('textarea')).to.have.attribute('aria-invalid', 'false');
140
+ });
141
+ it('is valid when filled in, disabled, and value exceeds `maxlength`', async () => {
142
+ const textarea = await fixture(html `<glide-core-textarea
143
+ value="value"
144
+ disabled
145
+ maxlength="3"
146
+ ></glide-core-textarea>`);
70
147
  expect(textarea.validity?.valid).to.be.true;
71
148
  expect(textarea.validity?.valueMissing).to.be.false;
72
149
  expect(textarea.validity?.tooLong).to.be.false;
73
150
  expect(textarea.checkValidity()).to.be.true;
74
151
  expect(textarea.reportValidity()).to.be.true;
152
+ await elementUpdated(textarea);
153
+ expect(textarea.shadowRoot?.querySelector('textarea')).to.have.attribute('aria-invalid', 'false');
75
154
  });
76
- it('is valid when filled in, disabled, and exceeds `maxlength`', async () => {
77
- const template = '<glide-core-textarea value="value" disabled maxlength="3"></glide-core-textarea>';
78
- const textarea = await fixture(template);
155
+ it('is valid when filled in, readonly, and value exceeds `maxlength`', async () => {
156
+ const textarea = await fixture(html `<glide-core-textarea
157
+ value="value"
158
+ readonly
159
+ maxlength="3"
160
+ ></glide-core-textarea>`);
79
161
  expect(textarea.validity?.valid).to.be.true;
80
162
  expect(textarea.validity?.valueMissing).to.be.false;
81
163
  expect(textarea.validity?.tooLong).to.be.false;
82
164
  expect(textarea.checkValidity()).to.be.true;
83
165
  expect(textarea.reportValidity()).to.be.true;
166
+ await elementUpdated(textarea);
167
+ expect(textarea.shadowRoot?.querySelector('textarea')).to.have.attribute('aria-invalid', 'false');
84
168
  });
85
169
  it('blurs the textarea and reports validity if `blur` is called', async () => {
86
170
  const textarea = await fixture(html `<glide-core-textarea required></glide-core-textarea>`);
@@ -91,6 +175,6 @@ it('blurs the textarea and reports validity if `blur` is called', async () => {
91
175
  await textarea.updateComplete;
92
176
  expect(textarea.shadowRoot?.activeElement === null).to.be.true;
93
177
  expect(textarea.validity.valid).to.equal(false);
94
- expect(textarea.shadowRoot?.querySelector('glide-core-label')?.error).to.be
95
- .true;
178
+ expect(textarea.shadowRoot?.querySelector('glide-core-private-label')?.error)
179
+ .to.be.true;
96
180
  });
package/dist/toasts.js CHANGED
@@ -1 +1 @@
1
- var __decorate=this&&this.__decorate||function(e,t,o,r){var s,i=arguments.length,l=i<3?t:null===r?r=Object.getOwnPropertyDescriptor(t,o):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)l=Reflect.decorate(e,t,o,r);else for(var n=e.length-1;n>=0;n--)(s=e[n])&&(l=(i<3?s(l):i>3?s(t,o,l):s(t,o))||l);return i>3&&l&&Object.defineProperty(t,o,l),l};import"./toasts.toast.js";import{LitElement,html}from"lit";import{LocalizeController}from"./library/localize.js";import{createRef,ref}from"lit/directives/ref.js";import{customElement}from"lit/decorators.js";import ow from"./library/ow.js";import styles from"./toasts.styles.js";let GlideCoreToasts=class GlideCoreToasts extends LitElement{static{this.shadowRootOptions={...LitElement.shadowRootOptions,mode:"closed"}}static{this.styles=styles}add(e){const{variant:t,label:o,description:r,duration:s}=e,i=Object.assign(document.createElement("glide-core-toast"),{variant:t,label:o,description:r,duration:s});return ow(this.#e.value,ow.object.instanceOf(Element)),this.#e.value.append(i),i.addEventListener("close",(()=>{i.remove()}),{once:!0}),i}render(){return html`<div class="component" role="region" tabindex="-1" aria-label="${this.#t.term("notifications")}" ${ref(this.#e)}></div>`}#e=createRef();#t=new LocalizeController(this)};GlideCoreToasts=__decorate([customElement("glide-core-toasts")],GlideCoreToasts);export default GlideCoreToasts;
1
+ var __decorate=this&&this.__decorate||function(e,t,o,r){var l,s=arguments.length,n=s<3?t:null===r?r=Object.getOwnPropertyDescriptor(t,o):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)n=Reflect.decorate(e,t,o,r);else for(var i=e.length-1;i>=0;i--)(l=e[i])&&(n=(s<3?l(n):s>3?l(t,o,n):l(t,o))||n);return s>3&&n&&Object.defineProperty(t,o,n),n};import"./toasts.toast.js";import{LitElement,html}from"lit";import{LocalizeController}from"./library/localize.js";import{createRef,ref}from"lit/directives/ref.js";import{customElement}from"lit/decorators.js";import ow from"./library/ow.js";import styles from"./toasts.styles.js";let GlideCoreToasts=class GlideCoreToasts extends LitElement{static{this.shadowRootOptions={...LitElement.shadowRootOptions,mode:"closed"}}static{this.styles=styles}add(e){ow(this.#e.value,ow.object.instanceOf(Element)),this.#e.value.popover="manual",this.#e.value.showPopover();const{variant:t,label:o,description:r,duration:l}=e,s=Object.assign(document.createElement("glide-core-toast"),{variant:t,label:o,description:r,duration:l});return this.#e.value.append(s),s.addEventListener("close",(()=>{s.remove(),0===this.#e.value?.querySelectorAll("glide-core-toast").length&&this.#e.value?.hidePopover()}),{once:!0}),s}render(){return html`<div class="component" role="region" tabindex="-1" aria-label="${this.#t.term("notifications")}" ${ref(this.#e)}></div>`}#e=createRef();#t=new LocalizeController(this)};GlideCoreToasts=__decorate([customElement("glide-core-toasts")],GlideCoreToasts);export default GlideCoreToasts;
@@ -1,15 +1,22 @@
1
1
  import{css}from"lit";export default[css`
2
2
  .component {
3
- display: flex;
3
+ background-color: transparent;
4
+ border: none;
5
+ display: none;
4
6
  flex-direction: column;
5
7
  gap: var(--glide-core-spacing-md);
6
8
  inline-size: 24.25rem;
7
9
  inset-block-start: 0;
8
10
  inset-inline-end: 0;
11
+ margin: 0 0 auto auto;
9
12
  max-block-size: 100%;
10
13
  max-inline-size: 100%;
11
14
  overflow: hidden;
12
15
  padding: var(--glide-core-spacing-sm);
13
16
  position: fixed;
17
+
18
+ &:popover-open {
19
+ display: flex;
20
+ }
14
21
  }
15
22
  `];
@@ -92,3 +92,23 @@ it('removes a closed toast from the DOM', async () => {
92
92
  toasts = component.shadowRoot?.querySelectorAll('glide-core-toast');
93
93
  expect(toasts?.length).to.equal(0);
94
94
  });
95
+ it('is hidden unless there are toasts displayed', async () => {
96
+ const component = await fixture(html `<glide-core-toasts></glide-core-toasts>`);
97
+ const shadowComponent = component.shadowRoot?.querySelector('.component');
98
+ assert(shadowComponent);
99
+ expect(shadowComponent.hasAttribute('popover')).to.equal(false);
100
+ expect(getComputedStyle(shadowComponent).display).to.equal('none');
101
+ component.add({
102
+ label: 'Test toast',
103
+ description: 'Test toast description',
104
+ variant: 'informational',
105
+ });
106
+ expect(shadowComponent.getAttribute('popover')).to.equal('manual');
107
+ expect(getComputedStyle(shadowComponent).display).to.equal('flex');
108
+ const toasts = component.shadowRoot?.querySelectorAll('glide-core-toast');
109
+ assert(toasts);
110
+ const toast = toasts[0];
111
+ toast.close();
112
+ toast.dispatchEvent(new Event('close', { bubbles: true }));
113
+ expect(getComputedStyle(shadowComponent).display).to.equal('none');
114
+ });
package/dist/toggle.js CHANGED
@@ -1 +1 @@
1
- var __decorate=this&&this.__decorate||function(e,t,o,i){var l,r=arguments.length,s=r<3?t:null===i?i=Object.getOwnPropertyDescriptor(t,o):i;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(e,t,o,i);else for(var d=e.length-1;d>=0;d--)(l=e[d])&&(s=(r<3?l(s):r>3?l(t,o,s):l(t,o))||s);return r>3&&s&&Object.defineProperty(t,o,s),s};import"./label.js";import{LitElement,html}from"lit";import{createRef,ref}from"lit/directives/ref.js";import{customElement,property}from"lit/decorators.js";import{ifDefined}from"lit/directives/if-defined.js";import styles from"./toggle.styles.js";let GlideCoreToggle=class GlideCoreToggle extends LitElement{constructor(){super(...arguments),this.checked=!1,this.disabled=!1,this.hideLabel=!1,this.orientation="horizontal",this.#e=createRef()}static{this.shadowRootOptions={...LitElement.shadowRootOptions,mode:"closed"}}static{this.styles=styles}click(){this.#e.value?.click()}focus(e){this.#e.value?.focus(e)}render(){return html`<div data-test="component"><glide-core-label orientation="${this.orientation}" split="${ifDefined(this.privateSplit??void 0)}" ?disabled="${this.disabled}" ?hide="${this.hideLabel}"><slot name="tooltip" slot="tooltip"></slot><label for="input">${this.label}</label><div class="toggle-and-input" slot="control"><input aria-checked="${this.checked}" aria-describedby="summary description" data-test="input" id="input" role="switch" type="checkbox" ?checked="${this.checked}" ?disabled="${this.disabled}" @change="${this.#t}" ${ref(this.#e)}></div><div slot="summary" id="summary">${this.summary}</div><slot class="description" id="description" name="description" slot="description"></slot></glide-core-label></div>`}#e;#t(e){e.target instanceof HTMLInputElement&&(this.checked=e.target.checked),this.dispatchEvent(new Event(e.type,e))}};__decorate([property({type:Boolean})],GlideCoreToggle.prototype,"checked",void 0),__decorate([property({reflect:!0,type:Boolean})],GlideCoreToggle.prototype,"disabled",void 0),__decorate([property({attribute:"hide-label",type:Boolean})],GlideCoreToggle.prototype,"hideLabel",void 0),__decorate([property({reflect:!0})],GlideCoreToggle.prototype,"label",void 0),__decorate([property({reflect:!0})],GlideCoreToggle.prototype,"orientation",void 0),__decorate([property({reflect:!0})],GlideCoreToggle.prototype,"name",void 0),__decorate([property()],GlideCoreToggle.prototype,"privateSplit",void 0),__decorate([property({reflect:!0})],GlideCoreToggle.prototype,"summary",void 0),GlideCoreToggle=__decorate([customElement("glide-core-toggle")],GlideCoreToggle);export default GlideCoreToggle;
1
+ var __decorate=this&&this.__decorate||function(e,t,o,i){var r,l=arguments.length,s=l<3?t:null===i?i=Object.getOwnPropertyDescriptor(t,o):i;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(e,t,o,i);else for(var d=e.length-1;d>=0;d--)(r=e[d])&&(s=(l<3?r(s):l>3?r(t,o,s):r(t,o))||s);return l>3&&s&&Object.defineProperty(t,o,s),s};import"./label.js";import{LitElement,html}from"lit";import{createRef,ref}from"lit/directives/ref.js";import{customElement,property}from"lit/decorators.js";import{ifDefined}from"lit/directives/if-defined.js";import styles from"./toggle.styles.js";let GlideCoreToggle=class GlideCoreToggle extends LitElement{constructor(){super(...arguments),this.checked=!1,this.disabled=!1,this.hideLabel=!1,this.orientation="horizontal",this.#e=createRef()}static{this.shadowRootOptions={...LitElement.shadowRootOptions,mode:"closed"}}static{this.styles=styles}click(){this.#e.value?.click()}focus(e){this.#e.value?.focus(e)}render(){return html`<div data-test="component"><glide-core-private-label orientation="${this.orientation}" split="${ifDefined(this.privateSplit??void 0)}" ?disabled="${this.disabled}" ?hide="${this.hideLabel}"><slot name="tooltip" slot="tooltip"></slot><label for="input">${this.label}</label><div class="toggle-and-input" slot="control"><input aria-checked="${this.checked}" aria-describedby="summary description" data-test="input" id="input" role="switch" type="checkbox" ?checked="${this.checked}" ?disabled="${this.disabled}" @change="${this.#t}" ${ref(this.#e)}></div><div slot="summary" id="summary">${this.summary}</div><slot class="description" id="description" name="description" slot="description"></slot></glide-core-private-label></div>`}#e;#t(e){e.target instanceof HTMLInputElement&&(this.checked=e.target.checked),this.dispatchEvent(new Event(e.type,e))}};__decorate([property({type:Boolean})],GlideCoreToggle.prototype,"checked",void 0),__decorate([property({reflect:!0,type:Boolean})],GlideCoreToggle.prototype,"disabled",void 0),__decorate([property({attribute:"hide-label",type:Boolean})],GlideCoreToggle.prototype,"hideLabel",void 0),__decorate([property({reflect:!0})],GlideCoreToggle.prototype,"label",void 0),__decorate([property({reflect:!0})],GlideCoreToggle.prototype,"orientation",void 0),__decorate([property({reflect:!0})],GlideCoreToggle.prototype,"name",void 0),__decorate([property()],GlideCoreToggle.prototype,"privateSplit",void 0),__decorate([property({reflect:!0})],GlideCoreToggle.prototype,"summary",void 0),GlideCoreToggle=__decorate([customElement("glide-core-toggle")],GlideCoreToggle);export default GlideCoreToggle;
@@ -1,7 +1,7 @@
1
1
  import { expect, fixture, html } from '@open-wc/testing';
2
2
  import GlideCoreToggle from './toggle.js';
3
3
  GlideCoreToggle.shadowRootOptions.mode = 'open';
4
- it('focuses the input when `focus` is called', async () => {
4
+ it('focuses the input when `focus()` is called', async () => {
5
5
  const component = await fixture(html `<glide-core-toggle label="Label"></glide-core-toggle>`);
6
6
  component.focus();
7
7
  const input = component.shadowRoot?.querySelector('[data-test="input"]');
@@ -0,0 +1 @@
1
+ export {};
package/dist/tooltip.d.ts CHANGED
@@ -12,12 +12,14 @@ export default class GlideCoreTooltip extends LitElement {
12
12
  #private;
13
13
  static shadowRootOptions: ShadowRootInit;
14
14
  static styles: import("lit").CSSResult[];
15
- disabled: boolean;
15
+ get disabled(): boolean;
16
+ set disabled(isDisabled: boolean);
17
+ offset: number;
18
+ get open(): boolean;
19
+ set open(isOpen: boolean);
16
20
  placement?: 'bottom' | 'left' | 'right' | 'top';
17
- containingBlock?: Element;
21
+ disconnectedCallback(): void;
18
22
  firstUpdated(): void;
19
- private get isVisible();
20
- private set isVisible(value);
21
23
  render(): import("lit").TemplateResult<1>;
22
- setContainingBlock(containingBlock: Element): void;
24
+ private effectivePlacement;
23
25
  }
package/dist/tooltip.js CHANGED
@@ -1 +1 @@
1
- var __decorate=this&&this.__decorate||function(e,t,o,i){var l,s=arguments.length,a=s<3?t:null===i?i=Object.getOwnPropertyDescriptor(t,o):i;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)a=Reflect.decorate(e,t,o,i);else for(var r=e.length-1;r>=0;r--)(l=e[r])&&(a=(s<3?l(a):s>3?l(t,o,a):l(t,o))||a);return s>3&&a&&Object.defineProperty(t,o,a),a};import{LitElement,html}from"lit";import{arrow,autoUpdate,computePosition,flip,offset,platform,shift}from"@floating-ui/dom";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{offsetParent}from"composed-offset-position";import{owSlot}from"./library/ow.js";import styles from"./tooltip.styles.js";let GlideCoreTooltip=class GlideCoreTooltip extends LitElement{constructor(){super(...arguments),this.disabled=!1,this.#e=createRef(),this.#t=createRef(),this.#o=!1,this.#i=createRef(),this.#l=createRef(),this.#s=createRef()}static{this.shadowRootOptions={...LitElement.shadowRootOptions,delegatesFocus:!0,mode:"closed"}}static{this.styles=styles}firstUpdated(){owSlot(this.#t.value),owSlot(this.#l.value),this.#a()}get isVisible(){return this.#o}set isVisible(e){this.#o=e,this.isVisible?this.#a():this.#r?.()}render(){return html`<div class="component" @mouseover="${this.#n}" @mouseout="${this.#f}"><div aria-labelledby="${ifDefined(this.disabled?void 0:"tooltip")}" class="target" slot="target" @focusin="${this.#p}" @focusout="${this.#c}" @keydown="${this.#d}" ${ref(this.#i)}><slot @slotchange="${this.#m}" ${ref(this.#l)} name="target"></slot></div><div class="${classMap({tooltip:!0,visible:this.isVisible&&!this.disabled})}" id="tooltip" role="${ifDefined(this.disabled?void 0:"tooltip")}" ${ref(this.#s)}><span aria-label="${ifDefined(this.disabled?void 0:"Tooltip: ")}"></span><slot @slotchange="${this.#h}" ${ref(this.#t)}></slot><div class="arrow" ${ref(this.#e)}></div></div></div>`}setContainingBlock(e){this.containingBlock=e}#e;#r;#u;#t;#o;#i;#l;#s;#g(){clearTimeout(this.#u)}#h(){owSlot(this.#t.value)}#p(){this.isVisible=!0}#c(){this.isVisible=!1}#d(e){"Escape"===e.key&&(this.isVisible=!1)}#f(){this.#R()}#n(){this.#g(),this.isVisible=!0}#m(){owSlot(this.#l.value)}#R(){this.#u=setTimeout((()=>{this.isVisible=!1}),200)}#a(){this.#i.value&&this.#s.value&&(this.#r=autoUpdate(this.#i.value,this.#s.value,(()=>{(async()=>{if(this.#i.value&&this.#s.value){const e=this.#e.value,{placement:t,x:o,y:i,middlewareData:l}=await computePosition(this.#i.value,this.#s.value,{platform:{...platform,getOffsetParent:e=>this.containingBlock&&e!==this.#e.value?this.containingBlock:platform.getOffsetParent(e,offsetParent)},placement:this.placement,strategy:"fixed",middleware:[offset(6),flip({fallbackStrategy:"initialPlacement"}),shift(),arrow({element:e})]});Object.assign(this.#s.value.style,{left:`${o}px`,top:`${i}px`});const s=l.arrow?.x??null,a=l.arrow?.y??null,r={top:"bottom",right:"left",bottom:"top",left:"right"}[t.split("-")[0]];Object.assign(e.style,{left:null===s?"":`${s}px`,top:null===a?"":`${a}px`,right:"",bottom:"",[r]:"-3px"})}})()})))}};__decorate([property({reflect:!0,type:Boolean})],GlideCoreTooltip.prototype,"disabled",void 0),__decorate([property()],GlideCoreTooltip.prototype,"placement",void 0),__decorate([state()],GlideCoreTooltip.prototype,"containingBlock",void 0),__decorate([state()],GlideCoreTooltip.prototype,"isVisible",null),GlideCoreTooltip=__decorate([customElement("glide-core-tooltip")],GlideCoreTooltip);export default GlideCoreTooltip;
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.#h}" @mouseout="${this.#d}"><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)}#d(){this.#w(),clearTimeout(this.#p)}#h(){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;