@mcp-b/web-components 0.2.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 (366) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +49 -0
  3. package/dist/accordion-B1Q3kuP_.d.ts +373 -0
  4. package/dist/accordion-item-DvPfhpm8.js +307 -0
  5. package/dist/accordion-item-bPRIahNn.d.ts +63 -0
  6. package/dist/accordion-zDr-Br4V.js +483 -0
  7. package/dist/action-bar-CYsjmhwP.d.ts +29 -0
  8. package/dist/action-bar-CjN_UcnP.js +56 -0
  9. package/dist/alert-dialog-4CnO3Nb5.d.ts +60 -0
  10. package/dist/alert-dialog-D25Oi_TS.js +126 -0
  11. package/dist/avatar-Bje_KpZo.d.ts +141 -0
  12. package/dist/avatar-CRP0kW3x.js +224 -0
  13. package/dist/badge-Ct95U4UO.js +301 -0
  14. package/dist/badge-D1DNQrWn.d.ts +106 -0
  15. package/dist/breadcrumb-BxZ-nQE5.d.ts +365 -0
  16. package/dist/breadcrumb-item-BC454oQe.d.ts +59 -0
  17. package/dist/breadcrumb-item-P5pdq_gE.js +151 -0
  18. package/dist/breadcrumb-uURhiqWJ.js +384 -0
  19. package/dist/button-5k_aL_gD.js +802 -0
  20. package/dist/button-BQofnUt4.d.ts +354 -0
  21. package/dist/button-group-BydvJTQy.js +197 -0
  22. package/dist/button-group-COodHeuB.d.ts +155 -0
  23. package/dist/callout-B8zTf8Go.js +188 -0
  24. package/dist/callout-DFwPao36.d.ts +103 -0
  25. package/dist/card-BYDzdMAU.d.ts +177 -0
  26. package/dist/card-DIg1-X2G.js +332 -0
  27. package/dist/carousel-Bktu7wrD.js +843 -0
  28. package/dist/carousel-DQITCtEY.d.ts +423 -0
  29. package/dist/carousel-item-B5-X31Ha.js +79 -0
  30. package/dist/carousel-item-BB3jL2tk.d.ts +34 -0
  31. package/dist/cdn/loader.js +530 -0
  32. package/dist/checkbox-D6r7PVPj.js +641 -0
  33. package/dist/checkbox-DoFcDEKB.d.ts +354 -0
  34. package/dist/checkbox-group-CLvNAO_F.js +201 -0
  35. package/dist/checkbox-group-Cnh8rAn4.d.ts +152 -0
  36. package/dist/color-input-Bky89xg_.d.ts +470 -0
  37. package/dist/color-input-DPIxi9wR.js +894 -0
  38. package/dist/color-picker-adwOmtRl.js +1240 -0
  39. package/dist/color-picker-wQw8bPsq.d.ts +360 -0
  40. package/dist/combobox-B6al50UG.js +1693 -0
  41. package/dist/combobox-item-D2H1CMxC.d.ts +714 -0
  42. package/dist/combobox-item-yM6tDrGG.js +225 -0
  43. package/dist/comparison-B1-nMwmp.d.ts +134 -0
  44. package/dist/comparison-CyqKrCN-.js +435 -0
  45. package/dist/components/accordion/accordion.d.ts +2 -0
  46. package/dist/components/accordion/accordion.js +2 -0
  47. package/dist/components/accordion-item/accordion-item.d.ts +2 -0
  48. package/dist/components/accordion-item/accordion-item.js +2 -0
  49. package/dist/components/action-bar/action-bar.d.ts +2 -0
  50. package/dist/components/action-bar/action-bar.js +2 -0
  51. package/dist/components/alert-dialog/alert-dialog.d.ts +2 -0
  52. package/dist/components/alert-dialog/alert-dialog.js +2 -0
  53. package/dist/components/avatar/avatar.d.ts +2 -0
  54. package/dist/components/avatar/avatar.js +2 -0
  55. package/dist/components/badge/badge.d.ts +2 -0
  56. package/dist/components/badge/badge.js +2 -0
  57. package/dist/components/breadcrumb/breadcrumb.d.ts +2 -0
  58. package/dist/components/breadcrumb/breadcrumb.js +2 -0
  59. package/dist/components/breadcrumb-item/breadcrumb-item.d.ts +2 -0
  60. package/dist/components/breadcrumb-item/breadcrumb-item.js +2 -0
  61. package/dist/components/button/button.d.ts +2 -0
  62. package/dist/components/button/button.js +2 -0
  63. package/dist/components/button-group/button-group.d.ts +2 -0
  64. package/dist/components/button-group/button-group.js +2 -0
  65. package/dist/components/callout/callout.d.ts +2 -0
  66. package/dist/components/callout/callout.js +2 -0
  67. package/dist/components/card/card.d.ts +2 -0
  68. package/dist/components/card/card.js +2 -0
  69. package/dist/components/carousel/carousel.d.ts +2 -0
  70. package/dist/components/carousel/carousel.js +2 -0
  71. package/dist/components/carousel-item/carousel-item.d.ts +2 -0
  72. package/dist/components/carousel-item/carousel-item.js +2 -0
  73. package/dist/components/checkbox/checkbox.d.ts +2 -0
  74. package/dist/components/checkbox/checkbox.js +2 -0
  75. package/dist/components/checkbox-group/checkbox-group.d.ts +2 -0
  76. package/dist/components/checkbox-group/checkbox-group.js +2 -0
  77. package/dist/components/color-input/color-input.d.ts +2 -0
  78. package/dist/components/color-input/color-input.js +2 -0
  79. package/dist/components/color-picker/color-picker.d.ts +2 -0
  80. package/dist/components/color-picker/color-picker.js +2 -0
  81. package/dist/components/combobox/combobox.d.ts +2 -0
  82. package/dist/components/combobox/combobox.js +2 -0
  83. package/dist/components/combobox-item/combobox-item.d.ts +2 -0
  84. package/dist/components/combobox-item/combobox-item.js +2 -0
  85. package/dist/components/comparison/comparison.d.ts +2 -0
  86. package/dist/components/comparison/comparison.js +2 -0
  87. package/dist/components/copy/copy.d.ts +2 -0
  88. package/dist/components/copy/copy.js +291 -0
  89. package/dist/components/data-table/data-table.d.ts +2 -0
  90. package/dist/components/data-table/data-table.js +2 -0
  91. package/dist/components/date/date.d.ts +2 -0
  92. package/dist/components/date/date.js +2 -0
  93. package/dist/components/dialog/dialog.d.ts +2 -0
  94. package/dist/components/dialog/dialog.js +2 -0
  95. package/dist/components/divider/divider.d.ts +2 -0
  96. package/dist/components/divider/divider.js +2 -0
  97. package/dist/components/dropdown/dropdown.d.ts +2 -0
  98. package/dist/components/dropdown/dropdown.js +2 -0
  99. package/dist/components/dropdown-item/dropdown-item.d.ts +2 -0
  100. package/dist/components/dropdown-item/dropdown-item.js +2 -0
  101. package/dist/components/empty-result/empty-result.d.ts +2 -0
  102. package/dist/components/empty-result/empty-result.js +2 -0
  103. package/dist/components/empty-state/empty-state.d.ts +2 -0
  104. package/dist/components/empty-state/empty-state.js +2 -0
  105. package/dist/components/expander/expander.d.ts +2 -0
  106. package/dist/components/expander/expander.js +2 -0
  107. package/dist/components/field/field.d.ts +2 -0
  108. package/dist/components/field/field.js +2 -0
  109. package/dist/components/file-input/file-input.d.ts +2 -0
  110. package/dist/components/file-input/file-input.js +2 -0
  111. package/dist/components/filter-bar/filter-bar.d.ts +2 -0
  112. package/dist/components/filter-bar/filter-bar.js +2 -0
  113. package/dist/components/form-section/form-section.d.ts +2 -0
  114. package/dist/components/form-section/form-section.js +2 -0
  115. package/dist/components/icon/icon.d.ts +2 -0
  116. package/dist/components/icon/icon.js +2 -0
  117. package/dist/components/include/include.d.ts +2 -0
  118. package/dist/components/include/include.js +2 -0
  119. package/dist/components/index.d.ts +85 -0
  120. package/dist/components/index.js +86 -0
  121. package/dist/components/infinite-scroller/infinite-scroller.d.ts +2 -0
  122. package/dist/components/infinite-scroller/infinite-scroller.js +2 -0
  123. package/dist/components/intersection-observer/intersection-observer.d.ts +2 -0
  124. package/dist/components/intersection-observer/intersection-observer.js +2 -0
  125. package/dist/components/listbox/listbox.d.ts +2 -0
  126. package/dist/components/listbox/listbox.js +2 -0
  127. package/dist/components/listbox-item/listbox-item.d.ts +2 -0
  128. package/dist/components/listbox-item/listbox-item.js +2 -0
  129. package/dist/components/lorem-ipsum/lorem-ipsum.d.ts +2 -0
  130. package/dist/components/lorem-ipsum/lorem-ipsum.js +2 -0
  131. package/dist/components/meter/meter.d.ts +2 -0
  132. package/dist/components/meter/meter.js +2 -0
  133. package/dist/components/metric/metric.d.ts +2 -0
  134. package/dist/components/metric/metric.js +2 -0
  135. package/dist/components/metric-grid/metric-grid.d.ts +2 -0
  136. package/dist/components/metric-grid/metric-grid.js +2 -0
  137. package/dist/components/mutation-observer/mutation-observer.d.ts +2 -0
  138. package/dist/components/mutation-observer/mutation-observer.js +2 -0
  139. package/dist/components/navicon/navicon.d.ts +2 -0
  140. package/dist/components/navicon/navicon.js +2 -0
  141. package/dist/components/number/number.d.ts +2 -0
  142. package/dist/components/number/number.js +2 -0
  143. package/dist/components/number-field/number-field.d.ts +2 -0
  144. package/dist/components/number-field/number-field.js +2 -0
  145. package/dist/components/pagination/pagination.d.ts +2 -0
  146. package/dist/components/pagination/pagination.js +2 -0
  147. package/dist/components/popover/popover.d.ts +2 -0
  148. package/dist/components/popover/popover.js +2 -0
  149. package/dist/components/preview-card/preview-card.d.ts +2 -0
  150. package/dist/components/preview-card/preview-card.js +2 -0
  151. package/dist/components/progress/progress.d.ts +2 -0
  152. package/dist/components/progress/progress.js +2 -0
  153. package/dist/components/radio/radio.d.ts +2 -0
  154. package/dist/components/radio/radio.js +2 -0
  155. package/dist/components/radio-item/radio-item.d.ts +2 -0
  156. package/dist/components/radio-item/radio-item.js +2 -0
  157. package/dist/components/random-content/random-content.d.ts +2 -0
  158. package/dist/components/random-content/random-content.js +2 -0
  159. package/dist/components/rating/rating.d.ts +2 -0
  160. package/dist/components/rating/rating.js +2 -0
  161. package/dist/components/resize-observer/resize-observer.d.ts +2 -0
  162. package/dist/components/resize-observer/resize-observer.js +2 -0
  163. package/dist/components/scroll-area/scroll-area.d.ts +2 -0
  164. package/dist/components/scroll-area/scroll-area.js +2 -0
  165. package/dist/components/scroller/scroller.d.ts +2 -0
  166. package/dist/components/scroller/scroller.js +2 -0
  167. package/dist/components/search-list/search-list.d.ts +2 -0
  168. package/dist/components/search-list/search-list.js +2 -0
  169. package/dist/components/select/select.d.ts +2 -0
  170. package/dist/components/select/select.js +2 -0
  171. package/dist/components/selection-summary/selection-summary.d.ts +2 -0
  172. package/dist/components/selection-summary/selection-summary.js +2 -0
  173. package/dist/components/share/share.d.ts +2 -0
  174. package/dist/components/share/share.js +2 -0
  175. package/dist/components/slide-activator/slide-activator.d.ts +2 -0
  176. package/dist/components/slide-activator/slide-activator.js +2 -0
  177. package/dist/components/slider/slider.d.ts +2 -0
  178. package/dist/components/slider/slider.js +2 -0
  179. package/dist/components/sparkline/sparkline.d.ts +2 -0
  180. package/dist/components/sparkline/sparkline.js +2 -0
  181. package/dist/components/spinner/spinner.d.ts +2 -0
  182. package/dist/components/spinner/spinner.js +2 -0
  183. package/dist/components/splitter/splitter.d.ts +2 -0
  184. package/dist/components/splitter/splitter.js +2 -0
  185. package/dist/components/switch/switch.d.ts +2 -0
  186. package/dist/components/switch/switch.js +2 -0
  187. package/dist/components/tab/tab.d.ts +2 -0
  188. package/dist/components/tab/tab.js +2 -0
  189. package/dist/components/tab-list/tab-list.d.ts +2 -0
  190. package/dist/components/tab-list/tab-list.js +2 -0
  191. package/dist/components/tab-panel/tab-panel.d.ts +2 -0
  192. package/dist/components/tab-panel/tab-panel.js +2 -0
  193. package/dist/components/text-area/text-area.d.ts +2 -0
  194. package/dist/components/text-area/text-area.js +2 -0
  195. package/dist/components/text-field/text-field.d.ts +2 -0
  196. package/dist/components/text-field/text-field.js +2 -0
  197. package/dist/components/text-mask/text-mask.d.ts +2 -0
  198. package/dist/components/text-mask/text-mask.js +2 -0
  199. package/dist/components/timed-content/timed-content.d.ts +2 -0
  200. package/dist/components/timed-content/timed-content.js +2 -0
  201. package/dist/components/toast/toast.d.ts +2 -0
  202. package/dist/components/toast/toast.js +2 -0
  203. package/dist/components/toast-item/toast-item.d.ts +2 -0
  204. package/dist/components/toast-item/toast-item.js +2 -0
  205. package/dist/components/toggle-icon/toggle-icon.d.ts +2 -0
  206. package/dist/components/toggle-icon/toggle-icon.js +2 -0
  207. package/dist/components/toggle-tag/toggle-tag.d.ts +2 -0
  208. package/dist/components/toggle-tag/toggle-tag.js +2 -0
  209. package/dist/components/toolbar/toolbar.d.ts +2 -0
  210. package/dist/components/toolbar/toolbar.js +2 -0
  211. package/dist/components/tooltip/tooltip.d.ts +2 -0
  212. package/dist/components/tooltip/tooltip.js +2 -0
  213. package/dist/components/transition-group/transition-group.d.ts +2 -0
  214. package/dist/components/transition-group/transition-group.js +2 -0
  215. package/dist/components/zoomable-frame/zoomable-frame.d.ts +2 -0
  216. package/dist/components/zoomable-frame/zoomable-frame.js +2 -0
  217. package/dist/copy-CvC9vaGw.d.ts +206 -0
  218. package/dist/copy.styles-DWGvGNTP.js +100 -0
  219. package/dist/data-table-CITa8DSn.js +247 -0
  220. package/dist/data-table-DL5RhE0d.d.ts +89 -0
  221. package/dist/date-CJPmOdi9.js +146 -0
  222. package/dist/date-DtaTBM71.d.ts +142 -0
  223. package/dist/decorate-DcF3lt7P.js +9 -0
  224. package/dist/dialog-Cx46HMaZ.js +983 -0
  225. package/dist/dialog-N-v0woIy.d.ts +414 -0
  226. package/dist/divider-9vNsfHW8.js +169 -0
  227. package/dist/divider-DWuAxcXv.d.ts +79 -0
  228. package/dist/docs/custom-elements.json +29301 -0
  229. package/dist/dropdown-BXSKpVX9.js +1123 -0
  230. package/dist/dropdown-Bo00Vlr5.d.ts +537 -0
  231. package/dist/dropdown-item-_lIs-Tfd.d.ts +111 -0
  232. package/dist/dropdown-item-i77cRuN6.js +504 -0
  233. package/dist/empty-result-B2ln1yFL.js +65 -0
  234. package/dist/empty-result-B54x_Ab2.d.ts +31 -0
  235. package/dist/empty-state-BLWjtKUo.js +186 -0
  236. package/dist/empty-state-SGKjpwp3.d.ts +117 -0
  237. package/dist/expander-BUev0BmM.d.ts +174 -0
  238. package/dist/expander-Bwvxj6Oa.js +342 -0
  239. package/dist/field-BEyS909F.js +163 -0
  240. package/dist/field-ITx0jVw-.d.ts +69 -0
  241. package/dist/file-input-BEumLJjg.js +841 -0
  242. package/dist/file-input-D2D6YC0B.d.ts +378 -0
  243. package/dist/filter-bar-Bj2QzEn9.d.ts +35 -0
  244. package/dist/filter-bar-Dcs67aXo.js +66 -0
  245. package/dist/form-section-BchPetkj.js +83 -0
  246. package/dist/form-section-xFBTBULQ.d.ts +34 -0
  247. package/dist/icon-BPVkNsY4.js +165 -0
  248. package/dist/icon-Ci9CPZJV.d.ts +72 -0
  249. package/dist/icon-library-D_if7p2h.d.ts +2 -0
  250. package/dist/include-CQHVVtNs.d.ts +103 -0
  251. package/dist/include-qNUh_6kT.js +155 -0
  252. package/dist/index.d.ts +89 -0
  253. package/dist/index.js +92 -0
  254. package/dist/infinite-scroller-BmmtnWNt.js +285 -0
  255. package/dist/infinite-scroller-CuUEAlB9.d.ts +174 -0
  256. package/dist/intersection-observer-B6TciOAQ.js +503 -0
  257. package/dist/intersection-observer-B7nmP7Zz.d.ts +418 -0
  258. package/dist/listbox-C3XXRWGX.js +1257 -0
  259. package/dist/listbox-DD4ujIJe.d.ts +682 -0
  260. package/dist/listbox-item-CwD9s3VY.js +135 -0
  261. package/dist/listbox-item-DQEJWp4Z.d.ts +53 -0
  262. package/dist/localize-322EtXNX.d.ts +66 -0
  263. package/dist/lorem-ipsum-B2x3V-v8.js +198 -0
  264. package/dist/lorem-ipsum-CR82CSuJ.d.ts +130 -0
  265. package/dist/meter-BC7uaJWf.d.ts +73 -0
  266. package/dist/meter-BIDyjwFp.js +155 -0
  267. package/dist/metric-CjlLq_VA.d.ts +36 -0
  268. package/dist/metric-DbuOcDp_.js +86 -0
  269. package/dist/metric-grid-C2Pb0Zl3.js +37 -0
  270. package/dist/metric-grid-C5Xbb1_0.d.ts +27 -0
  271. package/dist/mutation-observer-BmrZ-GER.d.ts +326 -0
  272. package/dist/mutation-observer-DS8EBuOp.js +388 -0
  273. package/dist/navicon-Dic5Qjzb.d.ts +159 -0
  274. package/dist/navicon-_yMHY27-.js +486 -0
  275. package/dist/number-BNtNXNF3.js +162 -0
  276. package/dist/number-BwbnErlB.d.ts +143 -0
  277. package/dist/number-field-BQHB7UYo.js +726 -0
  278. package/dist/number-field-odk4lKXM.d.ts +422 -0
  279. package/dist/pagination-6z2qcf3U.d.ts +322 -0
  280. package/dist/pagination-DuKPuzdb.js +679 -0
  281. package/dist/popover-D0sxTU6o.d.ts +259 -0
  282. package/dist/popover-DJBrJ0za.js +556 -0
  283. package/dist/preview-card-C7H1FPfd.js +287 -0
  284. package/dist/preview-card-DitOCZTD.d.ts +86 -0
  285. package/dist/progress-Db0_axHQ.d.ts +181 -0
  286. package/dist/progress-DzVk260j.js +494 -0
  287. package/dist/radio-BtDG9xJM.js +658 -0
  288. package/dist/radio-CieMa4zU.d.ts +460 -0
  289. package/dist/radio-item-DIrUStAX.js +264 -0
  290. package/dist/radio-item-Xq2U3cMu.d.ts +69 -0
  291. package/dist/random-content-BhSeJFKz.d.ts +380 -0
  292. package/dist/random-content-BwiirXdG.js +450 -0
  293. package/dist/rating-4xNsWumY.d.ts +369 -0
  294. package/dist/rating-C1BcJDIO.js +722 -0
  295. package/dist/resize-observer-BseSbVWP.d.ts +187 -0
  296. package/dist/resize-observer-DcrLhddo.js +236 -0
  297. package/dist/scroll-area-COc1857S.js +127 -0
  298. package/dist/scroll-area-CVYDf5qY.d.ts +61 -0
  299. package/dist/scroller-LYgBVyfY.js +590 -0
  300. package/dist/scroller-bB2rGs7b.d.ts +374 -0
  301. package/dist/search-list-Clmrg8EV.js +884 -0
  302. package/dist/search-list-n0GYO7rh.d.ts +777 -0
  303. package/dist/select-CkZK2jJn.d.ts +506 -0
  304. package/dist/select-DLIaRnA4.js +690 -0
  305. package/dist/selection-summary-BVnNJ8Lw.js +48 -0
  306. package/dist/selection-summary-DmFkGyZI.d.ts +34 -0
  307. package/dist/share-DPlqP2dc.d.ts +162 -0
  308. package/dist/share-bsgXZCl7.js +250 -0
  309. package/dist/sigvelo.d.ts +5 -0
  310. package/dist/sigvelo.js +5 -0
  311. package/dist/sigvelo.loader.d.ts +3 -0
  312. package/dist/sigvelo.loader.js +102 -0
  313. package/dist/slide-activator-D7bBz69E.d.ts +429 -0
  314. package/dist/slide-activator-DlxQt9R9.js +798 -0
  315. package/dist/slider-B0FVsV1o.d.ts +921 -0
  316. package/dist/slider-B90Il7x3.js +1744 -0
  317. package/dist/sparkline-CcpTaJ_Z.js +358 -0
  318. package/dist/sparkline-DlCIt81-.d.ts +235 -0
  319. package/dist/spinner-C04Dmc0H.js +188 -0
  320. package/dist/spinner-CZ19x_dC.d.ts +99 -0
  321. package/dist/splitter-DBDJAzsp.d.ts +325 -0
  322. package/dist/splitter-MnD4In9H.js +638 -0
  323. package/dist/switch-CPaEKbog.js +581 -0
  324. package/dist/switch-Cief9M59.d.ts +248 -0
  325. package/dist/tab-BcqYGsuW.d.ts +44 -0
  326. package/dist/tab-C-FtuNmh.js +102 -0
  327. package/dist/tab-list-B_Ye_Oj9.js +691 -0
  328. package/dist/tab-list-DDvS8qHr.d.ts +450 -0
  329. package/dist/tab-panel-BaBl6eep.js +60 -0
  330. package/dist/tab-panel-BzSJlSfd.d.ts +38 -0
  331. package/dist/text-area-B_mjCE9W.d.ts +327 -0
  332. package/dist/text-area-Czixaz-_.js +556 -0
  333. package/dist/text-field-BClWMp6q.d.ts +424 -0
  334. package/dist/text-field-inpJfp0A.js +687 -0
  335. package/dist/text-mask-CNKVKSFp.d.ts +336 -0
  336. package/dist/text-mask-DDEurj90.js +370 -0
  337. package/dist/themes/sigvelo.css +10 -0
  338. package/dist/themes/utilities.css +9 -0
  339. package/dist/timed-content-D2mGFamc.d.ts +181 -0
  340. package/dist/timed-content-pvEP4l5V.js +226 -0
  341. package/dist/toast-BnZaIg6Z.js +636 -0
  342. package/dist/toast-cEBVK9NQ.d.ts +487 -0
  343. package/dist/toast-item-BPpJT6vD.d.ts +159 -0
  344. package/dist/toast-item-IS8IFUEg.js +372 -0
  345. package/dist/toggle-icon-4oLDeEt4.js +752 -0
  346. package/dist/toggle-icon-DlwMMWZL.d.ts +359 -0
  347. package/dist/toggle-tag-1sfTFJtg.js +434 -0
  348. package/dist/toggle-tag-IVvMGT4R.d.ts +245 -0
  349. package/dist/toolbar-CABq0ZL1.d.ts +122 -0
  350. package/dist/toolbar-CEZ0-F-X.js +196 -0
  351. package/dist/tooltip-DbyoPFNe.js +521 -0
  352. package/dist/tooltip-ahFthek8.d.ts +192 -0
  353. package/dist/transition-group-3hnAnwSd.js +801 -0
  354. package/dist/transition-group-DD_CjSNC.d.ts +608 -0
  355. package/dist/translations/en.d.ts +6 -0
  356. package/dist/translations/en.js +75 -0
  357. package/dist/translations/es.d.ts +6 -0
  358. package/dist/translations/es.js +75 -0
  359. package/dist/types/custom-element-jsx.d.ts +13723 -0
  360. package/dist/utilities/icon-library.d.ts +3 -0
  361. package/dist/utilities/icon-library.js +93 -0
  362. package/dist/utilities/localize.d.ts +2 -0
  363. package/dist/utilities/localize.js +6 -0
  364. package/dist/zoomable-frame-Cldvj5sE.js +398 -0
  365. package/dist/zoomable-frame-r6S6587z.d.ts +162 -0
  366. package/package.json +83 -0
@@ -0,0 +1,1257 @@
1
+ import { Localize } from "./utilities/localize.js";
2
+ import { t as __decorate } from "./decorate-DcF3lt7P.js";
3
+ import "./listbox-item-CwD9s3VY.js";
4
+ import { css, html } from "lit";
5
+ import { property, query, state } from "lit/decorators.js";
6
+ import hostStyles from "@mcp-b/wc-support/styles/host.styles";
7
+ import { SigveloFormControlElement } from "@mcp-b/wc-support/base/sigvelo-element";
8
+ import { classMap } from "lit/directives/class-map.js";
9
+ import { SigveloBlurEvent, SigveloChangeEvent, SigveloFocusEvent, SigveloInputEvent } from "@mcp-b/wc-support/events/form";
10
+ import formControlStyles from "@mcp-b/wc-support/styles/form-control.styles";
11
+ //#region src/components/listbox/listbox.styles.ts
12
+ var listbox_styles_default = css`
13
+ #listbox {
14
+ display: flex;
15
+ flex-direction: column;
16
+ height: 12.125em;
17
+ padding: 0.25em 0;
18
+ padding: 0.25em;
19
+ overflow: auto;
20
+ border: var(--sigvelo-border-style) var(--sigvelo-border-width)
21
+ var(--sigvelo-color-neutral-border-muted);
22
+ border-radius: var(--sigvelo-radius-md);
23
+ background-color: var(--sigvelo-color-surface);
24
+ scrollbar-color: var(--sigvelo-color-neutral-bg) transparent;
25
+ scrollbar-width: thin;
26
+ }
27
+
28
+ /* Focus state for the listbox */
29
+ :host(:state(focused)) #listbox {
30
+ outline: var(--sigvelo-border-style) calc(var(--sigvelo-border-width) + 1px)
31
+ var(--sigvelo-color-focus);
32
+ outline-offset: calc(-1 * var(--sigvelo-border-width));
33
+ }
34
+
35
+ :host(:state(disabled)),
36
+ :host(:state(disabled)) ::slotted(sigvelo-listbox-item) {
37
+ cursor: not-allowed;
38
+ opacity: 0.5;
39
+ }
40
+
41
+ .readonly ::slotted(sigvelo-listbox-item) {
42
+ cursor: default;
43
+ }
44
+ `;
45
+ //#endregion
46
+ //#region src/components/listbox/listbox.ts
47
+ const nativeFileInput = document.createElement("input");
48
+ nativeFileInput.name = "sigvelo-faux-input";
49
+ nativeFileInput.type = "text";
50
+ nativeFileInput.required = true;
51
+ const VALIDATION_MESSAGE = nativeFileInput.validationMessage;
52
+ /**
53
+ * <sigvelo-listbox>
54
+ *
55
+ * @summary Displays a list of options, allowing users to select one or more items from the available choices.
56
+ * @tag sigvelo-listbox
57
+ * @documentation https://design-system.sigvelo.com/docs/components/listbox
58
+ * @status stable
59
+ * @since 1.0
60
+ *
61
+ * @dependency listbox-item
62
+ *
63
+ * @slot - Listbox items to show in the listbox.
64
+ * @slot label - The listbox's label. For plain-text labels, you can use the `label` attribute instead.
65
+ * @slot description - The listbox's description. For plain-text descriptions, you can use the `description` attribute
66
+ * instead.
67
+ *
68
+ * @event sigvelo-blur - Emitted when the list box loses focus. This event does not bubble.
69
+ * @event sigvelo-change - Emitted when the user commits changes to the list box's selection. In single select mode, it
70
+ * occurs when a change is made and the listbox loses focus. In multiselect mode, it occurs whenever an option is
71
+ * toggled even while the listbox has focus.
72
+ * @event sigvelo-focus - Emitted when the list box receives focus. This event does not bubble.
73
+ * @event sigvelo-input - Emitted when the list box's selection changes from user input.
74
+ *
75
+ * @csspart label - The element that contains the text field's label.
76
+ * @csspart description - The element that contains the text field's description.
77
+ * @csspart listbox - The internal listbox container that holds listbox items.
78
+ *
79
+ * @cssstate disabled - Applied when the text field is disabled.
80
+ * @cssstate blank - Applied when the text field has a blank value.
81
+ * @cssstate focused - Applied when the text field has focus.
82
+ * @cssstate user-valid - Applied when the text field is valid and the user has sufficiently interacted with it.
83
+ * @cssstate user-invalid - Applied when the text field is invalid and the user has sufficiently interacted with it.
84
+ *
85
+ * @example Default
86
+ * Listboxes follow the ARIA APG listbox pattern for accessibility. The listbox is labeled for assistive devices and listbox items are announced as options. To function more like native listboxes, the alternate selection model is used for keyboard interaction.
87
+ *
88
+ * ```html
89
+ * <sigvelo-listbox label="Our kittens" description="Select your new friends." multiple>
90
+ * <sigvelo-listbox-item value="1">Bella</sigvelo-listbox-item>
91
+ * <sigvelo-listbox-item value="2">Luna</sigvelo-listbox-item>
92
+ * <sigvelo-listbox-item value="3">Meowy McGee</sigvelo-listbox-item>
93
+ * <sigvelo-listbox-item value="4">Milo</sigvelo-listbox-item>
94
+ * <sigvelo-listbox-item value="5">Mittens</sigvelo-listbox-item>
95
+ * <sigvelo-listbox-item value="6">Oliver</sigvelo-listbox-item>
96
+ * <sigvelo-listbox-item value="7">Pepper</sigvelo-listbox-item>
97
+ * <sigvelo-listbox-item value="8">Shadow</sigvelo-listbox-item>
98
+ * <sigvelo-listbox-item value="9">Simba</sigvelo-listbox-item>
99
+ * <sigvelo-listbox-item value="10">Whiskers</sigvelo-listbox-item>
100
+ * </sigvelo-listbox>
101
+ * ```
102
+ *
103
+ * @example Labels and descriptions
104
+ * You can use the `label` and `description` attributes to provide plain text labels and descriptions for the listbox. If you want to provide HTML, use the `label` and `description` slots instead.
105
+ *
106
+ * ```html
107
+ * <sigvelo-listbox>
108
+ * <span slot="label">Feline <strong>Friends</strong></span>
109
+ * <span slot="description">
110
+ * For adoption information, <a href="https://example.com/" target="_blank">visit our cat sanctuary</a>.
111
+ * </span>
112
+ * <sigvelo-listbox-item value="1">Whiskers (3 years old)</sigvelo-listbox-item>
113
+ * <sigvelo-listbox-item value="2">Mittens (2 years old)</sigvelo-listbox-item>
114
+ * <sigvelo-listbox-item value="3">Shadow (5 years old)</sigvelo-listbox-item>
115
+ * </sigvelo-listbox>
116
+ * ```
117
+ *
118
+ * @example Providing options
119
+ * Create listbox options by adding `<sigvelo-listbox-item>` elements inside the listbox. Each item should have a `value` attribute that will be submitted with the form.
120
+ *
121
+ * ```html
122
+ * <sigvelo-listbox label="Favorite Cat Toys">
123
+ * <sigvelo-listbox-item value="feather">Feather Wand</sigvelo-listbox-item>
124
+ * <sigvelo-listbox-item value="laser">Laser Pointer</sigvelo-listbox-item>
125
+ * <sigvelo-listbox-item value="catnip">Catnip Mouse</sigvelo-listbox-item>
126
+ * <sigvelo-listbox-item value="tunnel">Crinkle Tunnel</sigvelo-listbox-item>
127
+ * <sigvelo-listbox-item value="box">Cardboard Box</sigvelo-listbox-item>
128
+ * </sigvelo-listbox>
129
+ * ```
130
+ *
131
+ * Listbox items can have structured content, too.
132
+ *
133
+ * ```html
134
+ * <sigvelo-listbox label="Favorite Cat Toys" id="listbox__options">
135
+ * <sigvelo-listbox-item value="feather">
136
+ * <h4>Feather Wand</h4>
137
+ * <small aria-hidden="true">Interactive toy that mimics bird movements</small>
138
+ * </sigvelo-listbox-item>
139
+ * <sigvelo-listbox-item value="laser">
140
+ * <h4>Laser Pointer</h4>
141
+ * <small aria-hidden="true">Creates a moving red dot for cats to chase</small>
142
+ * </sigvelo-listbox-item>
143
+ * <sigvelo-listbox-item value="catnip">
144
+ * <h4>Catnip Mouse</h4>
145
+ * <small aria-hidden="true">Soft toy filled with enticing catnip</small>
146
+ * </sigvelo-listbox-item>
147
+ * <sigvelo-listbox-item value="tunnel">
148
+ * <h4>Crinkle Tunnel</h4>
149
+ * <small aria-hidden="true">Collapsible tunnel with crinkly material cats love</small>
150
+ * </sigvelo-listbox-item>
151
+ * <sigvelo-listbox-item value="box">
152
+ * <h4>Cardboard Box</h4>
153
+ * <small aria-hidden="true">Simple but beloved hiding spot for feline friends</small>
154
+ * </sigvelo-listbox-item>
155
+ * </sigvelo-listbox>
156
+ *
157
+ * <style>
158
+ * #listbox__options {
159
+ * &::part(listbox) {
160
+ * height: auto;
161
+ * }
162
+ *
163
+ * h4 {
164
+ * font-size: 1.125rem;
165
+ * font-weight: var(--sigvelo-font-weight-semibold);
166
+ * line-height: 1.4;
167
+ * margin-block: 0;
168
+ * }
169
+ *
170
+ * sigvelo-listbox-item:state(selected) small {
171
+ * color: var(--sigvelo-color-primary-text-on-subtle);
172
+ * }
173
+ * }
174
+ * </style>
175
+ * ```
176
+ *
177
+ * **Warning:** Avoid placing interactive elements such as buttons and links inside the listbox item, as this will hinder accessibility and can lead to unexpected behaviors.
178
+ *
179
+ * @example Providing an initial value
180
+ * Add the `selected` attribute to the listbox item you want to select initially. When using `multiple`, you can apply `selected` to more than one option.
181
+ *
182
+ * ```html
183
+ * <sigvelo-listbox label="Favorite Nap Location">
184
+ * <sigvelo-listbox-item value="windowsill">Sunny Windowsill</sigvelo-listbox-item>
185
+ * <sigvelo-listbox-item value="lap" selected>Human's Lap</sigvelo-listbox-item>
186
+ * <sigvelo-listbox-item value="bed">Middle of the Bed</sigvelo-listbox-item>
187
+ * <sigvelo-listbox-item value="keyboard">Computer Keyboard</sigvelo-listbox-item>
188
+ * </sigvelo-listbox>
189
+ * ```
190
+ *
191
+ * @example Getting and setting the selection
192
+ * Listboxes provide several properties for interacting with their selection state programmatically. Use the `value` property for getting/setting a single value. Use the `selectedValues` property for multiple values. If you need to get or set a list of selected `<sigvelo-listbox-item>` elements, use the `selectedItems` property.
193
+ *
194
+ * #### Getting the selection
195
+ *
196
+ * Use `value` to get a single value. To get all selected values, use `selectedValues`. If you need to get an array of DOM elements, use `selectedItems`.
197
+ *
198
+ * ```js
199
+ * // Get the first selected value
200
+ * const value = listbox.value;
201
+ *
202
+ * // Get an array of all selected values
203
+ * const values = listbox.selectedValues;
204
+ *
205
+ * // Get an array of all selected listbox item elements
206
+ * const items = listbox.selectedItems;
207
+ * ```
208
+ *
209
+ * #### Setting the selection
210
+ *
211
+ * Use `value` to set a single value. To set multiple values, use `selectedValues`. If you need to get or set the selection via DOM elements, use `selectedItems`.
212
+ *
213
+ * ```js
214
+ * // Set a single value
215
+ * listbox.value = 'a';
216
+ *
217
+ * // Set multiple values
218
+ * listbox.selectedValues = ['a', 'b', 'c'];
219
+ *
220
+ * // Set using DOM elements
221
+ * const itemA = document.querySelector('sigvelo-listbox-item#a');
222
+ * const itemB = document.querySelector('sigvelo-listbox-item#b');
223
+ * const itemC = document.querySelector('sigvelo-listbox-item#c');
224
+ *
225
+ * listbox.selectedItems = [itemA, itemB, itemC];
226
+ * ```
227
+ *
228
+ * #### Convenience methods
229
+ *
230
+ * Use `selectAll()` and `deselectAll()` as a quick way to select all or no items.
231
+ *
232
+ * ```js
233
+ * // Select all items
234
+ * listbox.selectAll();
235
+ *
236
+ * // Deselect all items
237
+ * listbox.deselectAll();
238
+ * ```
239
+ *
240
+ * @example Disabling items
241
+ * Add the `disabled` attribute to individual listbox items to make them non-selectable.
242
+ *
243
+ * ```html
244
+ * <sigvelo-listbox label="Feeding Schedule">
245
+ * <sigvelo-listbox-item value="morning">Morning (7am)</sigvelo-listbox-item>
246
+ * <sigvelo-listbox-item value="noon">Noon (12pm)</sigvelo-listbox-item>
247
+ * <sigvelo-listbox-item value="night" disabled>Night (10pm) - Currently unavailable</sigvelo-listbox-item>
248
+ * </sigvelo-listbox>
249
+ * ```
250
+ *
251
+ * @example Multiple selection
252
+ * Use the `multiple` attribute to enable multi-selection mode. Users can select multiple items using <sigvelo-hotkey keys="$command" platform="mac"></sigvelo-hotkey> or <sigvelo-hotkey keys="$control" platform="windows"></sigvelo-hotkey> + click, <sigvelo-hotkey keys="$shift"></sigvelo-hotkey> + click for ranges, or <sigvelo-hotkey keys="$cmdctrl A"></sigvelo-hotkey> to select all. For coarse pointers, such as touch, tapping an item will toggle the selection.
253
+ *
254
+ * ```html
255
+ * <sigvelo-listbox label="Kitty Behavior" description="Select your cat's typical antics." multiple>
256
+ * <sigvelo-listbox-item value="1">Midnight Zoomies</sigvelo-listbox-item>
257
+ * <sigvelo-listbox-item value="2" selected>Knocking Things Off Tables</sigvelo-listbox-item>
258
+ * <sigvelo-listbox-item value="3" selected>Ignoring Expensive Toys</sigvelo-listbox-item>
259
+ * <sigvelo-listbox-item value="4">Sitting on Open Books</sigvelo-listbox-item>
260
+ * <sigvelo-listbox-item value="5">Watching Birds Through Windows</sigvelo-listbox-item>
261
+ * <sigvelo-listbox-item value="6">Following You to the Bathroom</sigvelo-listbox-item>
262
+ * <sigvelo-listbox-item value="7" selected>Demanding Pets Then Biting</sigvelo-listbox-item>
263
+ * <sigvelo-listbox-item value="8">Sleeping in Weird Positions</sigvelo-listbox-item>
264
+ * <sigvelo-listbox-item value="9">Hiding in Paper Bags</sigvelo-listbox-item>
265
+ * <sigvelo-listbox-item value="10">Sudden Grooming Sessions</sigvelo-listbox-item>
266
+ * </sigvelo-listbox>
267
+ * ```
268
+ *
269
+ * @example Changing the size
270
+ * Use the `size` attribute to change the listbox's size.
271
+ *
272
+ * ```html
273
+ * <sigvelo-select label="Select a size" style="max-width: 18rem; margin-block-end: 2rem;">
274
+ * <option value="xs">Extra small</option>
275
+ * <option value="sm">Small</option>
276
+ * <option value="md">Medium</option>
277
+ * <option value="lg">Large</option>
278
+ * <option value="xl">Extra large</option>
279
+ * </sigvelo-select>
280
+ *
281
+ * <sigvelo-listbox
282
+ * size="xs"
283
+ * label="Cat Accessories"
284
+ * description="Size changes dynamically based on selection above"
285
+ * id="listbox__size"
286
+ * multiple
287
+ * >
288
+ * <sigvelo-listbox-item value="cat-tree">Cat Tree</sigvelo-listbox-item>
289
+ * <sigvelo-listbox-item value="food-bowl">Food Bowl</sigvelo-listbox-item>
290
+ * <sigvelo-listbox-item value="scratching-post">Scratching Post</sigvelo-listbox-item>
291
+ * <sigvelo-listbox-item value="toy-mouse">Toy Mouse</sigvelo-listbox-item>
292
+ * </sigvelo-listbox>
293
+ *
294
+ * <script>
295
+ * const listbox = document.getElementById('listbox__size');
296
+ * const select = listbox.previousElementSibling;
297
+ *
298
+ * select.addEventListener('sigvelo-change', () => {
299
+ * listbox.size = select.value;
300
+ * });
301
+ * <\/script>
302
+ * ```
303
+ *
304
+ * @example Disabling
305
+ * Add the `disabled` attribute to disable the entire listbox.
306
+ *
307
+ * ```html
308
+ * <sigvelo-listbox label="Treat Options" description="Treats temporarily unavailable." disabled>
309
+ * <sigvelo-listbox-item value="1">Tuna Treats</sigvelo-listbox-item>
310
+ * <sigvelo-listbox-item value="2" selected>Chicken Bites</sigvelo-listbox-item>
311
+ * <sigvelo-listbox-item value="3">Salmon Flakes</sigvelo-listbox-item>
312
+ * <sigvelo-listbox-item value="4">Cheese Nibbles</sigvelo-listbox-item>
313
+ * <sigvelo-listbox-item value="5">Catnip Crisps</sigvelo-listbox-item>
314
+ * </sigvelo-listbox>
315
+ * ```
316
+ *
317
+ * @example Showing labels on the side
318
+ * With the `sigvelo-side-label` utility, you can show labels on the side instead of on top of the listbox. You can control the width of the label by setting the `--label-width` custom property.
319
+ *
320
+ * ```html
321
+ * <sigvelo-listbox
322
+ * class="sigvelo-side-label"
323
+ * style="--label-width: 10ch;"
324
+ * name="fur"
325
+ * label="Fur Type"
326
+ * description="What's your cat's coat like?"
327
+ * >
328
+ * <sigvelo-listbox-item value="short">Short-haired</sigvelo-listbox-item>
329
+ * <sigvelo-listbox-item value="long">Long-haired</sigvelo-listbox-item>
330
+ * <sigvelo-listbox-item value="curly">Curly-coated</sigvelo-listbox-item>
331
+ * </sigvelo-listbox>
332
+ * <br>
333
+ * <sigvelo-listbox
334
+ * class="sigvelo-side-label"
335
+ * style="--label-width: 10ch;"
336
+ * name="eye"
337
+ * label="Eye Color"
338
+ * description="What color are your cat's eyes?"
339
+ * >
340
+ * <sigvelo-listbox-item value="green">Green</sigvelo-listbox-item>
341
+ * <sigvelo-listbox-item value="blue">Blue</sigvelo-listbox-item>
342
+ * <sigvelo-listbox-item value="amber">Amber</sigvelo-listbox-item>
343
+ * </sigvelo-listbox>
344
+ * ```
345
+ *
346
+ * @example Validation
347
+ * The `required` attribute can be used to enable validation using the Constraint Validation API.
348
+ *
349
+ * ```html
350
+ * <form action="about:blank" method="get" target="_blank">
351
+ * <sigvelo-listbox name="meow" label="Meow Volume" required>
352
+ * <sigvelo-listbox-item value="1">Barely Audible</sigvelo-listbox-item>
353
+ * <sigvelo-listbox-item value="2">Conversational</sigvelo-listbox-item>
354
+ * <sigvelo-listbox-item value="3">Wake the Neighbors</sigvelo-listbox-item>
355
+ * </sigvelo-listbox>
356
+ * <br>
357
+ * <sigvelo-button type="submit" color="primary">Submit</sigvelo-button>
358
+ * <sigvelo-button type="reset">Reset</sigvelo-button>
359
+ * </form>
360
+ * ```
361
+ *
362
+ * @example Using custom validation
363
+ * Use the `setCustomValidity()` method to make the listbox invalid and show a custom error message on submit. This will override all other validation parameters. To clear the error, call the method with an empty string.
364
+ *
365
+ * ```html
366
+ * <form action="about:blank" method="get" target="_blank" id="listbox__custom-validation">
367
+ * <sigvelo-listbox
368
+ * name="purr"
369
+ * label="Purr Intensity"
370
+ * description="This field will be invalid until custom validation is removed"
371
+ * >
372
+ * <sigvelo-listbox-item value="1">Gentle Rumble</sigvelo-listbox-item>
373
+ * <sigvelo-listbox-item value="2">Medium Motor</sigvelo-listbox-item>
374
+ * <sigvelo-listbox-item value="3">Thunderous Vibration</sigvelo-listbox-item>
375
+ * </sigvelo-listbox>
376
+ * <br>
377
+ * <sigvelo-button type="submit" color="primary">Submit</sigvelo-button>
378
+ * </form>
379
+ *
380
+ * <script type="module">
381
+ * import { allDefined } from '/dist/sigvelo.js';
382
+ *
383
+ * await allDefined();
384
+ *
385
+ * const form = document.getElementById('listbox__custom-validation');
386
+ * const listbox = form.querySelector('sigvelo-listbox');
387
+ *
388
+ * listbox.setCustomValidity('Not so fast, bubba!');
389
+ * <\/script>
390
+ * ```
391
+ *
392
+ * @example Styling validation
393
+ * You can style valid and invalid listboxes using the `:valid` and `:invalid` pseudo classes.
394
+ *
395
+ * ```html
396
+ * <form action="about:blank" method="get" target="_blank" class="listbox__validation-pseudo">
397
+ * <sigvelo-listbox
398
+ * name="claws"
399
+ * label="Claw Trimming"
400
+ * description="This field is required for grooming appointments"
401
+ * required
402
+ * >
403
+ * <sigvelo-listbox-item value="1">Front Paws Only</sigvelo-listbox-item>
404
+ * <sigvelo-listbox-item value="2">All Paws</sigvelo-listbox-item>
405
+ * <sigvelo-listbox-item value="3">No Trimming Needed</sigvelo-listbox-item>
406
+ * </sigvelo-listbox>
407
+ * <br>
408
+ * <sigvelo-button type="submit" color="primary">Submit</sigvelo-button>
409
+ * <sigvelo-button type="reset">Reset</sigvelo-button>
410
+ * </form>
411
+ *
412
+ * <style>
413
+ * .listbox__validation-pseudo {
414
+ * sigvelo-listbox:valid {
415
+ * outline: solid 2px var(--sigvelo-color-success-border);
416
+ * outline-offset: .5rem;
417
+ * }
418
+ *
419
+ * sigvelo-listbox:invalid {
420
+ * outline: solid 2px var(--sigvelo-color-danger-border);
421
+ * outline-offset: .5rem;
422
+ * }
423
+ * }
424
+ * </style>
425
+ * ```
426
+ *
427
+ * However, these selectors will match even before the user has had a chance to interact with the form. More often than not, you'll want to use the `user-valid` and `user-invalid` custom states instead. This way, validation styles are only shown _after_ the user interacts with the form control or when the form is submitted.
428
+ *
429
+ * ```html
430
+ * <form action="about:blank" method="get" target="_blank" class="listbox__validation-custom">
431
+ * <sigvelo-listbox
432
+ * name="diet"
433
+ * label="Dietary Needs"
434
+ * description="Please select your cat's dietary preference"
435
+ * required
436
+ * >
437
+ * <sigvelo-listbox-item value="1">Grain-Free Formula</sigvelo-listbox-item>
438
+ * <sigvelo-listbox-item value="2">Senior Cat Diet</sigvelo-listbox-item>
439
+ * <sigvelo-listbox-item value="3">Hairball Control</sigvelo-listbox-item>
440
+ * </sigvelo-listbox>
441
+ * <br>
442
+ * <sigvelo-button type="submit" color="primary">Submit</sigvelo-button>
443
+ * <sigvelo-button type="reset">Reset</sigvelo-button>
444
+ * </form>
445
+ *
446
+ * <style>
447
+ * .listbox__validation-custom {
448
+ * sigvelo-listbox:state(user-valid) {
449
+ * outline: solid 2px var(--sigvelo-color-success-border);
450
+ * outline-offset: .5rem;
451
+ * }
452
+ *
453
+ * sigvelo-listbox:state(user-invalid) {
454
+ * outline: solid 2px var(--sigvelo-color-danger-border);
455
+ * outline-offset: .5rem;
456
+ * }
457
+ * }
458
+ * </style>
459
+ * ```
460
+ *
461
+ * @example Styling listboxes
462
+ * Listboxes are styled like form controls for consistency, but feel free to customize them to your liking. Here's an example you might see in an email client.
463
+ *
464
+ * ```html
465
+ * <sigvelo-listbox
466
+ * label="Select a message to view"
467
+ * class="sigvelo-vh-label"
468
+ * id="listbox__styling"
469
+ * >
470
+ * <sigvelo-listbox-item value="1000">
471
+ * <sigvelo-avatar image="https://images.unsplash.com/photo-1735820474275-dd0ff4f28d71?q=80&w=256&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D"></sigvelo-avatar>
472
+ * <h4 class="name">Sir Fluffington III</h4>
473
+ * <time class="time" datetime="2025-03-20T14:45">2:45 PM</time>
474
+ * <div class="summary" aria-hidden="true">Just knocked your favorite vase off the shelf. Not sorry.</div>
475
+ * <sigvelo-icon class="attachment" name="paperclip" label="1 attachment"></sigvelo-icon>
476
+ * </sigvelo-listbox-item>
477
+ *
478
+ * <sigvelo-listbox-item value="1001">
479
+ * <sigvelo-avatar image="https://images.unsplash.com/photo-1529778873920-4da4926a72c2?q=80&w=256&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D"></sigvelo-avatar>
480
+ * <h4 class="name">Captain Whiskers</h4>
481
+ * <time class="time" datetime="2025-03-20T13:37">1:37 PM</time>
482
+ * <div class="summary" aria-hidden="true">Require immediate attention. Food bowl is half empty. This is an emergency.</div>
483
+ * <sigvelo-icon class="attachment" name="flag" family="filled" label="Urgent!"></sigvelo-icon>
484
+ * </sigvelo-listbox-item>
485
+ *
486
+ * <sigvelo-listbox-item value="1002">
487
+ * <sigvelo-avatar image="https://images.unsplash.com/photo-1569591159212-b02ea8a9f239?q=80&w=256&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D"></sigvelo-avatar>
488
+ * <h4 class="name">Lady Purrlington</h4>
489
+ * <time class="time" datetime="2025-03-20T11:15">11:15 AM</time>
490
+ * <div class="summary" aria-hidden="true">Your lap is required for napping purposes at 3 PM sharp. Clear your schedule.</div>
491
+ * </sigvelo-listbox-item>
492
+ *
493
+ * <sigvelo-listbox-item value="1003">
494
+ * <sigvelo-avatar image="https://images.unsplash.com/photo-1672487209629-4d52e0c043d0?q=80&w=256&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D"></sigvelo-avatar>
495
+ * <h4 class="name">Meowy McGee</h4>
496
+ * <time class="time" datetime="2025-03-20T10:22">10:22 AM</time>
497
+ * <div class="summary" aria-hidden="true">Spotted a bird outside. Making weird chattering noises. Send help.</div>
498
+ * <sigvelo-icon class="attachment" name="paperclip" label="1 attachment"></sigvelo-icon>
499
+ * </sigvelo-listbox-item>
500
+ *
501
+ * <sigvelo-listbox-item value="1004">
502
+ * <sigvelo-avatar image="https://images.unsplash.com/photo-1579014868745-23e405c5605d?q=80&w=400&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D"></sigvelo-avatar>
503
+ * <h4 class="name">Chairman Meow</h4>
504
+ * <time class="time" datetime="2025-03-20T09:30">9:30 AM</time>
505
+ * <div class="summary" aria-hidden="true">Have claimed the new cardboard box. All other cats shall bow to my superiority.</div>
506
+ * </sigvelo-listbox-item>
507
+ * </sigvelo-listbox>
508
+ *
509
+ * <style>
510
+ * #listbox__styling {
511
+ * max-width: 600px;
512
+ * font-family: system-ui, -apple-system, BlinkMacSystemFont, sans-serif;
513
+ *
514
+ * &::part(listbox) {
515
+ * height: auto;
516
+ * padding: 0;
517
+ * }
518
+ *
519
+ * sigvelo-listbox-item {
520
+ * display: grid;
521
+ * grid-template-areas:
522
+ * "avatar name time"
523
+ * "avatar summary attachment";
524
+ * grid-template-columns: auto 1fr auto;
525
+ * grid-gap: 4px .75em;
526
+ * padding: .75em;
527
+ * border-bottom-color: var(--sigvelo-color-neutral-border-subtle);
528
+ * border-radius: 0;
529
+ * align-items: center;
530
+ * }
531
+ *
532
+ * sigvelo-listbox-item:has(+ sigvelo-listbox-item:state(selected)),
533
+ * sigvelo-listbox-item:state(selected) {
534
+ * border-bottom-color: var(--sigvelo-color-neutral-border-muted);
535
+ * }
536
+ *
537
+ * &:state(focused) {
538
+ * sigvelo-listbox-item:has(+ sigvelo-listbox-item:state(selected)),
539
+ * sigvelo-listbox-item:state(selected) {
540
+ * border-bottom-color: var(--sigvelo-color-primary-border-muted);
541
+ * }
542
+ * }
543
+ *
544
+ * sigvelo-avatar {
545
+ * grid-area: avatar;
546
+ * margin-right: 0.25rem;
547
+ * }
548
+ *
549
+ * .name {
550
+ * grid-area: name;
551
+ * margin: 0;
552
+ * font-size: 0.9375rem;
553
+ * font-weight: var(--sigvelo-font-weight-semibold);
554
+ * }
555
+ *
556
+ * .time {
557
+ * grid-area: time;
558
+ * font-size: 0.875em;
559
+ * color: var(--sigvelo-color-text-muted);
560
+ * justify-self: end;
561
+ * font-style: normal;
562
+ * }
563
+ *
564
+ * .summary {
565
+ * grid-area: summary;
566
+ * color: var(--sigvelo-color-text-muted);
567
+ * font-size: 0.875rem;
568
+ * white-space: nowrap;
569
+ * overflow: hidden;
570
+ * text-overflow: ellipsis;
571
+ * margin: 0;
572
+ * }
573
+ *
574
+ * .attachment {
575
+ * grid-area: attachment;
576
+ * color: var(--sigvelo-color-text-muted);
577
+ * justify-self: end;
578
+ * font-size: 0.875rem;
579
+ *
580
+ * &[name="flag"] {
581
+ * color: crimson;
582
+ * }
583
+ * }
584
+ *
585
+ * sigvelo-listbox-item:state(selected) {
586
+ * .name,
587
+ * .time,
588
+ * .summary,
589
+ * .attachment {
590
+ * color: var(--sigvelo-color-primary-text-on-subtle);
591
+ * }
592
+ * }
593
+ * }
594
+ * </style>
595
+ * ```
596
+ *
597
+ * **Note:** Note the use of `aria-hidden` on summaries, which reduces verbosity when used with screen readers.
598
+ */
599
+ var SigveloListbox = class extends SigveloFormControlElement {
600
+ constructor(..._args) {
601
+ super(..._args);
602
+ this.localize = new Localize(this);
603
+ this.firstSelectedValue = "";
604
+ this.hadUserInteraction = false;
605
+ this.isInvalid = false;
606
+ this.lastSelectedIndex = -1;
607
+ this.previousValue = "";
608
+ this.typeaheadBuffer = "";
609
+ this.typeaheadTimeout = null;
610
+ this.wasChanged = false;
611
+ this.wasSubmitted = false;
612
+ this.multiple = false;
613
+ this.disabled = false;
614
+ this.readonly = false;
615
+ this.size = "md";
616
+ this.required = false;
617
+ }
618
+ static {
619
+ this.formAssociated = true;
620
+ }
621
+ static {
622
+ this.observeSlots = true;
623
+ }
624
+ static {
625
+ this.styles = [
626
+ hostStyles,
627
+ formControlStyles,
628
+ listbox_styles_default
629
+ ];
630
+ }
631
+ /** The listbox's value. For multiple selection, this will be the value of the first selected item. */
632
+ get value() {
633
+ return this.firstSelectedValue;
634
+ }
635
+ set value(newValue) {
636
+ const oldValue = this.firstSelectedValue;
637
+ if (newValue !== oldValue) {
638
+ this.firstSelectedValue = newValue;
639
+ this.updateItemSelectionFromValue(newValue);
640
+ this.requestUpdate("value", oldValue);
641
+ }
642
+ }
643
+ /**
644
+ * Gets or sets the currently selected values as an array. This property provides a consistent way to access or modify
645
+ * the selection state regardless of whether the listbox is in single or multiple selection mode.
646
+ *
647
+ * In single selection mode, it returns an array with either zero or one value. In multiple selection mode, it returns
648
+ * an array of all selected values.
649
+ *
650
+ * When setting this property in single mode, the first value in the array (if any) becomes the selected value. In
651
+ * multiple mode, all values in the array become selected.
652
+ */
653
+ get selectedValues() {
654
+ return this.getSelectedValues();
655
+ }
656
+ set selectedValues(values) {
657
+ this.setSelectedValues(values);
658
+ }
659
+ /** Gets or sets an array of selected listbox items. */
660
+ get selectedItems() {
661
+ return this.getItems(true).filter((item) => item.selected);
662
+ }
663
+ set selectedItems(items) {
664
+ if (!Array.isArray(items)) {
665
+ this.deselectAll();
666
+ return;
667
+ }
668
+ const values = items.map((item) => item?.value).filter(Boolean);
669
+ this.selectedValues = values;
670
+ }
671
+ get focusableAnchor() {
672
+ return this.listbox;
673
+ }
674
+ connectedCallback() {
675
+ super.connectedCallback();
676
+ this.addEventListener("invalid", this.handleHostInvalid);
677
+ this.addEventListener("keydown", this.handleKeyDown);
678
+ }
679
+ disconnectedCallback() {
680
+ super.disconnectedCallback();
681
+ this.removeEventListener("invalid", this.handleHostInvalid);
682
+ this.removeEventListener("keydown", this.handleKeyDown);
683
+ this.clearTypeaheadTimeout();
684
+ }
685
+ firstUpdated(changedProperties) {
686
+ super.firstUpdated(changedProperties);
687
+ this.initializeValueFromSelectedItems();
688
+ this.initializeItems();
689
+ }
690
+ updated(changedProperties) {
691
+ this.updateValidity();
692
+ if (changedProperties.has("value")) {
693
+ this.customStates.set("blank", this.firstSelectedValue === "");
694
+ this.updateFormValue();
695
+ this.updateSelectedItems();
696
+ this.resetRovingTabIndex();
697
+ }
698
+ if (changedProperties.has("disabled")) {
699
+ this.customStates.set("disabled", this.disabled);
700
+ this.updateListboxAttributesOnItems();
701
+ }
702
+ const hadUserInteraction = this.hadUserInteraction || this.wasSubmitted;
703
+ this.customStates.set("user-invalid", hadUserInteraction && this.isInvalid);
704
+ this.customStates.set("user-valid", hadUserInteraction && !this.isInvalid);
705
+ }
706
+ formDisabledCallback(isDisabled) {
707
+ this.disabled = isDisabled;
708
+ }
709
+ formResetCallback() {
710
+ this.isInvalid = false;
711
+ this.wasChanged = false;
712
+ this.hadUserInteraction = false;
713
+ this.wasSubmitted = false;
714
+ this.firstSelectedValue = this.getAttribute("value") ?? "";
715
+ const initiallySelectedItems = this.getItems(true).filter((item) => item.hasAttribute("selected"));
716
+ this.getItems(true).forEach((item) => {
717
+ item.selected = initiallySelectedItems.includes(item);
718
+ });
719
+ if (initiallySelectedItems.length > 0) this.firstSelectedValue = initiallySelectedItems[0].value;
720
+ this.updateFormValue();
721
+ this.updateSelectedItems();
722
+ }
723
+ clearTypeaheadTimeout() {
724
+ if (this.typeaheadTimeout) {
725
+ window.clearTimeout(this.typeaheadTimeout);
726
+ this.typeaheadTimeout = null;
727
+ }
728
+ }
729
+ getItems(includeDisabled = false) {
730
+ const selector = includeDisabled ? "sigvelo-listbox-item" : "sigvelo-listbox-item:not(:state(disabled))";
731
+ return [...this.querySelectorAll(selector)];
732
+ }
733
+ getSelectedItems() {
734
+ return this.getItems().filter((item) => item.selected);
735
+ }
736
+ initializeValueFromSelectedItems() {
737
+ const initiallySelectedItems = this.getItems(true).filter((item) => item.hasAttribute("selected") || item.selected);
738
+ if (initiallySelectedItems.length > 0) if (!this.multiple && initiallySelectedItems.length > 1) {
739
+ const firstItem = initiallySelectedItems[0];
740
+ initiallySelectedItems.slice(1).forEach((item) => {
741
+ item.selected = false;
742
+ });
743
+ this.firstSelectedValue = firstItem.value;
744
+ } else this.firstSelectedValue = initiallySelectedItems[0].value;
745
+ this.updateFormValue();
746
+ }
747
+ initializeItems() {
748
+ const items = this.getItems();
749
+ if (items.length > 0) {
750
+ const selectedItems = this.getSelectedItems();
751
+ const initialItem = selectedItems.length > 0 ? selectedItems[0] : items[0];
752
+ this.setActiveItem(initialItem);
753
+ this.resetRovingTabIndex();
754
+ }
755
+ }
756
+ updateItemSelectionFromValue(newValue) {
757
+ this.getItems(true).forEach((item) => {
758
+ item.selected = item.value === newValue;
759
+ });
760
+ }
761
+ updateFormValue() {
762
+ const selectedItems = this.selectedItems;
763
+ if (this.multiple && selectedItems.length > 0) {
764
+ const formData = new FormData();
765
+ selectedItems.forEach((item) => {
766
+ formData.append(this.name || "", item.value);
767
+ });
768
+ this.internals.setFormValue(formData);
769
+ } else this.internals.setFormValue(this.firstSelectedValue);
770
+ }
771
+ updateSelectedItems() {
772
+ if (!this.multiple) this.getItems(true).forEach((item) => {
773
+ item.selected = item.value === this.firstSelectedValue;
774
+ });
775
+ }
776
+ /**
777
+ * Updates the current value to align with selected items. We track user interaction to allow us to dispatch events
778
+ * when human changes are made and suppress them for programmatic changes.
779
+ */
780
+ updateValueFromSelectedItems(isUserInteraction = false) {
781
+ const selectedItems = this.selectedItems;
782
+ this.previousValue = this.firstSelectedValue;
783
+ this.firstSelectedValue = selectedItems.length > 0 ? selectedItems[0].value : "";
784
+ if (isUserInteraction) {
785
+ this.hadUserInteraction = true;
786
+ if (this.multiple) {
787
+ this.dispatchEvent(new SigveloInputEvent());
788
+ this.dispatchEvent(new Event("input", {
789
+ bubbles: true,
790
+ composed: true
791
+ }));
792
+ this.dispatchEvent(new SigveloChangeEvent());
793
+ this.dispatchEvent(new Event("change", {
794
+ bubbles: true,
795
+ composed: true
796
+ }));
797
+ } else if (this.previousValue !== this.firstSelectedValue) {
798
+ this.dispatchEvent(new SigveloInputEvent());
799
+ this.dispatchEvent(new Event("input", {
800
+ bubbles: true,
801
+ composed: true
802
+ }));
803
+ this.wasChanged = true;
804
+ }
805
+ }
806
+ this.updateFormValue();
807
+ }
808
+ handleFocus() {
809
+ this.customStates.set("focused", true);
810
+ this.dispatchEvent(new SigveloFocusEvent());
811
+ if (this.getSelectedItems().length === 0) {
812
+ const items = this.getItems();
813
+ if (items.length > 0) {
814
+ const firstItem = items[0];
815
+ this.setActiveItem(firstItem);
816
+ this.updateValueFromSelectedItems();
817
+ }
818
+ }
819
+ this.updateListboxAttributesOnItems();
820
+ }
821
+ handleBlur() {
822
+ this.customStates.set("focused", false);
823
+ this.dispatchEvent(new SigveloBlurEvent());
824
+ if (!this.multiple && this.wasChanged && this.previousValue !== this.firstSelectedValue) {
825
+ this.dispatchEvent(new SigveloChangeEvent());
826
+ this.dispatchEvent(new Event("change", {
827
+ bubbles: true,
828
+ composed: true
829
+ }));
830
+ }
831
+ this.wasChanged = false;
832
+ this.updateListboxAttributesOnItems();
833
+ }
834
+ handleHostInvalid() {
835
+ this.wasSubmitted = true;
836
+ }
837
+ handleLabelClick() {
838
+ if (!this.disabled) this.focus();
839
+ }
840
+ handleListboxPointerDown(event) {
841
+ event.preventDefault();
842
+ }
843
+ handleItemClick(event) {
844
+ if (this.disabled) return;
845
+ const item = event.target.closest("sigvelo-listbox-item");
846
+ if (item?.disabled) return;
847
+ if (!item) {
848
+ this.deselectAll();
849
+ this.updateValueFromSelectedItems(true);
850
+ return;
851
+ }
852
+ const clickedIndex = this.getItems().indexOf(item);
853
+ if (clickedIndex === -1) return;
854
+ if (this.lastSelectedIndex === -1) this.lastSelectedIndex = clickedIndex;
855
+ if (!this.readonly) this.handleItemSelection(item, clickedIndex, event);
856
+ this.setActiveItem(item);
857
+ this.listbox.focus();
858
+ event.preventDefault();
859
+ }
860
+ handleItemSelection(item, itemIndex, event) {
861
+ const mouseEvent = event;
862
+ const modifiers = {
863
+ ctrl: mouseEvent.ctrlKey,
864
+ meta: mouseEvent.metaKey,
865
+ shift: mouseEvent.shiftKey
866
+ };
867
+ let selectionChanged = false;
868
+ const isCoarsePointer = event instanceof PointerEvent && (event.pointerType === "touch" || window.matchMedia("(pointer: coarse)").matches);
869
+ if (this.multiple && (modifiers.ctrl || modifiers.meta)) {
870
+ item.selected = !item.selected;
871
+ this.lastSelectedIndex = itemIndex;
872
+ selectionChanged = true;
873
+ } else if (this.multiple && modifiers.shift) {
874
+ const items = this.getItems();
875
+ const start = Math.min(this.lastSelectedIndex !== -1 ? this.lastSelectedIndex : 0, itemIndex);
876
+ const end = Math.max(this.lastSelectedIndex !== -1 ? this.lastSelectedIndex : 0, itemIndex);
877
+ selectionChanged = items.some((listItem, i) => {
878
+ return i >= start && i <= end && !listItem.selected;
879
+ });
880
+ if (selectionChanged) items.forEach((listItem, i) => {
881
+ if (i >= start && i <= end) listItem.selected = true;
882
+ });
883
+ } else if (this.multiple && isCoarsePointer) {
884
+ item.selected = !item.selected;
885
+ this.lastSelectedIndex = itemIndex;
886
+ selectionChanged = true;
887
+ } else if (this.multiple) {
888
+ const items = this.getItems();
889
+ selectionChanged = items.some((listItem, i) => {
890
+ return i === itemIndex && !listItem.selected || i !== itemIndex && listItem.selected;
891
+ });
892
+ if (selectionChanged) items.forEach((listItem, i) => {
893
+ listItem.selected = i === itemIndex;
894
+ });
895
+ this.lastSelectedIndex = itemIndex;
896
+ } else if (!item.selected) {
897
+ this.selectSingleItem(item);
898
+ selectionChanged = true;
899
+ }
900
+ requestAnimationFrame(() => {
901
+ if (selectionChanged) this.updateValueFromSelectedItems(true);
902
+ this.resetRovingTabIndex();
903
+ });
904
+ }
905
+ handleKeyDown(event) {
906
+ if (event.key.length === 1 && !event.metaKey && !event.ctrlKey) {
907
+ if (!this.readonly) this.handleTypeahead(event);
908
+ return;
909
+ }
910
+ const items = this.getItems();
911
+ if (items.length === 0) return;
912
+ if (this.getSelectedItems().length === 0) {
913
+ if (event.key === "ArrowDown" || event.key === "ArrowRight") {
914
+ event.preventDefault();
915
+ this.navigateToItem(0, items, event);
916
+ return;
917
+ } else if (event.key === "ArrowUp" || event.key === "ArrowLeft") {
918
+ event.preventDefault();
919
+ this.navigateToItem(items.length - 1, items, event);
920
+ return;
921
+ }
922
+ }
923
+ let activeItem = this.querySelector("sigvelo-listbox-item[active]");
924
+ let activeIndex = activeItem ? items.indexOf(activeItem) : -1;
925
+ if (activeIndex === -1) {
926
+ activeItem = this.getSelectedItems()[0] || items[0];
927
+ activeIndex = items.indexOf(activeItem);
928
+ this.setActiveItem(activeItem);
929
+ event.preventDefault();
930
+ return;
931
+ }
932
+ switch (event.key) {
933
+ case "ArrowDown":
934
+ case "ArrowRight":
935
+ event.preventDefault();
936
+ this.navigateToItem(activeIndex + 1, items, event);
937
+ break;
938
+ case "ArrowUp":
939
+ case "ArrowLeft":
940
+ event.preventDefault();
941
+ this.navigateToItem(activeIndex - 1, items, event);
942
+ break;
943
+ case "Home":
944
+ event.preventDefault();
945
+ if (!this.readonly && this.multiple && event.ctrlKey && event.shiftKey) {
946
+ const currentIndex = items.indexOf(activeItem);
947
+ for (let i = 0; i <= currentIndex; i++) items[i].selected = true;
948
+ this.updateValueFromSelectedItems(true);
949
+ this.navigateToItem(0, items, {
950
+ shiftKey: false,
951
+ ctrlKey: true,
952
+ metaKey: event.metaKey
953
+ });
954
+ } else this.navigateToItem(0, items, event);
955
+ break;
956
+ case "End":
957
+ event.preventDefault();
958
+ if (!this.readonly && this.multiple && event.ctrlKey && event.shiftKey) {
959
+ const currentIndex = items.indexOf(activeItem);
960
+ for (let i = currentIndex; i < items.length; i++) items[i].selected = true;
961
+ this.updateValueFromSelectedItems(true);
962
+ this.navigateToItem(items.length - 1, items, {
963
+ shiftKey: false,
964
+ ctrlKey: true,
965
+ metaKey: event.metaKey
966
+ });
967
+ } else this.navigateToItem(items.length - 1, items, event);
968
+ break;
969
+ case " ":
970
+ case "Enter":
971
+ event.preventDefault();
972
+ if (!this.readonly) if (this.multiple && event.shiftKey && !event.ctrlKey && !event.metaKey) {
973
+ const start = Math.min(this.lastSelectedIndex !== -1 ? this.lastSelectedIndex : 0, activeIndex);
974
+ const end = Math.max(this.lastSelectedIndex !== -1 ? this.lastSelectedIndex : 0, activeIndex);
975
+ items.forEach((item, i) => {
976
+ if (i >= start && i <= end) item.selected = true;
977
+ });
978
+ this.updateValueFromSelectedItems(true);
979
+ } else this.selectWithKeyboard(activeItem, activeIndex, event);
980
+ break;
981
+ case "a":
982
+ if (!this.readonly && (event.ctrlKey || event.metaKey) && this.multiple) {
983
+ event.preventDefault();
984
+ this.selectAll();
985
+ }
986
+ break;
987
+ }
988
+ this.listbox.focus();
989
+ }
990
+ /**
991
+ * Moves the active item, applying the selection semantics implied by the
992
+ * modifier keys.
993
+ *
994
+ * Takes only the modifier flags rather than the `KeyboardEvent`, because two
995
+ * call sites synthesise a modifier combination that did not happen (Ctrl is
996
+ * forced on for Ctrl+Shift+Home/End). Spreading a real event to fake that
997
+ * produced a plain object with none of the event prototype's accessors.
998
+ */
999
+ navigateToItem(index, items, event) {
1000
+ index = Math.max(0, Math.min(index, items.length - 1));
1001
+ const newActiveItem = items[index];
1002
+ this.setActiveItem(newActiveItem);
1003
+ if (this.multiple && !this.readonly) {
1004
+ if (event.shiftKey && !event.ctrlKey && !event.metaKey) {
1005
+ newActiveItem.selected = !newActiveItem.selected;
1006
+ this.lastSelectedIndex = index;
1007
+ this.updateValueFromSelectedItems(true);
1008
+ this.resetRovingTabIndex();
1009
+ } else if (!event.shiftKey && !event.ctrlKey && !event.metaKey) {
1010
+ this.selectSingleItem(newActiveItem);
1011
+ this.updateValueFromSelectedItems(true);
1012
+ this.resetRovingTabIndex();
1013
+ }
1014
+ } else if (!this.readonly) {
1015
+ this.selectSingleItem(newActiveItem);
1016
+ this.updateValueFromSelectedItems(true);
1017
+ this.resetRovingTabIndex();
1018
+ }
1019
+ }
1020
+ updateListboxAttributesOnItems() {
1021
+ const isFocused = this.customStates.has("focused");
1022
+ this.getItems(true).forEach((item) => {
1023
+ item.customStates.set("controller-disabled", this.disabled);
1024
+ item.customStates.set("controller-readonly", this.readonly);
1025
+ item.customStates.set("controller-focused", isFocused);
1026
+ });
1027
+ }
1028
+ selectWithKeyboard(activeItem, activeIndex, event) {
1029
+ if (!activeItem) return;
1030
+ const modifiers = {
1031
+ ctrl: event.ctrlKey || event.metaKey,
1032
+ shift: event.shiftKey
1033
+ };
1034
+ if (this.multiple && modifiers.ctrl) {
1035
+ activeItem.selected = !activeItem.selected;
1036
+ this.lastSelectedIndex = activeIndex;
1037
+ } else if (this.multiple && modifiers.shift) {
1038
+ const items = this.getItems();
1039
+ const start = Math.min(this.lastSelectedIndex !== -1 ? this.lastSelectedIndex : 0, activeIndex);
1040
+ const end = Math.max(this.lastSelectedIndex !== -1 ? this.lastSelectedIndex : 0, activeIndex);
1041
+ items.forEach((item, i) => {
1042
+ if (i >= start && i <= end) item.selected = true;
1043
+ });
1044
+ } else this.selectSingleItem(activeItem);
1045
+ this.updateValueFromSelectedItems(true);
1046
+ this.resetRovingTabIndex();
1047
+ }
1048
+ handleSlotChange() {
1049
+ this.updateListboxAttributesOnItems();
1050
+ this.updateSelectedItems();
1051
+ this.resetRovingTabIndex();
1052
+ }
1053
+ selectSingleItem(item) {
1054
+ this.getItems().forEach((listItem) => {
1055
+ listItem.selected = listItem === item;
1056
+ });
1057
+ this.lastSelectedIndex = this.getItems().indexOf(item);
1058
+ }
1059
+ handleTypeahead(event) {
1060
+ if (event.ctrlKey || event.metaKey || event.altKey || event.key.length !== 1) return;
1061
+ this.clearTypeaheadTimeout();
1062
+ this.typeaheadBuffer += event.key.toLowerCase();
1063
+ this.typeaheadTimeout = window.setTimeout(() => {
1064
+ this.typeaheadBuffer = "";
1065
+ this.typeaheadTimeout = null;
1066
+ }, 1e3);
1067
+ const match = this.findTypeaheadMatch();
1068
+ if (match) {
1069
+ this.selectSingleItem(match);
1070
+ this.setActiveItem(match);
1071
+ this.updateValueFromSelectedItems(true);
1072
+ }
1073
+ }
1074
+ findTypeaheadMatch() {
1075
+ const items = this.getItems();
1076
+ const matchText = (idx) => (items[idx].textContent || "").trim().toLowerCase().startsWith(this.typeaheadBuffer);
1077
+ for (let i = 0; i < items.length; i++) if (matchText(i)) return items[i];
1078
+ return null;
1079
+ }
1080
+ setActiveItem(item) {
1081
+ this.getItems(true).forEach((i) => {
1082
+ const isActive = i === item;
1083
+ i.toggleAttribute("active", isActive);
1084
+ i.setAttribute("aria-current", isActive ? "true" : "false");
1085
+ });
1086
+ if (item) requestAnimationFrame(() => this.scrollItemIntoView(item));
1087
+ }
1088
+ scrollItemIntoView(item) {
1089
+ const listbox = this.listbox;
1090
+ const r1 = listbox.getBoundingClientRect();
1091
+ const r2 = item.getBoundingClientRect();
1092
+ const isRTL = this.localize.dir() === "rtl";
1093
+ if (r2.bottom > r1.bottom) listbox.scrollTop += r2.bottom - r1.bottom;
1094
+ else if (r2.top < r1.top) listbox.scrollTop -= r1.top - r2.top;
1095
+ if (isRTL) {
1096
+ if (r1.right < r2.right) listbox.scrollLeft -= r2.right - r1.right;
1097
+ else if (r1.left > r2.left) listbox.scrollLeft += r1.left - r2.left;
1098
+ } else if (r1.left > r2.left) listbox.scrollLeft += r2.left - r1.left;
1099
+ else if (r1.right < r2.right) listbox.scrollLeft -= r1.right - r2.right;
1100
+ }
1101
+ async updateValidity() {
1102
+ await this.updateComplete;
1103
+ const isValueMissing = this.required && this.firstSelectedValue === "";
1104
+ const hasCustomValidity = this.getCustomValidity().length > 0;
1105
+ this.isInvalid = isValueMissing || hasCustomValidity;
1106
+ this.internals.setValidity({
1107
+ badInput: false,
1108
+ customError: hasCustomValidity,
1109
+ patternMismatch: false,
1110
+ rangeOverflow: false,
1111
+ rangeUnderflow: false,
1112
+ stepMismatch: false,
1113
+ tooLong: false,
1114
+ tooShort: false,
1115
+ typeMismatch: false,
1116
+ valueMissing: isValueMissing
1117
+ }, isValueMissing ? VALIDATION_MESSAGE : this.getCustomValidity(), this.focusableAnchor);
1118
+ }
1119
+ /**
1120
+ * @internal Manage tab order and focus tracking for keyboard navigation
1121
+ */
1122
+ resetRovingTabIndex() {
1123
+ const items = this.getItems();
1124
+ const selectedItem = this.getSelectedItems()[0];
1125
+ const targetIndex = selectedItem ? items.indexOf(selectedItem) : 0;
1126
+ items.forEach((item, index) => {
1127
+ item.tabIndex = -1;
1128
+ item.setAttribute("aria-current", index === targetIndex ? "true" : "false");
1129
+ });
1130
+ }
1131
+ /** Returns an array of all selected values. */
1132
+ getSelectedValues() {
1133
+ return this.selectedItems.map((item) => item.value);
1134
+ }
1135
+ /**
1136
+ * Sets the selected items by value(s) without triggering events.
1137
+ * Works for both single and multiple selection modes.
1138
+ * @param {string|string[]} values - Value(s) to select
1139
+ */
1140
+ setSelectedValues(values) {
1141
+ const items = this.getItems(true);
1142
+ const valueArray = Array.isArray(values) ? values : [values];
1143
+ if (this.multiple) items.forEach((item) => {
1144
+ item.selected = valueArray.includes(item.value);
1145
+ });
1146
+ else {
1147
+ const firstValue = valueArray[0];
1148
+ items.forEach((item) => {
1149
+ item.selected = item.value === firstValue;
1150
+ });
1151
+ }
1152
+ this.updateValueFromSelectedItems(false);
1153
+ }
1154
+ /** Convenience method for selecting all items. */
1155
+ selectAll() {
1156
+ if (!this.multiple) return;
1157
+ this.getItems().forEach((item) => item.selected = true);
1158
+ this.updateValueFromSelectedItems();
1159
+ }
1160
+ /** Convenience method for deselecting all items. */
1161
+ deselectAll() {
1162
+ this.getItems().forEach((item) => item.selected = false);
1163
+ this.updateValueFromSelectedItems();
1164
+ }
1165
+ /** Sets focus to the listbox. */
1166
+ focus() {
1167
+ this.listbox.focus();
1168
+ }
1169
+ /** Removes focus from the listbox. */
1170
+ blur() {
1171
+ this.listbox.blur();
1172
+ }
1173
+ render() {
1174
+ const hasLabel = this.label || this.slotsWithContent.has("label");
1175
+ const hasDescription = this.description || this.slotsWithContent.has("description");
1176
+ return html`
1177
+ <label
1178
+ id="label"
1179
+ part="label"
1180
+ for="listbox"
1181
+ class=${classMap({ vh: !hasLabel })}
1182
+ @click=${this.handleLabelClick}
1183
+ >
1184
+ <slot name="label">${this.label}</slot>
1185
+ </label>
1186
+
1187
+ <div id="description" part="description" class=${classMap({ vh: !hasDescription })}>
1188
+ <slot name="description">${this.description}</slot>
1189
+ </div>
1190
+
1191
+ <div
1192
+ id="listbox"
1193
+ part="listbox"
1194
+ class=${classMap({
1195
+ xs: this.size === "xs",
1196
+ sm: this.size === "sm",
1197
+ md: this.size === "md",
1198
+ lg: this.size === "lg",
1199
+ xl: this.size === "xl",
1200
+ disabled: this.disabled,
1201
+ readonly: this.readonly,
1202
+ multiple: this.multiple
1203
+ })}
1204
+ role="listbox"
1205
+ aria-multiselectable=${this.multiple ? "true" : "false"}
1206
+ aria-disabled=${this.disabled ? "true" : "false"}
1207
+ aria-readonly=${this.readonly ? "true" : "false"}
1208
+ aria-required=${this.required ? "true" : "false"}
1209
+ aria-labelledby="label"
1210
+ aria-describedby="description"
1211
+ tabindex=${this.disabled ? "-1" : "0"}
1212
+ @blur=${this.handleBlur}
1213
+ @focus=${this.handleFocus}
1214
+ @pointerdown=${this.handleListboxPointerDown}
1215
+ @click=${this.handleItemClick}
1216
+ >
1217
+ <slot @slotchange=${this.handleSlotChange}></slot>
1218
+ </div>
1219
+ `;
1220
+ }
1221
+ };
1222
+ __decorate([query("#listbox")], SigveloListbox.prototype, "listbox", void 0);
1223
+ __decorate([state()], SigveloListbox.prototype, "hadUserInteraction", void 0);
1224
+ __decorate([state()], SigveloListbox.prototype, "isInvalid", void 0);
1225
+ __decorate([state()], SigveloListbox.prototype, "lastSelectedIndex", void 0);
1226
+ __decorate([state()], SigveloListbox.prototype, "previousValue", void 0);
1227
+ __decorate([state()], SigveloListbox.prototype, "typeaheadBuffer", void 0);
1228
+ __decorate([state()], SigveloListbox.prototype, "typeaheadTimeout", void 0);
1229
+ __decorate([state()], SigveloListbox.prototype, "wasChanged", void 0);
1230
+ __decorate([state()], SigveloListbox.prototype, "wasSubmitted", void 0);
1231
+ __decorate([property()], SigveloListbox.prototype, "label", void 0);
1232
+ __decorate([property()], SigveloListbox.prototype, "description", void 0);
1233
+ __decorate([property({ reflect: true })], SigveloListbox.prototype, "name", void 0);
1234
+ __decorate([property({
1235
+ type: Boolean,
1236
+ reflect: true
1237
+ })], SigveloListbox.prototype, "multiple", void 0);
1238
+ __decorate([property({
1239
+ type: Boolean,
1240
+ reflect: true
1241
+ })], SigveloListbox.prototype, "disabled", void 0);
1242
+ __decorate([property({
1243
+ type: Boolean,
1244
+ reflect: true
1245
+ })], SigveloListbox.prototype, "readonly", void 0);
1246
+ __decorate([property({ reflect: true })], SigveloListbox.prototype, "size", void 0);
1247
+ __decorate([property()], SigveloListbox.prototype, "form", void 0);
1248
+ __decorate([property({
1249
+ type: Boolean,
1250
+ reflect: true
1251
+ })], SigveloListbox.prototype, "required", void 0);
1252
+ __decorate([property()], SigveloListbox.prototype, "value", null);
1253
+ __decorate([property({ type: Array })], SigveloListbox.prototype, "selectedValues", null);
1254
+ SigveloListbox.disableWarning?.("change-in-update");
1255
+ customElements.define("sigvelo-listbox", SigveloListbox);
1256
+ //#endregion
1257
+ export { SigveloListbox as t };