@crowdstrike/glide-core 0.7.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 (203) hide show
  1. package/README.md +44 -5
  2. package/dist/accordion.test.basics.js +1 -0
  3. package/dist/accordion.test.events.js +1 -0
  4. package/dist/button-group.button.d.ts +14 -15
  5. package/dist/button-group.button.js +1 -1
  6. package/dist/button-group.button.styles.js +75 -52
  7. package/dist/button-group.button.test.basics.d.ts +1 -1
  8. package/dist/button-group.button.test.basics.js +84 -147
  9. package/dist/button-group.button.test.events.js +9 -67
  10. package/dist/button-group.button.test.focus.js +13 -0
  11. package/dist/button-group.button.test.interactions.d.ts +1 -0
  12. package/dist/button-group.button.test.interactions.js +42 -0
  13. package/dist/button-group.d.ts +7 -10
  14. package/dist/button-group.js +1 -1
  15. package/dist/button-group.stories.d.ts +1 -5
  16. package/dist/button-group.styles.js +18 -6
  17. package/dist/button-group.test.basics.js +114 -234
  18. package/dist/button-group.test.events.js +211 -263
  19. package/dist/button-group.test.focus.d.ts +1 -0
  20. package/dist/button-group.test.focus.js +39 -0
  21. package/dist/button-group.test.interactions.d.ts +1 -0
  22. package/dist/button-group.test.interactions.js +91 -0
  23. package/dist/button.test.basics.js +2 -1
  24. package/dist/button.test.events.js +1 -0
  25. package/dist/button.test.form.js +1 -0
  26. package/dist/checkbox-group.js +1 -1
  27. package/dist/checkbox-group.styles.js +1 -1
  28. package/dist/checkbox-group.test.basics.js +2 -1
  29. package/dist/checkbox-group.test.events.js +5 -4
  30. package/dist/checkbox-group.test.focus.js +5 -3
  31. package/dist/checkbox-group.test.form.js +1 -0
  32. package/dist/checkbox-group.test.validity.js +1 -0
  33. package/dist/checkbox.d.ts +7 -1
  34. package/dist/checkbox.js +1 -1
  35. package/dist/checkbox.styles.js +11 -3
  36. package/dist/checkbox.test.basics.js +1 -0
  37. package/dist/checkbox.test.events.js +5 -4
  38. package/dist/checkbox.test.focus.js +2 -2
  39. package/dist/checkbox.test.form.js +1 -0
  40. package/dist/{checkbox.test.states.js → checkbox.test.interactions.js} +25 -1
  41. package/dist/checkbox.test.validity.js +1 -0
  42. package/dist/drawer.js +1 -1
  43. package/dist/drawer.test.basics.js +1 -0
  44. package/dist/drawer.test.closing.js +1 -0
  45. package/dist/drawer.test.events.js +1 -0
  46. package/dist/drawer.test.methods.js +1 -0
  47. package/dist/dropdown.d.ts +6 -4
  48. package/dist/dropdown.js +1 -1
  49. package/dist/dropdown.option.d.ts +7 -2
  50. package/dist/dropdown.option.js +1 -1
  51. package/dist/dropdown.option.styles.js +13 -0
  52. package/dist/dropdown.option.test.basics.js +7 -3
  53. package/dist/dropdown.option.test.basics.multiple.js +1 -0
  54. package/dist/dropdown.option.test.basics.single.js +1 -0
  55. package/dist/dropdown.option.test.events.js +2 -1
  56. package/dist/dropdown.option.test.focus.js +1 -1
  57. package/dist/dropdown.option.test.interactions.multiple.js +2 -54
  58. package/dist/dropdown.option.test.interactions.single.js +52 -9
  59. package/dist/dropdown.styles.js +20 -19
  60. package/dist/dropdown.test.basics.filterable.js +1 -0
  61. package/dist/dropdown.test.basics.js +144 -2
  62. package/dist/dropdown.test.basics.multiple.js +6 -3
  63. package/dist/dropdown.test.basics.single.js +1 -1
  64. package/dist/dropdown.test.events.filterable.js +74 -0
  65. package/dist/dropdown.test.events.js +50 -160
  66. package/dist/dropdown.test.events.multiple.js +268 -10
  67. package/dist/dropdown.test.events.single.js +202 -4
  68. package/dist/dropdown.test.focus.filterable.js +9 -5
  69. package/dist/dropdown.test.focus.js +2 -1
  70. package/dist/dropdown.test.focus.multiple.js +1 -2
  71. package/dist/dropdown.test.focus.single.js +1 -1
  72. package/dist/dropdown.test.form.js +1 -0
  73. package/dist/dropdown.test.form.multiple.js +1 -0
  74. package/dist/dropdown.test.form.single.js +1 -0
  75. package/dist/dropdown.test.interactions.filterable.js +69 -11
  76. package/dist/dropdown.test.interactions.js +95 -5
  77. package/dist/dropdown.test.interactions.multiple.js +203 -6
  78. package/dist/dropdown.test.interactions.single.js +69 -6
  79. package/dist/dropdown.test.validity.js +1 -0
  80. package/dist/form-controls-layout.test.basics.js +2 -1
  81. package/dist/icon-button.test.basics.js +2 -1
  82. package/dist/icons/checked.d.ts +1 -1
  83. package/dist/icons/checked.js +1 -1
  84. package/dist/icons/magnifying-glass.js +1 -1
  85. package/dist/input.d.ts +0 -6
  86. package/dist/input.js +1 -1
  87. package/dist/input.styles.js +7 -2
  88. package/dist/input.test.basics.js +20 -5
  89. package/dist/input.test.events.js +5 -4
  90. package/dist/input.test.focus.js +5 -4
  91. package/dist/input.test.form.js +1 -0
  92. package/dist/input.test.translations.d.ts +1 -0
  93. package/dist/input.test.translations.js +38 -0
  94. package/dist/input.test.validity.js +134 -4
  95. package/dist/label.d.ts +1 -1
  96. package/dist/label.js +1 -1
  97. package/dist/label.styles.js +29 -20
  98. package/dist/label.test.basics.js +27 -24
  99. package/dist/library/expect-argument-error.js +1 -1
  100. package/dist/library/localize.d.ts +5 -1
  101. package/dist/library/ow.test.d.ts +2 -1
  102. package/dist/library/ow.test.js +8 -3
  103. package/dist/menu.button.test.basics.js +1 -0
  104. package/dist/menu.d.ts +3 -5
  105. package/dist/menu.js +1 -1
  106. package/dist/menu.link.test.basics.js +1 -0
  107. package/dist/menu.options.test.basics.js +3 -2
  108. package/dist/menu.styles.js +1 -15
  109. package/dist/menu.test.basics.d.ts +1 -2
  110. package/dist/menu.test.basics.js +23 -6
  111. package/dist/menu.test.events.d.ts +1 -0
  112. package/dist/menu.test.events.js +2 -1
  113. package/dist/menu.test.focus.d.ts +1 -0
  114. package/dist/menu.test.focus.js +14 -6
  115. package/dist/menu.test.interactions.js +213 -56
  116. package/dist/modal.icon-button.test.basics.js +2 -1
  117. package/dist/modal.js +1 -1
  118. package/dist/modal.styles.js +18 -13
  119. package/dist/modal.tertiary-icon.d.ts +0 -1
  120. package/dist/modal.tertiary-icon.js +1 -1
  121. package/dist/modal.tertiary-icon.test.basics.js +2 -1
  122. package/dist/modal.test.accessibility.js +1 -0
  123. package/dist/modal.test.basics.js +2 -1
  124. package/dist/modal.test.close.js +1 -0
  125. package/dist/modal.test.events.js +11 -10
  126. package/dist/modal.test.lock-scroll.js +1 -0
  127. package/dist/modal.test.methods.js +1 -0
  128. package/dist/modal.test.scrollbars.js +1 -0
  129. package/dist/radio-group.js +1 -1
  130. package/dist/radio-group.styles.js +1 -1
  131. package/dist/radio-group.test.basics.js +1 -0
  132. package/dist/radio-group.test.events.js +1 -0
  133. package/dist/radio-group.test.focus.js +4 -3
  134. package/dist/radio-group.test.form.js +1 -0
  135. package/dist/radio-group.test.validity.js +1 -0
  136. package/dist/radio.d.ts +1 -0
  137. package/dist/radio.js +1 -1
  138. package/dist/radio.styles.js +33 -0
  139. package/dist/split-button.test.basics.js +1 -0
  140. package/dist/split-container.test.basics.js +5 -0
  141. package/dist/split-link.test.basics.js +1 -0
  142. package/dist/split-link.test.interactions.js +2 -1
  143. package/dist/styles/variables.css +1 -1
  144. package/dist/tab.d.ts +1 -3
  145. package/dist/tab.group.d.ts +3 -5
  146. package/dist/tab.group.js +1 -1
  147. package/dist/tab.group.styles.js +27 -13
  148. package/dist/tab.group.test.basics.js +8 -57
  149. package/dist/tab.group.test.interactions.d.ts +3 -0
  150. package/dist/tab.group.test.interactions.js +454 -0
  151. package/dist/tab.js +1 -1
  152. package/dist/tab.panel.d.ts +1 -0
  153. package/dist/tab.panel.js +1 -1
  154. package/dist/tab.panel.styles.js +11 -1
  155. package/dist/tab.styles.js +7 -68
  156. package/dist/tab.test.basics.js +0 -20
  157. package/dist/tabs.stories.d.ts +1 -2
  158. package/dist/tag.test.basics.js +3 -2
  159. package/dist/textarea.d.ts +0 -1
  160. package/dist/textarea.js +2 -2
  161. package/dist/textarea.stories.d.ts +3 -4
  162. package/dist/textarea.styles.js +14 -3
  163. package/dist/textarea.test.basics.js +81 -44
  164. package/dist/textarea.test.events.js +57 -41
  165. package/dist/textarea.test.form.js +1 -0
  166. package/dist/textarea.test.translations.d.ts +1 -0
  167. package/dist/textarea.test.translations.js +34 -0
  168. package/dist/textarea.test.validity.js +105 -20
  169. package/dist/toasts.js +1 -1
  170. package/dist/toasts.styles.js +8 -1
  171. package/dist/toasts.test.basics.js +20 -0
  172. package/dist/toggle.js +1 -1
  173. package/dist/toggle.test.basics.js +1 -0
  174. package/dist/toggle.test.events.js +1 -0
  175. package/dist/toggle.test.focus.js +1 -1
  176. package/dist/toggle.test.interactions.d.ts +1 -0
  177. package/dist/{toggle.test.states.js → toggle.test.interactions.js} +1 -0
  178. package/dist/tooltip.d.ts +7 -5
  179. package/dist/tooltip.js +1 -1
  180. package/dist/tooltip.styles.js +90 -25
  181. package/dist/tooltip.test.basics.js +39 -3
  182. package/dist/tooltip.test.interactions.js +137 -34
  183. package/dist/translations/en.js +1 -1
  184. package/dist/translations/fr.js +1 -1
  185. package/dist/translations/ja.js +1 -1
  186. package/dist/tree.d.ts +0 -1
  187. package/dist/tree.item.d.ts +2 -3
  188. package/dist/tree.item.js +1 -1
  189. package/dist/tree.item.menu.d.ts +0 -1
  190. package/dist/tree.item.menu.js +1 -1
  191. package/dist/tree.item.test.basics.js +1 -0
  192. package/dist/tree.js +1 -1
  193. package/dist/tree.test.basics.js +2 -1
  194. package/dist/tree.test.events.js +1 -1
  195. package/package.json +40 -29
  196. package/dist/drawer.test.floating-components.d.ts +0 -1
  197. package/dist/drawer.test.floating-components.js +0 -51
  198. package/dist/library/set-containing-block.d.ts +0 -15
  199. package/dist/library/set-containing-block.js +0 -1
  200. package/dist/modal.test.floating-components.js +0 -62
  201. /package/dist/{checkbox.test.states.d.ts → button-group.button.test.focus.d.ts} +0 -0
  202. /package/dist/{modal.test.floating-components.d.ts → checkbox.test.interactions.d.ts} +0 -0
  203. /package/dist/{toggle.test.states.d.ts → dropdown.test.events.filterable.d.ts} +0 -0
@@ -1,10 +1,10 @@
1
+ /* eslint-disable @typescript-eslint/no-unused-expressions */
1
2
  import './textarea.js';
2
3
  import * as sinon from 'sinon';
3
- import { aTimeout, expect, fixture, oneEvent } from '@open-wc/testing';
4
+ import { aTimeout, expect, fixture, html, oneEvent } from '@open-wc/testing';
4
5
  import { sendKeys } from '@web/test-runner-commands';
5
6
  it('dispatches a `input` event when typed in', async () => {
6
- const template = `<glide-core-textarea label="label"></glide-core-textarea>`;
7
- const textarea = await fixture(template);
7
+ const textarea = await fixture(html `<glide-core-textarea label="label"></glide-core-textarea>`);
8
8
  setTimeout(async () => {
9
9
  textarea.focus();
10
10
  await sendKeys({ type: 'testing' });
@@ -15,8 +15,7 @@ it('dispatches a `input` event when typed in', async () => {
15
15
  expect(event.bubbles).to.be.true;
16
16
  });
17
17
  it('dispatches an `change` event when typed in', async () => {
18
- const template = `<glide-core-textarea label="label"></glide-core-textarea>`;
19
- const textarea = await fixture(template);
18
+ const textarea = await fixture(html `<glide-core-textarea label="label"></glide-core-textarea>`);
20
19
  setTimeout(async () => {
21
20
  textarea.focus();
22
21
  await sendKeys({ type: 'testing' });
@@ -28,8 +27,7 @@ it('dispatches an `change` event when typed in', async () => {
28
27
  });
29
28
  it('dispatches an `invalid` event on submit when required and no value', async () => {
30
29
  const form = document.createElement('form');
31
- const template = `<glide-core-textarea label="label" required></glide-core-textarea>`;
32
- const textarea = await fixture(template, {
30
+ const textarea = await fixture(html `<glide-core-textarea label="label" required></glide-core-textarea>`, {
33
31
  parentNode: form,
34
32
  });
35
33
  setTimeout(() => form.requestSubmit());
@@ -38,8 +36,7 @@ it('dispatches an `invalid` event on submit when required and no value', async (
38
36
  });
39
37
  it('dispatches an `invalid` event after `checkValidity` is called when required and no value', async () => {
40
38
  const form = document.createElement('form');
41
- const template = `<glide-core-textarea label="label" required></glide-core-textarea>`;
42
- const textarea = await fixture(template, {
39
+ const textarea = await fixture(html `<glide-core-textarea label="label" required></glide-core-textarea>`, {
43
40
  parentNode: form,
44
41
  });
45
42
  setTimeout(() => textarea.checkValidity());
@@ -48,8 +45,7 @@ it('dispatches an `invalid` event after `checkValidity` is called when required
48
45
  });
49
46
  it('dispatches an `invalid` event after `reportValidity` is called when required and no value', async () => {
50
47
  const form = document.createElement('form');
51
- const template = `<glide-core-textarea label="label" required></glide-core-textarea>`;
52
- const textarea = await fixture(template, {
48
+ const textarea = await fixture(html `<glide-core-textarea label="label" required></glide-core-textarea>`, {
53
49
  parentNode: form,
54
50
  });
55
51
  setTimeout(() => textarea.reportValidity());
@@ -58,56 +54,62 @@ it('dispatches an `invalid` event after `reportValidity` is called when required
58
54
  });
59
55
  it('does not dispatch an `invalid` event after `checkValidity` is called when not required', async () => {
60
56
  const form = document.createElement('form');
61
- const template = `<glide-core-textarea label="label"></glide-core-textarea>`;
62
- const textarea = await fixture(template, {
57
+ const textarea = await fixture(html `<glide-core-textarea label="label"></glide-core-textarea>`, {
63
58
  parentNode: form,
64
59
  });
65
60
  const spy = sinon.spy();
66
61
  textarea.addEventListener('invalid', spy);
67
62
  textarea.checkValidity();
68
63
  await aTimeout(0);
69
- expect(spy.notCalled).to.be.true;
64
+ expect(spy.callCount).to.equal(0);
70
65
  });
71
66
  it('does not dispatch an `invalid` event after `checkValidity` is called when required, no value, and disabled', async () => {
72
67
  const form = document.createElement('form');
73
- const template = `<glide-core-textarea label="label" required disabled></glide-core-textarea>`;
74
- 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>`, {
75
73
  parentNode: form,
76
74
  });
77
75
  const spy = sinon.spy();
78
76
  textarea.addEventListener('invalid', spy);
79
77
  textarea.checkValidity();
80
78
  await aTimeout(0);
81
- expect(spy.notCalled).to.be.true;
79
+ expect(spy.callCount).to.equal(0);
82
80
  });
83
81
  it('does not dispatch an `invalid` event when `reportValidity` is called when not required,', async () => {
84
82
  const form = document.createElement('form');
85
- const template = `<glide-core-textarea label="label"></glide-core-textarea>`;
86
- const textarea = await fixture(template, {
83
+ const textarea = await fixture(html `<glide-core-textarea label="label"></glide-core-textarea>`, {
87
84
  parentNode: form,
88
85
  });
89
86
  const spy = sinon.spy();
90
87
  textarea.addEventListener('invalid', spy);
91
88
  textarea.reportValidity();
92
89
  await aTimeout(0);
93
- expect(spy.notCalled).to.be.true;
90
+ expect(spy.callCount).to.equal(0);
94
91
  });
95
92
  it('does not dispatch an `invalid` event when `reportValidity` is called when required, no value, and disabled', async () => {
96
93
  const form = document.createElement('form');
97
- const template = `<glide-core-textarea label="label" required disabled></glide-core-textarea>`;
98
- 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>`, {
99
99
  parentNode: form,
100
100
  });
101
101
  const spy = sinon.spy();
102
102
  textarea.addEventListener('invalid', spy);
103
103
  textarea.reportValidity();
104
104
  await aTimeout(0);
105
- expect(spy.notCalled).to.be.true;
105
+ expect(spy.callCount).to.equal(0);
106
106
  });
107
107
  it('dispatches an `invalid` event after `requestSubmit` is called when `maxlength` exceeded', async () => {
108
108
  const form = document.createElement('form');
109
- const template = `<glide-core-textarea label="label" maxlength="3"></glide-core-textarea>`;
110
- const textarea = await fixture(template, {
109
+ const textarea = await fixture(html `<glide-core-textarea
110
+ label="label"
111
+ maxlength="3"
112
+ ></glide-core-textarea>`, {
111
113
  parentNode: form,
112
114
  });
113
115
  setTimeout(async () => {
@@ -120,8 +122,10 @@ it('dispatches an `invalid` event after `requestSubmit` is called when `maxlengt
120
122
  });
121
123
  it('dispatches an `invalid` event after `checkValidity` is called when `maxlength` exceeded', async () => {
122
124
  const form = document.createElement('form');
123
- const template = `<glide-core-textarea label="label" maxlength="3"></glide-core-textarea>`;
124
- const textarea = await fixture(template, {
125
+ const textarea = await fixture(html `<glide-core-textarea
126
+ label="label"
127
+ maxlength="3"
128
+ ></glide-core-textarea>`, {
125
129
  parentNode: form,
126
130
  });
127
131
  setTimeout(async () => {
@@ -134,8 +138,10 @@ it('dispatches an `invalid` event after `checkValidity` is called when `maxlengt
134
138
  });
135
139
  it('dispatches an `invalid` event after `reportValidity` is called when `maxlength` exceeded', async () => {
136
140
  const form = document.createElement('form');
137
- const template = `<glide-core-textarea label="label" maxlength="3"></glide-core-textarea>`;
138
- const textarea = await fixture(template, {
141
+ const textarea = await fixture(html `<glide-core-textarea
142
+ label="label"
143
+ maxlength="3"
144
+ ></glide-core-textarea>`, {
139
145
  parentNode: form,
140
146
  });
141
147
  setTimeout(async () => {
@@ -148,8 +154,10 @@ it('dispatches an `invalid` event after `reportValidity` is called when `maxleng
148
154
  });
149
155
  it('does not dispatch an `invalid` event after `checkValidity` is called when `maxlength` not exceeded', async () => {
150
156
  const form = document.createElement('form');
151
- const template = `<glide-core-textarea label="label" maxlength="3"></glide-core-textarea>`;
152
- const textarea = await fixture(template, {
157
+ const textarea = await fixture(html `<glide-core-textarea
158
+ label="label"
159
+ maxlength="3"
160
+ ></glide-core-textarea>`, {
153
161
  parentNode: form,
154
162
  });
155
163
  const spy = sinon.spy();
@@ -158,12 +166,15 @@ it('does not dispatch an `invalid` event after `checkValidity` is called when `m
158
166
  await sendKeys({ type: 'ab' });
159
167
  textarea.checkValidity();
160
168
  await aTimeout(0);
161
- expect(spy.notCalled).to.be.true;
169
+ expect(spy.callCount).to.equal(0);
162
170
  });
163
171
  it('does not dispatch an `invalid` event after `checkValidity` is called when `maxlength` exceeded and disabled', async () => {
164
172
  const form = document.createElement('form');
165
- const template = `<glide-core-textarea label="label" maxlength="3" disabled></glide-core-textarea>`;
166
- 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>`, {
167
178
  parentNode: form,
168
179
  });
169
180
  const spy = sinon.spy();
@@ -172,12 +183,14 @@ it('does not dispatch an `invalid` event after `checkValidity` is called when `m
172
183
  await sendKeys({ type: 'test' });
173
184
  textarea.checkValidity();
174
185
  await aTimeout(0);
175
- expect(spy.notCalled).to.be.true;
186
+ expect(spy.callCount).to.equal(0);
176
187
  });
177
188
  it('does not dispatch an `invalid` event when `reportValidity` is called and `maxlength` is not exceeded,', async () => {
178
189
  const form = document.createElement('form');
179
- const template = `<glide-core-textarea label="label" maxlength="3"></glide-core-textarea>`;
180
- const textarea = await fixture(template, {
190
+ const textarea = await fixture(html `<glide-core-textarea
191
+ label="label"
192
+ maxlength="3"
193
+ ></glide-core-textarea>`, {
181
194
  parentNode: form,
182
195
  });
183
196
  const spy = sinon.spy();
@@ -186,12 +199,15 @@ it('does not dispatch an `invalid` event when `reportValidity` is called and `ma
186
199
  await sendKeys({ type: 'ab' });
187
200
  textarea.reportValidity();
188
201
  await aTimeout(0);
189
- expect(spy.notCalled).to.be.true;
202
+ expect(spy.callCount).to.equal(0);
190
203
  });
191
204
  it('does not dispatch an `invalid` event when `reportValidity` is called `maxlength` exceeded and disabled,', async () => {
192
205
  const form = document.createElement('form');
193
- const template = `<glide-core-textarea label="label" maxlength="3" disabled></glide-core-textarea>`;
194
- 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>`, {
195
211
  parentNode: form,
196
212
  });
197
213
  const spy = sinon.spy();
@@ -200,5 +216,5 @@ it('does not dispatch an `invalid` event when `reportValidity` is called `maxlen
200
216
  await sendKeys({ type: 'test' });
201
217
  textarea.reportValidity();
202
218
  await aTimeout(0);
203
- expect(spy.notCalled).to.be.true;
219
+ expect(spy.callCount).to.equal(0);
204
220
  });
@@ -1,3 +1,4 @@
1
+ /* eslint-disable @typescript-eslint/no-unused-expressions */
1
2
  import './textarea.js';
2
3
  import { expect, fixture, html } from '@open-wc/testing';
3
4
  import { sendKeys } from '@web/test-runner-commands';
@@ -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,19 +1,20 @@
1
- import { expect, fixture, html } from '@open-wc/testing';
1
+ /* eslint-disable @typescript-eslint/no-unused-expressions */
2
+ import { elementUpdated, expect, fixture, html } from '@open-wc/testing';
2
3
  import { sendKeys } from '@web/test-runner-commands';
3
4
  import GlideCoreTextarea from './textarea.js';
4
5
  GlideCoreTextarea.shadowRootOptions.mode = 'open';
5
6
  it('is valid by default', async () => {
6
- const template = '<glide-core-textarea></glide-core-textarea>';
7
- const textarea = await fixture(template);
7
+ const textarea = await fixture(html `<glide-core-textarea></glide-core-textarea>`);
8
8
  expect(textarea.validity?.valid).to.be.true;
9
9
  expect(textarea.validity?.valueMissing).to.be.false;
10
10
  expect(textarea.validity?.tooLong).to.be.false;
11
11
  expect(textarea.checkValidity()).to.be.true;
12
12
  expect(textarea.reportValidity()).to.be.true;
13
+ await elementUpdated(textarea);
14
+ expect(textarea.shadowRoot?.querySelector('textarea')).to.have.attribute('aria-invalid', 'false');
13
15
  });
14
16
  it('is valid after being filled in and required', async () => {
15
- const template = '<glide-core-textarea required></glide-core-textarea>';
16
- const textarea = await fixture(template);
17
+ const textarea = await fixture(html `<glide-core-textarea required></glide-core-textarea>`);
17
18
  textarea.focus();
18
19
  await sendKeys({ type: 'value' });
19
20
  expect(textarea.validity?.valid).to.be.true;
@@ -21,29 +22,32 @@ it('is valid after being filled in and required', async () => {
21
22
  expect(textarea.validity?.tooLong).to.be.false;
22
23
  expect(textarea.checkValidity()).to.be.true;
23
24
  expect(textarea.reportValidity()).to.be.true;
25
+ await elementUpdated(textarea);
26
+ expect(textarea.shadowRoot?.querySelector('textarea')).to.have.attribute('aria-invalid', 'false');
24
27
  });
25
28
  it('is invalid if no value and required', async () => {
26
- const template = '<glide-core-textarea required></glide-core-textarea>';
27
- const textarea = await fixture(template);
29
+ const textarea = await fixture(html `<glide-core-textarea required></glide-core-textarea>`);
28
30
  expect(textarea.validity?.valid).to.be.false;
29
31
  expect(textarea.validity?.valueMissing).to.be.true;
30
32
  expect(textarea.validity?.tooLong).to.be.false;
31
33
  expect(textarea.willValidate).to.be.true;
32
34
  expect(textarea.checkValidity()).to.be.false;
33
35
  expect(textarea.reportValidity()).to.be.false;
36
+ await elementUpdated(textarea);
37
+ expect(textarea.shadowRoot?.querySelector('textarea')).to.have.attribute('aria-invalid', 'true');
34
38
  });
35
39
  it('is valid when empty and does not exceed `maxlength`', async () => {
36
- const template = '<glide-core-textarea maxlength="3"></glide-core-textarea>';
37
- const textarea = await fixture(template);
40
+ const textarea = await fixture(html `<glide-core-textarea maxlength="3"></glide-core-textarea>`);
38
41
  expect(textarea.validity?.valid).to.be.true;
39
42
  expect(textarea.validity?.valueMissing).to.be.false;
40
43
  expect(textarea.validity?.tooLong).to.be.false;
41
44
  expect(textarea.checkValidity()).to.be.true;
42
45
  expect(textarea.reportValidity()).to.be.true;
46
+ await elementUpdated(textarea);
47
+ expect(textarea.shadowRoot?.querySelector('textarea')).to.have.attribute('aria-invalid', 'false');
43
48
  });
44
49
  it('is valid when filled in and does not exceed `maxlength`', async () => {
45
- const template = '<glide-core-textarea maxlength="3"></glide-core-textarea>';
46
- const textarea = await fixture(template);
50
+ const textarea = await fixture(html `<glide-core-textarea maxlength="3"></glide-core-textarea>`);
47
51
  textarea.focus();
48
52
  await sendKeys({ type: 'abc' });
49
53
  expect(textarea.validity?.valid).to.be.true;
@@ -51,10 +55,11 @@ it('is valid when filled in and does not exceed `maxlength`', async () => {
51
55
  expect(textarea.validity?.tooLong).to.be.false;
52
56
  expect(textarea.checkValidity()).to.be.true;
53
57
  expect(textarea.reportValidity()).to.be.true;
58
+ await elementUpdated(textarea);
59
+ expect(textarea.shadowRoot?.querySelector('textarea')).to.have.attribute('aria-invalid', 'false');
54
60
  });
55
61
  it('is invalid when filled in and exceeds `maxlength`', async () => {
56
- const template = '<glide-core-textarea maxlength="3"></glide-core-textarea>';
57
- const textarea = await fixture(template);
62
+ const textarea = await fixture(html `<glide-core-textarea maxlength="3"></glide-core-textarea>`);
58
63
  textarea.focus();
59
64
  await sendKeys({ type: 'value' });
60
65
  expect(textarea.validity?.valid).to.be.false;
@@ -62,24 +67,104 @@ it('is invalid when filled in and exceeds `maxlength`', async () => {
62
67
  expect(textarea.validity?.tooLong).to.be.true;
63
68
  expect(textarea.checkValidity()).to.be.false;
64
69
  expect(textarea.reportValidity()).to.be.false;
70
+ await elementUpdated(textarea);
71
+ expect(textarea.shadowRoot?.querySelector('textarea')).to.have.attribute('aria-invalid', 'true');
65
72
  });
66
73
  it('is valid if no value but required and disabled', async () => {
67
- const template = '<glide-core-textarea required disabled></glide-core-textarea>';
68
- 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>`);
69
147
  expect(textarea.validity?.valid).to.be.true;
70
148
  expect(textarea.validity?.valueMissing).to.be.false;
71
149
  expect(textarea.validity?.tooLong).to.be.false;
72
150
  expect(textarea.checkValidity()).to.be.true;
73
151
  expect(textarea.reportValidity()).to.be.true;
152
+ await elementUpdated(textarea);
153
+ expect(textarea.shadowRoot?.querySelector('textarea')).to.have.attribute('aria-invalid', 'false');
74
154
  });
75
- it('is valid when filled in, disabled, and exceeds `maxlength`', async () => {
76
- const template = '<glide-core-textarea value="value" disabled maxlength="3"></glide-core-textarea>';
77
- 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>`);
78
161
  expect(textarea.validity?.valid).to.be.true;
79
162
  expect(textarea.validity?.valueMissing).to.be.false;
80
163
  expect(textarea.validity?.tooLong).to.be.false;
81
164
  expect(textarea.checkValidity()).to.be.true;
82
165
  expect(textarea.reportValidity()).to.be.true;
166
+ await elementUpdated(textarea);
167
+ expect(textarea.shadowRoot?.querySelector('textarea')).to.have.attribute('aria-invalid', 'false');
83
168
  });
84
169
  it('blurs the textarea and reports validity if `blur` is called', async () => {
85
170
  const textarea = await fixture(html `<glide-core-textarea required></glide-core-textarea>`);
@@ -90,6 +175,6 @@ it('blurs the textarea and reports validity if `blur` is called', async () => {
90
175
  await textarea.updateComplete;
91
176
  expect(textarea.shadowRoot?.activeElement === null).to.be.true;
92
177
  expect(textarea.validity.valid).to.equal(false);
93
- expect(textarea.shadowRoot?.querySelector('glide-core-label')?.error).to.be
94
- .true;
178
+ expect(textarea.shadowRoot?.querySelector('glide-core-private-label')?.error)
179
+ .to.be.true;
95
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,3 +1,4 @@
1
+ /* eslint-disable @typescript-eslint/no-unused-expressions */
1
2
  import { expect, fixture, html } from '@open-wc/testing';
2
3
  import GlideCoreToggle from './toggle.js';
3
4
  GlideCoreToggle.shadowRootOptions.mode = 'open';
@@ -1,3 +1,4 @@
1
+ /* eslint-disable @typescript-eslint/no-unused-expressions */
1
2
  import { expect, fixture, html, oneEvent } from '@open-wc/testing';
2
3
  import GlideCoreToggle from './toggle.js';
3
4
  GlideCoreToggle.shadowRootOptions.mode = 'open';
@@ -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 {};
@@ -1,3 +1,4 @@
1
+ /* eslint-disable @typescript-eslint/no-unused-expressions */
1
2
  import { elementUpdated, expect, fixture, html } from '@open-wc/testing';
2
3
  import GlideCoreToggle from './toggle.js';
3
4
  GlideCoreToggle.shadowRootOptions.mode = 'open';
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;