@crowdstrike/glide-core 0.8.0 → 0.9.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 (181) hide show
  1. package/dist/accordion.d.ts +7 -3
  2. package/dist/button-group.button.d.ts +12 -16
  3. package/dist/button-group.button.js +1 -1
  4. package/dist/button-group.button.styles.js +76 -52
  5. package/dist/button-group.button.test.basics.d.ts +1 -1
  6. package/dist/button-group.button.test.basics.js +83 -147
  7. package/dist/button-group.button.test.events.js +8 -67
  8. package/dist/button-group.button.test.focus.js +13 -0
  9. package/dist/button-group.button.test.interactions.d.ts +1 -0
  10. package/dist/button-group.button.test.interactions.js +42 -0
  11. package/dist/button-group.d.ts +10 -10
  12. package/dist/button-group.js +1 -1
  13. package/dist/button-group.stories.d.ts +1 -5
  14. package/dist/button-group.styles.js +18 -6
  15. package/dist/button-group.test.basics.js +113 -234
  16. package/dist/button-group.test.events.js +210 -263
  17. package/dist/button-group.test.focus.d.ts +1 -0
  18. package/dist/button-group.test.focus.js +39 -0
  19. package/dist/button-group.test.interactions.d.ts +1 -0
  20. package/dist/button-group.test.interactions.js +91 -0
  21. package/dist/button.d.ts +3 -0
  22. package/dist/button.test.basics.js +1 -1
  23. package/dist/checkbox-group.d.ts +6 -2
  24. package/dist/checkbox-group.js +1 -1
  25. package/dist/checkbox-group.stories.d.ts +1 -1
  26. package/dist/checkbox-group.styles.js +1 -1
  27. package/dist/checkbox-group.test.basics.js +1 -1
  28. package/dist/checkbox-group.test.events.js +4 -4
  29. package/dist/checkbox-group.test.focus.js +4 -3
  30. package/dist/checkbox.d.ts +12 -5
  31. package/dist/checkbox.js +1 -1
  32. package/dist/checkbox.stories.d.ts +1 -1
  33. package/dist/checkbox.styles.js +10 -0
  34. package/dist/checkbox.test.basics.js +15 -6
  35. package/dist/checkbox.test.events.js +16 -8
  36. package/dist/checkbox.test.focus.js +3 -3
  37. package/dist/checkbox.test.form.js +1 -0
  38. package/dist/checkbox.test.interactions.js +123 -0
  39. package/dist/drawer.d.ts +5 -5
  40. package/dist/drawer.js +1 -1
  41. package/dist/drawer.stories.d.ts +0 -1
  42. package/dist/dropdown.d.ts +9 -6
  43. package/dist/dropdown.js +1 -1
  44. package/dist/dropdown.option.d.ts +6 -2
  45. package/dist/dropdown.option.js +1 -1
  46. package/dist/dropdown.option.styles.js +13 -0
  47. package/dist/dropdown.option.test.basics.js +6 -3
  48. package/dist/dropdown.option.test.events.js +1 -1
  49. package/dist/dropdown.option.test.focus.js +1 -1
  50. package/dist/dropdown.option.test.interactions.multiple.js +1 -54
  51. package/dist/dropdown.option.test.interactions.single.js +51 -9
  52. package/dist/dropdown.styles.js +20 -19
  53. package/dist/dropdown.test.basics.js +143 -2
  54. package/dist/dropdown.test.basics.multiple.js +5 -2
  55. package/dist/dropdown.test.events.filterable.js +74 -0
  56. package/dist/dropdown.test.events.js +49 -160
  57. package/dist/dropdown.test.events.multiple.js +265 -8
  58. package/dist/dropdown.test.events.single.js +199 -2
  59. package/dist/dropdown.test.focus.filterable.js +9 -5
  60. package/dist/dropdown.test.focus.js +1 -1
  61. package/dist/dropdown.test.focus.multiple.js +1 -1
  62. package/dist/dropdown.test.focus.single.js +1 -1
  63. package/dist/dropdown.test.interactions.filterable.js +68 -11
  64. package/dist/dropdown.test.interactions.js +94 -5
  65. package/dist/dropdown.test.interactions.multiple.js +202 -5
  66. package/dist/dropdown.test.interactions.single.js +68 -6
  67. package/dist/form-controls-layout.test.basics.js +1 -1
  68. package/dist/icon-button.d.ts +2 -0
  69. package/dist/icon-button.test.basics.js +1 -1
  70. package/dist/icons/checked.d.ts +1 -1
  71. package/dist/icons/checked.js +1 -1
  72. package/dist/icons/magnifying-glass.js +1 -1
  73. package/dist/input.d.ts +4 -9
  74. package/dist/input.js +1 -1
  75. package/dist/input.styles.js +7 -2
  76. package/dist/input.test.basics.js +19 -5
  77. package/dist/input.test.events.js +4 -4
  78. package/dist/input.test.focus.js +4 -4
  79. package/dist/input.test.translations.d.ts +1 -0
  80. package/dist/input.test.translations.js +38 -0
  81. package/dist/input.test.validity.js +133 -4
  82. package/dist/label.d.ts +1 -1
  83. package/dist/label.js +1 -1
  84. package/dist/label.styles.js +25 -13
  85. package/dist/label.test.basics.js +26 -24
  86. package/dist/library/expect-argument-error.js +1 -1
  87. package/dist/library/localize.d.ts +4 -1
  88. package/dist/menu.d.ts +3 -5
  89. package/dist/menu.js +1 -1
  90. package/dist/menu.options.test.basics.js +2 -2
  91. package/dist/menu.styles.js +1 -15
  92. package/dist/menu.test.basics.d.ts +1 -2
  93. package/dist/menu.test.basics.js +22 -6
  94. package/dist/menu.test.events.js +197 -7
  95. package/dist/menu.test.focus.d.ts +1 -0
  96. package/dist/menu.test.focus.js +13 -6
  97. package/dist/menu.test.interactions.js +214 -58
  98. package/dist/modal.icon-button.test.basics.js +1 -1
  99. package/dist/modal.js +1 -1
  100. package/dist/modal.stories.d.ts +1 -0
  101. package/dist/modal.styles.js +18 -13
  102. package/dist/modal.tertiary-icon.d.ts +0 -1
  103. package/dist/modal.tertiary-icon.js +1 -1
  104. package/dist/modal.tertiary-icon.test.basics.js +3 -3
  105. package/dist/modal.test.basics.js +1 -1
  106. package/dist/modal.test.events.js +10 -10
  107. package/dist/radio-group.d.ts +4 -3
  108. package/dist/radio-group.js +1 -1
  109. package/dist/radio-group.stories.d.ts +1 -1
  110. package/dist/radio-group.styles.js +1 -1
  111. package/dist/radio-group.test.focus.js +3 -3
  112. package/dist/radio.d.ts +2 -2
  113. package/dist/radio.js +1 -1
  114. package/dist/radio.styles.js +33 -0
  115. package/dist/split-container.d.ts +1 -1
  116. package/dist/split-container.test.basics.js +4 -0
  117. package/dist/split-link.test.interactions.js +1 -1
  118. package/dist/status-indicator.d.ts +1 -1
  119. package/dist/styles/variables.css +1 -1
  120. package/dist/tab.d.ts +1 -1
  121. package/dist/tab.group.js +1 -1
  122. package/dist/tab.group.test.basics.js +1 -1
  123. package/dist/tab.group.test.interactions.js +198 -2
  124. package/dist/tab.js +1 -1
  125. package/dist/tab.panel.d.ts +1 -0
  126. package/dist/tab.panel.js +1 -1
  127. package/dist/tab.panel.styles.js +11 -1
  128. package/dist/tabs.stories.d.ts +1 -0
  129. package/dist/tag.d.ts +3 -6
  130. package/dist/tag.test.basics.js +2 -2
  131. package/dist/textarea.d.ts +4 -4
  132. package/dist/textarea.js +2 -2
  133. package/dist/textarea.stories.d.ts +3 -4
  134. package/dist/textarea.styles.js +14 -3
  135. package/dist/textarea.test.basics.js +80 -44
  136. package/dist/textarea.test.events.js +56 -41
  137. package/dist/textarea.test.translations.d.ts +1 -0
  138. package/dist/textarea.test.translations.js +34 -0
  139. package/dist/textarea.test.validity.js +104 -20
  140. package/dist/toasts.js +1 -1
  141. package/dist/toasts.styles.js +8 -1
  142. package/dist/toasts.test.basics.js +20 -0
  143. package/dist/toggle.d.ts +3 -3
  144. package/dist/toggle.js +1 -1
  145. package/dist/toggle.stories.d.ts +1 -1
  146. package/dist/toggle.test.focus.js +1 -1
  147. package/dist/toggle.test.interactions.d.ts +1 -0
  148. package/dist/{toggle.test.states.js → toggle.test.interactions.js} +26 -0
  149. package/dist/tooltip.d.ts +9 -7
  150. package/dist/tooltip.js +1 -1
  151. package/dist/tooltip.styles.js +90 -25
  152. package/dist/tooltip.test.basics.js +38 -3
  153. package/dist/tooltip.test.interactions.js +136 -34
  154. package/dist/translations/en.js +1 -1
  155. package/dist/translations/fr.js +1 -1
  156. package/dist/translations/ja.js +1 -1
  157. package/dist/tree.d.ts +1 -2
  158. package/dist/tree.item.d.ts +1 -5
  159. package/dist/tree.item.icon-button.d.ts +1 -0
  160. package/dist/tree.item.icon-button.js +1 -1
  161. package/dist/tree.item.icon-button.test.basics.js +9 -0
  162. package/dist/tree.item.js +1 -1
  163. package/dist/tree.item.menu.d.ts +2 -1
  164. package/dist/tree.item.menu.js +1 -1
  165. package/dist/tree.item.menu.test.basics.js +15 -0
  166. package/dist/tree.item.styles.js +2 -0
  167. package/dist/tree.item.test.basics.d.ts +2 -1
  168. package/dist/tree.item.test.basics.js +46 -4
  169. package/dist/tree.js +1 -1
  170. package/dist/tree.test.basics.js +1 -1
  171. package/dist/tree.test.focus.js +91 -4
  172. package/package.json +3 -4
  173. package/dist/checkbox.test.states.js +0 -63
  174. package/dist/drawer.test.floating-components.d.ts +0 -1
  175. package/dist/drawer.test.floating-components.js +0 -52
  176. package/dist/library/set-containing-block.d.ts +0 -15
  177. package/dist/library/set-containing-block.js +0 -1
  178. package/dist/modal.test.floating-components.js +0 -63
  179. /package/dist/{checkbox.test.states.d.ts → button-group.button.test.focus.d.ts} +0 -0
  180. /package/dist/{modal.test.floating-components.d.ts → checkbox.test.interactions.d.ts} +0 -0
  181. /package/dist/{toggle.test.states.d.ts → dropdown.test.events.filterable.d.ts} +0 -0
@@ -1,5 +1,5 @@
1
1
  /* eslint-disable @typescript-eslint/no-unused-expressions */
2
- import { assert, elementUpdated, expect, fixture, html, } from '@open-wc/testing';
2
+ import { aTimeout, assert, elementUpdated, expect, fixture, html, } from '@open-wc/testing';
3
3
  import { sendKeys } from '@web/test-runner-commands';
4
4
  import { sendMouse } from '@web/test-runner-commands';
5
5
  import GlideCoreDropdown from './dropdown.js';
@@ -25,7 +25,11 @@ it('opens on click', async () => {
25
25
  component.shadowRoot
26
26
  ?.querySelector('[data-test="button"]')
27
27
  ?.dispatchEvent(new CustomEvent('click', { bubbles: true, detail: 1 }));
28
+ // Wait for it to open.
29
+ await aTimeout(0);
30
+ const options = component.shadowRoot?.querySelector('[data-test="options"]');
28
31
  expect(component.open).to.be.true;
32
+ expect(options?.checkVisibility()).to.be.true;
29
33
  });
30
34
  it('toggles open and closed when the button is clicked', async () => {
31
35
  const component = await fixture(html `<glide-core-dropdown
@@ -51,7 +55,10 @@ it('toggles open and closed when the button is clicked', async () => {
51
55
  component.shadowRoot
52
56
  ?.querySelector('[data-test="button"]')
53
57
  ?.dispatchEvent(new CustomEvent('click', { bubbles: true, detail: 1 }));
58
+ await elementUpdated(component);
59
+ const options = component.shadowRoot?.querySelector('[data-test="options"]');
54
60
  expect(component.open).to.be.false;
61
+ expect(options?.checkVisibility()).to.be.false;
55
62
  });
56
63
  it('does not toggle open and closed when the button overflow text is clicked', async () => {
57
64
  const component = await fixture(html `<glide-core-dropdown
@@ -77,7 +84,11 @@ it('does not toggle open and closed when the button overflow text is clicked', a
77
84
  component.shadowRoot
78
85
  ?.querySelector('[data-test="tag-overflow-text"]')
79
86
  ?.dispatchEvent(new CustomEvent('click', { bubbles: true, detail: 1 }));
87
+ // Wait for it to open.
88
+ await aTimeout(0);
89
+ const options = component.shadowRoot?.querySelector('[data-test="options"]');
80
90
  expect(component.open).to.be.true;
91
+ expect(options?.checkVisibility()).to.be.true;
81
92
  });
82
93
  it('selects options on click', async () => {
83
94
  const component = await fixture(html `<glide-core-dropdown
@@ -123,6 +134,8 @@ it('selects options on Space', async () => {
123
134
  value="two"
124
135
  ></glide-core-dropdown-option>
125
136
  </glide-core-dropdown>`);
137
+ // Wait for it to open.
138
+ await aTimeout(0);
126
139
  const options = component.querySelectorAll('glide-core-dropdown-option');
127
140
  options[0]?.focus();
128
141
  await sendKeys({ press: ' ' });
@@ -153,6 +166,8 @@ it('selects options on Enter', async () => {
153
166
  value="two"
154
167
  ></glide-core-dropdown-option>
155
168
  </glide-core-dropdown>`);
169
+ // Wait for it to open.
170
+ await aTimeout(0);
156
171
  const options = component.querySelectorAll('glide-core-dropdown-option');
157
172
  options[0]?.focus();
158
173
  await sendKeys({ press: 'Enter' });
@@ -398,6 +413,8 @@ it('updates `value` when a option is selected or deselected via Enter', async ()
398
413
 
399
414
  <glide-core-dropdown-option label="Three"></glide-core-dropdown-option>
400
415
  </glide-core-dropdown>`);
416
+ // Wait for it to open.
417
+ await aTimeout(0);
401
418
  const options = component.querySelectorAll('glide-core-dropdown-option');
402
419
  options[1].focus();
403
420
  await sendKeys({ press: 'Enter' });
@@ -424,6 +441,8 @@ it('updates `value` when an option is selected or deselected via Space', async (
424
441
 
425
442
  <glide-core-dropdown-option label="Three"></glide-core-dropdown-option>
426
443
  </glide-core-dropdown>`);
444
+ // Wait for it to open.
445
+ await aTimeout(0);
427
446
  const options = component.querySelectorAll('glide-core-dropdown-option');
428
447
  options[1].focus();
429
448
  await sendKeys({ press: ' ' });
@@ -626,7 +645,7 @@ it('deselects all but the last selected option when `multiple` is changed to `fa
626
645
  expect(options[0].selected).be.false;
627
646
  expect(options[1].selected).be.true;
628
647
  });
629
- it('selects all options when none are selected and Select All is clicked', async () => {
648
+ it('selects all options when none are selected and Select All is selected via click', async () => {
630
649
  const component = await fixture(html `<glide-core-dropdown
631
650
  label="Label"
632
651
  placeholder="Placeholder"
@@ -650,7 +669,7 @@ it('selects all options when none are selected and Select All is clicked', async
650
669
  expect(options[0].selected).to.be.true;
651
670
  expect(options[1].selected).to.be.true;
652
671
  });
653
- it('selects all options when some are selected and Select All is clicked', async () => {
672
+ it('selects all options when some are selected and Select All is selected via click', async () => {
654
673
  const component = await fixture(html `<glide-core-dropdown
655
674
  label="Label"
656
675
  placeholder="Placeholder"
@@ -675,7 +694,7 @@ it('selects all options when some are selected and Select All is clicked', async
675
694
  expect(options[0].selected).to.be.true;
676
695
  expect(options[1].selected).to.be.true;
677
696
  });
678
- it('deelects all options when all are selected and Select All is clicked', async () => {
697
+ it('deselects all options when all are selected and Select All is selected via click', async () => {
679
698
  const component = await fixture(html `<glide-core-dropdown
680
699
  label="Label"
681
700
  placeholder="Placeholder"
@@ -701,8 +720,181 @@ it('deelects all options when all are selected and Select All is clicked', async
701
720
  expect(options[0].selected).to.be.false;
702
721
  expect(options[1].selected).to.be.false;
703
722
  });
723
+ it('selects all options when none are selected and Select All is selected via Space', async () => {
724
+ const component = await fixture(html `<glide-core-dropdown
725
+ label="Label"
726
+ placeholder="Placeholder"
727
+ multiple
728
+ open
729
+ select-all
730
+ >
731
+ <glide-core-dropdown-option
732
+ label="One"
733
+ value="one"
734
+ ></glide-core-dropdown-option>
735
+
736
+ <glide-core-dropdown-option
737
+ label="Two"
738
+ value="two"
739
+ ></glide-core-dropdown-option>
740
+ </glide-core-dropdown>`);
741
+ component?.shadowRoot
742
+ ?.querySelector('[data-test="select-all"]')
743
+ ?.dispatchEvent(new MouseEvent('mouseover', { bubbles: true }));
744
+ component.focus();
745
+ await sendKeys({ press: ' ' });
746
+ const options = component.querySelectorAll('glide-core-dropdown-option');
747
+ expect(options[0].selected).to.be.true;
748
+ expect(options[1].selected).to.be.true;
749
+ });
750
+ it('selects all options when some are selected and Select All is selected via Space', async () => {
751
+ const component = await fixture(html `<glide-core-dropdown
752
+ label="Label"
753
+ placeholder="Placeholder"
754
+ multiple
755
+ open
756
+ select-all
757
+ >
758
+ <glide-core-dropdown-option
759
+ label="One"
760
+ value="one"
761
+ selected
762
+ ></glide-core-dropdown-option>
763
+
764
+ <glide-core-dropdown-option
765
+ label="Two"
766
+ value="two"
767
+ ></glide-core-dropdown-option>
768
+ </glide-core-dropdown>`);
769
+ component?.shadowRoot
770
+ ?.querySelector('[data-test="select-all"]')
771
+ ?.dispatchEvent(new MouseEvent('mouseover', { bubbles: true }));
772
+ component.focus();
773
+ await sendKeys({ press: ' ' });
774
+ const options = component.querySelectorAll('glide-core-dropdown-option');
775
+ expect(options[0].selected).to.be.true;
776
+ expect(options[1].selected).to.be.true;
777
+ });
778
+ it('deselects all options when all are selected and Select All is selected via Space', async () => {
779
+ const component = await fixture(html `<glide-core-dropdown
780
+ label="Label"
781
+ placeholder="Placeholder"
782
+ multiple
783
+ open
784
+ select-all
785
+ >
786
+ <glide-core-dropdown-option
787
+ label="One"
788
+ value="one"
789
+ selected
790
+ ></glide-core-dropdown-option>
791
+
792
+ <glide-core-dropdown-option
793
+ label="Two"
794
+ value="two"
795
+ selected
796
+ ></glide-core-dropdown-option>
797
+ </glide-core-dropdown>`);
798
+ component?.shadowRoot
799
+ ?.querySelector('[data-test="select-all"]')
800
+ ?.dispatchEvent(new MouseEvent('mouseover', { bubbles: true }));
801
+ component.focus();
802
+ await sendKeys({ press: ' ' });
803
+ const options = component.querySelectorAll('glide-core-dropdown-option');
804
+ expect(options[0].selected).to.be.false;
805
+ expect(options[1].selected).to.be.false;
806
+ });
807
+ it('selects all options when none are selected and Select All is selected via Enter', async () => {
808
+ const component = await fixture(html `<glide-core-dropdown
809
+ label="Label"
810
+ placeholder="Placeholder"
811
+ multiple
812
+ open
813
+ select-all
814
+ >
815
+ <glide-core-dropdown-option
816
+ label="One"
817
+ value="one"
818
+ ></glide-core-dropdown-option>
819
+
820
+ <glide-core-dropdown-option
821
+ label="Two"
822
+ value="two"
823
+ ></glide-core-dropdown-option>
824
+ </glide-core-dropdown>`);
825
+ component?.shadowRoot
826
+ ?.querySelector('[data-test="select-all"]')
827
+ ?.dispatchEvent(new MouseEvent('mouseover', { bubbles: true }));
828
+ component.focus();
829
+ await sendKeys({ press: 'Enter' });
830
+ const options = component.querySelectorAll('glide-core-dropdown-option');
831
+ expect(options[0].selected).to.be.true;
832
+ expect(options[1].selected).to.be.true;
833
+ });
834
+ it('selects all options when some are selected and Select All is selected via Enter', async () => {
835
+ const component = await fixture(html `<glide-core-dropdown
836
+ label="Label"
837
+ placeholder="Placeholder"
838
+ multiple
839
+ open
840
+ select-all
841
+ >
842
+ <glide-core-dropdown-option
843
+ label="One"
844
+ value="one"
845
+ selected
846
+ ></glide-core-dropdown-option>
847
+
848
+ <glide-core-dropdown-option
849
+ label="Two"
850
+ value="two"
851
+ ></glide-core-dropdown-option>
852
+ </glide-core-dropdown>`);
853
+ component?.shadowRoot
854
+ ?.querySelector('[data-test="select-all"]')
855
+ ?.dispatchEvent(new MouseEvent('mouseover', { bubbles: true }));
856
+ component.focus();
857
+ await sendKeys({ press: 'Enter' });
858
+ const options = component.querySelectorAll('glide-core-dropdown-option');
859
+ expect(options[0].selected).to.be.true;
860
+ expect(options[1].selected).to.be.true;
861
+ });
862
+ it('deselects all options when all are selected and Select All is selected via Enter', async () => {
863
+ const component = await fixture(html `<glide-core-dropdown
864
+ label="Label"
865
+ placeholder="Placeholder"
866
+ multiple
867
+ open
868
+ select-all
869
+ >
870
+ <glide-core-dropdown-option
871
+ label="One"
872
+ value="one"
873
+ selected
874
+ ></glide-core-dropdown-option>
875
+
876
+ <glide-core-dropdown-option
877
+ label="Two"
878
+ value="two"
879
+ selected
880
+ ></glide-core-dropdown-option>
881
+ </glide-core-dropdown>`);
882
+ component?.shadowRoot
883
+ ?.querySelector('[data-test="select-all"]')
884
+ ?.dispatchEvent(new MouseEvent('mouseover', { bubbles: true }));
885
+ component.focus();
886
+ await sendKeys({ press: 'Enter' });
887
+ const options = component.querySelectorAll('glide-core-dropdown-option');
888
+ expect(options[0].selected).to.be.false;
889
+ expect(options[1].selected).to.be.false;
890
+ });
704
891
  it('shows Select All', async () => {
705
- const component = await fixture(html `<glide-core-dropdown label="Label" placeholder="Placeholder" multiple>
892
+ const component = await fixture(html `<glide-core-dropdown
893
+ label="Label"
894
+ placeholder="Placeholder"
895
+ open
896
+ multiple
897
+ >
706
898
  <glide-core-dropdown-option
707
899
  label="One"
708
900
  value="one"
@@ -714,6 +906,8 @@ it('shows Select All', async () => {
714
906
  value="two"
715
907
  ></glide-core-dropdown-option>
716
908
  </glide-core-dropdown>`);
909
+ // Wait for it to open.
910
+ await aTimeout(0);
717
911
  component.selectAll = true;
718
912
  await elementUpdated(component);
719
913
  const selectAll = component.shadowRoot?.querySelector('[data-test="select-all"]');
@@ -786,6 +980,7 @@ it('sets Select All as indeterminate when not all options are selected', async (
786
980
  </glide-core-dropdown>`);
787
981
  const options = component.querySelectorAll('glide-core-dropdown-option');
788
982
  options[0].click();
983
+ await elementUpdated(component);
789
984
  const selectAll = component.shadowRoot?.querySelector('[data-test="select-all"]');
790
985
  expect(selectAll?.privateIndeterminate).to.be.true;
791
986
  });
@@ -878,6 +1073,8 @@ it('does not select an option on Enter when the option is not focused', async ()
878
1073
  value="two"
879
1074
  ></glide-core-dropdown-option>
880
1075
  </glide-core-dropdown>`);
1076
+ // Wait for it to open.
1077
+ await aTimeout(0);
881
1078
  const option = component.querySelector('glide-core-dropdown-option');
882
1079
  option?.focus();
883
1080
  await sendKeys({ down: 'Tab' });
@@ -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(() => {
@@ -5,6 +5,8 @@ declare global {
5
5
  }
6
6
  }
7
7
  /**
8
+ * @description A button with only an icon.
9
+ *
8
10
  * @slot - Reserved for the icon to display inside of the button.
9
11
  */
10
12
  export default class GlideCoreIconButton extends LitElement {
@@ -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
@@ -11,9 +11,10 @@ type SupportedTypes = (typeof SUPPORTED_TYPES)[number];
11
11
  /**
12
12
  * @description An input with a label and optional description and tooltip. Participates in forms and validation via `FormData` and various methods.
13
13
  *
14
- * @event change - (same as native input's `change` event)
15
- * @event input - (same as native input's `input` event)
16
-
14
+ * @event change - `(event: Event) => void`
15
+ * @event input - `(event: Event) => void`
16
+ * @event invalid - `(event: Event) => void`
17
+ *
17
18
  * @slot tooltip - Content for the tooltip.
18
19
  * @slot description - Additional information or context.
19
20
  * @slot prefix - An optional icon slot to display before the input.
@@ -41,24 +42,18 @@ export default class GlideCoreInput extends LitElement {
41
42
  disabled: boolean;
42
43
  privateSplit?: 'left' | 'middle';
43
44
  maxlength?: number;
44
- descriptionNodes: NodeListOf<HTMLElement>;
45
- prefixIconNodes: NodeListOf<HTMLElement>;
46
- suffixIconNodes: NodeListOf<HTMLElement>;
47
45
  get form(): HTMLFormElement | null;
48
46
  get validity(): ValidityState;
49
47
  get willValidate(): boolean;
50
48
  blur(): void;
51
49
  checkValidity(): boolean;
52
50
  disconnectedCallback(): void;
53
- firstUpdated(): void;
54
51
  formAssociatedCallback(): void;
55
52
  formResetCallback(): void;
56
- get isTypeSearch(): boolean;
57
53
  get hasClearIcon(): boolean;
58
54
  get isClearIconVisible(): boolean;
59
55
  render(): import("lit").TemplateResult<1>;
60
56
  reportValidity(): boolean;
61
- get valueCharacterCount(): number;
62
57
  constructor();
63
58
  private hasFocus;
64
59
  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({reflect:!0,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;