@helixui/library 3.7.0 → 3.8.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 (248) hide show
  1. package/custom-elements.json +1926 -303
  2. package/dist/components/hx-action-bar/hx-action-bar.d.ts +18 -0
  3. package/dist/components/hx-action-bar/hx-action-bar.d.ts.map +1 -1
  4. package/dist/components/hx-action-bar/hx-action-bar.styles.d.ts.map +1 -1
  5. package/dist/components/hx-action-bar/index.js +1 -1
  6. package/dist/components/hx-banner/hx-banner.d.ts +19 -0
  7. package/dist/components/hx-banner/hx-banner.d.ts.map +1 -1
  8. package/dist/components/hx-breadcrumb/hx-breadcrumb-item.d.ts.map +1 -1
  9. package/dist/components/hx-breadcrumb/hx-breadcrumb-item.styles.d.ts.map +1 -1
  10. package/dist/components/hx-breadcrumb/hx-breadcrumb.d.ts +18 -0
  11. package/dist/components/hx-breadcrumb/hx-breadcrumb.d.ts.map +1 -1
  12. package/dist/components/hx-breadcrumb/index.js +1 -1
  13. package/dist/components/hx-button/hx-button.styles.d.ts.map +1 -1
  14. package/dist/components/hx-button/index.js +1 -1
  15. package/dist/components/hx-button-group/hx-button-group.d.ts +47 -0
  16. package/dist/components/hx-button-group/hx-button-group.d.ts.map +1 -1
  17. package/dist/components/hx-button-group/index.js +1 -1
  18. package/dist/components/hx-checkbox/hx-checkbox.styles.d.ts.map +1 -1
  19. package/dist/components/hx-checkbox/index.js +1 -1
  20. package/dist/components/hx-checkbox-group/hx-checkbox-group.d.ts +36 -0
  21. package/dist/components/hx-checkbox-group/hx-checkbox-group.d.ts.map +1 -1
  22. package/dist/components/hx-checkbox-group/hx-checkbox-group.styles.d.ts.map +1 -1
  23. package/dist/components/hx-checkbox-group/index.js +1 -1
  24. package/dist/components/hx-clinical-status/hx-clinical-status.d.ts +19 -0
  25. package/dist/components/hx-clinical-status/hx-clinical-status.d.ts.map +1 -1
  26. package/dist/components/hx-color-picker/hx-color-picker.d.ts +18 -0
  27. package/dist/components/hx-color-picker/hx-color-picker.d.ts.map +1 -1
  28. package/dist/components/hx-color-picker/hx-color-picker.styles.d.ts.map +1 -1
  29. package/dist/components/hx-color-picker/index.js +1 -1
  30. package/dist/components/hx-combobox/hx-combobox.d.ts +18 -0
  31. package/dist/components/hx-combobox/hx-combobox.d.ts.map +1 -1
  32. package/dist/components/hx-copy-button/hx-copy-button.d.ts +18 -0
  33. package/dist/components/hx-copy-button/hx-copy-button.d.ts.map +1 -1
  34. package/dist/components/hx-copy-button/hx-copy-button.styles.d.ts.map +1 -1
  35. package/dist/components/hx-copy-button/index.js +1 -1
  36. package/dist/components/hx-date-picker/hx-date-picker.d.ts +18 -0
  37. package/dist/components/hx-date-picker/hx-date-picker.d.ts.map +1 -1
  38. package/dist/components/hx-date-picker/hx-date-picker.styles.d.ts.map +1 -1
  39. package/dist/components/hx-date-picker/index.js +1 -1
  40. package/dist/components/hx-drawer/hx-drawer.d.ts +18 -0
  41. package/dist/components/hx-drawer/hx-drawer.d.ts.map +1 -1
  42. package/dist/components/hx-dropdown/hx-dropdown.d.ts +18 -0
  43. package/dist/components/hx-dropdown/hx-dropdown.d.ts.map +1 -1
  44. package/dist/components/hx-dropdown/hx-dropdown.styles.d.ts.map +1 -1
  45. package/dist/components/hx-dropdown/index.js +1 -1
  46. package/dist/components/hx-field/hx-field.d.ts +17 -0
  47. package/dist/components/hx-field/hx-field.d.ts.map +1 -1
  48. package/dist/components/hx-field-label/hx-field-label.d.ts +17 -0
  49. package/dist/components/hx-field-label/hx-field-label.d.ts.map +1 -1
  50. package/dist/components/hx-file-upload/hx-file-upload.d.ts +18 -0
  51. package/dist/components/hx-file-upload/hx-file-upload.d.ts.map +1 -1
  52. package/dist/components/hx-form/hx-form.d.ts +19 -0
  53. package/dist/components/hx-form/hx-form.d.ts.map +1 -1
  54. package/dist/components/hx-help-text/hx-help-text.d.ts +17 -0
  55. package/dist/components/hx-help-text/hx-help-text.d.ts.map +1 -1
  56. package/dist/components/hx-icon-button/hx-icon-button.d.ts +18 -0
  57. package/dist/components/hx-icon-button/hx-icon-button.d.ts.map +1 -1
  58. package/dist/components/hx-menu/hx-menu.d.ts +18 -0
  59. package/dist/components/hx-menu/hx-menu.d.ts.map +1 -1
  60. package/dist/components/hx-nav/hx-nav.d.ts +18 -0
  61. package/dist/components/hx-nav/hx-nav.d.ts.map +1 -1
  62. package/dist/components/hx-nav/hx-nav.styles.d.ts.map +1 -1
  63. package/dist/components/hx-nav/index.js +1 -1
  64. package/dist/components/hx-number-input/hx-number-input.d.ts +18 -0
  65. package/dist/components/hx-number-input/hx-number-input.d.ts.map +1 -1
  66. package/dist/components/hx-number-input/index.js +1 -1
  67. package/dist/components/hx-overflow-menu/hx-overflow-menu.d.ts +18 -0
  68. package/dist/components/hx-overflow-menu/hx-overflow-menu.d.ts.map +1 -1
  69. package/dist/components/hx-popover/hx-popover.d.ts +18 -0
  70. package/dist/components/hx-popover/hx-popover.d.ts.map +1 -1
  71. package/dist/components/hx-popover/hx-popover.styles.d.ts.map +1 -1
  72. package/dist/components/hx-popover/index.js +1 -1
  73. package/dist/components/hx-popup/hx-popup.d.ts +18 -0
  74. package/dist/components/hx-popup/hx-popup.d.ts.map +1 -1
  75. package/dist/components/hx-popup/hx-popup.styles.d.ts.map +1 -1
  76. package/dist/components/hx-popup/index.js +1 -1
  77. package/dist/components/hx-radio-group/hx-radio-group.d.ts +18 -0
  78. package/dist/components/hx-radio-group/hx-radio-group.d.ts.map +1 -1
  79. package/dist/components/hx-radio-group/hx-radio-group.styles.d.ts.map +1 -1
  80. package/dist/components/hx-radio-group/hx-radio.styles.d.ts.map +1 -1
  81. package/dist/components/hx-radio-group/index.js +1 -1
  82. package/dist/components/hx-rating/hx-rating.d.ts +19 -0
  83. package/dist/components/hx-rating/hx-rating.d.ts.map +1 -1
  84. package/dist/components/hx-select/hx-select.d.ts +18 -0
  85. package/dist/components/hx-select/hx-select.d.ts.map +1 -1
  86. package/dist/components/hx-side-nav/hx-side-nav.d.ts +18 -0
  87. package/dist/components/hx-side-nav/hx-side-nav.d.ts.map +1 -1
  88. package/dist/components/hx-side-nav/hx-side-nav.styles.d.ts.map +1 -1
  89. package/dist/components/hx-side-nav/index.js +1 -1
  90. package/dist/components/hx-slider/hx-slider.d.ts +19 -0
  91. package/dist/components/hx-slider/hx-slider.d.ts.map +1 -1
  92. package/dist/components/hx-split-button/hx-split-button.d.ts +18 -0
  93. package/dist/components/hx-split-button/hx-split-button.d.ts.map +1 -1
  94. package/dist/components/hx-split-button/hx-split-button.styles.d.ts.map +1 -1
  95. package/dist/components/hx-split-button/index.js +1 -1
  96. package/dist/components/hx-switch/hx-switch.d.ts +18 -0
  97. package/dist/components/hx-switch/hx-switch.d.ts.map +1 -1
  98. package/dist/components/hx-switch/hx-switch.styles.d.ts.map +1 -1
  99. package/dist/components/hx-switch/index.js +1 -1
  100. package/dist/components/hx-tabs/hx-tab.styles.d.ts.map +1 -1
  101. package/dist/components/hx-tabs/hx-tabs.d.ts +18 -0
  102. package/dist/components/hx-tabs/hx-tabs.d.ts.map +1 -1
  103. package/dist/components/hx-tabs/index.js +1 -1
  104. package/dist/components/hx-text-input/hx-text-input.styles.d.ts.map +1 -1
  105. package/dist/components/hx-text-input/index.js +1 -1
  106. package/dist/components/hx-textarea/hx-textarea.d.ts +18 -0
  107. package/dist/components/hx-textarea/hx-textarea.d.ts.map +1 -1
  108. package/dist/components/hx-time-picker/hx-time-picker.d.ts +18 -0
  109. package/dist/components/hx-time-picker/hx-time-picker.d.ts.map +1 -1
  110. package/dist/components/hx-time-picker/hx-time-picker.styles.d.ts.map +1 -1
  111. package/dist/components/hx-time-picker/index.js +1 -1
  112. package/dist/components/hx-toast/hx-toast.d.ts +19 -0
  113. package/dist/components/hx-toast/hx-toast.d.ts.map +1 -1
  114. package/dist/components/hx-toggle-button/hx-toggle-button.d.ts +18 -0
  115. package/dist/components/hx-toggle-button/hx-toggle-button.d.ts.map +1 -1
  116. package/dist/components/hx-toggle-button/hx-toggle-button.styles.d.ts.map +1 -1
  117. package/dist/components/hx-toggle-button/index.js +1 -1
  118. package/dist/components/hx-tooltip/hx-tooltip.d.ts +18 -0
  119. package/dist/components/hx-tooltip/hx-tooltip.d.ts.map +1 -1
  120. package/dist/components/hx-tooltip/hx-tooltip.styles.d.ts.map +1 -1
  121. package/dist/components/hx-tooltip/index.js +1 -1
  122. package/dist/components/hx-top-nav/hx-top-nav.d.ts +18 -0
  123. package/dist/components/hx-top-nav/hx-top-nav.d.ts.map +1 -1
  124. package/dist/components/hx-top-nav/hx-top-nav.styles.d.ts.map +1 -1
  125. package/dist/components/hx-top-nav/index.js +1 -1
  126. package/dist/css/helix-all.css +239 -30
  127. package/dist/css/helix-core.css +4 -1
  128. package/dist/css/helix-forms.css +100 -15
  129. package/dist/css/helix-navigation.css +43 -2
  130. package/dist/css/helix-overlay.css +53 -0
  131. package/dist/css/helix-tokens.css +13 -12
  132. package/dist/css/helix-utility.css +39 -12
  133. package/dist/css/hx-action-bar.css +12 -0
  134. package/dist/css/hx-button.css +4 -1
  135. package/dist/css/hx-checkbox-group.css +11 -0
  136. package/dist/css/hx-checkbox.css +10 -0
  137. package/dist/css/hx-color-picker.css +14 -1
  138. package/dist/css/hx-copy-button.css +5 -2
  139. package/dist/css/hx-date-picker.css +6 -1
  140. package/dist/css/hx-dropdown.css +13 -0
  141. package/dist/css/hx-nav.css +24 -2
  142. package/dist/css/hx-number-input.css +8 -8
  143. package/dist/css/hx-popover.css +13 -0
  144. package/dist/css/hx-popup.css +14 -0
  145. package/dist/css/hx-radio-group.css +10 -0
  146. package/dist/css/hx-side-nav.css +7 -0
  147. package/dist/css/hx-split-button.css +22 -10
  148. package/dist/css/hx-switch.css +19 -1
  149. package/dist/css/hx-text-input.css +4 -1
  150. package/dist/css/hx-time-picker.css +7 -2
  151. package/dist/css/hx-toggle-button.css +11 -1
  152. package/dist/css/hx-tooltip.css +13 -0
  153. package/dist/css/hx-top-nav.css +12 -0
  154. package/dist/css/index.css +1 -1
  155. package/dist/css/manifest.json +40 -12
  156. package/dist/index.js +24 -24
  157. package/dist/shared/{hx-action-bar-CitgcpGv.js → hx-action-bar-BlEG4aZv.js} +41 -29
  158. package/dist/shared/hx-action-bar-BlEG4aZv.js.map +1 -0
  159. package/dist/shared/hx-banner-fpRnciIO.js.map +1 -1
  160. package/dist/shared/{hx-breadcrumb-item-3tKppF9h.js → hx-breadcrumb-item-D8xYqe3s.js} +56 -43
  161. package/dist/shared/hx-breadcrumb-item-D8xYqe3s.js.map +1 -0
  162. package/dist/shared/{hx-button-rRNmD4fd.js → hx-button-DOZTZnz-.js} +18 -15
  163. package/dist/shared/hx-button-DOZTZnz-.js.map +1 -0
  164. package/dist/shared/hx-button-group-D3QUmSzl.js +248 -0
  165. package/dist/shared/hx-button-group-D3QUmSzl.js.map +1 -0
  166. package/dist/shared/{hx-checkbox-hPlIw6Lb.js → hx-checkbox-DcgyGS9V.js} +30 -20
  167. package/dist/shared/hx-checkbox-DcgyGS9V.js.map +1 -0
  168. package/dist/shared/{hx-checkbox-group-D5piJLY8.js → hx-checkbox-group-C0q6HDqn.js} +101 -58
  169. package/dist/shared/hx-checkbox-group-C0q6HDqn.js.map +1 -0
  170. package/dist/shared/hx-clinical-status-D3XQIOqX.js.map +1 -1
  171. package/dist/shared/{hx-color-picker-DBwJzT5f.js → hx-color-picker-CYjx8i8R.js} +97 -84
  172. package/dist/shared/hx-color-picker-CYjx8i8R.js.map +1 -0
  173. package/dist/shared/hx-combobox-NgJaLbs2.js.map +1 -1
  174. package/dist/shared/{hx-copy-button-sUVuikyH.js → hx-copy-button-DJirFCUL.js} +18 -15
  175. package/dist/shared/hx-copy-button-DJirFCUL.js.map +1 -0
  176. package/dist/shared/{hx-date-picker-DSKDkCy1.js → hx-date-picker-0PtEav0K.js} +66 -61
  177. package/dist/shared/hx-date-picker-0PtEav0K.js.map +1 -0
  178. package/dist/shared/hx-drawer-CM_upadk.js.map +1 -1
  179. package/dist/shared/{hx-dropdown-D626S2ZG.js → hx-dropdown-xHwTJecv.js} +44 -31
  180. package/dist/shared/hx-dropdown-xHwTJecv.js.map +1 -0
  181. package/dist/shared/hx-field-label-BVRyyKeh.js.map +1 -1
  182. package/dist/shared/hx-field-zw0U1KVi.js.map +1 -1
  183. package/dist/shared/hx-file-upload-D3rKROK5.js.map +1 -1
  184. package/dist/shared/hx-form-CkChEATa.js.map +1 -1
  185. package/dist/shared/hx-help-text-Xb2Yr8x2.js.map +1 -1
  186. package/dist/shared/hx-icon-button-B2BdVdyK.js.map +1 -1
  187. package/dist/shared/hx-menu-divider-A6Guuzi_.js.map +1 -1
  188. package/dist/shared/{hx-nav-ldFM3Fle.js → hx-nav-ChMTfn7o.js} +66 -44
  189. package/dist/shared/hx-nav-ChMTfn7o.js.map +1 -0
  190. package/dist/shared/{hx-nav-item-CODtUlew.js → hx-nav-item-ClN17f1y.js} +62 -55
  191. package/dist/shared/hx-nav-item-ClN17f1y.js.map +1 -0
  192. package/dist/shared/{hx-number-input-yUzFOSC1.js → hx-number-input-MggsT7F0.js} +13 -13
  193. package/dist/shared/hx-number-input-MggsT7F0.js.map +1 -0
  194. package/dist/shared/hx-overflow-menu-DFjJAziP.js.map +1 -1
  195. package/dist/shared/{hx-popover-BAlAFOH9.js → hx-popover-BjB0nkcq.js} +51 -38
  196. package/dist/shared/hx-popover-BjB0nkcq.js.map +1 -0
  197. package/dist/shared/{hx-popup-COUXXZ9X.js → hx-popup-BiV_2evC.js} +59 -45
  198. package/dist/shared/hx-popup-BiV_2evC.js.map +1 -0
  199. package/dist/shared/{hx-radio-CY4kQfZw.js → hx-radio-BY4zpwdh.js} +45 -27
  200. package/dist/shared/hx-radio-BY4zpwdh.js.map +1 -0
  201. package/dist/shared/hx-rating-C3QP53k9.js.map +1 -1
  202. package/dist/shared/hx-select-DahFehiZ.js.map +1 -1
  203. package/dist/shared/hx-slider-Blmv_rwS.js.map +1 -1
  204. package/dist/shared/{hx-split-button-Ddle8iVx.js → hx-split-button-CdNz1XAu.js} +62 -50
  205. package/dist/shared/hx-split-button-CdNz1XAu.js.map +1 -0
  206. package/dist/shared/{hx-switch-TvKGvZJz.js → hx-switch-BCXuNxEH.js} +42 -24
  207. package/dist/shared/hx-switch-BCXuNxEH.js.map +1 -0
  208. package/dist/shared/{hx-tab-panel-DzsX8BHV.js → hx-tab-panel-BfisavKo.js} +47 -32
  209. package/dist/shared/hx-tab-panel-BfisavKo.js.map +1 -0
  210. package/dist/shared/{hx-text-input-D6FlOZM-.js → hx-text-input-V5sQOpDh.js} +5 -2
  211. package/dist/shared/hx-text-input-V5sQOpDh.js.map +1 -0
  212. package/dist/shared/hx-textarea-CNG590KY.js.map +1 -1
  213. package/dist/shared/{hx-time-picker-Bo7FWzmf.js → hx-time-picker-DfJkBwcX.js} +41 -36
  214. package/dist/shared/hx-time-picker-DfJkBwcX.js.map +1 -0
  215. package/dist/shared/{hx-toggle-button-DSJeFlb0.js → hx-toggle-button-xNVYeA3X.js} +37 -27
  216. package/dist/shared/hx-toggle-button-xNVYeA3X.js.map +1 -0
  217. package/dist/shared/{hx-tooltip-DVqtKPCD.js → hx-tooltip-CamO-9nd.js} +24 -11
  218. package/dist/shared/hx-tooltip-CamO-9nd.js.map +1 -0
  219. package/dist/shared/{hx-top-nav-DP6OFS8C.js → hx-top-nav-CsTxOtVI.js} +26 -14
  220. package/dist/shared/hx-top-nav-CsTxOtVI.js.map +1 -0
  221. package/dist/shared/toast-factory-Dht3pVsw.js.map +1 -1
  222. package/figma-inventory.json +1121 -345
  223. package/package.json +2 -2
  224. package/dist/shared/hx-action-bar-CitgcpGv.js.map +0 -1
  225. package/dist/shared/hx-breadcrumb-item-3tKppF9h.js.map +0 -1
  226. package/dist/shared/hx-button-group-4NUBpkyC.js +0 -181
  227. package/dist/shared/hx-button-group-4NUBpkyC.js.map +0 -1
  228. package/dist/shared/hx-button-rRNmD4fd.js.map +0 -1
  229. package/dist/shared/hx-checkbox-group-D5piJLY8.js.map +0 -1
  230. package/dist/shared/hx-checkbox-hPlIw6Lb.js.map +0 -1
  231. package/dist/shared/hx-color-picker-DBwJzT5f.js.map +0 -1
  232. package/dist/shared/hx-copy-button-sUVuikyH.js.map +0 -1
  233. package/dist/shared/hx-date-picker-DSKDkCy1.js.map +0 -1
  234. package/dist/shared/hx-dropdown-D626S2ZG.js.map +0 -1
  235. package/dist/shared/hx-nav-item-CODtUlew.js.map +0 -1
  236. package/dist/shared/hx-nav-ldFM3Fle.js.map +0 -1
  237. package/dist/shared/hx-number-input-yUzFOSC1.js.map +0 -1
  238. package/dist/shared/hx-popover-BAlAFOH9.js.map +0 -1
  239. package/dist/shared/hx-popup-COUXXZ9X.js.map +0 -1
  240. package/dist/shared/hx-radio-CY4kQfZw.js.map +0 -1
  241. package/dist/shared/hx-split-button-Ddle8iVx.js.map +0 -1
  242. package/dist/shared/hx-switch-TvKGvZJz.js.map +0 -1
  243. package/dist/shared/hx-tab-panel-DzsX8BHV.js.map +0 -1
  244. package/dist/shared/hx-text-input-D6FlOZM-.js.map +0 -1
  245. package/dist/shared/hx-time-picker-Bo7FWzmf.js.map +0 -1
  246. package/dist/shared/hx-toggle-button-DSJeFlb0.js.map +0 -1
  247. package/dist/shared/hx-tooltip-DVqtKPCD.js.map +0 -1
  248. package/dist/shared/hx-top-nav-DP6OFS8C.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hx-checkbox-DcgyGS9V.js","sources":["../../src/components/hx-checkbox/hx-checkbox.styles.ts","../../src/components/hx-checkbox/hx-checkbox.ts"],"sourcesContent":["import { css } from 'lit';\n\nexport const helixCheckboxStyles = css`\n :host {\n display: block;\n }\n\n :host([disabled]) {\n opacity: var(--hx-opacity-disabled, 0.5);\n pointer-events: none;\n }\n\n * {\n box-sizing: border-box;\n }\n\n .checkbox {\n display: flex;\n flex-direction: column;\n gap: var(--hx-space-1, 0.25rem);\n font-family: var(--hx-checkbox-font-family, var(--hx-font-family-sans, sans-serif));\n }\n\n /* ─── Control (checkbox + label row) ─── */\n\n .checkbox__control {\n display: inline-flex;\n align-items: flex-start;\n gap: var(--hx-space-2, 0.5rem);\n /* WCAG 2.5.5 (healthcare mandate): minimum 44px touch target height */\n min-height: var(--hx-touch-target-min, 2.75rem);\n cursor: pointer;\n }\n\n :host([disabled]) .checkbox__control {\n cursor: not-allowed;\n }\n\n /* ─── Hidden Native Input ─── */\n\n .checkbox__input {\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n margin: -1px;\n overflow: hidden;\n clip-path: inset(50%);\n white-space: nowrap;\n border: 0;\n }\n\n /* ─── Visual Checkbox ─── */\n\n .checkbox__box {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n width: var(--hx-checkbox-size, var(--hx-size-5, 1.25rem));\n height: var(--hx-checkbox-size, var(--hx-size-5, 1.25rem));\n border: var(--hx-border-width-medium, 2px) solid\n var(--hx-checkbox-border-color, var(--hx-color-border-strong, #66787b));\n border-radius: var(--hx-checkbox-border-radius, var(--hx-border-radius-sm, 0.25rem));\n background-color: var(--hx-checkbox-bg, var(--hx-color-surface-default, #ffffff));\n transition:\n background-color var(--hx-transition-fast, 150ms ease),\n border-color var(--hx-transition-fast, 150ms ease),\n box-shadow var(--hx-transition-fast, 150ms ease);\n margin-top: var(--hx-space-px, 1px);\n }\n\n /* ─── Focus Ring ─── */\n\n /*\n * Suppress the browser default ~1px host outline. Without this, the formal\n * AAA audit harness (which measures computed outline-width on the focused\n * host) records a sub-2px outline and reports WCAG 2.4.13 Partially Supports.\n * The visual focus indicator is rendered on the inner .checkbox__box below.\n */\n :host {\n outline: none;\n }\n\n /*\n * Host-focus path: on the modern (IDL element-references) render branch the\n * host is the tabbable surface (tabindex=0) and the inner input is demoted\n * to tabindex=-1. Drive the focus ring from ':host(:focus-visible)' so\n * keyboard users still get a visible affordance. Codex round-11 P1.\n */\n :host(:focus-visible) .checkbox__box {\n outline: var(--hx-checkbox-focus-ring-width, var(--hx-focus-ring-width, 2px)) solid\n var(--hx-checkbox-focus-ring-color, var(--hx-focus-ring-color, #0f7078));\n outline-offset: var(--hx-checkbox-focus-ring-offset, var(--hx-focus-ring-offset, 2px));\n }\n\n /*\n * Fallback (no-IDL-ref) path: the host carries tabindex=-1 and the inner\n * input is the tab target. The native :focus-visible on the input drives\n * the same visual ring, scoped via the inner-state class.\n */\n .checkbox__input:focus-visible ~ .checkbox__box {\n outline: var(--hx-checkbox-focus-ring-width, var(--hx-focus-ring-width, 2px)) solid\n var(--hx-checkbox-focus-ring-color, var(--hx-focus-ring-color, #0f7078));\n outline-offset: var(--hx-checkbox-focus-ring-offset, var(--hx-focus-ring-offset, 2px));\n }\n\n /* ─── Checked State ─── */\n\n .checkbox--checked .checkbox__box {\n background-color: var(--hx-checkbox-checked-bg, var(--hx-color-action-primary-bg, #0f7078));\n border-color: var(\n --hx-checkbox-checked-border-color,\n var(--hx-color-action-primary-bg, #0f7078)\n );\n }\n\n /* ─── Indeterminate State ─── */\n\n .checkbox--indeterminate .checkbox__box {\n background-color: var(--hx-checkbox-checked-bg, var(--hx-color-action-primary-bg, #0f7078));\n border-color: var(\n --hx-checkbox-checked-border-color,\n var(--hx-color-action-primary-bg, #0f7078)\n );\n }\n\n /* ─── Error State ─── */\n\n .checkbox--error .checkbox__box {\n border-color: var(--hx-checkbox-error-color, var(--hx-color-error-500, #e5493e));\n }\n\n .checkbox--error.checkbox--checked .checkbox__box,\n .checkbox--error.checkbox--indeterminate .checkbox__box {\n background-color: var(--hx-checkbox-error-color, var(--hx-color-error-500, #e5493e));\n border-color: var(--hx-checkbox-error-color, var(--hx-color-error-500, #e5493e));\n }\n\n /* ─── Hover ─── */\n\n /* P1-03: use component token so consumer overrides of --hx-checkbox-border-color work on hover */\n .checkbox__control:hover .checkbox__box {\n border-color: var(\n --hx-checkbox-hover-border-color,\n var(--hx-checkbox-border-color, var(--hx-color-primary-500, #429797))\n );\n }\n\n .checkbox--checked .checkbox__control:hover .checkbox__box {\n filter: brightness(var(--hx-filter-brightness-hover, 0.9));\n }\n\n .checkbox--error .checkbox__control:hover .checkbox__box {\n border-color: var(--hx-checkbox-error-color, var(--hx-color-error-500, #e5493e));\n }\n\n /* ─── Checkmark Icon ─── */\n\n .checkbox__icon {\n display: none;\n width: calc(var(--hx-checkbox-size, var(--hx-size-5, 1.25rem)) * 0.65);\n height: calc(var(--hx-checkbox-size, var(--hx-size-5, 1.25rem)) * 0.65);\n fill: none;\n stroke: var(--hx-checkbox-checkmark-color, var(--hx-color-text-on-primary, #ffffff));\n stroke-width: 2.5;\n stroke-linecap: round;\n stroke-linejoin: round;\n }\n\n .checkbox--checked .checkbox__icon--check {\n display: block;\n }\n\n .checkbox--indeterminate .checkbox__icon--indeterminate {\n display: block;\n }\n\n /* ─── Label ─── */\n\n .checkbox__label {\n font-size: var(--hx-font-size-sm, 0.875rem);\n font-weight: var(--hx-font-weight-medium, 500);\n color: var(--hx-checkbox-label-color, var(--hx-color-text-strong, #202b39));\n line-height: var(--hx-line-height-normal, 1.5);\n user-select: none;\n -webkit-user-select: none;\n }\n\n .checkbox__required-marker {\n color: var(--hx-checkbox-error-color, var(--hx-color-error-text, #c92a2a));\n font-weight: var(--hx-font-weight-bold, 700);\n }\n\n /* ─── Help Text & Error Messages ─── */\n\n .checkbox__help-text {\n font-size: var(--hx-font-size-xs, 0.75rem);\n color: var(--hx-checkbox-help-text-color, var(--hx-color-text-muted, #4a5362));\n line-height: var(--hx-line-height-normal, 1.5);\n padding-inline-start: calc(\n var(--hx-checkbox-size, var(--hx-size-5, 1.25rem)) + var(--hx-space-2, 0.5rem)\n );\n }\n\n .checkbox__error {\n font-size: var(--hx-font-size-xs, 0.75rem);\n color: var(--hx-checkbox-error-color, var(--hx-color-error-text, #c92a2a));\n line-height: var(--hx-line-height-normal, 1.5);\n padding-inline-start: calc(\n var(--hx-checkbox-size, var(--hx-size-5, 1.25rem)) + var(--hx-space-2, 0.5rem)\n );\n }\n\n /* ─── Size Variants ─── */\n\n :host([hx-size='sm']) {\n --hx-checkbox-size: var(--hx-size-4, 1rem);\n }\n\n :host([hx-size='sm']) .checkbox__label {\n font-size: var(--hx-font-size-xs, 0.75rem);\n }\n\n :host([hx-size='sm']) .checkbox__help-text,\n :host([hx-size='sm']) .checkbox__error {\n font-size: var(--hx-font-size-xs, 0.75rem);\n padding-inline-start: calc(var(--hx-size-4, 1rem) + var(--hx-space-2, 0.5rem));\n }\n\n :host([hx-size='lg']) {\n --hx-checkbox-size: var(--hx-size-6, 1.5rem);\n }\n\n :host([hx-size='lg']) .checkbox__label {\n font-size: var(--hx-font-size-md, 1rem);\n }\n\n :host([hx-size='lg']) .checkbox__help-text,\n :host([hx-size='lg']) .checkbox__error {\n font-size: var(--hx-font-size-sm, 0.875rem);\n padding-inline-start: calc(var(--hx-size-6, 1.5rem) + var(--hx-space-2, 0.5rem));\n }\n\n /* ─── Reduced Motion ─── */\n\n @media (prefers-reduced-motion: reduce) {\n .checkbox__box {\n transition: none;\n }\n }\n\n /* ─── High Contrast Mode (forced-colors) ─── */\n\n @media (forced-colors: active) {\n .checkbox__box {\n forced-color-adjust: none;\n background-color: ButtonFace;\n border: 2px solid ButtonText;\n }\n\n :host(:focus-visible) .checkbox__box,\n .checkbox__input:focus-visible ~ .checkbox__box {\n outline: 3px solid Highlight;\n outline-offset: 2px;\n }\n\n .checkbox--checked .checkbox__box,\n .checkbox--indeterminate .checkbox__box {\n background-color: Highlight;\n border-color: Highlight;\n }\n\n .checkbox__icon {\n stroke: HighlightText;\n }\n\n .checkbox--error .checkbox__box {\n border-color: LinkText;\n }\n\n .checkbox--error.checkbox--checked .checkbox__box,\n .checkbox--error.checkbox--indeterminate .checkbox__box {\n background-color: LinkText;\n border-color: LinkText;\n }\n\n :host([disabled]) {\n opacity: 1;\n }\n\n :host([disabled]) .checkbox__box {\n border-color: GrayText;\n background-color: ButtonFace;\n }\n\n :host([disabled]) .checkbox--checked .checkbox__box,\n :host([disabled]) .checkbox--indeterminate .checkbox__box {\n background-color: GrayText;\n border-color: GrayText;\n }\n\n :host([disabled]) .checkbox__label {\n color: GrayText;\n }\n\n .checkbox__label {\n color: CanvasText;\n }\n\n .checkbox__help-text {\n color: GrayText;\n }\n\n .checkbox__error {\n color: LinkText;\n }\n }\n`;\n","import { html, nothing, type PropertyValues } from 'lit';\nimport '../../utilities/document-token-adoption.js';\nimport { customElement, property, query, state } from 'lit/decorators.js';\nimport { classMap } from 'lit/directives/class-map.js';\nimport { ifDefined } from 'lit/directives/if-defined.js';\nimport { live } from 'lit/directives/live.js';\nimport { HelixElement, createIdCounter } from '../../base/index.js';\nimport { mixinDelegatesAria } from '../../mixins/index.js';\nimport { FormMixin } from '../../mixins/FormMixin.js';\nimport { helixCheckboxStyles } from './hx-checkbox.styles.js';\nimport { forcedColorsField } from '../../styles/forced-colors.js';\nimport { devWarn } from '../../utils/dev-warn.js';\nimport {\n installAriaIdrefMirror,\n resolveIdrefTokens,\n supportsIdrefElementReferences,\n type AriaIdrefMirrorHandle,\n} from '../../utils/aria-idref.js';\n\n// P2-05: monotonic counter — collision-free, deterministic, SSR-safe\nconst _nextCheckboxId = createIdCounter('hx-checkbox');\n\n/** Detail for the hx-change event dispatched by hx-checkbox. */\nexport interface HxCheckboxChangeDetail {\n checked: boolean;\n value: string;\n}\n\n/**\n * A checkbox component with label, validation, and form association.\n *\n * @summary Form-associated checkbox with built-in label, error, and help text.\n *\n * @tag hx-checkbox\n *\n * @slot - Custom label content (overrides the label property). Rich HTML allowed — Drupal can include links in consent labels.\n * @slot error - Custom error content (overrides the error property).\n * @slot help-text - Custom help text content (overrides the helpText property).\n *\n * @fires {CustomEvent<{checked: boolean, value: string}>} hx-change - Dispatched when the checkbox is toggled. Boolean-selection controls (`hx-switch`, `hx-checkbox`) include both `checked` (boolean state) and `value` (form value) in the detail; text-value controls (`hx-text-input`, `hx-combobox`, `hx-select`) emit only `{value}`.\n *\n * @csspart checkbox - The visual checkbox element.\n * @csspart checkmark - The SVG checkmark icon inside the checkbox.\n * @csspart label - The label element.\n * @csspart help-text - The help text container.\n * @csspart error - The error message container.\n * @csspart control - The wrapper around checkbox and label.\n *\n * @cssprop [--hx-checkbox-size=var(--hx-size-5, 1.25rem)] - Checkbox dimensions.\n * @cssprop [--hx-checkbox-bg=var(--hx-color-neutral-0, #ffffff)] - Unchecked background color.\n * @cssprop [--hx-checkbox-border-color=var(--hx-color-neutral-300, #B6BFB9)] - Checkbox border color.\n * @cssprop [--hx-checkbox-border-radius=var(--hx-border-radius-sm, 0.25rem)] - Checkbox border radius.\n * @cssprop [--hx-checkbox-checked-bg=var(--hx-color-primary-500, #429797)] - Checked background color.\n * @cssprop [--hx-checkbox-checked-border-color=var(--hx-color-primary-500, #429797)] - Checked border color.\n * @cssprop [--hx-checkbox-checkmark-color=var(--hx-color-neutral-0, #ffffff)] - Checkmark color.\n * @cssprop [--hx-checkbox-focus-ring-color=var(--hx-focus-ring-color, #6AB1B1)] - Focus ring color.\n * @cssprop [--hx-checkbox-label-color=var(--hx-color-neutral-700, #313E4B)] - Label text color.\n * @cssprop [--hx-checkbox-help-text-color=var(--hx-color-neutral-500, #66787B)] - Help text color.\n * @cssprop [--hx-checkbox-hover-border-color=var(--hx-checkbox-border-color)] - Border color on hover.\n * @cssprop [--hx-checkbox-error-color=var(--hx-color-error-500, #E5493E)] - Error state color.\n * @cssprop [--hx-opacity-disabled] - Opacity.\n * @cssprop [--hx-space-1] - Spacing token.\n * @cssprop [--hx-checkbox-font-family=var(--hx-font-family-sans)] - Font family for checkbox label and help text.\n * @cssprop [--hx-font-family-sans] - Font family.\n * @cssprop [--hx-space-2] - Spacing token.\n * @cssprop [--hx-touch-target-min] - Minimum touch target size.\n * @cssprop [--hx-size-5] - Size token.\n * @cssprop [--hx-border-width-medium] - Width.\n * @cssprop [--hx-color-neutral-300] - Color.\n * @cssprop [--hx-border-radius-sm] - CSS custom property.\n * @cssprop [--hx-color-neutral-0] - Color.\n * @cssprop [--hx-transition-fast] - Transition timing.\n * @cssprop [--hx-space-px] - Spacing token.\n * @cssprop [--hx-focus-ring-width] - Width.\n * @cssprop [--hx-focus-ring-color] - Color.\n * @cssprop [--hx-color-primary-400] - Color.\n * @cssprop [--hx-focus-ring-offset] - CSS custom property.\n * @cssprop [--hx-color-primary-500] - Color.\n * @cssprop [--hx-filter-brightness-hover] - CSS filter.\n * @cssprop [--hx-font-size-sm] - Font size.\n * @cssprop [--hx-font-weight-medium] - Font weight.\n * @cssprop [--hx-color-neutral-700] - Color.\n * @cssprop [--hx-line-height-normal] - Line height.\n * @cssprop [--hx-color-error-text] - Color.\n * @cssprop [--hx-font-weight-bold] - Font weight.\n * @cssprop [--hx-font-size-xs] - Font size.\n * @cssprop [--hx-color-neutral-500] - Color.\n * @cssprop [--hx-size-4] - Size token.\n * @cssprop [--hx-size-6] - Size token.\n * @cssprop [--hx-font-size-md] - Font size.\n * @cssprop [--hx-color-error-500] - Color.\n * @aaa-certified 2026-05-08\n * @aaa-criteria 1.4.6, 1.4.9, 2.1.3, 2.3.3, 2.4.12, 2.4.13, 2.5.5, 3.2.5, 3.3.6, forced-colors, apg-keyboard\n * @aaa-audit src/components/hx-checkbox/AAA-AUDIT.md\n * @keyboard-contract activate=Space; disabled-suppresses=true\n * @aria-pattern checkbox\n * @aria-pattern-source https://www.w3.org/WAI/ARIA/apg/patterns/checkbox/\n * @forced-colors-supported true\n * @stability stable\n * @since 3.6.0\n * @form-associated true\n * @theme-aware true\n * @brand-aware true\n * @drupal-sdc-eligible true\n * @react-wrapper-status complete\n * @figma-component-name hx-checkbox\n * @priority-tier P0\n * @phi-handles false\n * @clinical-context none\n */\n@customElement('hx-checkbox')\nexport class HelixCheckbox extends mixinDelegatesAria(FormMixin(HelixElement)) {\n static override styles = [helixCheckboxStyles, forcedColorsField];\n\n // ─── Form Association ───\n\n /** @internal */\n static override formAssociated = true;\n\n // ─── Properties ───\n\n /**\n * Whether the checkbox is checked.\n * @attr checked\n */\n @property({ type: Boolean, reflect: true })\n checked = false;\n\n /**\n * Whether the checkbox is in an indeterminate state (e.g., for \"select all\" patterns).\n * @attr indeterminate\n */\n @property({ type: Boolean, reflect: true })\n indeterminate = false;\n\n /**\n * Whether the checkbox is disabled.\n * @attr disabled\n */\n @property({ type: Boolean, reflect: true })\n disabled = false;\n\n /**\n * Whether the checkbox is required for form submission.\n * @attr required\n */\n @property({ type: Boolean, reflect: true })\n required = false;\n\n /**\n * The name of the checkbox, used for form submission.\n * @attr name\n */\n @property({ type: String, reflect: true })\n name = '';\n\n /**\n * The value submitted when the checkbox is checked.\n * @attr value\n */\n @property({ type: String, reflect: true })\n value = 'on';\n\n /**\n * The visible label text for the checkbox.\n * @attr label\n */\n @property({ type: String })\n label = '';\n\n /**\n * Error message to display. When set, the checkbox enters an error state.\n * @attr error\n */\n @property({ type: String })\n error = '';\n\n /**\n * Help text displayed below the checkbox for guidance.\n * @attr help-text\n */\n @property({ type: String, attribute: 'help-text' })\n helpText = '';\n\n /**\n * Validation message shown when the field is required but empty.\n * @attr required-message\n */\n @property({ attribute: 'required-message' })\n requiredMessage = 'This field is required.';\n\n /**\n * The size of the checkbox.\n * @attr hx-size\n */\n @property({ type: String, attribute: 'hx-size', reflect: true })\n size: 'sm' | 'md' | 'lg' = 'md';\n\n /**\n * Accessible label for the checkbox when no visible label text is provided.\n * Use when embedding a checkbox in a context where a label element is not practical.\n *\n * Accepts both `accessible-label` and the standard `aria-label` HTML attribute.\n * `accessible-label` takes precedence when both are set.\n * When set, replaces the visible label as the input's accessible name. Cannot be combined\n * with a visible label — set either `accessible-label` or the `label` slot, not both.\n *\n * @attr accessible-label\n */\n @property({ type: String, attribute: 'accessible-label' })\n accessibleLabel: string = '';\n\n /**\n * Returns the effective label for the checkbox, checking accessible-label first,\n * then the aria-label attribute, falling back to empty string.\n * @internal\n */\n private get _effectiveLabel(): string {\n return (\n this.accessibleLabel?.trim() ||\n this.getAttribute('data-aria-label')?.trim() ||\n this.getAttribute('aria-label')?.trim() ||\n ''\n );\n }\n\n /** @internal */\n @query('.checkbox__input')\n private _inputEl: HTMLInputElement | undefined;\n\n /** @internal */\n @state() private _hasErrorSlot = false;\n\n /** @internal */\n @state() private _hasHelpTextSlot = false;\n\n /** @internal */\n @state() private _hasLabelSlot = false;\n\n /**\n * Set by `hx-checkbox-group` to mark this child as group-managed. While\n * truthy, `_updateFormValue()` short-circuits to `setFormValue(null)`\n * regardless of `name`, so the child does NOT participate in form submission\n * — only the group does. This is durable against post-attach mutations to\n * `cb.name` by consumers/frameworks (which would otherwise re-arm\n * `_updateFormValue()` via the `name` setter and cause double-submission).\n * Codex round-3 finding #1.\n *\n * Public via accessor for the group's exclusive use; the underscore prefix\n * marks it as group-internal (not consumer API). The group sets it during\n * `slotchange` and clears it (via the same setter) when a child is removed.\n * @internal\n */\n set _groupedSuppress(value: boolean) {\n if (this.__groupedSuppress === value) return;\n this.__groupedSuppress = value;\n // Re-run form-value sync so the suppression takes effect immediately.\n this._updateFormValue();\n }\n get _groupedSuppress(): boolean {\n return this.__groupedSuppress;\n }\n /** @internal */\n private __groupedSuppress = false;\n\n /**\n * Deferred copy of this.error used inside the live region. Injected after\n * the region is visible (via requestAnimationFrame) so screen readers\n * re-announce the message even if it was set before the region became\n * visible — see WCAG 4.1.3.\n * @internal\n */\n @state() private _announcedError = '';\n\n /** @internal */\n private _hasWarnedLabelConflict = false;\n\n /**\n * Handle for the shared IDREF observer. Installed in `connectedCallback()`\n * so late-mutated `aria-labelledby`/`aria-describedby` and late-inserted\n * IDREF targets are picked up. See `installAriaIdrefMirror()`.\n * @internal\n */\n private _ariaMirror: AriaIdrefMirrorHandle | null = null;\n\n // ─── Slot Handlers ───\n\n /** @internal */\n private _handleErrorSlotChange(e: Event): void {\n const slot = e.target as HTMLSlotElement;\n this._hasErrorSlot = slot.assignedNodes({ flatten: true }).length > 0;\n }\n\n /** @internal */\n private _handleHelpTextSlotChange(e: Event): void {\n const slot = e.target as HTMLSlotElement;\n this._hasHelpTextSlot = slot.assignedNodes({ flatten: true }).length > 0;\n }\n\n /** @internal */\n private _handleLabelSlotChange(e: Event): void {\n const slot = e.target as HTMLSlotElement;\n // Default slot may include the fallback `${this.label}` text node — count\n // assigned (not flattened) nodes so the slot fallback is not mistaken for\n // user-supplied content. The visible label is independently tracked via\n // the `label` property below.\n this._hasLabelSlot = slot.assignedNodes().length > 0;\n }\n\n // ─── Lifecycle ───\n\n override connectedCallback(): void {\n super.connectedCallback();\n // Detect platform support for IDL element references. Cached as reactive\n // state so the render-time branch is consistent across update cycles and\n // tests can stub it deterministically. Codex round-2 finding #2.\n this._supportsIdrefRefs = supportsIdrefElementReferences(this._internals);\n // Seed root-independent semantics so the host carries the checkbox role\n // and reactive ARIA state from the moment of connection — before the\n // first paint. This closes the gap where AT scanning between connect\n // and `firstUpdated()` would see an unannounced surface.\n this._syncHostAriaSemantics();\n // Codex round-1 finding #1: host is the canonical announced surface on\n // modern browsers, so the inner `<input>` is demoted via\n // `aria-hidden + tabindex=-1` and the host owns tab order.\n //\n // Codex round-2 finding #2: on no-IDL-ref browsers the inner `<input>`\n // is the only surface AT can reach, so the host is demoted to\n // `tabindex=-1` and the inner input owns tab order. Without this,\n // `aria-labelledby`/`aria-describedby` on the inner input were inert\n // (the input was `aria-hidden`), leaving the control unnamed.\n // Codex round-14 P2: only claim ownership of `tabindex` when no consumer\n // value is present. Consumers using roving-tabindex toolbar patterns\n // must be able to set `tabindex=\"-1\"` on the host without it being\n // clobbered on every disabled flip. Note we still claim ownership when\n // disabled — the initial value is `-1` to keep the host out of tab order\n // and `updated()` re-asserts the appropriate value when disabled flips.\n if (!this.hasAttribute('tabindex')) {\n this._internalTabindexManaged = true;\n const enabledTabIndex = this._supportsIdrefRefs ? '0' : '-1';\n this.setAttribute('tabindex', this.disabled ? '-1' : enabledTabIndex);\n }\n this.addEventListener('keydown', this._handleHostKeyDown);\n this.addEventListener('click', this._handleHostClick);\n // Install the shared IDREF observer once the host is in a tree. The\n // observer covers consumer mutations to `aria-labelledby`/`-describedby`\n // (or their `data-aria-*` mirrors), late-inserted IDREF targets, and\n // `id` renames in the host's resolved root.\n this._ariaMirror = installAriaIdrefMirror(this, () => {\n this._syncHostAriaSemantics();\n });\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n this.removeEventListener('keydown', this._handleHostKeyDown);\n this.removeEventListener('click', this._handleHostClick);\n this._ariaMirror?.disconnect();\n this._ariaMirror = null;\n }\n\n /**\n * Host-level keydown handler. Space toggles per ARIA APG checkbox pattern\n * — but only on the modern path where the host is the announced focus\n * surface. On the no-IDL-ref fallback (round-2 finding #2), the inner\n * `<input>` owns focus + native Space activation, so the host stays out\n * of the activation pipeline to avoid double-toggle.\n * @internal\n */\n private _handleHostKeyDown = (e: KeyboardEvent): void => {\n if (this.disabled) return;\n if (!this._supportsIdrefRefs) return;\n // Only handle when the host itself is the focus target — events from\n // slotted/nested controls bubble through here too.\n if (e.target !== this) return;\n if (e.key === ' ') {\n e.preventDefault();\n this._handleChange();\n }\n };\n\n /**\n * Host-level click handler. Routes clicks on the host (e.g. via assistive\n * tech activation) to the change handler — only on the modern path. On the\n * fallback path the inner input is the announced surface and natively\n * receives clicks/AT activation.\n * @internal\n */\n private _handleHostClick = (e: MouseEvent): void => {\n if (this.disabled) return;\n if (!this._supportsIdrefRefs) return;\n // Only respond to clicks that originated on the host itself. Bubbled\n // events from inner shadow elements (which toggle through the existing\n // label/input change handler) are skipped to avoid double-activation.\n const path = e.composedPath();\n if (path[0] !== this) return;\n this._handleChange();\n };\n\n override updated(changedProperties: PropertyValues<this>): void {\n super.updated(changedProperties);\n if (\n changedProperties.has('checked') ||\n changedProperties.has('value') ||\n changedProperties.has('name')\n ) {\n this._updateFormValue();\n }\n\n // Codex round-1 finding #1: keep host focusability in sync with disabled\n // state. Disabled custom elements should not be in tab order.\n // Codex round-2 finding #2: on no-IDL-ref browsers the host is demoted\n // to `tabindex=-1` so the inner input remains the announced surface.\n // Codex round-14 P2: only re-assert when the component owns tabindex.\n // Consumer-managed values (e.g. roving-tabindex toolbar with `-1`) must\n // not be overwritten on disabled flips or supports-flag transitions.\n if (\n changedProperties.has('disabled') ||\n (changedProperties as Map<PropertyKey, unknown>).has('_supportsIdrefRefs')\n ) {\n if (this._internalTabindexManaged) {\n if (this.disabled) {\n this.setAttribute('tabindex', '-1');\n } else {\n this.setAttribute('tabindex', this._supportsIdrefRefs ? '0' : '-1');\n }\n }\n }\n\n // Re-resolve element references against the (possibly mutated) shadow\n // tree. `_syncHostAriaSemantics()` is also invoked from `_updateValidity()`\n // and by the IDREF mirror observer, so this keeps property-driven changes\n // current without depending on observer scheduling.\n this._syncHostAriaSemantics();\n // Warn when accessible-label is set alongside a visible label — they are mutually exclusive.\n // Checked unconditionally (not gated on changedProperties) because aria-label is supplied\n // via data-aria-label by mixinDelegatesAria and never appears in changedProperties.\n {\n const hasAccessibleLabel = !!(\n this.accessibleLabel?.trim() ||\n this.getAttribute('data-aria-label')?.trim() ||\n this.getAttribute('aria-label')?.trim()\n );\n const hasVisibleLabel =\n !!this.label ||\n (this.shadowRoot\n ?.querySelector<HTMLSlotElement>('.checkbox__label slot')\n ?.assignedNodes({ flatten: true }).length ?? 0) > 0;\n if (hasAccessibleLabel && hasVisibleLabel && !this._hasWarnedLabelConflict) {\n this._hasWarnedLabelConflict = true;\n devWarn(\n 'hx-checkbox',\n 'accessible-label is set alongside a visible label. Use either accessible-label or the label slot, not both.',\n );\n } else if (!hasAccessibleLabel || !hasVisibleLabel) {\n this._hasWarnedLabelConflict = false;\n }\n }\n // WCAG 4.1.3: Keep _announcedError in sync with the error property.\n // When error changes from one non-empty value to another, clear the live region\n // first then re-inject after a rAF tick so screen readers re-announce the updated\n // message (clearing content before the region is re-populated triggers a new event).\n // When transitioning from empty to non-empty (initial display), set directly so\n // the text is immediately available for synchronous DOM assertions.\n if (changedProperties.has('error')) {\n const previousError = changedProperties.get('error') as string;\n if (previousError && this.error) {\n // Changing from one error message to another: defer to trigger re-announcement.\n this._announcedError = '';\n requestAnimationFrame(() => {\n this._announcedError = this.error;\n });\n } else {\n // Transitioning from empty→error or error→empty: set directly.\n this._announcedError = this.error;\n }\n }\n }\n\n // ─── Form Integration ───\n\n /** Returns the associated form element, if any. */\n override get form(): HTMLFormElement | null {\n return this._internals.form;\n }\n\n /** Returns the validation message. */\n override get validationMessage(): string {\n return this._internals.validationMessage;\n }\n\n /** Returns the ValidityState object. */\n override get validity(): ValidityState {\n return this._internals.validity;\n }\n\n /** @internal */\n _updateValidity(): void {\n if (this.required && !this.checked) {\n // Codex round-17 P2: anchor validity UI to the announced surface. On\n // the modern path the host is the canonical announced/focus surface\n // (the inner input is `aria-hidden + tabindex=-1`), so reportValidity()\n // would otherwise focus a hidden node. On the fallback path the inner\n // input is the announced surface.\n const anchor: HTMLElement | undefined = this._supportsIdrefRefs\n ? this\n : (this._inputEl ?? undefined);\n this._internals.setValidity(\n { valueMissing: true },\n this.error || this.requiredMessage,\n anchor,\n );\n } else {\n this._internals.setValidity({});\n }\n // Sync host ARIA semantics immediately after every setValidity() call so\n // `internals.ariaInvalid` reflects the current `ValidityState` rather than\n // the previous render cycle's snapshot. Codex round-1 finding #6.\n this._syncHostAriaSemantics();\n }\n\n // ─── Form Lifecycle Hooks ───\n\n protected override _onFormReset(): void {\n this.checked = false;\n this.indeterminate = false;\n this._internals.setFormValue(null);\n this._resetInteractionState();\n }\n\n protected override _onFormStateRestore(\n state: File | string | FormData | null,\n _mode: 'restore' | 'autocomplete',\n ): void {\n this.checked = typeof state === 'string' && state === this.value;\n }\n\n protected override _onFormDisabled(disabled: boolean): void {\n this.disabled = disabled;\n }\n\n // ─── Event Handling ───\n\n /**\n * Writes the checkbox value to ElementInternals' form value. Suppressed when\n * the checkbox is grouped — `hx-checkbox-group` flips `_groupedSuppress` on\n * children so the group is the sole form participant.\n *\n * Codex round-3 finding #1: round-2 used `cb.name = ''` as the suppression\n * signal, but a consumer (or framework binding) that re-set `cb.name = 'foo'`\n * after attach regained form participation through the `name` setter. The\n * `_groupedSuppress` flag is a durable, name-independent kill switch.\n * Stand-alone checkboxes (no parent group) are unaffected.\n * @internal\n */\n private _updateFormValue(): void {\n if (this.__groupedSuppress || !this.name) {\n this._internals.setFormValue(null);\n return;\n }\n this._internals.setFormValue(this.checked ? this.value : null);\n }\n\n /** @internal */\n private _handleChange(): void {\n if (this.disabled) return;\n\n this.indeterminate = false;\n this.checked = !this.checked;\n\n this._updateFormValue();\n this._handleInteractionInput();\n\n /**\n * Dispatched when the checkbox is toggled.\n * @event hx-change\n */\n this.dispatchEvent(\n new CustomEvent<{ checked: boolean; value: string }>('hx-change', {\n bubbles: true,\n composed: true,\n detail: { checked: this.checked, value: this.value },\n }),\n );\n\n // Codex round-12 P2 (parity with hx-switch / hx-toggle-button): on the\n // modern path the host owns role=\"checkbox\" and tabindex=0; the inner\n // `<input>` is aria-hidden and tabindex=-1. Clicking the surrounding\n // `<label>` still routes activation to the input via native label-forward,\n // which focuses the input. Move focus to the host so the announced\n // surface is also the focus target.\n if (this._supportsIdrefRefs) {\n this.focus();\n }\n }\n\n /**\n * Handles native `change` events from the inner `<input type=checkbox>` on\n * the no-IDL-ref fallback path. On that path the inner input is the\n * announced surface (no `aria-hidden`, `tabindex=0`) and AT activates it\n * directly — pointer/keyboard activation flips `input.checked` natively.\n * We mirror the input's state onto the host, dispatch `hx-change`, and\n * update form participation.\n *\n * Codex round-3 finding #2: round-2 left the inner input click suppressed\n * on both paths, so on no-IDL-ref browsers AT activation could not toggle\n * the control. The fix is to NOT suppress click on the fallback path and\n * to honor the resulting `change` event here.\n * @internal\n */\n private _handleInternalChange = (e: Event): void => {\n e.stopPropagation();\n if (this.disabled) return;\n const input = e.currentTarget as HTMLInputElement;\n // The native input flipped its own state; mirror onto the host. Avoid\n // re-toggling — `_handleChange()` toggles `this.checked = !this.checked`,\n // which would invert the user's actual choice.\n this.indeterminate = false;\n this.checked = input.checked;\n\n this._updateFormValue();\n this._handleInteractionInput();\n\n this.dispatchEvent(\n new CustomEvent<{ checked: boolean; value: string }>('hx-change', {\n bubbles: true,\n composed: true,\n detail: { checked: this.checked, value: this.value },\n }),\n );\n };\n\n /** @internal */\n private _handleKeyDown(e: KeyboardEvent): void {\n if (e.key === ' ') {\n e.preventDefault();\n e.stopPropagation();\n this._handleChange();\n }\n }\n\n /**\n * Stable inner-input click suppressor for the modern (announced-host) path.\n * Hoisted to a class field so Lit sees a stable listener identity across\n * renders; previously inline arrows were re-allocated each render and\n * caused listener detach/re-attach churn (codex round-4 F3 — performance).\n * @internal\n */\n private _suppressInnerClick = (e: Event): void => {\n e.preventDefault();\n e.stopPropagation();\n };\n\n /**\n * Stable inner-input change suppressor for the modern (announced-host) path.\n * Mirrors the click suppressor above — stable identity across renders so\n * Lit's event-listener cache keeps a single registration (codex round-4 F3).\n * @internal\n */\n private _suppressInnerChange = (e: Event): void => {\n e.stopPropagation();\n };\n\n // ─── Public Methods ───\n\n /**\n * Moves focus to the announced checkbox surface. Codex round-1 finding #1\n * relocated the focus target from the inner `<input>` to the host on\n * modern engines so AT only sees one announced widget. Round-7 finding #3\n * extends that contract to the no-IDL-ref fallback: when the host is\n * demoted (`tabindex=-1`, role/state cleared on `internals`) the inner\n * `<input>` owns the announced semantics and tab order, so programmatic\n * `focus()` must redirect there — otherwise scripted focus and error\n * recovery land on the demoted host on unsupported engines.\n */\n override focus(options?: FocusOptions): void {\n if (this._supportsIdrefRefs) {\n super.focus(options);\n return;\n }\n this._inputEl?.focus(options);\n }\n\n // ─── Host ARIA Semantics (ElementInternals) ───\n\n /**\n * Mirrors checkbox semantics onto the host via ElementInternals so that\n * consumer-supplied `aria-label`, `aria-labelledby`, and `aria-describedby`\n * on `<hx-checkbox>` reach the announced control. Without this, those\n * attributes — intercepted by `mixinDelegatesAria` and stored on the host —\n * would not propagate through to the inner shadow `<input>`.\n *\n * Codex finding (aria-delegation, severity high): the announced semantic\n * node was the inner `<input>` and the host's labelled-by tokens could not\n * cross the shadow boundary.\n * @internal\n */\n private _syncHostAriaSemantics(): void {\n const internals = this._internals;\n const hostLabel = this._effectiveLabel;\n\n // Codex round-2 finding #2: branch on platform support for IDL element\n // references. On modern browsers the host is the canonical announced\n // surface and carries all checkbox semantics via ElementInternals. On\n // older browsers the inner `<input>` is the announced surface, so the\n // host's role/state are cleared and the consumer-supplied IDREFs are\n // mirrored to the inner input via render-time fallback state.\n if (this._supportsIdrefRefs) {\n // ─── Modern path: host is the announced surface ───\n internals.role = 'checkbox';\n internals.ariaChecked = this.indeterminate ? 'mixed' : this.checked ? 'true' : 'false';\n internals.ariaRequired = this.required ? 'true' : 'false';\n // Drive aria-invalid from validity state, not from visible error content.\n // A required-but-unchecked checkbox sets `valueMissing` via setValidity()\n // but may render no visible error yet — assistive tech still needs to hear\n // the invalid state.\n internals.ariaInvalid = !internals.validity.valid ? 'true' : 'false';\n internals.ariaDisabled = this.disabled ? 'true' : 'false';\n internals.ariaLabel = hostLabel || null;\n\n type InternalsWithRefs = ElementInternals & {\n ariaLabelledByElements: Element[] | null;\n ariaDescribedByElements: Element[] | null;\n };\n const refsInternals = internals as InternalsWithRefs;\n\n const externalLabelTokens = this.getAttribute('data-aria-labelledby');\n const externalDescTokens = this.getAttribute('data-aria-describedby');\n\n const labelEls = resolveIdrefTokens(this, externalLabelTokens);\n // Append the internal label element when the visible label has content\n // and no external labelling source already names the host.\n const internalLabel = this.shadowRoot?.getElementById(this._labelId);\n const hasVisibleLabel = !!this.label || this._hasLabelSlot;\n if (labelEls.length === 0 && !hostLabel && hasVisibleLabel && internalLabel) {\n labelEls.push(internalLabel);\n }\n refsInternals.ariaLabelledByElements = labelEls.length > 0 ? labelEls : null;\n\n const descEls = resolveIdrefTokens(this, externalDescTokens);\n // Codex round-13 P2: while an error is active, drop help text from the\n // described-by chain. The visible help node is suppressed in the render\n // tree, but referenced descriptions are announced even when their nodes\n // are hidden — leaving help in the chain would have AT read stale\n // guidance before the validation error. Otherwise help precedes error so\n // guidance reads before validation feedback when only one is shown.\n const helpEl = this.shadowRoot?.getElementById(this._helpTextId);\n const errorEl = this.shadowRoot?.getElementById(this._errorId);\n const hasError = !!(this.error || this._hasErrorSlot);\n if (helpEl && (this.helpText || this._hasHelpTextSlot) && !hasError) {\n descEls.push(helpEl);\n }\n if (errorEl && hasError) {\n descEls.push(errorEl);\n }\n refsInternals.ariaDescribedByElements = descEls.length > 0 ? descEls : null;\n // Clear fallbacks — IDL refs path is the canonical surface.\n this._fallbackAriaLabelledBy = null;\n this._fallbackAriaDescribedBy = null;\n } else {\n // ─── Fallback path: inner <input> is the announced surface ───\n // Codex round-2 finding #2: in round-1 we set host role/state via\n // ElementInternals AND mirrored aria-labelledby/describedby onto the\n // inner input. But the inner input was kept `aria-hidden`, making the\n // mirrored attributes inert — the control had no accessible name on\n // older browsers. The fix is to demote the host (clear its role/state\n // on internals so AT does not double-announce) and let the inner native\n // `<input type=checkbox>` be the announced surface, with consumer\n // IDREFs mirrored as real `aria-*` attributes that resolve through the\n // shadow root for shadow-internal IDs (cross-boundary IDREFs remain\n // unreachable on these engines — same baseline as the pre-fix code).\n internals.role = null;\n internals.ariaChecked = null;\n internals.ariaRequired = null;\n internals.ariaInvalid = null;\n internals.ariaDisabled = null;\n internals.ariaLabel = null;\n\n const externalLabelTokens = this.getAttribute('data-aria-labelledby');\n const externalDescTokens = this.getAttribute('data-aria-describedby');\n this._fallbackAriaLabelledBy = externalLabelTokens || null;\n this._fallbackAriaDescribedBy = externalDescTokens || null;\n }\n }\n\n /**\n * Fallback `aria-labelledby` token list applied to the inner input on\n * browsers that lack IDL element references. Tracked as a reactive state\n * so the value flows through the next `render()` call.\n * @internal\n */\n @state() private _fallbackAriaLabelledBy: string | null = null;\n\n /**\n * Fallback `aria-describedby` token list applied to the inner input on\n * browsers that lack IDL element references.\n * @internal\n */\n @state() private _fallbackAriaDescribedBy: string | null = null;\n\n /**\n * Whether the platform supports IDL element references on `ElementInternals`.\n * Drives the render-time branch between the modern path (host is the\n * announced surface, inner input is `aria-hidden + tabindex=-1`) and the\n * fallback path (inner input is the announced surface, host is demoted).\n *\n * Round-2 finding #2: the previous fallback mirrored `aria-labelledby` /\n * `aria-describedby` onto an `aria-hidden` inner input, leaving older\n * browsers with no accessible name. The fallback now keeps the inner input\n * in the a11y tree so AT can name and activate it natively.\n * @internal\n */\n @state() private _supportsIdrefRefs = true;\n\n /**\n * Tracks whether the host's `tabindex` is managed by the component itself\n * (vs. set explicitly by a consumer). Codex round-14 P2: a consumer-supplied\n * `tabindex` (e.g. roving-tabindex toolbar pattern with `tabindex=\"-1\"`)\n * must survive disabled flips and re-renders. Only re-assert tabindex in\n * `updated()` when the component originally claimed it.\n * @internal\n */\n private _internalTabindexManaged = false;\n\n // ─── Render ───\n\n // P2-05: monotonic counter — collision-free and deterministic\n /** @internal */\n private _id = _nextCheckboxId();\n /** @internal */\n private _helpTextId = `${this._id}-help`;\n /** @internal */\n private _errorId = `${this._id}-error`;\n /** @internal */\n private _labelId = `${this._id}-label`;\n\n override render() {\n const hasError = !!this.error || this._hasErrorSlot;\n const hasHelpText = !!this.helpText || this._hasHelpTextSlot;\n const hasVisibleLabel = !!this.label || this._hasLabelSlot;\n // Drive aria-invalid from the same validity source used by setValidity()\n // so a required-unchecked checkbox is announced as invalid even before any\n // visible error content has rendered.\n const isInvalid = hasError || (this.required && !this.checked);\n\n const containerClasses = {\n checkbox: true,\n 'checkbox--checked': this.checked,\n 'checkbox--indeterminate': this.indeterminate,\n 'checkbox--error': hasError,\n 'checkbox--disabled': this.disabled,\n 'checkbox--required': this.required,\n 'checkbox--sm': this.size === 'sm',\n 'checkbox--md': this.size === 'md',\n 'checkbox--lg': this.size === 'lg',\n };\n\n // describedBy chain: while an error is active, the visible help text is\n // suppressed in the rendered tree, so we must also drop it from the\n // described-by chain — referenced descriptions are announced even when\n // their nodes are hidden, and announcing stale guidance before the\n // validation error confuses screen-reader users (codex round-13 P2).\n // Otherwise help-text precedes error in the chain so guidance is read\n // before validation feedback when only one is shown.\n const describedBy =\n [hasError ? null : hasHelpText ? this._helpTextId : null, hasError ? this._errorId : null]\n .filter(Boolean)\n .join(' ') || undefined;\n\n const hostAriaLabel = this._effectiveLabel || undefined;\n // Only point the inner input at `_labelId` when there is actual visible\n // label content; otherwise the input would reference an empty container.\n const useInternalLabelId = !hostAriaLabel && hasVisibleLabel;\n\n // Codex round-1 finding #7: on no-IDL-ref browsers, mirror consumer\n // tokens (stored as `data-aria-*`) onto the inner input so cross-shadow\n // labelling still resolves for shadow-internal IDs. The render fallbacks\n // are tracked as reactive state from `_syncHostAriaSemantics()`.\n const fallbackLabelledBy = this._fallbackAriaLabelledBy;\n const fallbackDescribedBy = this._fallbackAriaDescribedBy;\n\n // Merge internal describedBy chain with consumer fallback tokens.\n const innerDescribedBy =\n [describedBy ?? null, fallbackDescribedBy].filter(Boolean).join(' ') || undefined;\n // For labelledby, prefer consumer fallback tokens; otherwise keep the\n // internal label association.\n const innerLabelledBy = fallbackLabelledBy ?? (useInternalLabelId ? this._labelId : undefined);\n\n // Codex round-2 finding #2: branch the inner input on platform support.\n // Modern path — host is announced, inner input is `aria-hidden + tabindex=-1`.\n // Fallback path — inner input is announced (NO aria-hidden, tabindex=0)\n // so consumer-mirrored aria-labelledby/describedby actually resolve to a\n // visible accessibility-tree node. The inner input keeps its own click\n // suppressor because the visible activation surface is the surrounding\n // `<label>`; the input's native click activation is wired through that.\n const innerIsAnnounced = !this._supportsIdrefRefs;\n const innerTabIndex = innerIsAnnounced && !this.disabled ? '0' : '-1';\n\n // Codex round-3 finding #2: branch the inner input event model on\n // platform support.\n //\n // Modern path (`innerIsAnnounced === false`): the inner input is\n // `aria-hidden + tabindex=-1` — AT cannot reach it. Pointer clicks on the\n // inner input bubble through the surrounding `<label>` whose `@click`\n // handler runs `_handleChange()`. The inner click handler suppresses the\n // native click so the label's click is the sole activation pipeline,\n // avoiding double-toggle. Native `change` is also swallowed.\n //\n // Fallback path (`innerIsAnnounced === true`): the inner input IS the\n // announced surface (no `aria-hidden`, `tabindex=0`). AT activation lands\n // directly on the input and must produce a real toggle. We do NOT\n // suppress click; instead we wire `@change=${_handleInternalChange}` so\n // the host mirrors the input's state, fires `hx-change`, and updates\n // form participation. The label's `@click` is a no-op on this path —\n // pointer clicks on the label bubble to the input which toggles natively.\n // Codex round-4 F3 (performance): handlers are class-field arrows with\n // stable identity, so Lit's event-listener cache keeps a single\n // registration across re-renders instead of detach/re-attach churn.\n const innerClickHandler = innerIsAnnounced ? undefined : this._suppressInnerClick;\n const innerChangeHandler = innerIsAnnounced\n ? this._handleInternalChange\n : this._suppressInnerChange;\n const labelClickHandler = innerIsAnnounced ? undefined : this._handleChange;\n // On the fallback path the native input owns Space/Enter activation; its\n // native `change` event flows through `_handleInternalChange`. Wiring the\n // host-side `_handleKeyDown` here would double-toggle (native flips +\n // _handleChange flips again). On the modern path the input is `aria-hidden\n // + tabindex=-1` so this handler is defensive only.\n const innerKeyDownHandler = innerIsAnnounced ? undefined : this._handleKeyDown;\n\n return html`\n <div class=${classMap(containerClasses)}>\n <label part=\"control\" class=\"checkbox__control\" @click=${ifDefined(labelClickHandler)}>\n <input\n class=\"checkbox__input\"\n type=\"checkbox\"\n id=${this._id}\n tabindex=${innerTabIndex}\n .checked=${live(this.checked)}\n .indeterminate=${live(this.indeterminate)}\n ?disabled=${this.disabled}\n ?required=${this.required}\n name=${ifDefined(this.name || undefined)}\n .value=${this.value}\n aria-checked=${this.indeterminate ? 'mixed' : nothing}\n aria-invalid=${isInvalid ? 'true' : nothing}\n aria-describedby=${ifDefined(innerDescribedBy)}\n aria-label=${ifDefined(hostAriaLabel)}\n aria-labelledby=${ifDefined(innerLabelledBy)}\n aria-hidden=${innerIsAnnounced ? nothing : 'true'}\n @keydown=${ifDefined(innerKeyDownHandler)}\n @click=${ifDefined(innerClickHandler)}\n @change=${innerChangeHandler}\n />\n\n <span part=\"checkbox\" class=\"checkbox__box\">\n <svg\n part=\"checkmark\"\n class=\"checkbox__icon checkbox__icon--check\"\n viewBox=\"0 0 16 16\"\n aria-hidden=\"true\"\n >\n <polyline points=\"3.5 8 6.5 11 12.5 5\"></polyline>\n </svg>\n <svg\n class=\"checkbox__icon checkbox__icon--indeterminate\"\n viewBox=\"0 0 16 16\"\n aria-hidden=\"true\"\n >\n <line x1=\"4\" y1=\"8\" x2=\"12\" y2=\"8\"></line>\n </svg>\n </span>\n\n <span part=\"label\" class=\"checkbox__label\" id=${this._labelId}>\n <slot @slotchange=${this._handleLabelSlotChange}>${this.label}</slot>\n ${this.required\n ? html`<span class=\"checkbox__required-marker\" aria-hidden=\"true\">*</span>`\n : nothing}\n </span>\n </label>\n\n <!--\n P0-01: wrapper div always owns _errorId so aria-describedby works\n regardless of whether error content comes from the .error property\n or the named slot. role=\"status\" replaces aria-live=\"polite\" to\n avoid conflicting live-region semantics.\n -->\n <div\n part=\"error\"\n class=\"checkbox__error\"\n id=${this._errorId}\n role=\"status\"\n ?hidden=${!hasError}\n >\n <slot name=\"error\" @slotchange=${this._handleErrorSlotChange}>\n ${this._announcedError}\n </slot>\n </div>\n\n <!--\n Persistent help-text container. Rendered whenever the property OR\n the slot has content, hidden when an error is present so guidance\n does not compete with validation feedback. Always present in the\n shadow tree so the host's aria-describedby chain remains stable.\n -->\n <div\n part=\"help-text\"\n class=\"checkbox__help-text\"\n id=${this._helpTextId}\n ?hidden=${!hasHelpText || hasError}\n >\n <slot name=\"help-text\" @slotchange=${this._handleHelpTextSlotChange}\n >${this.helpText}</slot\n >\n </div>\n </div>\n `;\n }\n}\n\n/** Canonical type alias for the hx-checkbox component. */\nexport type HxCheckbox = HelixCheckbox;\n\n/**\n * Per-component event map for type-safe addEventListener on hx-checkbox.\n * The `hx-change` detail always includes both `checked` and `value` for this component.\n */\nexport interface HxCheckboxEventMap {\n 'hx-change': CustomEvent<{ checked: boolean; value: string }>;\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'hx-checkbox': HelixCheckbox;\n }\n /**\n * Global hx-change event type. The detail shape is a union because hx-change is dispatched\n * by multiple components: form-field components (value only) and toggle components\n * (checked + value). Use per-component EventMap types (e.g. HxCheckboxEventMap) for\n * narrowed addEventListener calls.\n */\n interface HTMLElementEventMap {\n 'hx-change': CustomEvent<{ value: string } | { checked: boolean; value: string }>;\n }\n}\n"],"names":["helixCheckboxStyles","css","_nextCheckboxId","createIdCounter","HelixCheckbox","mixinDelegatesAria","FormMixin","HelixElement","input","_a","_b","_c","value","slot","supportsIdrefElementReferences","enabledTabIndex","installAriaIdrefMirror","changedProperties","hasAccessibleLabel","hasVisibleLabel","_e","_d","anchor","state","_mode","disabled","options","internals","hostLabel","refsInternals","externalLabelTokens","externalDescTokens","labelEls","resolveIdrefTokens","internalLabel","descEls","helpEl","errorEl","hasError","hasHelpText","isInvalid","containerClasses","describedBy","hostAriaLabel","useInternalLabelId","fallbackLabelledBy","fallbackDescribedBy","innerDescribedBy","innerLabelledBy","innerIsAnnounced","innerTabIndex","innerClickHandler","innerChangeHandler","labelClickHandler","innerKeyDownHandler","html","classMap","ifDefined","live","nothing","forcedColorsField","__decorateClass","property","query","customElement"],"mappings":";;;;;;;;;;;AAEO,MAAMA,IAAsBC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;A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"}
@@ -1,12 +1,12 @@
1
- import { css as N, nothing as R, html as H } from "lit";
2
- import { property as a, state as u, customElement as q } from "lit/decorators.js";
1
+ import { css as $, nothing as N, html as H } from "lit";
2
+ import { property as h, state as u, customElement as q } from "lit/decorators.js";
3
3
  import { classMap as M } from "lit/directives/class-map.js";
4
- import { F as W } from "./FormMixin-B8PXk5RQ.js";
5
- import { b as z } from "./forced-colors-CTEDFRGa.js";
6
- import { s as j, i as G, r as w } from "./aria-idref-DCuEaknC.js";
7
- import { H as P } from "./helix-element-BNEYeiys.js";
8
- import { c as U } from "./id-counter-DuX8vsui.js";
9
- const X = N`
4
+ import { F as z } from "./FormMixin-B8PXk5RQ.js";
5
+ import { b as W } from "./forced-colors-CTEDFRGa.js";
6
+ import { s as j, i as K, r as O } from "./aria-idref-DCuEaknC.js";
7
+ import { H as G } from "./helix-element-BNEYeiys.js";
8
+ import { c as P } from "./id-counter-DuX8vsui.js";
9
+ const U = $`
10
10
  :host {
11
11
  display: block;
12
12
  }
@@ -16,6 +16,17 @@ const X = N`
16
16
  cursor: not-allowed;
17
17
  }
18
18
 
19
+ /*
20
+ * AAA 2.4.13 Focus Appearance — host-level focus ring (group is focusable
21
+ * via roving tabindex in Tier-2). Token-driven: --hx-focus-ring-width
22
+ * resolves to ≥2px.
23
+ */
24
+ :host(:focus-visible) {
25
+ outline: var(--hx-focus-ring-width, 2px) solid
26
+ var(--hx-checkbox-group-focus-ring-color, var(--hx-focus-ring-color, #0f7078));
27
+ outline-offset: var(--hx-focus-ring-offset, 2px);
28
+ }
29
+
19
30
  * {
20
31
  box-sizing: border-box;
21
32
  }
@@ -116,13 +127,13 @@ const X = N`
116
127
  }
117
128
  }
118
129
  `;
119
- var K = Object.defineProperty, J = Object.getOwnPropertyDescriptor, l = (e, t, s, r) => {
120
- for (var i = r > 1 ? void 0 : r ? J(t, s) : t, c = e.length - 1, n; c >= 0; c--)
121
- (n = e[c]) && (i = (r ? n(t, s, i) : n(i)) || i);
122
- return r && i && K(t, s, i), i;
130
+ var X = Object.defineProperty, J = Object.getOwnPropertyDescriptor, a = (e, t, s, r) => {
131
+ for (var i = r > 1 ? void 0 : r ? J(t, s) : t, n = e.length - 1, l; n >= 0; n--)
132
+ (l = e[n]) && (i = (r ? l(t, s, i) : l(i)) || i);
133
+ return r && i && X(t, s, i), i;
123
134
  };
124
- const Q = U("hx-checkbox-group");
125
- function A(e) {
135
+ const Q = P("hx-checkbox-group");
136
+ function B(e) {
126
137
  const t = e.querySelector("slot");
127
138
  if (t) {
128
139
  const s = t.assignedNodes({ flatten: !0 });
@@ -131,9 +142,23 @@ function A(e) {
131
142
  }
132
143
  return (e.textContent ?? "").trim();
133
144
  }
134
- let o = class extends W(P) {
145
+ let o = class extends z(G) {
135
146
  constructor() {
136
- super(...arguments), this.name = "", this.label = "", this.required = !1, this.disabled = !1, this.error = "", this.helpText = "", this._orientation = "vertical", this._hasErrorSlot = !1, this._hasHelpSlot = !1, this._hasLabelSlot = !1, this._supportsIdrefRefs = !0, this._groupId = Q(), this._helpTextId = `${this._groupId}-help`, this._errorId = `${this._groupId}-error`, this._labelId = `${this._groupId}-label`, this._labelSlotTextObserver = null, this._helpSlotTextObserver = null, this._errorSlotTextObserver = null, this._ariaMirror = null, this._announcedError = "", this._lastWrittenLabelledBy = null, this._lastWrittenDescribedBy = null, this._consumerLabelledBy = null, this._consumerDescribedBy = null, this._suppressedChildren = /* @__PURE__ */ new WeakSet(), this._previousChildren = [], this._handleCheckboxChange = (e) => {
147
+ super(...arguments), this.name = "", this.label = "", this.required = !1, this.disabled = !1, this.error = "", this.helpText = "", this._orientation = "vertical", this._hasErrorSlot = !1, this._hasHelpSlot = !1, this._hasLabelSlot = !1, this._supportsIdrefRefs = !0, this._groupId = Q(), this._helpTextId = `${this._groupId}-help`, this._errorId = `${this._groupId}-error`, this._labelId = `${this._groupId}-label`, this._labelSlotTextObserver = null, this._helpSlotTextObserver = null, this._errorSlotTextObserver = null, this._ariaMirror = null, this._announcedError = "", this._lastWrittenLabelledBy = null, this._lastWrittenDescribedBy = null, this._consumerLabelledBy = null, this._consumerDescribedBy = null, this._handleHostKeydown = (e) => {
148
+ var i, n;
149
+ const t = this.orientation !== "horizontal", s = t ? "ArrowDown" : "ArrowRight", r = t ? "ArrowUp" : "ArrowLeft";
150
+ if (e.key === s)
151
+ e.preventDefault(), this._moveCheckboxFocus("next");
152
+ else if (e.key === r)
153
+ e.preventDefault(), this._moveCheckboxFocus("prev");
154
+ else if (e.key === "Home")
155
+ e.preventDefault(), (i = this._getEnabledCheckboxes()[0]) == null || i.focus();
156
+ else if (e.key === "End") {
157
+ e.preventDefault();
158
+ const l = this._getEnabledCheckboxes();
159
+ (n = l[l.length - 1]) == null || n.focus();
160
+ }
161
+ }, this._suppressedChildren = /* @__PURE__ */ new WeakSet(), this._previousChildren = [], this._handleCheckboxChange = (e) => {
137
162
  if (e.target === this) return;
138
163
  e.stopImmediatePropagation();
139
164
  const t = this._getCheckedValues();
@@ -235,15 +260,33 @@ let o = class extends W(P) {
235
260
  });
236
261
  }), this._errorSlotTextObserver = t;
237
262
  }
238
- // ─── Lifecycle ───
263
+ /** @internal */
264
+ _getEnabledCheckboxes() {
265
+ return this._getCheckboxes().filter((e) => {
266
+ const t = e;
267
+ return !t.disabled && !t.hasAttribute("disabled");
268
+ });
269
+ }
270
+ /** @internal */
271
+ _moveCheckboxFocus(e) {
272
+ var l;
273
+ const t = this._getEnabledCheckboxes();
274
+ if (!t.length) return;
275
+ let r = document.activeElement || null;
276
+ for (; r && r.shadowRoot && r.shadowRoot.activeElement; )
277
+ r = r.shadowRoot.activeElement;
278
+ const i = t.indexOf(r);
279
+ let n;
280
+ e === "next" ? n = i < t.length - 1 ? i + 1 : 0 : n = i > 0 ? i - 1 : t.length - 1, (l = t[n]) == null || l.focus();
281
+ }
239
282
  connectedCallback() {
240
- super.connectedCallback(), this._supportsIdrefRefs = j(this._internals), this.addEventListener("hx-change", this._handleCheckboxChange), this._syncHostAriaSemantics(), this._ariaMirror = G(this, () => {
283
+ super.connectedCallback(), this._supportsIdrefRefs = j(this._internals), this.addEventListener("hx-change", this._handleCheckboxChange), this.addEventListener("keydown", this._handleHostKeydown), this._syncHostAriaSemantics(), this._ariaMirror = K(this, () => {
241
284
  this._syncHostAriaSemantics();
242
285
  }), this._getCheckboxes().length > 0 && (this._syncCheckboxNames(), this._previousChildren = this._getCheckboxes());
243
286
  }
244
287
  disconnectedCallback() {
245
288
  var e, t, s, r;
246
- super.disconnectedCallback(), this.removeEventListener("hx-change", this._handleCheckboxChange), (e = this._ariaMirror) == null || e.disconnect(), this._ariaMirror = null, (t = this._labelSlotTextObserver) == null || t.disconnect(), this._labelSlotTextObserver = null, (s = this._helpSlotTextObserver) == null || s.disconnect(), this._helpSlotTextObserver = null, (r = this._errorSlotTextObserver) == null || r.disconnect(), this._errorSlotTextObserver = null, this._previousChildren.forEach((i) => {
289
+ super.disconnectedCallback(), this.removeEventListener("hx-change", this._handleCheckboxChange), this.removeEventListener("keydown", this._handleHostKeydown), (e = this._ariaMirror) == null || e.disconnect(), this._ariaMirror = null, (t = this._labelSlotTextObserver) == null || t.disconnect(), this._labelSlotTextObserver = null, (s = this._helpSlotTextObserver) == null || s.disconnect(), this._helpSlotTextObserver = null, (r = this._errorSlotTextObserver) == null || r.disconnect(), this._errorSlotTextObserver = null, this._previousChildren.forEach((i) => {
247
290
  this._suppressedChildren.has(i) && (i._groupedSuppress = !1, this._suppressedChildren.delete(i));
248
291
  }), this._previousChildren = [];
249
292
  }
@@ -261,28 +304,28 @@ let o = class extends W(P) {
261
304
  * @internal
262
305
  */
263
306
  _syncHostAriaSemantics() {
264
- var k, E, T, L, I;
307
+ var k, E, T, w, L;
265
308
  const e = this._internals;
266
309
  e.role = "group", e.ariaRequired = this.required ? "true" : "false", e.ariaInvalid = e.validity.valid ? "false" : "true", e.ariaDisabled = this.disabled ? "true" : "false";
267
- const t = ((k = this.getAttribute("aria-label")) == null ? void 0 : k.trim()) || "", s = (E = this.shadowRoot) == null ? void 0 : E.querySelector('slot[name="label"]'), r = ((s == null ? void 0 : s.assignedNodes().length) ?? 0) > 0, i = (s == null ? void 0 : s.assignedNodes().map((h) => h.textContent ?? "").join("").trim()) || "", c = r ? i || null : this.label || null, n = this.getAttribute("aria-labelledby");
268
- n !== this._lastWrittenLabelledBy && (this._consumerLabelledBy = n);
310
+ const t = ((k = this.getAttribute("aria-label")) == null ? void 0 : k.trim()) || "", s = (E = this.shadowRoot) == null ? void 0 : E.querySelector('slot[name="label"]'), r = ((s == null ? void 0 : s.assignedNodes().length) ?? 0) > 0, i = (s == null ? void 0 : s.assignedNodes().map((c) => c.textContent ?? "").join("").trim()) || "", n = r ? i || null : this.label || null, l = this.getAttribute("aria-labelledby");
311
+ l !== this._lastWrittenLabelledBy && (this._consumerLabelledBy = l);
269
312
  const y = this.getAttribute("aria-describedby");
270
313
  y !== this._lastWrittenDescribedBy && (this._consumerDescribedBy = y);
271
- const p = this._consumerLabelledBy, _ = this._consumerDescribedBy, d = w(this, p), S = d.length > 0;
272
- t ? e.ariaLabel = t : S ? e.ariaLabel = null : e.ariaLabel = c;
273
- const C = (T = this.shadowRoot) == null ? void 0 : T.getElementById(this._labelId);
274
- d.length === 0 && !t && (this.label || this._hasLabelSlot) && C && d.push(C);
275
- const b = w(this, _), f = (L = this.shadowRoot) == null ? void 0 : L.getElementById(this._helpTextId), x = (I = this.shadowRoot) == null ? void 0 : I.getElementById(this._errorId), g = !!(this.error || this._hasErrorSlot);
314
+ const p = this._consumerLabelledBy, _ = this._consumerDescribedBy, d = O(this, p), C = d.length > 0;
315
+ t ? e.ariaLabel = t : C ? e.ariaLabel = null : e.ariaLabel = n;
316
+ const S = (T = this.shadowRoot) == null ? void 0 : T.getElementById(this._labelId);
317
+ d.length === 0 && !t && (this.label || this._hasLabelSlot) && S && d.push(S);
318
+ const b = O(this, _), f = (w = this.shadowRoot) == null ? void 0 : w.getElementById(this._helpTextId), x = (L = this.shadowRoot) == null ? void 0 : L.getElementById(this._errorId), g = !!(this.error || this._hasErrorSlot);
276
319
  if (f && !g && (this.helpText || this._hasHelpSlot) && b.push(f), x && g && b.push(x), this._supportsIdrefRefs) {
277
- const h = e;
278
- h.ariaLabelledByElements = d.length > 0 ? d : null, h.ariaDescribedByElements = b.length > 0 ? b : null, e.ariaDescription = null;
320
+ const c = e;
321
+ c.ariaLabelledByElements = d.length > 0 ? d : null, c.ariaDescribedByElements = b.length > 0 ? b : null, e.ariaDescription = null;
279
322
  } else {
280
- const h = new Set(((p == null ? void 0 : p.split(/\s+/)) ?? []).filter(Boolean)), D = new Set(((_ == null ? void 0 : _.split(/\s+/)) ?? []).filter(Boolean)), m = S ? [...h].filter(Boolean).join(" ") : "", O = this.getAttribute("aria-labelledby");
281
- m ? (O !== m && this.setAttribute("aria-labelledby", m), this._lastWrittenLabelledBy = m) : O !== null && (this.removeAttribute("aria-labelledby"), this._lastWrittenLabelledBy = null);
282
- const v = [...D].filter(Boolean).join(" ") || "", B = this.getAttribute("aria-describedby");
283
- v ? (B !== v && this.setAttribute("aria-describedby", v), this._lastWrittenDescribedBy = v) : B !== null && this._lastWrittenDescribedBy !== null && (this.removeAttribute("aria-describedby"), this._lastWrittenDescribedBy = null);
284
- const V = f && !g && (this.helpText || this._hasHelpSlot) ? A(f) : "", F = x && g ? A(x) : "", $ = [V, F].filter(Boolean).join(" ");
285
- e.ariaDescription = $ || null;
323
+ const c = new Set(((p == null ? void 0 : p.split(/\s+/)) ?? []).filter(Boolean)), D = new Set(((_ == null ? void 0 : _.split(/\s+/)) ?? []).filter(Boolean)), m = C ? [...c].filter(Boolean).join(" ") : "", A = this.getAttribute("aria-labelledby");
324
+ m ? (A !== m && this.setAttribute("aria-labelledby", m), this._lastWrittenLabelledBy = m) : A !== null && (this.removeAttribute("aria-labelledby"), this._lastWrittenLabelledBy = null);
325
+ const v = [...D].filter(Boolean).join(" ") || "", I = this.getAttribute("aria-describedby");
326
+ v ? (I !== v && this.setAttribute("aria-describedby", v), this._lastWrittenDescribedBy = v) : I !== null && this._lastWrittenDescribedBy !== null && (this.removeAttribute("aria-describedby"), this._lastWrittenDescribedBy = null);
327
+ const V = f && !g && (this.helpText || this._hasHelpSlot) ? B(f) : "", F = x && g ? B(x) : "", R = [V, F].filter(Boolean).join(" ");
328
+ e.ariaDescription = R || null;
286
329
  }
287
330
  }
288
331
  firstUpdated(e) {
@@ -408,7 +451,7 @@ let o = class extends W(P) {
408
451
  <fieldset part="group" class=${M(s)} role="presentation">
409
452
  <legend part="label" class="fieldset__legend" id=${this._labelId}>
410
453
  <slot name="label" @slotchange=${this._handleLabelSlotChange}>${this.label}</slot>
411
- ${this.required ? H`<span class="fieldset__required-marker" aria-hidden="true">*</span>` : R}
454
+ ${this.required ? H`<span class="fieldset__required-marker" aria-hidden="true">*</span>` : N}
412
455
  </legend>
413
456
 
414
457
  <div class="fieldset__items">
@@ -449,48 +492,48 @@ let o = class extends W(P) {
449
492
  `;
450
493
  }
451
494
  };
452
- o.styles = [X, z];
495
+ o.styles = [U, W];
453
496
  o.formAssociated = !0;
454
- l([
455
- a({ type: String, reflect: !0 })
497
+ a([
498
+ h({ type: String, reflect: !0 })
456
499
  ], o.prototype, "name", 2);
457
- l([
458
- a({ type: String })
500
+ a([
501
+ h({ type: String })
459
502
  ], o.prototype, "label", 2);
460
- l([
461
- a({ type: Boolean, reflect: !0 })
503
+ a([
504
+ h({ type: Boolean, reflect: !0 })
462
505
  ], o.prototype, "required", 2);
463
- l([
464
- a({ type: Boolean, reflect: !0 })
506
+ a([
507
+ h({ type: Boolean, reflect: !0 })
465
508
  ], o.prototype, "disabled", 2);
466
- l([
467
- a({ type: String })
509
+ a([
510
+ h({ type: String })
468
511
  ], o.prototype, "error", 2);
469
- l([
470
- a({ type: String, attribute: "help-text" })
512
+ a([
513
+ h({ type: String, attribute: "help-text" })
471
514
  ], o.prototype, "helpText", 2);
472
- l([
473
- a({ type: String, reflect: !0 })
515
+ a([
516
+ h({ type: String, reflect: !0 })
474
517
  ], o.prototype, "orientation", 1);
475
- l([
518
+ a([
476
519
  u()
477
520
  ], o.prototype, "_hasErrorSlot", 2);
478
- l([
521
+ a([
479
522
  u()
480
523
  ], o.prototype, "_hasHelpSlot", 2);
481
- l([
524
+ a([
482
525
  u()
483
526
  ], o.prototype, "_hasLabelSlot", 2);
484
- l([
527
+ a([
485
528
  u()
486
529
  ], o.prototype, "_supportsIdrefRefs", 2);
487
- l([
530
+ a([
488
531
  u()
489
532
  ], o.prototype, "_announcedError", 2);
490
- o = l([
533
+ o = a([
491
534
  q("hx-checkbox-group")
492
535
  ], o);
493
536
  export {
494
537
  o as H
495
538
  };
496
- //# sourceMappingURL=hx-checkbox-group-D5piJLY8.js.map
539
+ //# sourceMappingURL=hx-checkbox-group-C0q6HDqn.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hx-checkbox-group-C0q6HDqn.js","sources":["../../src/components/hx-checkbox-group/hx-checkbox-group.styles.ts","../../src/components/hx-checkbox-group/hx-checkbox-group.ts"],"sourcesContent":["import { css } from 'lit';\n\nexport const helixCheckboxGroupStyles = css`\n :host {\n display: block;\n }\n\n :host([disabled]) {\n opacity: var(--hx-opacity-disabled);\n cursor: not-allowed;\n }\n\n /*\n * AAA 2.4.13 Focus Appearance — host-level focus ring (group is focusable\n * via roving tabindex in Tier-2). Token-driven: --hx-focus-ring-width\n * resolves to ≥2px.\n */\n :host(:focus-visible) {\n outline: var(--hx-focus-ring-width, 2px) solid\n var(--hx-checkbox-group-focus-ring-color, var(--hx-focus-ring-color, #0f7078));\n outline-offset: var(--hx-focus-ring-offset, 2px);\n }\n\n * {\n box-sizing: border-box;\n }\n\n /* ─── Fieldset ─── */\n\n .fieldset {\n border: none;\n margin: 0;\n padding: 0;\n display: flex;\n flex-direction: column;\n gap: var(--hx-space-2);\n font-family: var(--hx-checkbox-group-font-family, var(--hx-font-family-sans));\n }\n\n /* ─── Legend ─── */\n\n .fieldset__legend {\n display: flex;\n align-items: baseline;\n gap: var(--hx-space-1);\n font-size: var(--hx-font-size-sm);\n font-weight: var(--hx-font-weight-medium);\n color: var(--hx-checkbox-group-label-color, var(--hx-color-text-strong));\n line-height: var(--hx-line-height-normal);\n padding: 0;\n margin-bottom: var(--hx-space-1);\n }\n\n .fieldset__required-marker {\n color: var(--hx-checkbox-group-error-color, var(--hx-color-error-text, #c92a2a));\n font-weight: var(--hx-font-weight-bold);\n }\n\n /* ─── Items Container ─── */\n\n .fieldset__items {\n display: flex;\n flex-direction: column;\n gap: var(--hx-checkbox-group-gap, var(--hx-space-3));\n }\n\n :host([orientation='horizontal']) .fieldset__items {\n flex-direction: row;\n flex-wrap: wrap;\n }\n\n /* ─── Error State ─── */\n\n .fieldset--error .fieldset__legend {\n color: var(--hx-checkbox-group-error-color, var(--hx-color-error-text, #c92a2a));\n }\n\n /* ─── Help Text & Error Messages ─── */\n\n .fieldset__help-text {\n font-size: var(--hx-font-size-xs);\n color: var(--hx-checkbox-group-help-text-color, var(--hx-color-text-muted));\n line-height: var(--hx-line-height-normal);\n }\n\n .fieldset__error {\n font-size: var(--hx-font-size-xs);\n color: var(--hx-checkbox-group-error-color, var(--hx-color-error-text, #c92a2a));\n line-height: var(--hx-line-height-normal);\n }\n\n /* ─── High Contrast Mode (forced-colors) ─── */\n\n @media (forced-colors: active) {\n .fieldset {\n border: none;\n }\n\n .fieldset__legend {\n color: CanvasText;\n }\n\n .fieldset--error .fieldset__legend {\n color: LinkText;\n }\n\n :host([disabled]) {\n opacity: 1;\n }\n\n :host([disabled]) .fieldset__legend {\n color: GrayText;\n }\n\n .fieldset__help-text {\n color: GrayText;\n }\n\n .fieldset__error {\n color: LinkText;\n }\n }\n`;\n","import { html, nothing, type PropertyValues } from 'lit';\nimport '../../utilities/document-token-adoption.js';\nimport { customElement, property, state } from 'lit/decorators.js';\nimport { classMap } from 'lit/directives/class-map.js';\nimport { HelixElement, createIdCounter } from '../../base/index.js';\nimport { FormMixin } from '../../mixins/FormMixin.js';\nimport { helixCheckboxGroupStyles } from './hx-checkbox-group.styles.js';\nimport { forcedColorsField } from '../../styles/forced-colors.js';\nimport type { HelixCheckbox } from '../hx-checkbox/hx-checkbox.js';\nimport { devWarn } from '../../utils/dev-warn.js';\nimport {\n installAriaIdrefMirror,\n resolveIdrefTokens,\n supportsIdrefElementReferences,\n type AriaIdrefMirrorHandle,\n} from '../../utils/aria-idref.js';\n\nconst _nextCheckboxGroupId = createIdCounter('hx-checkbox-group');\n\n/**\n * Reads visible text from a shadow wrapper that contains a `<slot>`. Prefers\n * the slot's flattened assigned-nodes text when light DOM is projected,\n * otherwise falls back to the wrapper's own `textContent` (so property-driven\n * fallback content rendered inside the slot is still readable). Codex\n * round-23 P2 (Finding B): a wrapper-element `textContent` read does NOT\n * cross the shadow → light-DOM slot boundary, so the previous direct\n * `textContent` mirror returned empty when a consumer slotted help/error\n * content instead of using the property.\n */\nfunction readSlottedOrShadowText(wrapper: Element): string {\n const slot = wrapper.querySelector('slot');\n if (slot) {\n const assigned = (slot as HTMLSlotElement).assignedNodes({ flatten: true });\n if (assigned.length > 0) {\n return assigned\n .map((node) => node.textContent ?? '')\n .join('')\n .trim();\n }\n }\n return (wrapper.textContent ?? '').trim();\n}\n\n/** Detail for the hx-change event dispatched by hx-checkbox-group. */\nexport interface HxCheckboxGroupChangeDetail {\n values: string[];\n}\n\n/**\n * A form-associated checkbox group that manages a set of `<hx-checkbox>` children.\n *\n * @summary Form-associated checkbox group with label, validation, help text, and multi-value form submission.\n *\n * @tag hx-checkbox-group\n *\n * @slot - `<hx-checkbox>` elements.\n * @slot label - Rich HTML group label (overrides the label property when used).\n * @slot error - Custom error content (overrides the error property).\n * @slot help-text - Group-level help text.\n *\n * @fires {CustomEvent<{values: string[]}>} hx-change - Dispatched when any child checkbox changes.\n *\n * @csspart group - The fieldset wrapper.\n * @csspart label - The legend/label.\n * @csspart help-text - The help text container.\n * @csspart error - The error message container.\n *\n * @cssprop [--hx-checkbox-group-gap=var(--hx-space-3, 0.75rem)] - Gap between checkbox items.\n * @cssprop [--hx-checkbox-group-label-color=var(--hx-color-neutral-700, #313E4B)] - Label text color.\n * @cssprop [--hx-checkbox-group-error-color=var(--hx-color-error-500, #E5493E)] - Error message color.\n * @cssprop [--hx-checkbox-group-help-text-color=var(--hx-color-neutral-500)] - Help text color.\n *\n * @drupal\n * Form-associated; render via Twig:\n * ```twig\n * <hx-checkbox-group name=\"{{ field_name }}\" label=\"{{ label }}\"{{ required ? ' required' : '' }}>\n * {% for option in options %}\n * <hx-checkbox value=\"{{ option.value }}\" label=\"{{ option.label }}\"></hx-checkbox>\n * {% endfor %}\n * </hx-checkbox-group>\n * ```\n * The group is the sole form participant — children are suppressed via\n * `_groupedSuppress`. Setting `name` on a child has no effect inside a group.\n * @cssprop [--hx-opacity-disabled] - Opacity.\n * @cssprop [--hx-space-2] - Spacing token.\n * @cssprop [--hx-checkbox-group-font-family=var(--hx-font-family-sans)] - CSS custom property.\n * @cssprop [--hx-font-family-sans] - Font family.\n * @cssprop [--hx-space-1] - Spacing token.\n * @cssprop [--hx-font-size-sm] - Font size.\n * @cssprop [--hx-font-weight-medium] - Font weight.\n * @cssprop [--hx-color-neutral-700] - Color.\n * @cssprop [--hx-line-height-normal] - Line height.\n * @cssprop [--hx-color-error-text] - Color.\n * @cssprop [--hx-font-weight-bold] - Font weight.\n * @cssprop [--hx-space-3] - Spacing token.\n * @cssprop [--hx-font-size-xs] - Font size.\n * @cssprop [--hx-color-neutral-500] - Color.\n * @aaa-certified 2026-05-08\n * @aaa-criteria 1.4.6, 1.4.9, 2.1.3, 2.3.3, 2.4.12, 2.4.13, 2.5.5, 3.2.5, 3.3.6, forced-colors, apg-keyboard\n * @aaa-audit src/components/hx-checkbox-group/AAA-AUDIT.md\n * @keyboard-contract navigate=Tab; disabled-suppresses=true\n * @aria-pattern group\n * @aria-pattern-source https://www.w3.org/TR/wai-aria-1.2/#group\n * @forced-colors-supported true\n * @stability stable\n * @since 3.7.0\n * @form-associated true\n * @theme-aware true\n * @brand-aware true\n * @drupal-sdc-eligible true\n * @react-wrapper-status complete\n * @figma-component-name hx-checkbox-group\n * @priority-tier P0\n * @phi-handles false\n * @clinical-context none\n */\n@customElement('hx-checkbox-group')\nexport class HelixCheckboxGroup extends FormMixin(HelixElement) {\n static override styles = [helixCheckboxGroupStyles, forcedColorsField];\n\n // ─── Form Association ───\n\n /** Marks this element as form-associated for ElementInternals support. @internal */\n static override formAssociated = true;\n\n // ─── Properties ───\n\n /**\n * The name used for form submission. Passed to child `hx-checkbox` elements.\n * @attr name\n */\n @property({ type: String, reflect: true })\n name = '';\n\n /**\n * The fieldset legend/label text.\n * @attr label\n */\n @property({ type: String })\n label = '';\n\n /**\n * Whether at least one checkbox must be checked for form submission.\n * @attr required\n */\n @property({ type: Boolean, reflect: true })\n required = false;\n\n /**\n * Whether the entire group is disabled.\n * @attr disabled\n */\n @property({ type: Boolean, reflect: true })\n disabled = false;\n\n /**\n * Error message to display. When set, the group enters an error state.\n * @attr error\n */\n @property({ type: String })\n error = '';\n\n /**\n * Help text to display below the group. Can also be provided via the help-text slot.\n * @attr help-text\n */\n @property({ type: String, attribute: 'help-text' })\n helpText = '';\n\n /**\n * Layout orientation of the checkbox items.\n * @attr orientation\n */\n @property({ type: String, reflect: true })\n get orientation(): 'vertical' | 'horizontal' {\n return this._orientation;\n }\n set orientation(value: string) {\n if (value !== 'vertical' && value !== 'horizontal') {\n devWarn('hx-checkbox-group', `Invalid orientation \"${value}\", defaulting to \"vertical\".`);\n value = 'vertical';\n }\n this._orientation = value as 'vertical' | 'horizontal';\n }\n /** @internal */\n private _orientation: 'vertical' | 'horizontal' = 'vertical';\n\n /** Whether the named error slot contains projected content. @internal */\n @state() private _hasErrorSlot = false;\n /** Whether the named help-text slot contains projected content. @internal */\n @state() private _hasHelpSlot = false;\n /** Whether the named label slot contains projected content. @internal */\n @state() private _hasLabelSlot = false;\n\n /**\n * Whether the platform supports IDL element references on `ElementInternals`.\n * Drives the render-time branch between modern (host-canonical via\n * internals) and fallback (inner fieldset is the announced surface).\n * Codex round-17 P1.\n * @internal\n */\n @state() private _supportsIdrefRefs = true;\n\n // ─── Internal IDs ───\n\n /** @internal */\n private _groupId = _nextCheckboxGroupId();\n /** @internal */\n private _helpTextId = `${this._groupId}-help`;\n /** @internal */\n private _errorId = `${this._groupId}-error`;\n /** @internal */\n private _labelId = `${this._groupId}-label`;\n\n // ─── Slot Handlers ───\n\n /** @internal */\n private _handleErrorSlotChange(e: Event): void {\n const slot = e.target as HTMLSlotElement;\n this._hasErrorSlot = slot.assignedNodes({ flatten: true }).length > 0;\n // Codex round-23 P2 (Finding B): re-tune the in-place text observer over\n // the new assigned-node set so in-place `textContent` rewrites of slotted\n // error nodes resync `internals.ariaDescription` on the no-IDL-ref\n // fallback path. `slotchange` only fires when the *node set* changes;\n // mutating an already-assigned node's text does not, so a separate\n // observer is required. Mirrors `_installLabelSlotTextObserver`.\n this._installErrorSlotTextObserver(slot);\n this._syncHostAriaSemantics();\n }\n\n /** @internal */\n private _handleHelpSlotChange(e: Event): void {\n const slot = e.target as HTMLSlotElement;\n this._hasHelpSlot = slot.assignedNodes({ flatten: true }).length > 0;\n // Codex round-23 P2 (Finding B): same pattern as the error slot — keep\n // `internals.ariaDescription` in sync with in-place text edits on already\n // assigned help-text nodes.\n this._installHelpSlotTextObserver(slot);\n this._syncHostAriaSemantics();\n }\n\n /** @internal */\n private _handleLabelSlotChange(e: Event): void {\n const slot = e.target as HTMLSlotElement;\n this._hasLabelSlot = slot.assignedNodes().length > 0;\n // Codex round-21 P3: re-tune the in-place text observer over the new\n // assigned-node set. `slotchange` fires when the node *set* changes; the\n // observer below catches `textContent` rewrites on already-assigned nodes\n // (which do NOT fire `slotchange`). Re-installing here resets the watch\n // so detached nodes stop firing into a torn-down host and newly assigned\n // nodes contribute to the host's fallback `internals.ariaLabel` resync.\n this._installLabelSlotTextObserver(slot);\n // Pick up any text-content changes that landed alongside the slot\n // mutation in the same task — _syncHostAriaSemantics reads the slot's\n // assigned-nodes textContent for the no-IDL-ref fallback ariaLabel.\n this._syncHostAriaSemantics();\n }\n\n /**\n * Watches assigned `<slot name=\"label\">` nodes for in-place text mutations\n * so the no-IDL-ref fallback `internals.ariaLabel` stays in sync when a\n * framework rewrites `textContent` of an already-assigned node without\n * replacing it. `slotchange` does NOT fire for those mutations, so a\n * separate observer is required. Codex round-21 P3 (mirrors the\n * `hx-toggle-button` pattern from round-13 P2).\n * @internal\n */\n private _labelSlotTextObserver: MutationObserver | null = null;\n\n /**\n * (Re-)installs the mutation observer over the current set of assigned\n * label-slot nodes. Disconnects any prior observer first so detached nodes\n * stop firing into a torn-down host. Codex round-21 P3.\n * @internal\n */\n private _installLabelSlotTextObserver(slot: HTMLSlotElement | null): void {\n this._labelSlotTextObserver?.disconnect();\n if (!slot) {\n this._labelSlotTextObserver = null;\n return;\n }\n const observer = new MutationObserver(() => {\n // Resync host ARIA semantics: the fallback `internals.ariaLabel` is\n // derived from the slot's assigned-nodes `textContent`, so an in-place\n // edit must replay the resolution that ran at first paint.\n this._syncHostAriaSemantics();\n });\n slot.assignedNodes().forEach((node) => {\n observer.observe(node, {\n characterData: true,\n childList: true,\n subtree: true,\n });\n });\n this._labelSlotTextObserver = observer;\n }\n\n /**\n * Watches assigned `<slot name=\"help-text\">` nodes for in-place text\n * mutations so the no-IDL-ref fallback `internals.ariaDescription` stays in\n * sync when a framework rewrites `textContent` of an already-assigned node\n * without replacing it. `slotchange` does NOT fire for those mutations, so\n * a separate observer is required. Codex round-23 P2 (Finding B) — mirrors\n * the round-21 P3 label-slot observer pattern.\n * @internal\n */\n private _helpSlotTextObserver: MutationObserver | null = null;\n\n /**\n * Watches assigned `<slot name=\"error\">` nodes for in-place text mutations\n * so the no-IDL-ref fallback `internals.ariaDescription` stays in sync when\n * a framework rewrites `textContent` of an already-assigned node without\n * replacing it. Codex round-23 P2 (Finding B).\n * @internal\n */\n private _errorSlotTextObserver: MutationObserver | null = null;\n\n /**\n * (Re-)installs the mutation observer over the current set of assigned\n * help-text-slot nodes. Codex round-23 P2 (Finding B).\n * @internal\n */\n private _installHelpSlotTextObserver(slot: HTMLSlotElement | null): void {\n this._helpSlotTextObserver?.disconnect();\n if (!slot) {\n this._helpSlotTextObserver = null;\n return;\n }\n const observer = new MutationObserver(() => {\n this._syncHostAriaSemantics();\n });\n slot.assignedNodes().forEach((node) => {\n observer.observe(node, {\n characterData: true,\n childList: true,\n subtree: true,\n });\n });\n this._helpSlotTextObserver = observer;\n }\n\n /**\n * (Re-)installs the mutation observer over the current set of assigned\n * error-slot nodes. Codex round-23 P2 (Finding B).\n * @internal\n */\n private _installErrorSlotTextObserver(slot: HTMLSlotElement | null): void {\n this._errorSlotTextObserver?.disconnect();\n if (!slot) {\n this._errorSlotTextObserver = null;\n return;\n }\n const observer = new MutationObserver(() => {\n this._syncHostAriaSemantics();\n });\n slot.assignedNodes().forEach((node) => {\n observer.observe(node, {\n characterData: true,\n childList: true,\n subtree: true,\n });\n });\n this._errorSlotTextObserver = observer;\n }\n\n /**\n * Handle for the shared IDREF observer. See `installAriaIdrefMirror()`.\n * @internal\n */\n private _ariaMirror: AriaIdrefMirrorHandle | null = null;\n\n /**\n * Deferred copy of `error` driven through reactive state so the persistent\n * live region can re-announce on transitions without direct DOM mutation.\n * Codex round-1 finding #10.\n * @internal\n */\n @state() private _announcedError = '';\n\n /**\n * Last value of `aria-labelledby` we wrote to the host. Used to distinguish\n * external (consumer) attribute mutations from our own internal augmentation\n * writes when refreshing the host-attribute fallback. Codex round-10 P2:\n * without this guard, an internal mutation observer fire would re-read the\n * already-augmented host attribute as if it were consumer-supplied, causing\n * legend/help/error ids to leak forward as \"consumer tokens\" forever.\n * @internal\n */\n private _lastWrittenLabelledBy: string | null = null;\n /** @internal — see `_lastWrittenLabelledBy`. */\n private _lastWrittenDescribedBy: string | null = null;\n /**\n * Most recently observed *consumer-supplied* `aria-labelledby` baseline (the\n * set of tokens the consumer themselves wrote on the host). Refreshed only\n * when the host attribute changes via an external write — internal writes\n * leave the baseline untouched.\n * @internal\n */\n private _consumerLabelledBy: string | null = null;\n /** @internal — see `_consumerLabelledBy`. */\n private _consumerDescribedBy: string | null = null;\n\n // ─── Lifecycle ───\n\n /**\n * APG group / checkbox roving-tabindex keyboard handler.\n * Reference: https://www.w3.org/WAI/ARIA/apg/patterns/checkbox/\n *\n * - ArrowRight / ArrowDown: focus next checkbox, wrap.\n * - ArrowLeft / ArrowUp: focus prev checkbox, wrap.\n * - Home: focus first checkbox.\n * - End: focus last checkbox.\n *\n * Space / Enter activation is handled by the native checkbox itself —\n * the host does not intercept those keys.\n * @internal\n */\n private _handleHostKeydown = (e: KeyboardEvent): void => {\n const isVertical = this.orientation !== 'horizontal';\n const nextKey = isVertical ? 'ArrowDown' : 'ArrowRight';\n const prevKey = isVertical ? 'ArrowUp' : 'ArrowLeft';\n\n if (e.key === nextKey) {\n e.preventDefault();\n this._moveCheckboxFocus('next');\n } else if (e.key === prevKey) {\n e.preventDefault();\n this._moveCheckboxFocus('prev');\n } else if (e.key === 'Home') {\n e.preventDefault();\n const items = this._getEnabledCheckboxes();\n items[0]?.focus();\n } else if (e.key === 'End') {\n e.preventDefault();\n const items = this._getEnabledCheckboxes();\n items[items.length - 1]?.focus();\n }\n };\n\n /** @internal */\n private _getEnabledCheckboxes(): HTMLElement[] {\n return this._getCheckboxes().filter((cb) => {\n const el = cb as HTMLElement & { disabled?: boolean };\n return !el.disabled && !el.hasAttribute('disabled');\n }) as HTMLElement[];\n }\n\n /** @internal */\n private _moveCheckboxFocus(direction: 'next' | 'prev'): void {\n const items = this._getEnabledCheckboxes();\n if (!items.length) return;\n const focused = (document.activeElement as HTMLElement) || null;\n // activeElement may be the host; resolve through shadow active path.\n let deep: Element | null = focused;\n while (deep && deep.shadowRoot && deep.shadowRoot.activeElement) {\n deep = deep.shadowRoot.activeElement;\n }\n const currentIndex = items.indexOf(deep as HTMLElement);\n let nextIndex: number;\n if (direction === 'next') {\n nextIndex = currentIndex < items.length - 1 ? currentIndex + 1 : 0;\n } else {\n nextIndex = currentIndex > 0 ? currentIndex - 1 : items.length - 1;\n }\n items[nextIndex]?.focus();\n }\n\n override connectedCallback(): void {\n super.connectedCallback();\n // Detect IDL element-references API support so render() can branch the\n // fieldset between presentational (modern) and group-with-aria\n // (fallback) treatments. Codex round-17 P1.\n this._supportsIdrefRefs = supportsIdrefElementReferences(this._internals);\n this.addEventListener('hx-change', this._handleCheckboxChange);\n // APG-aligned host keyboard contract — fulfils WCAG 2.2 AAA 2.1.3\n // requirement that a focusable host with a declared role provides a\n // keyboard interaction contract (formal AAA audit verifies this).\n this.addEventListener('keydown', this._handleHostKeydown);\n // Seed root-independent semantics from connect.\n this._syncHostAriaSemantics();\n this._ariaMirror = installAriaIdrefMirror(this, () => {\n this._syncHostAriaSemantics();\n });\n // Codex round-10 P2: re-apply child suppression on reattach. On the first\n // mount `firstUpdated()` runs `_syncCheckboxNames()` later, but when the\n // same group node is detached and re-inserted (with the same children\n // already in place), `firstUpdated()` does NOT re-fire. Without this,\n // `disconnectedCallback()`'s suppression-clearing leaves children\n // form-active alongside the group on the next attach, which reintroduces\n // the duplicate-submission bug the round-1 fix eliminated.\n if (this._getCheckboxes().length > 0) {\n this._syncCheckboxNames();\n this._previousChildren = this._getCheckboxes();\n }\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n this.removeEventListener('hx-change', this._handleCheckboxChange);\n this.removeEventListener('keydown', this._handleHostKeydown);\n this._ariaMirror?.disconnect();\n this._ariaMirror = null;\n // Codex round-21 P3: tear down the slot-label text observer so detached\n // assigned nodes stop firing into a torn-down host.\n this._labelSlotTextObserver?.disconnect();\n this._labelSlotTextObserver = null;\n // Codex round-23 P2 (Finding B): tear down the help/error slot text\n // observers for the same reason.\n this._helpSlotTextObserver?.disconnect();\n this._helpSlotTextObserver = null;\n this._errorSlotTextObserver?.disconnect();\n this._errorSlotTextObserver = null;\n // Release suppression on every previously-tracked child so they regain\n // stand-alone form participation if re-parented or kept in the document\n // after the group is removed. Codex round-3 finding #1.\n this._previousChildren.forEach((cb) => {\n if (this._suppressedChildren.has(cb)) {\n cb._groupedSuppress = false;\n this._suppressedChildren.delete(cb);\n }\n });\n this._previousChildren = [];\n }\n\n override updated(changedProperties: PropertyValues<this>): void {\n super.updated(changedProperties);\n if (changedProperties.has('disabled')) {\n this._syncCheckboxes();\n }\n if (changedProperties.has('name')) {\n this._syncCheckboxNames();\n }\n // Host-elevated ARIA semantics — see _syncHostAriaSemantics.\n this._syncHostAriaSemantics();\n // Codex round-1 finding #10: drive re-announcement from reactive state\n // so the persistent live region stays in the shadow tree across error\n // transitions. The previous direct `errorEl.textContent =` mutation\n // deleted the slot subtree the renderer just produced.\n if (changedProperties.has('error')) {\n const previousError = changedProperties.get('error') as string;\n if (previousError && this.error) {\n this._announcedError = '';\n requestAnimationFrame(() => {\n this._announcedError = this.error;\n });\n } else {\n this._announcedError = this.error;\n }\n }\n }\n\n /**\n * Mirrors group semantics onto the host via ElementInternals so that\n * consumer-supplied `aria-label`, `aria-labelledby`, and `aria-describedby`\n * on `<hx-checkbox-group>` reach the announced control. Without host-level\n * semantics, the announced node is the shadow `<fieldset>`, which is\n * unreachable from light-DOM IDREFs.\n * @internal\n */\n private _syncHostAriaSemantics(): void {\n const internals = this._internals;\n internals.role = 'group';\n internals.ariaRequired = this.required ? 'true' : 'false';\n internals.ariaInvalid = !internals.validity.valid ? 'true' : 'false';\n internals.ariaDisabled = this.disabled ? 'true' : 'false';\n\n // Prefer consumer-supplied host aria-label; fall back to the visible legend\n // text (label property or label slot) so the host always carries an\n // accessible name.\n //\n // Codex round-7 #0: on the no-IDL-ref fallback path the slotted legend\n // is the only source of an accessible name (the IDREF branch wires it via\n // `ariaLabelledByElements`, which is unavailable here). Read the slot's\n // assigned nodes for a `<slot name=\"label\">` payload so it contributes to\n // `internals.ariaLabel` — without this, fallback browsers leave the host\n // unnamed when only the slot supplies the legend.\n //\n // Codex round-20 P2: do NOT read the rendered <legend>'s `textContent`.\n // The legend renders the visible required marker as a sibling of the\n // `<slot name=\"label\">` (`<span class=\"fieldset__required-marker\"\n // aria-hidden=\"true\">*</span>`) — flattening descendants would fold the\n // visible \"*\" into the host's ariaLabel (\"Topics *\"), so AT mis-announces\n // required groups. Read assigned slot nodes directly: the marker lives\n // outside the slot in shadow DOM, so it is excluded cleanly. Mirrors the\n // hx-radio-group fallback (which has no label slot, only `this.label`).\n const hostAriaLabel = this.getAttribute('aria-label')?.trim() || '';\n const labelSlot = this.shadowRoot?.querySelector<HTMLSlotElement>('slot[name=\"label\"]');\n const labelSlotHasAssignedNodes = (labelSlot?.assignedNodes().length ?? 0) > 0;\n const slottedLabelText =\n labelSlot\n ?.assignedNodes()\n .map((node) => node.textContent ?? '')\n .join('')\n .trim() || '';\n // Codex round-22 P2: documented contract — `@slot label - Rich HTML group\n // label (overrides the label property when used)`. Slot wins. When a\n // consumer supplies BOTH `label=\"...\"` AND `<span slot=\"label\">...</span>`,\n // the slot is the public-facing legend; the property must not clobber it\n // on the fallback path's `internals.ariaLabel`.\n //\n // Codex round-23 P2 (Finding A): the slot precedence must hold even when\n // the slot is whitespace-only or empty. Previously `slottedLabelText ||\n // this.label` fell through to the property when the slot trimmed to '',\n // which diverged from the visible legend (the slot suppresses fallback\n // text via `<slot name=\"label\">${this.label}</slot>` — the slot's\n // assigned-node trail wins, so the rendered legend stays empty too). Use\n // the slot's *assigned-node presence* as the precedence signal: any\n // assigned nodes mean the slot is in use, so the property must NOT leak\n // into `internals.ariaLabel`. Empty-string slots resolve to `null` (no\n // accessible name) — the same outcome the visible legend produces.\n const internalLegendText = labelSlotHasAssignedNodes\n ? slottedLabelText || null\n : this.label || null;\n\n // Codex round-10 P2: refresh the consumer baseline only when the host\n // attribute moved due to an *external* write. Compare the live attribute\n // against our last-written snapshot — if it differs, the consumer wrote.\n const liveLabelledBy = this.getAttribute('aria-labelledby');\n if (liveLabelledBy !== this._lastWrittenLabelledBy) {\n this._consumerLabelledBy = liveLabelledBy;\n }\n const liveDescribedBy = this.getAttribute('aria-describedby');\n if (liveDescribedBy !== this._lastWrittenDescribedBy) {\n this._consumerDescribedBy = liveDescribedBy;\n }\n const externalLabelTokens = this._consumerLabelledBy;\n const externalDescTokens = this._consumerDescribedBy;\n\n // Resolve the candidate label/desc element references once — both render\n // branches (modern IDL-ref and host-attribute fallback) consume the same\n // collections; the IDL-ref branch assigns them as `Element[]`, the\n // fallback mirrors their `id` tokens onto the host's `aria-*` attributes.\n const labelEls = resolveIdrefTokens(this, externalLabelTokens);\n // Codex round-35 (medium): `aria-labelledby` is only \"effective\" when at\n // least one IDREF resolves to a real element. A typo or transiently-\n // missing target must NOT erase the visible legend — fall back to the\n // legend slot/property so the group keeps a name on both render paths.\n const hasEffectiveLabelledBy = labelEls.length > 0;\n if (hostAriaLabel) {\n internals.ariaLabel = hostAriaLabel;\n } else if (!hasEffectiveLabelledBy) {\n internals.ariaLabel = internalLegendText;\n } else {\n internals.ariaLabel = null;\n }\n const internalLegend = this.shadowRoot?.getElementById(this._labelId);\n if (\n labelEls.length === 0 &&\n !hostAriaLabel &&\n (this.label || this._hasLabelSlot) &&\n internalLegend\n ) {\n labelEls.push(internalLegend);\n }\n\n const descEls = resolveIdrefTokens(this, externalDescTokens);\n const helpEl = this.shadowRoot?.getElementById(this._helpTextId);\n const errorEl = this.shadowRoot?.getElementById(this._errorId);\n const hasError = !!(this.error || this._hasErrorSlot);\n // Codex round-15 P2: drop help text from the describedby chain while an\n // error is active. The render path hides the help wrapper in that state\n // (`?hidden=${!hasHelp || hasError}`); appending the hidden node to host\n // semantics would make AT announce stale guidance ahead of the\n // validation error. Mirrors the hx-switch and hx-checkbox treatment.\n if (helpEl && !hasError && (this.helpText || this._hasHelpSlot)) {\n descEls.push(helpEl);\n }\n if (errorEl && hasError) {\n descEls.push(errorEl);\n }\n\n // Branch off the cached `_supportsIdrefRefs` (seeded at connect by the\n // platform probe) so tests can force the fallback branch by flipping the\n // flag. TODO(codex round-19 follow-up): re-probe on `adoptedCallback` if\n // we ever support cross-document moves; today the cached value is set\n // once at connect.\n if (this._supportsIdrefRefs) {\n type InternalsWithRefs = ElementInternals & {\n ariaLabelledByElements: Element[] | null;\n ariaDescribedByElements: Element[] | null;\n };\n const refsInternals = internals as InternalsWithRefs;\n refsInternals.ariaLabelledByElements = labelEls.length > 0 ? labelEls : null;\n refsInternals.ariaDescribedByElements = descEls.length > 0 ? descEls : null;\n // Clear any stale fallback `ariaDescription` string in case a prior sync\n // ran on the fallback path (e.g. tests flipping `_supportsIdrefRefs`).\n // The modern path uses element references exclusively; coexisting strings\n // would cause AT to announce the description twice.\n internals.ariaDescription = null;\n } else {\n // ─── No-IDL-ref fallback (codex round-19 P1) ───\n // The IDL element-references API is unavailable, so internal shadow\n // help/error/legend wrappers cannot be projected onto the host\n // accessibility node via `internals.aria*Elements`.\n //\n // Codex round-19 P1: keep the host as the canonical accessible-container\n // surface on BOTH modern and fallback paths. Earlier rounds promoted the\n // inner fieldset to `role=\"group\"` here and tried to splice consumer\n // light-DOM ids together with shadow-internal ids on the fieldset's\n // `aria-labelledby` / `aria-describedby`. That created two nested\n // accessible containers (host group → inner group → controls) AND the\n // spliced shadow IDREFs could never resolve to consumer light-DOM\n // targets, so the inner fieldset's \"external label\" was silently broken.\n //\n // The correct trade-off on legacy engines (notably Firefox today): the\n // host owns the role + ARIA strings (via `internals.role`,\n // `internals.ariaLabel`, and the host attribute mirror below); we accept\n // a documented loss of *internal* legend/help/error references and rely\n // on consumer-supplied light-DOM tokens, which resolve correctly in the\n // host's containing root. The inner fieldset stays presentational on\n // both paths so AT announces a single accessible container.\n const consumerLabelIds = new Set((externalLabelTokens?.split(/\\s+/) ?? []).filter(Boolean));\n const consumerDescIds = new Set((externalDescTokens?.split(/\\s+/) ?? []).filter(Boolean));\n\n // Host attributes: ONLY consumer tokens (never shadow-internal ids —\n // those cannot resolve across the shadow boundary). Restore the\n // consumer baseline on the host so its accessible-name computation in\n // the light DOM resolves the labels the consumer wired up. If the\n // consumer supplied nothing, clear any stale mirror we may have\n // written in a prior round.\n //\n // Codex round-35 (medium): mirror consumer tokens to the host attribute\n // ONLY when at least one token resolves to a real element. Broken\n // tokens (typo, target not yet attached) would otherwise erase the\n // accessible name on legacy engines per ARIA priority\n // (aria-labelledby > aria-label > internals.ariaLabel). When tokens\n // don't resolve, clear the host attribute so the `internals.ariaLabel`\n // fallback the modern path set above (`internalLegendText`) wins.\n const hostLabel = hasEffectiveLabelledBy\n ? [...consumerLabelIds].filter(Boolean).join(' ')\n : '';\n const liveLabel = this.getAttribute('aria-labelledby');\n if (hostLabel) {\n if (liveLabel !== hostLabel) {\n this.setAttribute('aria-labelledby', hostLabel);\n }\n this._lastWrittenLabelledBy = hostLabel;\n } else if (liveLabel !== null) {\n // Codex round-36 (medium): when consumer-supplied tokens don't\n // resolve (`!hasEffectiveLabelledBy`), actively clear the host\n // attribute even if WE didn't write it. Per ARIA priority\n // (aria-labelledby > aria-label > internals.ariaLabel), a broken\n // consumer-authored attribute on the announced surface erases the\n // legend on legacy engines. The original tokens remain cached in\n // `_consumerLabelledBy` so they replay on a future sync if the\n // target later attaches.\n this.removeAttribute('aria-labelledby');\n this._lastWrittenLabelledBy = null;\n }\n\n const hostDesc = [...consumerDescIds].filter(Boolean).join(' ') || '';\n const liveDesc = this.getAttribute('aria-describedby');\n if (hostDesc) {\n if (liveDesc !== hostDesc) {\n this.setAttribute('aria-describedby', hostDesc);\n }\n this._lastWrittenDescribedBy = hostDesc;\n } else if (liveDesc !== null && this._lastWrittenDescribedBy !== null) {\n this.removeAttribute('aria-describedby');\n this._lastWrittenDescribedBy = null;\n }\n\n // Codex round-22 P1 #2: on the no-IDL-ref fallback path, consumer-supplied\n // describedby tokens reach the host (above) but the *internal* shadow\n // help/error wrappers cannot be referenced from light-DOM IDREFs. Mirror\n // their `textContent` into `internals.ariaDescription` so the host's\n // accessible description still surfaces the live help/error strings on\n // legacy engines (Firefox today). The string-form description hook is\n // independent of element references and survives the shadow boundary.\n // Empty strings are normalized to `null` so AT does not announce an\n // empty description.\n //\n // Codex round-23 P2 (Finding B): a wrapper-element `textContent` read\n // does NOT cross the shadow → light-DOM slot boundary — it returns only\n // the wrapper's shadow tree, which for a slotted help/error is just the\n // slot's fallback (empty when a property is not set). Use a helper that\n // prefers the slot's flattened assigned-nodes text when present and\n // falls back to the wrapper's textContent for property-rendered fallback\n // content. The new help/error slot text observers (above) keep this in\n // sync when a framework rewrites the slotted node's textContent in place.\n const helpText =\n helpEl && !hasError && (this.helpText || this._hasHelpSlot)\n ? readSlottedOrShadowText(helpEl)\n : '';\n const errorText = errorEl && hasError ? readSlottedOrShadowText(errorEl) : '';\n const internalDescriptionText = [helpText, errorText].filter(Boolean).join(' ');\n internals.ariaDescription = internalDescriptionText || null;\n }\n }\n\n override firstUpdated(changedProperties: PropertyValues<this>): void {\n super.firstUpdated(changedProperties);\n this._syncCheckboxes();\n this._syncCheckboxNames();\n this._previousChildren = this._getCheckboxes();\n const checkedValues = this._getCheckedValues();\n this._updateFormValue(checkedValues);\n this._updateValidity(checkedValues);\n }\n\n // ─── Checkbox Management ───\n\n /** @internal */\n private _getCheckboxes(): HelixCheckbox[] {\n return Array.from(this.children).filter((c): c is HelixCheckbox => c.tagName === 'HX-CHECKBOX');\n }\n\n /** @internal */\n private _getCheckedValues(): string[] {\n return this._getCheckboxes()\n .filter((cb) => cb.checked)\n .map((cb) => cb.value);\n }\n\n /** @internal */\n private _syncCheckboxes(): void {\n const checkboxes = this._getCheckboxes();\n checkboxes.forEach((cb) => {\n cb.disabled = this.disabled;\n });\n }\n\n /**\n * Tracks the set of checkboxes most recently flagged with\n * `_groupedSuppress = true` so a child removed from the group can have its\n * suppression cleared and regain stand-alone form participation. Codex\n * round-3 finding #1.\n * @internal\n */\n private _suppressedChildren = new WeakSet<HelixCheckbox>();\n\n /**\n * Centralizes form participation on the group: when an `hx-checkbox` is\n * grouped, the group is the sole form participant. Without this, both the\n * group AND each child would call `setFormValue` for the same name, causing\n * every checked value to submit twice.\n *\n * Codex round-2 finding #1 used `cb.name = ''` as the suppression signal.\n * Codex round-3 finding #1 hardened that: a consumer (or framework binding)\n * that re-set `cb.name = 'foo'` after attach regained form participation\n * because the child's `name` setter re-armed `_updateFormValue()` while no\n * `slotchange` re-fired to re-null the name.\n *\n * The fix is a durable, name-independent kill switch — `_groupedSuppress` —\n * on each child. While the flag is set the child's `_updateFormValue()`\n * short-circuits to `setFormValue(null)` regardless of its `name` value.\n * Children removed from the group have the flag cleared so they regain\n * stand-alone form participation.\n * @internal\n */\n private _syncCheckboxNames(): void {\n const current = new Set(this._getCheckboxes());\n // Clear suppression on any previously-grouped child that has since been\n // removed from this group. WeakSet has no iterator, so we re-walk current\n // children plus track removals via the slotchange handler's \"delta\" — but\n // since WeakSet does not enumerate, we instead resolve via the child's\n // own state below: any child WITH the flag that is no longer a current\n // child must be cleared. To do that without enumeration we mark all\n // current children true here and rely on `_handleSlotChange` to clear\n // departed children explicitly via `_clearSuppressionForRemoved()`.\n // Group ownership invariant (round-3 hardening, reaffirmed round-22):\n // `hx-checkbox-group` is the sole form participant for its children, full\n // stop. Children inside a group never submit independently, regardless of\n // whether the group or the child carries a `name` attribute. Any consumer\n // who attaches a `<hx-checkbox name=\"...\">` directly inside a\n // `<hx-checkbox-group>` (even one without its own `name`) is misusing the\n // API — the child must be moved out of the group to submit independently.\n // Suppression is unconditional to prevent re-arming attacks where\n // `cb.name = ''` would otherwise restore stand-alone participation while\n // the child still appears \"grouped\".\n current.forEach((cb) => {\n cb._groupedSuppress = true;\n this._suppressedChildren.add(cb);\n });\n }\n\n /**\n * Clears `_groupedSuppress` on any checkbox that was previously in this\n * group but has since been removed (re-parented or detached). Called from\n * `_handleSlotChange()` after `_syncCheckboxNames()` re-applies the flag\n * to current children.\n *\n * `previousChildren` is a snapshot captured before slot mutation; any child\n * in that set but not in the current set has left the group and must have\n * its suppression cleared so stand-alone use restores form participation.\n * @internal\n */\n private _clearSuppressionForRemoved(previousChildren: HelixCheckbox[]): void {\n const current = new Set(this._getCheckboxes());\n previousChildren.forEach((cb) => {\n if (!current.has(cb) && this._suppressedChildren.has(cb)) {\n cb._groupedSuppress = false;\n this._suppressedChildren.delete(cb);\n }\n });\n }\n\n /**\n * Snapshot of children captured before each `slotchange` so removed children\n * can be detected (WeakSet is non-enumerable).\n * @internal\n */\n private _previousChildren: HelixCheckbox[] = [];\n\n // ─── Event Handling ───\n\n /** @internal */\n private _handleCheckboxChange = (e: Event): void => {\n // Only intercept events from direct hx-checkbox children — do not re-intercept\n // the hx-change we dispatch ourselves from this element.\n if (e.target === this) return;\n\n e.stopImmediatePropagation();\n\n const values = this._getCheckedValues();\n this._updateFormValue(values);\n this._updateValidity(values);\n this._handleInteractionInput();\n\n /**\n * Dispatched when any child checkbox changes.\n * @event hx-change\n */\n this.dispatchEvent(\n new CustomEvent<{ values: string[] }>('hx-change', {\n bubbles: true,\n composed: true,\n detail: { values },\n }),\n );\n };\n\n /** @internal */\n private _handleSlotChange(): void {\n this._syncCheckboxes();\n // Capture pre-mutation snapshot from the previous _previousChildren cache\n // (the previous slot pass) so removed children can be released from\n // suppression. Then refresh the snapshot for the next slotchange.\n const previous = this._previousChildren;\n this._syncCheckboxNames();\n this._clearSuppressionForRemoved(previous);\n this._previousChildren = this._getCheckboxes();\n const checkedValues = this._getCheckedValues();\n this._updateFormValue(checkedValues);\n this._updateValidity(checkedValues);\n }\n\n // ─── Form Integration ───\n\n /** @internal */\n private _updateFormValue(values: string[]): void {\n if (values.length === 0) {\n this._internals.setFormValue(null);\n return;\n }\n const formData = new FormData();\n values.forEach((v) => formData.append(this.name, v));\n this._internals.setFormValue(formData);\n }\n\n /** @internal */\n override _updateValidity(values?: string[]): void {\n const checkedValues = values ?? this._getCheckedValues();\n if (this.required && checkedValues.length === 0) {\n const firstCheckbox = this._getCheckboxes()[0];\n this._internals.setValidity(\n { valueMissing: true },\n this.error || 'Please select at least one option.',\n firstCheckbox,\n );\n } else {\n this._internals.setValidity({});\n }\n // Codex round-1 finding #6: re-sync host ARIA after every setValidity().\n this._syncHostAriaSemantics();\n }\n\n /** @internal */\n protected override _onFormReset(): void {\n const checkboxes = this._getCheckboxes();\n checkboxes.forEach((cb) => {\n cb.checked = false;\n });\n this._internals.setFormValue(null);\n this._updateValidity([]);\n this._resetInteractionState();\n }\n\n /** @internal */\n protected override _onFormStateRestore(\n state: File | string | FormData | null,\n _mode: 'restore' | 'autocomplete',\n ): void {\n if (!(state instanceof FormData)) return;\n const restoredValues = state.getAll(this.name).map((v) => String(v));\n const checkboxes = this._getCheckboxes();\n checkboxes.forEach((cb) => {\n cb.checked = restoredValues.includes(cb.value);\n });\n this._updateFormValue(restoredValues);\n this._updateValidity(restoredValues);\n }\n\n /** @internal */\n protected override _onFormDisabled(disabled: boolean): void {\n this.disabled = disabled;\n }\n\n // ─── Render ───\n\n override render() {\n const hasError = !!this.error || this._hasErrorSlot;\n const hasHelp = !!this.helpText || this._hasHelpSlot;\n\n const fieldsetClasses = {\n fieldset: true,\n 'fieldset--error': hasError,\n 'fieldset--disabled': this.disabled,\n 'fieldset--required': this.required,\n };\n\n // Codex round-19 P1: inner fieldset is presentational on BOTH the modern\n // and no-IDL-ref fallback paths so AT announces exactly one accessible\n // container (the host). Earlier rounds promoted the fieldset to\n // `role=\"group\"` on the fallback branch and spliced shadow-internal ids\n // into its aria-* attributes; that produced nested host→fieldset groups\n // and broke external IDREFs (shadow ids cannot resolve across the\n // boundary). The host carries the role + accessible name via\n // ElementInternals on both paths.\n return html`\n <fieldset part=\"group\" class=${classMap(fieldsetClasses)} role=\"presentation\">\n <legend part=\"label\" class=\"fieldset__legend\" id=${this._labelId}>\n <slot name=\"label\" @slotchange=${this._handleLabelSlotChange}>${this.label}</slot>\n ${this.required\n ? html`<span class=\"fieldset__required-marker\" aria-hidden=\"true\">*</span>`\n : nothing}\n </legend>\n\n <div class=\"fieldset__items\">\n <slot @slotchange=${this._handleSlotChange}></slot>\n </div>\n\n <!--\n Persistent live region. role=\"alert\" is set from first paint so\n assistive tech tracks a stable element across error transitions;\n the content updates rather than the container being replaced.\n -->\n <div\n part=\"error\"\n class=\"fieldset__error\"\n id=${this._errorId}\n role=\"alert\"\n ?hidden=${!hasError}\n >\n <slot name=\"error\" @slotchange=${this._handleErrorSlotChange}\n >${this._announcedError}</slot\n >\n </div>\n\n <!--\n Persistent help-text wrapper, hidden when error overrides so guidance\n does not compete with validation feedback. Always in the shadow tree\n so the host's aria-describedby chain is stable.\n -->\n <div\n part=\"help-text\"\n class=\"fieldset__help-text\"\n id=${this._helpTextId}\n ?hidden=${!hasHelp || hasError}\n >\n <slot name=\"help-text\" @slotchange=${this._handleHelpSlotChange}>${this.helpText}</slot>\n </div>\n </fieldset>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'hx-checkbox-group': HelixCheckboxGroup;\n }\n}\n"],"names":["helixCheckboxGroupStyles","css","_nextCheckboxGroupId","createIdCounter","readSlottedOrShadowText","wrapper","slot","assigned","node","HelixCheckboxGroup","FormMixin","HelixElement","isVertical","nextKey","prevKey","_a","items","_b","values","value","observer","cb","el","direction","deep","currentIndex","nextIndex","supportsIdrefElementReferences","installAriaIdrefMirror","_c","_d","changedProperties","internals","hostAriaLabel","labelSlot","labelSlotHasAssignedNodes","slottedLabelText","internalLegendText","liveLabelledBy","liveDescribedBy","externalLabelTokens","externalDescTokens","labelEls","resolveIdrefTokens","hasEffectiveLabelledBy","internalLegend","descEls","helpEl","errorEl","_e","hasError","refsInternals","consumerLabelIds","consumerDescIds","hostLabel","liveLabel","hostDesc","liveDesc","helpText","errorText","internalDescriptionText","checkedValues","c","previousChildren","current","previous","formData","v","firstCheckbox","state","_mode","restoredValues","disabled","hasHelp","fieldsetClasses","html","classMap","nothing","forcedColorsField","__decorateClass","property","customElement"],"mappings":"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"}