@crowdstrike/glide-core 0.12.3 → 0.13.1

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 (47) hide show
  1. package/dist/accordion.d.ts +1 -1
  2. package/dist/accordion.styles.js +2 -1
  3. package/dist/button-group.js +1 -1
  4. package/dist/button-group.stories.d.ts +0 -1
  5. package/dist/button-group.test.events.js +2 -0
  6. package/dist/checkbox.styles.js +6 -3
  7. package/dist/drawer.js +1 -1
  8. package/dist/dropdown.d.ts +5 -1
  9. package/dist/dropdown.js +65 -51
  10. package/dist/dropdown.option.d.ts +1 -1
  11. package/dist/dropdown.option.js +1 -1
  12. package/dist/dropdown.option.styles.js +36 -6
  13. package/dist/dropdown.option.test.interactions.single.js +2 -2
  14. package/dist/dropdown.styles.js +39 -35
  15. package/dist/dropdown.test.basics.filterable.js +8 -3
  16. package/dist/dropdown.test.events.filterable.js +1 -13
  17. package/dist/dropdown.test.focus.js +1 -1
  18. package/dist/dropdown.test.focus.single.js +1 -17
  19. package/dist/dropdown.test.interactions.filterable.js +84 -0
  20. package/dist/dropdown.test.interactions.js +25 -25
  21. package/dist/input.d.ts +1 -1
  22. package/dist/input.js +2 -1
  23. package/dist/input.styles.js +48 -30
  24. package/dist/library/localize.d.ts +2 -0
  25. package/dist/menu.js +1 -1
  26. package/dist/menu.stories.d.ts +1 -0
  27. package/dist/menu.styles.js +1 -1
  28. package/dist/menu.test.interactions.js +1 -1
  29. package/dist/modal.d.ts +1 -1
  30. package/dist/modal.js +1 -1
  31. package/dist/radio-group.stories.d.ts +0 -1
  32. package/dist/styles/variables.css +1 -1
  33. package/dist/tab.group.d.ts +0 -1
  34. package/dist/tab.group.js +1 -1
  35. package/dist/tab.group.styles.js +5 -7
  36. package/dist/tabs.stories.d.ts +0 -1
  37. package/dist/tag.js +1 -1
  38. package/dist/tag.styles.js +5 -3
  39. package/dist/tag.test.interactions.js +8 -8
  40. package/dist/textarea.styles.js +4 -0
  41. package/dist/translations/en.js +1 -1
  42. package/dist/translations/fr.d.ts +1 -1
  43. package/dist/translations/fr.js +1 -1
  44. package/dist/translations/ja.d.ts +1 -1
  45. package/dist/translations/ja.js +1 -1
  46. package/dist/tree.stories.d.ts +0 -1
  47. package/package.json +19 -19
@@ -1,6 +1,7 @@
1
1
  import{css}from"lit";import focusOutline from"./styles/focus-outline.js";import opacityAndScaleAnimation from"./styles/opacity-and-scale-animation.js";import visuallyHidden from"./styles/visually-hidden.js";export default[css`
2
2
  ${focusOutline(".add-button:focus-visible")}
3
3
  ${opacityAndScaleAnimation(".options-and-footer:popover-open")}
4
+ ${visuallyHidden(".item-count")}
4
5
  ${visuallyHidden(".selected-option-labels")}
5
6
  `,css`
6
7
  .component {
@@ -16,11 +17,11 @@ import{css}from"lit";import focusOutline from"./styles/focus-outline.js";import
16
17
 
17
18
  glide-core-private-label {
18
19
  &::part(private-control-and-summary) {
19
- /*
20
- The Label component's grid column styling combined with the fact that
21
- ".dropdown-and-options" isn't a direct descendant of that grid means that
22
- Dropdown's label won't shrink when space constrained without a minimum
23
- width on Label's ".control-and-summary". It's not clear to me why Grid
20
+ /*
21
+ The Label component's grid column styling combined with the fact that
22
+ ".dropdown-and-options" isn't a direct descendant of that grid means that
23
+ Dropdown's label won't shrink when space constrained without a minimum
24
+ width on Label's ".control-and-summary". It's not clear to me why Grid
24
25
  behaves this way.
25
26
  */
26
27
  min-inline-size: var(--min-inline-size);
@@ -60,7 +61,7 @@ import{css}from"lit";import focusOutline from"./styles/focus-outline.js";import
60
61
  column-gap: var(--glide-core-spacing-xxs);
61
62
  min-inline-size: 3.75rem;
62
63
  padding-block: 0;
63
- padding-inline: 0.375rem;
64
+ padding-inline: var(--glide-core-spacing-sm);
64
65
  }
65
66
 
66
67
  &.disabled {
@@ -91,6 +92,7 @@ import{css}from"lit";import focusOutline from"./styles/focus-outline.js";import
91
92
 
92
93
  &:is(
93
94
  :hover,
95
+ :has(.primary-button:hover),
94
96
  :has(.primary-button:focus-visible, .input:focus-visible)
95
97
  ):not(&.disabled, &.error, &.quiet, &.readonly) {
96
98
  border-color: var(--glide-core-border-focus);
@@ -114,22 +116,15 @@ import{css}from"lit";import focusOutline from"./styles/focus-outline.js";import
114
116
  min-inline-size: var(--min-inline-size);
115
117
  padding: 0;
116
118
  position: absolute;
117
-
118
- &.hidden {
119
- display: none;
120
- }
121
119
  }
122
120
 
123
121
  .options {
124
- --padding: var(--glide-core-spacing-xxxs);
125
-
126
122
  box-sizing: border-box;
127
123
  max-block-size: calc(
128
- var(--private-option-height) * 9 + var(--padding) * 2 +
124
+ var(--private-option-height) * 9 + var(--glide-core-spacing-xxxs) * 2 +
129
125
  var(--border-width) * 2
130
126
  );
131
127
  overflow: auto;
132
- padding: var(--padding);
133
128
  scroll-behavior: smooth;
134
129
 
135
130
  &.large {
@@ -139,20 +134,26 @@ import{css}from"lit";import focusOutline from"./styles/focus-outline.js";import
139
134
  &.small {
140
135
  --private-option-height: 1.25rem;
141
136
  }
137
+
138
+ &.hidden {
139
+ display: none;
140
+ }
141
+ }
142
+
143
+ .options-slot {
144
+ display: block;
145
+ padding: var(--glide-core-spacing-xxxs);
142
146
  }
143
147
 
144
148
  .footer {
145
- background-color: var(--glide-core-surface-page);
146
149
  border-block-start: 1px solid var(--glide-core-border-base);
147
- box-shadow: 0 -8px 8px -8px
148
- var(--glide-core-surface-base-gray, rgb(0 0 0 / 40%));
149
150
  display: none;
150
151
  inline-size: calc(100% - var(--glide-core-spacing-xxxs) * 2);
151
152
  inset-block-end: 0;
152
153
  padding: var(--glide-core-spacing-xxxs);
153
154
 
154
- /*
155
- "sticky" is a little hack so that footer is absolutely positioned but
155
+ /*
156
+ "sticky" is a little hack so that footer is absolutely positioned but
156
157
  its space in layout is preserved, so it doesn't overlap the last option.
157
158
  */
158
159
  position: sticky;
@@ -207,32 +208,31 @@ import{css}from"lit";import focusOutline from"./styles/focus-outline.js";import
207
208
  }
208
209
 
209
210
  .select-all {
210
- border-block-end: 1px solid var(--glide-core-border-base-light);
211
- margin-block-end: var(--glide-core-spacing-xxxs);
212
- padding-block-end: var(--glide-core-spacing-xxxs);
211
+ border-block-end: 1px solid var(--glide-core-border-base);
212
+ padding: var(--glide-core-spacing-xxxs);
213
213
 
214
214
  &:not([hidden]) {
215
215
  display: block;
216
216
  }
217
217
  }
218
218
 
219
+ .no-results {
220
+ font-family: var(--glide-core-body-sm-font-family);
221
+ font-size: var(--glide-core-body-sm-font-size);
222
+ font-weight: var(--glide-core-body-sm-font-weight);
223
+ line-height: var(--glide-core-body-sm-line-height);
224
+ padding: 0.625rem 0.875rem;
225
+ text-transform: capitalize;
226
+ }
227
+
219
228
  .placeholder {
220
- /*
221
- Using the browser's default placeholder color for now, as
222
- '--glide-core-text-placeholder' has dark mode issues. Aligns
223
- with Input and Textarea as suggested by design.
224
- */
225
- color: rgb(117 117 117);
229
+ color: var(--glide-core-text-placeholder);
226
230
 
227
231
  &.quiet {
228
232
  &:not(.disabled) {
229
233
  color: var(--glide-core-text-body-1);
230
234
  }
231
235
  }
232
-
233
- &.disabled {
234
- color: var(--glide-core-text-tertiary-disabled);
235
- }
236
236
  }
237
237
 
238
238
  .tags {
@@ -261,6 +261,7 @@ import{css}from"lit";import focusOutline from"./styles/focus-outline.js";import
261
261
  align-content: center;
262
262
  color: var(--glide-core-text-link);
263
263
  margin-inline-end: var(--glide-core-spacing-md);
264
+ white-space: nowrap;
264
265
  }
265
266
 
266
267
  .single-select-icon-slot {
@@ -326,19 +327,22 @@ import{css}from"lit";import focusOutline from"./styles/focus-outline.js";import
326
327
  font-family: var(--glide-core-font-sans);
327
328
  font-size: inherit;
328
329
  min-inline-size: var(--min-inline-size);
330
+ padding-inline: 0;
329
331
 
330
- /*
332
+ &:not(.quiet) {
333
+ /*
331
334
  2px so the value is vertically aligned. "vertical-align: middle" has no
332
335
  effect flex children.
333
336
  */
334
- padding-block: 0.125rem 0;
335
- padding-inline: 0;
337
+ padding-block: 0.125rem 0;
338
+ }
336
339
 
337
340
  &:focus {
338
341
  outline: none;
339
342
  }
340
343
 
341
344
  &::placeholder {
345
+ color: var(--glide-core-text-placeholder);
342
346
  font-family: var(--glide-core-font-sans);
343
347
  }
344
348
  }
@@ -21,9 +21,14 @@ it('is accessible', async () => {
21
21
  ${defaultSlot}
22
22
  </glide-core-dropdown>`);
23
23
  await expect(component).to.be.accessible({
24
- // Axe doesn't search within slots when determining whether an element
25
- // has an ID that matches `aria-activedescendant` exists.
26
- ignoredRules: ['aria-valid-attr-value'],
24
+ ignoredRules: [
25
+ // Axe doesn't like that our item count element doesn't have a `role`. Yet
26
+ // it does label `<input>` and is announced correctly, at least by VoiceOver.
27
+ 'aria-prohibited-attr',
28
+ // Axe doesn't search within slots when determining whether an element
29
+ // has an ID that matches `aria-activedescendant` exists.
30
+ 'aria-valid-attr-value',
31
+ ],
27
32
  });
28
33
  });
29
34
  it('is filterable', async () => {
@@ -1,6 +1,6 @@
1
1
  /* eslint-disable @typescript-eslint/no-unused-expressions */
2
2
  import * as sinon from 'sinon';
3
- import { expect, fixture, html, oneEvent } from '@open-wc/testing';
3
+ import { 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';
@@ -19,18 +19,6 @@ const defaultSlot = html `
19
19
  <glide-core-dropdown-option label="Ten"></glide-core-dropdown-option>
20
20
  <glide-core-dropdown-option label="Eleven"></glide-core-dropdown-option>
21
21
  `;
22
- it('dispatches a "filter" event on "input"', async () => {
23
- const component = await fixture(html `<glide-core-dropdown label="Label" placeholder="Placeholder">
24
- ${defaultSlot}
25
- </glide-core-dropdown>`);
26
- component.focus();
27
- sendKeys({ type: 'o' });
28
- const event = await oneEvent(component, 'filter');
29
- expect(event instanceof CustomEvent).to.be.true;
30
- expect(event.bubbles).to.be.true;
31
- expect(event.composed).to.be.true;
32
- expect(event.detail).to.equal('o');
33
- });
34
22
  it('does not dispatch "input" events on input', async () => {
35
23
  const component = await fixture(html `<glide-core-dropdown label="Label" placeholder="Placeholder">
36
24
  ${defaultSlot}
@@ -67,7 +67,7 @@ it('focuses the Add button on ArrowDown', async () => {
67
67
  expect(options[0]?.privateActive).to.be.false;
68
68
  expect(options[1]?.privateActive).to.be.false;
69
69
  expect(options[1]?.privateIsEditActive).to.be.false;
70
- expect(options[1]?.privateIsOpenTooltip).to.be.false;
70
+ expect(options[1]?.privateIsTooltipOpen).to.be.false;
71
71
  expect(component.shadowRoot?.activeElement).to.equal(addButton);
72
72
  });
73
73
  it('returns focus to itself on Escape when the Add button has focus', async () => {
@@ -1,6 +1,6 @@
1
1
  /* eslint-disable @typescript-eslint/no-unused-expressions */
2
2
  import './dropdown.option.js';
3
- import { aTimeout, elementUpdated, expect, fixture, html, } from '@open-wc/testing';
3
+ import { expect, fixture, html } from '@open-wc/testing';
4
4
  import GlideCoreDropdown from './dropdown.js';
5
5
  import GlideCoreDropdownOption from './dropdown.option.js';
6
6
  GlideCoreDropdown.shadowRootOptions.mode = 'open';
@@ -40,19 +40,3 @@ it('does not focus the primary button when `checkValidity` is called', async ()
40
40
  component.checkValidity();
41
41
  expect(component.shadowRoot?.activeElement).to.equal(null);
42
42
  });
43
- it('has a tooltip on focus when its internal label is overflowing', async () => {
44
- // The period is arbitrary. 500 of them ensures we overflow.
45
- const component = await fixture(html `<glide-core-dropdown label="Label" placeholder="Placeholder">
46
- <glide-core-dropdown-option
47
- label=${'.'.repeat(500)}
48
- selected
49
- ></glide-core-dropdown-option>
50
- </glide-core-dropdown>`);
51
- component.focus();
52
- await elementUpdated(component);
53
- // Wait for the Resize Observer to do its thing.
54
- await aTimeout(0);
55
- const tooltip = component.shadowRoot?.querySelector('[data-test="internal-label-tooltip"]');
56
- expect(tooltip?.open).to.be.true;
57
- expect(tooltip?.disabled).to.be.false;
58
- });
@@ -264,6 +264,34 @@ it('hides Select All when filtering', async () => {
264
264
  const selectAll = component.shadowRoot?.querySelector('[data-test="select-all"]');
265
265
  expect(selectAll?.checkVisibility()).to.not.be.ok;
266
266
  });
267
+ it('unhides every option after filtering when one is selected and Dropdown is reopened', async () => {
268
+ const component = await fixture(html `<glide-core-dropdown
269
+ label="Label"
270
+ placeholder="Placeholder"
271
+ open
272
+ filterable
273
+ >
274
+ <glide-core-dropdown-option
275
+ label="One"
276
+ selected
277
+ ></glide-core-dropdown-option>
278
+
279
+ <glide-core-dropdown-option label="Two"></glide-core-dropdown-option>
280
+ </glide-core-dropdown>`);
281
+ // Wait for it to open.
282
+ await aTimeout(0);
283
+ component.focus();
284
+ await sendKeys({ type: 'two' });
285
+ component.blur();
286
+ await elementUpdated(component);
287
+ component.open = true;
288
+ // Wait for it to open.
289
+ await aTimeout(0);
290
+ const options = [
291
+ ...component.querySelectorAll('glide-core-dropdown-option'),
292
+ ].filter(({ hidden }) => !hidden);
293
+ expect(options.length).to.equal(2);
294
+ });
267
295
  it('sets the first unfiltered option as active when the previously active option is filtered out', async () => {
268
296
  const component = await fixture(html `<glide-core-dropdown
269
297
  label="Label"
@@ -719,3 +747,59 @@ it('has no icon when filtering and an option is selected', async () => {
719
747
  const iconSlot = component.shadowRoot?.querySelector('[data-test="single-select-icon-slot"]');
720
748
  expect(iconSlot).to.be.null;
721
749
  });
750
+ it('supports custom filtering', async () => {
751
+ const component = await fixture(html `<glide-core-dropdown
752
+ label="Label"
753
+ placeholder="Placeholder"
754
+ filterable
755
+ >
756
+ <glide-core-dropdown-option label="One"></glide-core-dropdown-option>
757
+ <glide-core-dropdown-option label="Two"></glide-core-dropdown-option>
758
+ </glide-core-dropdown>`);
759
+ component.filter = async (filter) => {
760
+ const options = [
761
+ ...component.querySelectorAll('glide-core-dropdown-option'),
762
+ ];
763
+ return options.filter(({ label }) => label.includes(filter));
764
+ };
765
+ component.focus();
766
+ await sendKeys({ type: 'O' });
767
+ const options = [
768
+ ...component.querySelectorAll('glide-core-dropdown-option'),
769
+ ].filter(({ hidden }) => !hidden);
770
+ expect(options.length).to.equal(1);
771
+ expect(options[0].label).to.equal('One');
772
+ });
773
+ it('does nothing when filtering fails', async () => {
774
+ const component = await fixture(html `<glide-core-dropdown
775
+ label="Label"
776
+ placeholder="Placeholder"
777
+ filterable
778
+ >
779
+ <glide-core-dropdown-option label="One"></glide-core-dropdown-option>
780
+ <glide-core-dropdown-option label="Two"></glide-core-dropdown-option>
781
+ </glide-core-dropdown>`);
782
+ component.filter = () => {
783
+ return Promise.reject();
784
+ };
785
+ component.focus();
786
+ await sendKeys({ type: 'O' });
787
+ const options = [
788
+ ...component.querySelectorAll('glide-core-dropdown-option'),
789
+ ].filter(({ hidden }) => !hidden);
790
+ expect(options.length).to.equal(2);
791
+ });
792
+ it('updates its item count after filtering', async () => {
793
+ const component = await fixture(html `<glide-core-dropdown
794
+ label="Label"
795
+ placeholder="Placeholder"
796
+ filterable
797
+ >
798
+ <glide-core-dropdown-option label="One"></glide-core-dropdown-option>
799
+ <glide-core-dropdown-option label="Two"></glide-core-dropdown-option>
800
+ </glide-core-dropdown>`);
801
+ component.focus();
802
+ await sendKeys({ type: 'one' });
803
+ const itemCount = component.shadowRoot?.querySelector('[data-test="item-count"]');
804
+ expect(itemCount?.ariaLabel).to.equal('1 items');
805
+ });
@@ -135,7 +135,7 @@ it('does not open on Space when `readonly`', async () => {
135
135
  expect(component.open).to.be.false;
136
136
  expect(options?.checkVisibility()).to.be.false;
137
137
  });
138
- // See the `document` click listener comment in `dropdown.ts` for an explanation.
138
+ // See the `document` click handler comment in `dropdown.ts` for an explanation.
139
139
  it('opens when opened programmatically via the click handler of another element', async () => {
140
140
  const div = document.createElement('div');
141
141
  const component = await fixture(html `<glide-core-dropdown label="Label" placeholder="Placeholder">
@@ -297,7 +297,7 @@ it('activates the Edit button on ArrowDown', async () => {
297
297
  const options = component.querySelectorAll('glide-core-dropdown-option');
298
298
  expect(options[0]?.privateActive).to.be.true;
299
299
  expect(options[0]?.privateIsEditActive).true;
300
- expect(options[0]?.privateIsOpenTooltip).false;
300
+ expect(options[0]?.privateIsTooltipOpen).false;
301
301
  expect(options[1]?.privateActive).to.be.false;
302
302
  expect(options[1]?.privateIsEditActive).to.be.false;
303
303
  });
@@ -320,7 +320,7 @@ it('activates the next option on ArrowDown when the Edit button is active', asyn
320
320
  expect(options[0]?.privateIsEditActive).false;
321
321
  expect(options[1]?.privateActive).to.be.true;
322
322
  expect(options[1]?.privateIsEditActive).to.be.false;
323
- expect(options[1]?.privateIsOpenTooltip).true;
323
+ expect(options[1]?.privateIsTooltipOpen).true;
324
324
  });
325
325
  it('activates the previous option on ArrowUp', async () => {
326
326
  const component = await fixture(html `<glide-core-dropdown label="Label" placeholder="Placeholder" open>
@@ -359,10 +359,10 @@ it('activates the Edit button on on ArrowUp', async () => {
359
359
  const options = component.querySelectorAll('glide-core-dropdown-option');
360
360
  expect(options[0]?.privateActive).to.be.true;
361
361
  expect(options[0]?.privateIsEditActive).to.be.true;
362
- expect(options[0]?.privateIsOpenTooltip).false;
362
+ expect(options[0]?.privateIsTooltipOpen).false;
363
363
  expect(options[1]?.privateActive).to.be.false;
364
364
  expect(options[1]?.privateIsEditActive).to.be.false;
365
- expect(options[1]?.privateIsOpenTooltip).to.be.false;
365
+ expect(options[1]?.privateIsTooltipOpen).to.be.false;
366
366
  });
367
367
  it('activates previously active option on ArrowUp', async () => {
368
368
  const component = await fixture(html `<glide-core-dropdown
@@ -383,9 +383,9 @@ it('activates previously active option on ArrowUp', async () => {
383
383
  const options = component.querySelectorAll('glide-core-dropdown-option');
384
384
  expect(options[0]?.privateActive).to.be.false;
385
385
  expect(options[0]?.privateIsEditActive).to.be.false;
386
- expect(options[0]?.privateIsOpenTooltip).to.be.false;
386
+ expect(options[0]?.privateIsTooltipOpen).to.be.false;
387
387
  expect(options[1]?.privateActive).to.be.true;
388
- expect(options[1]?.privateIsOpenTooltip).to.be.true;
388
+ expect(options[1]?.privateIsTooltipOpen).to.be.true;
389
389
  expect(options[1]?.privateIsEditActive).to.be.false;
390
390
  });
391
391
  it('activates the Edit button on ArrowUp', async () => {
@@ -412,10 +412,10 @@ it('activates the Edit button on ArrowUp', async () => {
412
412
  const options = component.querySelectorAll('glide-core-dropdown-option');
413
413
  expect(options[0]?.privateActive).to.be.false;
414
414
  expect(options[0]?.privateIsEditActive).to.be.false;
415
- expect(options[0]?.privateIsOpenTooltip).to.be.false;
415
+ expect(options[0]?.privateIsTooltipOpen).to.be.false;
416
416
  expect(options[1]?.privateActive).to.be.true;
417
417
  expect(options[1]?.privateIsEditActive).to.be.true;
418
- expect(options[1]?.privateIsOpenTooltip).to.be.false;
418
+ expect(options[1]?.privateIsTooltipOpen).to.be.false;
419
419
  });
420
420
  it('activates the first option on Home', async () => {
421
421
  const component = await fixture(html `<glide-core-dropdown label="Label" placeholder="Placeholder" open>
@@ -430,10 +430,10 @@ it('activates the first option on Home', async () => {
430
430
  const options = component.querySelectorAll('glide-core-dropdown-option');
431
431
  expect(options[0]?.privateActive).to.be.true;
432
432
  expect(options[0]?.privateIsEditActive).to.be.false;
433
- expect(options[0]?.privateIsOpenTooltip).to.be.true;
433
+ expect(options[0]?.privateIsTooltipOpen).to.be.true;
434
434
  expect(options[1]?.privateActive).to.be.false;
435
435
  expect(options[1]?.privateIsEditActive).to.be.false;
436
- expect(options[1]?.privateIsOpenTooltip).to.be.false;
436
+ expect(options[1]?.privateIsTooltipOpen).to.be.false;
437
437
  });
438
438
  it('activates the first option on PageUp', async () => {
439
439
  const component = await fixture(html `<glide-core-dropdown label="Label" placeholder="Placeholder" open>
@@ -448,10 +448,10 @@ it('activates the first option on PageUp', async () => {
448
448
  const options = component.querySelectorAll('glide-core-dropdown-option');
449
449
  expect(options[0]?.privateActive).to.be.true;
450
450
  expect(options[0]?.privateIsEditActive).to.be.false;
451
- expect(options[0]?.privateIsOpenTooltip).to.be.true;
451
+ expect(options[0]?.privateIsTooltipOpen).to.be.true;
452
452
  expect(options[1]?.privateActive).to.be.false;
453
453
  expect(options[1]?.privateIsEditActive).to.be.false;
454
- expect(options[1]?.privateIsOpenTooltip).to.be.false;
454
+ expect(options[1]?.privateIsTooltipOpen).to.be.false;
455
455
  });
456
456
  it('activates the first option on ArrowUp + Meta', async () => {
457
457
  const component = await fixture(html `<glide-core-dropdown label="Label" placeholder="Placeholder" open>
@@ -468,10 +468,10 @@ it('activates the first option on ArrowUp + Meta', async () => {
468
468
  const options = component.querySelectorAll('glide-core-dropdown-option');
469
469
  expect(options[0]?.privateActive).to.be.true;
470
470
  expect(options[0]?.privateIsEditActive).to.be.false;
471
- expect(options[0]?.privateIsOpenTooltip).to.be.true;
471
+ expect(options[0]?.privateIsTooltipOpen).to.be.true;
472
472
  expect(options[1]?.privateActive).to.be.false;
473
473
  expect(options[1]?.privateIsEditActive).to.be.false;
474
- expect(options[1]?.privateIsOpenTooltip).to.be.false;
474
+ expect(options[1]?.privateIsTooltipOpen).to.be.false;
475
475
  });
476
476
  it('activates the last option on End', async () => {
477
477
  const component = await fixture(html `<glide-core-dropdown label="Label" placeholder="Placeholder" open>
@@ -485,10 +485,10 @@ it('activates the last option on End', async () => {
485
485
  const options = component.querySelectorAll('glide-core-dropdown-option');
486
486
  expect(options[0]?.privateActive).to.be.false;
487
487
  expect(options[0]?.privateIsEditActive).to.be.false;
488
- expect(options[0]?.privateIsOpenTooltip).to.be.false;
488
+ expect(options[0]?.privateIsTooltipOpen).to.be.false;
489
489
  expect(options[1]?.privateActive).to.be.true;
490
490
  expect(options[1]?.privateIsEditActive).to.be.false;
491
- expect(options[1]?.privateIsOpenTooltip).to.be.true;
491
+ expect(options[1]?.privateIsTooltipOpen).to.be.true;
492
492
  });
493
493
  it('activates the last option on PageDown', async () => {
494
494
  const component = await fixture(html `<glide-core-dropdown label="Label" placeholder="Placeholder" open>
@@ -502,10 +502,10 @@ it('activates the last option on PageDown', async () => {
502
502
  const options = component.querySelectorAll('glide-core-dropdown-option');
503
503
  expect(options[0]?.privateActive).to.be.false;
504
504
  expect(options[0]?.privateIsEditActive).to.be.false;
505
- expect(options[0]?.privateIsOpenTooltip).to.be.false;
505
+ expect(options[0]?.privateIsTooltipOpen).to.be.false;
506
506
  expect(options[1]?.privateActive).to.be.true;
507
507
  expect(options[1]?.privateIsEditActive).to.be.false;
508
- expect(options[1]?.privateIsOpenTooltip).to.be.true;
508
+ expect(options[1]?.privateIsTooltipOpen).to.be.true;
509
509
  });
510
510
  it('activates the last option on Meta + ArrowDown', async () => {
511
511
  const component = await fixture(html `<glide-core-dropdown label="Label" placeholder="Placeholder" open>
@@ -521,10 +521,10 @@ it('activates the last option on Meta + ArrowDown', async () => {
521
521
  const options = component.querySelectorAll('glide-core-dropdown-option');
522
522
  expect(options[0]?.privateActive).to.be.false;
523
523
  expect(options[0]?.privateIsEditActive).to.be.false;
524
- expect(options[0]?.privateIsOpenTooltip).to.be.false;
524
+ expect(options[0]?.privateIsTooltipOpen).to.be.false;
525
525
  expect(options[1]?.privateActive).to.be.true;
526
526
  expect(options[1]?.privateIsEditActive).to.be.false;
527
- expect(options[1]?.privateIsOpenTooltip).to.be.true;
527
+ expect(options[1]?.privateIsTooltipOpen).to.be.true;
528
528
  });
529
529
  it('activates the previously active option when tabbing back from the Add button', async () => {
530
530
  const component = await fixture(html `<glide-core-dropdown
@@ -548,13 +548,13 @@ it('activates the previously active option when tabbing back from the Add button
548
548
  const options = component.querySelectorAll('glide-core-dropdown-option');
549
549
  expect(options[0]?.privateActive).to.be.false;
550
550
  expect(options[0]?.privateIsEditActive).to.be.false;
551
- expect(options[0]?.privateIsOpenTooltip).to.be.false;
551
+ expect(options[0]?.privateIsTooltipOpen).to.be.false;
552
552
  expect(options[1]?.privateActive).to.be.true;
553
553
  expect(options[1]?.privateIsEditActive).to.be.false;
554
- expect(options[1]?.privateIsOpenTooltip).to.be.true;
554
+ expect(options[1]?.privateIsTooltipOpen).to.be.true;
555
555
  expect(options[2]?.privateActive).to.be.false;
556
556
  expect(options[2]?.privateIsEditActive).to.be.false;
557
- expect(options[2]?.privateIsOpenTooltip).to.be.false;
557
+ expect(options[2]?.privateIsTooltipOpen).to.be.false;
558
558
  });
559
559
  it('deactivates the active option when the Add button is tabbed to', async () => {
560
560
  const component = await fixture(html `<glide-core-dropdown
@@ -574,7 +574,7 @@ it('deactivates the active option when the Add button is tabbed to', async () =>
574
574
  const options = component.querySelectorAll('glide-core-dropdown-option');
575
575
  expect(options[0]?.privateActive).to.be.false;
576
576
  expect(options[0]?.privateIsEditActive).to.be.false;
577
- expect(options[0]?.privateIsOpenTooltip).to.be.false;
577
+ expect(options[0]?.privateIsTooltipOpen).to.be.false;
578
578
  expect(options[1]?.privateActive).to.be.false;
579
579
  });
580
580
  it('does not wrap on ArrowUp', async () => {
package/dist/input.d.ts CHANGED
@@ -6,7 +6,7 @@ declare global {
6
6
  'glide-core-input': GlideCoreInput;
7
7
  }
8
8
  }
9
- export declare const SUPPORTED_TYPES: readonly ["email", "number", "password", "search", "tel", "text", "url"];
9
+ export declare const SUPPORTED_TYPES: readonly ["date", "email", "number", "password", "search", "tel", "text", "url"];
10
10
  type SupportedTypes = (typeof SUPPORTED_TYPES)[number];
11
11
  /**
12
12
  * @event change - `(event: Event) => void`
package/dist/input.js CHANGED
@@ -1,4 +1,4 @@
1
- var __decorate=this&&this.__decorate||function(t,e,i,s){var a,r=arguments.length,o=r<3?e:null===s?s=Object.getOwnPropertyDescriptor(e,i):s;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)o=Reflect.decorate(t,e,i,s);else for(var l=t.length-1;l>=0;l--)(a=t[l])&&(o=(r<3?a(o):r>3?a(e,i,o):a(e,i))||o);return r>3&&o&&Object.defineProperty(e,i,o),o};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{unsafeHTML}from"lit/directives/unsafe-html.js";import{when}from"lit/directives/when.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.pattern?(this.#t.setValidity({customError:Boolean(this.validityMessage),patternMismatch:!new RegExp(this.pattern).test(this.value),valueMissing:Boolean(this.required&&!this.value)}," ",this.#e.value),this.#t.validity):!this.pattern&&this.#t.validity.patternMismatch?(this.#t.setValidity({}),this.#t.validity):!this.required||this.value||this.disabled?this.required&&this.#t.validity.valueMissing&&this.value?(this.#t.setValidity({}),this.#t.validity):(this.required||!this.#t.validity.valueMissing||this.value||this.#t.setValidity({}),this.#t.validity):(this.#t.setValidity({customError:Boolean(this.validityMessage),valueMissing:!0}," ",this.#e.value),this.#t.validity)}get willValidate(){return this.#t.willValidate}blur(){this.#e.value?.blur()}checkValidity(){this.isCheckingValidity=!0;const t=this.#t.checkValidity();return this.isCheckingValidity=!1,t}disconnectedCallback(){super.disconnectedCallback(),this.form?.removeEventListener("formdata",this.#i)}formAssociatedCallback(){this.form?.addEventListener("formdata",this.#i)}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`
1
+ var __decorate=this&&this.__decorate||function(t,e,i,s){var a,r=arguments.length,o=r<3?e:null===s?s=Object.getOwnPropertyDescriptor(e,i):s;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)o=Reflect.decorate(t,e,i,s);else for(var l=t.length-1;l>=0;l--)(a=t[l])&&(o=(r<3?a(o):r>3?a(e,i,o):a(e,i))||o);return r>3&&o&&Object.defineProperty(e,i,o),o};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{unsafeHTML}from"lit/directives/unsafe-html.js";import{when}from"lit/directives/when.js";import magnifyingGlassIcon from"./icons/magnifying-glass.js";import ow from"./library/ow.js";import styles from"./input.styles.js";export const SUPPORTED_TYPES=["date","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.pattern?(this.#t.setValidity({customError:Boolean(this.validityMessage),patternMismatch:!new RegExp(this.pattern).test(this.value),valueMissing:Boolean(this.required&&!this.value)}," ",this.#e.value),this.#t.validity):!this.pattern&&this.#t.validity.patternMismatch?(this.#t.setValidity({}),this.#t.validity):!this.required||this.value||this.disabled?this.required&&this.#t.validity.valueMissing&&this.value?(this.#t.setValidity({}),this.#t.validity):(this.required||!this.#t.validity.valueMissing||this.value||this.#t.setValidity({}),this.#t.validity):(this.#t.setValidity({customError:Boolean(this.validityMessage),valueMissing:!0}," ",this.#e.value),this.#t.validity)}get willValidate(){return this.#t.willValidate}blur(){this.#e.value?.blur()}checkValidity(){this.isCheckingValidity=!0;const t=this.#t.checkValidity();return this.isCheckingValidity=!1,t}disconnectedCallback(){super.disconnectedCallback(),this.form?.removeEventListener("formdata",this.#i)}formAssociatedCallback(){this.form?.addEventListener("formdata",this.#i)}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`
2
2
  <glide-core-private-label
3
3
  class=${classMap({left:"left"===this.privateSplit,middle:"middle"===this.privateSplit})}
4
4
  orientation=${this.orientation}
@@ -20,6 +20,7 @@ var __decorate=this&&this.__decorate||function(t,e,i,s){var a,r=arguments.length
20
20
  <input
21
21
  aria-describedby="meta"
22
22
  aria-invalid=${this.#s||this.#a}
23
+ class="input"
23
24
  id="input"
24
25
  type=${"password"===this.type&&this.passwordVisible?"text":this.type}
25
26
  .value=${this.value}