@helixui/library 0.3.3 → 1.0.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 (441) hide show
  1. package/LICENSE +21 -0
  2. package/custom-elements.json +13178 -12195
  3. package/dist/components/hx-accordion/hx-accordion-item.d.ts +3 -1
  4. package/dist/components/hx-accordion/hx-accordion-item.d.ts.map +1 -1
  5. package/dist/components/hx-accordion/hx-accordion.d.ts +9 -1
  6. package/dist/components/hx-accordion/hx-accordion.d.ts.map +1 -1
  7. package/dist/components/hx-accordion/index.js +1 -1
  8. package/dist/components/hx-action-bar/hx-action-bar.d.ts +1 -1
  9. package/dist/components/hx-action-bar/hx-action-bar.d.ts.map +1 -1
  10. package/dist/components/hx-action-bar/index.js +1 -1
  11. package/dist/components/hx-alert/hx-alert.d.ts +3 -6
  12. package/dist/components/hx-alert/hx-alert.d.ts.map +1 -1
  13. package/dist/components/hx-alert/index.js +1 -1
  14. package/dist/components/hx-avatar/hx-avatar.d.ts +1 -1
  15. package/dist/components/hx-avatar/hx-avatar.d.ts.map +1 -1
  16. package/dist/components/hx-avatar/index.js +1 -1
  17. package/dist/components/hx-badge/hx-badge.d.ts +1 -1
  18. package/dist/components/hx-banner/hx-banner.d.ts +99 -0
  19. package/dist/components/hx-banner/hx-banner.d.ts.map +1 -0
  20. package/dist/components/hx-banner/hx-banner.styles.d.ts +2 -0
  21. package/dist/components/hx-banner/hx-banner.styles.d.ts.map +1 -0
  22. package/dist/components/hx-banner/index.d.ts +3 -0
  23. package/dist/components/hx-banner/index.d.ts.map +1 -0
  24. package/dist/components/hx-banner/index.js +5 -0
  25. package/dist/components/hx-banner/index.js.map +1 -0
  26. package/dist/components/hx-breadcrumb/hx-breadcrumb-item.d.ts +1 -1
  27. package/dist/components/hx-breadcrumb/hx-breadcrumb.d.ts +6 -1
  28. package/dist/components/hx-breadcrumb/hx-breadcrumb.d.ts.map +1 -1
  29. package/dist/components/hx-breadcrumb/index.js +1 -1
  30. package/dist/components/hx-button/hx-button.d.ts +17 -0
  31. package/dist/components/hx-button/hx-button.d.ts.map +1 -1
  32. package/dist/components/hx-button/hx-button.styles.d.ts.map +1 -1
  33. package/dist/components/hx-button/index.js +1 -1
  34. package/dist/components/hx-button-group/hx-button-group.d.ts +9 -1
  35. package/dist/components/hx-button-group/hx-button-group.d.ts.map +1 -1
  36. package/dist/components/hx-button-group/index.js +1 -1
  37. package/dist/components/hx-card/hx-card.d.ts +17 -1
  38. package/dist/components/hx-card/hx-card.d.ts.map +1 -1
  39. package/dist/components/hx-card/hx-card.styles.d.ts.map +1 -1
  40. package/dist/components/hx-card/index.js +1 -1
  41. package/dist/components/hx-carousel/hx-carousel-item.d.ts +1 -1
  42. package/dist/components/hx-carousel/hx-carousel.d.ts +123 -1
  43. package/dist/components/hx-carousel/hx-carousel.d.ts.map +1 -1
  44. package/dist/components/hx-carousel/index.js +1 -1
  45. package/dist/components/hx-checkbox/hx-checkbox.d.ts +4 -2
  46. package/dist/components/hx-checkbox/hx-checkbox.d.ts.map +1 -1
  47. package/dist/components/hx-checkbox-group/hx-checkbox-group.d.ts +6 -2
  48. package/dist/components/hx-checkbox-group/hx-checkbox-group.d.ts.map +1 -1
  49. package/dist/components/hx-checkbox-group/index.js +1 -1
  50. package/dist/components/hx-code-snippet/hx-code-snippet.d.ts +21 -6
  51. package/dist/components/hx-code-snippet/hx-code-snippet.d.ts.map +1 -1
  52. package/dist/components/hx-code-snippet/index.js +1 -1
  53. package/dist/components/hx-color-picker/hx-color-picker.d.ts +14 -1
  54. package/dist/components/hx-color-picker/hx-color-picker.d.ts.map +1 -1
  55. package/dist/components/hx-color-picker/hx-color-picker.styles.d.ts.map +1 -1
  56. package/dist/components/hx-color-picker/index.js +1 -1
  57. package/dist/components/hx-combobox/hx-combobox.d.ts +25 -1
  58. package/dist/components/hx-combobox/hx-combobox.d.ts.map +1 -1
  59. package/dist/components/hx-combobox/hx-combobox.styles.d.ts.map +1 -1
  60. package/dist/components/hx-combobox/index.js +1 -1
  61. package/dist/components/hx-container/hx-container.d.ts +4 -2
  62. package/dist/components/hx-container/hx-container.d.ts.map +1 -1
  63. package/dist/components/hx-copy-button/hx-copy-button.d.ts +7 -1
  64. package/dist/components/hx-copy-button/hx-copy-button.d.ts.map +1 -1
  65. package/dist/components/hx-copy-button/index.js +1 -1
  66. package/dist/components/hx-counter/hx-counter.d.ts +79 -0
  67. package/dist/components/hx-counter/hx-counter.d.ts.map +1 -0
  68. package/dist/components/hx-counter/hx-counter.styles.d.ts +2 -0
  69. package/dist/components/hx-counter/hx-counter.styles.d.ts.map +1 -0
  70. package/dist/components/hx-counter/index.d.ts +3 -0
  71. package/dist/components/hx-counter/index.d.ts.map +1 -0
  72. package/dist/components/hx-counter/index.js +5 -0
  73. package/dist/components/hx-counter/index.js.map +1 -0
  74. package/dist/components/hx-data-table/hx-data-table.d.ts +7 -1
  75. package/dist/components/hx-data-table/hx-data-table.d.ts.map +1 -1
  76. package/dist/components/hx-data-table/hx-data-table.styles.d.ts.map +1 -1
  77. package/dist/components/hx-data-table/index.js +1 -1
  78. package/dist/components/hx-date-picker/hx-date-picker.d.ts +125 -1
  79. package/dist/components/hx-date-picker/hx-date-picker.d.ts.map +1 -1
  80. package/dist/components/hx-date-picker/index.js +1 -1
  81. package/dist/components/hx-dialog/hx-dialog.d.ts +1 -1
  82. package/dist/components/hx-dialog/hx-dialog.d.ts.map +1 -1
  83. package/dist/components/hx-dialog/index.js +1 -1
  84. package/dist/components/hx-divider/hx-divider.d.ts +4 -1
  85. package/dist/components/hx-divider/hx-divider.d.ts.map +1 -1
  86. package/dist/components/hx-drawer/hx-drawer.d.ts +55 -2
  87. package/dist/components/hx-drawer/hx-drawer.d.ts.map +1 -1
  88. package/dist/components/hx-drawer/index.js +1 -1
  89. package/dist/components/hx-dropdown/hx-dropdown.d.ts +6 -1
  90. package/dist/components/hx-dropdown/hx-dropdown.d.ts.map +1 -1
  91. package/dist/components/hx-field/hx-field.d.ts +32 -2
  92. package/dist/components/hx-field/hx-field.d.ts.map +1 -1
  93. package/dist/components/hx-field/index.js +1 -1
  94. package/dist/components/hx-field-label/hx-field-label.d.ts +1 -1
  95. package/dist/components/hx-file-upload/hx-file-upload.d.ts +13 -1
  96. package/dist/components/hx-file-upload/hx-file-upload.d.ts.map +1 -1
  97. package/dist/components/hx-file-upload/index.js +1 -1
  98. package/dist/components/hx-form/hx-form.d.ts +25 -1
  99. package/dist/components/hx-form/hx-form.d.ts.map +1 -1
  100. package/dist/components/hx-form/index.js +1 -1
  101. package/dist/components/hx-format-date/hx-format-date.d.ts +1 -1
  102. package/dist/components/hx-grid/hx-grid.d.ts +2 -2
  103. package/dist/components/hx-help-text/hx-help-text.d.ts +4 -1
  104. package/dist/components/hx-help-text/hx-help-text.d.ts.map +1 -1
  105. package/dist/components/hx-icon/hx-icon.d.ts +1 -1
  106. package/dist/components/hx-icon-button/hx-icon-button.d.ts +1 -1
  107. package/dist/components/hx-icon-button/hx-icon-button.d.ts.map +1 -1
  108. package/dist/components/hx-icon-button/index.js +1 -1
  109. package/dist/components/hx-image/hx-image.d.ts +1 -1
  110. package/dist/components/hx-link/hx-link.d.ts +1 -1
  111. package/dist/components/hx-list/hx-list-item.d.ts +1 -1
  112. package/dist/components/hx-list/hx-list.d.ts +1 -1
  113. package/dist/components/hx-list/hx-list.d.ts.map +1 -1
  114. package/dist/components/hx-list/index.js +1 -1
  115. package/dist/components/hx-menu/hx-menu-divider.d.ts +1 -1
  116. package/dist/components/hx-menu/hx-menu-item.d.ts +1 -1
  117. package/dist/components/hx-menu/hx-menu.d.ts +13 -1
  118. package/dist/components/hx-menu/hx-menu.d.ts.map +1 -1
  119. package/dist/components/hx-menu/index.js +1 -1
  120. package/dist/components/hx-meter/hx-meter.d.ts +3 -1
  121. package/dist/components/hx-meter/hx-meter.d.ts.map +1 -1
  122. package/dist/components/hx-meter/index.js +1 -1
  123. package/dist/components/hx-nav/hx-nav.d.ts +16 -2
  124. package/dist/components/hx-nav/hx-nav.d.ts.map +1 -1
  125. package/dist/components/hx-nav/index.js +1 -1
  126. package/dist/components/hx-number-input/hx-number-input.d.ts +3 -1
  127. package/dist/components/hx-number-input/hx-number-input.d.ts.map +1 -1
  128. package/dist/components/hx-number-input/index.js +1 -1
  129. package/dist/components/hx-overflow-menu/hx-overflow-menu.d.ts +15 -1
  130. package/dist/components/hx-overflow-menu/hx-overflow-menu.d.ts.map +1 -1
  131. package/dist/components/hx-overflow-menu/index.js +1 -1
  132. package/dist/components/hx-pagination/hx-pagination.d.ts +6 -1
  133. package/dist/components/hx-pagination/hx-pagination.d.ts.map +1 -1
  134. package/dist/components/hx-pagination/index.js +1 -1
  135. package/dist/components/hx-popover/hx-popover.d.ts +11 -39
  136. package/dist/components/hx-popover/hx-popover.d.ts.map +1 -1
  137. package/dist/components/hx-popover/index.js +1 -1
  138. package/dist/components/hx-popup/hx-popup.d.ts +1 -1
  139. package/dist/components/hx-progress-bar/hx-progress-bar.d.ts +11 -1
  140. package/dist/components/hx-progress-bar/hx-progress-bar.d.ts.map +1 -1
  141. package/dist/components/hx-progress-bar/index.js +1 -1
  142. package/dist/components/hx-progress-ring/hx-progress-ring.d.ts.map +1 -1
  143. package/dist/components/hx-progress-ring/index.js +1 -1
  144. package/dist/components/hx-prose/hx-prose.d.ts +1 -1
  145. package/dist/components/hx-radio-group/hx-radio-group.d.ts +76 -4
  146. package/dist/components/hx-radio-group/hx-radio-group.d.ts.map +1 -1
  147. package/dist/components/hx-radio-group/hx-radio.d.ts +4 -2
  148. package/dist/components/hx-radio-group/hx-radio.d.ts.map +1 -1
  149. package/dist/components/hx-radio-group/index.js +1 -1
  150. package/dist/components/hx-rating/hx-rating.d.ts +19 -4
  151. package/dist/components/hx-rating/hx-rating.d.ts.map +1 -1
  152. package/dist/components/hx-rating/index.js +1 -1
  153. package/dist/components/hx-select/hx-select.d.ts +10 -1
  154. package/dist/components/hx-select/hx-select.d.ts.map +1 -1
  155. package/dist/components/hx-select/index.js +1 -1
  156. package/dist/components/hx-side-nav/hx-nav-item.d.ts +1 -1
  157. package/dist/components/hx-side-nav/hx-side-nav.d.ts +1 -1
  158. package/dist/components/hx-side-nav/hx-side-nav.d.ts.map +1 -1
  159. package/dist/components/hx-side-nav/index.js +1 -1
  160. package/dist/components/hx-skeleton/hx-skeleton.d.ts +1 -1
  161. package/dist/components/hx-slider/hx-slider.d.ts +2 -0
  162. package/dist/components/hx-slider/hx-slider.d.ts.map +1 -1
  163. package/dist/components/hx-slider/index.js +1 -1
  164. package/dist/components/hx-spinner/hx-spinner.d.ts +1 -1
  165. package/dist/components/hx-split-button/hx-split-button.d.ts +17 -1
  166. package/dist/components/hx-split-button/hx-split-button.d.ts.map +1 -1
  167. package/dist/components/hx-split-button/index.js +1 -1
  168. package/dist/components/hx-split-panel/hx-split-panel.d.ts +12 -1
  169. package/dist/components/hx-split-panel/hx-split-panel.d.ts.map +1 -1
  170. package/dist/components/hx-stack/hx-stack.d.ts +1 -1
  171. package/dist/components/hx-stat/hx-stat.d.ts +71 -0
  172. package/dist/components/hx-stat/hx-stat.d.ts.map +1 -0
  173. package/dist/components/hx-stat/hx-stat.styles.d.ts +2 -0
  174. package/dist/components/hx-stat/hx-stat.styles.d.ts.map +1 -0
  175. package/dist/components/hx-stat/index.d.ts +3 -0
  176. package/dist/components/hx-stat/index.d.ts.map +1 -0
  177. package/dist/components/hx-stat/index.js +5 -0
  178. package/dist/components/hx-stat/index.js.map +1 -0
  179. package/dist/components/hx-status-indicator/hx-status-indicator.d.ts +1 -1
  180. package/dist/components/hx-steps/hx-step.d.ts +1 -1
  181. package/dist/components/hx-steps/hx-steps.d.ts +6 -1
  182. package/dist/components/hx-steps/hx-steps.d.ts.map +1 -1
  183. package/dist/components/hx-steps/index.js +1 -1
  184. package/dist/components/hx-structured-list/hx-structured-list.d.ts +4 -2
  185. package/dist/components/hx-structured-list/hx-structured-list.d.ts.map +1 -1
  186. package/dist/components/hx-structured-list/index.js +1 -1
  187. package/dist/components/hx-switch/hx-switch.d.ts +3 -1
  188. package/dist/components/hx-switch/hx-switch.d.ts.map +1 -1
  189. package/dist/components/hx-switch/index.js +1 -1
  190. package/dist/components/hx-table/hx-table.d.ts +60 -0
  191. package/dist/components/hx-table/hx-table.d.ts.map +1 -0
  192. package/dist/components/hx-table/hx-table.styles.d.ts +9 -0
  193. package/dist/components/hx-table/hx-table.styles.d.ts.map +1 -0
  194. package/dist/components/hx-table/hx-tbody.d.ts +23 -0
  195. package/dist/components/hx-table/hx-tbody.d.ts.map +1 -0
  196. package/dist/components/hx-table/hx-td.d.ts +46 -0
  197. package/dist/components/hx-table/hx-td.d.ts.map +1 -0
  198. package/dist/components/hx-table/hx-tfoot.d.ts +23 -0
  199. package/dist/components/hx-table/hx-tfoot.d.ts.map +1 -0
  200. package/dist/components/hx-table/hx-th.d.ts +61 -0
  201. package/dist/components/hx-table/hx-th.d.ts.map +1 -0
  202. package/dist/components/hx-table/hx-thead.d.ts +23 -0
  203. package/dist/components/hx-table/hx-thead.d.ts.map +1 -0
  204. package/dist/components/hx-table/hx-tr.d.ts +33 -0
  205. package/dist/components/hx-table/hx-tr.d.ts.map +1 -0
  206. package/dist/components/hx-table/index.d.ts +9 -0
  207. package/dist/components/hx-table/index.d.ts.map +1 -0
  208. package/dist/components/hx-table/index.js +11 -0
  209. package/dist/components/hx-table/index.js.map +1 -0
  210. package/dist/components/hx-tabs/hx-tab-panel.d.ts +1 -1
  211. package/dist/components/hx-tabs/hx-tab.d.ts +1 -1
  212. package/dist/components/hx-tabs/hx-tabs.d.ts +1 -1
  213. package/dist/components/hx-tabs/hx-tabs.d.ts.map +1 -1
  214. package/dist/components/hx-tabs/index.js +1 -1
  215. package/dist/components/hx-tag/hx-tag.d.ts +1 -1
  216. package/dist/components/hx-text/hx-text.d.ts +1 -1
  217. package/dist/components/hx-text-input/hx-text-input.d.ts +2 -1
  218. package/dist/components/hx-text-input/hx-text-input.d.ts.map +1 -1
  219. package/dist/components/hx-text-input/index.js +1 -1
  220. package/dist/components/hx-textarea/hx-textarea.d.ts +15 -1
  221. package/dist/components/hx-textarea/hx-textarea.d.ts.map +1 -1
  222. package/dist/components/hx-textarea/hx-textarea.styles.d.ts.map +1 -1
  223. package/dist/components/hx-textarea/index.js +1 -1
  224. package/dist/components/hx-theme/hx-theme.d.ts +1 -1
  225. package/dist/components/hx-time-picker/hx-time-picker.d.ts +23 -2
  226. package/dist/components/hx-time-picker/hx-time-picker.d.ts.map +1 -1
  227. package/dist/components/hx-time-picker/index.js +1 -1
  228. package/dist/components/hx-toast/hx-toast-stack.d.ts +36 -0
  229. package/dist/components/hx-toast/hx-toast-stack.d.ts.map +1 -0
  230. package/dist/components/hx-toast/hx-toast.d.ts +1 -53
  231. package/dist/components/hx-toast/hx-toast.d.ts.map +1 -1
  232. package/dist/components/hx-toast/index.d.ts +6 -2
  233. package/dist/components/hx-toast/index.d.ts.map +1 -1
  234. package/dist/components/hx-toast/index.js +1 -1
  235. package/dist/components/hx-toast/toast-factory.d.ts +25 -0
  236. package/dist/components/hx-toast/toast-factory.d.ts.map +1 -0
  237. package/dist/components/hx-toggle-button/hx-toggle-button.d.ts +2 -1
  238. package/dist/components/hx-toggle-button/hx-toggle-button.d.ts.map +1 -1
  239. package/dist/components/hx-toggle-button/index.js +1 -1
  240. package/dist/components/hx-tooltip/hx-tooltip.d.ts +2 -46
  241. package/dist/components/hx-tooltip/hx-tooltip.d.ts.map +1 -1
  242. package/dist/components/hx-tooltip/index.js +1 -1
  243. package/dist/components/hx-top-nav/hx-top-nav.d.ts +1 -1
  244. package/dist/components/hx-top-nav/hx-top-nav.d.ts.map +1 -1
  245. package/dist/components/hx-top-nav/index.js +1 -1
  246. package/dist/components/hx-tree-view/hx-tree-item.d.ts +51 -1
  247. package/dist/components/hx-tree-view/hx-tree-item.d.ts.map +1 -1
  248. package/dist/components/hx-tree-view/hx-tree-view.d.ts +16 -1
  249. package/dist/components/hx-tree-view/hx-tree-view.d.ts.map +1 -1
  250. package/dist/components/hx-tree-view/index.js +1 -1
  251. package/dist/components/hx-visually-hidden/hx-visually-hidden.d.ts +1 -1
  252. package/dist/index.d.ts +20 -2
  253. package/dist/index.d.ts.map +1 -1
  254. package/dist/index.js +168 -154
  255. package/dist/index.js.map +1 -1
  256. package/dist/shared/body-scroll-lock-VBa5TFP-.js +12 -0
  257. package/dist/shared/body-scroll-lock-VBa5TFP-.js.map +1 -0
  258. package/dist/shared/dev-warn-YlwPHjtX.js +6 -0
  259. package/dist/shared/dev-warn-YlwPHjtX.js.map +1 -0
  260. package/dist/shared/{hx-accordion-D95XSAft.js → hx-accordion-Cyswa6J3.js} +46 -43
  261. package/dist/shared/hx-accordion-Cyswa6J3.js.map +1 -0
  262. package/dist/shared/{hx-action-bar-B4i9tBCP.js → hx-action-bar-we_WJety.js} +41 -40
  263. package/dist/shared/hx-action-bar-we_WJety.js.map +1 -0
  264. package/dist/shared/{hx-alert-BQpT4gL3.js → hx-alert-Cg-zxRiU.js} +2 -2
  265. package/dist/shared/hx-alert-Cg-zxRiU.js.map +1 -0
  266. package/dist/shared/{hx-avatar-yHjmNdtf.js → hx-avatar-Cep6Urm3.js} +62 -65
  267. package/dist/shared/hx-avatar-Cep6Urm3.js.map +1 -0
  268. package/dist/shared/hx-banner-lxAIJ2kR.js +349 -0
  269. package/dist/shared/hx-banner-lxAIJ2kR.js.map +1 -0
  270. package/dist/shared/{hx-breadcrumb-item-DtSxRZ_W.js → hx-breadcrumb-item-C0rz0fzV.js} +46 -44
  271. package/dist/shared/hx-breadcrumb-item-C0rz0fzV.js.map +1 -0
  272. package/dist/shared/{hx-button-CtiJsmOg.js → hx-button-Cbhqpm5i.js} +111 -28
  273. package/dist/shared/hx-button-Cbhqpm5i.js.map +1 -0
  274. package/dist/shared/{hx-button-group-BMV5qFs4.js → hx-button-group-CWjWv-wS.js} +10 -10
  275. package/dist/shared/hx-button-group-CWjWv-wS.js.map +1 -0
  276. package/dist/shared/{hx-card-DAkEfpJd.js → hx-card-Bg4W4uXC.js} +16 -16
  277. package/dist/shared/hx-card-Bg4W4uXC.js.map +1 -0
  278. package/dist/shared/{hx-carousel-item-C2yBnM0r.js → hx-carousel-item-BKpmFbUT.js} +101 -63
  279. package/dist/shared/hx-carousel-item-BKpmFbUT.js.map +1 -0
  280. package/dist/shared/hx-checkbox-BMayOpAM.js.map +1 -1
  281. package/dist/shared/{hx-checkbox-group-DTS9iT4b.js → hx-checkbox-group-ydUdV9Sx.js} +7 -7
  282. package/dist/shared/hx-checkbox-group-ydUdV9Sx.js.map +1 -0
  283. package/dist/shared/{hx-code-snippet-DdEqy-1B.js → hx-code-snippet-B4hV7rWG.js} +65 -53
  284. package/dist/shared/hx-code-snippet-B4hV7rWG.js.map +1 -0
  285. package/dist/shared/{hx-color-picker-K2x_dyeG.js → hx-color-picker-BvfJ_h16.js} +100 -90
  286. package/dist/shared/hx-color-picker-BvfJ_h16.js.map +1 -0
  287. package/dist/shared/{hx-combobox-DjMigccw.js → hx-combobox-BBi3izKJ.js} +80 -44
  288. package/dist/shared/hx-combobox-BBi3izKJ.js.map +1 -0
  289. package/dist/shared/hx-container-DLUKnTi9.js.map +1 -1
  290. package/dist/shared/{hx-copy-button-BXL1xkxb.js → hx-copy-button-CLBA31to.js} +45 -50
  291. package/dist/shared/hx-copy-button-CLBA31to.js.map +1 -0
  292. package/dist/shared/hx-counter-D-1NXzGs.js +138 -0
  293. package/dist/shared/hx-counter-D-1NXzGs.js.map +1 -0
  294. package/dist/shared/{hx-data-table-D3NZvc3P.js → hx-data-table-DNiDVWR2.js} +100 -95
  295. package/dist/shared/hx-data-table-DNiDVWR2.js.map +1 -0
  296. package/dist/shared/{hx-date-picker-CIHwx9b3.js → hx-date-picker-D7yCK0nk.js} +17 -12
  297. package/dist/shared/hx-date-picker-D7yCK0nk.js.map +1 -0
  298. package/dist/shared/{hx-dialog-e4CSD8xX.js → hx-dialog-Z7Ou_AZ9.js} +37 -36
  299. package/dist/shared/hx-dialog-Z7Ou_AZ9.js.map +1 -0
  300. package/dist/shared/hx-divider-XgWIz4Mr.js.map +1 -1
  301. package/dist/shared/{hx-drawer-bTF0nbrg.js → hx-drawer-Dk-_xzy0.js} +59 -58
  302. package/dist/shared/hx-drawer-Dk-_xzy0.js.map +1 -0
  303. package/dist/shared/hx-dropdown-DnjLnkTj.js.map +1 -1
  304. package/dist/shared/{hx-field-Dz-7M_SC.js → hx-field-CDP8EXuj.js} +22 -19
  305. package/dist/shared/hx-field-CDP8EXuj.js.map +1 -0
  306. package/dist/shared/{hx-file-upload-DnYiIhyN.js → hx-file-upload-CUORgnKc.js} +17 -14
  307. package/dist/shared/hx-file-upload-CUORgnKc.js.map +1 -0
  308. package/dist/shared/{hx-form-BJeLK34m.js → hx-form-BFv_N1dm.js} +9 -1
  309. package/dist/shared/{hx-form-BJeLK34m.js.map → hx-form-BFv_N1dm.js.map} +1 -1
  310. package/dist/shared/hx-help-text-DaOPN1iB.js.map +1 -1
  311. package/dist/shared/{hx-icon-button-C_fsUJW4.js → hx-icon-button-C83bCR0K.js} +2 -4
  312. package/dist/shared/hx-icon-button-C83bCR0K.js.map +1 -0
  313. package/dist/shared/{hx-list-CF-AAnp-.js → hx-list-CdRNgeoP.js} +7 -9
  314. package/dist/shared/{hx-list-CF-AAnp-.js.map → hx-list-CdRNgeoP.js.map} +1 -1
  315. package/dist/shared/{hx-menu-divider-Buc5XA9E.js → hx-menu-divider-11Dp2VfM.js} +50 -48
  316. package/dist/shared/hx-menu-divider-11Dp2VfM.js.map +1 -0
  317. package/dist/shared/{hx-meter-qcXl0zCL.js → hx-meter-UinDQjl6.js} +43 -37
  318. package/dist/shared/hx-meter-UinDQjl6.js.map +1 -0
  319. package/dist/shared/{hx-nav-CWwByFdq.js → hx-nav-DSpwWYUX.js} +81 -81
  320. package/dist/shared/hx-nav-DSpwWYUX.js.map +1 -0
  321. package/dist/shared/{hx-nav-item-DItaMWl0.js → hx-nav-item-D54-5eUM.js} +12 -12
  322. package/dist/shared/hx-nav-item-D54-5eUM.js.map +1 -0
  323. package/dist/shared/{hx-number-input-CS6_w1lT.js → hx-number-input-BP6TIA92.js} +5 -1
  324. package/dist/shared/hx-number-input-BP6TIA92.js.map +1 -0
  325. package/dist/shared/{hx-overflow-menu-CAS1Mlus.js → hx-overflow-menu-C7k5wlZy.js} +39 -34
  326. package/dist/shared/hx-overflow-menu-C7k5wlZy.js.map +1 -0
  327. package/dist/shared/{hx-pagination-DNFgXQm3.js → hx-pagination-BQ0cLTuB.js} +65 -62
  328. package/dist/shared/hx-pagination-BQ0cLTuB.js.map +1 -0
  329. package/dist/shared/{hx-popover-BjAyLbzp.js → hx-popover-BQsgrJCW.js} +7 -7
  330. package/dist/shared/hx-popover-BQsgrJCW.js.map +1 -0
  331. package/dist/shared/{hx-progress-bar-b3_m1hna.js → hx-progress-bar-C_mdPVF-.js} +61 -52
  332. package/dist/shared/hx-progress-bar-C_mdPVF-.js.map +1 -0
  333. package/dist/shared/{hx-progress-ring-wOSv2y_I.js → hx-progress-ring-BHJBaXNk.js} +2 -4
  334. package/dist/shared/hx-progress-ring-BHJBaXNk.js.map +1 -0
  335. package/dist/shared/{hx-radio-CGtFKls2.js → hx-radio-Bqyi8re3.js} +44 -12
  336. package/dist/shared/hx-radio-Bqyi8re3.js.map +1 -0
  337. package/dist/shared/{hx-rating-C4kTOyHF.js → hx-rating-Y_t7Z4qb.js} +104 -67
  338. package/dist/shared/hx-rating-Y_t7Z4qb.js.map +1 -0
  339. package/dist/shared/{hx-select-D9bYJcDv.js → hx-select-BBae2LqN.js} +16 -10
  340. package/dist/shared/hx-select-BBae2LqN.js.map +1 -0
  341. package/dist/shared/{hx-slider-Duzmuid9.js → hx-slider-CpnxH2UP.js} +9 -5
  342. package/dist/shared/{hx-slider-Duzmuid9.js.map → hx-slider-CpnxH2UP.js.map} +1 -1
  343. package/dist/shared/{hx-split-button-DhncgAtZ.js → hx-split-button-BvwoG8h2.js} +14 -13
  344. package/dist/shared/hx-split-button-BvwoG8h2.js.map +1 -0
  345. package/dist/shared/hx-split-panel-Cxkeauwe.js.map +1 -1
  346. package/dist/shared/hx-stat-C2wfph8W.js +212 -0
  347. package/dist/shared/hx-stat-C2wfph8W.js.map +1 -0
  348. package/dist/shared/{hx-step-nMT0fHEn.js → hx-step-DYoIumpR.js} +29 -29
  349. package/dist/shared/hx-step-DYoIumpR.js.map +1 -0
  350. package/dist/shared/{hx-structured-list-CMja1VXz.js → hx-structured-list-CMWllxGg.js} +23 -17
  351. package/dist/shared/{hx-structured-list-CMja1VXz.js.map → hx-structured-list-CMWllxGg.js.map} +1 -1
  352. package/dist/shared/{hx-switch-BPvIcDpM.js → hx-switch-DkKchcuP.js} +8 -3
  353. package/dist/shared/{hx-switch-BPvIcDpM.js.map → hx-switch-DkKchcuP.js.map} +1 -1
  354. package/dist/shared/{hx-tab-panel-C7h5lRpw.js → hx-tab-panel-CHB0u1zF.js} +91 -85
  355. package/dist/shared/hx-tab-panel-CHB0u1zF.js.map +1 -0
  356. package/dist/shared/hx-td-CVwCGBYf.js +604 -0
  357. package/dist/shared/hx-td-CVwCGBYf.js.map +1 -0
  358. package/dist/shared/{hx-text-input-BUMgOQHX.js → hx-text-input-BrCjo4fJ.js} +5 -1
  359. package/dist/shared/hx-text-input-BrCjo4fJ.js.map +1 -0
  360. package/dist/shared/{hx-textarea-B_nmxzhC.js → hx-textarea-BsQdB1Rk.js} +51 -18
  361. package/dist/shared/hx-textarea-BsQdB1Rk.js.map +1 -0
  362. package/dist/shared/{hx-time-picker-a-BCkecJ.js → hx-time-picker-DRRAFuVd.js} +62 -54
  363. package/dist/shared/hx-time-picker-DRRAFuVd.js.map +1 -0
  364. package/dist/shared/{hx-toggle-button--xCXWRJW.js → hx-toggle-button-D4F1soEM.js} +34 -22
  365. package/dist/shared/{hx-toggle-button--xCXWRJW.js.map → hx-toggle-button-D4F1soEM.js.map} +1 -1
  366. package/dist/shared/{hx-tooltip-DN6lMlP5.js → hx-tooltip-Bk1iQRHs.js} +23 -23
  367. package/dist/shared/hx-tooltip-Bk1iQRHs.js.map +1 -0
  368. package/dist/shared/{hx-top-nav-8lDKNZUj.js → hx-top-nav-DzW7XLv-.js} +42 -29
  369. package/dist/shared/{hx-top-nav-8lDKNZUj.js.map → hx-top-nav-DzW7XLv-.js.map} +1 -1
  370. package/dist/shared/{hx-tree-item-Cesh_du5.js → hx-tree-item-DdH6RbMs.js} +170 -111
  371. package/dist/shared/hx-tree-item-DdH6RbMs.js.map +1 -0
  372. package/dist/shared/{hx-toast-ikwh9Y03.js → toast-factory-B8jicczW.js} +69 -66
  373. package/dist/shared/toast-factory-B8jicczW.js.map +1 -0
  374. package/dist/tools/cem-a11y-analyzer/analyzers/aria-analyzer.d.ts +12 -0
  375. package/dist/tools/cem-a11y-analyzer/analyzers/aria-analyzer.d.ts.map +1 -0
  376. package/dist/tools/cem-a11y-analyzer/analyzers/focus-analyzer.d.ts +13 -0
  377. package/dist/tools/cem-a11y-analyzer/analyzers/focus-analyzer.d.ts.map +1 -0
  378. package/dist/tools/cem-a11y-analyzer/analyzers/form-analyzer.d.ts +13 -0
  379. package/dist/tools/cem-a11y-analyzer/analyzers/form-analyzer.d.ts.map +1 -0
  380. package/dist/tools/cem-a11y-analyzer/analyzers/keyboard-analyzer.d.ts +12 -0
  381. package/dist/tools/cem-a11y-analyzer/analyzers/keyboard-analyzer.d.ts.map +1 -0
  382. package/dist/tools/cem-a11y-analyzer/analyzers/label-analyzer.d.ts +13 -0
  383. package/dist/tools/cem-a11y-analyzer/analyzers/label-analyzer.d.ts.map +1 -0
  384. package/dist/tools/cem-a11y-analyzer/analyzers/motion-analyzer.d.ts +12 -0
  385. package/dist/tools/cem-a11y-analyzer/analyzers/motion-analyzer.d.ts.map +1 -0
  386. package/dist/tools/cem-a11y-analyzer/index.d.ts +14 -0
  387. package/dist/tools/cem-a11y-analyzer/index.d.ts.map +1 -0
  388. package/dist/tools/cem-a11y-analyzer/reporter.d.ts +6 -0
  389. package/dist/tools/cem-a11y-analyzer/reporter.d.ts.map +1 -0
  390. package/dist/tools/cem-a11y-analyzer/scorer.d.ts +22 -0
  391. package/dist/tools/cem-a11y-analyzer/scorer.d.ts.map +1 -0
  392. package/dist/tools/cem-a11y-analyzer/types.d.ts +171 -0
  393. package/dist/tools/cem-a11y-analyzer/types.d.ts.map +1 -0
  394. package/dist/utils/body-scroll-lock.d.ts +34 -0
  395. package/dist/utils/body-scroll-lock.d.ts.map +1 -0
  396. package/dist/utils/dev-warn.d.ts +19 -0
  397. package/dist/utils/dev-warn.d.ts.map +1 -0
  398. package/package.json +33 -27
  399. package/dist/shared/hx-accordion-D95XSAft.js.map +0 -1
  400. package/dist/shared/hx-action-bar-B4i9tBCP.js.map +0 -1
  401. package/dist/shared/hx-alert-BQpT4gL3.js.map +0 -1
  402. package/dist/shared/hx-avatar-yHjmNdtf.js.map +0 -1
  403. package/dist/shared/hx-breadcrumb-item-DtSxRZ_W.js.map +0 -1
  404. package/dist/shared/hx-button-CtiJsmOg.js.map +0 -1
  405. package/dist/shared/hx-button-group-BMV5qFs4.js.map +0 -1
  406. package/dist/shared/hx-card-DAkEfpJd.js.map +0 -1
  407. package/dist/shared/hx-carousel-item-C2yBnM0r.js.map +0 -1
  408. package/dist/shared/hx-checkbox-group-DTS9iT4b.js.map +0 -1
  409. package/dist/shared/hx-code-snippet-DdEqy-1B.js.map +0 -1
  410. package/dist/shared/hx-color-picker-K2x_dyeG.js.map +0 -1
  411. package/dist/shared/hx-combobox-DjMigccw.js.map +0 -1
  412. package/dist/shared/hx-copy-button-BXL1xkxb.js.map +0 -1
  413. package/dist/shared/hx-data-table-D3NZvc3P.js.map +0 -1
  414. package/dist/shared/hx-date-picker-CIHwx9b3.js.map +0 -1
  415. package/dist/shared/hx-dialog-e4CSD8xX.js.map +0 -1
  416. package/dist/shared/hx-drawer-bTF0nbrg.js.map +0 -1
  417. package/dist/shared/hx-field-Dz-7M_SC.js.map +0 -1
  418. package/dist/shared/hx-file-upload-DnYiIhyN.js.map +0 -1
  419. package/dist/shared/hx-icon-button-C_fsUJW4.js.map +0 -1
  420. package/dist/shared/hx-menu-divider-Buc5XA9E.js.map +0 -1
  421. package/dist/shared/hx-meter-qcXl0zCL.js.map +0 -1
  422. package/dist/shared/hx-nav-CWwByFdq.js.map +0 -1
  423. package/dist/shared/hx-nav-item-DItaMWl0.js.map +0 -1
  424. package/dist/shared/hx-number-input-CS6_w1lT.js.map +0 -1
  425. package/dist/shared/hx-overflow-menu-CAS1Mlus.js.map +0 -1
  426. package/dist/shared/hx-pagination-DNFgXQm3.js.map +0 -1
  427. package/dist/shared/hx-popover-BjAyLbzp.js.map +0 -1
  428. package/dist/shared/hx-progress-bar-b3_m1hna.js.map +0 -1
  429. package/dist/shared/hx-progress-ring-wOSv2y_I.js.map +0 -1
  430. package/dist/shared/hx-radio-CGtFKls2.js.map +0 -1
  431. package/dist/shared/hx-rating-C4kTOyHF.js.map +0 -1
  432. package/dist/shared/hx-select-D9bYJcDv.js.map +0 -1
  433. package/dist/shared/hx-split-button-DhncgAtZ.js.map +0 -1
  434. package/dist/shared/hx-step-nMT0fHEn.js.map +0 -1
  435. package/dist/shared/hx-tab-panel-C7h5lRpw.js.map +0 -1
  436. package/dist/shared/hx-text-input-BUMgOQHX.js.map +0 -1
  437. package/dist/shared/hx-textarea-B_nmxzhC.js.map +0 -1
  438. package/dist/shared/hx-time-picker-a-BCkecJ.js.map +0 -1
  439. package/dist/shared/hx-toast-ikwh9Y03.js.map +0 -1
  440. package/dist/shared/hx-tooltip-DN6lMlP5.js.map +0 -1
  441. package/dist/shared/hx-tree-item-Cesh_du5.js.map +0 -1
@@ -1,4 +1,4 @@
1
- import { css as b, LitElement as g, nothing as c, html as p } from "lit";
1
+ import { css as b, LitElement as g, nothing as p, html as c } from "lit";
2
2
  import { property as l, state as x, query as _, customElement as y } from "lit/decorators.js";
3
3
  import { classMap as w } from "lit/directives/class-map.js";
4
4
  import { ifDefined as v } from "lit/directives/if-defined.js";
@@ -245,7 +245,7 @@ var k = Object.defineProperty, D = Object.getOwnPropertyDescriptor, a = (e, r, i
245
245
  };
246
246
  let I = 0, s = class extends g {
247
247
  constructor() {
248
- super(), this.name = "", this.accept = "", this.maxSize = 0, this.maxFiles = 0, this.multiple = !1, this.label = "", this.disabled = !1, this.error = "", this._files = [], this._dragOver = !1, this._hasFileListSlot = !1, this._baseId = `hx-file-upload-${++I}`, this._labelId = `${this._baseId}-label`, this._errorId = `${this._baseId}-error`, this._dropzoneId = `${this._baseId}-dropzone`, this._liveId = `${this._baseId}-live`, this._internals = this.attachInternals();
248
+ super(), this.name = "", this.accept = "", this.maxSize = 0, this.maxFiles = 0, this.multiple = !1, this.label = "", this.disabled = !1, this.error = "", this.labelDropzone = "Drag files here or click to browse", this._files = [], this._dragOver = !1, this._hasFileListSlot = !1, this._baseId = `hx-file-upload-${++I}`, this._labelId = `${this._baseId}-label`, this._errorId = `${this._baseId}-error`, this._dropzoneId = `${this._baseId}-dropzone`, this._liveId = `${this._baseId}-live`, this._internals = this.attachInternals();
249
249
  }
250
250
  // ─── Slot Handling ───
251
251
  _handleFileListSlotChange(e) {
@@ -449,12 +449,12 @@ let I = 0, s = class extends g {
449
449
  }
450
450
  // ─── Render Helpers ───
451
451
  _renderFileList() {
452
- return this._hasFileListSlot ? c : this._files.length === 0 ? c : p`
452
+ return this._hasFileListSlot ? p : this._files.length === 0 ? p : c`
453
453
  <ul part="file-list" class="file-list" aria-label="Selected files">
454
454
  ${$(
455
455
  this._files,
456
456
  (e) => e.file.name + e.file.size,
457
- (e, r) => p`
457
+ (e, r) => c`
458
458
  <li part="file-item" class="file-item">
459
459
  <div class="file-item__row">
460
460
  <span class="file-item__name" title=${e.file.name}> ${e.file.name} </span>
@@ -506,14 +506,14 @@ let I = 0, s = class extends g {
506
506
  dropzone: !0,
507
507
  "dropzone--drag-over": this._dragOver,
508
508
  "dropzone--error": e
509
- }, i = this.label ? `${this.label} — Drag files here or click to browse` : "Drag files here or click to browse";
510
- return p`
509
+ }, i = this.label ? `${this.label} — ${this.labelDropzone}` : this.labelDropzone;
510
+ return c`
511
511
  <div class="field">
512
- ${this.label ? p`
512
+ ${this.label ? c`
513
513
  <label part="label" class="field__label" id=${this._labelId} for=${this._dropzoneId}>
514
514
  ${this.label}
515
515
  </label>
516
- ` : c}
516
+ ` : p}
517
517
 
518
518
  <div
519
519
  part="dropzone"
@@ -521,9 +521,9 @@ let I = 0, s = class extends g {
521
521
  id=${this._dropzoneId}
522
522
  role="button"
523
523
  tabindex=${this.disabled ? "-1" : "0"}
524
- aria-label=${i}
524
+ aria-label=${v(this.label ? void 0 : i)}
525
525
  aria-labelledby=${v(this.label ? this._labelId : void 0)}
526
- aria-disabled=${this.disabled ? "true" : c}
526
+ aria-disabled=${this.disabled ? "true" : p}
527
527
  aria-describedby=${v(e ? this._errorId : void 0)}
528
528
  @click=${this._handleDropzoneClick}
529
529
  @keydown=${this._handleDropzoneKeyDown}
@@ -531,7 +531,7 @@ let I = 0, s = class extends g {
531
531
  @dragleave=${this._handleDragLeave}
532
532
  @drop=${this._handleDrop}
533
533
  >
534
- <slot>Drag files here or click to browse</slot>
534
+ <slot>${this.labelDropzone}</slot>
535
535
  </div>
536
536
 
537
537
  <input
@@ -548,7 +548,7 @@ let I = 0, s = class extends g {
548
548
  <slot name="file-list" @slotchange=${this._handleFileListSlotChange}></slot>
549
549
 
550
550
  ${this._renderFileList()}
551
- ${e ? p`
551
+ ${e ? c`
552
552
  <div
553
553
  part="error"
554
554
  class="field__error"
@@ -558,7 +558,7 @@ let I = 0, s = class extends g {
558
558
  >
559
559
  ${this.error}
560
560
  </div>
561
- ` : c}
561
+ ` : p}
562
562
 
563
563
  <div id=${this._liveId} class="sr-only" aria-live="assertive" aria-atomic="true">
564
564
  ${this._dragOver ? "File detected. Release to upload." : ""}
@@ -593,6 +593,9 @@ a([
593
593
  a([
594
594
  l({ type: String })
595
595
  ], s.prototype, "error", 2);
596
+ a([
597
+ l({ type: String, attribute: "label-dropzone" })
598
+ ], s.prototype, "labelDropzone", 2);
596
599
  a([
597
600
  x()
598
601
  ], s.prototype, "_files", 2);
@@ -611,4 +614,4 @@ s = a([
611
614
  export {
612
615
  s as H
613
616
  };
614
- //# sourceMappingURL=hx-file-upload-DnYiIhyN.js.map
617
+ //# sourceMappingURL=hx-file-upload-CUORgnKc.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hx-file-upload-CUORgnKc.js","sources":["../../src/components/hx-file-upload/hx-file-upload.styles.ts","../../src/components/hx-file-upload/hx-file-upload.ts"],"sourcesContent":["import { css } from 'lit';\n\nexport const helixFileUploadStyles = 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 .field {\n display: flex;\n flex-direction: column;\n gap: var(--hx-space-2, 0.5rem);\n font-family: var(--hx-font-family-sans, sans-serif);\n }\n\n /* ─── Label ─── */\n\n .field__label {\n display: flex;\n align-items: baseline;\n gap: var(--hx-space-1, 0.25rem);\n font-size: var(--hx-font-size-sm, 0.875rem);\n font-weight: var(--hx-font-weight-medium, 500);\n color: var(--hx-color-neutral-700, #343a40);\n line-height: var(--hx-line-height-normal, 1.5);\n }\n\n /* ─── Dropzone ─── */\n\n .dropzone {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: var(--hx-space-2, 0.5rem);\n min-height: var(--hx-size-32, 8rem);\n padding: var(--hx-space-6, 1.5rem) var(--hx-space-4, 1rem);\n border: var(--hx-border-width-thin, 1px) dashed\n var(--hx-file-upload-dropzone-border-color, var(--hx-color-neutral-300, #ced4da));\n border-radius: var(--hx-file-upload-dropzone-border-radius, var(--hx-border-radius-lg, 0.5rem));\n background-color: var(--hx-file-upload-dropzone-bg, var(--hx-color-neutral-50, #f8f9fa));\n cursor: pointer;\n text-align: center;\n transition:\n border-color var(--hx-transition-fast, 150ms ease),\n background-color var(--hx-transition-fast, 150ms ease),\n box-shadow var(--hx-transition-fast, 150ms ease);\n user-select: none;\n color: var(--hx-color-neutral-600, #495057);\n font-size: var(--hx-font-size-sm, 0.875rem);\n }\n\n .dropzone:focus-visible {\n outline: none;\n border-color: var(--hx-focus-ring-color, #2563eb);\n box-shadow: 0 0 0 var(--hx-focus-ring-width, 2px)\n color-mix(\n in srgb,\n var(--hx-focus-ring-color, #2563eb) calc(var(--hx-focus-ring-opacity, 0.25) * 100%),\n transparent\n );\n }\n\n .dropzone--drag-over {\n border-color: var(--hx-color-primary-500, #2563eb);\n background-color: var(\n --hx-file-upload-dropzone-active-bg,\n color-mix(\n in srgb,\n var(--hx-color-primary-500, #2563eb) 8%,\n var(--hx-color-neutral-0, #ffffff)\n )\n );\n border-style: solid;\n }\n\n .dropzone--error {\n border-color: var(--hx-file-upload-error-color, var(--hx-color-error-500, #dc3545));\n }\n\n @media (prefers-reduced-motion: reduce) {\n .dropzone {\n transition: none;\n }\n }\n\n /* ─── Hidden file input ─── */\n\n .file-input {\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n margin: -1px;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n white-space: nowrap;\n border-width: 0;\n }\n\n /* ─── File list ─── */\n\n .file-list {\n display: flex;\n flex-direction: column;\n gap: var(--hx-space-2, 0.5rem);\n list-style: none;\n margin: 0;\n padding: 0;\n }\n\n .file-list:empty {\n display: none;\n }\n\n /* ─── File item ─── */\n\n .file-item {\n display: flex;\n flex-direction: column;\n gap: var(--hx-space-1, 0.25rem);\n padding: var(--hx-space-2, 0.5rem) var(--hx-space-3, 0.75rem);\n border: var(--hx-border-width-thin, 1px) solid var(--hx-color-neutral-200, #e9ecef);\n border-radius: var(--hx-border-radius-md, 0.375rem);\n background-color: var(--hx-color-neutral-0, #ffffff);\n }\n\n .file-item__row {\n display: flex;\n align-items: center;\n gap: var(--hx-space-2, 0.5rem);\n }\n\n .file-item__name {\n flex: 1;\n font-size: var(--hx-font-size-sm, 0.875rem);\n font-weight: var(--hx-font-weight-medium, 500);\n color: var(--hx-color-neutral-800, #212529);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n .file-item__size {\n flex-shrink: 0;\n font-size: var(--hx-font-size-xs, 0.75rem);\n color: var(--hx-color-neutral-500, #6c757d);\n }\n\n .file-item__remove {\n flex-shrink: 0;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n padding: var(--hx-space-1, 0.25rem);\n border: none;\n border-radius: var(--hx-border-radius-sm, 0.25rem);\n background: transparent;\n color: var(--hx-color-neutral-500, #6c757d);\n cursor: pointer;\n line-height: 1;\n transition:\n color var(--hx-transition-fast, 150ms ease),\n background-color var(--hx-transition-fast, 150ms ease);\n }\n\n .file-item__remove:hover {\n color: var(--hx-file-upload-error-color, var(--hx-color-error-text, #b91c1c));\n background-color: color-mix(in srgb, var(--hx-color-error-500, #dc3545) 8%, transparent);\n }\n\n .file-item__remove:focus-visible {\n outline: var(--hx-focus-ring-width, 2px) solid var(--hx-focus-ring-color, #2563eb);\n outline-offset: 2px;\n }\n\n @media (prefers-reduced-motion: reduce) {\n .file-item__remove {\n transition: none;\n }\n }\n\n /* ─── Progress bar ─── */\n\n .progress-track {\n width: 100%;\n height: 4px;\n background-color: var(--hx-color-neutral-200, #e9ecef);\n border-radius: var(--hx-border-radius-full, 9999px);\n overflow: hidden;\n }\n\n .progress-bar {\n height: 100%;\n background-color: var(--hx-file-upload-progress-color, var(--hx-color-primary-500, #2563eb));\n border-radius: inherit;\n transition: width var(--hx-transition-fast, 150ms ease);\n width: 0%;\n }\n\n @media (prefers-reduced-motion: reduce) {\n .progress-bar {\n transition: none;\n }\n }\n\n /* ─── Screen-reader only utility ─── */\n\n .sr-only {\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n margin: -1px;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n white-space: nowrap;\n border-width: 0;\n }\n\n /* ─── Error message ─── */\n\n .field__error {\n font-size: var(--hx-font-size-xs, 0.75rem);\n color: var(--hx-file-upload-error-color, var(--hx-color-error-text, #b91c1c));\n line-height: var(--hx-line-height-normal, 1.5);\n }\n`;\n","import { LitElement, html, nothing } from 'lit';\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 { repeat } from 'lit/directives/repeat.js';\nimport { tokenStyles } from '@helixui/tokens/lit';\nimport { helixFileUploadStyles } from './hx-file-upload.styles.js';\n\n// Module-level counter for stable, SSR-safe IDs (avoids Math.random() hydration mismatch)\nlet _hxFileUploadIdCounter = 0;\n\ninterface FileEntry {\n file: File;\n progress: number;\n}\n\n/**\n * A drag-and-drop file upload component with client-side validation,\n * file list management, per-file progress, and native form association.\n *\n * @summary Form-associated file upload dropzone with drag-and-drop, validation, and progress tracking.\n *\n * @tag hx-file-upload\n *\n * @slot - Default dropzone content. Replaces the built-in \"Drag files here or click to browse\" prompt.\n * @slot file-list - Custom file list display. When provided, the built-in file list is hidden.\n *\n * @fires {CustomEvent<{files: File[]}>} hx-upload - Dispatched when valid files are selected via drag-and-drop or the file picker.\n * @fires {CustomEvent<{file: File, index: number}>} hx-remove - Dispatched when a file is removed from the list.\n * @fires {CustomEvent<{message: string, files: File[]}>} hx-error - Dispatched when file validation fails (type or size constraint).\n *\n * @csspart dropzone - The drag-and-drop target area.\n * @csspart file-list - The container wrapping the list of selected files.\n * @csspart file-item - An individual file entry in the list.\n * @csspart progress - The progress bar track for a file item.\n * @csspart label - The visible label element.\n * @csspart error - The error message container below the dropzone.\n *\n * @cssprop [--hx-file-upload-dropzone-bg=var(--hx-color-neutral-50)] - Dropzone background color.\n * @cssprop [--hx-file-upload-dropzone-border-color=var(--hx-color-neutral-300)] - Dropzone border color.\n * @cssprop [--hx-file-upload-dropzone-border-radius=var(--hx-border-radius-lg)] - Dropzone border radius.\n * @cssprop [--hx-file-upload-dropzone-active-bg] - Dropzone background when a file is dragged over.\n * @cssprop [--hx-file-upload-progress-color=var(--hx-color-primary-500)] - Progress bar fill color.\n * @cssprop [--hx-file-upload-error-color=var(--hx-color-error-500)] - Error state and remove-button hover color.\n */\n@customElement('hx-file-upload')\nexport class HelixFileUpload extends LitElement {\n static override styles = [tokenStyles, helixFileUploadStyles];\n\n // ─── Form Association ───\n\n /** Marks this element as form-associated for ElementInternals support. @internal */\n static formAssociated = true;\n\n /** Holds the ElementInternals instance used for form value and validity management. @internal */\n private _internals: ElementInternals;\n\n constructor() {\n super();\n this._internals = this.attachInternals();\n }\n\n // ─── Properties ───\n\n /**\n * The form field name used during form submission.\n * @attr name\n */\n @property({ type: String })\n name = '';\n\n /**\n * Accepted file types as a comma-separated list of MIME types or extensions.\n * Mirrors the native `<input type=\"file\" accept>` attribute.\n * @attr accept\n */\n @property({ type: String })\n accept = '';\n\n /**\n * Maximum allowed file size in bytes. 0 means unlimited.\n * @attr max-size\n */\n @property({ type: Number, attribute: 'max-size' })\n maxSize = 0;\n\n /**\n * Maximum number of files that can be selected. 0 means unlimited.\n * @attr max-files\n */\n @property({ type: Number, attribute: 'max-files' })\n maxFiles = 0;\n\n /**\n * Whether multiple files may be selected at once.\n * @attr multiple\n */\n @property({ type: Boolean })\n multiple = false;\n\n /**\n * Visible label text for the dropzone.\n * @attr label\n */\n @property({ type: String })\n label = '';\n\n /**\n * Whether the component is disabled.\n * @attr disabled\n */\n @property({ type: Boolean, reflect: true })\n disabled = false;\n\n /**\n * Error message displayed below the dropzone. Also puts the dropzone in an error visual state.\n * @attr error\n */\n @property({ type: String })\n error = '';\n\n /**\n * Instructional text shown in the dropzone when no custom slot content is provided.\n * Also used as the accessible label for the dropzone.\n * @attr label-dropzone\n */\n @property({ type: String, attribute: 'label-dropzone' })\n labelDropzone = 'Drag files here or click to browse';\n\n // ─── Internal State ───\n\n /** The list of currently selected file entries, each with a file reference and upload progress. @internal */\n @state() private _files: FileEntry[] = [];\n /** Whether a file is currently being dragged over the dropzone. @internal */\n @state() private _dragOver = false;\n /** Whether the named file-list slot contains projected content. @internal */\n @state() private _hasFileListSlot = false;\n\n // ─── Internal References ───\n\n /** Reference to the hidden native file input element used to open the OS file picker. @internal */\n @query('.file-input')\n private _fileInput: HTMLInputElement | null | undefined;\n\n // ─── Stable IDs ───\n\n private readonly _baseId = `hx-file-upload-${++_hxFileUploadIdCounter}`;\n private readonly _labelId = `${this._baseId}-label`;\n private readonly _errorId = `${this._baseId}-error`;\n private readonly _dropzoneId = `${this._baseId}-dropzone`;\n private readonly _liveId = `${this._baseId}-live`;\n\n // ─── Slot Handling ───\n\n private _handleFileListSlotChange(e: Event): void {\n const slot = e.target as HTMLSlotElement;\n this._hasFileListSlot = slot.assignedElements({ flatten: true }).length > 0;\n }\n\n // ─── Lifecycle ───\n\n override updated(changedProperties: Map<string, unknown>): void {\n super.updated(changedProperties);\n if (changedProperties.has('_files') || changedProperties.has('name')) {\n this._syncFormValue();\n }\n }\n\n // ─── Form Integration ───\n\n /** Returns the associated form element, if any. */\n get form(): HTMLFormElement | null {\n return this._internals.form;\n }\n\n /** Returns the validation message. */\n get validationMessage(): string {\n return this._internals.validationMessage;\n }\n\n /** Returns the ValidityState object. */\n get validity(): ValidityState {\n return this._internals.validity;\n }\n\n /** Checks whether the component satisfies its constraints. */\n checkValidity(): boolean {\n return this._internals.checkValidity();\n }\n\n /** Reports validity and shows the browser's constraint validation UI. */\n reportValidity(): boolean {\n return this._internals.reportValidity();\n }\n\n /** Called by the form when it resets. */\n formResetCallback(): void {\n this._files = [];\n this._internals.setFormValue(null);\n }\n\n private _syncFormValue(): void {\n if (this._files.length === 0) {\n this._internals.setFormValue(null);\n return;\n }\n\n if (this._files.length === 1) {\n // Single file — pass directly as File (accepted by setFormValue)\n const firstEntry = this._files[0];\n if (firstEntry) {\n this._internals.setFormValue(firstEntry.file);\n }\n return;\n }\n\n // Multiple files — use FormData so all files are submitted under the same name\n const formData = new FormData();\n for (const entry of this._files) {\n formData.append(this.name, entry.file, entry.file.name);\n }\n this._internals.setFormValue(formData);\n }\n\n // ─── Validation ───\n\n /**\n * Validates a file against `accept` and `maxSize` constraints.\n * Returns null on success, or an error message string on failure.\n */\n private _validateFile(file: File): string | null {\n if (this.accept) {\n const accepted = this._isAccepted(file);\n if (!accepted) {\n return `\"${file.name}\" has an unsupported file type. Accepted types: ${this.accept}`;\n }\n }\n\n if (this.maxSize > 0 && file.size > this.maxSize) {\n const maxMb = (this.maxSize / (1024 * 1024)).toFixed(1);\n return `\"${file.name}\" exceeds the maximum size of ${maxMb} MB.`;\n }\n\n return null;\n }\n\n /**\n * Checks whether a file is accepted given the `accept` attribute value.\n * Handles MIME types (e.g. \"image/png\"), wildcard MIME types (e.g. \"image/*\"),\n * and extensions (e.g. \".pdf\").\n */\n private _isAccepted(file: File): boolean {\n const tokens = this.accept.split(',').map((t) => t.trim().toLowerCase());\n\n for (const token of tokens) {\n if (token.startsWith('.')) {\n // Extension match\n if (file.name.toLowerCase().endsWith(token)) return true;\n } else if (token.endsWith('/*')) {\n // Wildcard MIME type e.g. \"image/*\"\n const baseType = token.slice(0, -2);\n if (file.type.toLowerCase().startsWith(baseType)) return true;\n } else {\n // Exact MIME type\n if (file.type.toLowerCase() === token) return true;\n }\n }\n\n return false;\n }\n\n // ─── File Processing ───\n\n private _processFiles(rawFiles: File[]): void {\n if (this.disabled) return;\n\n const candidateFiles = this.multiple ? rawFiles : rawFiles.slice(0, 1);\n const validFiles: File[] = [];\n const invalidFiles: File[] = [];\n const errorMessages: string[] = [];\n\n for (const file of candidateFiles) {\n const validationError = this._validateFile(file);\n if (validationError) {\n invalidFiles.push(file);\n errorMessages.push(validationError);\n } else {\n validFiles.push(file);\n }\n }\n\n if (invalidFiles.length > 0) {\n this.dispatchEvent(\n new CustomEvent('hx-error', {\n bubbles: true,\n composed: true,\n detail: { message: errorMessages.join(' '), files: invalidFiles },\n }),\n );\n }\n\n if (validFiles.length === 0) return;\n\n // Enforce maxFiles limit (only in multiple mode — single-file mode always replaces)\n const currentCount = this.multiple ? this._files.length : 0;\n const capacity =\n this.maxFiles > 0 ? Math.max(0, this.maxFiles - currentCount) : validFiles.length;\n const allowedFiles = validFiles.slice(0, capacity);\n\n if (allowedFiles.length === 0 && this.maxFiles > 0) {\n this.dispatchEvent(\n new CustomEvent('hx-error', {\n bubbles: true,\n composed: true,\n detail: {\n message: `Maximum of ${this.maxFiles} file${this.maxFiles === 1 ? '' : 's'} allowed.`,\n files: validFiles,\n },\n }),\n );\n return;\n }\n\n if (allowedFiles.length > 0) {\n const newEntries: FileEntry[] = allowedFiles.map((file) => ({ file, progress: 0 }));\n\n if (this.multiple) {\n this._files = [...this._files, ...newEntries];\n } else {\n this._files = newEntries;\n }\n\n this.dispatchEvent(\n new CustomEvent('hx-upload', {\n bubbles: true,\n composed: true,\n detail: { files: allowedFiles },\n }),\n );\n }\n\n // If remaining valid files were cut by maxFiles, report that too\n const overflow = validFiles.slice(capacity);\n if (overflow.length > 0 && this.maxFiles > 0) {\n this.dispatchEvent(\n new CustomEvent('hx-error', {\n bubbles: true,\n composed: true,\n detail: {\n message: `Maximum of ${this.maxFiles} file${this.maxFiles === 1 ? '' : 's'} allowed. ${overflow.length} file${overflow.length === 1 ? ' was' : 's were'} not added.`,\n files: overflow,\n },\n }),\n );\n }\n }\n\n // ─── Public Methods ───\n\n /**\n * Sets the upload progress for a file at the given index.\n * @param index - Zero-based index into the current file list.\n * @param percent - Progress percentage from 0 to 100.\n */\n setProgress(index: number, percent: number): void {\n if (index < 0 || index >= this._files.length) return;\n const clamped = Math.max(0, Math.min(100, percent));\n this._files = this._files.map((entry, i) =>\n i === index ? { ...entry, progress: clamped } : entry,\n );\n }\n\n /**\n * Returns a read-only copy of the currently selected files.\n */\n get files(): File[] {\n return this._files.map((e) => e.file);\n }\n\n // ─── Drag and Drop Handlers ───\n\n private _handleDragOver(e: DragEvent): void {\n e.preventDefault();\n if (this.disabled) return;\n this._dragOver = true;\n }\n\n private _handleDragLeave(e: DragEvent): void {\n // Only clear drag state when leaving the dropzone entirely\n const target = e.relatedTarget as Node | null;\n if (target && this.contains(target)) return;\n const dropzone = this.shadowRoot?.querySelector('.dropzone');\n if (dropzone && dropzone.contains(target)) return;\n this._dragOver = false;\n }\n\n private _handleDrop(e: DragEvent): void {\n e.preventDefault();\n this._dragOver = false;\n if (this.disabled) return;\n\n const dt = e.dataTransfer;\n if (!dt) return;\n\n const rawFiles = Array.from(dt.files);\n if (rawFiles.length === 0) return;\n\n this._processFiles(rawFiles);\n }\n\n // ─── Click / Keyboard Handlers ───\n\n private _handleDropzoneClick(): void {\n if (this.disabled) return;\n this._fileInput?.click();\n }\n\n private _handleDropzoneKeyDown(e: KeyboardEvent): void {\n if (this.disabled) return;\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n this._fileInput?.click();\n }\n }\n\n private _handleFileInputChange(e: Event): void {\n const input = e.target as HTMLInputElement;\n if (!input.files || input.files.length === 0) return;\n\n const rawFiles = Array.from(input.files);\n // Reset the input so the same file can be re-selected after removal\n input.value = '';\n this._processFiles(rawFiles);\n }\n\n // ─── Remove Handler ───\n\n private _handleRemove(index: number): void {\n if (this.disabled) return;\n const entry = this._files[index];\n if (!entry) return;\n\n const removedFile = entry.file;\n this._files = this._files.filter((_, i) => i !== index);\n\n this.dispatchEvent(\n new CustomEvent('hx-remove', {\n bubbles: true,\n composed: true,\n detail: { file: removedFile, index },\n }),\n );\n }\n\n // ─── Formatters ───\n\n private _formatSize(bytes: number): string {\n if (bytes < 1024) return `${bytes} B`;\n if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;\n return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;\n }\n\n // ─── Render Helpers ───\n\n private _renderFileList() {\n if (this._hasFileListSlot) return nothing;\n if (this._files.length === 0) return nothing;\n\n return html`\n <ul part=\"file-list\" class=\"file-list\" aria-label=\"Selected files\">\n ${repeat(\n this._files,\n (entry) => entry.file.name + entry.file.size,\n (entry, index) => html`\n <li part=\"file-item\" class=\"file-item\">\n <div class=\"file-item__row\">\n <span class=\"file-item__name\" title=${entry.file.name}> ${entry.file.name} </span>\n <span class=\"file-item__size\">${this._formatSize(entry.file.size)}</span>\n <button\n type=\"button\"\n class=\"file-item__remove\"\n aria-label=${`Remove ${entry.file.name}`}\n @click=${() => this._handleRemove(index)}\n >\n <svg\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 14 14\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n aria-hidden=\"true\"\n focusable=\"false\"\n >\n <path\n d=\"M1 1L13 13M13 1L1 13\"\n stroke=\"currentColor\"\n stroke-width=\"1.75\"\n stroke-linecap=\"round\"\n />\n </svg>\n </button>\n </div>\n <div\n part=\"progress\"\n class=\"progress-track\"\n role=\"progressbar\"\n aria-valuenow=${entry.progress}\n aria-valuemin=\"0\"\n aria-valuemax=\"100\"\n aria-label=${`Upload progress for ${entry.file.name}: ${entry.progress}%`}\n >\n <div class=\"progress-bar\" style=\"width: ${entry.progress}%\"></div>\n </div>\n </li>\n `,\n )}\n </ul>\n `;\n }\n\n // ─── Render ───\n\n override render() {\n const hasError = !!this.error;\n\n const dropzoneClasses = {\n dropzone: true,\n 'dropzone--drag-over': this._dragOver,\n 'dropzone--error': hasError,\n };\n\n const dropzoneLabel = this.label ? `${this.label} — ${this.labelDropzone}` : this.labelDropzone;\n\n return html`\n <div class=\"field\">\n ${this.label\n ? html`\n <label part=\"label\" class=\"field__label\" id=${this._labelId} for=${this._dropzoneId}>\n ${this.label}\n </label>\n `\n : nothing}\n\n <div\n part=\"dropzone\"\n class=${classMap(dropzoneClasses)}\n id=${this._dropzoneId}\n role=\"button\"\n tabindex=${this.disabled ? '-1' : '0'}\n aria-label=${ifDefined(!this.label ? dropzoneLabel : undefined)}\n aria-labelledby=${ifDefined(this.label ? this._labelId : undefined)}\n aria-disabled=${this.disabled ? 'true' : nothing}\n aria-describedby=${ifDefined(hasError ? this._errorId : undefined)}\n @click=${this._handleDropzoneClick}\n @keydown=${this._handleDropzoneKeyDown}\n @dragover=${this._handleDragOver}\n @dragleave=${this._handleDragLeave}\n @drop=${this._handleDrop}\n >\n <slot>${this.labelDropzone}</slot>\n </div>\n\n <input\n class=\"file-input\"\n type=\"file\"\n tabindex=\"-1\"\n aria-hidden=\"true\"\n accept=${ifDefined(this.accept || undefined)}\n ?multiple=${this.multiple}\n ?disabled=${this.disabled}\n @change=${this._handleFileInputChange}\n />\n\n <slot name=\"file-list\" @slotchange=${this._handleFileListSlotChange}></slot>\n\n ${this._renderFileList()}\n ${hasError\n ? html`\n <div\n part=\"error\"\n class=\"field__error\"\n id=${this._errorId}\n role=\"alert\"\n aria-live=\"polite\"\n >\n ${this.error}\n </div>\n `\n : nothing}\n\n <div id=${this._liveId} class=\"sr-only\" aria-live=\"assertive\" aria-atomic=\"true\">\n ${this._dragOver ? 'File detected. Release to upload.' : ''}\n </div>\n </div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'hx-file-upload': HelixFileUpload;\n }\n}\n"],"names":["helixFileUploadStyles","css","_hxFileUploadIdCounter","HelixFileUpload","LitElement","slot","changedProperties","firstEntry","formData","entry","file","maxMb","tokens","t","token","baseType","rawFiles","candidateFiles","validFiles","invalidFiles","errorMessages","validationError","currentCount","capacity","allowedFiles","newEntries","overflow","index","percent","clamped","i","target","dropzone","_a","dt","input","removedFile","_","bytes","nothing","html","repeat","hasError","dropzoneClasses","dropzoneLabel","classMap","ifDefined","tokenStyles","__decorateClass","property","state","query","customElement"],"mappings":";;;;;;AAEO,MAAMA,IAAwBC;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;;;;;;ACOrC,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"}
@@ -1162,6 +1162,7 @@ let i = class extends l {
1162
1162
  /**
1163
1163
  * Returns all elements that support constraint validation, including
1164
1164
  * both native form elements and hx-* components with `checkValidity`.
1165
+ * @internal
1165
1166
  */
1166
1167
  _getAllValidatableElements() {
1167
1168
  const e = Array.from(this.querySelectorAll("input, select, textarea")), r = this.getFormElements().filter(
@@ -1171,6 +1172,7 @@ let i = class extends l {
1171
1172
  }
1172
1173
  /**
1173
1174
  * Sets `aria-invalid="true"` on fields with errors, removes it from valid fields.
1175
+ * @internal
1174
1176
  */
1175
1177
  _applyAriaInvalidFromErrors(e) {
1176
1178
  const r = new Set(e.map((n) => n.name)), o = this._getAllValidatableElements();
@@ -1181,6 +1183,7 @@ let i = class extends l {
1181
1183
  }
1182
1184
  /**
1183
1185
  * Sets `aria-invalid` based on native constraint validation state.
1186
+ * @internal
1184
1187
  */
1185
1188
  _applyAriaInvalidFromValidity() {
1186
1189
  const e = this._getAllValidatableElements();
@@ -1189,12 +1192,17 @@ let i = class extends l {
1189
1192
  }
1190
1193
  /**
1191
1194
  * Removes `aria-invalid` from all validatable elements.
1195
+ * @internal
1192
1196
  */
1193
1197
  _clearAriaInvalid() {
1194
1198
  const e = this._getAllValidatableElements();
1195
1199
  for (const r of e)
1196
1200
  r.removeAttribute("aria-invalid");
1197
1201
  }
1202
+ /**
1203
+ * Collects constraint validation errors from all validatable elements after a failed submit attempt.
1204
+ * @internal
1205
+ */
1198
1206
  _collectValidationErrors() {
1199
1207
  const e = [], r = this._getAllValidatableElements();
1200
1208
  for (const o of r)
@@ -1261,4 +1269,4 @@ i = a([
1261
1269
  export {
1262
1270
  i as H
1263
1271
  };
1264
- //# sourceMappingURL=hx-form-BJeLK34m.js.map
1272
+ //# sourceMappingURL=hx-form-BFv_N1dm.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"hx-form-BJeLK34m.js","sources":["../../src/styles/form/form.scoped.css?raw","../../src/components/hx-form/hx-form.styles.ts","../../src/components/hx-form/hx-form.ts"],"sourcesContent":["export default \"/* ==========================================================================\\n * form.scoped.css — Scoped barrel file\\n *\\n * Contains all form styles with every selector prefixed by `hx-form` to\\n * prevent leaking outside the <hx-form> Light DOM wrapper.\\n *\\n * IMPORTANT: This file does NOT use @import because CSS imports cannot\\n * add scope prefixes. All styles are written inline.\\n * ==========================================================================\\n */\\n\\n/* ==========================================================================\\n * HOST / FORM ROOT TOKENS\\n * ========================================================================== */\\n\\nhx-form {\\n display: flex;\\n flex-direction: column;\\n gap: var(--hx-form-gap, var(--hx-space-4, 1rem));\\n max-width: var(--hx-form-max-width, none);\\n padding: var(--hx-form-padding, 0);\\n}\\n\\n/* ==========================================================================\\n * ERROR SUMMARY\\n * ========================================================================== */\\n\\nhx-form .hx-form-error-summary {\\n border: var(--hx-border-width-thin, 1px) solid\\n var(--hx-input-error-color, var(--hx-color-error-500, #dc3545));\\n border-radius: var(--hx-border-radius-md, 0.375rem);\\n background-color: var(--hx-color-error-50, #fef2f2);\\n color: var(--hx-input-error-color, var(--hx-color-error-500, #dc3545));\\n padding: var(--hx-space-3, 0.75rem) var(--hx-space-4, 1rem);\\n font-size: var(--hx-font-size-sm, 0.875rem);\\n line-height: var(--hx-line-height-normal, 1.5);\\n font-family: var(--hx-input-font-family, var(--hx-font-family-sans, sans-serif));\\n}\\n\\nhx-form .hx-form-error-summary ul {\\n margin: 0;\\n padding: 0 0 0 var(--hx-space-4, 1rem);\\n}\\n\\nhx-form .hx-form-error-summary li {\\n margin-bottom: var(--hx-space-1, 0.25rem);\\n}\\n\\nhx-form .hx-form-error-summary li:last-child {\\n margin-bottom: 0;\\n}\\n\\n/* ==========================================================================\\n * FIELD (_field.css scoped)\\n * ========================================================================== */\\n\\n/* ─── Field Container ─── */\\n\\nhx-form .form-item {\\n display: flex;\\n flex-direction: column;\\n gap: var(--hx-space-1, 0.25rem);\\n font-family: var(--hx-input-font-family, var(--hx-font-family-sans, sans-serif));\\n}\\n\\nhx-form .form-item + .form-item {\\n margin-top: var(--hx-space-4, 1rem);\\n}\\n\\n/* ─── Label ─── */\\n\\nhx-form label {\\n display: flex;\\n align-items: baseline;\\n gap: var(--hx-space-1, 0.25rem);\\n font-size: var(--hx-font-size-sm, 0.875rem);\\n font-weight: var(--hx-font-weight-medium, 500);\\n color: var(--hx-input-label-color, var(--hx-color-neutral-700, #343a40));\\n line-height: var(--hx-line-height-normal, 1.5);\\n}\\n\\n/* ─── Required Marker ─── */\\n\\nhx-form .form-required {\\n color: var(--hx-input-error-color, var(--hx-color-error-500, #dc3545));\\n font-weight: var(--hx-font-weight-bold, 700);\\n}\\n\\n/* ─── Description / Help Text ─── */\\n\\nhx-form .description {\\n font-size: var(--hx-font-size-xs, 0.75rem);\\n color: var(--hx-color-neutral-500, #6c757d);\\n line-height: var(--hx-line-height-normal, 1.5);\\n}\\n\\n/* ─── Box Sizing Reset ─── */\\n\\nhx-form .form-item *,\\nhx-form .form-item *::before,\\nhx-form .form-item *::after {\\n box-sizing: border-box;\\n}\\n\\n/* ==========================================================================\\n * TEXT INPUT (_text-input.css scoped)\\n * ========================================================================== */\\n\\nhx-form input[type='text'],\\nhx-form input[type='email'],\\nhx-form input[type='password'],\\nhx-form input[type='tel'],\\nhx-form input[type='url'],\\nhx-form input[type='search'],\\nhx-form input[type='number'] {\\n display: block;\\n width: 100%;\\n border: var(--hx-border-width-thin, 1px) solid\\n var(--hx-input-border-color, var(--hx-color-neutral-300, #ced4da));\\n border-radius: var(--hx-input-border-radius, var(--hx-border-radius-md, 0.375rem));\\n background-color: var(--hx-input-bg, var(--hx-color-neutral-0, #ffffff));\\n padding: var(--hx-space-2, 0.5rem) var(--hx-space-3, 0.75rem);\\n font-family: var(--hx-input-font-family, var(--hx-font-family-sans, sans-serif));\\n font-size: var(--hx-font-size-md, 1rem);\\n color: var(--hx-input-color, var(--hx-color-neutral-800, #212529));\\n line-height: var(--hx-line-height-normal, 1.5);\\n min-height: var(--hx-size-10, 2.5rem);\\n transition:\\n border-color var(--hx-transition-fast, 150ms ease),\\n box-shadow var(--hx-transition-fast, 150ms ease);\\n}\\n\\n/* ─── Placeholder ─── */\\n\\nhx-form input[type='text']::placeholder,\\nhx-form input[type='email']::placeholder,\\nhx-form input[type='password']::placeholder,\\nhx-form input[type='tel']::placeholder,\\nhx-form input[type='url']::placeholder,\\nhx-form input[type='search']::placeholder,\\nhx-form input[type='number']::placeholder {\\n color: var(--hx-color-neutral-400, #adb5bd);\\n}\\n\\n/* ─── Focus State ─── */\\n\\nhx-form input[type='text']:focus,\\nhx-form input[type='email']:focus,\\nhx-form input[type='password']:focus,\\nhx-form input[type='tel']:focus,\\nhx-form input[type='url']:focus,\\nhx-form input[type='search']:focus,\\nhx-form input[type='number']:focus {\\n outline: 0;\\n border-color: var(--hx-input-focus-ring-color, var(--hx-focus-ring-color, #2563eb));\\n box-shadow: 0 0 0 var(--hx-focus-ring-width, 2px)\\n color-mix(\\n in srgb,\\n var(--hx-input-focus-ring-color, var(--hx-focus-ring-color, #2563eb))\\n calc(var(--hx-focus-ring-opacity, 0.25) * 100%),\\n transparent\\n );\\n}\\n\\n@media (forced-colors: active) {\\n hx-form input[type='text']:focus,\\n hx-form input[type='email']:focus,\\n hx-form input[type='password']:focus,\\n hx-form input[type='tel']:focus,\\n hx-form input[type='url']:focus,\\n hx-form input[type='search']:focus,\\n hx-form input[type='number']:focus {\\n outline: var(--hx-focus-ring-width, 2px) solid ButtonText;\\n outline-offset: var(--hx-focus-ring-offset, 2px);\\n }\\n}\\n\\n/* ─── Disabled State ─── */\\n\\nhx-form input[type='text']:disabled,\\nhx-form input[type='email']:disabled,\\nhx-form input[type='password']:disabled,\\nhx-form input[type='tel']:disabled,\\nhx-form input[type='url']:disabled,\\nhx-form input[type='search']:disabled,\\nhx-form input[type='number']:disabled {\\n opacity: var(--hx-opacity-disabled, 0.5);\\n cursor: not-allowed;\\n pointer-events: none;\\n}\\n\\n/* ─── Read-Only State ─── */\\n\\nhx-form input[type='text']:read-only,\\nhx-form input[type='email']:read-only,\\nhx-form input[type='password']:read-only,\\nhx-form input[type='tel']:read-only,\\nhx-form input[type='url']:read-only,\\nhx-form input[type='search']:read-only,\\nhx-form input[type='number']:read-only {\\n background-color: var(--hx-color-neutral-100, #e9ecef);\\n}\\n\\n/* ─── Remove browser search decorations ─── */\\n\\nhx-form input[type='search']::-webkit-search-decoration,\\nhx-form input[type='search']::-webkit-search-cancel-button,\\nhx-form input[type='search']::-webkit-search-results-button,\\nhx-form input[type='search']::-webkit-search-results-decoration {\\n -webkit-appearance: none;\\n}\\n\\n/* ─── Remove number input spinners ─── */\\n\\nhx-form input[type='number']::-webkit-inner-spin-button,\\nhx-form input[type='number']::-webkit-outer-spin-button {\\n -webkit-appearance: none;\\n margin: 0;\\n}\\n\\nhx-form input[type='number'] {\\n appearance: textfield;\\n}\\n\\n/* ==========================================================================\\n * TEXTAREA (_textarea.css scoped)\\n * ========================================================================== */\\n\\nhx-form textarea {\\n display: block;\\n width: 100%;\\n border: var(--hx-border-width-thin, 1px) solid\\n var(--hx-input-border-color, var(--hx-color-neutral-300, #ced4da));\\n border-radius: var(--hx-input-border-radius, var(--hx-border-radius-md, 0.375rem));\\n background-color: var(--hx-input-bg, var(--hx-color-neutral-0, #ffffff));\\n padding: var(--hx-space-2, 0.5rem) var(--hx-space-3, 0.75rem);\\n font-family: var(--hx-input-font-family, var(--hx-font-family-sans, sans-serif));\\n font-size: var(--hx-font-size-md, 1rem);\\n color: var(--hx-input-color, var(--hx-color-neutral-800, #212529));\\n line-height: var(--hx-line-height-normal, 1.5);\\n min-height: var(--hx-textarea-min-height, var(--hx-size-20, 5rem));\\n resize: vertical;\\n transition:\\n border-color var(--hx-transition-fast, 150ms ease),\\n box-shadow var(--hx-transition-fast, 150ms ease);\\n}\\n\\nhx-form textarea::placeholder {\\n color: var(--hx-color-neutral-400, #adb5bd);\\n}\\n\\nhx-form textarea:focus {\\n outline: 0;\\n border-color: var(--hx-input-focus-ring-color, var(--hx-focus-ring-color, #2563eb));\\n box-shadow: 0 0 0 var(--hx-focus-ring-width, 2px)\\n color-mix(\\n in srgb,\\n var(--hx-input-focus-ring-color, var(--hx-focus-ring-color, #2563eb))\\n calc(var(--hx-focus-ring-opacity, 0.25) * 100%),\\n transparent\\n );\\n}\\n\\n@media (forced-colors: active) {\\n hx-form textarea:focus {\\n outline: var(--hx-focus-ring-width, 2px) solid ButtonText;\\n outline-offset: var(--hx-focus-ring-offset, 2px);\\n }\\n}\\n\\nhx-form textarea:disabled {\\n opacity: var(--hx-opacity-disabled, 0.5);\\n cursor: not-allowed;\\n pointer-events: none;\\n}\\n\\nhx-form textarea:read-only {\\n background-color: var(--hx-color-neutral-100, #e9ecef);\\n}\\n\\n/* ==========================================================================\\n * SELECT (_select.css scoped)\\n * ========================================================================== */\\n\\nhx-form select {\\n display: block;\\n width: 100%;\\n border: var(--hx-border-width-thin, 1px) solid\\n var(--hx-select-border-color, var(--hx-color-neutral-300, #ced4da));\\n border-radius: var(--hx-select-border-radius, var(--hx-border-radius-md, 0.375rem));\\n background-color: var(--hx-select-bg, var(--hx-color-neutral-0, #ffffff));\\n padding: var(--hx-space-2, 0.5rem) var(--hx-space-8, 2rem) var(--hx-space-2, 0.5rem)\\n var(--hx-space-3, 0.75rem);\\n font-family: var(--hx-select-font-family, var(--hx-font-family-sans, sans-serif));\\n font-size: var(--hx-font-size-md, 1rem);\\n color: var(--hx-select-color, var(--hx-color-neutral-800, #212529));\\n line-height: var(--hx-line-height-normal, 1.5);\\n min-height: var(--hx-input-height-md, var(--hx-size-10, 2.5rem));\\n cursor: pointer;\\n transition:\\n border-color var(--hx-transition-fast, 150ms ease),\\n box-shadow var(--hx-transition-fast, 150ms ease);\\n appearance: none;\\n -webkit-appearance: none;\\n -moz-appearance: none;\\n background-image: url(\\\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5L6 6.5L11 1.5' stroke='%236c757d' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round' fill='none'/%3E%3C/svg%3E\\\");\\n background-repeat: no-repeat;\\n background-position: right var(--hx-space-3, 0.75rem) center;\\n background-size: 12px 8px;\\n}\\n\\nhx-form select:focus {\\n outline: 0;\\n border-color: var(--hx-select-focus-ring-color, var(--hx-focus-ring-color, #2563eb));\\n box-shadow: 0 0 0 var(--hx-focus-ring-width, 2px)\\n color-mix(\\n in srgb,\\n var(--hx-select-focus-ring-color, var(--hx-focus-ring-color, #2563eb))\\n calc(var(--hx-focus-ring-opacity, 0.25) * 100%),\\n transparent\\n );\\n}\\n\\n@media (forced-colors: active) {\\n hx-form select:focus {\\n outline: var(--hx-focus-ring-width, 2px) solid ButtonText;\\n outline-offset: var(--hx-focus-ring-offset, 2px);\\n }\\n}\\n\\nhx-form select:disabled {\\n opacity: var(--hx-opacity-disabled, 0.5);\\n cursor: not-allowed;\\n pointer-events: none;\\n}\\n\\nhx-form select[multiple] {\\n min-height: var(--hx-size-20, 5rem);\\n padding-right: var(--hx-space-3, 0.75rem);\\n background-image: none;\\n}\\n\\nhx-form select[multiple] option {\\n padding: var(--hx-space-1, 0.25rem) var(--hx-space-2, 0.5rem);\\n}\\n\\nhx-form select::-ms-expand {\\n display: none;\\n}\\n\\n/* ==========================================================================\\n * CHECKBOX (_checkbox.css scoped)\\n * ========================================================================== */\\n\\nhx-form input[type='checkbox'] {\\n appearance: none;\\n -webkit-appearance: none;\\n -moz-appearance: none;\\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 margin: 0;\\n border: var(--hx-border-width-medium, 2px) solid\\n var(--hx-checkbox-border-color, var(--hx-color-neutral-300, #ced4da));\\n border-radius: var(--hx-checkbox-border-radius, var(--hx-border-radius-sm, 0.25rem));\\n background-color: var(--hx-color-neutral-0, #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 cursor: pointer;\\n vertical-align: middle;\\n}\\n\\nhx-form input[type='checkbox']:checked {\\n background-color: var(--hx-checkbox-checked-bg, var(--hx-color-primary-500, #2563eb));\\n border-color: var(--hx-checkbox-checked-border-color, var(--hx-color-primary-500, #2563eb));\\n background-image: url(\\\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none'%3E%3Cpath d='M3.5 8.5L6.5 11.5L12.5 4.5' stroke='%23ffffff' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E\\\");\\n background-repeat: no-repeat;\\n background-position: center;\\n background-size: 100%;\\n}\\n\\nhx-form input[type='checkbox']:indeterminate {\\n background-color: var(--hx-checkbox-checked-bg, var(--hx-color-primary-500, #2563eb));\\n border-color: var(--hx-checkbox-checked-border-color, var(--hx-color-primary-500, #2563eb));\\n background-image: url(\\\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none'%3E%3Cpath d='M4 8H12' stroke='%23ffffff' stroke-width='2' stroke-linecap='round'/%3E%3C/svg%3E\\\");\\n background-repeat: no-repeat;\\n background-position: center;\\n background-size: 100%;\\n}\\n\\nhx-form input[type='checkbox']:focus-visible {\\n outline: var(--hx-focus-ring-width, 2px) solid\\n var(--hx-checkbox-focus-ring-color, var(--hx-focus-ring-color, #2563eb));\\n outline-offset: var(--hx-focus-ring-offset, 2px);\\n}\\n\\nhx-form input[type='checkbox']:hover:not(:disabled) {\\n border-color: var(--hx-color-primary-500, #2563eb);\\n}\\n\\nhx-form input[type='checkbox']:checked:hover:not(:disabled) {\\n filter: brightness(var(--hx-filter-brightness-hover, 0.9));\\n}\\n\\nhx-form input[type='checkbox']:disabled {\\n opacity: var(--hx-opacity-disabled, 0.5);\\n cursor: not-allowed;\\n pointer-events: none;\\n}\\n\\nhx-form .form-type-checkbox,\\nhx-form .form-type-checkbox-toggle {\\n display: flex;\\n align-items: flex-start;\\n gap: var(--hx-space-2, 0.5rem);\\n}\\n\\nhx-form .form-type-checkbox label,\\nhx-form .form-type-checkbox-toggle 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-neutral-700, #343a40));\\n line-height: var(--hx-line-height-normal, 1.5);\\n cursor: pointer;\\n user-select: none;\\n -webkit-user-select: none;\\n}\\n\\n/* ==========================================================================\\n * RADIO (_radio.css scoped)\\n * ========================================================================== */\\n\\nhx-form input[type='radio'] {\\n appearance: none;\\n -webkit-appearance: none;\\n -moz-appearance: none;\\n display: inline-flex;\\n align-items: center;\\n justify-content: center;\\n flex-shrink: 0;\\n width: var(--hx-radio-size, var(--hx-size-5, 1.25rem));\\n height: var(--hx-radio-size, var(--hx-size-5, 1.25rem));\\n margin: 0;\\n border: var(--hx-border-width-medium, 2px) solid\\n var(--hx-radio-border-color, var(--hx-color-neutral-300, #ced4da));\\n border-radius: var(--hx-border-radius-full, 9999px);\\n background-color: var(--hx-color-neutral-0, #ffffff);\\n transition:\\n border-color var(--hx-transition-fast, 150ms ease),\\n background-color var(--hx-transition-fast, 150ms ease),\\n box-shadow var(--hx-transition-fast, 150ms ease);\\n cursor: pointer;\\n vertical-align: middle;\\n}\\n\\nhx-form input[type='radio']:checked {\\n border-color: var(--hx-radio-checked-border-color, var(--hx-color-primary-500, #2563eb));\\n background-color: var(--hx-radio-checked-bg, var(--hx-color-primary-500, #2563eb));\\n box-shadow: inset 0 0 0 calc(var(--hx-radio-size, var(--hx-size-5, 1.25rem)) * 0.3)\\n var(--hx-radio-dot-color, var(--hx-color-neutral-0, #ffffff));\\n}\\n\\nhx-form input[type='radio']:focus-visible {\\n outline: var(--hx-focus-ring-width, 2px) solid\\n var(--hx-radio-focus-ring-color, var(--hx-focus-ring-color, #2563eb));\\n outline-offset: var(--hx-focus-ring-offset, 2px);\\n}\\n\\nhx-form input[type='radio']:hover:not(:disabled):not(:checked) {\\n border-color: var(--hx-color-neutral-400, #adb5bd);\\n}\\n\\nhx-form input[type='radio']:disabled {\\n opacity: var(--hx-opacity-disabled, 0.5);\\n cursor: not-allowed;\\n pointer-events: none;\\n}\\n\\nhx-form .form-type-radio {\\n display: inline-flex;\\n align-items: center;\\n gap: var(--hx-space-2, 0.5rem);\\n}\\n\\nhx-form .form-type-radio label {\\n font-size: var(--hx-font-size-md, 1rem);\\n color: var(--hx-radio-label-color, var(--hx-color-neutral-700, #343a40));\\n line-height: var(--hx-line-height-normal, 1.5);\\n cursor: pointer;\\n user-select: none;\\n -webkit-user-select: none;\\n}\\n\\nhx-form .form-radios {\\n display: flex;\\n flex-direction: column;\\n gap: var(--hx-radio-group-gap, var(--hx-space-3, 0.75rem));\\n}\\n\\nhx-form .form-radios--horizontal {\\n flex-direction: row;\\n flex-wrap: wrap;\\n}\\n\\n/* ==========================================================================\\n * SWITCH (_switch.css scoped)\\n * ========================================================================== */\\n\\nhx-form .form-type-switch {\\n display: flex;\\n flex-direction: column;\\n gap: var(--hx-space-1, 0.25rem);\\n font-family: var(--hx-font-family-sans, sans-serif);\\n}\\n\\nhx-form .form-type-switch .switch__control-row {\\n display: flex;\\n align-items: center;\\n gap: var(--hx-space-2, 0.5rem);\\n}\\n\\nhx-form .form-type-switch input[type='checkbox'] {\\n appearance: none;\\n -webkit-appearance: none;\\n -moz-appearance: none;\\n position: relative;\\n display: inline-flex;\\n align-items: center;\\n flex-shrink: 0;\\n width: var(--hx-switch-track-width-md, var(--hx-size-10, 2.5rem));\\n height: var(--hx-switch-track-height-md, var(--hx-size-5-5, 1.375rem));\\n margin: 0;\\n border: none;\\n border-radius: var(--hx-border-radius-full, 9999px);\\n background-color: var(--hx-switch-track-bg, var(--hx-color-neutral-300, #ced4da));\\n transition: background-color var(--hx-transition-fast, 150ms ease);\\n cursor: pointer;\\n background-image: none;\\n}\\n\\nhx-form .form-type-switch input[type='checkbox']::before {\\n content: '';\\n position: absolute;\\n top: 50%;\\n left: var(--hx-switch-thumb-offset, var(--hx-space-0-5, 0.125rem));\\n transform: translateY(-50%);\\n width: var(--hx-switch-thumb-size-md, var(--hx-size-4-5, 1.125rem));\\n height: var(--hx-switch-thumb-size-md, var(--hx-size-4-5, 1.125rem));\\n border-radius: var(--hx-border-radius-full, 9999px);\\n background-color: var(--hx-switch-thumb-bg, var(--hx-color-neutral-0, #ffffff));\\n box-shadow: var(--hx-switch-thumb-shadow, var(--hx-shadow-sm, 0 1px 2px 0 rgb(0 0 0 / 0.05)));\\n transition: transform var(--hx-transition-fast, 150ms ease);\\n}\\n\\nhx-form .form-type-switch input[type='checkbox']:checked {\\n background-color: var(--hx-switch-track-checked-bg, var(--hx-color-primary-500, #2563eb));\\n background-image: none;\\n}\\n\\nhx-form .form-type-switch input[type='checkbox']:checked::before {\\n transform: translateY(-50%)\\n translateX(var(--hx-switch-thumb-size-md, var(--hx-size-4-5, 1.125rem)));\\n}\\n\\nhx-form .form-type-switch input[type='checkbox']:focus-visible {\\n outline: var(--hx-focus-ring-width, 2px) solid\\n var(--hx-switch-focus-ring-color, var(--hx-focus-ring-color, #2563eb));\\n outline-offset: var(--hx-focus-ring-offset, 2px);\\n}\\n\\nhx-form .form-type-switch input[type='checkbox']:disabled {\\n opacity: var(--hx-opacity-disabled, 0.5);\\n cursor: not-allowed;\\n pointer-events: none;\\n}\\n\\nhx-form .form-type-switch label {\\n font-size: var(--hx-font-size-sm, 0.875rem);\\n font-weight: var(--hx-font-weight-medium, 500);\\n color: var(--hx-switch-label-color, var(--hx-color-neutral-700, #343a40));\\n line-height: var(--hx-line-height-normal, 1.5);\\n cursor: pointer;\\n user-select: none;\\n -webkit-user-select: none;\\n}\\n\\n/* Small */\\nhx-form .form-type-switch--sm input[type='checkbox'] {\\n width: var(--hx-switch-track-width-sm, var(--hx-size-8, 2rem));\\n height: var(--hx-switch-track-height-sm, var(--hx-size-4-5, 1.125rem));\\n}\\n\\nhx-form .form-type-switch--sm input[type='checkbox']::before {\\n width: var(--hx-switch-thumb-size-sm, var(--hx-size-3-5, 0.875rem));\\n height: var(--hx-switch-thumb-size-sm, var(--hx-size-3-5, 0.875rem));\\n}\\n\\nhx-form .form-type-switch--sm input[type='checkbox']:checked::before {\\n transform: translateY(-50%)\\n translateX(var(--hx-switch-thumb-size-sm, var(--hx-size-3-5, 0.875rem)));\\n}\\n\\n/* Large */\\nhx-form .form-type-switch--lg input[type='checkbox'] {\\n width: var(--hx-switch-track-width-lg, var(--hx-size-12, 3rem));\\n height: var(--hx-switch-track-height-lg, var(--hx-size-6-5, 1.625rem));\\n}\\n\\nhx-form .form-type-switch--lg input[type='checkbox']::before {\\n width: var(--hx-switch-thumb-size-lg, var(--hx-size-5-5, 1.375rem));\\n height: var(--hx-switch-thumb-size-lg, var(--hx-size-5-5, 1.375rem));\\n}\\n\\nhx-form .form-type-switch--lg input[type='checkbox']:checked::before {\\n transform: translateY(-50%)\\n translateX(var(--hx-switch-thumb-size-lg, var(--hx-size-5-5, 1.375rem)));\\n}\\n\\n/* ==========================================================================\\n * FORM LAYOUT (_form-layout.css scoped)\\n * ========================================================================== */\\n\\n/* ─── Form Root ─── */\\n\\nhx-form form {\\n display: flex;\\n flex-direction: column;\\n gap: var(--hx-form-gap, var(--hx-space-4, 1rem));\\n font-family: var(--hx-input-font-family, var(--hx-font-family-sans, sans-serif));\\n}\\n\\n/* ─── Fieldset ─── */\\n\\nhx-form fieldset {\\n border: var(--hx-border-width-thin, 1px) solid var(--hx-color-neutral-200, #dee2e6);\\n border-radius: var(--hx-border-radius-md, 0.375rem);\\n padding: var(--hx-space-4, 1rem) var(--hx-space-4, 1rem) var(--hx-space-4, 1rem);\\n margin: 0;\\n display: flex;\\n flex-direction: column;\\n gap: var(--hx-space-4, 1rem);\\n}\\n\\n/* ─── Legend ─── */\\n\\nhx-form legend {\\n display: flex;\\n align-items: baseline;\\n gap: var(--hx-space-1, 0.25rem);\\n font-size: var(--hx-font-size-sm, 0.875rem);\\n font-weight: var(--hx-font-weight-semibold, 600);\\n color: var(--hx-color-neutral-700, #343a40);\\n line-height: var(--hx-line-height-normal, 1.5);\\n padding: 0 var(--hx-space-1, 0.25rem);\\n}\\n\\n/* ─── Details / Collapsible Fieldset (Drupal) ─── */\\n\\nhx-form details {\\n border: var(--hx-border-width-thin, 1px) solid var(--hx-color-neutral-200, #dee2e6);\\n border-radius: var(--hx-border-radius-md, 0.375rem);\\n padding: var(--hx-space-4, 1rem);\\n margin: 0;\\n}\\n\\nhx-form summary {\\n font-size: var(--hx-font-size-sm, 0.875rem);\\n font-weight: var(--hx-font-weight-semibold, 600);\\n color: var(--hx-color-neutral-700, #343a40);\\n line-height: var(--hx-line-height-normal, 1.5);\\n cursor: pointer;\\n padding: var(--hx-space-1, 0.25rem) 0;\\n user-select: none;\\n -webkit-user-select: none;\\n}\\n\\nhx-form summary:focus-visible {\\n outline: var(--hx-focus-ring-width, 2px) solid var(--hx-focus-ring-color, #2563eb);\\n outline-offset: var(--hx-focus-ring-offset, 2px);\\n border-radius: var(--hx-border-radius-sm, 0.25rem);\\n}\\n\\n/* ─── Form Actions (button group) ─── */\\n\\nhx-form .form-actions {\\n display: flex;\\n align-items: center;\\n gap: var(--hx-space-3, 0.75rem);\\n padding-top: var(--hx-space-4, 1rem);\\n}\\n\\nhx-form .form-actions--end {\\n justify-content: flex-end;\\n}\\n\\nhx-form .form-actions--between {\\n justify-content: space-between;\\n}\\n\\n/* ─── Multi-Column Layout ─── */\\n\\nhx-form .form-columns {\\n display: grid;\\n gap: var(--hx-space-4, 1rem);\\n}\\n\\nhx-form .form-columns--2 {\\n grid-template-columns: repeat(2, 1fr);\\n}\\n\\nhx-form .form-columns--3 {\\n grid-template-columns: repeat(3, 1fr);\\n}\\n\\nhx-form .form-columns--4 {\\n grid-template-columns: repeat(4, 1fr);\\n}\\n\\n@media (max-width: 640px) {\\n hx-form .form-columns--2,\\n hx-form .form-columns--3,\\n hx-form .form-columns--4 {\\n grid-template-columns: 1fr;\\n }\\n}\\n\\n/* ─── Full-Width Form Item (spans all columns) ─── */\\n\\nhx-form .form-item--full {\\n grid-column: 1 / -1;\\n}\\n\\n/* ─── Inline Form Layout ─── */\\n\\nhx-form .form-inline {\\n display: flex;\\n flex-wrap: wrap;\\n align-items: flex-end;\\n gap: var(--hx-space-3, 0.75rem);\\n}\\n\\nhx-form .form-inline .form-item {\\n flex: 1;\\n min-width: 0;\\n}\\n\\nhx-form .form-inline .form-item + .form-item {\\n margin-top: 0;\\n}\\n\\n/* ─── Form Divider ─── */\\n\\nhx-form .form-divider {\\n border: none;\\n border-top: var(--hx-border-width-thin, 1px) solid var(--hx-color-neutral-200, #dee2e6);\\n margin: var(--hx-space-2, 0.5rem) 0;\\n}\\n\\n/* ==========================================================================\\n * VALIDATION (_validation.css scoped)\\n * ========================================================================== */\\n\\n/* ─── Error State on Field Wrapper ─── */\\n\\nhx-form .form-item.error label,\\nhx-form .form-item.has-error label,\\nhx-form .form-item--error label {\\n color: var(--hx-input-error-color, var(--hx-color-error-500, #dc3545));\\n}\\n\\nhx-form .form-item.error input[type='text'],\\nhx-form .form-item.error input[type='email'],\\nhx-form .form-item.error input[type='password'],\\nhx-form .form-item.error input[type='tel'],\\nhx-form .form-item.error input[type='url'],\\nhx-form .form-item.error input[type='search'],\\nhx-form .form-item.error input[type='number'],\\nhx-form .form-item.error textarea,\\nhx-form .form-item.error select,\\nhx-form .form-item.has-error input[type='text'],\\nhx-form .form-item.has-error input[type='email'],\\nhx-form .form-item.has-error input[type='password'],\\nhx-form .form-item.has-error input[type='tel'],\\nhx-form .form-item.has-error input[type='url'],\\nhx-form .form-item.has-error input[type='search'],\\nhx-form .form-item.has-error input[type='number'],\\nhx-form .form-item.has-error textarea,\\nhx-form .form-item.has-error select,\\nhx-form .form-item--error input[type='text'],\\nhx-form .form-item--error input[type='email'],\\nhx-form .form-item--error input[type='password'],\\nhx-form .form-item--error input[type='tel'],\\nhx-form .form-item--error input[type='url'],\\nhx-form .form-item--error input[type='search'],\\nhx-form .form-item--error input[type='number'],\\nhx-form .form-item--error textarea,\\nhx-form .form-item--error select {\\n border-color: var(--hx-input-error-color, var(--hx-color-error-500, #dc3545));\\n}\\n\\nhx-form .form-item.error input[type='text']:focus,\\nhx-form .form-item.error input[type='email']:focus,\\nhx-form .form-item.error input[type='password']:focus,\\nhx-form .form-item.error input[type='tel']:focus,\\nhx-form .form-item.error input[type='url']:focus,\\nhx-form .form-item.error input[type='search']:focus,\\nhx-form .form-item.error input[type='number']:focus,\\nhx-form .form-item.error textarea:focus,\\nhx-form .form-item.error select:focus,\\nhx-form .form-item.has-error input[type='text']:focus,\\nhx-form .form-item.has-error input[type='email']:focus,\\nhx-form .form-item.has-error input[type='password']:focus,\\nhx-form .form-item.has-error input[type='tel']:focus,\\nhx-form .form-item.has-error input[type='url']:focus,\\nhx-form .form-item.has-error input[type='search']:focus,\\nhx-form .form-item.has-error input[type='number']:focus,\\nhx-form .form-item.has-error textarea:focus,\\nhx-form .form-item.has-error select:focus,\\nhx-form .form-item--error input[type='text']:focus,\\nhx-form .form-item--error input[type='email']:focus,\\nhx-form .form-item--error input[type='password']:focus,\\nhx-form .form-item--error input[type='tel']:focus,\\nhx-form .form-item--error input[type='url']:focus,\\nhx-form .form-item--error input[type='search']:focus,\\nhx-form .form-item--error input[type='number']:focus,\\nhx-form .form-item--error textarea:focus,\\nhx-form .form-item--error select:focus {\\n border-color: var(--hx-input-error-color, var(--hx-color-error-500, #dc3545));\\n box-shadow: 0 0 0 var(--hx-focus-ring-width, 2px)\\n color-mix(\\n in srgb,\\n var(--hx-input-error-color, var(--hx-color-error-500, #dc3545))\\n calc(var(--hx-focus-ring-opacity, 0.25) * 100%),\\n transparent\\n );\\n}\\n\\n/* ─── Error State on Checkbox/Radio ─── */\\n\\nhx-form .form-item.error input[type='checkbox'],\\nhx-form .form-item.has-error input[type='checkbox'],\\nhx-form .form-item--error input[type='checkbox'] {\\n border-color: var(--hx-checkbox-error-color, var(--hx-color-error-500, #dc3545));\\n}\\n\\nhx-form .form-item.error input[type='checkbox']:checked,\\nhx-form .form-item.has-error input[type='checkbox']:checked,\\nhx-form .form-item--error input[type='checkbox']:checked {\\n background-color: var(--hx-checkbox-error-color, var(--hx-color-error-500, #dc3545));\\n border-color: var(--hx-checkbox-error-color, var(--hx-color-error-500, #dc3545));\\n}\\n\\nhx-form .form-item.error input[type='radio'],\\nhx-form .form-item.has-error input[type='radio'],\\nhx-form .form-item--error input[type='radio'] {\\n border-color: var(--hx-color-error-500, #dc3545);\\n}\\n\\n/* ─── Inline Error Message ─── */\\n\\nhx-form .form-item__error-message,\\nhx-form .form-item .error-message,\\nhx-form .error-message {\\n font-size: var(--hx-font-size-xs, 0.75rem);\\n color: var(--hx-input-error-color, var(--hx-color-error-500, #dc3545));\\n line-height: var(--hx-line-height-normal, 1.5);\\n}\\n\\n/* ─── Success State on Field Wrapper ─── */\\n\\nhx-form .form-item.success label,\\nhx-form .form-item.has-success label,\\nhx-form .form-item--success label {\\n color: var(--hx-color-success-500, #198754);\\n}\\n\\nhx-form .form-item.success input[type='text'],\\nhx-form .form-item.success input[type='email'],\\nhx-form .form-item.success input[type='password'],\\nhx-form .form-item.success input[type='tel'],\\nhx-form .form-item.success input[type='url'],\\nhx-form .form-item.success input[type='search'],\\nhx-form .form-item.success input[type='number'],\\nhx-form .form-item.success textarea,\\nhx-form .form-item.success select,\\nhx-form .form-item.has-success input[type='text'],\\nhx-form .form-item.has-success input[type='email'],\\nhx-form .form-item.has-success input[type='password'],\\nhx-form .form-item.has-success input[type='tel'],\\nhx-form .form-item.has-success input[type='url'],\\nhx-form .form-item.has-success input[type='search'],\\nhx-form .form-item.has-success input[type='number'],\\nhx-form .form-item.has-success textarea,\\nhx-form .form-item.has-success select,\\nhx-form .form-item--success input[type='text'],\\nhx-form .form-item--success input[type='email'],\\nhx-form .form-item--success input[type='password'],\\nhx-form .form-item--success input[type='tel'],\\nhx-form .form-item--success input[type='url'],\\nhx-form .form-item--success input[type='search'],\\nhx-form .form-item--success input[type='number'],\\nhx-form .form-item--success textarea,\\nhx-form .form-item--success select {\\n border-color: var(--hx-color-success-500, #198754);\\n}\\n\\nhx-form .form-item.success input[type='text']:focus,\\nhx-form .form-item.success input[type='email']:focus,\\nhx-form .form-item.success input[type='password']:focus,\\nhx-form .form-item.success input[type='tel']:focus,\\nhx-form .form-item.success input[type='url']:focus,\\nhx-form .form-item.success input[type='search']:focus,\\nhx-form .form-item.success input[type='number']:focus,\\nhx-form .form-item.success textarea:focus,\\nhx-form .form-item.success select:focus,\\nhx-form .form-item.has-success input[type='text']:focus,\\nhx-form .form-item.has-success input[type='email']:focus,\\nhx-form .form-item.has-success input[type='password']:focus,\\nhx-form .form-item.has-success input[type='tel']:focus,\\nhx-form .form-item.has-success input[type='url']:focus,\\nhx-form .form-item.has-success input[type='search']:focus,\\nhx-form .form-item.has-success input[type='number']:focus,\\nhx-form .form-item.has-success textarea:focus,\\nhx-form .form-item.has-success select:focus,\\nhx-form .form-item--success input[type='text']:focus,\\nhx-form .form-item--success input[type='email']:focus,\\nhx-form .form-item--success input[type='password']:focus,\\nhx-form .form-item--success input[type='tel']:focus,\\nhx-form .form-item--success input[type='url']:focus,\\nhx-form .form-item--success input[type='search']:focus,\\nhx-form .form-item--success input[type='number']:focus,\\nhx-form .form-item--success textarea:focus,\\nhx-form .form-item--success select:focus {\\n border-color: var(--hx-color-success-500, #198754);\\n box-shadow: 0 0 0 var(--hx-focus-ring-width, 2px)\\n color-mix(\\n in srgb,\\n var(--hx-color-success-500, #198754) calc(var(--hx-focus-ring-opacity, 0.25) * 100%),\\n transparent\\n );\\n}\\n\\n/* ─── Inline Success Message ─── */\\n\\nhx-form .form-item__success-message,\\nhx-form .form-item .success-message,\\nhx-form .success-message {\\n font-size: var(--hx-font-size-xs, 0.75rem);\\n color: var(--hx-color-success-500, #198754);\\n line-height: var(--hx-line-height-normal, 1.5);\\n}\\n\\n/* ─── Drupal System Messages ─── */\\n\\nhx-form .messages--error {\\n border: var(--hx-border-width-thin, 1px) solid\\n var(--hx-input-error-color, var(--hx-color-error-500, #dc3545));\\n border-radius: var(--hx-border-radius-md, 0.375rem);\\n background-color: var(--hx-color-error-50, #fef2f2);\\n color: var(--hx-input-error-color, var(--hx-color-error-500, #dc3545));\\n padding: var(--hx-space-3, 0.75rem) var(--hx-space-4, 1rem);\\n font-size: var(--hx-font-size-sm, 0.875rem);\\n line-height: var(--hx-line-height-normal, 1.5);\\n}\\n\\nhx-form .messages--status {\\n border: var(--hx-border-width-thin, 1px) solid var(--hx-color-success-500, #198754);\\n border-radius: var(--hx-border-radius-md, 0.375rem);\\n background-color: var(--hx-color-success-50, #f0fdf4);\\n color: var(--hx-color-success-500, #198754);\\n padding: var(--hx-space-3, 0.75rem) var(--hx-space-4, 1rem);\\n font-size: var(--hx-font-size-sm, 0.875rem);\\n line-height: var(--hx-line-height-normal, 1.5);\\n}\\n\\nhx-form .messages--warning {\\n border: var(--hx-border-width-thin, 1px) solid var(--hx-color-warning-500, #ffc107);\\n border-radius: var(--hx-border-radius-md, 0.375rem);\\n background-color: var(--hx-color-warning-50, #fffbeb);\\n color: var(--hx-color-warning-700, #92400e);\\n padding: var(--hx-space-3, 0.75rem) var(--hx-space-4, 1rem);\\n font-size: var(--hx-font-size-sm, 0.875rem);\\n line-height: var(--hx-line-height-normal, 1.5);\\n}\\n\\n/* ==========================================================================\\n * FORCED-COLORS / HIGH CONTRAST MODE (P1-01)\\n *\\n * When box-shadow is used for focus rings, it is invisible in Windows\\n * High Contrast Mode. Restore a visible outline.\\n * ========================================================================== */\\n\\n@media (forced-colors: active) {\\n hx-form input[type='text']:focus,\\n hx-form input[type='email']:focus,\\n hx-form input[type='password']:focus,\\n hx-form input[type='tel']:focus,\\n hx-form input[type='url']:focus,\\n hx-form input[type='search']:focus,\\n hx-form input[type='number']:focus,\\n hx-form textarea:focus,\\n hx-form select:focus {\\n outline: 2px solid CanvasText;\\n outline-offset: 2px;\\n }\\n\\n hx-form .hx-form-error-summary {\\n border-color: LinkText;\\n }\\n}\\n\"","import formScopedCss from '../../styles/form/form.scoped.css?raw';\n\nexport const helixFormScopedCss = formScopedCss;\n","import { LitElement, html, nothing } from 'lit';\nimport { customElement, property, state } from 'lit/decorators.js';\nimport { ifDefined } from 'lit/directives/if-defined.js';\nimport { AdoptedStylesheetsController } from '../../controllers/adopted-stylesheets.js';\nimport { helixFormScopedCss } from './hx-form.styles.js';\n\n/**\n * A Light DOM form wrapper that styles native HTML form elements and\n * hx-* components with the design system's form styles.\n *\n * When `action` is set, renders a `<form>` wrapper around slotted content.\n * When no `action` is set (the Drupal pattern), renders only a `<slot>`\n * so Drupal can provide its own `<form>` tag.\n *\n * Uses adopted stylesheets to inject scoped CSS into the document without\n * Shadow DOM, keeping native form participation and Drupal compatibility.\n *\n * @summary Light DOM form wrapper with scoped styles for native and hx-* form elements.\n *\n * @tag hx-form\n *\n * @slot - Default slot for form fields and controls.\n *\n * @fires {CustomEvent<{valid: boolean, values: Record<string, FormDataEntryValue | FormDataEntryValue[]>, formData: FormData}>} hx-submit - Dispatched on valid client-side submit when no action is set.\n * @fires {CustomEvent<{errors: Array<{name: string, message: string}>}>} hx-invalid - Dispatched when validation fails on submit.\n * @fires {CustomEvent} hx-reset - Dispatched when the form is reset.\n *\n * @cssprop [--hx-form-gap=var(--hx-space-4)] - Gap between form fields.\n * @cssprop [--hx-form-max-width=none] - Maximum width of the form.\n * @cssprop [--hx-form-padding=0] - Internal padding of the form.\n */\n@customElement('hx-form')\nexport class HelixForm extends LitElement {\n // ─── Light DOM ───\n\n override createRenderRoot(): HTMLElement {\n return this;\n }\n\n // ─── Adopted Stylesheets ───\n\n private _styles = new AdoptedStylesheetsController(this, helixFormScopedCss, document);\n\n // ─── Internal State ───\n\n @state()\n private _validationErrors: Array<{ name: string; message: string }> = [];\n\n // ─── Lifecycle ───\n\n override connectedCallback(): void {\n super.connectedCallback();\n this.addEventListener('submit', this._handleSubmit);\n this.addEventListener('reset', this._handleReset);\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n this.removeEventListener('submit', this._handleSubmit);\n this.removeEventListener('reset', this._handleReset);\n }\n\n // ─── Properties ───\n\n /**\n * The URL to submit the form to. When empty, the form handles\n * submission client-side only and dispatches `hx-submit`.\n * @attr action\n */\n @property({ type: String })\n action = '';\n\n /**\n * The HTTP method used when submitting the form.\n * @attr method\n */\n @property({ type: String })\n method: 'get' | 'post' = 'post';\n\n /**\n * When true, disables the browser's built-in constraint validation\n * on form submission.\n * @attr novalidate\n */\n @property({ type: Boolean })\n novalidate = false;\n\n /**\n * Identifies the form for scripting and form discovery.\n * @attr name\n */\n @property({ type: String })\n name = '';\n\n /**\n * The encoding type for form submission. Only used when `action` is set.\n * Use `multipart/form-data` for forms with file uploads.\n * @attr enctype\n */\n @property({ type: String })\n enctype: 'application/x-www-form-urlencoded' | 'multipart/form-data' | 'text/plain' =\n 'application/x-www-form-urlencoded';\n\n // ─── Public Methods ───\n\n /**\n * Checks the validity of all child form elements without showing\n * validation UI. Returns `true` if all elements are valid.\n */\n checkValidity(): boolean {\n const formElements = this._getAllValidatableElements();\n return formElements.every((el) => {\n if ('checkValidity' in el && typeof el.checkValidity === 'function') {\n return (el as HTMLInputElement).checkValidity();\n }\n return true;\n });\n }\n\n /**\n * Checks validity and triggers the browser's constraint validation UI\n * on each invalid element. Returns `true` if all elements are valid.\n */\n reportValidity(): boolean {\n const formElements = this._getAllValidatableElements();\n let allValid = true;\n for (const el of formElements) {\n if ('reportValidity' in el && typeof el.reportValidity === 'function') {\n if (!(el as HTMLInputElement).reportValidity()) {\n allValid = false;\n }\n }\n }\n return allValid;\n }\n\n /**\n * Collects form data from all child form elements (native and hx-*).\n * Returns a `FormData` object.\n */\n getFormData(): FormData {\n // If there is a native <form> child, use it directly\n const formEl = this.querySelector('form');\n if (formEl) {\n return new FormData(formEl);\n }\n\n // Otherwise, manually collect from all named inputs\n const formData = new FormData();\n const elements = this.getNativeFormElements();\n for (const el of elements) {\n const input = el as HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement;\n if (!input.name) continue;\n\n if (input instanceof HTMLInputElement) {\n if (input.type === 'checkbox' || input.type === 'radio') {\n if (input.checked) {\n formData.append(input.name, input.value || 'on');\n }\n } else {\n formData.append(input.name, input.value);\n }\n } else {\n formData.append(input.name, input.value);\n }\n }\n\n return formData;\n }\n\n /**\n * Returns all child hx-* form components that implement the form\n * component contract (hx-text-input, hx-select, hx-checkbox, hx-textarea,\n * hx-radio-group, hx-switch).\n *\n * Note: This uses a hardcoded allowlist. When a new hx-* form component\n * is added, update this selector to include it.\n */\n getFormElements(): HTMLElement[] {\n return Array.from(\n this.querySelectorAll<HTMLElement>(\n 'hx-text-input, hx-select, hx-checkbox, hx-textarea, hx-radio-group, hx-switch',\n ),\n );\n }\n\n /**\n * Returns all native form elements (input, select, textarea, button)\n * found within this component's light DOM.\n */\n getNativeFormElements(): Array<\n HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement | HTMLButtonElement\n > {\n return Array.from(\n this.querySelectorAll<\n HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement | HTMLButtonElement\n >('input, select, textarea, button'),\n );\n }\n\n /**\n * Programmatically sets server-side validation errors on the form.\n * Renders an error summary and sets `aria-invalid=\"true\"` on named fields.\n *\n * Useful for surfacing Drupal server-side validation responses.\n *\n * @param errors - Array of `{name, message}` pairs matching field `name` attributes.\n */\n setErrors(errors: Array<{ name: string; message: string }>): void {\n this._validationErrors = errors;\n this._applyAriaInvalidFromErrors(errors);\n }\n\n /**\n * Programmatically sets a single field error. Merges with any existing errors.\n *\n * @param name - The `name` attribute of the field.\n * @param message - The error message to display.\n */\n setFieldError(name: string, message: string): void {\n const existing = this._validationErrors.filter((e) => e.name !== name);\n this.setErrors([...existing, { name, message }]);\n }\n\n /**\n * Clears all validation errors from the error summary and removes\n * `aria-invalid` from all fields.\n */\n clearErrors(): void {\n this._clearAriaInvalid();\n this._validationErrors = [];\n }\n\n // ─── Private Helpers ───\n\n /**\n * Returns all elements that support constraint validation, including\n * both native form elements and hx-* components with `checkValidity`.\n */\n private _getAllValidatableElements(): HTMLElement[] {\n const native = Array.from(this.querySelectorAll<HTMLElement>('input, select, textarea'));\n const wcElements = this.getFormElements().filter(\n (el) =>\n 'checkValidity' in el &&\n typeof (el as Record<string, unknown>).checkValidity === 'function',\n );\n return [...native, ...wcElements];\n }\n\n /**\n * Sets `aria-invalid=\"true\"` on fields with errors, removes it from valid fields.\n */\n private _applyAriaInvalidFromErrors(errors: Array<{ name: string; message: string }>): void {\n const errorNames = new Set(errors.map((e) => e.name));\n const allElements = this._getAllValidatableElements();\n for (const el of allElements) {\n const named = el as HTMLElement & { name?: string };\n const fieldName = named.name ?? el.tagName.toLowerCase();\n if (errorNames.has(fieldName)) {\n el.setAttribute('aria-invalid', 'true');\n } else {\n el.removeAttribute('aria-invalid');\n }\n }\n }\n\n /**\n * Sets `aria-invalid` based on native constraint validation state.\n */\n private _applyAriaInvalidFromValidity(): void {\n const allElements = this._getAllValidatableElements();\n for (const el of allElements) {\n if ('validity' in el) {\n const validatable = el as HTMLInputElement;\n if (!validatable.validity.valid) {\n el.setAttribute('aria-invalid', 'true');\n } else {\n el.removeAttribute('aria-invalid');\n }\n }\n }\n }\n\n /**\n * Removes `aria-invalid` from all validatable elements.\n */\n private _clearAriaInvalid(): void {\n const allElements = this._getAllValidatableElements();\n for (const el of allElements) {\n el.removeAttribute('aria-invalid');\n }\n }\n\n // ─── Event Handling ───\n\n private _handleSubmit = (e: Event): void => {\n // If there is an action, let native form submission happen\n if (this.action) {\n return;\n }\n\n // Client-side only: prevent default and dispatch hx-submit or hx-invalid\n e.preventDefault();\n\n if (!this.novalidate && !this.checkValidity()) {\n const errors = this._collectValidationErrors();\n this._validationErrors = errors;\n this._applyAriaInvalidFromValidity();\n\n /**\n * Dispatched when validation fails on submit.\n * @event hx-invalid\n */\n this.dispatchEvent(\n new CustomEvent('hx-invalid', {\n bubbles: true,\n composed: true,\n detail: { errors },\n }),\n );\n return;\n }\n\n // Clear any previous errors on successful submit\n this._validationErrors = [];\n this._clearAriaInvalid();\n\n const formData = this.getFormData();\n const values: Record<string, FormDataEntryValue | FormDataEntryValue[]> = {};\n for (const key of new Set(formData.keys())) {\n const all = formData.getAll(key);\n if (all.length === 1 && all[0] !== undefined) {\n values[key] = all[0];\n } else {\n values[key] = all;\n }\n }\n\n /**\n * Dispatched on valid client-side submit.\n * @event hx-submit\n */\n this.dispatchEvent(\n new CustomEvent('hx-submit', {\n bubbles: true,\n composed: true,\n detail: { valid: true, values, formData },\n }),\n );\n };\n\n private _handleReset = (): void => {\n this._validationErrors = [];\n this._clearAriaInvalid();\n\n /**\n * Dispatched when the form is reset.\n * @event hx-reset\n */\n this.dispatchEvent(\n new CustomEvent('hx-reset', {\n bubbles: true,\n composed: true,\n }),\n );\n };\n\n private _collectValidationErrors(): Array<{ name: string; message: string }> {\n const errors: Array<{ name: string; message: string }> = [];\n const elements = this._getAllValidatableElements();\n\n for (const el of elements) {\n if ('validity' in el && 'validationMessage' in el) {\n const validatable = el as HTMLInputElement;\n if (!validatable.validity.valid) {\n errors.push({\n name: validatable.name || validatable.tagName.toLowerCase(),\n message: validatable.validationMessage,\n });\n }\n }\n }\n\n return errors;\n }\n\n // ─── Render ───\n\n override render() {\n const errorSummary =\n this._validationErrors.length > 0\n ? html`\n <div\n class=\"hx-form-error-summary\"\n role=\"alert\"\n aria-live=\"assertive\"\n aria-atomic=\"true\"\n >\n <ul>\n ${this._validationErrors.map(\n (error) => html`<li>${error.message || error.name}</li>`,\n )}\n </ul>\n </div>\n `\n : nothing;\n\n if (this.action) {\n return html`\n ${errorSummary}\n <form\n action=${this.action}\n method=${this.method}\n enctype=${this.enctype}\n name=${ifDefined(this.name || undefined)}\n ?novalidate=${this.novalidate}\n >\n <slot></slot>\n </form>\n `;\n }\n\n return html`${errorSummary}<slot></slot>`;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'hx-form': HelixForm;\n }\n}\n"],"names":["formScopedCss","helixFormScopedCss","HelixForm","LitElement","AdoptedStylesheetsController","errors","formData","values","key","all","el","formElements","allValid","formEl","elements","input","name","message","existing","e","native","wcElements","errorNames","allElements","fieldName","validatable","errorSummary","html","error","nothing","ifDefined","__decorateClass","state","property","customElement"],"mappings":";;;;AAAA,MAAAA,IAAe;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;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;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;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;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;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"}
1
+ {"version":3,"file":"hx-form-BFv_N1dm.js","sources":["../../src/styles/form/form.scoped.css?raw","../../src/components/hx-form/hx-form.styles.ts","../../src/components/hx-form/hx-form.ts"],"sourcesContent":["export default \"/* ==========================================================================\\n * form.scoped.css — Scoped barrel file\\n *\\n * Contains all form styles with every selector prefixed by `hx-form` to\\n * prevent leaking outside the <hx-form> Light DOM wrapper.\\n *\\n * IMPORTANT: This file does NOT use @import because CSS imports cannot\\n * add scope prefixes. All styles are written inline.\\n * ==========================================================================\\n */\\n\\n/* ==========================================================================\\n * HOST / FORM ROOT TOKENS\\n * ========================================================================== */\\n\\nhx-form {\\n display: flex;\\n flex-direction: column;\\n gap: var(--hx-form-gap, var(--hx-space-4, 1rem));\\n max-width: var(--hx-form-max-width, none);\\n padding: var(--hx-form-padding, 0);\\n}\\n\\n/* ==========================================================================\\n * ERROR SUMMARY\\n * ========================================================================== */\\n\\nhx-form .hx-form-error-summary {\\n border: var(--hx-border-width-thin, 1px) solid\\n var(--hx-input-error-color, var(--hx-color-error-500, #dc3545));\\n border-radius: var(--hx-border-radius-md, 0.375rem);\\n background-color: var(--hx-color-error-50, #fef2f2);\\n color: var(--hx-input-error-color, var(--hx-color-error-500, #dc3545));\\n padding: var(--hx-space-3, 0.75rem) var(--hx-space-4, 1rem);\\n font-size: var(--hx-font-size-sm, 0.875rem);\\n line-height: var(--hx-line-height-normal, 1.5);\\n font-family: var(--hx-input-font-family, var(--hx-font-family-sans, sans-serif));\\n}\\n\\nhx-form .hx-form-error-summary ul {\\n margin: 0;\\n padding: 0 0 0 var(--hx-space-4, 1rem);\\n}\\n\\nhx-form .hx-form-error-summary li {\\n margin-bottom: var(--hx-space-1, 0.25rem);\\n}\\n\\nhx-form .hx-form-error-summary li:last-child {\\n margin-bottom: 0;\\n}\\n\\n/* ==========================================================================\\n * FIELD (_field.css scoped)\\n * ========================================================================== */\\n\\n/* ─── Field Container ─── */\\n\\nhx-form .form-item {\\n display: flex;\\n flex-direction: column;\\n gap: var(--hx-space-1, 0.25rem);\\n font-family: var(--hx-input-font-family, var(--hx-font-family-sans, sans-serif));\\n}\\n\\nhx-form .form-item + .form-item {\\n margin-top: var(--hx-space-4, 1rem);\\n}\\n\\n/* ─── Label ─── */\\n\\nhx-form label {\\n display: flex;\\n align-items: baseline;\\n gap: var(--hx-space-1, 0.25rem);\\n font-size: var(--hx-font-size-sm, 0.875rem);\\n font-weight: var(--hx-font-weight-medium, 500);\\n color: var(--hx-input-label-color, var(--hx-color-neutral-700, #343a40));\\n line-height: var(--hx-line-height-normal, 1.5);\\n}\\n\\n/* ─── Required Marker ─── */\\n\\nhx-form .form-required {\\n color: var(--hx-input-error-color, var(--hx-color-error-500, #dc3545));\\n font-weight: var(--hx-font-weight-bold, 700);\\n}\\n\\n/* ─── Description / Help Text ─── */\\n\\nhx-form .description {\\n font-size: var(--hx-font-size-xs, 0.75rem);\\n color: var(--hx-color-neutral-500, #6c757d);\\n line-height: var(--hx-line-height-normal, 1.5);\\n}\\n\\n/* ─── Box Sizing Reset ─── */\\n\\nhx-form .form-item *,\\nhx-form .form-item *::before,\\nhx-form .form-item *::after {\\n box-sizing: border-box;\\n}\\n\\n/* ==========================================================================\\n * TEXT INPUT (_text-input.css scoped)\\n * ========================================================================== */\\n\\nhx-form input[type='text'],\\nhx-form input[type='email'],\\nhx-form input[type='password'],\\nhx-form input[type='tel'],\\nhx-form input[type='url'],\\nhx-form input[type='search'],\\nhx-form input[type='number'] {\\n display: block;\\n width: 100%;\\n border: var(--hx-border-width-thin, 1px) solid\\n var(--hx-input-border-color, var(--hx-color-neutral-300, #ced4da));\\n border-radius: var(--hx-input-border-radius, var(--hx-border-radius-md, 0.375rem));\\n background-color: var(--hx-input-bg, var(--hx-color-neutral-0, #ffffff));\\n padding: var(--hx-space-2, 0.5rem) var(--hx-space-3, 0.75rem);\\n font-family: var(--hx-input-font-family, var(--hx-font-family-sans, sans-serif));\\n font-size: var(--hx-font-size-md, 1rem);\\n color: var(--hx-input-color, var(--hx-color-neutral-800, #212529));\\n line-height: var(--hx-line-height-normal, 1.5);\\n min-height: var(--hx-size-10, 2.5rem);\\n transition:\\n border-color var(--hx-transition-fast, 150ms ease),\\n box-shadow var(--hx-transition-fast, 150ms ease);\\n}\\n\\n/* ─── Placeholder ─── */\\n\\nhx-form input[type='text']::placeholder,\\nhx-form input[type='email']::placeholder,\\nhx-form input[type='password']::placeholder,\\nhx-form input[type='tel']::placeholder,\\nhx-form input[type='url']::placeholder,\\nhx-form input[type='search']::placeholder,\\nhx-form input[type='number']::placeholder {\\n color: var(--hx-color-neutral-400, #adb5bd);\\n}\\n\\n/* ─── Focus State ─── */\\n\\nhx-form input[type='text']:focus,\\nhx-form input[type='email']:focus,\\nhx-form input[type='password']:focus,\\nhx-form input[type='tel']:focus,\\nhx-form input[type='url']:focus,\\nhx-form input[type='search']:focus,\\nhx-form input[type='number']:focus {\\n outline: 0;\\n border-color: var(--hx-input-focus-ring-color, var(--hx-focus-ring-color, #2563eb));\\n box-shadow: 0 0 0 var(--hx-focus-ring-width, 2px)\\n color-mix(\\n in srgb,\\n var(--hx-input-focus-ring-color, var(--hx-focus-ring-color, #2563eb))\\n calc(var(--hx-focus-ring-opacity, 0.25) * 100%),\\n transparent\\n );\\n}\\n\\n@media (forced-colors: active) {\\n hx-form input[type='text']:focus,\\n hx-form input[type='email']:focus,\\n hx-form input[type='password']:focus,\\n hx-form input[type='tel']:focus,\\n hx-form input[type='url']:focus,\\n hx-form input[type='search']:focus,\\n hx-form input[type='number']:focus {\\n outline: var(--hx-focus-ring-width, 2px) solid ButtonText;\\n outline-offset: var(--hx-focus-ring-offset, 2px);\\n }\\n}\\n\\n/* ─── Disabled State ─── */\\n\\nhx-form input[type='text']:disabled,\\nhx-form input[type='email']:disabled,\\nhx-form input[type='password']:disabled,\\nhx-form input[type='tel']:disabled,\\nhx-form input[type='url']:disabled,\\nhx-form input[type='search']:disabled,\\nhx-form input[type='number']:disabled {\\n opacity: var(--hx-opacity-disabled, 0.5);\\n cursor: not-allowed;\\n pointer-events: none;\\n}\\n\\n/* ─── Read-Only State ─── */\\n\\nhx-form input[type='text']:read-only,\\nhx-form input[type='email']:read-only,\\nhx-form input[type='password']:read-only,\\nhx-form input[type='tel']:read-only,\\nhx-form input[type='url']:read-only,\\nhx-form input[type='search']:read-only,\\nhx-form input[type='number']:read-only {\\n background-color: var(--hx-color-neutral-100, #e9ecef);\\n}\\n\\n/* ─── Remove browser search decorations ─── */\\n\\nhx-form input[type='search']::-webkit-search-decoration,\\nhx-form input[type='search']::-webkit-search-cancel-button,\\nhx-form input[type='search']::-webkit-search-results-button,\\nhx-form input[type='search']::-webkit-search-results-decoration {\\n -webkit-appearance: none;\\n}\\n\\n/* ─── Remove number input spinners ─── */\\n\\nhx-form input[type='number']::-webkit-inner-spin-button,\\nhx-form input[type='number']::-webkit-outer-spin-button {\\n -webkit-appearance: none;\\n margin: 0;\\n}\\n\\nhx-form input[type='number'] {\\n appearance: textfield;\\n}\\n\\n/* ==========================================================================\\n * TEXTAREA (_textarea.css scoped)\\n * ========================================================================== */\\n\\nhx-form textarea {\\n display: block;\\n width: 100%;\\n border: var(--hx-border-width-thin, 1px) solid\\n var(--hx-input-border-color, var(--hx-color-neutral-300, #ced4da));\\n border-radius: var(--hx-input-border-radius, var(--hx-border-radius-md, 0.375rem));\\n background-color: var(--hx-input-bg, var(--hx-color-neutral-0, #ffffff));\\n padding: var(--hx-space-2, 0.5rem) var(--hx-space-3, 0.75rem);\\n font-family: var(--hx-input-font-family, var(--hx-font-family-sans, sans-serif));\\n font-size: var(--hx-font-size-md, 1rem);\\n color: var(--hx-input-color, var(--hx-color-neutral-800, #212529));\\n line-height: var(--hx-line-height-normal, 1.5);\\n min-height: var(--hx-textarea-min-height, var(--hx-size-20, 5rem));\\n resize: vertical;\\n transition:\\n border-color var(--hx-transition-fast, 150ms ease),\\n box-shadow var(--hx-transition-fast, 150ms ease);\\n}\\n\\nhx-form textarea::placeholder {\\n color: var(--hx-color-neutral-400, #adb5bd);\\n}\\n\\nhx-form textarea:focus {\\n outline: 0;\\n border-color: var(--hx-input-focus-ring-color, var(--hx-focus-ring-color, #2563eb));\\n box-shadow: 0 0 0 var(--hx-focus-ring-width, 2px)\\n color-mix(\\n in srgb,\\n var(--hx-input-focus-ring-color, var(--hx-focus-ring-color, #2563eb))\\n calc(var(--hx-focus-ring-opacity, 0.25) * 100%),\\n transparent\\n );\\n}\\n\\n@media (forced-colors: active) {\\n hx-form textarea:focus {\\n outline: var(--hx-focus-ring-width, 2px) solid ButtonText;\\n outline-offset: var(--hx-focus-ring-offset, 2px);\\n }\\n}\\n\\nhx-form textarea:disabled {\\n opacity: var(--hx-opacity-disabled, 0.5);\\n cursor: not-allowed;\\n pointer-events: none;\\n}\\n\\nhx-form textarea:read-only {\\n background-color: var(--hx-color-neutral-100, #e9ecef);\\n}\\n\\n/* ==========================================================================\\n * SELECT (_select.css scoped)\\n * ========================================================================== */\\n\\nhx-form select {\\n display: block;\\n width: 100%;\\n border: var(--hx-border-width-thin, 1px) solid\\n var(--hx-select-border-color, var(--hx-color-neutral-300, #ced4da));\\n border-radius: var(--hx-select-border-radius, var(--hx-border-radius-md, 0.375rem));\\n background-color: var(--hx-select-bg, var(--hx-color-neutral-0, #ffffff));\\n padding: var(--hx-space-2, 0.5rem) var(--hx-space-8, 2rem) var(--hx-space-2, 0.5rem)\\n var(--hx-space-3, 0.75rem);\\n font-family: var(--hx-select-font-family, var(--hx-font-family-sans, sans-serif));\\n font-size: var(--hx-font-size-md, 1rem);\\n color: var(--hx-select-color, var(--hx-color-neutral-800, #212529));\\n line-height: var(--hx-line-height-normal, 1.5);\\n min-height: var(--hx-input-height-md, var(--hx-size-10, 2.5rem));\\n cursor: pointer;\\n transition:\\n border-color var(--hx-transition-fast, 150ms ease),\\n box-shadow var(--hx-transition-fast, 150ms ease);\\n appearance: none;\\n -webkit-appearance: none;\\n -moz-appearance: none;\\n background-image: url(\\\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5L6 6.5L11 1.5' stroke='%236c757d' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round' fill='none'/%3E%3C/svg%3E\\\");\\n background-repeat: no-repeat;\\n background-position: right var(--hx-space-3, 0.75rem) center;\\n background-size: 12px 8px;\\n}\\n\\nhx-form select:focus {\\n outline: 0;\\n border-color: var(--hx-select-focus-ring-color, var(--hx-focus-ring-color, #2563eb));\\n box-shadow: 0 0 0 var(--hx-focus-ring-width, 2px)\\n color-mix(\\n in srgb,\\n var(--hx-select-focus-ring-color, var(--hx-focus-ring-color, #2563eb))\\n calc(var(--hx-focus-ring-opacity, 0.25) * 100%),\\n transparent\\n );\\n}\\n\\n@media (forced-colors: active) {\\n hx-form select:focus {\\n outline: var(--hx-focus-ring-width, 2px) solid ButtonText;\\n outline-offset: var(--hx-focus-ring-offset, 2px);\\n }\\n}\\n\\nhx-form select:disabled {\\n opacity: var(--hx-opacity-disabled, 0.5);\\n cursor: not-allowed;\\n pointer-events: none;\\n}\\n\\nhx-form select[multiple] {\\n min-height: var(--hx-size-20, 5rem);\\n padding-right: var(--hx-space-3, 0.75rem);\\n background-image: none;\\n}\\n\\nhx-form select[multiple] option {\\n padding: var(--hx-space-1, 0.25rem) var(--hx-space-2, 0.5rem);\\n}\\n\\nhx-form select::-ms-expand {\\n display: none;\\n}\\n\\n/* ==========================================================================\\n * CHECKBOX (_checkbox.css scoped)\\n * ========================================================================== */\\n\\nhx-form input[type='checkbox'] {\\n appearance: none;\\n -webkit-appearance: none;\\n -moz-appearance: none;\\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 margin: 0;\\n border: var(--hx-border-width-medium, 2px) solid\\n var(--hx-checkbox-border-color, var(--hx-color-neutral-300, #ced4da));\\n border-radius: var(--hx-checkbox-border-radius, var(--hx-border-radius-sm, 0.25rem));\\n background-color: var(--hx-color-neutral-0, #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 cursor: pointer;\\n vertical-align: middle;\\n}\\n\\nhx-form input[type='checkbox']:checked {\\n background-color: var(--hx-checkbox-checked-bg, var(--hx-color-primary-500, #2563eb));\\n border-color: var(--hx-checkbox-checked-border-color, var(--hx-color-primary-500, #2563eb));\\n background-image: url(\\\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none'%3E%3Cpath d='M3.5 8.5L6.5 11.5L12.5 4.5' stroke='%23ffffff' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E\\\");\\n background-repeat: no-repeat;\\n background-position: center;\\n background-size: 100%;\\n}\\n\\nhx-form input[type='checkbox']:indeterminate {\\n background-color: var(--hx-checkbox-checked-bg, var(--hx-color-primary-500, #2563eb));\\n border-color: var(--hx-checkbox-checked-border-color, var(--hx-color-primary-500, #2563eb));\\n background-image: url(\\\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none'%3E%3Cpath d='M4 8H12' stroke='%23ffffff' stroke-width='2' stroke-linecap='round'/%3E%3C/svg%3E\\\");\\n background-repeat: no-repeat;\\n background-position: center;\\n background-size: 100%;\\n}\\n\\nhx-form input[type='checkbox']:focus-visible {\\n outline: var(--hx-focus-ring-width, 2px) solid\\n var(--hx-checkbox-focus-ring-color, var(--hx-focus-ring-color, #2563eb));\\n outline-offset: var(--hx-focus-ring-offset, 2px);\\n}\\n\\nhx-form input[type='checkbox']:hover:not(:disabled) {\\n border-color: var(--hx-color-primary-500, #2563eb);\\n}\\n\\nhx-form input[type='checkbox']:checked:hover:not(:disabled) {\\n filter: brightness(var(--hx-filter-brightness-hover, 0.9));\\n}\\n\\nhx-form input[type='checkbox']:disabled {\\n opacity: var(--hx-opacity-disabled, 0.5);\\n cursor: not-allowed;\\n pointer-events: none;\\n}\\n\\nhx-form .form-type-checkbox,\\nhx-form .form-type-checkbox-toggle {\\n display: flex;\\n align-items: flex-start;\\n gap: var(--hx-space-2, 0.5rem);\\n}\\n\\nhx-form .form-type-checkbox label,\\nhx-form .form-type-checkbox-toggle 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-neutral-700, #343a40));\\n line-height: var(--hx-line-height-normal, 1.5);\\n cursor: pointer;\\n user-select: none;\\n -webkit-user-select: none;\\n}\\n\\n/* ==========================================================================\\n * RADIO (_radio.css scoped)\\n * ========================================================================== */\\n\\nhx-form input[type='radio'] {\\n appearance: none;\\n -webkit-appearance: none;\\n -moz-appearance: none;\\n display: inline-flex;\\n align-items: center;\\n justify-content: center;\\n flex-shrink: 0;\\n width: var(--hx-radio-size, var(--hx-size-5, 1.25rem));\\n height: var(--hx-radio-size, var(--hx-size-5, 1.25rem));\\n margin: 0;\\n border: var(--hx-border-width-medium, 2px) solid\\n var(--hx-radio-border-color, var(--hx-color-neutral-300, #ced4da));\\n border-radius: var(--hx-border-radius-full, 9999px);\\n background-color: var(--hx-color-neutral-0, #ffffff);\\n transition:\\n border-color var(--hx-transition-fast, 150ms ease),\\n background-color var(--hx-transition-fast, 150ms ease),\\n box-shadow var(--hx-transition-fast, 150ms ease);\\n cursor: pointer;\\n vertical-align: middle;\\n}\\n\\nhx-form input[type='radio']:checked {\\n border-color: var(--hx-radio-checked-border-color, var(--hx-color-primary-500, #2563eb));\\n background-color: var(--hx-radio-checked-bg, var(--hx-color-primary-500, #2563eb));\\n box-shadow: inset 0 0 0 calc(var(--hx-radio-size, var(--hx-size-5, 1.25rem)) * 0.3)\\n var(--hx-radio-dot-color, var(--hx-color-neutral-0, #ffffff));\\n}\\n\\nhx-form input[type='radio']:focus-visible {\\n outline: var(--hx-focus-ring-width, 2px) solid\\n var(--hx-radio-focus-ring-color, var(--hx-focus-ring-color, #2563eb));\\n outline-offset: var(--hx-focus-ring-offset, 2px);\\n}\\n\\nhx-form input[type='radio']:hover:not(:disabled):not(:checked) {\\n border-color: var(--hx-color-neutral-400, #adb5bd);\\n}\\n\\nhx-form input[type='radio']:disabled {\\n opacity: var(--hx-opacity-disabled, 0.5);\\n cursor: not-allowed;\\n pointer-events: none;\\n}\\n\\nhx-form .form-type-radio {\\n display: inline-flex;\\n align-items: center;\\n gap: var(--hx-space-2, 0.5rem);\\n}\\n\\nhx-form .form-type-radio label {\\n font-size: var(--hx-font-size-md, 1rem);\\n color: var(--hx-radio-label-color, var(--hx-color-neutral-700, #343a40));\\n line-height: var(--hx-line-height-normal, 1.5);\\n cursor: pointer;\\n user-select: none;\\n -webkit-user-select: none;\\n}\\n\\nhx-form .form-radios {\\n display: flex;\\n flex-direction: column;\\n gap: var(--hx-radio-group-gap, var(--hx-space-3, 0.75rem));\\n}\\n\\nhx-form .form-radios--horizontal {\\n flex-direction: row;\\n flex-wrap: wrap;\\n}\\n\\n/* ==========================================================================\\n * SWITCH (_switch.css scoped)\\n * ========================================================================== */\\n\\nhx-form .form-type-switch {\\n display: flex;\\n flex-direction: column;\\n gap: var(--hx-space-1, 0.25rem);\\n font-family: var(--hx-font-family-sans, sans-serif);\\n}\\n\\nhx-form .form-type-switch .switch__control-row {\\n display: flex;\\n align-items: center;\\n gap: var(--hx-space-2, 0.5rem);\\n}\\n\\nhx-form .form-type-switch input[type='checkbox'] {\\n appearance: none;\\n -webkit-appearance: none;\\n -moz-appearance: none;\\n position: relative;\\n display: inline-flex;\\n align-items: center;\\n flex-shrink: 0;\\n width: var(--hx-switch-track-width-md, var(--hx-size-10, 2.5rem));\\n height: var(--hx-switch-track-height-md, var(--hx-size-5-5, 1.375rem));\\n margin: 0;\\n border: none;\\n border-radius: var(--hx-border-radius-full, 9999px);\\n background-color: var(--hx-switch-track-bg, var(--hx-color-neutral-300, #ced4da));\\n transition: background-color var(--hx-transition-fast, 150ms ease);\\n cursor: pointer;\\n background-image: none;\\n}\\n\\nhx-form .form-type-switch input[type='checkbox']::before {\\n content: '';\\n position: absolute;\\n top: 50%;\\n left: var(--hx-switch-thumb-offset, var(--hx-space-0-5, 0.125rem));\\n transform: translateY(-50%);\\n width: var(--hx-switch-thumb-size-md, var(--hx-size-4-5, 1.125rem));\\n height: var(--hx-switch-thumb-size-md, var(--hx-size-4-5, 1.125rem));\\n border-radius: var(--hx-border-radius-full, 9999px);\\n background-color: var(--hx-switch-thumb-bg, var(--hx-color-neutral-0, #ffffff));\\n box-shadow: var(--hx-switch-thumb-shadow, var(--hx-shadow-sm, 0 1px 2px 0 rgb(0 0 0 / 0.05)));\\n transition: transform var(--hx-transition-fast, 150ms ease);\\n}\\n\\nhx-form .form-type-switch input[type='checkbox']:checked {\\n background-color: var(--hx-switch-track-checked-bg, var(--hx-color-primary-500, #2563eb));\\n background-image: none;\\n}\\n\\nhx-form .form-type-switch input[type='checkbox']:checked::before {\\n transform: translateY(-50%)\\n translateX(var(--hx-switch-thumb-size-md, var(--hx-size-4-5, 1.125rem)));\\n}\\n\\nhx-form .form-type-switch input[type='checkbox']:focus-visible {\\n outline: var(--hx-focus-ring-width, 2px) solid\\n var(--hx-switch-focus-ring-color, var(--hx-focus-ring-color, #2563eb));\\n outline-offset: var(--hx-focus-ring-offset, 2px);\\n}\\n\\nhx-form .form-type-switch input[type='checkbox']:disabled {\\n opacity: var(--hx-opacity-disabled, 0.5);\\n cursor: not-allowed;\\n pointer-events: none;\\n}\\n\\nhx-form .form-type-switch label {\\n font-size: var(--hx-font-size-sm, 0.875rem);\\n font-weight: var(--hx-font-weight-medium, 500);\\n color: var(--hx-switch-label-color, var(--hx-color-neutral-700, #343a40));\\n line-height: var(--hx-line-height-normal, 1.5);\\n cursor: pointer;\\n user-select: none;\\n -webkit-user-select: none;\\n}\\n\\n/* Small */\\nhx-form .form-type-switch--sm input[type='checkbox'] {\\n width: var(--hx-switch-track-width-sm, var(--hx-size-8, 2rem));\\n height: var(--hx-switch-track-height-sm, var(--hx-size-4-5, 1.125rem));\\n}\\n\\nhx-form .form-type-switch--sm input[type='checkbox']::before {\\n width: var(--hx-switch-thumb-size-sm, var(--hx-size-3-5, 0.875rem));\\n height: var(--hx-switch-thumb-size-sm, var(--hx-size-3-5, 0.875rem));\\n}\\n\\nhx-form .form-type-switch--sm input[type='checkbox']:checked::before {\\n transform: translateY(-50%)\\n translateX(var(--hx-switch-thumb-size-sm, var(--hx-size-3-5, 0.875rem)));\\n}\\n\\n/* Large */\\nhx-form .form-type-switch--lg input[type='checkbox'] {\\n width: var(--hx-switch-track-width-lg, var(--hx-size-12, 3rem));\\n height: var(--hx-switch-track-height-lg, var(--hx-size-6-5, 1.625rem));\\n}\\n\\nhx-form .form-type-switch--lg input[type='checkbox']::before {\\n width: var(--hx-switch-thumb-size-lg, var(--hx-size-5-5, 1.375rem));\\n height: var(--hx-switch-thumb-size-lg, var(--hx-size-5-5, 1.375rem));\\n}\\n\\nhx-form .form-type-switch--lg input[type='checkbox']:checked::before {\\n transform: translateY(-50%)\\n translateX(var(--hx-switch-thumb-size-lg, var(--hx-size-5-5, 1.375rem)));\\n}\\n\\n/* ==========================================================================\\n * FORM LAYOUT (_form-layout.css scoped)\\n * ========================================================================== */\\n\\n/* ─── Form Root ─── */\\n\\nhx-form form {\\n display: flex;\\n flex-direction: column;\\n gap: var(--hx-form-gap, var(--hx-space-4, 1rem));\\n font-family: var(--hx-input-font-family, var(--hx-font-family-sans, sans-serif));\\n}\\n\\n/* ─── Fieldset ─── */\\n\\nhx-form fieldset {\\n border: var(--hx-border-width-thin, 1px) solid var(--hx-color-neutral-200, #dee2e6);\\n border-radius: var(--hx-border-radius-md, 0.375rem);\\n padding: var(--hx-space-4, 1rem) var(--hx-space-4, 1rem) var(--hx-space-4, 1rem);\\n margin: 0;\\n display: flex;\\n flex-direction: column;\\n gap: var(--hx-space-4, 1rem);\\n}\\n\\n/* ─── Legend ─── */\\n\\nhx-form legend {\\n display: flex;\\n align-items: baseline;\\n gap: var(--hx-space-1, 0.25rem);\\n font-size: var(--hx-font-size-sm, 0.875rem);\\n font-weight: var(--hx-font-weight-semibold, 600);\\n color: var(--hx-color-neutral-700, #343a40);\\n line-height: var(--hx-line-height-normal, 1.5);\\n padding: 0 var(--hx-space-1, 0.25rem);\\n}\\n\\n/* ─── Details / Collapsible Fieldset (Drupal) ─── */\\n\\nhx-form details {\\n border: var(--hx-border-width-thin, 1px) solid var(--hx-color-neutral-200, #dee2e6);\\n border-radius: var(--hx-border-radius-md, 0.375rem);\\n padding: var(--hx-space-4, 1rem);\\n margin: 0;\\n}\\n\\nhx-form summary {\\n font-size: var(--hx-font-size-sm, 0.875rem);\\n font-weight: var(--hx-font-weight-semibold, 600);\\n color: var(--hx-color-neutral-700, #343a40);\\n line-height: var(--hx-line-height-normal, 1.5);\\n cursor: pointer;\\n padding: var(--hx-space-1, 0.25rem) 0;\\n user-select: none;\\n -webkit-user-select: none;\\n}\\n\\nhx-form summary:focus-visible {\\n outline: var(--hx-focus-ring-width, 2px) solid var(--hx-focus-ring-color, #2563eb);\\n outline-offset: var(--hx-focus-ring-offset, 2px);\\n border-radius: var(--hx-border-radius-sm, 0.25rem);\\n}\\n\\n/* ─── Form Actions (button group) ─── */\\n\\nhx-form .form-actions {\\n display: flex;\\n align-items: center;\\n gap: var(--hx-space-3, 0.75rem);\\n padding-top: var(--hx-space-4, 1rem);\\n}\\n\\nhx-form .form-actions--end {\\n justify-content: flex-end;\\n}\\n\\nhx-form .form-actions--between {\\n justify-content: space-between;\\n}\\n\\n/* ─── Multi-Column Layout ─── */\\n\\nhx-form .form-columns {\\n display: grid;\\n gap: var(--hx-space-4, 1rem);\\n}\\n\\nhx-form .form-columns--2 {\\n grid-template-columns: repeat(2, 1fr);\\n}\\n\\nhx-form .form-columns--3 {\\n grid-template-columns: repeat(3, 1fr);\\n}\\n\\nhx-form .form-columns--4 {\\n grid-template-columns: repeat(4, 1fr);\\n}\\n\\n@media (max-width: 640px) {\\n hx-form .form-columns--2,\\n hx-form .form-columns--3,\\n hx-form .form-columns--4 {\\n grid-template-columns: 1fr;\\n }\\n}\\n\\n/* ─── Full-Width Form Item (spans all columns) ─── */\\n\\nhx-form .form-item--full {\\n grid-column: 1 / -1;\\n}\\n\\n/* ─── Inline Form Layout ─── */\\n\\nhx-form .form-inline {\\n display: flex;\\n flex-wrap: wrap;\\n align-items: flex-end;\\n gap: var(--hx-space-3, 0.75rem);\\n}\\n\\nhx-form .form-inline .form-item {\\n flex: 1;\\n min-width: 0;\\n}\\n\\nhx-form .form-inline .form-item + .form-item {\\n margin-top: 0;\\n}\\n\\n/* ─── Form Divider ─── */\\n\\nhx-form .form-divider {\\n border: none;\\n border-top: var(--hx-border-width-thin, 1px) solid var(--hx-color-neutral-200, #dee2e6);\\n margin: var(--hx-space-2, 0.5rem) 0;\\n}\\n\\n/* ==========================================================================\\n * VALIDATION (_validation.css scoped)\\n * ========================================================================== */\\n\\n/* ─── Error State on Field Wrapper ─── */\\n\\nhx-form .form-item.error label,\\nhx-form .form-item.has-error label,\\nhx-form .form-item--error label {\\n color: var(--hx-input-error-color, var(--hx-color-error-500, #dc3545));\\n}\\n\\nhx-form .form-item.error input[type='text'],\\nhx-form .form-item.error input[type='email'],\\nhx-form .form-item.error input[type='password'],\\nhx-form .form-item.error input[type='tel'],\\nhx-form .form-item.error input[type='url'],\\nhx-form .form-item.error input[type='search'],\\nhx-form .form-item.error input[type='number'],\\nhx-form .form-item.error textarea,\\nhx-form .form-item.error select,\\nhx-form .form-item.has-error input[type='text'],\\nhx-form .form-item.has-error input[type='email'],\\nhx-form .form-item.has-error input[type='password'],\\nhx-form .form-item.has-error input[type='tel'],\\nhx-form .form-item.has-error input[type='url'],\\nhx-form .form-item.has-error input[type='search'],\\nhx-form .form-item.has-error input[type='number'],\\nhx-form .form-item.has-error textarea,\\nhx-form .form-item.has-error select,\\nhx-form .form-item--error input[type='text'],\\nhx-form .form-item--error input[type='email'],\\nhx-form .form-item--error input[type='password'],\\nhx-form .form-item--error input[type='tel'],\\nhx-form .form-item--error input[type='url'],\\nhx-form .form-item--error input[type='search'],\\nhx-form .form-item--error input[type='number'],\\nhx-form .form-item--error textarea,\\nhx-form .form-item--error select {\\n border-color: var(--hx-input-error-color, var(--hx-color-error-500, #dc3545));\\n}\\n\\nhx-form .form-item.error input[type='text']:focus,\\nhx-form .form-item.error input[type='email']:focus,\\nhx-form .form-item.error input[type='password']:focus,\\nhx-form .form-item.error input[type='tel']:focus,\\nhx-form .form-item.error input[type='url']:focus,\\nhx-form .form-item.error input[type='search']:focus,\\nhx-form .form-item.error input[type='number']:focus,\\nhx-form .form-item.error textarea:focus,\\nhx-form .form-item.error select:focus,\\nhx-form .form-item.has-error input[type='text']:focus,\\nhx-form .form-item.has-error input[type='email']:focus,\\nhx-form .form-item.has-error input[type='password']:focus,\\nhx-form .form-item.has-error input[type='tel']:focus,\\nhx-form .form-item.has-error input[type='url']:focus,\\nhx-form .form-item.has-error input[type='search']:focus,\\nhx-form .form-item.has-error input[type='number']:focus,\\nhx-form .form-item.has-error textarea:focus,\\nhx-form .form-item.has-error select:focus,\\nhx-form .form-item--error input[type='text']:focus,\\nhx-form .form-item--error input[type='email']:focus,\\nhx-form .form-item--error input[type='password']:focus,\\nhx-form .form-item--error input[type='tel']:focus,\\nhx-form .form-item--error input[type='url']:focus,\\nhx-form .form-item--error input[type='search']:focus,\\nhx-form .form-item--error input[type='number']:focus,\\nhx-form .form-item--error textarea:focus,\\nhx-form .form-item--error select:focus {\\n border-color: var(--hx-input-error-color, var(--hx-color-error-500, #dc3545));\\n box-shadow: 0 0 0 var(--hx-focus-ring-width, 2px)\\n color-mix(\\n in srgb,\\n var(--hx-input-error-color, var(--hx-color-error-500, #dc3545))\\n calc(var(--hx-focus-ring-opacity, 0.25) * 100%),\\n transparent\\n );\\n}\\n\\n/* ─── Error State on Checkbox/Radio ─── */\\n\\nhx-form .form-item.error input[type='checkbox'],\\nhx-form .form-item.has-error input[type='checkbox'],\\nhx-form .form-item--error input[type='checkbox'] {\\n border-color: var(--hx-checkbox-error-color, var(--hx-color-error-500, #dc3545));\\n}\\n\\nhx-form .form-item.error input[type='checkbox']:checked,\\nhx-form .form-item.has-error input[type='checkbox']:checked,\\nhx-form .form-item--error input[type='checkbox']:checked {\\n background-color: var(--hx-checkbox-error-color, var(--hx-color-error-500, #dc3545));\\n border-color: var(--hx-checkbox-error-color, var(--hx-color-error-500, #dc3545));\\n}\\n\\nhx-form .form-item.error input[type='radio'],\\nhx-form .form-item.has-error input[type='radio'],\\nhx-form .form-item--error input[type='radio'] {\\n border-color: var(--hx-color-error-500, #dc3545);\\n}\\n\\n/* ─── Inline Error Message ─── */\\n\\nhx-form .form-item__error-message,\\nhx-form .form-item .error-message,\\nhx-form .error-message {\\n font-size: var(--hx-font-size-xs, 0.75rem);\\n color: var(--hx-input-error-color, var(--hx-color-error-500, #dc3545));\\n line-height: var(--hx-line-height-normal, 1.5);\\n}\\n\\n/* ─── Success State on Field Wrapper ─── */\\n\\nhx-form .form-item.success label,\\nhx-form .form-item.has-success label,\\nhx-form .form-item--success label {\\n color: var(--hx-color-success-500, #198754);\\n}\\n\\nhx-form .form-item.success input[type='text'],\\nhx-form .form-item.success input[type='email'],\\nhx-form .form-item.success input[type='password'],\\nhx-form .form-item.success input[type='tel'],\\nhx-form .form-item.success input[type='url'],\\nhx-form .form-item.success input[type='search'],\\nhx-form .form-item.success input[type='number'],\\nhx-form .form-item.success textarea,\\nhx-form .form-item.success select,\\nhx-form .form-item.has-success input[type='text'],\\nhx-form .form-item.has-success input[type='email'],\\nhx-form .form-item.has-success input[type='password'],\\nhx-form .form-item.has-success input[type='tel'],\\nhx-form .form-item.has-success input[type='url'],\\nhx-form .form-item.has-success input[type='search'],\\nhx-form .form-item.has-success input[type='number'],\\nhx-form .form-item.has-success textarea,\\nhx-form .form-item.has-success select,\\nhx-form .form-item--success input[type='text'],\\nhx-form .form-item--success input[type='email'],\\nhx-form .form-item--success input[type='password'],\\nhx-form .form-item--success input[type='tel'],\\nhx-form .form-item--success input[type='url'],\\nhx-form .form-item--success input[type='search'],\\nhx-form .form-item--success input[type='number'],\\nhx-form .form-item--success textarea,\\nhx-form .form-item--success select {\\n border-color: var(--hx-color-success-500, #198754);\\n}\\n\\nhx-form .form-item.success input[type='text']:focus,\\nhx-form .form-item.success input[type='email']:focus,\\nhx-form .form-item.success input[type='password']:focus,\\nhx-form .form-item.success input[type='tel']:focus,\\nhx-form .form-item.success input[type='url']:focus,\\nhx-form .form-item.success input[type='search']:focus,\\nhx-form .form-item.success input[type='number']:focus,\\nhx-form .form-item.success textarea:focus,\\nhx-form .form-item.success select:focus,\\nhx-form .form-item.has-success input[type='text']:focus,\\nhx-form .form-item.has-success input[type='email']:focus,\\nhx-form .form-item.has-success input[type='password']:focus,\\nhx-form .form-item.has-success input[type='tel']:focus,\\nhx-form .form-item.has-success input[type='url']:focus,\\nhx-form .form-item.has-success input[type='search']:focus,\\nhx-form .form-item.has-success input[type='number']:focus,\\nhx-form .form-item.has-success textarea:focus,\\nhx-form .form-item.has-success select:focus,\\nhx-form .form-item--success input[type='text']:focus,\\nhx-form .form-item--success input[type='email']:focus,\\nhx-form .form-item--success input[type='password']:focus,\\nhx-form .form-item--success input[type='tel']:focus,\\nhx-form .form-item--success input[type='url']:focus,\\nhx-form .form-item--success input[type='search']:focus,\\nhx-form .form-item--success input[type='number']:focus,\\nhx-form .form-item--success textarea:focus,\\nhx-form .form-item--success select:focus {\\n border-color: var(--hx-color-success-500, #198754);\\n box-shadow: 0 0 0 var(--hx-focus-ring-width, 2px)\\n color-mix(\\n in srgb,\\n var(--hx-color-success-500, #198754) calc(var(--hx-focus-ring-opacity, 0.25) * 100%),\\n transparent\\n );\\n}\\n\\n/* ─── Inline Success Message ─── */\\n\\nhx-form .form-item__success-message,\\nhx-form .form-item .success-message,\\nhx-form .success-message {\\n font-size: var(--hx-font-size-xs, 0.75rem);\\n color: var(--hx-color-success-500, #198754);\\n line-height: var(--hx-line-height-normal, 1.5);\\n}\\n\\n/* ─── Drupal System Messages ─── */\\n\\nhx-form .messages--error {\\n border: var(--hx-border-width-thin, 1px) solid\\n var(--hx-input-error-color, var(--hx-color-error-500, #dc3545));\\n border-radius: var(--hx-border-radius-md, 0.375rem);\\n background-color: var(--hx-color-error-50, #fef2f2);\\n color: var(--hx-input-error-color, var(--hx-color-error-500, #dc3545));\\n padding: var(--hx-space-3, 0.75rem) var(--hx-space-4, 1rem);\\n font-size: var(--hx-font-size-sm, 0.875rem);\\n line-height: var(--hx-line-height-normal, 1.5);\\n}\\n\\nhx-form .messages--status {\\n border: var(--hx-border-width-thin, 1px) solid var(--hx-color-success-500, #198754);\\n border-radius: var(--hx-border-radius-md, 0.375rem);\\n background-color: var(--hx-color-success-50, #f0fdf4);\\n color: var(--hx-color-success-500, #198754);\\n padding: var(--hx-space-3, 0.75rem) var(--hx-space-4, 1rem);\\n font-size: var(--hx-font-size-sm, 0.875rem);\\n line-height: var(--hx-line-height-normal, 1.5);\\n}\\n\\nhx-form .messages--warning {\\n border: var(--hx-border-width-thin, 1px) solid var(--hx-color-warning-500, #ffc107);\\n border-radius: var(--hx-border-radius-md, 0.375rem);\\n background-color: var(--hx-color-warning-50, #fffbeb);\\n color: var(--hx-color-warning-700, #92400e);\\n padding: var(--hx-space-3, 0.75rem) var(--hx-space-4, 1rem);\\n font-size: var(--hx-font-size-sm, 0.875rem);\\n line-height: var(--hx-line-height-normal, 1.5);\\n}\\n\\n/* ==========================================================================\\n * FORCED-COLORS / HIGH CONTRAST MODE (P1-01)\\n *\\n * When box-shadow is used for focus rings, it is invisible in Windows\\n * High Contrast Mode. Restore a visible outline.\\n * ========================================================================== */\\n\\n@media (forced-colors: active) {\\n hx-form input[type='text']:focus,\\n hx-form input[type='email']:focus,\\n hx-form input[type='password']:focus,\\n hx-form input[type='tel']:focus,\\n hx-form input[type='url']:focus,\\n hx-form input[type='search']:focus,\\n hx-form input[type='number']:focus,\\n hx-form textarea:focus,\\n hx-form select:focus {\\n outline: 2px solid CanvasText;\\n outline-offset: 2px;\\n }\\n\\n hx-form .hx-form-error-summary {\\n border-color: LinkText;\\n }\\n}\\n\"","import formScopedCss from '../../styles/form/form.scoped.css?raw';\n\nexport const helixFormScopedCss = formScopedCss;\n","import { LitElement, html, nothing } from 'lit';\nimport { customElement, property, state } from 'lit/decorators.js';\nimport { ifDefined } from 'lit/directives/if-defined.js';\nimport { AdoptedStylesheetsController } from '../../controllers/adopted-stylesheets.js';\nimport { helixFormScopedCss } from './hx-form.styles.js';\n\n/**\n * A Light DOM form wrapper that styles native HTML form elements and\n * hx-* components with the design system's form styles.\n *\n * When `action` is set, renders a `<form>` wrapper around slotted content.\n * When no `action` is set (the Drupal pattern), renders only a `<slot>`\n * so Drupal can provide its own `<form>` tag.\n *\n * Uses adopted stylesheets to inject scoped CSS into the document without\n * Shadow DOM, keeping native form participation and Drupal compatibility.\n *\n * @summary Light DOM form wrapper with scoped styles for native and hx-* form elements.\n *\n * @tag hx-form\n *\n * @slot - Default slot for form fields and controls.\n *\n * @fires {CustomEvent<{valid: boolean, values: Record<string, FormDataEntryValue | FormDataEntryValue[]>, formData: FormData}>} hx-submit - Dispatched on valid client-side submit when no action is set.\n * @fires {CustomEvent<{errors: Array<{name: string, message: string}>}>} hx-invalid - Dispatched when validation fails on submit.\n * @fires {CustomEvent} hx-reset - Dispatched when the form is reset.\n *\n * @cssprop [--hx-form-gap=var(--hx-space-4)] - Gap between form fields.\n * @cssprop [--hx-form-max-width=none] - Maximum width of the form.\n * @cssprop [--hx-form-padding=0] - Internal padding of the form.\n */\n@customElement('hx-form')\nexport class HelixForm extends LitElement {\n // ─── Light DOM ───\n\n override createRenderRoot(): HTMLElement {\n return this;\n }\n\n // ─── Adopted Stylesheets ───\n\n /**\n * Controller that injects scoped CSS into the document via adopted stylesheets for Light DOM styling.\n * @internal\n */\n private _styles = new AdoptedStylesheetsController(this, helixFormScopedCss, document);\n\n // ─── Internal State ───\n\n /**\n * Current list of validation errors rendered in the error summary and used to set aria-invalid on fields.\n * @internal\n */\n @state()\n private _validationErrors: Array<{ name: string; message: string }> = [];\n\n // ─── Lifecycle ───\n\n override connectedCallback(): void {\n super.connectedCallback();\n this.addEventListener('submit', this._handleSubmit);\n this.addEventListener('reset', this._handleReset);\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n this.removeEventListener('submit', this._handleSubmit);\n this.removeEventListener('reset', this._handleReset);\n }\n\n // ─── Properties ───\n\n /**\n * The URL to submit the form to. When empty, the form handles\n * submission client-side only and dispatches `hx-submit`.\n * @attr action\n */\n @property({ type: String })\n action = '';\n\n /**\n * The HTTP method used when submitting the form.\n * @attr method\n */\n @property({ type: String })\n method: 'get' | 'post' = 'post';\n\n /**\n * When true, disables the browser's built-in constraint validation\n * on form submission.\n * @attr novalidate\n */\n @property({ type: Boolean })\n novalidate = false;\n\n /**\n * Identifies the form for scripting and form discovery.\n * @attr name\n */\n @property({ type: String })\n name = '';\n\n /**\n * The encoding type for form submission. Only used when `action` is set.\n * Use `multipart/form-data` for forms with file uploads.\n * @attr enctype\n */\n @property({ type: String })\n enctype: 'application/x-www-form-urlencoded' | 'multipart/form-data' | 'text/plain' =\n 'application/x-www-form-urlencoded';\n\n // ─── Public Methods ───\n\n /**\n * Checks the validity of all child form elements without showing\n * validation UI. Returns `true` if all elements are valid.\n */\n checkValidity(): boolean {\n const formElements = this._getAllValidatableElements();\n return formElements.every((el) => {\n if ('checkValidity' in el && typeof el.checkValidity === 'function') {\n return (el as HTMLInputElement).checkValidity();\n }\n return true;\n });\n }\n\n /**\n * Checks validity and triggers the browser's constraint validation UI\n * on each invalid element. Returns `true` if all elements are valid.\n */\n reportValidity(): boolean {\n const formElements = this._getAllValidatableElements();\n let allValid = true;\n for (const el of formElements) {\n if ('reportValidity' in el && typeof el.reportValidity === 'function') {\n if (!(el as HTMLInputElement).reportValidity()) {\n allValid = false;\n }\n }\n }\n return allValid;\n }\n\n /**\n * Collects form data from all child form elements (native and hx-*).\n * Returns a `FormData` object.\n */\n getFormData(): FormData {\n // If there is a native <form> child, use it directly\n const formEl = this.querySelector('form');\n if (formEl) {\n return new FormData(formEl);\n }\n\n // Otherwise, manually collect from all named inputs\n const formData = new FormData();\n const elements = this.getNativeFormElements();\n for (const el of elements) {\n const input = el as HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement;\n if (!input.name) continue;\n\n if (input instanceof HTMLInputElement) {\n if (input.type === 'checkbox' || input.type === 'radio') {\n if (input.checked) {\n formData.append(input.name, input.value || 'on');\n }\n } else {\n formData.append(input.name, input.value);\n }\n } else {\n formData.append(input.name, input.value);\n }\n }\n\n return formData;\n }\n\n /**\n * Returns all child hx-* form components that implement the form\n * component contract (hx-text-input, hx-select, hx-checkbox, hx-textarea,\n * hx-radio-group, hx-switch).\n *\n * Note: This uses a hardcoded allowlist. When a new hx-* form component\n * is added, update this selector to include it.\n */\n getFormElements(): HTMLElement[] {\n return Array.from(\n this.querySelectorAll<HTMLElement>(\n 'hx-text-input, hx-select, hx-checkbox, hx-textarea, hx-radio-group, hx-switch',\n ),\n );\n }\n\n /**\n * Returns all native form elements (input, select, textarea, button)\n * found within this component's light DOM.\n */\n getNativeFormElements(): Array<\n HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement | HTMLButtonElement\n > {\n return Array.from(\n this.querySelectorAll<\n HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement | HTMLButtonElement\n >('input, select, textarea, button'),\n );\n }\n\n /**\n * Programmatically sets server-side validation errors on the form.\n * Renders an error summary and sets `aria-invalid=\"true\"` on named fields.\n *\n * Useful for surfacing Drupal server-side validation responses.\n *\n * @param errors - Array of `{name, message}` pairs matching field `name` attributes.\n */\n setErrors(errors: Array<{ name: string; message: string }>): void {\n this._validationErrors = errors;\n this._applyAriaInvalidFromErrors(errors);\n }\n\n /**\n * Programmatically sets a single field error. Merges with any existing errors.\n *\n * @param name - The `name` attribute of the field.\n * @param message - The error message to display.\n */\n setFieldError(name: string, message: string): void {\n const existing = this._validationErrors.filter((e) => e.name !== name);\n this.setErrors([...existing, { name, message }]);\n }\n\n /**\n * Clears all validation errors from the error summary and removes\n * `aria-invalid` from all fields.\n */\n clearErrors(): void {\n this._clearAriaInvalid();\n this._validationErrors = [];\n }\n\n // ─── Private Helpers ───\n\n /**\n * Returns all elements that support constraint validation, including\n * both native form elements and hx-* components with `checkValidity`.\n * @internal\n */\n private _getAllValidatableElements(): HTMLElement[] {\n const native = Array.from(this.querySelectorAll<HTMLElement>('input, select, textarea'));\n const wcElements = this.getFormElements().filter(\n (el) =>\n 'checkValidity' in el &&\n typeof (el as Record<string, unknown>).checkValidity === 'function',\n );\n return [...native, ...wcElements];\n }\n\n /**\n * Sets `aria-invalid=\"true\"` on fields with errors, removes it from valid fields.\n * @internal\n */\n private _applyAriaInvalidFromErrors(errors: Array<{ name: string; message: string }>): void {\n const errorNames = new Set(errors.map((e) => e.name));\n const allElements = this._getAllValidatableElements();\n for (const el of allElements) {\n const named = el as HTMLElement & { name?: string };\n const fieldName = named.name ?? el.tagName.toLowerCase();\n if (errorNames.has(fieldName)) {\n el.setAttribute('aria-invalid', 'true');\n } else {\n el.removeAttribute('aria-invalid');\n }\n }\n }\n\n /**\n * Sets `aria-invalid` based on native constraint validation state.\n * @internal\n */\n private _applyAriaInvalidFromValidity(): void {\n const allElements = this._getAllValidatableElements();\n for (const el of allElements) {\n if ('validity' in el) {\n const validatable = el as HTMLInputElement;\n if (!validatable.validity.valid) {\n el.setAttribute('aria-invalid', 'true');\n } else {\n el.removeAttribute('aria-invalid');\n }\n }\n }\n }\n\n /**\n * Removes `aria-invalid` from all validatable elements.\n * @internal\n */\n private _clearAriaInvalid(): void {\n const allElements = this._getAllValidatableElements();\n for (const el of allElements) {\n el.removeAttribute('aria-invalid');\n }\n }\n\n // ─── Event Handling ───\n\n /**\n * Handles native form submit events, intercepting for client-side validation and hx-submit dispatch.\n * @internal\n */\n private _handleSubmit = (e: Event): void => {\n // If there is an action, let native form submission happen\n if (this.action) {\n return;\n }\n\n // Client-side only: prevent default and dispatch hx-submit or hx-invalid\n e.preventDefault();\n\n if (!this.novalidate && !this.checkValidity()) {\n const errors = this._collectValidationErrors();\n this._validationErrors = errors;\n this._applyAriaInvalidFromValidity();\n\n /**\n * Dispatched when validation fails on submit.\n * @event hx-invalid\n */\n this.dispatchEvent(\n new CustomEvent('hx-invalid', {\n bubbles: true,\n composed: true,\n detail: { errors },\n }),\n );\n return;\n }\n\n // Clear any previous errors on successful submit\n this._validationErrors = [];\n this._clearAriaInvalid();\n\n const formData = this.getFormData();\n const values: Record<string, FormDataEntryValue | FormDataEntryValue[]> = {};\n for (const key of new Set(formData.keys())) {\n const all = formData.getAll(key);\n if (all.length === 1 && all[0] !== undefined) {\n values[key] = all[0];\n } else {\n values[key] = all;\n }\n }\n\n /**\n * Dispatched on valid client-side submit.\n * @event hx-submit\n */\n this.dispatchEvent(\n new CustomEvent('hx-submit', {\n bubbles: true,\n composed: true,\n detail: { valid: true, values, formData },\n }),\n );\n };\n\n /**\n * Handles native form reset events, clearing validation errors and dispatching hx-reset.\n * @internal\n */\n private _handleReset = (): void => {\n this._validationErrors = [];\n this._clearAriaInvalid();\n\n /**\n * Dispatched when the form is reset.\n * @event hx-reset\n */\n this.dispatchEvent(\n new CustomEvent('hx-reset', {\n bubbles: true,\n composed: true,\n }),\n );\n };\n\n /**\n * Collects constraint validation errors from all validatable elements after a failed submit attempt.\n * @internal\n */\n private _collectValidationErrors(): Array<{ name: string; message: string }> {\n const errors: Array<{ name: string; message: string }> = [];\n const elements = this._getAllValidatableElements();\n\n for (const el of elements) {\n if ('validity' in el && 'validationMessage' in el) {\n const validatable = el as HTMLInputElement;\n if (!validatable.validity.valid) {\n errors.push({\n name: validatable.name || validatable.tagName.toLowerCase(),\n message: validatable.validationMessage,\n });\n }\n }\n }\n\n return errors;\n }\n\n // ─── Render ───\n\n override render() {\n const errorSummary =\n this._validationErrors.length > 0\n ? html`\n <div\n class=\"hx-form-error-summary\"\n role=\"alert\"\n aria-live=\"assertive\"\n aria-atomic=\"true\"\n >\n <ul>\n ${this._validationErrors.map(\n (error) => html`<li>${error.message || error.name}</li>`,\n )}\n </ul>\n </div>\n `\n : nothing;\n\n if (this.action) {\n return html`\n ${errorSummary}\n <form\n action=${this.action}\n method=${this.method}\n enctype=${this.enctype}\n name=${ifDefined(this.name || undefined)}\n ?novalidate=${this.novalidate}\n >\n <slot></slot>\n </form>\n `;\n }\n\n return html`${errorSummary}<slot></slot>`;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'hx-form': HelixForm;\n }\n}\n"],"names":["formScopedCss","helixFormScopedCss","HelixForm","LitElement","AdoptedStylesheetsController","errors","formData","values","key","all","el","formElements","allValid","formEl","elements","input","name","message","existing","e","native","wcElements","errorNames","allElements","fieldName","validatable","errorSummary","html","error","nothing","ifDefined","__decorateClass","state","property","customElement"],"mappings":";;;;AAAA,MAAAA,IAAe;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;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;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;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;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;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"}
@@ -1 +1 @@
1
- {"version":3,"file":"hx-help-text-DaOPN1iB.js","sources":["../../src/components/hx-help-text/hx-help-text.styles.ts","../../src/components/hx-help-text/hx-help-text.ts"],"sourcesContent":["import { css } from 'lit';\n\nexport const helixHelpTextStyles = css`\n :host {\n display: block;\n }\n\n .help-text {\n display: inline-flex;\n align-items: baseline;\n gap: var(--hx-help-text-icon-gap, 0.375rem);\n font-family: var(--hx-help-text-font-family, var(--hx-font-family-sans, sans-serif));\n font-size: var(--hx-help-text-font-size, var(--hx-font-size-sm, 0.875rem));\n font-weight: var(--hx-help-text-font-weight, var(--hx-font-weight-normal, 400));\n line-height: var(--hx-help-text-line-height, var(--hx-line-height-normal, 1.5));\n color: var(--hx-help-text-color, var(--hx-color-neutral-500, #6b7280));\n margin: 0;\n }\n\n .help-text__icon {\n flex-shrink: 0;\n display: inline-flex;\n align-items: center;\n }\n\n .help-text__text {\n min-width: 0;\n }\n\n /* ─── Variant: default ─── */\n\n .help-text--default {\n --hx-help-text-color: var(--hx-color-neutral-500, #6b7280);\n }\n\n /* ─── Variant: error ─── */\n\n .help-text--error {\n --hx-help-text-color: var(--hx-color-error-600, #dc2626);\n }\n\n /* ─── Variant: warning ─── */\n\n .help-text--warning {\n --hx-help-text-color: var(--hx-color-warning-700, #b45309);\n }\n\n /* ─── Variant: success ─── */\n\n .help-text--success {\n --hx-help-text-color: var(--hx-color-success-700, #15803d);\n }\n`;\n","import { LitElement, html, nothing } from 'lit';\nimport { customElement, property } from 'lit/decorators.js';\nimport { classMap } from 'lit/directives/class-map.js';\nimport { ifDefined } from 'lit/directives/if-defined.js';\nimport { tokenStyles } from '@helixui/tokens/lit';\nimport { helixHelpTextStyles } from './hx-help-text.styles.js';\n\n/** Icon SVG for error variant (circle with exclamation mark). */\nconst errorIcon = html`<svg viewBox=\"0 0 16 16\" aria-hidden=\"true\" width=\"1em\" height=\"1em\">\n <circle cx=\"8\" cy=\"8\" r=\"7\" stroke=\"currentColor\" stroke-width=\"1.5\" fill=\"none\" />\n <line\n x1=\"8\"\n y1=\"4.5\"\n x2=\"8\"\n y2=\"8.5\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n />\n <circle cx=\"8\" cy=\"11\" r=\"0.75\" fill=\"currentColor\" />\n</svg>`;\n\n/** Icon SVG for warning variant (triangle with exclamation mark). */\nconst warningIcon = html`<svg viewBox=\"0 0 16 16\" aria-hidden=\"true\" width=\"1em\" height=\"1em\">\n <path\n d=\"M7.134 2.5a1 1 0 011.732 0l5.196 9a1 1 0 01-.866 1.5H2.804a1 1 0 01-.866-1.5l5.196-9z\"\n stroke=\"currentColor\"\n stroke-width=\"1.25\"\n fill=\"none\"\n />\n <line\n x1=\"8\"\n y1=\"6\"\n x2=\"8\"\n y2=\"9\"\n stroke=\"currentColor\"\n stroke-width=\"1.25\"\n stroke-linecap=\"round\"\n />\n <circle cx=\"8\" cy=\"11\" r=\"0.625\" fill=\"currentColor\" />\n</svg>`;\n\n/** Icon SVG for success variant (circle with checkmark). */\nconst successIcon = html`<svg viewBox=\"0 0 16 16\" aria-hidden=\"true\" width=\"1em\" height=\"1em\">\n <circle cx=\"8\" cy=\"8\" r=\"7\" stroke=\"currentColor\" stroke-width=\"1.5\" fill=\"none\" />\n <path\n d=\"M5.25 8.25l1.75 1.75 3.75-3.75\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n fill=\"none\"\n />\n</svg>`;\n\n/** Map of variant to icon template. Default has no icon. */\nconst variantIcons = {\n default: nothing,\n error: errorIcon,\n warning: warningIcon,\n success: successIcon,\n} as const;\n\n/**\n * Standardized help/hint text displayed below form fields.\n * Used by hx-field as a consistent sub-component for guidance and validation messages.\n *\n * Non-default variants render an inline icon alongside the text to satisfy\n * WCAG 1.4.1 (color is not the sole visual indicator). The `error` variant\n * uses `role=\"alert\"` for immediate screen-reader announcement; `warning`\n * and `success` use `aria-live=\"polite\"` for non-intrusive announcements.\n *\n * @summary Help text displayed below form controls for guidance or validation feedback.\n *\n * @tag hx-help-text\n *\n * @slot - The help text content.\n *\n * @csspart base - The root element of the help text.\n * @csspart icon - The icon wrapper (only rendered for non-default variants).\n * @csspart text - The text wrapper around the default slot.\n *\n * @cssprop [--hx-help-text-color=var(--hx-color-neutral-500)] - Text color.\n * @cssprop [--hx-help-text-font-family=var(--hx-font-family-sans)] - Font family.\n * @cssprop [--hx-help-text-font-size=var(--hx-font-size-sm)] - Font size.\n * @cssprop [--hx-help-text-font-weight=var(--hx-font-weight-normal)] - Font weight.\n * @cssprop [--hx-help-text-line-height=var(--hx-line-height-normal)] - Line height.\n * @cssprop [--hx-help-text-icon-gap=0.375rem] - Gap between icon and text.\n */\n@customElement('hx-help-text')\nexport class HelixHelpText extends LitElement {\n static override styles = [tokenStyles, helixHelpTextStyles];\n\n /**\n * Visual variant that determines the text color and icon.\n * Use `error` for validation errors, `warning` for cautions, `success` for confirmation.\n * @attr variant\n */\n @property({ type: String, reflect: true })\n variant: 'default' | 'error' | 'warning' | 'success' = 'default';\n\n override render() {\n const classes = {\n 'help-text': true,\n [`help-text--${this.variant}`]: true,\n };\n\n const icon = variantIcons[this.variant];\n const role = this.variant === 'error' ? 'alert' : undefined;\n const ariaLive =\n this.variant === 'warning' || this.variant === 'success' ? 'polite' : undefined;\n\n return html`<span\n part=\"base\"\n class=${classMap(classes)}\n role=${ifDefined(role)}\n aria-live=${ifDefined(ariaLive)}\n >${icon !== nothing\n ? html`<span part=\"icon\" class=\"help-text__icon\">${icon}</span>`\n : nothing}<span part=\"text\" class=\"help-text__text\"><slot></slot></span>\n </span>`;\n }\n}\n\nexport type WcHelpText = HelixHelpText;\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'hx-help-text': HelixHelpText;\n }\n}\n"],"names":["helixHelpTextStyles","css","errorIcon","html","warningIcon","successIcon","variantIcons","nothing","HelixHelpText","LitElement","classes","icon","role","ariaLive","classMap","ifDefined","tokenStyles","__decorateClass","property","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;;;;;;ACMnC,MAAMC,IAAYC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,SAeZC,IAAcD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,SAoBdE,IAAcF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,SAadG,IAAe;AAAA,EACnB,SAASC;AAAA,EACT,OAAOL;AAAA,EACP,SAASE;AAAA,EACT,SAASC;AACX;AA6BO,IAAMG,IAAN,cAA4BC,EAAW;AAAA,EAAvC,cAAA;AAAA,UAAA,GAAA,SAAA,GASL,KAAA,UAAuD;AAAA,EAAA;AAAA,EAE9C,SAAS;AAChB,UAAMC,IAAU;AAAA,MACd,aAAa;AAAA,MACb,CAAC,cAAc,KAAK,OAAO,EAAE,GAAG;AAAA,IAAA,GAG5BC,IAAOL,EAAa,KAAK,OAAO,GAChCM,IAAO,KAAK,YAAY,UAAU,UAAU,QAC5CC,IACJ,KAAK,YAAY,aAAa,KAAK,YAAY,YAAY,WAAW;AAExE,WAAOV;AAAA;AAAA,cAEGW,EAASJ,CAAO,CAAC;AAAA,aAClBK,EAAUH,CAAI,CAAC;AAAA,kBACVG,EAAUF,CAAQ,CAAC;AAAA,SAC5BF,MAASJ,IACRJ,8CAAiDQ,CAAI,YACrDJ,CAAO;AAAA;AAAA,EAEf;AACF;AAhCaC,EACK,SAAS,CAACQ,GAAahB,CAAmB;AAQ1DiB,EAAA;AAAA,EADCC,EAAS,EAAE,MAAM,QAAQ,SAAS,IAAM;AAAA,GAR9BV,EASX,WAAA,WAAA,CAAA;AATWA,IAANS,EAAA;AAAA,EADNE,EAAc,cAAc;AAAA,GAChBX,CAAA;"}
1
+ {"version":3,"file":"hx-help-text-DaOPN1iB.js","sources":["../../src/components/hx-help-text/hx-help-text.styles.ts","../../src/components/hx-help-text/hx-help-text.ts"],"sourcesContent":["import { css } from 'lit';\n\nexport const helixHelpTextStyles = css`\n :host {\n display: block;\n }\n\n .help-text {\n display: inline-flex;\n align-items: baseline;\n gap: var(--hx-help-text-icon-gap, 0.375rem);\n font-family: var(--hx-help-text-font-family, var(--hx-font-family-sans, sans-serif));\n font-size: var(--hx-help-text-font-size, var(--hx-font-size-sm, 0.875rem));\n font-weight: var(--hx-help-text-font-weight, var(--hx-font-weight-normal, 400));\n line-height: var(--hx-help-text-line-height, var(--hx-line-height-normal, 1.5));\n color: var(--hx-help-text-color, var(--hx-color-neutral-500, #6b7280));\n margin: 0;\n }\n\n .help-text__icon {\n flex-shrink: 0;\n display: inline-flex;\n align-items: center;\n }\n\n .help-text__text {\n min-width: 0;\n }\n\n /* ─── Variant: default ─── */\n\n .help-text--default {\n --hx-help-text-color: var(--hx-color-neutral-500, #6b7280);\n }\n\n /* ─── Variant: error ─── */\n\n .help-text--error {\n --hx-help-text-color: var(--hx-color-error-600, #dc2626);\n }\n\n /* ─── Variant: warning ─── */\n\n .help-text--warning {\n --hx-help-text-color: var(--hx-color-warning-700, #b45309);\n }\n\n /* ─── Variant: success ─── */\n\n .help-text--success {\n --hx-help-text-color: var(--hx-color-success-700, #15803d);\n }\n`;\n","import { LitElement, html, nothing } from 'lit';\nimport { customElement, property } from 'lit/decorators.js';\nimport { classMap } from 'lit/directives/class-map.js';\nimport { ifDefined } from 'lit/directives/if-defined.js';\nimport { tokenStyles } from '@helixui/tokens/lit';\nimport { helixHelpTextStyles } from './hx-help-text.styles.js';\n\n/** Icon SVG for error variant (circle with exclamation mark). */\nconst errorIcon = html`<svg viewBox=\"0 0 16 16\" aria-hidden=\"true\" width=\"1em\" height=\"1em\">\n <circle cx=\"8\" cy=\"8\" r=\"7\" stroke=\"currentColor\" stroke-width=\"1.5\" fill=\"none\" />\n <line\n x1=\"8\"\n y1=\"4.5\"\n x2=\"8\"\n y2=\"8.5\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n />\n <circle cx=\"8\" cy=\"11\" r=\"0.75\" fill=\"currentColor\" />\n</svg>`;\n\n/** Icon SVG for warning variant (triangle with exclamation mark). */\nconst warningIcon = html`<svg viewBox=\"0 0 16 16\" aria-hidden=\"true\" width=\"1em\" height=\"1em\">\n <path\n d=\"M7.134 2.5a1 1 0 011.732 0l5.196 9a1 1 0 01-.866 1.5H2.804a1 1 0 01-.866-1.5l5.196-9z\"\n stroke=\"currentColor\"\n stroke-width=\"1.25\"\n fill=\"none\"\n />\n <line\n x1=\"8\"\n y1=\"6\"\n x2=\"8\"\n y2=\"9\"\n stroke=\"currentColor\"\n stroke-width=\"1.25\"\n stroke-linecap=\"round\"\n />\n <circle cx=\"8\" cy=\"11\" r=\"0.625\" fill=\"currentColor\" />\n</svg>`;\n\n/** Icon SVG for success variant (circle with checkmark). */\nconst successIcon = html`<svg viewBox=\"0 0 16 16\" aria-hidden=\"true\" width=\"1em\" height=\"1em\">\n <circle cx=\"8\" cy=\"8\" r=\"7\" stroke=\"currentColor\" stroke-width=\"1.5\" fill=\"none\" />\n <path\n d=\"M5.25 8.25l1.75 1.75 3.75-3.75\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n fill=\"none\"\n />\n</svg>`;\n\n/** Map of variant to icon template. Default has no icon. */\nconst variantIcons = {\n default: nothing,\n error: errorIcon,\n warning: warningIcon,\n success: successIcon,\n} as const;\n\n/**\n * Standardized help/hint text displayed below form fields.\n * Used by hx-field as a consistent sub-component for guidance and validation messages.\n *\n * Non-default variants render an inline icon alongside the text to satisfy\n * WCAG 1.4.1 (color is not the sole visual indicator). The `error` variant\n * uses `role=\"alert\"` for immediate screen-reader announcement; `warning`\n * and `success` use `aria-live=\"polite\"` for non-intrusive announcements.\n *\n * @summary Help text displayed below form controls for guidance or validation feedback.\n *\n * @tag hx-help-text\n *\n * @slot - The help text content.\n *\n * @csspart base - The root element of the help text.\n * @csspart icon - The icon wrapper (only rendered for non-default variants).\n * @csspart text - The text wrapper around the default slot.\n *\n * @cssprop [--hx-help-text-color=var(--hx-color-neutral-500)] - Text color.\n * @cssprop [--hx-help-text-font-family=var(--hx-font-family-sans)] - Font family.\n * @cssprop [--hx-help-text-font-size=var(--hx-font-size-sm)] - Font size.\n * @cssprop [--hx-help-text-font-weight=var(--hx-font-weight-normal)] - Font weight.\n * @cssprop [--hx-help-text-line-height=var(--hx-line-height-normal)] - Line height.\n * @cssprop [--hx-help-text-icon-gap=0.375rem] - Gap between icon and text.\n */\n@customElement('hx-help-text')\nexport class HelixHelpText extends LitElement {\n static override styles = [tokenStyles, helixHelpTextStyles];\n\n /**\n * Visual variant that determines the text color and icon.\n * Use `error` for validation errors, `warning` for cautions, `success` for confirmation.\n * @attr variant\n */\n @property({ type: String, reflect: true })\n variant: 'default' | 'error' | 'warning' | 'success' = 'default';\n\n override render() {\n const classes = {\n 'help-text': true,\n [`help-text--${this.variant}`]: true,\n };\n\n const icon = variantIcons[this.variant];\n const role = this.variant === 'error' ? 'alert' : undefined;\n const ariaLive =\n this.variant === 'warning' || this.variant === 'success' ? 'polite' : undefined;\n\n return html`<span\n part=\"base\"\n class=${classMap(classes)}\n role=${ifDefined(role)}\n aria-live=${ifDefined(ariaLive)}\n >${icon !== nothing\n ? html`<span part=\"icon\" class=\"help-text__icon\">${icon}</span>`\n : nothing}<span part=\"text\" class=\"help-text__text\"><slot></slot></span>\n </span>`;\n }\n}\n\n/** Canonical type alias for the hx-help-text component. */\nexport type HxHelpText = HelixHelpText;\n\n/** @deprecated Use {@link HxHelpText} instead. The `Wc` prefix was a legacy naming convention. */\nexport type WcHelpText = HelixHelpText;\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'hx-help-text': HelixHelpText;\n }\n}\n"],"names":["helixHelpTextStyles","css","errorIcon","html","warningIcon","successIcon","variantIcons","nothing","HelixHelpText","LitElement","classes","icon","role","ariaLive","classMap","ifDefined","tokenStyles","__decorateClass","property","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;;;;;;ACMnC,MAAMC,IAAYC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,SAeZC,IAAcD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,SAoBdE,IAAcF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,SAadG,IAAe;AAAA,EACnB,SAASC;AAAA,EACT,OAAOL;AAAA,EACP,SAASE;AAAA,EACT,SAASC;AACX;AA6BO,IAAMG,IAAN,cAA4BC,EAAW;AAAA,EAAvC,cAAA;AAAA,UAAA,GAAA,SAAA,GASL,KAAA,UAAuD;AAAA,EAAA;AAAA,EAE9C,SAAS;AAChB,UAAMC,IAAU;AAAA,MACd,aAAa;AAAA,MACb,CAAC,cAAc,KAAK,OAAO,EAAE,GAAG;AAAA,IAAA,GAG5BC,IAAOL,EAAa,KAAK,OAAO,GAChCM,IAAO,KAAK,YAAY,UAAU,UAAU,QAC5CC,IACJ,KAAK,YAAY,aAAa,KAAK,YAAY,YAAY,WAAW;AAExE,WAAOV;AAAA;AAAA,cAEGW,EAASJ,CAAO,CAAC;AAAA,aAClBK,EAAUH,CAAI,CAAC;AAAA,kBACVG,EAAUF,CAAQ,CAAC;AAAA,SAC5BF,MAASJ,IACRJ,8CAAiDQ,CAAI,YACrDJ,CAAO;AAAA;AAAA,EAEf;AACF;AAhCaC,EACK,SAAS,CAACQ,GAAahB,CAAmB;AAQ1DiB,EAAA;AAAA,EADCC,EAAS,EAAE,MAAM,QAAQ,SAAS,IAAM;AAAA,GAR9BV,EASX,WAAA,WAAA,CAAA;AATWA,IAANS,EAAA;AAAA,EADNE,EAAc,cAAc;AAAA,GAChBX,CAAA;"}
@@ -217,9 +217,7 @@ let o = class extends v {
217
217
  >
218
218
  ${this._iconSlot()}
219
219
  </button>
220
- ` : (console.warn(
221
- "[hx-icon-button] The `label` property is required for accessibility. Render suppressed."
222
- ), u);
220
+ ` : u;
223
221
  }
224
222
  };
225
223
  o.styles = [f, m];
@@ -254,4 +252,4 @@ o = r([
254
252
  export {
255
253
  o as H
256
254
  };
257
- //# sourceMappingURL=hx-icon-button-C_fsUJW4.js.map
255
+ //# sourceMappingURL=hx-icon-button-C83bCR0K.js.map