@crowdstrike/glide-core 0.9.6 → 0.10.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 (207) hide show
  1. package/README.md +17 -53
  2. package/dist/accordion.d.ts +10 -10
  3. package/dist/accordion.js +1 -1
  4. package/dist/accordion.stories.d.ts +0 -1
  5. package/dist/accordion.styles.js +36 -38
  6. package/dist/accordion.test.basics.js +13 -95
  7. package/dist/accordion.test.events.js +21 -33
  8. package/dist/accordion.test.focus.d.ts +1 -0
  9. package/dist/accordion.test.focus.js +11 -0
  10. package/dist/accordion.test.interactions.d.ts +1 -0
  11. package/dist/accordion.test.interactions.js +75 -0
  12. package/dist/button-group.button.d.ts +2 -4
  13. package/dist/button-group.button.js +1 -1
  14. package/dist/button-group.button.styles.js +6 -14
  15. package/dist/button-group.button.test.basics.js +8 -17
  16. package/dist/button-group.button.test.interactions.js +4 -4
  17. package/dist/button-group.d.ts +0 -2
  18. package/dist/button-group.test.basics.js +10 -10
  19. package/dist/button-group.test.events.js +2 -2
  20. package/dist/button-group.test.interactions.js +1 -1
  21. package/dist/button.d.ts +7 -10
  22. package/dist/button.js +1 -1
  23. package/dist/button.styles.js +4 -7
  24. package/dist/button.test.basics.js +10 -26
  25. package/dist/button.test.events.js +9 -9
  26. package/dist/checkbox-group.d.ts +3 -4
  27. package/dist/checkbox-group.js +1 -1
  28. package/dist/checkbox-group.styles.js +13 -1
  29. package/dist/checkbox-group.test.basics.js +8 -12
  30. package/dist/checkbox-group.test.focus.js +7 -7
  31. package/dist/checkbox-group.test.interactions.d.ts +1 -0
  32. package/dist/checkbox-group.test.interactions.js +82 -0
  33. package/dist/checkbox.d.ts +5 -4
  34. package/dist/checkbox.js +1 -1
  35. package/dist/checkbox.styles.js +35 -15
  36. package/dist/checkbox.test.basics.js +6 -15
  37. package/dist/checkbox.test.focus.js +4 -2
  38. package/dist/checkbox.test.interactions.js +11 -11
  39. package/dist/drawer.d.ts +2 -5
  40. package/dist/drawer.js +1 -1
  41. package/dist/drawer.test.accessibility.js +8 -8
  42. package/dist/drawer.test.basics.js +16 -16
  43. package/dist/drawer.test.closing.js +18 -16
  44. package/dist/drawer.test.events.js +13 -24
  45. package/dist/drawer.test.methods.js +22 -22
  46. package/dist/dropdown.d.ts +7 -5
  47. package/dist/dropdown.js +1 -1
  48. package/dist/dropdown.option.d.ts +1 -3
  49. package/dist/dropdown.option.js +1 -1
  50. package/dist/dropdown.option.styles.js +31 -19
  51. package/dist/dropdown.option.test.basics.js +4 -4
  52. package/dist/dropdown.styles.js +39 -3
  53. package/dist/dropdown.test.basics.js +8 -13
  54. package/dist/dropdown.test.basics.multiple.js +63 -31
  55. package/dist/dropdown.test.basics.single.js +49 -0
  56. package/dist/dropdown.test.focus.filterable.js +12 -3
  57. package/dist/dropdown.test.focus.js +18 -2
  58. package/dist/dropdown.test.interactions.filterable.js +121 -45
  59. package/dist/dropdown.test.interactions.multiple.js +71 -30
  60. package/dist/dropdown.test.interactions.single.js +26 -4
  61. package/dist/form-controls-layout.d.ts +0 -2
  62. package/dist/icon-button.d.ts +2 -4
  63. package/dist/icon-button.js +1 -1
  64. package/dist/icon-button.test.basics.js +14 -82
  65. package/dist/icon-button.test.focus.d.ts +1 -0
  66. package/dist/icon-button.test.focus.js +13 -0
  67. package/dist/input.d.ts +4 -5
  68. package/dist/input.js +1 -1
  69. package/dist/input.styles.js +4 -4
  70. package/dist/input.test.basics.js +0 -52
  71. package/dist/input.test.events.js +27 -27
  72. package/dist/input.test.focus.js +27 -26
  73. package/dist/input.test.form.js +6 -6
  74. package/dist/input.test.validity.js +130 -130
  75. package/dist/label.d.ts +1 -3
  76. package/dist/label.js +1 -1
  77. package/dist/label.styles.js +5 -6
  78. package/dist/label.test.basics.js +4 -4
  79. package/dist/library/ow.js +1 -1
  80. package/dist/menu.button.d.ts +0 -2
  81. package/dist/menu.button.test.basics.js +3 -3
  82. package/dist/menu.d.ts +1 -4
  83. package/dist/menu.js +1 -1
  84. package/dist/menu.link.d.ts +1 -2
  85. package/dist/menu.link.js +1 -1
  86. package/dist/menu.options.d.ts +0 -2
  87. package/dist/menu.test.events.js +6 -6
  88. package/dist/menu.test.focus.js +5 -18
  89. package/dist/menu.test.interactions.js +48 -24
  90. package/dist/modal.d.ts +6 -17
  91. package/dist/modal.icon-button.d.ts +0 -2
  92. package/dist/modal.icon-button.test.basics.js +3 -3
  93. package/dist/modal.js +1 -1
  94. package/dist/modal.styles.js +13 -19
  95. package/dist/modal.tertiary-icon.d.ts +0 -3
  96. package/dist/modal.tertiary-icon.test.basics.js +3 -3
  97. package/dist/modal.test.basics.js +9 -5
  98. package/dist/modal.test.close.js +2 -2
  99. package/dist/modal.test.events.js +2 -2
  100. package/dist/radio-group.d.ts +0 -3
  101. package/dist/radio-group.js +1 -1
  102. package/dist/radio-group.test.basics.js +61 -61
  103. package/dist/radio-group.test.events.js +13 -13
  104. package/dist/radio-group.test.focus.js +1 -1
  105. package/dist/radio-group.test.form.js +2 -2
  106. package/dist/radio-group.test.validity.js +12 -12
  107. package/dist/radio.d.ts +0 -3
  108. package/dist/radio.styles.js +4 -12
  109. package/dist/split-button.d.ts +8 -11
  110. package/dist/split-button.js +1 -1
  111. package/dist/split-button.primary-button.d.ts +21 -0
  112. package/dist/split-button.primary-button.js +1 -0
  113. package/dist/split-button.primary-button.styles.js +96 -0
  114. package/dist/split-button.primary-button.test.basics.d.ts +1 -0
  115. package/dist/split-button.primary-button.test.basics.js +31 -0
  116. package/dist/split-button.primary-button.test.focus.d.ts +1 -0
  117. package/dist/split-button.primary-button.test.focus.js +14 -0
  118. package/dist/split-button.primary-link.d.ts +19 -0
  119. package/dist/split-button.primary-link.js +1 -0
  120. package/dist/split-button.primary-link.test.basics.d.ts +1 -0
  121. package/dist/split-button.primary-link.test.basics.js +30 -0
  122. package/dist/split-button.primary-link.test.focus.d.ts +1 -0
  123. package/dist/split-button.primary-link.test.focus.js +15 -0
  124. package/dist/split-button.secondary-button.d.ts +25 -0
  125. package/dist/split-button.secondary-button.js +1 -0
  126. package/dist/split-button.secondary-button.styles.js +103 -0
  127. package/dist/split-button.secondary-button.test.basics.d.ts +1 -0
  128. package/dist/split-button.secondary-button.test.basics.js +58 -0
  129. package/dist/split-button.secondary-button.test.focus.d.ts +1 -0
  130. package/dist/split-button.secondary-button.test.focus.js +14 -0
  131. package/dist/split-button.secondary-button.test.interactions.d.ts +2 -0
  132. package/dist/split-button.secondary-button.test.interactions.js +30 -0
  133. package/dist/split-button.stories.d.ts +4 -3
  134. package/dist/split-button.styles.js +1 -94
  135. package/dist/split-button.test.basics.d.ts +2 -1
  136. package/dist/split-button.test.basics.js +67 -80
  137. package/dist/split-button.test.interactions.d.ts +4 -0
  138. package/dist/split-button.test.interactions.js +51 -0
  139. package/dist/styles/opacity-and-scale-animation.js +2 -6
  140. package/dist/styles/variables.css +1 -1
  141. package/dist/tab.d.ts +2 -11
  142. package/dist/tab.group.d.ts +2 -5
  143. package/dist/tab.group.styles.js +12 -15
  144. package/dist/tab.group.test.basics.js +49 -34
  145. package/dist/tab.group.test.interactions.js +17 -14
  146. package/dist/tab.panel.d.ts +0 -3
  147. package/dist/tab.test.basics.js +6 -5
  148. package/dist/tag.d.ts +6 -4
  149. package/dist/tag.js +1 -1
  150. package/dist/tag.styles.js +36 -36
  151. package/dist/tag.test.basics.js +16 -109
  152. package/dist/tag.test.events.js +12 -8
  153. package/dist/tag.test.focus.js +2 -3
  154. package/dist/tag.test.interactions.d.ts +1 -0
  155. package/dist/tag.test.interactions.js +34 -0
  156. package/dist/textarea.d.ts +2 -3
  157. package/dist/textarea.js +2 -2
  158. package/dist/textarea.test.basics.js +8 -8
  159. package/dist/textarea.test.events.js +55 -55
  160. package/dist/textarea.test.form.js +9 -9
  161. package/dist/textarea.test.validity.js +167 -135
  162. package/dist/toasts.d.ts +1 -5
  163. package/dist/toasts.test.basics.js +2 -1
  164. package/dist/toasts.toast.d.ts +1 -4
  165. package/dist/toasts.toast.js +1 -1
  166. package/dist/toasts.toast.styles.js +12 -0
  167. package/dist/toggle.d.ts +0 -2
  168. package/dist/toggle.styles.js +1 -5
  169. package/dist/toggle.test.basics.js +2 -2
  170. package/dist/toggle.test.interactions.js +7 -7
  171. package/dist/tooltip.d.ts +2 -1
  172. package/dist/tooltip.js +1 -1
  173. package/dist/tooltip.styles.js +36 -13
  174. package/dist/tooltip.test.basics.d.ts +1 -1
  175. package/dist/tooltip.test.basics.js +19 -19
  176. package/dist/tree.d.ts +0 -2
  177. package/dist/tree.item.d.ts +5 -7
  178. package/dist/tree.item.icon-button.d.ts +1 -4
  179. package/dist/tree.item.js +1 -1
  180. package/dist/tree.item.menu.d.ts +0 -2
  181. package/dist/tree.item.menu.test.basics.js +9 -9
  182. package/dist/tree.item.styles.js +4 -3
  183. package/dist/tree.item.test.basics.js +43 -31
  184. package/dist/tree.test.basics.js +29 -29
  185. package/dist/tree.test.focus.js +77 -74
  186. package/package.json +12 -14
  187. package/dist/split-container.d.ts +0 -31
  188. package/dist/split-container.js +0 -1
  189. package/dist/split-container.styles.js +0 -132
  190. package/dist/split-container.test.basics.d.ts +0 -3
  191. package/dist/split-container.test.basics.js +0 -445
  192. package/dist/split-container.test.interactions.d.ts +0 -1
  193. package/dist/split-container.test.interactions.js +0 -20
  194. package/dist/split-link.d.ts +0 -25
  195. package/dist/split-link.js +0 -1
  196. package/dist/split-link.test.basics.d.ts +0 -1
  197. package/dist/split-link.test.basics.js +0 -93
  198. package/dist/split-link.test.interactions.d.ts +0 -1
  199. package/dist/split-link.test.interactions.js +0 -20
  200. package/dist/status-indicator.d.ts +0 -30
  201. package/dist/status-indicator.js +0 -1
  202. package/dist/status-indicator.stories.d.ts +0 -5
  203. package/dist/status-indicator.styles.js +0 -58
  204. package/dist/status-indicator.test.basics.d.ts +0 -1
  205. package/dist/status-indicator.test.basics.js +0 -102
  206. /package/dist/{split-container.styles.d.ts → split-button.primary-button.styles.d.ts} +0 -0
  207. /package/dist/{status-indicator.styles.d.ts → split-button.secondary-button.styles.d.ts} +0 -0
@@ -5,176 +5,176 @@ import { sendKeys } from '@web/test-runner-commands';
5
5
  import GlideCoreInput from './input.js';
6
6
  GlideCoreInput.shadowRootOptions.mode = 'open';
7
7
  it('is valid if empty but not required', async () => {
8
- const input = await fixture(html `<glide-core-input></glide-core-input>`);
9
- expect(input.validity?.valid).to.be.true;
10
- expect(input.validity?.valueMissing).to.be.false;
11
- expect(input.checkValidity()).to.be.true;
12
- expect(input.reportValidity()).to.be.true;
13
- await elementUpdated(input);
14
- expect(input.shadowRoot?.querySelector('input')).to.have.attribute('aria-invalid', 'false');
8
+ const component = await fixture(html `<glide-core-input></glide-core-input>`);
9
+ expect(component.validity?.valid).to.be.true;
10
+ expect(component.validity?.valueMissing).to.be.false;
11
+ expect(component.checkValidity()).to.be.true;
12
+ expect(component.reportValidity()).to.be.true;
13
+ await elementUpdated(component);
14
+ expect(component.shadowRoot?.querySelector('input')?.getAttribute('aria-invalid')).to.equal('false');
15
15
  });
16
16
  it('is valid after being filled in when empty and required', async () => {
17
- const input = await fixture(html `<glide-core-input required></glide-core-input>`);
18
- input.focus();
17
+ const component = await fixture(html `<glide-core-input required></glide-core-input>`);
18
+ component.focus();
19
19
  await sendKeys({ type: 'value' });
20
- expect(input.validity?.valid).to.be.true;
21
- expect(input.validity?.valueMissing).to.be.false;
22
- expect(input.checkValidity()).to.be.true;
23
- expect(input.reportValidity()).to.be.true;
24
- await elementUpdated(input);
25
- expect(input.shadowRoot?.querySelector('input')).to.have.attribute('aria-invalid', 'false');
20
+ expect(component.validity?.valid).to.be.true;
21
+ expect(component.validity?.valueMissing).to.be.false;
22
+ expect(component.checkValidity()).to.be.true;
23
+ expect(component.reportValidity()).to.be.true;
24
+ await elementUpdated(component);
25
+ expect(component.shadowRoot?.querySelector('input')?.getAttribute('aria-invalid')).to.equal('false');
26
26
  });
27
27
  it('is invalid if no value and required', async () => {
28
- const input = await fixture(html `<glide-core-input required></glide-core-input>`);
29
- expect(input.validity?.valid).to.be.false;
30
- expect(input.validity?.valueMissing).to.be.true;
31
- expect(input.willValidate).to.be.true;
32
- expect(input.checkValidity()).to.be.false;
33
- expect(input.reportValidity()).to.be.false;
34
- await elementUpdated(input);
35
- expect(input.shadowRoot?.querySelector('input')).to.have.attribute('aria-invalid', 'true');
28
+ const component = await fixture(html `<glide-core-input required></glide-core-input>`);
29
+ expect(component.validity?.valid).to.be.false;
30
+ expect(component.validity?.valueMissing).to.be.true;
31
+ expect(component.willValidate).to.be.true;
32
+ expect(component.checkValidity()).to.be.false;
33
+ expect(component.reportValidity()).to.be.false;
34
+ await elementUpdated(component);
35
+ expect(component.shadowRoot?.querySelector('input')?.getAttribute('aria-invalid')).to.equal('true');
36
36
  });
37
37
  it('is invalid after value is cleared when required', async () => {
38
- const input = await fixture(html `<glide-core-input
38
+ const component = await fixture(html `<glide-core-input
39
39
  clearable
40
40
  value="value"
41
41
  required
42
42
  ></glide-core-input>`);
43
- const clearButton = input.shadowRoot?.querySelector('[data-test="clear-button"]');
43
+ const clearButton = component.shadowRoot?.querySelector('[data-test="clear-button"]');
44
44
  clearButton?.click();
45
- await input.updateComplete;
46
- expect(input.validity?.valid).to.be.false;
47
- expect(input.validity?.valueMissing).to.be.true;
48
- expect(input.checkValidity()).to.be.false;
49
- expect(input.reportValidity()).to.be.false;
50
- await elementUpdated(input);
51
- expect(input.shadowRoot?.querySelector('input')).to.have.attribute('aria-invalid', 'true');
45
+ await component.updateComplete;
46
+ expect(component.validity?.valid).to.be.false;
47
+ expect(component.validity?.valueMissing).to.be.true;
48
+ expect(component.checkValidity()).to.be.false;
49
+ expect(component.reportValidity()).to.be.false;
50
+ await elementUpdated(component);
51
+ expect(component.shadowRoot?.querySelector('input')?.getAttribute('aria-invalid')).to.equal('true');
52
52
  });
53
53
  it('is valid when empty and does not exceed `maxlength`', async () => {
54
- const input = await fixture(html `<glide-core-input maxlength="3"></glide-core-input>`);
55
- expect(input.validity?.valid).to.be.true;
56
- expect(input.validity?.valueMissing).to.be.false;
57
- expect(input.validity?.tooLong).to.be.false;
58
- expect(input.checkValidity()).to.be.true;
59
- expect(input.reportValidity()).to.be.true;
60
- await elementUpdated(input);
61
- expect(input.shadowRoot?.querySelector('input')).to.have.attribute('aria-invalid', 'false');
54
+ const component = await fixture(html `<glide-core-input maxlength="3"></glide-core-input>`);
55
+ expect(component.validity?.valid).to.be.true;
56
+ expect(component.validity?.valueMissing).to.be.false;
57
+ expect(component.validity?.tooLong).to.be.false;
58
+ expect(component.checkValidity()).to.be.true;
59
+ expect(component.reportValidity()).to.be.true;
60
+ await elementUpdated(component);
61
+ expect(component.shadowRoot?.querySelector('input')?.getAttribute('aria-invalid')).to.equal('false');
62
62
  });
63
63
  it('is valid when filled in and does not exceed `maxlength`', async () => {
64
- const input = await fixture(html `<glide-core-input maxlength="3"></glide-core-input>`);
65
- input.focus();
64
+ const component = await fixture(html `<glide-core-input maxlength="3"></glide-core-input>`);
65
+ component.focus();
66
66
  await sendKeys({ type: 'val' });
67
- expect(input.validity?.valid).to.be.true;
68
- expect(input.validity?.valueMissing).to.be.false;
69
- expect(input.validity?.tooLong).to.be.false;
70
- expect(input.checkValidity()).to.be.true;
71
- expect(input.reportValidity()).to.be.true;
72
- await elementUpdated(input);
73
- expect(input.shadowRoot?.querySelector('input')).to.have.attribute('aria-invalid', 'false');
67
+ expect(component.validity?.valid).to.be.true;
68
+ expect(component.validity?.valueMissing).to.be.false;
69
+ expect(component.validity?.tooLong).to.be.false;
70
+ expect(component.checkValidity()).to.be.true;
71
+ expect(component.reportValidity()).to.be.true;
72
+ await elementUpdated(component);
73
+ expect(component.shadowRoot?.querySelector('input')?.getAttribute('aria-invalid')).to.equal('false');
74
74
  });
75
75
  it('is valid when filled in, disabled, and value exceeds `maxlength`', async () => {
76
- const input = await fixture(html `<glide-core-input
76
+ const component = await fixture(html `<glide-core-input
77
77
  value="value"
78
78
  maxlength="3"
79
79
  disabled
80
80
  ></glide-core-input>`);
81
- expect(input.validity?.valid).to.be.true;
82
- expect(input.validity?.valueMissing).to.be.false;
83
- expect(input.validity?.tooLong).to.be.false;
84
- expect(input.checkValidity()).to.be.true;
85
- expect(input.reportValidity()).to.be.true;
86
- await elementUpdated(input);
87
- expect(input.shadowRoot?.querySelector('input')).to.have.attribute('aria-invalid', 'false');
81
+ expect(component.validity?.valid).to.be.true;
82
+ expect(component.validity?.valueMissing).to.be.false;
83
+ expect(component.validity?.tooLong).to.be.false;
84
+ expect(component.checkValidity()).to.be.true;
85
+ expect(component.reportValidity()).to.be.true;
86
+ await elementUpdated(component);
87
+ expect(component.shadowRoot?.querySelector('input')?.getAttribute('aria-invalid')).to.equal('false');
88
88
  });
89
89
  it('is valid when filled in, readonly, and value exceeds `maxlength`', async () => {
90
- const input = await fixture(html `<glide-core-input
90
+ const component = await fixture(html `<glide-core-input
91
91
  value="value"
92
92
  maxlength="3"
93
93
  readonly
94
94
  ></glide-core-input>`);
95
- expect(input.validity?.valid).to.be.true;
96
- expect(input.validity?.valueMissing).to.be.false;
97
- expect(input.validity?.tooLong).to.be.false;
98
- expect(input.checkValidity()).to.be.true;
99
- expect(input.reportValidity()).to.be.true;
100
- await elementUpdated(input);
101
- expect(input.shadowRoot?.querySelector('input')).to.have.attribute('aria-invalid', 'false');
95
+ expect(component.validity?.valid).to.be.true;
96
+ expect(component.validity?.valueMissing).to.be.false;
97
+ expect(component.validity?.tooLong).to.be.false;
98
+ expect(component.checkValidity()).to.be.true;
99
+ expect(component.reportValidity()).to.be.true;
100
+ await elementUpdated(component);
101
+ expect(component.shadowRoot?.querySelector('input')?.getAttribute('aria-invalid')).to.equal('false');
102
102
  });
103
103
  it('is invalid when filled in and exceeds `maxlength`', async () => {
104
- const input = await fixture(html `<glide-core-input maxlength="3"></glide-core-input>`);
105
- input.focus();
104
+ const component = await fixture(html `<glide-core-input maxlength="3"></glide-core-input>`);
105
+ component.focus();
106
106
  await sendKeys({ type: 'value' });
107
- expect(input.validity?.valid).to.be.false;
108
- expect(input.validity?.tooLong).to.be.true;
109
- expect(input.checkValidity()).to.be.false;
110
- expect(input.reportValidity()).to.be.false;
111
- await elementUpdated(input);
112
- expect(input.shadowRoot?.querySelector('input')).to.have.attribute('aria-invalid', 'true');
107
+ expect(component.validity?.valid).to.be.false;
108
+ expect(component.validity?.tooLong).to.be.true;
109
+ expect(component.checkValidity()).to.be.false;
110
+ expect(component.reportValidity()).to.be.false;
111
+ await elementUpdated(component);
112
+ expect(component.shadowRoot?.querySelector('input')?.getAttribute('aria-invalid')).to.equal('true');
113
113
  });
114
114
  it('is valid if no value and required but disabled', async () => {
115
- const input = await fixture(html `<glide-core-input disabled required></glide-core-input>`);
116
- expect(input.validity?.valid).to.be.true;
117
- expect(input.validity?.valueMissing).to.be.false;
118
- expect(input.checkValidity()).to.be.true;
119
- expect(input.reportValidity()).to.be.true;
120
- await elementUpdated(input);
121
- expect(input.shadowRoot?.querySelector('input')).to.have.attribute('aria-invalid', 'false');
115
+ const component = await fixture(html `<glide-core-input disabled required></glide-core-input>`);
116
+ expect(component.validity?.valid).to.be.true;
117
+ expect(component.validity?.valueMissing).to.be.false;
118
+ expect(component.checkValidity()).to.be.true;
119
+ expect(component.reportValidity()).to.be.true;
120
+ await elementUpdated(component);
121
+ expect(component.shadowRoot?.querySelector('input')?.getAttribute('aria-invalid')).to.equal('false');
122
122
  });
123
123
  it('updates validity when `required` and `value` is changed programmatically', async () => {
124
- const input = await fixture(html `<glide-core-input label="Label" required></glide-core-input>`);
125
- expect(input.validity?.valid).to.be.false;
126
- expect(input.validity?.valueMissing).to.be.true;
127
- expect(input.checkValidity()).to.be.false;
128
- expect(input.reportValidity()).to.be.false;
129
- await elementUpdated(input);
130
- expect(input.shadowRoot?.querySelector('input')).to.have.attribute('aria-invalid', 'true');
131
- input.value = 'text';
132
- await elementUpdated(input);
133
- expect(input.validity?.valid).to.be.true;
134
- expect(input.validity?.valueMissing).to.be.false;
135
- expect(input.checkValidity()).to.be.true;
136
- expect(input.reportValidity()).to.be.true;
137
- await elementUpdated(input);
138
- expect(input.shadowRoot?.querySelector('input')).to.have.attribute('aria-invalid', 'false');
124
+ const component = await fixture(html `<glide-core-input label="Label" required></glide-core-input>`);
125
+ expect(component.validity?.valid).to.be.false;
126
+ expect(component.validity?.valueMissing).to.be.true;
127
+ expect(component.checkValidity()).to.be.false;
128
+ expect(component.reportValidity()).to.be.false;
129
+ await elementUpdated(component);
130
+ expect(component.shadowRoot?.querySelector('input')?.getAttribute('aria-invalid')).to.equal('true');
131
+ component.value = 'text';
132
+ await elementUpdated(component);
133
+ expect(component.validity?.valid).to.be.true;
134
+ expect(component.validity?.valueMissing).to.be.false;
135
+ expect(component.checkValidity()).to.be.true;
136
+ expect(component.reportValidity()).to.be.true;
137
+ await elementUpdated(component);
138
+ expect(component.shadowRoot?.querySelector('input')?.getAttribute('aria-invalid')).to.equal('false');
139
139
  // Resetting the value to empty to ensure it goes
140
140
  // back to an invalid state
141
- input.value = '';
142
- await elementUpdated(input);
143
- expect(input.validity?.valid).to.be.false;
144
- expect(input.validity?.valueMissing).to.be.true;
145
- expect(input.checkValidity()).to.be.false;
146
- expect(input.reportValidity()).to.be.false;
147
- expect(input.shadowRoot?.querySelector('input')).to.have.attribute('aria-invalid', 'true');
141
+ component.value = '';
142
+ await elementUpdated(component);
143
+ expect(component.validity?.valid).to.be.false;
144
+ expect(component.validity?.valueMissing).to.be.true;
145
+ expect(component.checkValidity()).to.be.false;
146
+ expect(component.reportValidity()).to.be.false;
147
+ expect(component.shadowRoot?.querySelector('input')?.getAttribute('aria-invalid')).to.equal('true');
148
148
  });
149
149
  it('is invalid when `value` is empty and `required` is set to `true` programmatically', async () => {
150
- const input = await fixture(html `<glide-core-input label="Label"></glide-core-input>`);
151
- expect(input.validity?.valid).to.be.true;
152
- expect(input.validity?.valueMissing).to.be.false;
153
- expect(input.checkValidity()).to.be.true;
154
- expect(input.reportValidity()).to.be.true;
155
- await elementUpdated(input);
156
- expect(input.shadowRoot?.querySelector('input')).to.have.attribute('aria-invalid', 'false');
157
- input.required = true;
158
- await elementUpdated(input);
159
- expect(input.validity?.valid).to.be.false;
160
- expect(input.validity?.valueMissing).to.be.true;
161
- expect(input.checkValidity()).to.be.false;
162
- expect(input.reportValidity()).to.be.false;
163
- expect(input.shadowRoot?.querySelector('input')).to.have.attribute('aria-invalid', 'true');
150
+ const component = await fixture(html `<glide-core-input label="Label"></glide-core-input>`);
151
+ expect(component.validity?.valid).to.be.true;
152
+ expect(component.validity?.valueMissing).to.be.false;
153
+ expect(component.checkValidity()).to.be.true;
154
+ expect(component.reportValidity()).to.be.true;
155
+ await elementUpdated(component);
156
+ expect(component.shadowRoot?.querySelector('input')?.getAttribute('aria-invalid')).to.equal('false');
157
+ component.required = true;
158
+ await elementUpdated(component);
159
+ expect(component.validity?.valid).to.be.false;
160
+ expect(component.validity?.valueMissing).to.be.true;
161
+ expect(component.checkValidity()).to.be.false;
162
+ expect(component.reportValidity()).to.be.false;
163
+ expect(component.shadowRoot?.querySelector('input')?.getAttribute('aria-invalid')).to.equal('true');
164
164
  });
165
165
  it('is valid when `value` is empty and `required` is set to `false` programmatically', async () => {
166
- const input = await fixture(html `<glide-core-input label="Label" required></glide-core-input>`);
167
- expect(input.validity?.valid).to.be.false;
168
- expect(input.validity?.valueMissing).to.be.true;
169
- expect(input.checkValidity()).to.be.false;
170
- expect(input.reportValidity()).to.be.false;
171
- await elementUpdated(input);
172
- expect(input.shadowRoot?.querySelector('input')).to.have.attribute('aria-invalid', 'true');
173
- input.required = false;
174
- await elementUpdated(input);
175
- expect(input.validity?.valid).to.be.true;
176
- expect(input.validity?.valueMissing).to.be.false;
177
- expect(input.checkValidity()).to.be.true;
178
- expect(input.reportValidity()).to.be.true;
179
- expect(input.shadowRoot?.querySelector('input')).to.have.attribute('aria-invalid', 'false');
166
+ const component = await fixture(html `<glide-core-input label="Label" required></glide-core-input>`);
167
+ expect(component.validity?.valid).to.be.false;
168
+ expect(component.validity?.valueMissing).to.be.true;
169
+ expect(component.checkValidity()).to.be.false;
170
+ expect(component.reportValidity()).to.be.false;
171
+ await elementUpdated(component);
172
+ expect(component.shadowRoot?.querySelector('input')?.getAttribute('aria-invalid')).to.equal('true');
173
+ component.required = false;
174
+ await elementUpdated(component);
175
+ expect(component.validity?.valid).to.be.true;
176
+ expect(component.validity?.valueMissing).to.be.false;
177
+ expect(component.checkValidity()).to.be.true;
178
+ expect(component.reportValidity()).to.be.true;
179
+ expect(component.shadowRoot?.querySelector('input')?.getAttribute('aria-invalid')).to.equal('false');
180
180
  });
package/dist/label.d.ts CHANGED
@@ -8,8 +8,6 @@ declare global {
8
8
  /**
9
9
  * @private
10
10
  *
11
- * @description A label with a required control and optional description and tooltip.
12
- *
13
11
  * @slot - The label.
14
12
  * @slot control - The control with which the label is associated.
15
13
  * @slot summary - Additional information or context.
@@ -28,7 +26,7 @@ export default class GlideCoreLabel extends LitElement {
28
26
  split?: 'left' | 'middle';
29
27
  firstUpdated(): void;
30
28
  render(): import("lit").TemplateResult<1>;
31
- private hasDescriptionSlot;
29
+ private hasDescription;
32
30
  private hasSummarySlot;
33
31
  private hasTooltipSlot;
34
32
  private isLabelTooltip;
package/dist/label.js CHANGED
@@ -1 +1 @@
1
- var __decorate=this&&this.__decorate||function(e,t,o,l){var i,s=arguments.length,r=s<3?t:null===l?l=Object.getOwnPropertyDescriptor(t,o):l;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)r=Reflect.decorate(e,t,o,l);else for(var a=e.length-1;a>=0;a--)(i=e[a])&&(r=(s<3?i(r):s>3?i(t,o,r):i(t,o))||r);return s>3&&r&&Object.defineProperty(t,o,r),r};import"./tooltip.js";import{LitElement,html,svg}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 ow,{owSlot}from"./library/ow.js";import styles from"./label.styles.js";const infoCircleIcon=svg`<circle cx="12" cy="12" r="10" stroke="currentColor" stroke-width="2"><path d="M12 16L12 12" stroke="currentColor" stroke-width="2" stroke-linecap="round"><circle cx="12" cy="8" r="1" fill="currentColor">`;let GlideCoreLabel=class GlideCoreLabel extends LitElement{constructor(){super(...arguments),this.disabled=!1,this.error=!1,this.hide=!1,this.orientation="horizontal",this.required=!1,this.hasDescriptionSlot=!1,this.hasSummarySlot=!1,this.hasTooltipSlot=!1,this.isLabelTooltip=!1,this.label="",this.#e=createRef(),this.#t=createRef(),this.#o=createRef(),this.#l=createRef(),this.#i=new LocalizeController(this),this.#s=createRef(),this.#r=createRef()}static{this.shadowRootOptions={...LitElement.shadowRootOptions,mode:"closed"}}static{this.styles=styles}firstUpdated(){owSlot(this.#t.value),owSlot(this.#e.value)}render(){return html`<div class="${classMap({component:!0,horizontal:"horizontal"===this.orientation,vertical:"vertical"===this.orientation,left:"left"===this.split,middle:"middle"===this.split,"hidden-label":this.hide})}"><div class="${classMap({"tooltips-and-label":!0,hidden:this.hide,left:"left"===this.split,middle:"middle"===this.split})}" part="tooltips-and-label"><glide-core-tooltip class="${classMap({"optional-tooltip":!0,vertical:"vertical"===this.orientation,visible:this.hasTooltipSlot})}" placement="${"vertical"===this.orientation?"right":"bottom"}"><span class="optional-tooltip-target" slot="target" tabindex="0"><svg aria-label="${this.#i.term("moreInformation")}" width="16" height="16" viewBox="0 0 24 24" fill="none">${infoCircleIcon}</svg></span><slot name="tooltip" @slotchange="${this.#a}" ${ref(this.#r)}></slot></glide-core-tooltip><glide-core-tooltip class="label-tooltip" placement="right" ?disabled="${!this.isLabelTooltip}"><div class="${classMap({label:!0,disabled:this.disabled})}" data-test="label" slot="target" ${ref(this.#l)}><slot @slotchange="${this.#n}" ${ref(this.#t)}></slot>${this.required?html`<span aria-hidden="true" class="required-symbol">*</span>`:""}</div><div aria-hidden="true">${this.label}</div></glide-core-tooltip></div><div class="control-and-summary"><slot class="${classMap({control:!0,error:this.error,disabled:this.disabled,vertical:"vertical"===this.orientation,summaryless:!this.hasSummarySlot,"hidden-label":this.hide})}" name="control" @slotchange="${this.#d}" ${ref(this.#e)}></slot><slot class="${classMap({summary:!0,error:this.error})}" name="summary" @slotchange="${this.#c}" ${ref(this.#s)}></slot></div><slot class="${classMap({description:!0,visible:this.hasDescriptionSlot,error:this.error,tooltip:this.hasTooltipSlot})}" id="description" name="description" @slotchange="${this.#h}" ${ref(this.#o)}></slot></div>`}#e;#t;#o;#l;#i;#s;#r;#d(){owSlot(this.#e.value)}#n(){owSlot(this.#t.value);const e=this.#t.value?.assignedElements().at(0),t=this.#l.value;ow(e,ow.object.instanceOf(Element)),ow(t,ow.object.instanceOf(HTMLElement)),e.textContent&&(this.label=e.textContent);new ResizeObserver((()=>{this.isLabelTooltip=e.getBoundingClientRect().width>t.getBoundingClientRect().width})).observe(t)}#h(){const e=this.#o.value?.assignedNodes({flatten:!0});this.hasDescriptionSlot=Boolean(e&&e.length>0)}#c(){const e=this.#s.value?.assignedNodes({flatten:!0});this.hasSummarySlot=Boolean(e&&e.length>0)}#a(){const e=this.#r.value?.assignedNodes({flatten:!0});this.hasTooltipSlot=Boolean(e&&e.length>0)}};__decorate([property({reflect:!0,type:Boolean})],GlideCoreLabel.prototype,"disabled",void 0),__decorate([property({reflect:!0,type:Boolean})],GlideCoreLabel.prototype,"error",void 0),__decorate([property({reflect:!0,type:Boolean})],GlideCoreLabel.prototype,"hide",void 0),__decorate([property({reflect:!0})],GlideCoreLabel.prototype,"orientation",void 0),__decorate([property({reflect:!0,type:Boolean})],GlideCoreLabel.prototype,"required",void 0),__decorate([property()],GlideCoreLabel.prototype,"split",void 0),__decorate([state()],GlideCoreLabel.prototype,"hasDescriptionSlot",void 0),__decorate([state()],GlideCoreLabel.prototype,"hasSummarySlot",void 0),__decorate([state()],GlideCoreLabel.prototype,"hasTooltipSlot",void 0),__decorate([state()],GlideCoreLabel.prototype,"isLabelTooltip",void 0),__decorate([state()],GlideCoreLabel.prototype,"label",void 0),GlideCoreLabel=__decorate([customElement("glide-core-private-label")],GlideCoreLabel);export default GlideCoreLabel;
1
+ var __decorate=this&&this.__decorate||function(e,t,o,l){var i,s=arguments.length,r=s<3?t:null===l?l=Object.getOwnPropertyDescriptor(t,o):l;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)r=Reflect.decorate(e,t,o,l);else for(var a=e.length-1;a>=0;a--)(i=e[a])&&(r=(s<3?i(r):s>3?i(t,o,r):i(t,o))||r);return s>3&&r&&Object.defineProperty(t,o,r),r};import"./tooltip.js";import{LitElement,html,svg}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 ow,{owSlot}from"./library/ow.js";import styles from"./label.styles.js";const infoCircleIcon=svg`<circle cx="12" cy="12" r="10" stroke="currentColor" stroke-width="2"><path d="M12 16L12 12" stroke="currentColor" stroke-width="2" stroke-linecap="round"><circle cx="12" cy="8" r="1" fill="currentColor">`;let GlideCoreLabel=class GlideCoreLabel extends LitElement{constructor(){super(...arguments),this.disabled=!1,this.error=!1,this.hide=!1,this.orientation="horizontal",this.required=!1,this.hasDescription=!1,this.hasSummarySlot=!1,this.hasTooltipSlot=!1,this.isLabelTooltip=!1,this.label="",this.#e=createRef(),this.#t=createRef(),this.#o=createRef(),this.#l=createRef(),this.#i=new LocalizeController(this),this.#s=createRef(),this.#r=createRef()}static{this.shadowRootOptions={...LitElement.shadowRootOptions,mode:"closed"}}static{this.styles=styles}firstUpdated(){owSlot(this.#t.value),owSlot(this.#e.value);const e=new ResizeObserver((()=>{this.hasDescription=Boolean(this.#o.value&&this.#o.value.offsetHeight>0)}));this.#o.value&&e.observe(this.#o.value)}render(){return html`<div class="${classMap({component:!0,horizontal:"horizontal"===this.orientation,vertical:"vertical"===this.orientation,left:"left"===this.split,middle:"middle"===this.split,"hidden-label":this.hide})}"><div class="${classMap({"tooltips-and-label":!0,hidden:this.hide,left:"left"===this.split,middle:"middle"===this.split})}" part="tooltips-and-label"><glide-core-tooltip class="${classMap({"optional-tooltip":!0,vertical:"vertical"===this.orientation,visible:this.hasTooltipSlot})}" placement="${"vertical"===this.orientation?"right":"bottom"}"><span class="optional-tooltip-target" slot="target" tabindex="0"><svg aria-label="${this.#i.term("moreInformation")}" width="16" height="16" viewBox="0 0 24 24" fill="none">${infoCircleIcon}</svg></span><slot name="tooltip" @slotchange="${this.#a}" ${ref(this.#r)}></slot></glide-core-tooltip><glide-core-tooltip class="label-tooltip" placement="right" ?disabled="${!this.isLabelTooltip}"><div class="${classMap({label:!0,disabled:this.disabled})}" data-test="label" slot="target" ${ref(this.#l)}><slot @slotchange="${this.#n}" ${ref(this.#t)}></slot>${this.required?html`<span aria-hidden="true" class="required-symbol">*</span>`:""}</div><div aria-hidden="true">${this.label}</div></glide-core-tooltip></div><div class="control-and-summary"><slot class="${classMap({control:!0,error:this.error,disabled:this.disabled,vertical:"vertical"===this.orientation,summaryless:!this.hasSummarySlot,"hidden-label":this.hide})}" name="control" @slotchange="${this.#d}" ${ref(this.#e)}></slot><slot class="${classMap({summary:!0,error:this.error})}" name="summary" @slotchange="${this.#c}" ${ref(this.#s)}></slot></div><slot class="${classMap({description:!0,content:this.hasDescription,error:this.error,tooltip:this.hasTooltipSlot})}" id="description" name="description" ${ref(this.#o)}></slot></div>`}#e;#t;#o;#l;#i;#s;#r;#d(){owSlot(this.#e.value)}#n(){owSlot(this.#t.value);const e=this.#t.value?.assignedElements().at(0),t=this.#l.value;ow(e,ow.object.instanceOf(Element)),ow(t,ow.object.instanceOf(HTMLElement)),e.textContent&&(this.label=e.textContent);new ResizeObserver((()=>{this.isLabelTooltip=e.getBoundingClientRect().width>t.getBoundingClientRect().width})).observe(t)}#c(){const e=this.#s.value?.assignedNodes({flatten:!0});this.hasSummarySlot=Boolean(e&&e.length>0)}#a(){const e=this.#r.value?.assignedNodes({flatten:!0});this.hasTooltipSlot=Boolean(e&&e.length>0)}};__decorate([property({reflect:!0,type:Boolean})],GlideCoreLabel.prototype,"disabled",void 0),__decorate([property({reflect:!0,type:Boolean})],GlideCoreLabel.prototype,"error",void 0),__decorate([property({reflect:!0,type:Boolean})],GlideCoreLabel.prototype,"hide",void 0),__decorate([property({reflect:!0})],GlideCoreLabel.prototype,"orientation",void 0),__decorate([property({reflect:!0,type:Boolean})],GlideCoreLabel.prototype,"required",void 0),__decorate([property()],GlideCoreLabel.prototype,"split",void 0),__decorate([state()],GlideCoreLabel.prototype,"hasDescription",void 0),__decorate([state()],GlideCoreLabel.prototype,"hasSummarySlot",void 0),__decorate([state()],GlideCoreLabel.prototype,"hasTooltipSlot",void 0),__decorate([state()],GlideCoreLabel.prototype,"isLabelTooltip",void 0),__decorate([state()],GlideCoreLabel.prototype,"label",void 0),GlideCoreLabel=__decorate([customElement("glide-core-private-label")],GlideCoreLabel);export default GlideCoreLabel;
@@ -160,21 +160,20 @@ import{css}from"lit";import focusOutline from"./styles/focus-outline.js";import
160
160
 
161
161
  .description {
162
162
  color: var(--glide-core-text-body-1);
163
- display: none;
163
+ display: block;
164
164
  font-family: var(--glide-core-body-xs-font-family);
165
165
  font-size: var(--glide-core-body-xs-font-size);
166
166
  font-style: var(--glide-core-body-xs-font-style);
167
167
  font-weight: var(--glide-core-body-xs-font-weight);
168
168
  grid-column: 2;
169
169
  line-height: var(--glide-core-body-xs-line-height);
170
- margin-block-start: var(--glide-core-spacing-xxs);
171
170
 
172
- &.error {
173
- color: var(--glide-core-status-error);
171
+ &.content {
172
+ margin-block-start: var(--glide-core-spacing-xxs);
174
173
  }
175
174
 
176
- &.visible {
177
- display: block;
175
+ &.error {
176
+ color: var(--glide-core-status-error);
178
177
  }
179
178
  }
180
179
  `];
@@ -13,9 +13,9 @@ it('has defaults', async () => {
13
13
  <input id="input" slot="control" />
14
14
  </glide-core-private-label>`);
15
15
  expect(component.getAttribute('error')).to.equal(null);
16
- expect(component.error).to.equal(false);
16
+ expect(component.error).to.be.false;
17
17
  expect(component.getAttribute('hide')).to.equal(null);
18
- expect(component.hide).to.equal(false);
18
+ expect(component.hide).to.be.false;
19
19
  expect(component.getAttribute('orientation')).to.equal('horizontal');
20
20
  expect(component.orientation).to.equal('horizontal');
21
21
  expect(component.hasAttribute('required')).to.be.false;
@@ -68,7 +68,7 @@ it('can be required', async () => {
68
68
  <input id="input" slot="control" />
69
69
  </glide-core-private-label>`);
70
70
  expect(component.hasAttribute('required')).to.be.true;
71
- expect(component.required).to.equal(true);
71
+ expect(component.required).to.be.true;
72
72
  const label = component.shadowRoot?.querySelector('[data-test="label"]');
73
73
  expect(label?.textContent?.includes('*')).to.be.true;
74
74
  });
@@ -78,7 +78,7 @@ it('can have an `error`', async () => {
78
78
  <input id="input" slot="control" />
79
79
  </glide-core-private-label>`);
80
80
  expect(component.hasAttribute('error')).to.be.true;
81
- expect(component.error).to.equal(true);
81
+ expect(component.error).to.be.true;
82
82
  });
83
83
  it('places the tooltip on the bottom when horizontal', async () => {
84
84
  const component = await fixture(html `<glide-core-private-label>
@@ -1 +1 @@
1
- import ow,{}from"ow";const isDevelopment=window.location.host.startsWith("localhost")||window.location.host.startsWith("127.0.0.1");export function owSlot(e){isDevelopment&&(ow(e,ow.object.is((e=>e instanceof HTMLSlotElement))),ow(e.assignedNodes().length,ow.number.is((e=>e>0)).message(e.name?`Expected a "${e.name}" slot.`:"Expected a default slot.")))}export function owSlotType(e,o=[]){if(isDevelopment&&(ow(e,ow.object.is((e=>e instanceof HTMLSlotElement))),0!==e.assignedNodes().length&&o.length>0)){const t=e.assignedNodes({flatten:!0}).filter((e=>!!(e instanceof Text&&o.includes(Text))||!(e instanceof Text)));ow(t.length,ow.number.is((e=>e>0)).message(`Expected a slotted node that extends ${o.map((({name:e})=>e)).join(" or ")}.`));for(const e of t){const t=`Expected slotted node to extend ${o.map((({name:e})=>e)).join(" or ")}. Extends ${e.constructor.name} instead.`,n=o.some((o=>e instanceof o));ow(n,ow.boolean.true.message(t))}}}const shim=new Proxy((()=>{}),{get:()=>shim,apply:()=>shim}),owOrShim=isDevelopment?ow:shim;export default owOrShim;
1
+ import ow,{}from"ow";const isDevelopment=window.location.host.startsWith("localhost")||window.location.host.startsWith("127.0.0.1");export function owSlot(e){isDevelopment&&(ow(e,ow.object.is((e=>e instanceof HTMLSlotElement))),ow(e.assignedNodes().length,ow.number.is((e=>e>0)).message(e.name?`Expected a "${e.name}" slot.`:"Expected a default slot.")))}export function owSlotType(e,o=[]){if(isDevelopment&&(ow(e,ow.object.is((e=>e instanceof HTMLSlotElement))),0!==e.assignedNodes().length&&o.length>0)){const t=e.assignedNodes({flatten:!0}).filter((e=>!!(e instanceof Text&&o.includes(Text))||!(e instanceof Text)));ow(t.length,ow.number.is((e=>e>0)).message(`Expected a slotted element that extends ${o.map((({name:e})=>e)).join(" or ")}.`));for(const e of t){const t=`Expected slotted element to extend ${o.map((({name:e})=>e)).join(" or ")}. Extends ${e.constructor.name} instead.`,n=o.some((o=>e instanceof o));ow(n,ow.boolean.true.message(t))}}}const shim=new Proxy((()=>{}),{get:()=>shim,apply:()=>shim}),owOrShim=isDevelopment?ow:shim;export default owOrShim;
@@ -5,8 +5,6 @@ declare global {
5
5
  }
6
6
  }
7
7
  /**
8
- * @description A button for use within a <glide-core-menu>.
9
- *
10
8
  * @slot icon - An icon.
11
9
  */
12
10
  export default class GlideCoreMenuButton extends LitElement {
@@ -11,11 +11,11 @@ it('has defaults', async () => {
11
11
  // typechecked, which means supplying required attributes up front.
12
12
  const component = await fixture(html `<glide-core-menu-button label="Label"></glide-core-menu-button>`);
13
13
  // Not reflected. So no attribute assertions are necessary.
14
- expect(component.privateActive).to.equal(false);
14
+ expect(component.privateActive).to.be.false;
15
15
  });
16
16
  it('can have a label', async () => {
17
- const button = await fixture(html `<glide-core-menu-button label="Label"></glide-core-menu-button>`);
18
- expect(button.shadowRoot?.textContent?.trim()).to.equal('Label');
17
+ const component = await fixture(html `<glide-core-menu-button label="Label"></glide-core-menu-button>`);
18
+ expect(component.shadowRoot?.textContent?.trim()).to.equal('Label');
19
19
  });
20
20
  it('can have an icon', async () => {
21
21
  const component = await fixture(html `<glide-core-menu-button label="Label">
package/dist/menu.d.ts CHANGED
@@ -6,9 +6,7 @@ declare global {
6
6
  }
7
7
  }
8
8
  /**
9
- * @description A basic menu.
10
- *
11
- * @slot - `<glide-core-menu-options>`.
9
+ * @slot - One of `<glide-core-menu-options>`.
12
10
  * @slot target - A focusable element against which Menu will be positioned. Opens and closes Menu when interacted with.
13
11
  */
14
12
  export default class GlideCoreMenu extends LitElement {
@@ -24,7 +22,6 @@ export default class GlideCoreMenu extends LitElement {
24
22
  createRenderRoot(): ShadowRoot;
25
23
  disconnectedCallback(): void;
26
24
  firstUpdated(): void;
27
- focus(options?: FocusOptions): void;
28
25
  private get isTargetDisabled();
29
26
  render(): import("lit").TemplateResult<1>;
30
27
  }
package/dist/menu.js CHANGED
@@ -1 +1 @@
1
- var __decorate=this&&this.__decorate||function(e,t,i,o){var n,s=arguments.length,l=s<3?t:null===o?o=Object.getOwnPropertyDescriptor(t,i):o;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)l=Reflect.decorate(e,t,i,o);else for(var a=e.length-1;a>=0;a--)(n=e[a])&&(l=(s<3?n(l):s>3?n(t,i,l):n(t,i))||l);return s>3&&l&&Object.defineProperty(t,i,l),l};import{LitElement,html}from"lit";import{autoUpdate,computePosition,flip,offset}from"@floating-ui/dom";import{createRef,ref}from"lit/directives/ref.js";import{customElement,property}from"lit/decorators.js";import{nanoid}from"nanoid";import GlideCoreMenuButton from"./menu.button.js";import GlideCoreMenuLink from"./menu.link.js";import GlideCoreMenuOptions from"./menu.options.js";import ow,{owSlot,owSlotType}from"./library/ow.js";import styles from"./menu.styles.js";let GlideCoreMenu=class GlideCoreMenu extends LitElement{constructor(){super(...arguments),this.placement="bottom-start",this.#e=createRef(),this.#t=createRef(),this.#i=!1,this.#o=!1,this.#n="large",this.#s=createRef(),this.#l=e=>{e.target&&e.target instanceof Node&&this.contains(e.target)||(this.open=!1,this.#a&&(this.#a.ariaActivedescendant=""))}}static{this.shadowRootOptions={...LitElement.shadowRootOptions,mode:"closed"}}static{this.styles=styles}get open(){return this.#o}set open(e){this.#o=e,e&&!this.isTargetDisabled?this.#r():this.#c()}get size(){return this.#n}set size(e){this.#n=e,this.#a&&(this.#a.privateSize=e)}connectedCallback(){super.connectedCallback(),document.addEventListener("click",this.#l,{capture:!0})}createRenderRoot(){return this.#d=super.createRenderRoot(),this.#d}disconnectedCallback(){super.disconnectedCallback(),document.removeEventListener("click",this.#l,{capture:!0})}firstUpdated(){ow(this.#a,ow.object.instanceOf(GlideCoreMenuOptions)),owSlot(this.#t.value),owSlot(this.#s.value),owSlotType(this.#t.value,[GlideCoreMenuOptions]),this.#t.value.popover="manual";const e=this.#h?.at(0);this.open&&e&&!this.isTargetDisabled&&(e.privateActive=!0,this.#r())}focus(e){this.#p&&"focus"in this.#p&&this.#p?.focus(e)}get isTargetDisabled(){const e=this.#p&&"disabled"in this.#p&&this.#p.disabled,t=this.#p&&"true"===this.#p.ariaDisabled;return Boolean(e)||Boolean(t)}render(){return html`<div class="component" @focusout="${this.#u}" ${ref(this.#e)}><slot class="target-slot" name="target" @click="${this.#m}" @keydown="${this.#f}" @slotchange="${this.#E}" ${ref(this.#s)}></slot><slot class="default-slot" @click="${this.#v}" @focusin="${this.#g}" @keydown="${this.#f}" @mouseover="${this.#w}" @slotchange="${this.#S}" ${ref(this.#t)}></slot></div>`}#C;#e;#t;#i;#o;#d;#n;#s;get#y(){return this.#h?.find((({privateActive:e})=>e))}#l;#c(){this.#C?.(),this.#a&&(this.#a.ariaActivedescendant=""),this.#p&&(this.#p.ariaExpanded="false"),this.#t.value?.hidePopover()}get#a(){const e=this.#t.value?.assignedElements().at(0);return e instanceof GlideCoreMenuOptions?e:null}#S(){ow(this.#a,ow.object.instanceOf(GlideCoreMenuOptions)),owSlot(this.#t.value),owSlotType(this.#t.value,[GlideCoreMenuOptions]);const e=this.#h?.at(0);e&&(e.privateActive=!0),this.#a.privateSize=this.size}#v(){this.open=!1}#g(e){(e.target instanceof GlideCoreMenuButton||e.target instanceof GlideCoreMenuLink)&&this.#y&&this.#a&&(this.#y.privateActive=!1,e.target.privateActive=!0,this.#a.ariaActivedescendant=e.target.id)}#w(e){if(e.target instanceof GlideCoreMenuLink||e.target instanceof GlideCoreMenuButton){if(this.#h)for(const t of this.#h)t.privateActive=t===e.target;this.#a&&(this.#a.ariaActivedescendant=e.target.id)}}#u(e){const t=e.relatedTarget instanceof HTMLElement&&this.#d?.contains(e.relatedTarget),i=e.relatedTarget instanceof GlideCoreMenuOptions,o=e.relatedTarget instanceof GlideCoreMenuButton||e.relatedTarget instanceof GlideCoreMenuLink;t||i||o||(this.open=!1)}#f(e){if(ow(this.#a,ow.object.instanceOf(GlideCoreMenuOptions)),[" ","Enter"].includes(e.key)&&this.open)return this.open=!1,this.focus(),this.#y?.dispatchEvent(new PointerEvent("click",{bubbles:!0})),void(this.#i=!0);if(["Escape"].includes(e.key)&&this.open)return this.open=!1,void this.focus();if(["ArrowUp","ArrowDown"].includes(e.key)&&!this.open&&this.#y)return e.preventDefault(),this.open=!0,void(this.#a.ariaActivedescendant=this.#y.id);if(this.open){ow(this.#h,ow.array),ow(this.#a,ow.object.instanceOf(GlideCoreMenuOptions)),ow(this.#y,ow.object.is((e=>e instanceof GlideCoreMenuButton||e instanceof GlideCoreMenuLink)));const t=this.#h.indexOf(this.#y);if("ArrowUp"===e.key&&!e.metaKey){e.preventDefault();const i=this.#h.at(t-1);return void(i&&0!==t&&(this.#y.privateActive=!1,this.#a.ariaActivedescendant=i.id,i.privateActive=!0))}if("ArrowDown"===e.key&&!e.metaKey){e.preventDefault();const i=this.#h.at(t+1);return void(i&&(this.#y.privateActive=!1,this.#a.ariaActivedescendant=i.id,i.privateActive=!0))}if("ArrowUp"===e.key&&e.metaKey||"Home"===e.key||"PageUp"===e.key){e.preventDefault();const t=this.#h.at(0);return void(t&&(this.#y.privateActive=!1,this.#a.ariaActivedescendant=t.id,t.privateActive=!0))}if("ArrowDown"===e.key&&e.metaKey||"End"===e.key||"PageDown"===e.key){e.preventDefault();const t=this.#h.at(-1);return void(t&&(this.#y.privateActive=!1,this.#a.ariaActivedescendant=t.id,t.privateActive=!0))}}}#E(){owSlot(this.#s.value),ow(this.#p,ow.object.instanceOf(Element)),ow(this.#a,ow.object.instanceOf(GlideCoreMenuOptions));new MutationObserver((e=>{e.some((e=>"disabled"===e.attributeName||"aria-disabled"===e.attributeName))&&(this.open&&!this.isTargetDisabled?this.#r():this.#c())})).observe(this.#p,{attributes:!0}),this.#p.ariaHasPopup="true",this.#p.id=nanoid(),this.#p.setAttribute("aria-controls",this.#a.id),this.#a.ariaLabelledby=this.#p.id,this.open&&!this.isTargetDisabled?this.#r():this.#c()}#m(){this.isTargetDisabled?this.#c():this.#i?this.#i=!1:this.#h&&this.#h.length>0&&(this.open=!this.open)}get#h(){let e=this.#t.value?.assignedElements()?.at(0)?.children;const t=e?.[0];if(t instanceof HTMLSlotElement&&(e=t.assignedElements()),e)return[...e].filter((e=>e instanceof GlideCoreMenuLink||e instanceof GlideCoreMenuButton))}#r(){this.#C?.(),this.#p&&this.#t.value&&(this.#C=autoUpdate(this.#p,this.#t.value,(()=>{(async()=>{if(this.#p&&this.#t.value){const{x:e,y:t,placement:i}=await computePosition(this.#p,this.#t.value,{placement:this.placement,middleware:[offset({mainAxis:Number.parseFloat(window.getComputedStyle(document.body).getPropertyValue("--glide-core-spacing-xxs"))*Number.parseFloat(window.getComputedStyle(document.documentElement).fontSize)}),flip()]});this.#t.value.dataset.placement=i,Object.assign(this.#t.value.style,{left:`${e}px`,top:`${t}px`})}this.#t.value?.showPopover(),this.#a&&this.#y?.id&&(this.#a.ariaActivedescendant=this.#y.id),this.#p&&(this.#p.ariaExpanded="true")})()})))}get#p(){return this.#s.value?.assignedElements().at(0)}};__decorate([property({reflect:!0,type:Boolean})],GlideCoreMenu.prototype,"open",null),__decorate([property({reflect:!0})],GlideCoreMenu.prototype,"placement",void 0),__decorate([property({reflect:!0})],GlideCoreMenu.prototype,"size",null),GlideCoreMenu=__decorate([customElement("glide-core-menu")],GlideCoreMenu);export default GlideCoreMenu;
1
+ var __decorate=this&&this.__decorate||function(e,t,i,o){var n,s=arguments.length,l=s<3?t:null===o?o=Object.getOwnPropertyDescriptor(t,i):o;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)l=Reflect.decorate(e,t,i,o);else for(var a=e.length-1;a>=0;a--)(n=e[a])&&(l=(s<3?n(l):s>3?n(t,i,l):n(t,i))||l);return s>3&&l&&Object.defineProperty(t,i,l),l};import{LitElement,html}from"lit";import{autoUpdate,computePosition,flip,offset}from"@floating-ui/dom";import{createRef,ref}from"lit/directives/ref.js";import{customElement,property}from"lit/decorators.js";import{nanoid}from"nanoid";import GlideCoreMenuButton from"./menu.button.js";import GlideCoreMenuLink from"./menu.link.js";import GlideCoreMenuOptions from"./menu.options.js";import ow,{owSlot,owSlotType}from"./library/ow.js";import styles from"./menu.styles.js";let GlideCoreMenu=class GlideCoreMenu extends LitElement{constructor(){super(...arguments),this.placement="bottom-start",this.#e=createRef(),this.#t=createRef(),this.#i=!1,this.#o=!1,this.#n=!1,this.#s="large",this.#l=createRef(),this.#a=()=>{this.#n?this.#n=!1:(this.open=!1,this.#r&&(this.#r.ariaActivedescendant=""))}}static{this.shadowRootOptions={...LitElement.shadowRootOptions,mode:"closed"}}static{this.styles=styles}get open(){return this.#o}set open(e){this.#o=e,e&&!this.isTargetDisabled?this.#c():this.#h()}get size(){return this.#s}set size(e){this.#s=e,this.#r&&(this.#r.privateSize=e)}connectedCallback(){super.connectedCallback(),document.addEventListener("click",this.#a,{capture:!0})}createRenderRoot(){return this.#d=super.createRenderRoot(),this.#d}disconnectedCallback(){super.disconnectedCallback(),document.removeEventListener("click",this.#a,{capture:!0})}firstUpdated(){ow(this.#r,ow.object.instanceOf(GlideCoreMenuOptions)),owSlot(this.#t.value),owSlot(this.#l.value),owSlotType(this.#t.value,[GlideCoreMenuOptions]),this.#t.value.popover="manual";const e=this.#p?.at(0);this.open&&e&&!this.isTargetDisabled&&(e.privateActive=!0,this.#c()),this.#l.value.addEventListener("mouseup",(()=>{this.#n=!0}))}get isTargetDisabled(){const e=this.#u&&"disabled"in this.#u&&this.#u.disabled,t=this.#u&&"true"===this.#u.ariaDisabled;return Boolean(e)||Boolean(t)}render(){return html`<div class="component" @focusout="${this.#m}" ${ref(this.#e)}><slot class="target-slot" name="target" @click="${this.#f}" @keydown="${this.#E}" @slotchange="${this.#v}" ${ref(this.#l)}></slot><slot class="default-slot" @click="${this.#g}" @focusin="${this.#S}" @keydown="${this.#E}" @mouseover="${this.#w}" @slotchange="${this.#C}" ${ref(this.#t)}></slot></div>`}#y;#e;#t;#i;#o;#n;#d;#s;#l;get#R(){return this.#p?.find((({privateActive:e})=>e))}#a;#k(e){this.#u&&"focus"in this.#u&&this.#u?.focus(e)}#h(){this.#y?.(),this.#r&&(this.#r.ariaActivedescendant=""),this.#u&&(this.#u.ariaExpanded="false"),this.#t.value?.hidePopover()}get#r(){const e=this.#t.value?.assignedElements().at(0);return e instanceof GlideCoreMenuOptions?e:null}#C(){ow(this.#r,ow.object.instanceOf(GlideCoreMenuOptions)),owSlot(this.#t.value),owSlotType(this.#t.value,[GlideCoreMenuOptions]);const e=this.#p?.at(0);e&&(e.privateActive=!0),this.#r.privateSize=this.size}#g(){this.open=!1}#S(e){(e.target instanceof GlideCoreMenuButton||e.target instanceof GlideCoreMenuLink)&&this.#R&&this.#r&&(this.#R.privateActive=!1,e.target.privateActive=!0,this.#r.ariaActivedescendant=e.target.id)}#w(e){if(e.target instanceof GlideCoreMenuLink||e.target instanceof GlideCoreMenuButton){if(this.#p)for(const t of this.#p)t.privateActive=t===e.target;this.#r&&(this.#r.ariaActivedescendant=e.target.id)}}#m(e){const t=e.relatedTarget instanceof HTMLElement&&this.#d?.contains(e.relatedTarget),i=e.relatedTarget instanceof GlideCoreMenuOptions,o=e.relatedTarget instanceof GlideCoreMenuButton||e.relatedTarget instanceof GlideCoreMenuLink;t||i||o||(this.open=!1)}#E(e){if(ow(this.#r,ow.object.instanceOf(GlideCoreMenuOptions)),[" ","Enter"].includes(e.key)&&this.open)return this.open=!1,this.#k(),this.#R?.click(),void(this.#i=!0);if(["Escape"].includes(e.key)&&this.open)return this.open=!1,void this.#k();if(["ArrowUp","ArrowDown"].includes(e.key)&&!this.open&&this.#R)return e.preventDefault(),this.open=!0,void(this.#r.ariaActivedescendant=this.#R.id);if(this.open){ow(this.#p,ow.array),ow(this.#r,ow.object.instanceOf(GlideCoreMenuOptions)),ow(this.#R,ow.object.is((e=>e instanceof GlideCoreMenuButton||e instanceof GlideCoreMenuLink)));const t=this.#p.indexOf(this.#R);if("ArrowUp"===e.key&&!e.metaKey){e.preventDefault();const i=this.#p.at(t-1);return void(i&&0!==t&&(this.#R.privateActive=!1,this.#r.ariaActivedescendant=i.id,i.privateActive=!0))}if("ArrowDown"===e.key&&!e.metaKey){e.preventDefault();const i=this.#p.at(t+1);return void(i&&(this.#R.privateActive=!1,this.#r.ariaActivedescendant=i.id,i.privateActive=!0))}if("ArrowUp"===e.key&&e.metaKey||"Home"===e.key||"PageUp"===e.key){e.preventDefault();const t=this.#p.at(0);return void(t&&(this.#R.privateActive=!1,this.#r.ariaActivedescendant=t.id,t.privateActive=!0))}if("ArrowDown"===e.key&&e.metaKey||"End"===e.key||"PageDown"===e.key){e.preventDefault();const t=this.#p.at(-1);return void(t&&(this.#R.privateActive=!1,this.#r.ariaActivedescendant=t.id,t.privateActive=!0))}}}#v(){owSlot(this.#l.value),ow(this.#u,ow.object.instanceOf(Element)),ow(this.#r,ow.object.instanceOf(GlideCoreMenuOptions));new MutationObserver((()=>{this.open&&!this.isTargetDisabled?this.#c():this.#h()})).observe(this.#u,{attributes:!0,attributeFilter:["aria-disabled","disabled"]}),this.#u.ariaHasPopup="true",this.#u.id=nanoid(),this.#u.setAttribute("aria-controls",this.#r.id),this.#r.ariaLabelledby=this.#u.id,this.open&&!this.isTargetDisabled?this.#c():this.#h()}#f(){this.isTargetDisabled?this.#h():this.#i?this.#i=!1:this.#p&&this.#p.length>0&&(this.open=!this.open)}get#p(){let e=this.#t.value?.assignedElements()?.at(0)?.children;const t=e?.[0];if(t instanceof HTMLSlotElement&&(e=t.assignedElements()),e)return[...e].filter((e=>e instanceof GlideCoreMenuLink||e instanceof GlideCoreMenuButton))}#c(){this.#y?.(),this.#u&&this.#t.value&&(this.#y=autoUpdate(this.#u,this.#t.value,(()=>{(async()=>{if(this.#u&&this.#t.value){const{x:e,y:t,placement:i}=await computePosition(this.#u,this.#t.value,{placement:this.placement,middleware:[offset({mainAxis:Number.parseFloat(window.getComputedStyle(document.body).getPropertyValue("--glide-core-spacing-xxs"))*Number.parseFloat(window.getComputedStyle(document.documentElement).fontSize)}),flip()]});this.#t.value.dataset.placement=i,Object.assign(this.#t.value.style,{left:`${e}px`,top:`${t}px`})}this.#t.value?.showPopover(),this.#r&&this.#R?.id&&(this.#r.ariaActivedescendant=this.#R.id),this.#u&&(this.#u.ariaExpanded="true")})()})))}get#u(){return this.#l.value?.assignedElements().at(0)}};__decorate([property({reflect:!0,type:Boolean})],GlideCoreMenu.prototype,"open",null),__decorate([property({reflect:!0})],GlideCoreMenu.prototype,"placement",void 0),__decorate([property({reflect:!0})],GlideCoreMenu.prototype,"size",null),GlideCoreMenu=__decorate([customElement("glide-core-menu")],GlideCoreMenu);export default GlideCoreMenu;
@@ -5,8 +5,6 @@ declare global {
5
5
  }
6
6
  }
7
7
  /**
8
- * @description A link for use within a <glide-core-menu>.
9
- *
10
8
  * @slot icon - An icon.
11
9
  */
12
10
  export default class GlideCoreMenuLink extends LitElement {
@@ -16,6 +14,7 @@ export default class GlideCoreMenuLink extends LitElement {
16
14
  label?: string;
17
15
  url?: string;
18
16
  privateActive: boolean;
17
+ click(): void;
19
18
  connectedCallback(): void;
20
19
  render(): import("lit").TemplateResult<1>;
21
20
  }
package/dist/menu.link.js CHANGED
@@ -1 +1 @@
1
- var __decorate=this&&this.__decorate||function(e,t,i,o){var r,n=arguments.length,l=n<3?t:null===o?o=Object.getOwnPropertyDescriptor(t,i):o;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)l=Reflect.decorate(e,t,i,o);else for(var s=e.length-1;s>=0;s--)(r=e[s])&&(l=(n<3?r(l):n>3?r(t,i,l):r(t,i))||l);return n>3&&l&&Object.defineProperty(t,i,l),l};import{LitElement,html}from"lit";import{classMap}from"lit/directives/class-map.js";import{customElement,property}from"lit/decorators.js";import{ifDefined}from"lit/directives/if-defined.js";import{nanoid}from"nanoid";import styles from"./menu.link.styles.js";let GlideCoreMenuLink=class GlideCoreMenuLink extends LitElement{constructor(){super(...arguments),this.privateActive=!1,this.#e=nanoid()}static{this.shadowRootOptions={...LitElement.shadowRootOptions,mode:"closed"}}static{this.styles=styles}connectedCallback(){super.connectedCallback(),this.id=this.#e,this.role="menuitem",this.tabIndex=-1}render(){return html`<a class="${classMap({component:!0,active:this.privateActive})}" data-test="component" href="${ifDefined(this.url)}"><slot name="icon"></slot>${this.label}</a>`}#e};__decorate([property({reflect:!0})],GlideCoreMenuLink.prototype,"label",void 0),__decorate([property({reflect:!0})],GlideCoreMenuLink.prototype,"url",void 0),__decorate([property({type:Boolean})],GlideCoreMenuLink.prototype,"privateActive",void 0),GlideCoreMenuLink=__decorate([customElement("glide-core-menu-link")],GlideCoreMenuLink);export default GlideCoreMenuLink;
1
+ var __decorate=this&&this.__decorate||function(e,t,i,o){var r,n=arguments.length,l=n<3?t:null===o?o=Object.getOwnPropertyDescriptor(t,i):o;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)l=Reflect.decorate(e,t,i,o);else for(var s=e.length-1;s>=0;s--)(r=e[s])&&(l=(n<3?r(l):n>3?r(t,i,l):r(t,i))||l);return n>3&&l&&Object.defineProperty(t,i,l),l};import{LitElement,html}from"lit";import{classMap}from"lit/directives/class-map.js";import{createRef,ref}from"lit/directives/ref.js";import{customElement,property}from"lit/decorators.js";import{ifDefined}from"lit/directives/if-defined.js";import{nanoid}from"nanoid";import styles from"./menu.link.styles.js";let GlideCoreMenuLink=class GlideCoreMenuLink extends LitElement{constructor(){super(...arguments),this.privateActive=!1,this.#e=createRef(),this.#t=nanoid()}static{this.shadowRootOptions={...LitElement.shadowRootOptions,mode:"closed"}}static{this.styles=styles}click(){this.#e.value?.click()}connectedCallback(){super.connectedCallback(),this.id=this.#t,this.role="menuitem",this.tabIndex=-1}render(){return html`<a class="${classMap({component:!0,active:this.privateActive})}" data-test="component" href="${ifDefined(this.url)}" ${ref(this.#e)}><slot name="icon"></slot>${this.label}</a>`}#e;#t};__decorate([property({reflect:!0})],GlideCoreMenuLink.prototype,"label",void 0),__decorate([property({reflect:!0})],GlideCoreMenuLink.prototype,"url",void 0),__decorate([property({type:Boolean})],GlideCoreMenuLink.prototype,"privateActive",void 0),GlideCoreMenuLink=__decorate([customElement("glide-core-menu-link")],GlideCoreMenuLink);export default GlideCoreMenuLink;
@@ -5,8 +5,6 @@ declare global {
5
5
  }
6
6
  }
7
7
  /**
8
- * @description An options container for use within a <glide-core-menu>.
9
- *
10
8
  * @slot - One or more of <glide-core-menu-link> or <glide-core-menu-button>.
11
9
  */
12
10
  export default class GlideCoreMenuOptions extends LitElement {
@@ -55,8 +55,8 @@ it('dispatches one link "click" event when a link is selected via Space', async
55
55
  const link = component.querySelector('glide-core-menu-link');
56
56
  assert(link);
57
57
  link.addEventListener('click', spy);
58
- component.focus();
59
- sendKeys({ press: 'Space' });
58
+ component.querySelector('button')?.focus();
59
+ sendKeys({ press: ' ' });
60
60
  const event = await oneEvent(link, 'click');
61
61
  expect(event instanceof PointerEvent).to.be.true;
62
62
  expect(event.bubbles).to.be.true;
@@ -75,8 +75,8 @@ it('dispatches one button "click" event when a button is selected via Space', as
75
75
  const button = component.querySelector('glide-core-menu-button');
76
76
  assert(button);
77
77
  button.addEventListener('click', spy);
78
- component.focus();
79
- sendKeys({ press: 'Space' });
78
+ component.querySelector('button')?.focus();
79
+ sendKeys({ press: ' ' });
80
80
  const event = await oneEvent(button, 'click');
81
81
  expect(event instanceof PointerEvent).to.be.true;
82
82
  expect(event.bubbles).to.be.true;
@@ -95,7 +95,7 @@ it('dispatches one link "click" event when a link is selected via Enter', async
95
95
  const link = component.querySelector('glide-core-menu-link');
96
96
  assert(link);
97
97
  link.addEventListener('click', spy);
98
- component.focus();
98
+ component.querySelector('button')?.focus();
99
99
  sendKeys({ press: 'Enter' });
100
100
  const event = await oneEvent(link, 'click');
101
101
  expect(event instanceof PointerEvent).to.be.true;
@@ -115,7 +115,7 @@ it('dispatches one button "click" event when a button is selected via Enter', as
115
115
  const button = component.querySelector('glide-core-menu-button');
116
116
  assert(button);
117
117
  button.addEventListener('click', spy);
118
- component.focus();
118
+ component.querySelector('button')?.focus();
119
119
  sendKeys({ press: 'Enter' });
120
120
  const event = await oneEvent(button, 'click');
121
121
  expect(event instanceof PointerEvent).to.be.true;