@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,6 +1,6 @@
1
1
  /* eslint-disable @typescript-eslint/no-unused-expressions */
2
2
  import { ArgumentError } from 'ow';
3
- import { assert, elementUpdated, expect, fixture, html, } from '@open-wc/testing';
3
+ import { aTimeout, assert, elementUpdated, expect, fixture, html, } from '@open-wc/testing';
4
4
  import { sendKeys } from '@web/test-runner-commands';
5
5
  import GlideCoreDropdown from './dropdown.js';
6
6
  import GlideCoreDropdownOption from './dropdown.option.js';
@@ -21,7 +21,11 @@ it('opens on click', async () => {
21
21
  component.shadowRoot
22
22
  ?.querySelector('[data-test="button"]')
23
23
  ?.dispatchEvent(new CustomEvent('click', { bubbles: true, detail: 1 }));
24
+ // Wait for it to open.
25
+ await aTimeout(0);
26
+ const options = component.shadowRoot?.querySelector('[data-test="options"]');
24
27
  expect(component.open).to.be.true;
28
+ expect(options?.checkVisibility()).to.be.true;
25
29
  });
26
30
  it('toggles open and closed when the button is clicked', async () => {
27
31
  const component = await fixture(html `<glide-core-dropdown label="Label" placeholder="Placeholder" open>
@@ -37,7 +41,10 @@ it('toggles open and closed when the button is clicked', async () => {
37
41
  component.shadowRoot
38
42
  ?.querySelector('[data-test="button"]')
39
43
  ?.dispatchEvent(new CustomEvent('click', { bubbles: true, detail: 1 }));
44
+ await elementUpdated(component);
45
+ const options = component.shadowRoot?.querySelector('[data-test="options"]');
40
46
  expect(component.open).to.be.false;
47
+ expect(options?.checkVisibility()).to.be.false;
41
48
  });
42
49
  it('does not toggle open and closed when the button overflow text is clicked', async () => {
43
50
  const component = await fixture(html `<glide-core-dropdown label="Label" placeholder="Placeholder" open>
@@ -53,7 +60,11 @@ it('does not toggle open and closed when the button overflow text is clicked', a
53
60
  component.shadowRoot
54
61
  ?.querySelector('[data-test="tag-overflow-text"]')
55
62
  ?.dispatchEvent(new CustomEvent('click', { bubbles: true, detail: 1 }));
63
+ // Wait for it to open.
64
+ await aTimeout(0);
65
+ const options = component.shadowRoot?.querySelector('[data-test="options"]');
56
66
  expect(component.open).to.be.true;
67
+ expect(options?.checkVisibility()).to.be.true;
57
68
  });
58
69
  it('selects an option on click', async () => {
59
70
  const component = await fixture(html `<glide-core-dropdown label="Label" placeholder="Placeholder" open>
@@ -62,6 +73,8 @@ it('selects an option on click', async () => {
62
73
  value="one"
63
74
  ></glide-core-dropdown-option>
64
75
  </glide-core-dropdown>`);
76
+ // Wait for it to open.
77
+ await aTimeout(0);
65
78
  const option = component.querySelector('glide-core-dropdown-option');
66
79
  option?.click();
67
80
  await elementUpdated(component);
@@ -77,11 +90,26 @@ it('selects an option on Space', async () => {
77
90
  value="one"
78
91
  ></glide-core-dropdown-option>
79
92
  </glide-core-dropdown>`);
93
+ // Wait for it to open.
94
+ await aTimeout(0);
80
95
  const option = component.querySelector('glide-core-dropdown-option');
81
96
  option?.focus();
82
97
  await sendKeys({ press: ' ' });
83
98
  expect(option?.selected).to.be.true;
84
99
  });
100
+ it('does not deselect options on Space', async () => {
101
+ const component = await fixture(html `<glide-core-dropdown label="Label" placeholder="Placeholder" open>
102
+ <glide-core-dropdown-option
103
+ label="One"
104
+ value="one"
105
+ selected
106
+ ></glide-core-dropdown-option>
107
+ </glide-core-dropdown>`);
108
+ component?.focus();
109
+ await sendKeys({ press: ' ' });
110
+ const option = component.querySelector('glide-core-dropdown-option');
111
+ expect(option?.selected).to.be.true;
112
+ });
85
113
  it('selects an option on Enter', async () => {
86
114
  const component = await fixture(html `<glide-core-dropdown label="Label" placeholder="Placeholder" open>
87
115
  <glide-core-dropdown-option
@@ -89,6 +117,8 @@ it('selects an option on Enter', async () => {
89
117
  value="one"
90
118
  ></glide-core-dropdown-option>
91
119
  </glide-core-dropdown>`);
120
+ // Wait for it to open.
121
+ await aTimeout(0);
92
122
  const option = component.querySelector('glide-core-dropdown-option');
93
123
  option?.focus();
94
124
  await sendKeys({ press: 'Enter' });
@@ -122,6 +152,17 @@ it('closes when an option is selected via click', async () => {
122
152
  component.querySelector('glide-core-dropdown-option')?.click();
123
153
  expect(component.open).to.be.false;
124
154
  });
155
+ it('closes when an option is selected via Space', async () => {
156
+ const component = await fixture(html `<glide-core-dropdown label="Label" placeholder="Placeholder" open>
157
+ <glide-core-dropdown-option
158
+ label="Label"
159
+ value="value"
160
+ ></glide-core-dropdown-option>
161
+ </glide-core-dropdown>`);
162
+ component.focus();
163
+ await sendKeys({ press: ' ' });
164
+ expect(component.open).to.be.false;
165
+ });
125
166
  it('closes when an option is selected via Enter', async () => {
126
167
  const component = await fixture(html `<glide-core-dropdown label="Label" placeholder="Placeholder" open>
127
168
  <glide-core-dropdown-option
@@ -129,6 +170,19 @@ it('closes when an option is selected via Enter', async () => {
129
170
  value="value"
130
171
  ></glide-core-dropdown-option>
131
172
  </glide-core-dropdown>`);
173
+ component.focus();
174
+ await sendKeys({ press: 'Enter' });
175
+ expect(component.open).to.be.false;
176
+ });
177
+ it('closes when an option is selected via Enter', async () => {
178
+ const component = await fixture(html `<glide-core-dropdown label="Label" placeholder="Placeholder" open>
179
+ <glide-core-dropdown-option
180
+ label="Label"
181
+ value="value"
182
+ ></glide-core-dropdown-option>
183
+ </glide-core-dropdown>`);
184
+ // Wait for it to open.
185
+ await aTimeout(0);
132
186
  component.querySelector('glide-core-dropdown-option')?.focus();
133
187
  await sendKeys({ press: 'Enter' });
134
188
  expect(component.open).to.be.false;
@@ -140,6 +194,8 @@ it('closes when an option is selected via Space', async () => {
140
194
  value="value"
141
195
  ></glide-core-dropdown-option>
142
196
  </glide-core-dropdown>`);
197
+ // Wait for it to open.
198
+ await aTimeout(0);
143
199
  const option = component.querySelector('glide-core-dropdown-option');
144
200
  option?.focus();
145
201
  await sendKeys({ press: ' ' });
@@ -211,7 +267,7 @@ it('throws when `value` is changed programmatically to include more than one val
211
267
  spy();
212
268
  }
213
269
  }
214
- expect(spy.called).to.be.true;
270
+ expect(spy.callCount).to.equal(1);
215
271
  });
216
272
  it('updates `value` when an option `value` is changed programmatically', async () => {
217
273
  const component = await fixture(html `<glide-core-dropdown label="Label" placeholder="Placeholder">
@@ -274,6 +330,8 @@ it('updates `value` when an option is selected via Enter', async () => {
274
330
 
275
331
  <glide-core-dropdown-option label="Two"></glide-core-dropdown-option>
276
332
  </glide-core-dropdown>`);
333
+ // Wait for it to open.
334
+ await aTimeout(0);
277
335
  const options = component.querySelectorAll('glide-core-dropdown-option');
278
336
  options[0].focus();
279
337
  await sendKeys({ press: 'Enter' });
@@ -283,7 +341,7 @@ it('updates `value` when an option is selected via Enter', async () => {
283
341
  ?.querySelector('[data-test="button"]')
284
342
  ?.dispatchEvent(new CustomEvent('click', { bubbles: true, detail: 1 }));
285
343
  // Wait for it to open.
286
- await elementUpdated(component);
344
+ await aTimeout(0);
287
345
  options[1].focus();
288
346
  await sendKeys({ press: 'Enter' });
289
347
  expect(component.value).to.deep.equal(['two']);
@@ -292,7 +350,7 @@ it('updates `value` when an option is selected via Enter', async () => {
292
350
  ?.querySelector('[data-test="button"]')
293
351
  ?.dispatchEvent(new CustomEvent('click', { bubbles: true, detail: 1 }));
294
352
  // Wait for it to open.
295
- await elementUpdated(component);
353
+ await aTimeout(0);
296
354
  options[2].focus();
297
355
  await sendKeys({ press: 'Enter' });
298
356
  expect(component.value).to.deep.equal([]);
@@ -311,6 +369,8 @@ it('updates `value` when an option is selected via Space', async () => {
311
369
 
312
370
  <glide-core-dropdown-option label="Three"></glide-core-dropdown-option>
313
371
  </glide-core-dropdown>`);
372
+ // Wait for it to open.
373
+ await aTimeout(0);
314
374
  const options = component.querySelectorAll('glide-core-dropdown-option');
315
375
  options[0].focus();
316
376
  await sendKeys({ press: ' ' });
@@ -320,7 +380,7 @@ it('updates `value` when an option is selected via Space', async () => {
320
380
  ?.querySelector('[data-test="button"]')
321
381
  ?.dispatchEvent(new CustomEvent('click', { bubbles: true, detail: 1 }));
322
382
  // Wait for it to open.
323
- await elementUpdated(component);
383
+ await aTimeout(0);
324
384
  options[1].focus();
325
385
  await sendKeys({ press: ' ' });
326
386
  expect(component.value).to.deep.equal(['two']);
@@ -329,7 +389,7 @@ it('updates `value` when an option is selected via Space', async () => {
329
389
  ?.querySelector('[data-test="button"]')
330
390
  ?.dispatchEvent(new CustomEvent('click', { bubbles: true, detail: 1 }));
331
391
  // Wait for it to open.
332
- await elementUpdated(component);
392
+ await aTimeout(0);
333
393
  options[2].focus();
334
394
  await sendKeys({ press: ' ' });
335
395
  expect(component.value).to.deep.equal([]);
@@ -442,6 +502,8 @@ it('does not select an option on Enter when the option is not focused', async ()
442
502
  value="two"
443
503
  ></glide-core-dropdown-option>
444
504
  </glide-core-dropdown>`);
505
+ // Wait for it to open.
506
+ await aTimeout(0);
445
507
  const option = component.querySelector('glide-core-dropdown-option');
446
508
  option?.focus();
447
509
  await sendKeys({ down: 'Tab' });
@@ -49,7 +49,7 @@ it('throws if it does not have a default slot', async () => {
49
49
  spy();
50
50
  }
51
51
  }
52
- expect(spy.called).to.be.true;
52
+ expect(spy.callCount).to.equal(1);
53
53
  });
54
54
  it('throws if its default slot is the incorrect type', async () => {
55
55
  await expectArgumentError(() => {
@@ -107,5 +107,5 @@ it('throws if it does not have a default slot', async () => {
107
107
  spy();
108
108
  }
109
109
  }
110
- expect(spy.called).to.be.true;
110
+ expect(spy.callCount).to.equal(1);
111
111
  });
@@ -1,2 +1,2 @@
1
- declare const _default: import("lit").TemplateResult;
1
+ declare const _default: import("lit").TemplateResult<1>;
2
2
  export default _default;
@@ -1 +1 @@
1
- import{svg}from"lit/static-html.js";export default svg`<svg fill="none" viewBox="0 0 24 24" style="height: var(--size, 0.875rem); width: var(--size, 0.875rem);"><path d="M20 6L9 17L4 12" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>`;
1
+ import{html}from"lit";export default html`<svg fill="none" viewBox="0 0 24 24" style="height: var(--size, 0.875rem); width: var(--size, 0.875rem);"><path d="M20 6L9 17L4 12" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>`;
@@ -1 +1 @@
1
- import{svg}from"lit/static-html.js";export default svg`<svg class="search-icon" fill="none" width="16" height="16" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" d="m21 21-5.197-5.197m0 0A7.5 7.5 0 1 0 5.196 5.196a7.5 7.5 0 0 0 10.607 10.607Z"/></svg>`;
1
+ import{svg}from"lit/static-html.js";export default svg`<svg class="search-icon" data-test="search-icon" fill="none" width="16" height="16" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" d="m21 21-5.197-5.197m0 0A7.5 7.5 0 1 0 5.196 5.196a7.5 7.5 0 0 0 10.607 10.607Z"/></svg>`;
package/dist/input.d.ts CHANGED
@@ -41,24 +41,18 @@ export default class GlideCoreInput extends LitElement {
41
41
  disabled: boolean;
42
42
  privateSplit?: 'left' | 'middle';
43
43
  maxlength?: number;
44
- descriptionNodes: NodeListOf<HTMLElement>;
45
- prefixIconNodes: NodeListOf<HTMLElement>;
46
- suffixIconNodes: NodeListOf<HTMLElement>;
47
44
  get form(): HTMLFormElement | null;
48
45
  get validity(): ValidityState;
49
46
  get willValidate(): boolean;
50
47
  blur(): void;
51
48
  checkValidity(): boolean;
52
49
  disconnectedCallback(): void;
53
- firstUpdated(): void;
54
50
  formAssociatedCallback(): void;
55
51
  formResetCallback(): void;
56
- get isTypeSearch(): boolean;
57
52
  get hasClearIcon(): boolean;
58
53
  get isClearIconVisible(): boolean;
59
54
  render(): import("lit").TemplateResult<1>;
60
55
  reportValidity(): boolean;
61
- get valueCharacterCount(): number;
62
56
  constructor();
63
57
  private hasFocus;
64
58
  private isBlurring;
package/dist/input.js CHANGED
@@ -1 +1 @@
1
- var __decorate=this&&this.__decorate||function(t,e,i,o){var r,s=arguments.length,a=s<3?e:null===o?o=Object.getOwnPropertyDescriptor(e,i):o;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)a=Reflect.decorate(t,e,i,o);else for(var l=t.length-1;l>=0;l--)(r=t[l])&&(a=(s<3?r(a):s>3?r(e,i,a):r(e,i))||a);return s>3&&a&&Object.defineProperty(e,i,a),a};import"./icon-button.js";import"./label.js";import{LitElement,html,nothing}from"lit";import{LocalizeController}from"./library/localize.js";import{classMap}from"lit/directives/class-map.js";import{createRef,ref}from"lit/directives/ref.js";import{customElement,property,queryAssignedNodes,state}from"lit/decorators.js";import{ifDefined}from"lit/directives/if-defined.js";import magnifyingGlassIcon from"./icons/magnifying-glass.js";import ow from"./library/ow.js";import styles from"./input.styles.js";export const SUPPORTED_TYPES=["email","number","password","search","tel","text","url"];let GlideCoreInput=class GlideCoreInput extends LitElement{static{this.formAssociated=!0}static{this.shadowRootOptions={...LitElement.shadowRootOptions,mode:"closed",delegatesFocus:!0}}static{this.styles=styles}get form(){return this.#t.form}get validity(){return this.#t.validity}get willValidate(){return this.#t.willValidate}blur(){this.#e?.blur()}checkValidity(){this.isCheckingValidity=!0;const t=this.#t.checkValidity();return this.isCheckingValidity=!1,t}disconnectedCallback(){super.disconnectedCallback(),this.form?.removeEventListener("formdata",this.#i)}firstUpdated(){this.#o()}formAssociatedCallback(){this.form?.addEventListener("formdata",this.#i)}formResetCallback(){this.value=this.getAttribute("value")??""}get isTypeSearch(){return"search"===this.type}get hasClearIcon(){return this.clearable&&!this.disabled&&!this.readonly}get isClearIconVisible(){return this.hasClearIcon&&this.value.length>0}render(){return html`<glide-core-label class="${classMap({left:"left"===this.privateSplit,middle:"middle"===this.privateSplit})}" orientation="${this.orientation}" split="${ifDefined(this.privateSplit??void 0)}" ?disabled="${this.disabled}" ?error="${this.#r||this.#s}" ?hide="${this.hideLabel}" ?required="${this.required}"><slot name="tooltip" slot="tooltip"></slot><label for="input">${this.label}</label><div class="${classMap({"input-box":!0,focused:this.hasFocus,empty:""===this.value,disabled:this.disabled,readonly:this.readonly&&!this.disabled,error:this.#r||this.#s})}" slot="control"><slot name="prefix"></slot><input aria-describedby="meta" id="input" type="${"password"===this.type&&this.passwordVisible?"text":this.type}" .value="${this.value}" placeholder="${ifDefined(this.placeholder)}" autocapitalize="${ifDefined(this.autocapitalize)}" spellcheck="${this.spellcheck}" ?required="${this.required}" ?readonly="${this.readonly}" ?disabled="${this.disabled}" @focus="${this.#a}" @blur="${this.#l}" @change="${this.#n}" @input="${this.#d}" ${ref(this.#p)}> ${this.hasClearIcon?html`<glide-core-icon-button variant="tertiary" class="${classMap({"clear-icon-button":!0,"clear-icon-button--visible":this.isClearIconVisible})}" aria-label="${this.#h.term("clearEntry")}" @click="${this.#c}" tabindex="-1"><slot name="clear-icon"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor"><path d="M6 6L18 18" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/><path d="M18 6L6 18" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg></slot></glide-core-icon-button>`:""} ${"password"===this.type&&this.passwordToggle&&!this.disabled?html`<glide-core-icon-button variant="tertiary" class="password-toggle" aria-label="${this.passwordVisible?"Hide password":"Show password"}" aria-controls="input" aria-expanded="${this.passwordVisible?"true":"false"}" @click="${this.#u}" tabindex="-1">${this.passwordVisible?html`<svg width="16" height="16" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" d="M3.98 8.223A10.477 10.477 0 0 0 1.934 12C3.226 16.338 7.244 19.5 12 19.5c.993 0 1.953-.138 2.863-.395M6.228 6.228A10.451 10.451 0 0 1 12 4.5c4.756 0 8.773 3.162 10.065 7.498a10.522 10.522 0 0 1-4.293 5.774M6.228 6.228 3 3m3.228 3.228 3.65 3.65m7.894 7.894L21 21m-3.228-3.228-3.65-3.65m0 0a3 3 0 1 0-4.243-4.243m4.242 4.242L9.88 9.88"/></svg>`:html`<svg width="16" height="16" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" d="M2.036 12.322a1.012 1.012 0 0 1 0-.639C3.423 7.51 7.36 4.5 12 4.5c4.638 0 8.573 3.007 9.963 7.178.07.207.07.431 0 .639C20.577 16.49 16.64 19.5 12 19.5c-4.638 0-8.573-3.007-9.963-7.178Z"/><path stroke-linecap="round" stroke-linejoin="round" d="M15 12a3 3 0 1 1-6 0 3 3 0 0 1 6 0Z"/></svg>`}</glide-core-icon-button>`:""}<div class="suffix">${this.isTypeSearch?magnifyingGlassIcon:html`<slot name="suffix"></slot>`}</div></div><div class="meta" id="meta" slot="description"><slot class="description" name="description"></slot>${this.maxlength?html`<div class="${classMap({"character-count":!0,error:this.#s})}">${this.valueCharacterCount}/${this.maxlength}</div>`:nothing}</div></glide-core-label>`}reportValidity(){this.isReportValidityOrSubmit=!0;const t=this.#t.reportValidity();return this.requestUpdate(),t}get valueCharacterCount(){return this.value.length}constructor(){super(),this.type="text",this.value="",this.hideLabel=!1,this.orientation="horizontal",this.clearable=!1,this.spellcheck=!1,this.autocapitalize="on",this.passwordToggle=!1,this.required=!1,this.readonly=!1,this.disabled=!1,this.hasFocus=!1,this.isBlurring=!1,this.isCheckingValidity=!1,this.isReportValidityOrSubmit=!1,this.passwordVisible=!1,this.#p=createRef(),this.#h=new LocalizeController(this),this.#i=({formData:t})=>{this.name&&this.value&&!this.disabled&&t.append(this.name,this.value)},this.#t=this.attachInternals(),this.addEventListener("invalid",(t=>{if(t?.preventDefault(),this.isCheckingValidity||this.isBlurring)return;this.isReportValidityOrSubmit=!0;this.form?.querySelector(":invalid")===this&&this.focus()}))}#p;#t;#h;#i;get#s(){return Boolean(this.maxlength&&this.valueCharacterCount>this.maxlength)}get#r(){return!this.disabled&&!this.validity?.valid&&this.isReportValidityOrSubmit}get#e(){return this.#p.value}#l(){this.isBlurring=!0,this.reportValidity(),this.isBlurring=!1,this.hasFocus=!1}#n(t){ow(this.#e,ow.object.instanceOf(HTMLInputElement)),this.value=this.#e.value,this.#o(),this.dispatchEvent(new Event(t.type,t))}#c(t){this.value="",this.dispatchEvent(new Event("clear",{bubbles:!0})),this.#e?.focus(),this.#o(),t.stopPropagation()}#a(){this.hasFocus=!0}#d(){ow(this.#e,ow.object.instanceOf(HTMLInputElement)),this.value=this.#e.value,this.#o()}#u(){this.passwordVisible=!this.passwordVisible}async#o(){await this.updateComplete,this.#t.setValidity(this.#e?.validity,this.#e?.validationMessage,this.#e),this.isReportValidityOrSubmit&&this.reportValidity()}};__decorate([property()],GlideCoreInput.prototype,"type",void 0),__decorate([property({reflect:!0})],GlideCoreInput.prototype,"name",void 0),__decorate([property()],GlideCoreInput.prototype,"value",void 0),__decorate([property()],GlideCoreInput.prototype,"label",void 0),__decorate([property({attribute:"hide-label",type:Boolean})],GlideCoreInput.prototype,"hideLabel",void 0),__decorate([property({reflect:!0})],GlideCoreInput.prototype,"orientation",void 0),__decorate([property()],GlideCoreInput.prototype,"placeholder",void 0),__decorate([property({type:Boolean})],GlideCoreInput.prototype,"clearable",void 0),__decorate([property({type:Boolean})],GlideCoreInput.prototype,"spellcheck",void 0),__decorate([property()],GlideCoreInput.prototype,"autocapitalize",void 0),__decorate([property({attribute:"password-toggle",type:Boolean})],GlideCoreInput.prototype,"passwordToggle",void 0),__decorate([property({reflect:!0,type:Boolean})],GlideCoreInput.prototype,"required",void 0),__decorate([property({type:Boolean})],GlideCoreInput.prototype,"readonly",void 0),__decorate([property({type:Boolean})],GlideCoreInput.prototype,"disabled",void 0),__decorate([property()],GlideCoreInput.prototype,"privateSplit",void 0),__decorate([property({type:Number,converter:t=>t&&Number.parseInt(t,10)})],GlideCoreInput.prototype,"maxlength",void 0),__decorate([queryAssignedNodes({slot:"description"})],GlideCoreInput.prototype,"descriptionNodes",void 0),__decorate([queryAssignedNodes({slot:"prefix"})],GlideCoreInput.prototype,"prefixIconNodes",void 0),__decorate([queryAssignedNodes({slot:"suffix"})],GlideCoreInput.prototype,"suffixIconNodes",void 0),__decorate([state()],GlideCoreInput.prototype,"hasFocus",void 0),__decorate([state()],GlideCoreInput.prototype,"isBlurring",void 0),__decorate([state()],GlideCoreInput.prototype,"isCheckingValidity",void 0),__decorate([state()],GlideCoreInput.prototype,"isReportValidityOrSubmit",void 0),__decorate([state()],GlideCoreInput.prototype,"passwordVisible",void 0),GlideCoreInput=__decorate([customElement("glide-core-input")],GlideCoreInput);export default GlideCoreInput;
1
+ var __decorate=this&&this.__decorate||function(e,t,i,o){var r,s=arguments.length,a=s<3?t:null===o?o=Object.getOwnPropertyDescriptor(t,i):o;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)a=Reflect.decorate(e,t,i,o);else for(var l=e.length-1;l>=0;l--)(r=e[l])&&(a=(s<3?r(a):s>3?r(t,i,a):r(t,i))||a);return s>3&&a&&Object.defineProperty(t,i,a),a};import"./icon-button.js";import"./label.js";import{LitElement,html,nothing}from"lit";import{LocalizeController}from"./library/localize.js";import{classMap}from"lit/directives/class-map.js";import{createRef,ref}from"lit/directives/ref.js";import{customElement,property,state}from"lit/decorators.js";import{ifDefined}from"lit/directives/if-defined.js";import magnifyingGlassIcon from"./icons/magnifying-glass.js";import ow from"./library/ow.js";import styles from"./input.styles.js";export const SUPPORTED_TYPES=["email","number","password","search","tel","text","url"];let GlideCoreInput=class GlideCoreInput extends LitElement{static{this.formAssociated=!0}static{this.shadowRootOptions={...LitElement.shadowRootOptions,mode:"closed",delegatesFocus:!0}}static{this.styles=styles}get form(){return this.#e.form}get validity(){return!this.required||this.value||this.disabled?this.#t?this.#e.setValidity({tooLong:!0}," ",this.#i.value):this.#e.setValidity({}):this.#e.setValidity({valueMissing:!0}," ",this.#i.value),this.#e.validity}get willValidate(){return this.#e.willValidate}blur(){this.#i.value?.blur()}checkValidity(){this.isCheckingValidity=!0;const e=this.#e.checkValidity();return this.isCheckingValidity=!1,e}disconnectedCallback(){super.disconnectedCallback(),this.form?.removeEventListener("formdata",this.#o)}formAssociatedCallback(){this.form?.addEventListener("formdata",this.#o)}formResetCallback(){this.value=this.getAttribute("value")??""}get hasClearIcon(){return this.clearable&&!this.disabled&&!this.readonly}get isClearIconVisible(){return this.hasClearIcon&&this.value.length>0}render(){return html`<glide-core-private-label class="${classMap({left:"left"===this.privateSplit,middle:"middle"===this.privateSplit})}" orientation="${this.orientation}" split="${ifDefined(this.privateSplit??void 0)}" ?disabled="${this.disabled}" ?error="${this.#r||this.#t}" ?hide="${this.hideLabel}" ?required="${this.required}"><slot name="tooltip" slot="tooltip"></slot><label for="input">${this.label}</label><div class="${classMap({"input-container":!0,focused:this.hasFocus,empty:""===this.value,disabled:this.disabled,readonly:this.readonly&&!this.disabled,error:this.#r||this.#t})}" slot="control"><slot name="prefix"></slot><input aria-describedby="meta" aria-invalid="${this.#r||this.#t}" id="input" type="${"password"===this.type&&this.passwordVisible?"text":this.type}" .value="${this.value}" placeholder="${ifDefined(this.placeholder)}" autocapitalize="${ifDefined(this.autocapitalize)}" spellcheck="${this.spellcheck}" ?required="${this.required}" ?readonly="${this.readonly}" ?disabled="${this.disabled}" @focus="${this.#s}" @blur="${this.#a}" @change="${this.#l}" @input="${this.#n}" ${ref(this.#i)}> ${this.hasClearIcon?html`<glide-core-icon-button variant="tertiary" class="${classMap({"clear-icon-button":!0,"clear-icon-button--visible":this.isClearIconVisible})}" data-test="clear-button" label="${this.#d.term("clearEntry",this.label)}" @click="${this.#h}"><svg aria-hidden="true" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor"><path d="M6 6L18 18" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/><path d="M18 6L6 18" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg></glide-core-icon-button>`:nothing} ${"password"===this.type&&this.passwordToggle&&!this.disabled?html`<glide-core-icon-button variant="tertiary" class="password-toggle" data-test="password-toggle" label="${this.passwordVisible?"Hide password":"Show password"}" aria-controls="input" aria-expanded="${this.passwordVisible?"true":"false"}" @click="${this.#p}">${this.passwordVisible?html`<svg aria-hidden="true" width="16" height="16" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" d="M3.98 8.223A10.477 10.477 0 0 0 1.934 12C3.226 16.338 7.244 19.5 12 19.5c.993 0 1.953-.138 2.863-.395M6.228 6.228A10.451 10.451 0 0 1 12 4.5c4.756 0 8.773 3.162 10.065 7.498a10.522 10.522 0 0 1-4.293 5.774M6.228 6.228 3 3m3.228 3.228 3.65 3.65m7.894 7.894L21 21m-3.228-3.228-3.65-3.65m0 0a3 3 0 1 0-4.243-4.243m4.242 4.242L9.88 9.88"/></svg>`:html`<svg aria-hidden="true" width="16" height="16" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" d="M2.036 12.322a1.012 1.012 0 0 1 0-.639C3.423 7.51 7.36 4.5 12 4.5c4.638 0 8.573 3.007 9.963 7.178.07.207.07.431 0 .639C20.577 16.49 16.64 19.5 12 19.5c-4.638 0-8.573-3.007-9.963-7.178Z"/><path stroke-linecap="round" stroke-linejoin="round" d="M15 12a3 3 0 1 1-6 0 3 3 0 0 1 6 0Z"/></svg>`}</glide-core-icon-button>`:nothing}<div class="suffix">${"search"===this.type?magnifyingGlassIcon:html`<slot name="suffix"></slot>`}</div></div><div class="meta" id="meta" slot="description"><slot class="description" name="description"></slot>${this.maxlength?html`<div class="${classMap({"character-count":!0,error:this.#t})}" data-test="character-count-container"><span aria-hidden="true" data-test="character-count-text">${this.#d.term("displayedCharacterCount",this.#c,this.maxlength)} </span><span class="hidden" data-test="character-count-announcement">${this.#d.term("announcedCharacterCount",this.#c,this.maxlength)}</span></div>`:nothing}</div></glide-core-private-label>`}reportValidity(){this.isReportValidityOrSubmit=!0;const e=this.#e.reportValidity();return this.requestUpdate(),e}constructor(){super(),this.type="text",this.value="",this.hideLabel=!1,this.orientation="horizontal",this.clearable=!1,this.spellcheck=!1,this.autocapitalize="on",this.passwordToggle=!1,this.required=!1,this.readonly=!1,this.disabled=!1,this.hasFocus=!1,this.isBlurring=!1,this.isCheckingValidity=!1,this.isReportValidityOrSubmit=!1,this.passwordVisible=!1,this.#i=createRef(),this.#d=new LocalizeController(this),this.#o=({formData:e})=>{this.name&&this.value&&!this.disabled&&e.append(this.name,this.value)},this.#e=this.attachInternals(),this.addEventListener("invalid",(e=>{if(e?.preventDefault(),this.isCheckingValidity||this.isBlurring)return;this.isReportValidityOrSubmit=!0;this.form?.querySelector(":invalid")===this&&this.focus()}))}#i;#e;#d;get#c(){return this.value.length}#o;get#t(){return Boolean(!this.disabled&&!this.readonly&&this.maxlength&&this.#c>this.maxlength)}get#r(){return!this.disabled&&!this.validity?.valid&&this.isReportValidityOrSubmit}#a(){this.isBlurring=!0,this.reportValidity(),this.isBlurring=!1,this.hasFocus=!1}#l(e){ow(this.#i.value,ow.object.instanceOf(HTMLInputElement)),this.value=this.#i.value?.value,this.dispatchEvent(new Event(e.type,e))}#h(e){this.value="",this.dispatchEvent(new Event("clear",{bubbles:!0})),this.#i.value?.focus(),e.stopPropagation()}#s(){this.hasFocus=!0}#n(){ow(this.#i.value,ow.object.instanceOf(HTMLInputElement)),this.value=this.#i.value.value}#p(){this.passwordVisible=!this.passwordVisible}};__decorate([property()],GlideCoreInput.prototype,"type",void 0),__decorate([property({reflect:!0})],GlideCoreInput.prototype,"name",void 0),__decorate([property()],GlideCoreInput.prototype,"value",void 0),__decorate([property()],GlideCoreInput.prototype,"label",void 0),__decorate([property({attribute:"hide-label",type:Boolean})],GlideCoreInput.prototype,"hideLabel",void 0),__decorate([property({reflect:!0})],GlideCoreInput.prototype,"orientation",void 0),__decorate([property()],GlideCoreInput.prototype,"placeholder",void 0),__decorate([property({type:Boolean})],GlideCoreInput.prototype,"clearable",void 0),__decorate([property({type:Boolean})],GlideCoreInput.prototype,"spellcheck",void 0),__decorate([property()],GlideCoreInput.prototype,"autocapitalize",void 0),__decorate([property({attribute:"password-toggle",type:Boolean})],GlideCoreInput.prototype,"passwordToggle",void 0),__decorate([property({reflect:!0,type:Boolean})],GlideCoreInput.prototype,"required",void 0),__decorate([property({type:Boolean})],GlideCoreInput.prototype,"readonly",void 0),__decorate([property({type:Boolean})],GlideCoreInput.prototype,"disabled",void 0),__decorate([property()],GlideCoreInput.prototype,"privateSplit",void 0),__decorate([property({type:Number,converter:e=>e&&Number.parseInt(e,10)})],GlideCoreInput.prototype,"maxlength",void 0),__decorate([state()],GlideCoreInput.prototype,"hasFocus",void 0),__decorate([state()],GlideCoreInput.prototype,"isBlurring",void 0),__decorate([state()],GlideCoreInput.prototype,"isCheckingValidity",void 0),__decorate([state()],GlideCoreInput.prototype,"isReportValidityOrSubmit",void 0),__decorate([state()],GlideCoreInput.prototype,"passwordVisible",void 0),GlideCoreInput=__decorate([customElement("glide-core-input")],GlideCoreInput);export default GlideCoreInput;
@@ -1,4 +1,4 @@
1
- import{css}from"lit";export default css`
1
+ import{css}from"lit";import visuallyHidden from"./styles/visually-hidden.js";export default css`
2
2
  .meta {
3
3
  column-gap: var(--glide-core-spacing-xs);
4
4
  display: flex;
@@ -15,6 +15,10 @@ import{css}from"lit";export default css`
15
15
  &.error {
16
16
  font-weight: var(--glide-core-font-weight-bold);
17
17
  }
18
+
19
+ .hidden {
20
+ ${visuallyHidden};
21
+ }
18
22
  }
19
23
 
20
24
  .search-icon {
@@ -22,7 +26,7 @@ import{css}from"lit";export default css`
22
26
  display: flex;
23
27
  }
24
28
 
25
- .input-box {
29
+ .input-container {
26
30
  align-items: center;
27
31
  background-color: var(--glide-core-surface-base-lighter);
28
32
  block-size: 2.125rem;
@@ -41,6 +45,7 @@ import{css}from"lit";export default css`
41
45
 
42
46
  &.focused:not(.error) {
43
47
  border-color: var(--glide-core-border-focus);
48
+ transition: border-color 200ms ease-in-out;
44
49
  }
45
50
 
46
51
  /* We had to resort to a class selector because there may be a bug in Chrome and Safari
@@ -54,7 +54,7 @@ it('changes to type text when password is revealed', async () => {
54
54
  const inputElement = element.shadowRoot?.querySelector('input');
55
55
  expect(inputElement).to.exist;
56
56
  expect(inputElement?.getAttribute('type')).to.equal('password');
57
- const passwordToggle = element.shadowRoot?.querySelector('.password-toggle');
57
+ const passwordToggle = element.shadowRoot?.querySelector('[data-test="password-toggle"]');
58
58
  passwordToggle?.click();
59
59
  await element.updateComplete;
60
60
  expect(inputElement?.getAttribute('type')).to.equal('text');
@@ -66,7 +66,7 @@ it('shows search icon with type search', async () => {
66
66
  const inputElement = element.shadowRoot?.querySelector('input');
67
67
  expect(inputElement).to.exist;
68
68
  expect(inputElement?.getAttribute('type')).to.equal('search');
69
- const searchIcon = element.shadowRoot?.querySelector('.search-icon');
69
+ const searchIcon = element.shadowRoot?.querySelector('[data-test="search-icon"]');
70
70
  expect(searchIcon).to.exist;
71
71
  });
72
72
  it('when using "focus() on input", the native input is focused', async () => {
@@ -100,7 +100,7 @@ it('clearable attribute allows for a button which can clear input', async () =>
100
100
  const element = await fixture(html `
101
101
  <glide-core-input label="Test" clearable></glide-core-input>
102
102
  `);
103
- const clearButton = element.shadowRoot?.querySelector('.clear-icon-button');
103
+ const clearButton = element.shadowRoot?.querySelector('[data-test="clear-button"]');
104
104
  element.focus();
105
105
  await sendKeys({ type: 'testing' });
106
106
  expect(element.value).to.be.equal('testing');
@@ -119,8 +119,22 @@ it('displays a max character and current character count if maxlength is provide
119
119
  const element = await fixture(html `
120
120
  <glide-core-input label="Test label" maxlength="5"></glide-core-input>
121
121
  `);
122
- const maxCharacterCountContainer = element.shadowRoot?.querySelector('.character-count');
123
- expect(maxCharacterCountContainer?.textContent?.trim()).to.be.equal('0/5');
122
+ const maxCharacterCountText = element.shadowRoot?.querySelector('[data-test="character-count-text"]');
123
+ expect(maxCharacterCountText?.textContent?.trim()).to.equal('0/5');
124
+ });
125
+ it('displays visually hidden character count text for screenreaders', async () => {
126
+ const element = await fixture(html `
127
+ <glide-core-input label="Test label" maxlength="5"></glide-core-input>
128
+ `);
129
+ const maxCharacterCountAnnouncement = element.shadowRoot?.querySelector('[data-test="character-count-announcement"]');
130
+ expect(maxCharacterCountAnnouncement?.textContent?.trim()).to.equal('Character count 0 of 5');
131
+ });
132
+ it('does not render a character count when attribute `maxlength` is set less than than zero', async () => {
133
+ const element = await fixture(html `
134
+ <glide-core-input label="Test label" maxlength="0"></glide-core-input>
135
+ `);
136
+ const container = element.shadowRoot?.querySelector('[data-test="character-count-container"]');
137
+ expect(container).to.be.null;
124
138
  });
125
139
  it('supports a "tooltip" slot', async () => {
126
140
  const component = await fixture(html `<glide-core-input label="test">
@@ -65,7 +65,7 @@ it('does not dispatch an "invalid" event after `checkValidity` is called when no
65
65
  input.addEventListener('invalid', spy);
66
66
  input.checkValidity();
67
67
  await aTimeout(0);
68
- expect(spy.notCalled).to.be.true;
68
+ expect(spy.callCount).to.equal(0);
69
69
  });
70
70
  it('does not dispatch an "invalid" event after `checkValidity` is called when required and no value but disabled', async () => {
71
71
  const form = document.createElement('form');
@@ -74,7 +74,7 @@ it('does not dispatch an "invalid" event after `checkValidity` is called when re
74
74
  input.addEventListener('invalid', spy);
75
75
  input.checkValidity();
76
76
  await aTimeout(0);
77
- expect(spy.notCalled).to.be.true;
77
+ expect(spy.callCount).to.equal(0);
78
78
  });
79
79
  it('does not dispatch an "invalid" event when `reportValidity` is called when not required,', async () => {
80
80
  const form = document.createElement('form');
@@ -85,7 +85,7 @@ it('does not dispatch an "invalid" event when `reportValidity` is called when no
85
85
  input.addEventListener('invalid', spy);
86
86
  input.reportValidity();
87
87
  await aTimeout(0);
88
- expect(spy.notCalled).to.be.true;
88
+ expect(spy.callCount).to.equal(0);
89
89
  });
90
90
  it('does not dispatch an "invalid" event when `reportValidity` is called when required and no value but disabled', async () => {
91
91
  const form = document.createElement('form');
@@ -94,5 +94,5 @@ it('does not dispatch an "invalid" event when `reportValidity` is called when re
94
94
  input.addEventListener('invalid', spy);
95
95
  input.reportValidity();
96
96
  await aTimeout(0);
97
- expect(spy.notCalled).to.be.true;
97
+ expect(spy.callCount).to.equal(0);
98
98
  });
@@ -1,9 +1,9 @@
1
1
  /* eslint-disable @typescript-eslint/no-unused-expressions */
2
2
  import './input.js';
3
3
  import { expect, fixture, html } from '@open-wc/testing';
4
- import Input from './input.js';
5
- Input.shadowRootOptions.mode = 'open';
6
- it('focuses the input when `focus` is called', async () => {
4
+ import GlideCoreInput from './input.js';
5
+ GlideCoreInput.shadowRootOptions.mode = 'open';
6
+ it('focuses the input when `focus()` is called', async () => {
7
7
  const input = await fixture(html `<glide-core-input required></glide-core-input>`);
8
8
  input.focus();
9
9
  const inputElement = input.shadowRoot?.querySelector('input');
@@ -27,7 +27,7 @@ it('blurs the input and reports validity if `blur` is called', async () => {
27
27
  await input.updateComplete;
28
28
  expect(input.shadowRoot?.activeElement).to.equal(null);
29
29
  expect(input.validity.valid).to.equal(false);
30
- expect(input.shadowRoot?.querySelector('glide-core-label')?.error).to.equal(true);
30
+ expect(input.shadowRoot?.querySelector('glide-core-private-label')?.error).to.equal(true);
31
31
  });
32
32
  it('focuses the input after `reportValidity` is called when required and no value', async () => {
33
33
  const form = document.createElement('form');
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,38 @@
1
+ /* eslint-disable @typescript-eslint/no-unused-expressions */
2
+ import { elementUpdated, expect, fixture, html } from '@open-wc/testing';
3
+ import GlideCoreInput from './input.js';
4
+ GlideCoreInput.shadowRootOptions.mode = 'open';
5
+ it('renders dynamic strings in Japanese', async () => {
6
+ const element = await fixture(html `
7
+ <glide-core-input
8
+ label="Test"
9
+ value="lorem"
10
+ maxlength="40"
11
+ clearable
12
+ ></glide-core-input>
13
+ `);
14
+ document.documentElement.setAttribute('lang', 'ja');
15
+ await elementUpdated(element);
16
+ const maxCharacterCountText = element.shadowRoot?.querySelector('[data-test="character-count-text"]');
17
+ expect(maxCharacterCountText?.textContent?.trim()).to.equal('5/40');
18
+ const maxCharacterCountAnnouncement = element.shadowRoot?.querySelector('[data-test="character-count-announcement"]');
19
+ expect(maxCharacterCountAnnouncement?.textContent?.trim()).to.equal('Character count 5 of 40');
20
+ expect(element.shadowRoot?.querySelector('[data-test="clear-button"]')?.label).to.equal('Clear Test entry');
21
+ });
22
+ it('renders dynamic strings in French', async () => {
23
+ const element = await fixture(html `
24
+ <glide-core-input
25
+ label="Test"
26
+ value="lorem"
27
+ maxlength="40"
28
+ clearable
29
+ ></glide-core-input>
30
+ `);
31
+ document.documentElement.setAttribute('lang', 'fr');
32
+ await elementUpdated(element);
33
+ const maxCharacterCountText = element.shadowRoot?.querySelector('[data-test="character-count-text"]');
34
+ expect(maxCharacterCountText?.textContent?.trim()).to.equal('5/40');
35
+ const maxCharacterCountAnnouncement = element.shadowRoot?.querySelector('[data-test="character-count-announcement"]');
36
+ expect(maxCharacterCountAnnouncement?.textContent?.trim()).to.equal('Character count 5 of 40');
37
+ expect(element.shadowRoot?.querySelector('[data-test="clear-button"]')?.label).to.equal('Clear Test entry');
38
+ });