@crowdstrike/glide-core 0.9.6 → 0.11.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 (216) 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.events.js +9 -0
  38. package/dist/checkbox.test.focus.js +4 -2
  39. package/dist/checkbox.test.interactions.js +11 -11
  40. package/dist/drawer.d.ts +2 -5
  41. package/dist/drawer.js +1 -1
  42. package/dist/drawer.test.accessibility.js +8 -8
  43. package/dist/drawer.test.basics.js +16 -16
  44. package/dist/drawer.test.closing.js +18 -16
  45. package/dist/drawer.test.events.js +13 -24
  46. package/dist/drawer.test.methods.js +22 -22
  47. package/dist/dropdown.d.ts +7 -5
  48. package/dist/dropdown.js +1 -1
  49. package/dist/dropdown.option.d.ts +2 -3
  50. package/dist/dropdown.option.js +1 -1
  51. package/dist/dropdown.option.styles.js +31 -19
  52. package/dist/dropdown.option.test.basics.js +4 -4
  53. package/dist/dropdown.option.test.events.js +9 -1
  54. package/dist/dropdown.option.test.interactions.single.js +2 -2
  55. package/dist/dropdown.styles.js +39 -3
  56. package/dist/dropdown.test.basics.d.ts +1 -1
  57. package/dist/dropdown.test.basics.js +27 -14
  58. package/dist/dropdown.test.basics.multiple.js +65 -32
  59. package/dist/dropdown.test.basics.single.js +49 -0
  60. package/dist/dropdown.test.events.filterable.js +13 -2
  61. package/dist/dropdown.test.focus.filterable.js +12 -3
  62. package/dist/dropdown.test.focus.js +18 -2
  63. package/dist/dropdown.test.form.multiple.js +3 -2
  64. package/dist/dropdown.test.interactions.filterable.js +141 -45
  65. package/dist/dropdown.test.interactions.js +24 -0
  66. package/dist/dropdown.test.interactions.multiple.js +87 -30
  67. package/dist/dropdown.test.interactions.single.js +40 -4
  68. package/dist/form-controls-layout.d.ts +0 -2
  69. package/dist/icon-button.d.ts +2 -4
  70. package/dist/icon-button.js +1 -1
  71. package/dist/icon-button.test.basics.js +14 -82
  72. package/dist/icon-button.test.focus.d.ts +1 -0
  73. package/dist/icon-button.test.focus.js +13 -0
  74. package/dist/input.d.ts +4 -5
  75. package/dist/input.js +1 -1
  76. package/dist/input.styles.js +4 -4
  77. package/dist/input.test.basics.js +0 -52
  78. package/dist/input.test.events.js +27 -27
  79. package/dist/input.test.focus.js +27 -26
  80. package/dist/input.test.form.js +6 -6
  81. package/dist/input.test.validity.js +130 -130
  82. package/dist/label.d.ts +1 -3
  83. package/dist/label.js +1 -1
  84. package/dist/label.styles.js +5 -6
  85. package/dist/label.test.basics.js +4 -4
  86. package/dist/library/ow.js +1 -1
  87. package/dist/menu.button.d.ts +0 -2
  88. package/dist/menu.button.test.basics.js +3 -3
  89. package/dist/menu.d.ts +1 -4
  90. package/dist/menu.js +1 -1
  91. package/dist/menu.link.d.ts +1 -2
  92. package/dist/menu.link.js +1 -1
  93. package/dist/menu.options.d.ts +0 -2
  94. package/dist/menu.test.events.js +6 -6
  95. package/dist/menu.test.focus.js +5 -18
  96. package/dist/menu.test.interactions.js +48 -24
  97. package/dist/modal.d.ts +6 -17
  98. package/dist/modal.icon-button.d.ts +0 -2
  99. package/dist/modal.icon-button.test.basics.js +3 -3
  100. package/dist/modal.js +1 -1
  101. package/dist/modal.styles.js +13 -19
  102. package/dist/modal.tertiary-icon.d.ts +0 -3
  103. package/dist/modal.tertiary-icon.test.basics.js +3 -3
  104. package/dist/modal.test.basics.js +9 -5
  105. package/dist/modal.test.close.js +2 -2
  106. package/dist/modal.test.events.js +2 -2
  107. package/dist/radio-group.d.ts +0 -3
  108. package/dist/radio-group.js +1 -1
  109. package/dist/radio-group.test.basics.js +61 -61
  110. package/dist/radio-group.test.events.js +13 -13
  111. package/dist/radio-group.test.focus.js +1 -1
  112. package/dist/radio-group.test.form.js +2 -2
  113. package/dist/radio-group.test.validity.js +12 -12
  114. package/dist/radio.d.ts +0 -3
  115. package/dist/radio.styles.js +4 -12
  116. package/dist/split-button.d.ts +8 -11
  117. package/dist/split-button.js +1 -1
  118. package/dist/split-button.primary-button.d.ts +21 -0
  119. package/dist/split-button.primary-button.js +1 -0
  120. package/dist/split-button.primary-button.styles.js +96 -0
  121. package/dist/split-button.primary-button.test.basics.d.ts +1 -0
  122. package/dist/split-button.primary-button.test.basics.js +31 -0
  123. package/dist/split-button.primary-button.test.focus.d.ts +1 -0
  124. package/dist/split-button.primary-button.test.focus.js +14 -0
  125. package/dist/split-button.primary-link.d.ts +19 -0
  126. package/dist/split-button.primary-link.js +1 -0
  127. package/dist/split-button.primary-link.test.basics.d.ts +1 -0
  128. package/dist/split-button.primary-link.test.basics.js +30 -0
  129. package/dist/split-button.primary-link.test.focus.d.ts +1 -0
  130. package/dist/split-button.primary-link.test.focus.js +15 -0
  131. package/dist/split-button.secondary-button.d.ts +25 -0
  132. package/dist/split-button.secondary-button.js +1 -0
  133. package/dist/split-button.secondary-button.styles.js +103 -0
  134. package/dist/split-button.secondary-button.test.basics.d.ts +1 -0
  135. package/dist/split-button.secondary-button.test.basics.js +58 -0
  136. package/dist/split-button.secondary-button.test.focus.d.ts +1 -0
  137. package/dist/split-button.secondary-button.test.focus.js +14 -0
  138. package/dist/split-button.secondary-button.test.interactions.d.ts +2 -0
  139. package/dist/split-button.secondary-button.test.interactions.js +30 -0
  140. package/dist/split-button.stories.d.ts +4 -3
  141. package/dist/split-button.styles.js +1 -94
  142. package/dist/split-button.test.basics.d.ts +2 -1
  143. package/dist/split-button.test.basics.js +67 -80
  144. package/dist/split-button.test.interactions.d.ts +4 -0
  145. package/dist/split-button.test.interactions.js +51 -0
  146. package/dist/styles/opacity-and-scale-animation.js +2 -6
  147. package/dist/styles/variables.css +1 -1
  148. package/dist/tab.d.ts +2 -11
  149. package/dist/tab.group.d.ts +3 -5
  150. package/dist/tab.group.js +1 -1
  151. package/dist/tab.group.styles.js +18 -15
  152. package/dist/tab.group.test.basics.js +49 -34
  153. package/dist/tab.group.test.interactions.js +17 -14
  154. package/dist/tab.panel.d.ts +0 -3
  155. package/dist/tab.test.basics.js +6 -5
  156. package/dist/tag.d.ts +5 -4
  157. package/dist/tag.js +1 -1
  158. package/dist/tag.styles.js +47 -38
  159. package/dist/tag.test.basics.js +18 -110
  160. package/dist/tag.test.events.js +12 -8
  161. package/dist/tag.test.focus.js +2 -3
  162. package/dist/tag.test.interactions.d.ts +1 -0
  163. package/dist/tag.test.interactions.js +36 -0
  164. package/dist/textarea.d.ts +2 -3
  165. package/dist/textarea.js +2 -2
  166. package/dist/textarea.test.basics.js +8 -8
  167. package/dist/textarea.test.events.js +55 -55
  168. package/dist/textarea.test.form.js +9 -9
  169. package/dist/textarea.test.validity.js +167 -135
  170. package/dist/toasts.d.ts +1 -5
  171. package/dist/toasts.test.basics.js +2 -1
  172. package/dist/toasts.toast.d.ts +1 -4
  173. package/dist/toasts.toast.js +1 -1
  174. package/dist/toasts.toast.styles.js +12 -0
  175. package/dist/toggle.d.ts +0 -2
  176. package/dist/toggle.styles.js +1 -5
  177. package/dist/toggle.test.basics.js +2 -2
  178. package/dist/toggle.test.interactions.js +7 -7
  179. package/dist/tooltip.d.ts +2 -1
  180. package/dist/tooltip.js +1 -1
  181. package/dist/tooltip.styles.js +37 -13
  182. package/dist/tooltip.test.basics.d.ts +1 -1
  183. package/dist/tooltip.test.basics.js +19 -19
  184. package/dist/tree.d.ts +0 -2
  185. package/dist/tree.item.d.ts +5 -7
  186. package/dist/tree.item.icon-button.d.ts +1 -4
  187. package/dist/tree.item.js +1 -1
  188. package/dist/tree.item.menu.d.ts +1 -2
  189. package/dist/tree.item.menu.js +1 -1
  190. package/dist/tree.item.menu.test.basics.js +31 -10
  191. package/dist/tree.item.styles.js +7 -9
  192. package/dist/tree.item.test.basics.js +43 -31
  193. package/dist/tree.test.basics.js +29 -29
  194. package/dist/tree.test.focus.js +77 -74
  195. package/package.json +12 -14
  196. package/dist/split-container.d.ts +0 -31
  197. package/dist/split-container.js +0 -1
  198. package/dist/split-container.styles.js +0 -132
  199. package/dist/split-container.test.basics.d.ts +0 -3
  200. package/dist/split-container.test.basics.js +0 -445
  201. package/dist/split-container.test.interactions.d.ts +0 -1
  202. package/dist/split-container.test.interactions.js +0 -20
  203. package/dist/split-link.d.ts +0 -25
  204. package/dist/split-link.js +0 -1
  205. package/dist/split-link.test.basics.d.ts +0 -1
  206. package/dist/split-link.test.basics.js +0 -93
  207. package/dist/split-link.test.interactions.d.ts +0 -1
  208. package/dist/split-link.test.interactions.js +0 -20
  209. package/dist/status-indicator.d.ts +0 -30
  210. package/dist/status-indicator.js +0 -1
  211. package/dist/status-indicator.stories.d.ts +0 -5
  212. package/dist/status-indicator.styles.js +0 -58
  213. package/dist/status-indicator.test.basics.d.ts +0 -1
  214. package/dist/status-indicator.test.basics.js +0 -102
  215. /package/dist/{split-container.styles.d.ts → split-button.primary-button.styles.d.ts} +0 -0
  216. /package/dist/{status-indicator.styles.d.ts → split-button.secondary-button.styles.d.ts} +0 -0
@@ -17,7 +17,7 @@ it('has defaults', async () => {
17
17
  expect(component.disabled).to.be.false;
18
18
  expect(component.selected).to.be.false;
19
19
  expect(component.value).to.equal('');
20
- expect(component).to.have.attribute('value', '');
20
+ expect(component.getAttribute('value')).to.equal('');
21
21
  expect(component).to.not.have.attribute('disabled');
22
22
  expect(component).to.not.have.attribute('selected');
23
23
  });
@@ -34,29 +34,20 @@ it('can have a label', async () => {
34
34
  ></glide-core-button-group-button>`);
35
35
  expect(component.shadowRoot?.textContent?.trim()).to.equal('Button');
36
36
  });
37
- it('can have a "prefix" slot', async () => {
38
- const component = await fixture(html `<glide-core-button-group-button label="Button">
39
- <span slot="prefix">Prefix</span>
40
- </glide-core-button-group-button>`);
41
- const assignedElements = component.shadowRoot
42
- ?.querySelector('slot[name="prefix"]')
43
- ?.assignedElements();
44
- expect(assignedElements?.at(0)?.textContent).to.equal('Prefix');
45
- });
46
37
  it('sets `aria-checked` when selected', async () => {
47
38
  const component = await fixture(html `<glide-core-button-group-button
48
39
  label="Button"
49
40
  selected
50
41
  ></glide-core-button-group-button>`);
51
42
  const radio = component.shadowRoot?.querySelector('[role="radio"]');
52
- expect(radio).to.have.attribute('aria-checked', 'true');
43
+ expect(radio?.getAttribute('aria-checked')).to.equal('true');
53
44
  });
54
45
  it('sets `aria-checked` when not selected', async () => {
55
46
  const component = await fixture(html `<glide-core-button-group-button
56
47
  label="Button"
57
48
  ></glide-core-button-group-button>`);
58
49
  const radio = component.shadowRoot?.querySelector('[role="radio"]');
59
- expect(radio).to.have.attribute('aria-checked', 'false');
50
+ expect(radio?.getAttribute('aria-checked')).to.equal('false');
60
51
  });
61
52
  it('sets `aria-disabled` when disabled', async () => {
62
53
  const component = await fixture(html `<glide-core-button-group-button
@@ -64,14 +55,14 @@ it('sets `aria-disabled` when disabled', async () => {
64
55
  disabled
65
56
  ></glide-core-button-group-button>`);
66
57
  const radio = component.shadowRoot?.querySelector('[role="radio"]');
67
- expect(radio).to.have.attribute('aria-disabled', 'true');
58
+ expect(radio?.getAttribute('aria-disabled')).to.equal('true');
68
59
  });
69
60
  it('sets `aria-disabled` when not disabled', async () => {
70
61
  const component = await fixture(html `<glide-core-button-group-button
71
62
  label="Button"
72
63
  ></glide-core-button-group-button>`);
73
64
  const radio = component.shadowRoot?.querySelector('[role="radio"]');
74
- expect(radio).to.have.attribute('aria-disabled', 'false');
65
+ expect(radio?.getAttribute('aria-disabled')).to.equal('false');
75
66
  });
76
67
  it('is tabbable when selected', async () => {
77
68
  const component = await fixture(html `<glide-core-button-group-button
@@ -79,16 +70,16 @@ it('is tabbable when selected', async () => {
79
70
  selected
80
71
  ></glide-core-button-group-button>`);
81
72
  const radio = component.shadowRoot?.querySelector('[role="radio"]');
82
- expect(radio).to.have.attribute('tabindex', '0');
73
+ expect(radio?.getAttribute('tabindex')).to.equal('0');
83
74
  });
84
75
  it('is not tabbable when not selected', async () => {
85
76
  const component = await fixture(html `<glide-core-button-group-button
86
77
  label="Button"
87
78
  ></glide-core-button-group-button>`);
88
79
  const radio = component.shadowRoot?.querySelector('[role="radio"]');
89
- expect(radio).to.have.attribute('tabindex', '-1');
80
+ expect(radio?.getAttribute('tabindex')).to.equal('-1');
90
81
  });
91
- it('throws when icon-only and no "prefix" slot', async () => {
82
+ it('throws when icon-only and no "icon" slot', async () => {
92
83
  const spy = sinon.spy();
93
84
  try {
94
85
  await fixture(html `<glide-core-button-group-button
@@ -9,7 +9,7 @@ it('sets `aria-checked` when selected programmatically', async () => {
9
9
  component.selected = true;
10
10
  await elementUpdated(component);
11
11
  const radio = component.shadowRoot?.querySelector('[role="radio"]');
12
- expect(radio).to.have.attribute('aria-checked', 'true');
12
+ expect(radio?.getAttribute('aria-checked')).to.equal('true');
13
13
  });
14
14
  it('sets `aria-checked` when deselected programmatically', async () => {
15
15
  const component = await fixture(html `<glide-core-button-group-button
@@ -19,7 +19,7 @@ it('sets `aria-checked` when deselected programmatically', async () => {
19
19
  component.selected = false;
20
20
  await elementUpdated(component);
21
21
  const radio = component.shadowRoot?.querySelector('[role="radio"]');
22
- expect(radio).to.have.attribute('aria-checked', 'false');
22
+ expect(radio?.getAttribute('aria-checked')).to.equal('false');
23
23
  });
24
24
  it('sets `aria-disabled` when disabled programmatically', async () => {
25
25
  const component = await fixture(html `<glide-core-button-group-button
@@ -28,7 +28,7 @@ it('sets `aria-disabled` when disabled programmatically', async () => {
28
28
  component.disabled = true;
29
29
  await elementUpdated(component);
30
30
  const radio = component.shadowRoot?.querySelector('[role="radio"]');
31
- expect(radio).to.have.attribute('aria-disabled', 'true');
31
+ expect(radio?.getAttribute('aria-disabled')).to.equal('true');
32
32
  });
33
33
  it('sets `aria-disabled` when enabled programmatically', async () => {
34
34
  const component = await fixture(html `<glide-core-button-group-button
@@ -38,5 +38,5 @@ it('sets `aria-disabled` when enabled programmatically', async () => {
38
38
  component.disabled = false;
39
39
  await elementUpdated(component);
40
40
  const radio = component.shadowRoot?.querySelector('[role="radio"]');
41
- expect(radio).to.have.attribute('aria-disabled', 'false');
41
+ expect(radio?.getAttribute('aria-disabled')).to.equal('false');
42
42
  });
@@ -5,8 +5,6 @@ declare global {
5
5
  }
6
6
  }
7
7
  /**
8
- * @description A button group.
9
- *
10
8
  * @event change - `(event: Event) => void`
11
9
  * @event input - `(event: Event) => void`
12
10
  *
@@ -21,11 +21,11 @@ it('has defaults', async () => {
21
21
  </glide-core-button-group>`);
22
22
  expect(component.orientation).to.equal('horizontal');
23
23
  expect(component.variant).to.equal(undefined);
24
- expect(component).to.have.attribute('orientation', 'horizontal');
24
+ expect(component.getAttribute('orientation')).to.equal('horizontal');
25
25
  expect(component).to.not.have.attribute('variant');
26
26
  });
27
27
  it('is accessible', async () => {
28
- const component = await fixture(html `<glide-core-button-group label="label">
28
+ const component = await fixture(html `<glide-core-button-group label="Label">
29
29
  <glide-core-button-group-button
30
30
  label="One"
31
31
  ></glide-core-button-group-button>
@@ -42,7 +42,7 @@ it('is accessible', async () => {
42
42
  });
43
43
  });
44
44
  it('can have a label', async () => {
45
- const component = await fixture(html `<glide-core-button-group label="label">
45
+ const component = await fixture(html `<glide-core-button-group label="Label">
46
46
  <glide-core-button-group-button
47
47
  label="One"
48
48
  ></glide-core-button-group-button>
@@ -53,8 +53,8 @@ it('can have a label', async () => {
53
53
  </glide-core-button-group>`);
54
54
  const label = component.shadowRoot?.querySelector('[data-test="label"]');
55
55
  const radioGroup = component.shadowRoot?.querySelector('[role="radiogroup"]');
56
- expect(label?.textContent).to.equal('label');
57
- expect(radioGroup).to.have.attribute('aria-labelledby', label?.id);
56
+ expect(label?.textContent).to.equal('Label');
57
+ expect(radioGroup?.getAttribute('aria-labelledby')).to.equal(label?.id);
58
58
  });
59
59
  it('sets the orientation of each button when horizontal', async () => {
60
60
  await fixture(html `<glide-core-button-group>
@@ -85,13 +85,13 @@ it('sets the orientation of each button when vertical', async () => {
85
85
  expect(buttons[1]?.privateOrientation).to.equal('vertical');
86
86
  });
87
87
  it('sets `privateVariant` on each button', async () => {
88
- await fixture(html `<glide-core-button-group label="label" variant="icon-only">
88
+ await fixture(html `<glide-core-button-group label="Label" variant="icon-only">
89
89
  <glide-core-button-group-button label="One">
90
- <div slot="prefix">Prefix</div>
90
+ <div slot="icon">Icon</div>
91
91
  </glide-core-button-group-button>
92
92
 
93
93
  <glide-core-button-group-button label="Two">
94
- <div slot="prefix">Prefix</div>
94
+ <div slot="icon">Icon</div>
95
95
  </glide-core-button-group-button>
96
96
  </glide-core-button-group>`);
97
97
  const buttons = document.querySelectorAll('glide-core-button-group-button');
@@ -101,13 +101,13 @@ it('sets `privateVariant` on each button', async () => {
101
101
  it('throws when its default slot is the wrong type', async () => {
102
102
  await expectArgumentError(() => {
103
103
  return fixture(html `
104
- <glide-core-button-group label="label">
104
+ <glide-core-button-group label="Label">
105
105
  <div></div>
106
106
  </glide-core-button-group>
107
107
  `);
108
108
  });
109
109
  await expectArgumentError(() => {
110
- return fixture(html `<glide-core-button-group label="label"> </glide-core-button-group>`);
110
+ return fixture(html `<glide-core-button-group label="Label"> </glide-core-button-group>`);
111
111
  });
112
112
  });
113
113
  it('selects the first button not disabled', async () => {
@@ -157,7 +157,7 @@ it('emits a "change" event when a button is selected via Space', async () => {
157
157
  </glide-core-button-group>`);
158
158
  const buttons = document.querySelectorAll('glide-core-button-group-button');
159
159
  buttons[1]?.focus();
160
- sendKeys({ press: 'Space' });
160
+ sendKeys({ press: ' ' });
161
161
  const event = await oneEvent(component, 'input');
162
162
  expect(event instanceof Event).to.be.true;
163
163
  expect(event.bubbles).to.be.true;
@@ -196,7 +196,7 @@ it('does not emit a "change" event when an already selected button is selected v
196
196
  buttons[0]?.focus();
197
197
  const spy = sinon.spy();
198
198
  component.addEventListener('change', spy);
199
- sendKeys({ press: 'Space' });
199
+ sendKeys({ press: ' ' });
200
200
  expect(spy.callCount).to.equal(0);
201
201
  });
202
202
  it('does not emit a "change" event a button is selected programmatically', async () => {
@@ -68,7 +68,7 @@ it('selects a button on Space', async () => {
68
68
  </glide-core-button-group>`);
69
69
  const buttons = document.querySelectorAll('glide-core-button-group-button');
70
70
  buttons[1]?.focus();
71
- await sendKeys({ press: 'Space' });
71
+ await sendKeys({ press: ' ' });
72
72
  expect(buttons[0].selected).to.be.false;
73
73
  expect(buttons[1].selected).to.be.true;
74
74
  });
package/dist/button.d.ts CHANGED
@@ -5,21 +5,18 @@ declare global {
5
5
  }
6
6
  }
7
7
  /**
8
- *
9
- * @description A group of buttons that work like radios—with labels and optional icons.
10
- *
11
- * @slot - A label for the contents of the button.
12
- * @slot prefix - An optional icon slot to display before the label.
13
- * @slot suffix - An optional icon slot to display after the label.
8
+ * @slot - A label.
9
+ * @slot prefix-icon - An optional icon before the label.
10
+ * @slot suffix-icon - An optional icon after the label.
14
11
  */
15
12
  export default class GlideCoreButton extends LitElement {
16
13
  #private;
17
14
  static formAssociated: boolean;
18
15
  static shadowRootOptions: ShadowRootInit;
19
16
  static styles: import("lit").CSSResult[];
17
+ ariaControls: string | null;
20
18
  ariaExpanded: 'true' | 'false' | null;
21
19
  ariaHasPopup: 'true' | 'false' | 'menu' | 'listbox' | 'tree' | 'grid' | 'dialog' | null;
22
- ariaControls: string | null;
23
20
  autofocus: boolean;
24
21
  disabled: boolean;
25
22
  formAction: string;
@@ -27,6 +24,7 @@ export default class GlideCoreButton extends LitElement {
27
24
  formMethod: '' | 'dialog' | 'get' | 'post';
28
25
  formNoValidate: boolean;
29
26
  formTarget: '' | '_blank' | '_parent' | '_self' | '_top';
27
+ label?: string;
30
28
  name: string;
31
29
  popoverTarget?: string;
32
30
  popoverTargetAction: '' | 'hide' | 'show' | 'toggle';
@@ -36,9 +34,8 @@ export default class GlideCoreButton extends LitElement {
36
34
  variant: 'primary' | 'secondary' | 'tertiary';
37
35
  get form(): HTMLFormElement | null;
38
36
  click(): void;
39
- firstUpdated(): void;
40
37
  render(): import("lit").TemplateResult<1>;
41
38
  constructor();
42
- private hasPrefixSlot;
43
- private hasSuffixSlot;
39
+ private hasPrefixIcon;
40
+ private hasSuffixIcon;
44
41
  }
package/dist/button.js CHANGED
@@ -1 +1 @@
1
- var __decorate=this&&this.__decorate||function(t,e,o,r){var i,a=arguments.length,l=a<3?e:null===r?r=Object.getOwnPropertyDescriptor(e,o):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)l=Reflect.decorate(t,e,o,r);else for(var s=t.length-1;s>=0;s--)(i=t[s])&&(l=(a<3?i(l):a>3?i(e,o,l):i(e,o))||l);return a>3&&l&&Object.defineProperty(e,o,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,state}from"lit/decorators.js";import{ifDefined}from"lit/directives/if-defined.js";import{owSlot}from"./library/ow.js";import styles from"./button.styles.js";let GlideCoreButton=class GlideCoreButton extends LitElement{static{this.formAssociated=!0}static{this.shadowRootOptions={...LitElement.shadowRootOptions,delegatesFocus:!0,mode:"closed"}}static{this.styles=styles}get form(){return this.#t.form}click(){this.#e.value?.click()}firstUpdated(){owSlot(this.#o.value)}render(){return html`<button aria-controls="${ifDefined(this.ariaControls??void 0)}" aria-expanded="${ifDefined(this.ariaExpanded??void 0)}" aria-haspopup="${ifDefined(this.ariaHasPopup??void 0)}" ?autofocus="${this.autofocus}" class="${classMap({component:!0,primary:"primary"===this.variant,secondary:"secondary"===this.variant,tertiary:"tertiary"===this.variant,large:"large"===this.size,small:"small"===this.size,"has-prefix":this.hasPrefixSlot,"has-suffix":this.hasSuffixSlot})}" ?disabled="${this.disabled}" @click="${this.#r}" ${ref(this.#e)}><slot name="prefix" @slotchange="${this.#i}" ${ref(this.#a)}></slot><slot @slotchange="${this.#l}" ${ref(this.#o)}></slot><slot name="suffix" @slotchange="${this.#s}" ${ref(this.#n)}></slot></button>`}constructor(){super(),this.ariaExpanded=null,this.ariaHasPopup=null,this.ariaControls=null,this.autofocus=!1,this.disabled=!1,this.formAction="",this.formEncType="",this.formMethod="",this.formNoValidate=!1,this.formTarget="",this.name="",this.popoverTargetAction="",this.size="large",this.type="button",this.value="",this.variant="primary",this.hasPrefixSlot=!1,this.hasSuffixSlot=!1,this.#e=createRef(),this.#o=createRef(),this.#a=createRef(),this.#n=createRef(),this.#t=this.attachInternals()}#e;#o;#t;#a;#n;#r(){"submit"!==this.type?"reset"!==this.type||this.form?.reset():this.form?.requestSubmit()}#l(){owSlot(this.#o.value)}#i(){const t=this.#a.value?.assignedNodes();this.hasPrefixSlot=Boolean(t&&t.length>0)}#s(){const t=this.#n.value?.assignedNodes();this.hasSuffixSlot=Boolean(t&&t.length>0)}};__decorate([property({attribute:"aria-expanded",reflect:!0})],GlideCoreButton.prototype,"ariaExpanded",void 0),__decorate([property({attribute:"aria-haspopup",reflect:!0})],GlideCoreButton.prototype,"ariaHasPopup",void 0),__decorate([property({attribute:"aria-controls",reflect:!0})],GlideCoreButton.prototype,"ariaControls",void 0),__decorate([property({type:Boolean,reflect:!0})],GlideCoreButton.prototype,"autofocus",void 0),__decorate([property({type:Boolean,reflect:!0})],GlideCoreButton.prototype,"disabled",void 0),__decorate([property({attribute:"formaction",reflect:!0})],GlideCoreButton.prototype,"formAction",void 0),__decorate([property({attribute:"formenctype",reflect:!0})],GlideCoreButton.prototype,"formEncType",void 0),__decorate([property({attribute:"formmethod",reflect:!0})],GlideCoreButton.prototype,"formMethod",void 0),__decorate([property({attribute:"formnovalidate",type:Boolean,reflect:!0})],GlideCoreButton.prototype,"formNoValidate",void 0),__decorate([property({attribute:"formtarget",reflect:!0})],GlideCoreButton.prototype,"formTarget",void 0),__decorate([property({reflect:!0})],GlideCoreButton.prototype,"name",void 0),__decorate([property({attribute:"popovertarget",reflect:!0})],GlideCoreButton.prototype,"popoverTarget",void 0),__decorate([property({attribute:"popovertargetaction",reflect:!0})],GlideCoreButton.prototype,"popoverTargetAction",void 0),__decorate([property({reflect:!0})],GlideCoreButton.prototype,"size",void 0),__decorate([property({reflect:!0})],GlideCoreButton.prototype,"type",void 0),__decorate([property({reflect:!0})],GlideCoreButton.prototype,"value",void 0),__decorate([property({reflect:!0})],GlideCoreButton.prototype,"variant",void 0),__decorate([state()],GlideCoreButton.prototype,"hasPrefixSlot",void 0),__decorate([state()],GlideCoreButton.prototype,"hasSuffixSlot",void 0),GlideCoreButton=__decorate([customElement("glide-core-button")],GlideCoreButton);export default GlideCoreButton;
1
+ var __decorate=this&&this.__decorate||function(t,e,o,r){var i,a=arguments.length,s=a<3?e:null===r?r=Object.getOwnPropertyDescriptor(e,o):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(t,e,o,r);else for(var n=t.length-1;n>=0;n--)(i=t[n])&&(s=(a<3?i(s):a>3?i(e,o,s):i(e,o))||s);return a>3&&s&&Object.defineProperty(e,o,s),s};import{LitElement,html}from"lit";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 styles from"./button.styles.js";let GlideCoreButton=class GlideCoreButton extends LitElement{static{this.formAssociated=!0}static{this.shadowRootOptions={...LitElement.shadowRootOptions,delegatesFocus:!0,mode:"closed"}}static{this.styles=styles}get form(){return this.#t.form}click(){this.#e.value?.click()}render(){return html`<button aria-controls="${ifDefined(this.ariaControls??void 0)}" aria-expanded="${ifDefined(this.ariaExpanded??void 0)}" aria-haspopup="${ifDefined(this.ariaHasPopup??void 0)}" ?autofocus="${this.autofocus}" class="${classMap({component:!0,primary:"primary"===this.variant,secondary:"secondary"===this.variant,tertiary:"tertiary"===this.variant,large:"large"===this.size,small:"small"===this.size,"prefix-icon":this.hasPrefixIcon,"suffix-icon":this.hasSuffixIcon})}" ?disabled="${this.disabled}" @click="${this.#o}" ${ref(this.#e)}><slot name="prefix-icon" @slotchange="${this.#r}" ${ref(this.#i)}></slot>${this.label}<slot name="suffix-icon" @slotchange="${this.#a}" ${ref(this.#s)}></slot></button>`}constructor(){super(),this.ariaControls=null,this.ariaExpanded=null,this.ariaHasPopup=null,this.autofocus=!1,this.disabled=!1,this.formAction="",this.formEncType="",this.formMethod="",this.formNoValidate=!1,this.formTarget="",this.name="",this.popoverTargetAction="",this.size="large",this.type="button",this.value="",this.variant="primary",this.hasPrefixIcon=!1,this.hasSuffixIcon=!1,this.#e=createRef(),this.#i=createRef(),this.#s=createRef(),this.#t=this.attachInternals()}#e;#t;#i;#s;#o(){"submit"!==this.type?"reset"!==this.type||this.form?.reset():this.form?.requestSubmit()}#r(){const t=this.#i.value?.assignedNodes();this.hasPrefixIcon=Boolean(t&&t.length>0)}#a(){const t=this.#s.value?.assignedNodes();this.hasSuffixIcon=Boolean(t&&t.length>0)}};__decorate([property({attribute:"aria-controls",reflect:!0})],GlideCoreButton.prototype,"ariaControls",void 0),__decorate([property({attribute:"aria-expanded",reflect:!0})],GlideCoreButton.prototype,"ariaExpanded",void 0),__decorate([property({attribute:"aria-haspopup",reflect:!0})],GlideCoreButton.prototype,"ariaHasPopup",void 0),__decorate([property({type:Boolean,reflect:!0})],GlideCoreButton.prototype,"autofocus",void 0),__decorate([property({type:Boolean,reflect:!0})],GlideCoreButton.prototype,"disabled",void 0),__decorate([property({attribute:"formaction",reflect:!0})],GlideCoreButton.prototype,"formAction",void 0),__decorate([property({attribute:"formenctype",reflect:!0})],GlideCoreButton.prototype,"formEncType",void 0),__decorate([property({attribute:"formmethod",reflect:!0})],GlideCoreButton.prototype,"formMethod",void 0),__decorate([property({attribute:"formnovalidate",type:Boolean,reflect:!0})],GlideCoreButton.prototype,"formNoValidate",void 0),__decorate([property({attribute:"formtarget",reflect:!0})],GlideCoreButton.prototype,"formTarget",void 0),__decorate([property({reflect:!0})],GlideCoreButton.prototype,"label",void 0),__decorate([property({reflect:!0})],GlideCoreButton.prototype,"name",void 0),__decorate([property({attribute:"popovertarget",reflect:!0})],GlideCoreButton.prototype,"popoverTarget",void 0),__decorate([property({attribute:"popovertargetaction",reflect:!0})],GlideCoreButton.prototype,"popoverTargetAction",void 0),__decorate([property({reflect:!0})],GlideCoreButton.prototype,"size",void 0),__decorate([property({reflect:!0})],GlideCoreButton.prototype,"type",void 0),__decorate([property({reflect:!0})],GlideCoreButton.prototype,"value",void 0),__decorate([property({reflect:!0})],GlideCoreButton.prototype,"variant",void 0),__decorate([state()],GlideCoreButton.prototype,"hasPrefixIcon",void 0),__decorate([state()],GlideCoreButton.prototype,"hasSuffixIcon",void 0),GlideCoreButton=__decorate([customElement("glide-core-button")],GlideCoreButton);export default GlideCoreButton;
@@ -35,15 +35,12 @@ import{css}from"lit";import focusOutline from"./styles/focus-outline.js";export
35
35
  opacity: 1;
36
36
  }
37
37
 
38
- /* We remove spacing using negative margin when an icon is present to help with empty space balancing */
39
- &.has-prefix,
40
- ::slotted([slot='prefix']) {
41
- margin-inline-start: -0.125rem;
38
+ &.prefix-icon {
39
+ padding-inline-start: 0.875rem;
42
40
  }
43
41
 
44
- &.has-suffix,
45
- ::slotted([slot='suffix']) {
46
- margin-inline-end: -0.125rem;
42
+ &.suffix-icon {
43
+ padding-inline-end: 0.875rem;
47
44
  }
48
45
 
49
46
  &.primary {
@@ -1,20 +1,18 @@
1
1
  /* eslint-disable @typescript-eslint/no-unused-expressions */
2
2
  import './button.js';
3
- import { ArgumentError } from 'ow';
4
3
  import { expect, fixture, html } from '@open-wc/testing';
5
4
  import GlideCoreButton from './button.js';
6
- import sinon from 'sinon';
7
5
  GlideCoreButton.shadowRootOptions.mode = 'open';
8
6
  it('registers', async () => {
9
7
  expect(window.customElements.get('glide-core-button')).to.equal(GlideCoreButton);
10
8
  });
11
9
  it('is accessible', async () => {
12
- const component = await fixture(html `<glide-core-button>Button</glide-core-button>`);
10
+ const component = await fixture(html `<glide-core-button label="Label"></glide-core-button>`);
13
11
  await expect(component).to.be.accessible();
14
12
  });
15
13
  it('has defaults', async () => {
16
14
  const component = await fixture(html `
17
- <glide-core-button>Button</glide-core-button>
15
+ <glide-core-button label="Label"></glide-core-button>
18
16
  `);
19
17
  expect(component.ariaControls).to.be.null;
20
18
  expect(component.ariaExpanded).to.be.null;
@@ -48,38 +46,24 @@ it('has defaults', async () => {
48
46
  expect(button?.getAttribute('aria-controls')).to.be.null;
49
47
  expect(button?.ariaExpanded).to.be.null;
50
48
  expect(button?.ariaHasPopup).to.be.null;
51
- expect(button?.disabled).to.equal(false);
49
+ expect(button?.disabled).to.be.false;
52
50
  });
53
51
  it('delegates focus', async () => {
54
- const component = await fixture(html `<glide-core-button>Button</glide-core-button>`);
52
+ const component = await fixture(html `<glide-core-button label="Label"></glide-core-button>`);
55
53
  component.focus();
56
54
  expect(component.shadowRoot?.activeElement).to.equal(component.shadowRoot?.querySelector('button'));
57
55
  });
58
- it('throws if it does not have a default slot', async () => {
59
- const spy = sinon.spy();
60
- try {
61
- await fixture(html `<glide-core-button></glide-core-button>`);
62
- }
63
- catch (error) {
64
- if (error instanceof ArgumentError) {
65
- spy();
66
- }
67
- }
68
- expect(spy.callCount).to.equal(1);
69
- });
70
- it('`#onPrefixSlotChange` coverage', async () => {
56
+ it('has `#onPrefixSlotChange` coverage', async () => {
71
57
  await fixture(html `
72
- <glide-core-button>
73
- <span slot="prefix">Prefix</span>
74
- Button
58
+ <glide-core-button label="Label">
59
+ <span slot="prefix-icon">Prefix</span>
75
60
  </glide-core-button>
76
61
  `);
77
62
  });
78
- it('`#onSuffixSlotChange` coverage', async () => {
63
+ it('has `#onSuffixIconSlotChange` coverage', async () => {
79
64
  await fixture(html `
80
- <glide-core-button>
81
- Button
82
- <span slot="suffix">Suffix</span>
65
+ <glide-core-button label="Label">
66
+ <span slot="suffix-icon">Suffix</span>
83
67
  </glide-core-button>
84
68
  `);
85
69
  });
@@ -6,7 +6,7 @@ import GlideCoreButton from './button.js';
6
6
  GlideCoreButton.shadowRootOptions.mode = 'open';
7
7
  it('dispatches a "click" event when clicked', async () => {
8
8
  const component = await fixture(html `
9
- <glide-core-button type="button">Button</glide-core-button>
9
+ <glide-core-button label="Label" type="button"></glide-core-button>
10
10
  `);
11
11
  setTimeout(() => {
12
12
  component.click();
@@ -17,7 +17,7 @@ it('dispatches a "click" event when clicked', async () => {
17
17
  });
18
18
  it('dispatches a "click" event on Enter', async () => {
19
19
  const component = await fixture(html `
20
- <glide-core-button type="button">Button</glide-core-button>
20
+ <glide-core-button label="Label" type="button"></glide-core-button>
21
21
  `);
22
22
  component.focus();
23
23
  sendKeys({ press: 'Enter' });
@@ -27,7 +27,7 @@ it('dispatches a "click" event on Enter', async () => {
27
27
  });
28
28
  it('dispatches a "click" event on Space', async () => {
29
29
  const component = await fixture(html `
30
- <glide-core-button type="button">Button</glide-core-button>
30
+ <glide-core-button label="Label" type="button"></glide-core-button>
31
31
  `);
32
32
  component.focus();
33
33
  sendKeys({ press: ' ' });
@@ -37,7 +37,7 @@ it('dispatches a "click" event on Space', async () => {
37
37
  });
38
38
  it('dispatches a "reset" event on click', async () => {
39
39
  const form = document.createElement('form');
40
- const component = await fixture(html ` <glide-core-button type="reset">Button</glide-core-button> `, {
40
+ const component = await fixture(html ` <glide-core-button label="Label" type="reset"></glide-core-button>`, {
41
41
  parentNode: form,
42
42
  });
43
43
  setTimeout(() => {
@@ -48,7 +48,7 @@ it('dispatches a "reset" event on click', async () => {
48
48
  });
49
49
  it('dispatches a "reset" event on Enter', async () => {
50
50
  const form = document.createElement('form');
51
- const component = await fixture(html ` <glide-core-button type="reset">Button</glide-core-button> `, {
51
+ const component = await fixture(html ` <glide-core-button label="Label" type="reset"></glide-core-button>`, {
52
52
  parentNode: form,
53
53
  });
54
54
  component.focus();
@@ -58,7 +58,7 @@ it('dispatches a "reset" event on Enter', async () => {
58
58
  });
59
59
  it('dispatches a "reset" event on Space', async () => {
60
60
  const form = document.createElement('form');
61
- const component = await fixture(html ` <glide-core-button type="reset">Button</glide-core-button> `, {
61
+ const component = await fixture(html ` <glide-core-button label="Label" type="reset"></glide-core-button>`, {
62
62
  parentNode: form,
63
63
  });
64
64
  component.focus();
@@ -68,7 +68,7 @@ it('dispatches a "reset" event on Space', async () => {
68
68
  });
69
69
  it('dispatches a "submit" event on click', async () => {
70
70
  const form = document.createElement('form');
71
- const component = await fixture(html ` <glide-core-button type="submit">Button</glide-core-button> `, {
71
+ const component = await fixture(html ` <glide-core-button label="Label" type="submit"></glide-core-button>`, {
72
72
  parentNode: form,
73
73
  });
74
74
  form.addEventListener('submit', (event) => event.preventDefault());
@@ -80,7 +80,7 @@ it('dispatches a "submit" event on click', async () => {
80
80
  });
81
81
  it('dispatches a "submit" event on Enter', async () => {
82
82
  const form = document.createElement('form');
83
- const component = await fixture(html ` <glide-core-button type="submit">Button</glide-core-button> `, {
83
+ const component = await fixture(html ` <glide-core-button label="Label" type="submit"></glide-core-button>`, {
84
84
  parentNode: form,
85
85
  });
86
86
  form.addEventListener('submit', (event) => event.preventDefault());
@@ -91,7 +91,7 @@ it('dispatches a "submit" event on Enter', async () => {
91
91
  });
92
92
  it('dispatches a "submit" event on Space', async () => {
93
93
  const form = document.createElement('form');
94
- const component = await fixture(html ` <glide-core-button type="submit">Button</glide-core-button> `, {
94
+ const component = await fixture(html ` <glide-core-button label="Label" type="submit"></glide-core-button>`, {
95
95
  parentNode: form,
96
96
  });
97
97
  form.addEventListener('submit', (event) => event.preventDefault());
@@ -6,8 +6,6 @@ declare global {
6
6
  }
7
7
  }
8
8
  /**
9
- * @description A group of checkboxes with a label and optional description and tooltip. Participates in forms and validation via `FormData` and various methods.
10
- *
11
9
  * @event change - `(event: Event) => void`
12
10
  * @event input - `(event: Event) => void`
13
11
  * @event invalid - `(event: Event) => void`
@@ -25,12 +23,13 @@ export default class GlideCoreCheckboxGroup extends LitElement {
25
23
  set disabled(isDisabled: boolean);
26
24
  hideLabel: boolean;
27
25
  label?: string;
28
- name?: string;
26
+ name: string;
29
27
  privateSplit?: 'left' | 'middle';
30
28
  get required(): boolean;
31
29
  set required(isRequired: boolean);
32
30
  summary?: string;
33
- value: readonly string[];
31
+ get value(): string[];
32
+ set value(value: string[]);
34
33
  checkValidity(): boolean;
35
34
  disconnectedCallback(): void;
36
35
  firstUpdated(): void;
@@ -1 +1 @@
1
- var __decorate=this&&this.__decorate||function(e,t,i,o){var r,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--)(r=e[a])&&(l=(s<3?r(l):s>3?r(t,i,l):r(t,i))||l);return s>3&&l&&Object.defineProperty(t,i,l),l};import"./label.js";import{LitElement,html}from"lit";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{owSlot,owSlotType}from"./library/ow.js";import GlideCoreCheckbox from"./checkbox.js";import styles from"./checkbox-group.styles.js";let GlideCoreCheckboxGroup=class GlideCoreCheckboxGroup extends LitElement{static{this.formAssociated=!0}static{this.shadowRootOptions={...LitElement.shadowRootOptions,mode:"closed"}}static{this.styles=styles}get disabled(){return this.#e}set disabled(e){this.#e=e;for(const t of this.#t)t.disabled=e}get required(){return this.#i}set required(e){this.#i=e;for(const t of this.#t)e?t.setValidity(this.#o.validity," "):t.setValidity({}),t.requestUpdate()}checkValidity(){this.isCheckingValidity=!0;const e=this.#o.checkValidity();return this.isCheckingValidity=!1,e}disconnectedCallback(){super.disconnectedCallback(),this.form?.removeEventListener("formdata",this.#r)}firstUpdated(){if(owSlot(this.#s.value),owSlotType(this.#s.value,[GlideCoreCheckbox]),this.disabled)for(const e of this.#t)e.disabled=!0;this.value=this.#t.filter((({checked:e,disabled:t})=>e&&!t)).map((({value:e})=>e)).filter((e=>Boolean(e)));for(const e of this.#t)e.privateVariant="minimal",e.addEventListener("blur",this.#l.bind(this))}get form(){return this.#o.form}get validity(){const e=this.#t.some((({checked:e})=>e));this.required&&!e?this.#o.setValidity({valueMissing:!0}," ",this.#a.value):this.#o.setValidity({});for(const e of this.#t)e.setValidity(this.#o.validity," "),e.requestUpdate();return this.#o.validity}get willValidate(){return this.#o.willValidate}focus(e){const t=this.#t.find((({disabled:e})=>!e));t?.focus(e)}formAssociatedCallback(){this.form?.addEventListener("formdata",this.#r)}formResetCallback(){for(const e of this.#t)e.formResetCallback()}render(){return html`<div class="component" data-test="component" ${ref(this.#a)}><glide-core-private-label split="${ifDefined(this.privateSplit??void 0)}" ?hide="${this.hideLabel}" ?disabled="${this.disabled}" ?error="${this.#d}" ?required="${this.required}"><slot name="tooltip" slot="tooltip"></slot><label id="label">${this.label}</label><div aria-labelledby="label description" role="group" slot="control"><slot class="checkboxes" @change="${this.#c}" @slotchange="${this.#n}" ${ref(this.#s)}></slot></div><slot id="description" name="description" slot="description"></slot></glide-core-private-label></div>`}reportValidity(){this.isReportValidityOrSubmit=!0;const e=this.#o.reportValidity();return this.requestUpdate(),e}constructor(){super(),this.hideLabel=!1,this.value=[],this.isBlurring=!1,this.isCheckingValidity=!1,this.isReportValidityOrSubmit=!1,this.#a=createRef(),this.#s=createRef(),this.#e=!1,this.#i=!1,this.#r=({formData:e})=>{this.name&&this.value.length>0&&!this.disabled&&e.append(this.name,JSON.stringify(this.value))},this.#o=this.attachInternals(),this.addEventListener("invalid",(e=>{if(e?.preventDefault(),this.isCheckingValidity||this.isBlurring)return;this.isReportValidityOrSubmit=!0;this.form?.querySelector(":invalid")===this&&this.focus()}))}#a;#s;#o;#e;#i;get#t(){return this.#s.value?this.#s.value.assignedElements().filter((e=>e instanceof GlideCoreCheckbox)):[]}#r;get#d(){return this.required&&!this.disabled&&!this.validity.valid&&this.isReportValidityOrSubmit}#h(){for(const e of this.#t)e.isReportValidityOrSubmit=!0}#l(e){const t=e.relatedTarget;t&&t instanceof GlideCoreCheckbox&&this.#t.includes(t)||this.#h()}#c(){this.value=this.#t.filter((({checked:e,disabled:t})=>e&&!t)).map((({value:e})=>e)).filter((e=>Boolean(e)))}#n(){owSlot(this.#s.value),owSlotType(this.#s.value,[GlideCoreCheckbox])}};__decorate([property({reflect:!0,type:Boolean})],GlideCoreCheckboxGroup.prototype,"disabled",null),__decorate([property({attribute:"hide-label",type:Boolean})],GlideCoreCheckboxGroup.prototype,"hideLabel",void 0),__decorate([property({reflect:!0})],GlideCoreCheckboxGroup.prototype,"label",void 0),__decorate([property({reflect:!0})],GlideCoreCheckboxGroup.prototype,"name",void 0),__decorate([property()],GlideCoreCheckboxGroup.prototype,"privateSplit",void 0),__decorate([property({reflect:!0,type:Boolean})],GlideCoreCheckboxGroup.prototype,"required",null),__decorate([property({reflect:!0})],GlideCoreCheckboxGroup.prototype,"summary",void 0),__decorate([property({type:Array})],GlideCoreCheckboxGroup.prototype,"value",void 0),__decorate([state()],GlideCoreCheckboxGroup.prototype,"isBlurring",void 0),__decorate([state()],GlideCoreCheckboxGroup.prototype,"isCheckingValidity",void 0),__decorate([state()],GlideCoreCheckboxGroup.prototype,"isReportValidityOrSubmit",void 0),GlideCoreCheckboxGroup=__decorate([customElement("glide-core-checkbox-group")],GlideCoreCheckboxGroup);export default GlideCoreCheckboxGroup;
1
+ var __decorate=this&&this.__decorate||function(e,t,i,o){var r,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--)(r=e[a])&&(l=(s<3?r(l):s>3?r(t,i,l):r(t,i))||l);return s>3&&l&&Object.defineProperty(t,i,l),l};import"./label.js";import{LitElement,html}from"lit";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{owSlot,owSlotType}from"./library/ow.js";import GlideCoreCheckbox from"./checkbox.js";import styles from"./checkbox-group.styles.js";let GlideCoreCheckboxGroup=class GlideCoreCheckboxGroup extends LitElement{static{this.formAssociated=!0}static{this.shadowRootOptions={...LitElement.shadowRootOptions,mode:"closed"}}static{this.styles=styles}get disabled(){return this.#e}set disabled(e){this.#e=e;for(const t of this.#t)t.disabled=e}get required(){return this.#i}set required(e){this.#i=e;for(const t of this.#t)e?t.setValidity(this.#o.validity," "):t.setValidity({}),t.requestUpdate()}get value(){return this.#r}set value(e){this.#r=e;for(const t of this.#t){e.some((e=>e&&e===t.value))?t.checked=!0:t.value&&(t.checked=!1),t.checked&&t.disabled&&(t.disabled=!1)}}checkValidity(){this.isCheckingValidity=!0;const e=this.#o.checkValidity();return this.isCheckingValidity=!1,e}disconnectedCallback(){super.disconnectedCallback(),this.form?.removeEventListener("formdata",this.#s)}firstUpdated(){if(owSlot(this.#l.value),owSlotType(this.#l.value,[GlideCoreCheckbox]),this.disabled)for(const e of this.#t)e.disabled=!0;this.value=this.#t.filter((({checked:e,disabled:t})=>e&&!t)).map((({value:e})=>e)).filter((e=>Boolean(e)));for(const e of this.#t)e.privateVariant="minimal",e.addEventListener("blur",this.#a.bind(this))}get form(){return this.#o.form}get validity(){const e=this.#t.some((({checked:e})=>e));this.required&&!e?this.#o.setValidity({valueMissing:!0}," ",this.#d.value):this.#o.setValidity({});for(const e of this.#t)e.setValidity(this.#o.validity," "),e.requestUpdate();return this.#o.validity}get willValidate(){return this.#o.willValidate}focus(e){const t=this.#t.find((({disabled:e})=>!e));t?.focus(e)}formAssociatedCallback(){this.form?.addEventListener("formdata",this.#s)}formResetCallback(){for(const e of this.#t)e.formResetCallback()}render(){return html`<div class="component" data-test="component" ${ref(this.#d)}><glide-core-private-label split="${ifDefined(this.privateSplit??void 0)}" ?hide="${this.hideLabel}" ?disabled="${this.disabled}" ?error="${this.#c}" ?required="${this.required}"><slot name="tooltip" slot="tooltip"></slot><label id="label">${this.label}</label><div aria-labelledby="label description" role="group" slot="control" class="${classMap({"checkbox-container":!0,invalid:this.#c})}"><slot class="checkboxes" @change="${this.#n}" @private-value-change="${this.#h}" @slotchange="${this.#p}" ${ref(this.#l)}></slot></div><slot id="description" name="description" slot="description"></slot></glide-core-private-label></div>`}reportValidity(){this.isReportValidityOrSubmit=!0;const e=this.#o.reportValidity();return this.requestUpdate(),e}constructor(){super(),this.hideLabel=!1,this.name="",this.isBlurring=!1,this.isCheckingValidity=!1,this.isReportValidityOrSubmit=!1,this.#d=createRef(),this.#l=createRef(),this.#e=!1,this.#i=!1,this.#r=[],this.#s=({formData:e})=>{this.name&&this.value.length>0&&!this.disabled&&e.append(this.name,JSON.stringify(this.value))},this.#o=this.attachInternals(),this.addEventListener("invalid",(e=>{if(e?.preventDefault(),this.isCheckingValidity||this.isBlurring)return;this.isReportValidityOrSubmit=!0;this.form?.querySelector(":invalid")===this&&this.focus()}))}#d;#l;#o;#e;#i;#r;get#t(){return this.#l.value?this.#l.value.assignedElements().filter((e=>e instanceof GlideCoreCheckbox)):[]}#s;get#c(){return this.required&&!this.disabled&&!this.validity.valid&&this.isReportValidityOrSubmit}#u(){for(const e of this.#t)e.isReportValidityOrSubmit=!0}#a(e){const t=e.relatedTarget;t&&t instanceof GlideCoreCheckbox&&this.#t.includes(t)||this.#u()}#n(){this.value=this.#t.filter((({checked:e,disabled:t})=>e&&!t)).map((({value:e})=>e)).filter((e=>Boolean(e)))}#h(e){e.target instanceof GlideCoreCheckbox&&e.target.checked&&e.detail.new?this.value=this.#r.map((t=>t===e.detail.old?e.detail.new:t)):e.target instanceof GlideCoreCheckbox&&e.target.checked&&(this.value=this.#r.filter((t=>t!==e.detail.old)))}#p(){owSlot(this.#l.value),owSlotType(this.#l.value,[GlideCoreCheckbox])}};__decorate([property({reflect:!0,type:Boolean})],GlideCoreCheckboxGroup.prototype,"disabled",null),__decorate([property({attribute:"hide-label",type:Boolean})],GlideCoreCheckboxGroup.prototype,"hideLabel",void 0),__decorate([property({reflect:!0})],GlideCoreCheckboxGroup.prototype,"label",void 0),__decorate([property({reflect:!0})],GlideCoreCheckboxGroup.prototype,"name",void 0),__decorate([property()],GlideCoreCheckboxGroup.prototype,"privateSplit",void 0),__decorate([property({reflect:!0,type:Boolean})],GlideCoreCheckboxGroup.prototype,"required",null),__decorate([property({reflect:!0})],GlideCoreCheckboxGroup.prototype,"summary",void 0),__decorate([property({reflect:!0,type:Array})],GlideCoreCheckboxGroup.prototype,"value",null),__decorate([state()],GlideCoreCheckboxGroup.prototype,"isBlurring",void 0),__decorate([state()],GlideCoreCheckboxGroup.prototype,"isCheckingValidity",void 0),__decorate([state()],GlideCoreCheckboxGroup.prototype,"isReportValidityOrSubmit",void 0),GlideCoreCheckboxGroup=__decorate([customElement("glide-core-checkbox-group")],GlideCoreCheckboxGroup);export default GlideCoreCheckboxGroup;
@@ -11,10 +11,22 @@ import{css}from"lit";export default[css`
11
11
  align-items: flex-start;
12
12
  }
13
13
 
14
+ .checkbox-container {
15
+ display: flex;
16
+ gap: 0.375rem;
17
+ inline-size: min-content;
18
+
19
+ &.invalid {
20
+ border: 1px solid var(--glide-core-status-error);
21
+ border-radius: 0.5rem;
22
+ padding: var(--glide-core-spacing-xxs) 0.375rem;
23
+ }
24
+ }
25
+
14
26
  .checkboxes {
15
27
  display: flex;
16
28
  flex-direction: column;
17
29
  grid-column: 2;
18
- row-gap: var(--glide-core-spacing-xxs);
30
+ row-gap: var(--glide-core-spacing-xs);
19
31
  }
20
32
  `];
@@ -13,13 +13,9 @@ it('has defaults', async () => {
13
13
  const component = await fixture(html `<glide-core-checkbox-group label="Checkbox Group">
14
14
  <glide-core-checkbox label="Checkbox"></glide-core-checkbox>
15
15
  </glide-core-checkbox-group>`);
16
- expect(component.hasAttribute('disabled')).to.be.false;
17
16
  expect(component.disabled).to.be.false;
18
- expect(component.hasAttribute('hide-label')).to.be.false;
19
17
  expect(component.hideLabel).to.be.false;
20
- expect(component.getAttribute('name')).to.be.null;
21
- expect(component.name).to.equal(undefined);
22
- expect(component.hasAttribute('required')).to.be.false;
18
+ expect(component.name).to.be.empty.string;
23
19
  expect(component.required).to.be.false;
24
20
  // Not reflected, so no attribute assertion is necessary.
25
21
  expect(component.value).to.deep.equal([]);
@@ -72,10 +68,10 @@ it('can be disabled initially', async () => {
72
68
  <glide-core-checkbox label="Two"></glide-core-checkbox>
73
69
  </glide-core-checkbox-group>`);
74
70
  const checkboxes = component.querySelectorAll('glide-core-checkbox');
75
- expect(checkboxes[0].disabled).to.equal(true);
76
- expect(checkboxes[1].disabled).to.equal(true);
71
+ expect(checkboxes[0].disabled).to.be.true;
72
+ expect(checkboxes[1].disabled).to.be.true;
77
73
  expect(component.hasAttribute('disabled')).to.be.true;
78
- expect(component.disabled).to.equal(true);
74
+ expect(component.disabled).to.be.true;
79
75
  });
80
76
  it('can be disabled dynamically', async () => {
81
77
  const component = await fixture(html `<glide-core-checkbox-group label="Checkbox Group">
@@ -85,17 +81,17 @@ it('can be disabled dynamically', async () => {
85
81
  component.disabled = true;
86
82
  await elementUpdated(component);
87
83
  const checkboxes = component.querySelectorAll('glide-core-checkbox');
88
- expect(checkboxes[0].disabled).to.equal(true);
89
- expect(checkboxes[1].disabled).to.equal(true);
84
+ expect(checkboxes[0].disabled).to.be.true;
85
+ expect(checkboxes[1].disabled).to.be.true;
90
86
  expect(component.hasAttribute('disabled')).to.be.true;
91
- expect(component.disabled).to.equal(true);
87
+ expect(component.disabled).to.be.true;
92
88
  });
93
89
  it('can be required', async () => {
94
90
  const component = await fixture(html `<glide-core-checkbox-group label="Checkbox Group" required>
95
91
  <glide-core-checkbox label="Checkbox"></glide-core-checkbox>
96
92
  </glide-core-checkbox-group>`);
97
93
  expect(component.hasAttribute('required')).to.be.true;
98
- expect(component.required).to.equal(true);
94
+ expect(component.required).to.be.true;
99
95
  });
100
96
  it('throws if it does not have a default slot', async () => {
101
97
  const spy = sinon.spy();
@@ -58,13 +58,13 @@ it('reports validity of checkboxes if blurred', async () => {
58
58
  expect(document.activeElement === checkboxes[0]).to.be.true;
59
59
  await sendKeys({ press: 'Tab' });
60
60
  expect(document.activeElement === checkboxes[1]).to.be.true;
61
- expect(checkboxes[0].isReportValidityOrSubmit).to.equal(false);
62
- expect(checkboxes[1].isReportValidityOrSubmit).to.equal(false);
61
+ expect(checkboxes[0].isReportValidityOrSubmit).to.be.false;
62
+ expect(checkboxes[1].isReportValidityOrSubmit).to.be.false;
63
63
  await sendKeys({ press: 'Tab' });
64
64
  expect(document.activeElement === document.body).to.be.true;
65
- expect(component.validity.valid).to.equal(false);
66
- expect(checkboxes[0].validity.valid).to.equal(false);
67
- expect(checkboxes[0].isReportValidityOrSubmit).to.equal(true);
68
- expect(checkboxes[1].validity.valid).to.equal(false);
69
- expect(checkboxes[1].isReportValidityOrSubmit).to.equal(true);
65
+ expect(component.validity.valid).to.be.false;
66
+ expect(checkboxes[0].validity.valid).to.be.false;
67
+ expect(checkboxes[0].isReportValidityOrSubmit).to.be.true;
68
+ expect(checkboxes[1].validity.valid).to.be.false;
69
+ expect(checkboxes[1].isReportValidityOrSubmit).to.be.true;
70
70
  });
@@ -0,0 +1 @@
1
+ import './checkbox.js';