@proyecto-viviana/solidaria 0.2.5 → 0.3.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 (555) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +31 -236
  3. package/dist/actiongroup/createActionGroup.d.ts +29 -0
  4. package/dist/actiongroup/createActionGroup.d.ts.map +1 -0
  5. package/dist/actiongroup/index.d.ts +2 -0
  6. package/dist/actiongroup/index.d.ts.map +1 -0
  7. package/dist/autocomplete/createAutocomplete.d.ts +16 -12
  8. package/dist/autocomplete/createAutocomplete.d.ts.map +1 -1
  9. package/dist/autocomplete/index.d.ts +1 -1
  10. package/dist/autocomplete/index.d.ts.map +1 -1
  11. package/dist/breadcrumbs/createBreadcrumbs.d.ts +11 -7
  12. package/dist/breadcrumbs/createBreadcrumbs.d.ts.map +1 -1
  13. package/dist/breadcrumbs/index.d.ts +1 -1
  14. package/dist/button/createButton.d.ts +1 -1
  15. package/dist/button/createButton.d.ts.map +1 -1
  16. package/dist/button/createToggleButton.d.ts +3 -3
  17. package/dist/button/createToggleButtonGroup.d.ts +32 -0
  18. package/dist/button/createToggleButtonGroup.d.ts.map +1 -0
  19. package/dist/button/index.d.ts +6 -4
  20. package/dist/button/index.d.ts.map +1 -1
  21. package/dist/button/types.d.ts +18 -12
  22. package/dist/button/types.d.ts.map +1 -1
  23. package/dist/calendar/createCalendar.d.ts +15 -5
  24. package/dist/calendar/createCalendar.d.ts.map +1 -1
  25. package/dist/calendar/createCalendarCell.d.ts +8 -2
  26. package/dist/calendar/createCalendarCell.d.ts.map +1 -1
  27. package/dist/calendar/createCalendarGrid.d.ts +4 -4
  28. package/dist/calendar/createCalendarGrid.d.ts.map +1 -1
  29. package/dist/calendar/createRangeCalendar.d.ts +15 -5
  30. package/dist/calendar/createRangeCalendar.d.ts.map +1 -1
  31. package/dist/calendar/createRangeCalendarCell.d.ts +7 -3
  32. package/dist/calendar/createRangeCalendarCell.d.ts.map +1 -1
  33. package/dist/calendar/index.d.ts +5 -5
  34. package/dist/calendar/index.d.ts.map +1 -1
  35. package/dist/calendar/intl/index.d.ts +12 -0
  36. package/dist/calendar/intl/index.d.ts.map +1 -0
  37. package/dist/calendar/utils.d.ts +12 -0
  38. package/dist/calendar/utils.d.ts.map +1 -0
  39. package/dist/checkbox/createCheckbox.d.ts +6 -6
  40. package/dist/checkbox/createCheckbox.d.ts.map +1 -1
  41. package/dist/checkbox/createCheckboxGroup.d.ts +11 -7
  42. package/dist/checkbox/createCheckboxGroup.d.ts.map +1 -1
  43. package/dist/checkbox/createCheckboxGroupItem.d.ts +4 -4
  44. package/dist/checkbox/createCheckboxGroupItem.d.ts.map +1 -1
  45. package/dist/checkbox/createCheckboxGroupState.d.ts +2 -2
  46. package/dist/checkbox/createCheckboxGroupState.d.ts.map +1 -1
  47. package/dist/checkbox/index.d.ts +8 -8
  48. package/dist/checkbox/index.d.ts.map +1 -1
  49. package/dist/collections/index.d.ts +56 -0
  50. package/dist/collections/index.d.ts.map +1 -0
  51. package/dist/color/createColorArea.d.ts +3 -3
  52. package/dist/color/createColorArea.d.ts.map +1 -1
  53. package/dist/color/createColorField.d.ts +4 -4
  54. package/dist/color/createColorField.d.ts.map +1 -1
  55. package/dist/color/createColorSlider.d.ts +4 -4
  56. package/dist/color/createColorSlider.d.ts.map +1 -1
  57. package/dist/color/createColorSwatch.d.ts +2 -2
  58. package/dist/color/createColorSwatch.d.ts.map +1 -1
  59. package/dist/color/createColorWheel.d.ts +3 -3
  60. package/dist/color/createColorWheel.d.ts.map +1 -1
  61. package/dist/color/index.d.ts +6 -6
  62. package/dist/color/types.d.ts +98 -16
  63. package/dist/color/types.d.ts.map +1 -1
  64. package/dist/combobox/createComboBox.d.ts +16 -7
  65. package/dist/combobox/createComboBox.d.ts.map +1 -1
  66. package/dist/combobox/index.d.ts +1 -1
  67. package/dist/combobox/intl/index.d.ts +1 -1
  68. package/dist/datepicker/createDateField.d.ts +18 -6
  69. package/dist/datepicker/createDateField.d.ts.map +1 -1
  70. package/dist/datepicker/createDatePicker.d.ts +57 -5
  71. package/dist/datepicker/createDatePicker.d.ts.map +1 -1
  72. package/dist/datepicker/createDatePickerGroup.d.ts +19 -0
  73. package/dist/datepicker/createDatePickerGroup.d.ts.map +1 -0
  74. package/dist/datepicker/createDateRangePicker.d.ts +42 -0
  75. package/dist/datepicker/createDateRangePicker.d.ts.map +1 -0
  76. package/dist/datepicker/createDateSegment.d.ts +11 -3
  77. package/dist/datepicker/createDateSegment.d.ts.map +1 -1
  78. package/dist/datepicker/createTimeField.d.ts +11 -5
  79. package/dist/datepicker/createTimeField.d.ts.map +1 -1
  80. package/dist/datepicker/createTimeSegment.d.ts +29 -0
  81. package/dist/datepicker/createTimeSegment.d.ts.map +1 -0
  82. package/dist/datepicker/index.d.ts +7 -4
  83. package/dist/datepicker/index.d.ts.map +1 -1
  84. package/dist/dialog/createDialog.d.ts +5 -5
  85. package/dist/dialog/createDialog.d.ts.map +1 -1
  86. package/dist/dialog/index.d.ts +2 -2
  87. package/dist/dialog/index.d.ts.map +1 -1
  88. package/dist/dialog/types.d.ts +4 -4
  89. package/dist/disclosure/createDisclosure.d.ts +5 -2
  90. package/dist/disclosure/createDisclosure.d.ts.map +1 -1
  91. package/dist/disclosure/createDisclosureGroup.d.ts +4 -3
  92. package/dist/disclosure/createDisclosureGroup.d.ts.map +1 -1
  93. package/dist/disclosure/index.d.ts +2 -2
  94. package/dist/dnd/createDrag.d.ts +2 -2
  95. package/dist/dnd/createDrag.d.ts.map +1 -1
  96. package/dist/dnd/createDraggableCollection.d.ts +6 -2
  97. package/dist/dnd/createDraggableCollection.d.ts.map +1 -1
  98. package/dist/dnd/createDraggableItem.d.ts +3 -3
  99. package/dist/dnd/createDraggableItem.d.ts.map +1 -1
  100. package/dist/dnd/createDrop.d.ts +2 -2
  101. package/dist/dnd/createDrop.d.ts.map +1 -1
  102. package/dist/dnd/createDroppableCollection.d.ts +55 -4
  103. package/dist/dnd/createDroppableCollection.d.ts.map +1 -1
  104. package/dist/dnd/createDroppableItem.d.ts +3 -3
  105. package/dist/dnd/createDroppableItem.d.ts.map +1 -1
  106. package/dist/dnd/index.d.ts +12 -12
  107. package/dist/dnd/index.d.ts.map +1 -1
  108. package/dist/dnd/types.d.ts +2 -2
  109. package/dist/dnd/types.d.ts.map +1 -1
  110. package/dist/dnd/utils.d.ts +1 -1
  111. package/dist/dnd/utils.d.ts.map +1 -1
  112. package/dist/focus/FocusScope.d.ts +1 -1
  113. package/dist/focus/FocusScope.d.ts.map +1 -1
  114. package/dist/focus/createAutoFocus.d.ts.map +1 -1
  115. package/dist/focus/createFocusRestore.d.ts.map +1 -1
  116. package/dist/focus/createVirtualFocus.d.ts +4 -4
  117. package/dist/focus/createVirtualFocus.d.ts.map +1 -1
  118. package/dist/focus/index.d.ts +4 -4
  119. package/dist/focus/index.d.ts.map +1 -1
  120. package/dist/form/createFormReset.d.ts +1 -1
  121. package/dist/form/createFormValidation.d.ts +3 -3
  122. package/dist/form/createFormValidation.d.ts.map +1 -1
  123. package/dist/form/index.d.ts +2 -2
  124. package/dist/form/index.d.ts.map +1 -1
  125. package/dist/grid/GridKeyboardDelegate.d.ts +5 -5
  126. package/dist/grid/createGrid.d.ts +3 -3
  127. package/dist/grid/createGrid.d.ts.map +1 -1
  128. package/dist/grid/createGridCell.d.ts +3 -3
  129. package/dist/grid/createGridRow.d.ts +3 -3
  130. package/dist/grid/index.d.ts +5 -5
  131. package/dist/grid/types.d.ts +8 -8
  132. package/dist/gridlist/createGridList.d.ts +6 -4
  133. package/dist/gridlist/createGridList.d.ts.map +1 -1
  134. package/dist/gridlist/createGridListItem.d.ts +4 -4
  135. package/dist/gridlist/createGridListItem.d.ts.map +1 -1
  136. package/dist/gridlist/createGridListSelectionCheckbox.d.ts +3 -3
  137. package/dist/gridlist/createGridListSelectionCheckbox.d.ts.map +1 -1
  138. package/dist/gridlist/index.d.ts +4 -4
  139. package/dist/gridlist/types.d.ts +11 -7
  140. package/dist/gridlist/types.d.ts.map +1 -1
  141. package/dist/i18n/createCollator.d.ts.map +1 -1
  142. package/dist/i18n/createDateFormatter.d.ts.map +1 -1
  143. package/dist/i18n/createFilter.d.ts.map +1 -1
  144. package/dist/i18n/createNumberFormatter.d.ts +1 -1
  145. package/dist/i18n/createNumberFormatter.d.ts.map +1 -1
  146. package/dist/i18n/createStringFormatter.d.ts +2 -2
  147. package/dist/i18n/createStringFormatter.d.ts.map +1 -1
  148. package/dist/i18n/index.d.ts +8 -8
  149. package/dist/i18n/index.d.ts.map +1 -1
  150. package/dist/i18n/locale.d.ts +2 -2
  151. package/dist/i18n/locale.d.ts.map +1 -1
  152. package/dist/i18n/utils.d.ts.map +1 -1
  153. package/dist/index.d.ts +52 -49
  154. package/dist/index.d.ts.map +1 -1
  155. package/dist/index.js +18089 -15690
  156. package/dist/index.js.map +1 -7
  157. package/dist/index.jsx +18242 -0
  158. package/dist/index.jsx.map +1 -0
  159. package/dist/interactions/FocusableProvider.d.ts +2 -2
  160. package/dist/interactions/FocusableProvider.d.ts.map +1 -1
  161. package/dist/interactions/PressEvent.d.ts +2 -2
  162. package/dist/interactions/createFocus.d.ts +1 -1
  163. package/dist/interactions/createFocus.d.ts.map +1 -1
  164. package/dist/interactions/createFocusRing.d.ts +1 -1
  165. package/dist/interactions/createFocusRing.d.ts.map +1 -1
  166. package/dist/interactions/createFocusWithin.d.ts +1 -1
  167. package/dist/interactions/createFocusWithin.d.ts.map +1 -1
  168. package/dist/interactions/createFocusable.d.ts +3 -3
  169. package/dist/interactions/createFocusable.d.ts.map +1 -1
  170. package/dist/interactions/createHover.d.ts +5 -5
  171. package/dist/interactions/createHover.d.ts.map +1 -1
  172. package/dist/interactions/createInteractionModality.d.ts +3 -3
  173. package/dist/interactions/createInteractionModality.d.ts.map +1 -1
  174. package/dist/interactions/createKeyboard.d.ts +1 -1
  175. package/dist/interactions/createLongPress.d.ts +5 -5
  176. package/dist/interactions/createMove.d.ts +5 -5
  177. package/dist/interactions/createMove.d.ts.map +1 -1
  178. package/dist/interactions/createPress.d.ts +4 -4
  179. package/dist/interactions/createPress.d.ts.map +1 -1
  180. package/dist/interactions/index.d.ts +12 -12
  181. package/dist/interactions/index.d.ts.map +1 -1
  182. package/dist/label/createField.d.ts +4 -4
  183. package/dist/label/createField.d.ts.map +1 -1
  184. package/dist/label/createLabel.d.ts +7 -7
  185. package/dist/label/createLabel.d.ts.map +1 -1
  186. package/dist/label/createLabels.d.ts +1 -1
  187. package/dist/label/createLabels.d.ts.map +1 -1
  188. package/dist/label/index.d.ts +5 -5
  189. package/dist/landmark/createLandmark.d.ts +5 -5
  190. package/dist/landmark/createLandmark.d.ts.map +1 -1
  191. package/dist/landmark/index.d.ts +1 -1
  192. package/dist/link/createLink.d.ts +23 -7
  193. package/dist/link/createLink.d.ts.map +1 -1
  194. package/dist/link/index.d.ts +1 -1
  195. package/dist/listbox/createListBox.d.ts +12 -6
  196. package/dist/listbox/createListBox.d.ts.map +1 -1
  197. package/dist/listbox/createOption.d.ts +21 -4
  198. package/dist/listbox/createOption.d.ts.map +1 -1
  199. package/dist/listbox/index.d.ts +2 -2
  200. package/dist/listbox/index.d.ts.map +1 -1
  201. package/dist/live-announcer/announce.d.ts +2 -2
  202. package/dist/live-announcer/announce.d.ts.map +1 -1
  203. package/dist/live-announcer/index.d.ts +1 -1
  204. package/dist/menu/createMenu.d.ts +8 -7
  205. package/dist/menu/createMenu.d.ts.map +1 -1
  206. package/dist/menu/createMenuItem.d.ts +16 -4
  207. package/dist/menu/createMenuItem.d.ts.map +1 -1
  208. package/dist/menu/createMenuTrigger.d.ts +4 -4
  209. package/dist/menu/index.d.ts +3 -3
  210. package/dist/menu/index.d.ts.map +1 -1
  211. package/dist/meter/createMeter.d.ts +6 -6
  212. package/dist/meter/createMeter.d.ts.map +1 -1
  213. package/dist/meter/index.d.ts +1 -1
  214. package/dist/numberfield/createNumberField.d.ts +27 -8
  215. package/dist/numberfield/createNumberField.d.ts.map +1 -1
  216. package/dist/numberfield/index.d.ts +1 -1
  217. package/dist/overlays/ariaHideOutside.d.ts.map +1 -1
  218. package/dist/overlays/createModal.d.ts +19 -3
  219. package/dist/overlays/createModal.d.ts.map +1 -1
  220. package/dist/overlays/createOverlay.d.ts +1 -1
  221. package/dist/overlays/createOverlay.d.ts.map +1 -1
  222. package/dist/overlays/createOverlayTrigger.d.ts +6 -6
  223. package/dist/overlays/index.d.ts +6 -6
  224. package/dist/overlays/index.d.ts.map +1 -1
  225. package/dist/popover/calculatePosition.d.ts +4 -4
  226. package/dist/popover/calculatePosition.d.ts.map +1 -1
  227. package/dist/popover/createOverlayPosition.d.ts +3 -3
  228. package/dist/popover/createOverlayPosition.d.ts.map +1 -1
  229. package/dist/popover/createPopover.d.ts +4 -4
  230. package/dist/popover/createPopover.d.ts.map +1 -1
  231. package/dist/popover/index.d.ts +3 -3
  232. package/dist/progress/createProgressBar.d.ts +7 -5
  233. package/dist/progress/createProgressBar.d.ts.map +1 -1
  234. package/dist/progress/index.d.ts +1 -1
  235. package/dist/radio/createRadio.d.ts +7 -7
  236. package/dist/radio/createRadio.d.ts.map +1 -1
  237. package/dist/radio/createRadioGroup.d.ts +11 -11
  238. package/dist/radio/createRadioGroup.d.ts.map +1 -1
  239. package/dist/radio/createRadioGroupState.d.ts +3 -3
  240. package/dist/radio/createRadioGroupState.d.ts.map +1 -1
  241. package/dist/radio/index.d.ts +3 -3
  242. package/dist/radio/index.d.ts.map +1 -1
  243. package/dist/searchfield/createSearchField.d.ts +7 -7
  244. package/dist/searchfield/createSearchField.d.ts.map +1 -1
  245. package/dist/searchfield/index.d.ts +2 -2
  246. package/dist/select/createHiddenSelect.d.ts +4 -4
  247. package/dist/select/createHiddenSelect.d.ts.map +1 -1
  248. package/dist/select/createSelect.d.ts +14 -6
  249. package/dist/select/createSelect.d.ts.map +1 -1
  250. package/dist/select/index.d.ts +2 -2
  251. package/dist/select/index.d.ts.map +1 -1
  252. package/dist/selection/createTypeSelect.d.ts +2 -2
  253. package/dist/selection/index.d.ts +1 -1
  254. package/dist/separator/createSeparator.d.ts +9 -5
  255. package/dist/separator/createSeparator.d.ts.map +1 -1
  256. package/dist/separator/index.d.ts +1 -1
  257. package/dist/slider/createSlider.d.ts +11 -7
  258. package/dist/slider/createSlider.d.ts.map +1 -1
  259. package/dist/slider/index.d.ts +2 -2
  260. package/dist/ssr/index.d.ts +1 -1
  261. package/dist/ssr/index.d.ts.map +1 -1
  262. package/dist/steplist/createStepList.d.ts +36 -0
  263. package/dist/steplist/createStepList.d.ts.map +1 -0
  264. package/dist/steplist/index.d.ts +2 -0
  265. package/dist/steplist/index.d.ts.map +1 -0
  266. package/dist/switch/createSwitch.d.ts +6 -4
  267. package/dist/switch/createSwitch.d.ts.map +1 -1
  268. package/dist/switch/index.d.ts +1 -1
  269. package/dist/table/createTable.d.ts +3 -3
  270. package/dist/table/createTable.d.ts.map +1 -1
  271. package/dist/table/createTableCell.d.ts +3 -3
  272. package/dist/table/createTableCell.d.ts.map +1 -1
  273. package/dist/table/createTableColumnHeader.d.ts +3 -3
  274. package/dist/table/createTableColumnHeader.d.ts.map +1 -1
  275. package/dist/table/createTableColumnResize.d.ts +41 -0
  276. package/dist/table/createTableColumnResize.d.ts.map +1 -0
  277. package/dist/table/createTableHeaderRow.d.ts +3 -3
  278. package/dist/table/createTableRow.d.ts +3 -3
  279. package/dist/table/createTableRow.d.ts.map +1 -1
  280. package/dist/table/createTableRowGroup.d.ts +2 -2
  281. package/dist/table/createTableRowGroup.d.ts.map +1 -1
  282. package/dist/table/createTableSelectAllCheckbox.d.ts +3 -3
  283. package/dist/table/createTableSelectAllCheckbox.d.ts.map +1 -1
  284. package/dist/table/createTableSelectionCheckbox.d.ts +3 -3
  285. package/dist/table/index.d.ts +11 -9
  286. package/dist/table/index.d.ts.map +1 -1
  287. package/dist/table/types.d.ts +15 -7
  288. package/dist/table/types.d.ts.map +1 -1
  289. package/dist/tabs/createTabs.d.ts +28 -25
  290. package/dist/tabs/createTabs.d.ts.map +1 -1
  291. package/dist/tabs/index.d.ts +1 -1
  292. package/dist/tag/createTag.d.ts +2 -2
  293. package/dist/tag/createTag.d.ts.map +1 -1
  294. package/dist/tag/createTagGroup.d.ts +5 -5
  295. package/dist/tag/createTagGroup.d.ts.map +1 -1
  296. package/dist/tag/index.d.ts +2 -2
  297. package/dist/tag/index.d.ts.map +1 -1
  298. package/dist/textfield/createTextField.d.ts +17 -11
  299. package/dist/textfield/createTextField.d.ts.map +1 -1
  300. package/dist/textfield/index.d.ts +1 -1
  301. package/dist/textfield/index.d.ts.map +1 -1
  302. package/dist/toast/createToast.d.ts +6 -2
  303. package/dist/toast/createToast.d.ts.map +1 -1
  304. package/dist/toast/createToastRegion.d.ts +5 -3
  305. package/dist/toast/createToastRegion.d.ts.map +1 -1
  306. package/dist/toast/index.d.ts +2 -2
  307. package/dist/toast/index.d.ts.map +1 -1
  308. package/dist/toggle/createToggle.d.ts +9 -9
  309. package/dist/toggle/createToggle.d.ts.map +1 -1
  310. package/dist/toggle/createToggleState.d.ts +2 -2
  311. package/dist/toggle/createToggleState.d.ts.map +1 -1
  312. package/dist/toggle/index.d.ts +4 -4
  313. package/dist/toggle/index.d.ts.map +1 -1
  314. package/dist/toolbar/createToolbar.d.ts +9 -9
  315. package/dist/toolbar/createToolbar.d.ts.map +1 -1
  316. package/dist/toolbar/index.d.ts +1 -1
  317. package/dist/toolbar/index.d.ts.map +1 -1
  318. package/dist/tooltip/createTooltip.d.ts +5 -5
  319. package/dist/tooltip/createTooltip.d.ts.map +1 -1
  320. package/dist/tooltip/createTooltipTrigger.d.ts +10 -5
  321. package/dist/tooltip/createTooltipTrigger.d.ts.map +1 -1
  322. package/dist/tooltip/index.d.ts +2 -2
  323. package/dist/tree/createTree.d.ts +3 -3
  324. package/dist/tree/createTree.d.ts.map +1 -1
  325. package/dist/tree/createTreeItem.d.ts +4 -4
  326. package/dist/tree/createTreeItem.d.ts.map +1 -1
  327. package/dist/tree/createTreeSelectionCheckbox.d.ts +3 -3
  328. package/dist/tree/createTreeSelectionCheckbox.d.ts.map +1 -1
  329. package/dist/tree/index.d.ts +4 -4
  330. package/dist/tree/types.d.ts +13 -5
  331. package/dist/tree/types.d.ts.map +1 -1
  332. package/dist/utils/createDescription.d.ts +2 -2
  333. package/dist/utils/createDescription.d.ts.map +1 -1
  334. package/dist/utils/dom.d.ts.map +1 -1
  335. package/dist/utils/env.d.ts +1 -1
  336. package/dist/utils/env.d.ts.map +1 -1
  337. package/dist/utils/focus.d.ts +1 -1
  338. package/dist/utils/focus.d.ts.map +1 -1
  339. package/dist/utils/geometry.d.ts.map +1 -1
  340. package/dist/utils/index.d.ts +12 -12
  341. package/dist/utils/index.d.ts.map +1 -1
  342. package/dist/utils/mergeProps.d.ts.map +1 -1
  343. package/dist/utils/platform.d.ts.map +1 -1
  344. package/dist/utils/reactivity.d.ts +1 -1
  345. package/dist/visually-hidden/createVisuallyHidden.d.ts +2 -2
  346. package/dist/visually-hidden/createVisuallyHidden.d.ts.map +1 -1
  347. package/dist/visually-hidden/index.d.ts +1 -1
  348. package/package.json +34 -32
  349. package/src/actiongroup/createActionGroup.ts +334 -0
  350. package/src/actiongroup/index.ts +8 -0
  351. package/src/autocomplete/createAutocomplete.ts +137 -131
  352. package/src/autocomplete/index.ts +1 -1
  353. package/src/breadcrumbs/createBreadcrumbs.ts +37 -51
  354. package/src/breadcrumbs/index.ts +1 -1
  355. package/src/button/createButton.ts +102 -73
  356. package/src/button/createToggleButton.ts +10 -10
  357. package/src/button/createToggleButtonGroup.ts +121 -0
  358. package/src/button/index.ts +10 -4
  359. package/src/button/types.ts +18 -12
  360. package/src/calendar/createCalendar.ts +62 -29
  361. package/src/calendar/createCalendarCell.ts +102 -48
  362. package/src/calendar/createCalendarGrid.ts +78 -47
  363. package/src/calendar/createRangeCalendar.ts +66 -31
  364. package/src/calendar/createRangeCalendarCell.ts +115 -37
  365. package/src/calendar/index.ts +5 -9
  366. package/src/calendar/intl/index.ts +210 -0
  367. package/src/calendar/utils.ts +227 -0
  368. package/src/checkbox/createCheckbox.ts +13 -21
  369. package/src/checkbox/createCheckboxGroup.ts +86 -45
  370. package/src/checkbox/createCheckboxGroupItem.ts +16 -27
  371. package/src/checkbox/createCheckboxGroupState.ts +3 -22
  372. package/src/checkbox/index.ts +8 -10
  373. package/src/collections/index.ts +246 -0
  374. package/src/color/createColorArea.ts +458 -314
  375. package/src/color/createColorField.ts +186 -137
  376. package/src/color/createColorSlider.ts +444 -197
  377. package/src/color/createColorSwatch.ts +65 -40
  378. package/src/color/createColorWheel.ts +343 -208
  379. package/src/color/index.ts +24 -24
  380. package/src/color/types.ts +198 -116
  381. package/src/combobox/createComboBox.ts +727 -647
  382. package/src/combobox/index.ts +6 -6
  383. package/src/combobox/intl/index.ts +5 -5
  384. package/src/datepicker/createDateField.ts +192 -39
  385. package/src/datepicker/createDatePicker.ts +294 -63
  386. package/src/datepicker/createDatePickerGroup.ts +149 -0
  387. package/src/datepicker/createDateRangePicker.ts +294 -0
  388. package/src/datepicker/createDateSegment.ts +316 -75
  389. package/src/datepicker/createTimeField.ts +38 -34
  390. package/src/datepicker/createTimeSegment.ts +352 -0
  391. package/src/datepicker/index.ts +24 -11
  392. package/src/dialog/createDialog.ts +127 -120
  393. package/src/dialog/index.ts +2 -2
  394. package/src/dialog/types.ts +19 -19
  395. package/src/disclosure/createDisclosure.ts +138 -33
  396. package/src/disclosure/createDisclosureGroup.ts +8 -18
  397. package/src/disclosure/index.ts +2 -2
  398. package/src/dnd/createDrag.ts +218 -209
  399. package/src/dnd/createDraggableCollection.ts +96 -63
  400. package/src/dnd/createDraggableItem.ts +260 -243
  401. package/src/dnd/createDrop.ts +313 -321
  402. package/src/dnd/createDroppableCollection.ts +799 -293
  403. package/src/dnd/createDroppableItem.ts +215 -213
  404. package/src/dnd/index.ts +66 -47
  405. package/src/dnd/types.ts +86 -89
  406. package/src/dnd/utils.ts +281 -294
  407. package/src/focus/FocusScope.tsx +155 -164
  408. package/src/focus/createAutoFocus.ts +305 -321
  409. package/src/focus/createFocusRestore.ts +300 -313
  410. package/src/focus/createVirtualFocus.ts +380 -396
  411. package/src/focus/index.ts +4 -8
  412. package/src/form/createFormReset.ts +4 -4
  413. package/src/form/createFormValidation.ts +201 -224
  414. package/src/form/index.ts +8 -11
  415. package/src/grid/GridKeyboardDelegate.ts +30 -30
  416. package/src/grid/createGrid.ts +38 -36
  417. package/src/grid/createGridCell.ts +18 -18
  418. package/src/grid/createGridRow.ts +14 -14
  419. package/src/grid/index.ts +5 -5
  420. package/src/grid/types.ts +8 -8
  421. package/src/gridlist/createGridList.ts +45 -24
  422. package/src/gridlist/createGridListItem.ts +68 -23
  423. package/src/gridlist/createGridListSelectionCheckbox.ts +12 -9
  424. package/src/gridlist/index.ts +4 -4
  425. package/src/gridlist/types.ts +11 -7
  426. package/src/i18n/createCollator.ts +66 -79
  427. package/src/i18n/createDateFormatter.ts +75 -83
  428. package/src/i18n/createFilter.ts +118 -131
  429. package/src/i18n/createNumberFormatter.ts +50 -52
  430. package/src/i18n/createStringFormatter.ts +19 -15
  431. package/src/i18n/index.ts +37 -40
  432. package/src/i18n/locale.tsx +163 -188
  433. package/src/i18n/utils.ts +95 -99
  434. package/src/index.ts +114 -164
  435. package/src/interactions/FocusableProvider.tsx +3 -7
  436. package/src/interactions/PressEvent.ts +4 -4
  437. package/src/interactions/createFocus.ts +16 -11
  438. package/src/interactions/createFocusRing.ts +21 -19
  439. package/src/interactions/createFocusWithin.ts +24 -16
  440. package/src/interactions/createFocusable.ts +15 -16
  441. package/src/interactions/createHover.ts +70 -55
  442. package/src/interactions/createInteractionModality.ts +75 -82
  443. package/src/interactions/createKeyboard.ts +2 -2
  444. package/src/interactions/createLongPress.ts +174 -174
  445. package/src/interactions/createMove.ts +299 -289
  446. package/src/interactions/createPress.ts +168 -91
  447. package/src/interactions/index.ts +24 -16
  448. package/src/label/createField.ts +18 -19
  449. package/src/label/createLabel.ts +18 -30
  450. package/src/label/createLabels.ts +8 -12
  451. package/src/label/index.ts +5 -5
  452. package/src/landmark/createLandmark.ts +356 -377
  453. package/src/landmark/index.ts +8 -8
  454. package/src/link/createLink.ts +96 -54
  455. package/src/link/index.ts +1 -1
  456. package/src/listbox/createListBox.ts +319 -269
  457. package/src/listbox/createOption.ts +208 -151
  458. package/src/listbox/index.ts +8 -12
  459. package/src/live-announcer/announce.ts +295 -322
  460. package/src/live-announcer/index.ts +9 -9
  461. package/src/menu/createMenu.ts +434 -396
  462. package/src/menu/createMenuItem.ts +201 -149
  463. package/src/menu/createMenuTrigger.ts +88 -88
  464. package/src/menu/index.ts +9 -18
  465. package/src/meter/createMeter.ts +7 -20
  466. package/src/meter/index.ts +1 -1
  467. package/src/numberfield/createNumberField.ts +368 -268
  468. package/src/numberfield/index.ts +5 -5
  469. package/src/overlays/ariaHideOutside.ts +223 -219
  470. package/src/overlays/createInteractOutside.ts +152 -149
  471. package/src/overlays/createModal.tsx +238 -202
  472. package/src/overlays/createOverlay.ts +195 -155
  473. package/src/overlays/createOverlayTrigger.ts +85 -85
  474. package/src/overlays/createPreventScroll.ts +288 -266
  475. package/src/overlays/index.ts +37 -44
  476. package/src/popover/calculatePosition.ts +117 -119
  477. package/src/popover/createOverlayPosition.ts +52 -43
  478. package/src/popover/createPopover.ts +63 -24
  479. package/src/popover/index.ts +3 -3
  480. package/src/progress/createProgressBar.ts +36 -32
  481. package/src/progress/index.ts +1 -1
  482. package/src/radio/createRadio.ts +95 -73
  483. package/src/radio/createRadioGroup.ts +142 -62
  484. package/src/radio/createRadioGroupState.ts +7 -31
  485. package/src/radio/index.ts +3 -8
  486. package/src/searchfield/createSearchField.ts +269 -186
  487. package/src/searchfield/index.ts +2 -2
  488. package/src/select/createHiddenSelect.tsx +276 -236
  489. package/src/select/createSelect.ts +430 -395
  490. package/src/select/index.ts +9 -14
  491. package/src/selection/createTypeSelect.ts +11 -11
  492. package/src/selection/index.ts +1 -1
  493. package/src/separator/createSeparator.ts +20 -25
  494. package/src/separator/index.ts +1 -1
  495. package/src/slider/createSlider.ts +333 -349
  496. package/src/slider/index.ts +2 -2
  497. package/src/ssr/index.tsx +331 -370
  498. package/src/steplist/createStepList.ts +106 -0
  499. package/src/steplist/index.ts +8 -0
  500. package/src/switch/createSwitch.ts +9 -14
  501. package/src/switch/index.ts +1 -1
  502. package/src/table/createTable.ts +155 -86
  503. package/src/table/createTableCell.ts +17 -16
  504. package/src/table/createTableColumnHeader.ts +67 -20
  505. package/src/table/createTableColumnResize.ts +256 -0
  506. package/src/table/createTableHeaderRow.ts +7 -7
  507. package/src/table/createTableRow.ts +149 -29
  508. package/src/table/createTableRowGroup.ts +5 -7
  509. package/src/table/createTableSelectAllCheckbox.ts +12 -11
  510. package/src/table/createTableSelectionCheckbox.ts +8 -8
  511. package/src/table/index.ts +14 -9
  512. package/src/table/types.ts +15 -7
  513. package/src/tabs/createTabs.ts +138 -127
  514. package/src/tabs/index.ts +1 -1
  515. package/src/tag/createTag.ts +171 -40
  516. package/src/tag/createTagGroup.ts +50 -39
  517. package/src/tag/index.ts +2 -6
  518. package/src/textfield/createTextField.ts +67 -35
  519. package/src/textfield/index.ts +1 -5
  520. package/src/toast/createToast.ts +34 -26
  521. package/src/toast/createToastRegion.ts +169 -27
  522. package/src/toast/index.ts +2 -6
  523. package/src/toggle/createToggle.ts +95 -53
  524. package/src/toggle/createToggleState.ts +2 -10
  525. package/src/toggle/index.ts +4 -5
  526. package/src/toolbar/createToolbar.ts +226 -169
  527. package/src/toolbar/index.ts +1 -1
  528. package/src/tooltip/createTooltip.ts +66 -79
  529. package/src/tooltip/createTooltipTrigger.ts +238 -222
  530. package/src/tooltip/index.ts +6 -6
  531. package/src/tree/createTree.ts +259 -246
  532. package/src/tree/createTreeItem.ts +282 -233
  533. package/src/tree/createTreeSelectionCheckbox.ts +71 -68
  534. package/src/tree/index.ts +16 -16
  535. package/src/tree/types.ts +95 -87
  536. package/src/utils/createDescription.ts +6 -23
  537. package/src/utils/dom.ts +61 -54
  538. package/src/utils/env.ts +53 -54
  539. package/src/utils/events.ts +7 -7
  540. package/src/utils/filterDOMProps.ts +49 -49
  541. package/src/utils/focus.ts +60 -68
  542. package/src/utils/geometry.ts +1 -4
  543. package/src/utils/globalListeners.ts +9 -9
  544. package/src/utils/index.ts +12 -22
  545. package/src/utils/mergeProps.ts +42 -15
  546. package/src/utils/platform.ts +16 -6
  547. package/src/utils/reactivity.ts +3 -3
  548. package/src/utils/textSelection.ts +16 -16
  549. package/src/visually-hidden/createVisuallyHidden.ts +127 -124
  550. package/src/visually-hidden/index.ts +6 -6
  551. package/dist/i18n/NumberFormatter.d.ts +0 -43
  552. package/dist/i18n/NumberFormatter.d.ts.map +0 -1
  553. package/dist/index.ssr.js +0 -15875
  554. package/dist/index.ssr.js.map +0 -7
  555. package/src/i18n/NumberFormatter.ts +0 -266
@@ -1,396 +1,434 @@
1
- /**
2
- * Provides the behavior and accessibility implementation for a menu component.
3
- * A menu displays a list of actions or options that a user can choose.
4
- * Based on @react-aria/menu useMenu.
5
- */
6
-
7
- import { createEffect, onCleanup, type JSX, type Accessor } from 'solid-js';
8
- import { createFocusWithin } from '../interactions/createFocusWithin';
9
- import { createLabel } from '../label/createLabel';
10
- import { createTypeSelect } from '../selection/createTypeSelect';
11
- import { filterDOMProps } from '../utils/filterDOMProps';
12
- import { mergeProps } from '../utils/mergeProps';
13
- import { createId } from '../ssr';
14
- import { access, type MaybeAccessor } from '../utils/reactivity';
15
- import { isDevEnv } from '../utils/env';
16
- import type { MenuState, Key, Collection } from '@proyecto-viviana/solid-stately';
17
-
18
- /**
19
- * Default number of items to skip for page up/down when DOM measurement is not available.
20
- */
21
- const DEFAULT_PAGE_SIZE = 10;
22
-
23
- /**
24
- * Find the next non-disabled key in a collection.
25
- */
26
- function findNextNonDisabledKey<T>(
27
- collection: Collection<T>,
28
- currentKey: Key | null,
29
- direction: 'next' | 'prev',
30
- isDisabled: (key: Key) => boolean,
31
- wrap: boolean
32
- ): Key | null {
33
- const getNextKey = direction === 'next'
34
- ? (key: Key) => collection.getKeyAfter(key)
35
- : (key: Key) => collection.getKeyBefore(key);
36
-
37
- const getFirstKey = direction === 'next'
38
- ? () => collection.getFirstKey()
39
- : () => collection.getLastKey();
40
-
41
- let nextKey = currentKey != null ? getNextKey(currentKey) : getFirstKey();
42
-
43
- // Skip disabled keys
44
- while (nextKey != null && isDisabled(nextKey)) {
45
- nextKey = getNextKey(nextKey);
46
- }
47
-
48
- // If we've reached the end and wrapping is enabled
49
- if (nextKey == null && wrap) {
50
- nextKey = getFirstKey();
51
- // Skip disabled keys from the start
52
- while (nextKey != null && isDisabled(nextKey)) {
53
- nextKey = getNextKey(nextKey);
54
- }
55
- }
56
-
57
- return nextKey;
58
- }
59
-
60
- export interface AriaMenuProps {
61
- /** An ID for the menu. */
62
- id?: string;
63
- /** Whether the menu is disabled. */
64
- isDisabled?: boolean;
65
- /** The label for the menu. */
66
- label?: JSX.Element;
67
- /** An accessible label for the menu when no visible label is provided. */
68
- 'aria-label'?: string;
69
- /** The ID of an element that labels the menu. */
70
- 'aria-labelledby'?: string;
71
- /** The ID of an element that describes the menu. */
72
- 'aria-describedby'?: string;
73
- /** Handler called when focus moves into the menu. */
74
- onFocus?: (e: FocusEvent) => void;
75
- /** Handler called when focus moves out of the menu. */
76
- onBlur?: (e: FocusEvent) => void;
77
- /** Handler called when the focus state changes. */
78
- onFocusChange?: (isFocused: boolean) => void;
79
- /** Handler called when an item is activated (pressed). */
80
- onAction?: (key: Key) => void;
81
- /** Handler called when the menu should close. */
82
- onClose?: () => void;
83
- /** Whether focus should automatically wrap around. */
84
- shouldFocusWrap?: boolean;
85
- /** Whether to auto-focus the first item when the menu opens. */
86
- autoFocus?: boolean | 'first' | 'last';
87
- /** Whether type-to-select is disabled. @default false */
88
- disallowTypeAhead?: boolean;
89
- }
90
-
91
- export interface MenuAria {
92
- /** Props for the menu element. */
93
- menuProps: JSX.HTMLAttributes<HTMLElement>;
94
- /** Props for the menu's label element (if any). */
95
- labelProps: JSX.HTMLAttributes<HTMLElement>;
96
- }
97
-
98
- // Shared data between menu and menu items
99
- const menuData = new WeakMap<object, MenuData>();
100
-
101
- interface MenuData {
102
- id: string;
103
- onAction?: (key: Key) => void;
104
- onClose?: () => void;
105
- }
106
-
107
- export function getMenuData(state: MenuState): MenuData | undefined {
108
- return menuData.get(state);
109
- }
110
-
111
- /**
112
- * Provides the behavior and accessibility implementation for a menu component.
113
- * A menu displays a list of actions or options that a user can choose.
114
- */
115
- export function createMenu<T>(
116
- props: MaybeAccessor<AriaMenuProps>,
117
- state: MenuState<T>,
118
- ref?: Accessor<HTMLElement | null>
119
- ): MenuAria {
120
- const getProps = () => access(props);
121
- const id = createId(getProps().id);
122
-
123
- // Development-time warning for missing accessibility labels
124
- if (isDevEnv()) {
125
- const p = getProps();
126
- if (!p.label && !p['aria-label'] && !p['aria-labelledby']) {
127
- console.warn(
128
- '[solidaria] A Menu requires an aria-label or aria-labelledby attribute for accessibility.'
129
- );
130
- }
131
- }
132
-
133
- // Filter DOM props
134
- const domProps = () => filterDOMProps(getProps() as unknown as Record<string, unknown>, { labelable: true });
135
-
136
- // Share data with child menu items
137
- createEffect(() => {
138
- const p = getProps();
139
- menuData.set(state, {
140
- id,
141
- onAction: p.onAction,
142
- onClose: p.onClose,
143
- });
144
-
145
- onCleanup(() => {
146
- menuData.delete(state);
147
- });
148
- });
149
-
150
- // Handle focus within
151
- const { focusWithinProps } = createFocusWithin({
152
- onFocusWithin: (e) => getProps().onFocus?.(e),
153
- onBlurWithin: (e) => getProps().onBlur?.(e),
154
- onFocusWithinChange: (isFocused) => {
155
- getProps().onFocusChange?.(isFocused);
156
- state.setFocused(isFocused);
157
- },
158
- });
159
-
160
- // Label handling
161
- const { labelProps, fieldProps } = createLabel({
162
- get id() {
163
- return id;
164
- },
165
- get label() {
166
- return getProps().label;
167
- },
168
- get 'aria-label'() {
169
- return getProps()['aria-label'];
170
- },
171
- get 'aria-labelledby'() {
172
- return getProps()['aria-labelledby'];
173
- },
174
- labelElementType: 'span',
175
- });
176
-
177
- // Type-to-select
178
- const { typeSelectProps } = createTypeSelect({
179
- collection: () => state.collection(),
180
- focusedKey: () => state.focusedKey(),
181
- onFocusedKeyChange: (key) => state.setFocusedKey(key),
182
- isKeyDisabled: (key) => state.isDisabled(key),
183
- get isDisabled() {
184
- return getProps().disallowTypeAhead ?? false;
185
- },
186
- });
187
-
188
- // Keyboard navigation
189
- const onKeyDown: JSX.EventHandler<HTMLElement, KeyboardEvent> = (e) => {
190
- if (getProps().isDisabled) return;
191
-
192
- const collection = state.collection();
193
- const p = getProps();
194
- const wrap = p.shouldFocusWrap ?? false;
195
-
196
- // Use state.isDisabled which properly checks the disabledKeys accessor
197
- const isDisabled = (key: Key) => state.isDisabled(key);
198
-
199
- switch (e.key) {
200
- case 'ArrowDown': {
201
- e.preventDefault();
202
- const currentKey = state.focusedKey();
203
- const nextKey = findNextNonDisabledKey(collection, currentKey, 'next', isDisabled, wrap);
204
- if (nextKey != null) {
205
- state.setFocusedKey(nextKey);
206
- }
207
- break;
208
- }
209
- case 'ArrowUp': {
210
- e.preventDefault();
211
- const currentKey = state.focusedKey();
212
- const prevKey = findNextNonDisabledKey(collection, currentKey, 'prev', isDisabled, wrap);
213
- if (prevKey != null) {
214
- state.setFocusedKey(prevKey);
215
- }
216
- break;
217
- }
218
- case 'Home': {
219
- e.preventDefault();
220
- // Find first non-disabled key
221
- let firstKey = collection.getFirstKey();
222
- while (firstKey != null && isDisabled(firstKey)) {
223
- firstKey = collection.getKeyAfter(firstKey);
224
- }
225
- if (firstKey != null) {
226
- state.setFocusedKey(firstKey);
227
- }
228
- break;
229
- }
230
- case 'End': {
231
- e.preventDefault();
232
- // Find last non-disabled key
233
- let lastKey = collection.getLastKey();
234
- while (lastKey != null && isDisabled(lastKey)) {
235
- lastKey = collection.getKeyBefore(lastKey);
236
- }
237
- if (lastKey != null) {
238
- state.setFocusedKey(lastKey);
239
- }
240
- break;
241
- }
242
- case ' ':
243
- case 'Enter': {
244
- e.preventDefault();
245
- const focusedKey = state.focusedKey();
246
- // Don't activate disabled items
247
- if (focusedKey != null && !isDisabled(focusedKey)) {
248
- p.onAction?.(focusedKey);
249
- p.onClose?.();
250
- }
251
- break;
252
- }
253
- case 'Escape': {
254
- e.preventDefault();
255
- p.onClose?.();
256
- break;
257
- }
258
- case 'PageDown': {
259
- e.preventDefault();
260
- const currentKey = state.focusedKey();
261
- const el = ref?.();
262
-
263
- if (el) {
264
- // Use DOM measurements to calculate how many items fit in a page
265
- const visibleHeight = el.clientHeight;
266
- let traveled = 0;
267
- let targetKey = currentKey;
268
-
269
- while (targetKey != null && traveled < visibleHeight) {
270
- const nextKey = collection.getKeyAfter(targetKey);
271
- if (nextKey == null) break;
272
-
273
- // Try to measure the item height
274
- const itemElement = el.querySelector(`[data-key="${targetKey}"]`);
275
- traveled += itemElement?.clientHeight ?? 32;
276
-
277
- // Skip disabled items
278
- if (!isDisabled(nextKey)) {
279
- targetKey = nextKey;
280
- } else {
281
- // Skip over disabled items without counting them
282
- const afterDisabled = findNextNonDisabledKey(collection, nextKey, 'next', isDisabled, false);
283
- if (afterDisabled != null) {
284
- targetKey = afterDisabled;
285
- } else {
286
- break;
287
- }
288
- }
289
- }
290
-
291
- if (targetKey != null && targetKey !== currentKey) {
292
- state.setFocusedKey(targetKey);
293
- }
294
- } else {
295
- // Fallback: move by DEFAULT_PAGE_SIZE items
296
- let count = DEFAULT_PAGE_SIZE;
297
- let targetKey = currentKey;
298
-
299
- while (count > 0 && targetKey != null) {
300
- const nextKey = findNextNonDisabledKey(collection, targetKey, 'next', isDisabled, false);
301
- if (nextKey == null) break;
302
- targetKey = nextKey;
303
- count--;
304
- }
305
-
306
- if (targetKey != null) {
307
- state.setFocusedKey(targetKey);
308
- }
309
- }
310
- break;
311
- }
312
- case 'PageUp': {
313
- e.preventDefault();
314
- const currentKey = state.focusedKey();
315
- const el = ref?.();
316
-
317
- if (el) {
318
- // Use DOM measurements to calculate how many items fit in a page
319
- const visibleHeight = el.clientHeight;
320
- let traveled = 0;
321
- let targetKey = currentKey;
322
-
323
- while (targetKey != null && traveled < visibleHeight) {
324
- const prevKey = collection.getKeyBefore(targetKey);
325
- if (prevKey == null) break;
326
-
327
- // Try to measure the item height
328
- const itemElement = el.querySelector(`[data-key="${targetKey}"]`);
329
- traveled += itemElement?.clientHeight ?? 32;
330
-
331
- // Skip disabled items
332
- if (!isDisabled(prevKey)) {
333
- targetKey = prevKey;
334
- } else {
335
- // Skip over disabled items without counting them
336
- const beforeDisabled = findNextNonDisabledKey(collection, prevKey, 'prev', isDisabled, false);
337
- if (beforeDisabled != null) {
338
- targetKey = beforeDisabled;
339
- } else {
340
- break;
341
- }
342
- }
343
- }
344
-
345
- if (targetKey != null && targetKey !== currentKey) {
346
- state.setFocusedKey(targetKey);
347
- }
348
- } else {
349
- // Fallback: move by DEFAULT_PAGE_SIZE items
350
- let count = DEFAULT_PAGE_SIZE;
351
- let targetKey = currentKey;
352
-
353
- while (count > 0 && targetKey != null) {
354
- const prevKey = findNextNonDisabledKey(collection, targetKey, 'prev', isDisabled, false);
355
- if (prevKey == null) break;
356
- targetKey = prevKey;
357
- count--;
358
- }
359
-
360
- if (targetKey != null) {
361
- state.setFocusedKey(targetKey);
362
- }
363
- }
364
- break;
365
- }
366
- }
367
- };
368
-
369
- return {
370
- get labelProps() {
371
- return labelProps as JSX.HTMLAttributes<HTMLElement>;
372
- },
373
- get menuProps() {
374
- const p = getProps();
375
-
376
- const baseProps = mergeProps(
377
- domProps(),
378
- focusWithinProps as Record<string, unknown>,
379
- fieldProps as Record<string, unknown>,
380
- {
381
- role: 'menu',
382
- tabIndex: p.isDisabled ? undefined : 0,
383
- 'aria-disabled': p.isDisabled || undefined,
384
- onKeyDown,
385
- } as Record<string, unknown>
386
- );
387
-
388
- // Add type-select props if enabled
389
- if (!p.disallowTypeAhead) {
390
- return mergeProps(baseProps, typeSelectProps as Record<string, unknown>) as JSX.HTMLAttributes<HTMLElement>;
391
- }
392
-
393
- return baseProps as JSX.HTMLAttributes<HTMLElement>;
394
- },
395
- };
396
- }
1
+ /**
2
+ * Provides the behavior and accessibility implementation for a menu component.
3
+ * A menu displays a list of actions or options that a user can choose.
4
+ * Based on @react-aria/menu useMenu.
5
+ */
6
+
7
+ import { createEffect, onCleanup, type JSX, type Accessor } from "solid-js";
8
+ import { createFocusWithin } from "../interactions/createFocusWithin";
9
+ import { createLabel } from "../label/createLabel";
10
+ import { createTypeSelect } from "../selection/createTypeSelect";
11
+ import { filterDOMProps } from "../utils/filterDOMProps";
12
+ import { mergeProps } from "../utils/mergeProps";
13
+ import { createId } from "../ssr";
14
+ import { access, type MaybeAccessor } from "../utils/reactivity";
15
+ import { isDevEnv } from "../utils/env";
16
+ import type { MenuState, Key, Collection } from "@proyecto-viviana/solid-stately";
17
+
18
+ /**
19
+ * Default number of items to skip for page up/down when DOM measurement is not available.
20
+ */
21
+ const DEFAULT_PAGE_SIZE = 10;
22
+
23
+ /**
24
+ * Find the next non-disabled key in a collection.
25
+ */
26
+ function findNextNonDisabledKey<T>(
27
+ collection: Collection<T>,
28
+ currentKey: Key | null,
29
+ direction: "next" | "prev",
30
+ isDisabled: (key: Key) => boolean,
31
+ wrap: boolean,
32
+ ): Key | null {
33
+ const getNextKey =
34
+ direction === "next"
35
+ ? (key: Key) => collection.getKeyAfter(key)
36
+ : (key: Key) => collection.getKeyBefore(key);
37
+
38
+ const getFirstKey =
39
+ direction === "next" ? () => collection.getFirstKey() : () => collection.getLastKey();
40
+
41
+ let nextKey = currentKey != null ? getNextKey(currentKey) : getFirstKey();
42
+
43
+ // Skip disabled keys
44
+ while (nextKey != null && isDisabled(nextKey)) {
45
+ nextKey = getNextKey(nextKey);
46
+ }
47
+
48
+ // If we've reached the end and wrapping is enabled
49
+ if (nextKey == null && wrap) {
50
+ nextKey = getFirstKey();
51
+ // Skip disabled keys from the start
52
+ while (nextKey != null && isDisabled(nextKey)) {
53
+ nextKey = getNextKey(nextKey);
54
+ }
55
+ }
56
+
57
+ return nextKey;
58
+ }
59
+
60
+ export interface AriaMenuProps {
61
+ /** An ID for the menu. */
62
+ id?: string;
63
+ /** Whether the menu is disabled. */
64
+ isDisabled?: boolean;
65
+ /** The label for the menu. */
66
+ label?: JSX.Element;
67
+ /** An accessible label for the menu when no visible label is provided. */
68
+ "aria-label"?: string;
69
+ /** The ID of an element that labels the menu. */
70
+ "aria-labelledby"?: string;
71
+ /** The ID of an element that describes the menu. */
72
+ "aria-describedby"?: string;
73
+ /** Handler called when focus moves into the menu. */
74
+ onFocus?: (e: FocusEvent) => void;
75
+ /** Handler called when focus moves out of the menu. */
76
+ onBlur?: (e: FocusEvent) => void;
77
+ /** Handler called when the focus state changes. */
78
+ onFocusChange?: (isFocused: boolean) => void;
79
+ /** Handler called when an item is activated (pressed). */
80
+ onAction?: (key: Key) => void;
81
+ /** Handler called when the menu should close. */
82
+ onClose?: () => void;
83
+ /** Whether focus should automatically wrap around. */
84
+ shouldFocusWrap?: boolean;
85
+ /** Whether to auto-focus the first item when the menu opens. */
86
+ autoFocus?: boolean | "first" | "last";
87
+ /** Whether type-to-select is disabled. @default false */
88
+ disallowTypeAhead?: boolean;
89
+ }
90
+
91
+ export interface MenuAria {
92
+ /** Props for the menu element. */
93
+ menuProps: JSX.HTMLAttributes<HTMLElement>;
94
+ /** Props for the menu's label element (if any). */
95
+ labelProps: JSX.HTMLAttributes<HTMLElement>;
96
+ }
97
+
98
+ // Shared data between menu and menu items
99
+ const menuData = new WeakMap<object, MenuData>();
100
+
101
+ interface MenuData {
102
+ id: string;
103
+ onAction?: (key: Key) => void;
104
+ onClose?: () => void;
105
+ isDisabled?: boolean;
106
+ }
107
+
108
+ export function getMenuData(state: MenuState): MenuData | undefined {
109
+ return menuData.get(state);
110
+ }
111
+
112
+ /**
113
+ * Provides the behavior and accessibility implementation for a menu component.
114
+ * A menu displays a list of actions or options that a user can choose.
115
+ */
116
+ export function createMenu<T>(
117
+ props: MaybeAccessor<AriaMenuProps>,
118
+ state: MenuState<T>,
119
+ ref?: Accessor<HTMLElement | null>,
120
+ ): MenuAria {
121
+ const getProps = () => access(props);
122
+ const id = createId(getProps().id);
123
+
124
+ // Development-time warning for missing accessibility labels
125
+ if (isDevEnv()) {
126
+ const p = getProps();
127
+ if (!p.label && !p["aria-label"] && !p["aria-labelledby"]) {
128
+ console.warn(
129
+ "[solidaria] A Menu requires an aria-label or aria-labelledby attribute for accessibility.",
130
+ );
131
+ }
132
+ }
133
+
134
+ // Filter DOM props
135
+ const domProps = () =>
136
+ filterDOMProps(getProps() as unknown as Record<string, unknown>, { labelable: true });
137
+
138
+ const updateSharedData = () => {
139
+ const p = getProps();
140
+ menuData.set(state, {
141
+ id,
142
+ onAction: p.onAction,
143
+ onClose: p.onClose,
144
+ isDisabled: p.isDisabled,
145
+ });
146
+ };
147
+
148
+ // Ensure menu items created in the same render pass can read parent metadata.
149
+ updateSharedData();
150
+
151
+ // Share data with child menu items
152
+ createEffect(() => {
153
+ updateSharedData();
154
+
155
+ onCleanup(() => {
156
+ menuData.delete(state);
157
+ });
158
+ });
159
+
160
+ // Handle focus within
161
+ const { focusWithinProps } = createFocusWithin({
162
+ onFocusWithin: (e) => getProps().onFocus?.(e),
163
+ onBlurWithin: (e) => getProps().onBlur?.(e),
164
+ onFocusWithinChange: (isFocused) => {
165
+ getProps().onFocusChange?.(isFocused);
166
+ state.setFocused(isFocused);
167
+ },
168
+ });
169
+
170
+ // Label handling
171
+ const { labelProps, fieldProps } = createLabel({
172
+ get id() {
173
+ return id;
174
+ },
175
+ get label() {
176
+ return getProps().label;
177
+ },
178
+ get "aria-label"() {
179
+ return getProps()["aria-label"];
180
+ },
181
+ get "aria-labelledby"() {
182
+ return getProps()["aria-labelledby"];
183
+ },
184
+ labelElementType: "span",
185
+ });
186
+
187
+ // Type-to-select
188
+ const { typeSelectProps } = createTypeSelect({
189
+ collection: () => state.collection(),
190
+ focusedKey: () => state.focusedKey(),
191
+ onFocusedKeyChange: (key) => state.setFocusedKey(key),
192
+ isKeyDisabled: (key) => state.isDisabled(key),
193
+ get isDisabled() {
194
+ return getProps().disallowTypeAhead ?? false;
195
+ },
196
+ });
197
+
198
+ // Keyboard navigation
199
+ const onKeyDown: JSX.EventHandler<HTMLElement, KeyboardEvent> = (e) => {
200
+ if (getProps().isDisabled) return;
201
+
202
+ const collection = state.collection();
203
+ const p = getProps();
204
+ const wrap = p.shouldFocusWrap ?? false;
205
+
206
+ // Use state.isDisabled which properly checks the disabledKeys accessor
207
+ const isDisabled = (key: Key) => state.isDisabled(key);
208
+
209
+ switch (e.key) {
210
+ case "ArrowDown": {
211
+ e.preventDefault();
212
+ const currentKey = state.focusedKey();
213
+ const nextKey = findNextNonDisabledKey(collection, currentKey, "next", isDisabled, wrap);
214
+ if (nextKey != null) {
215
+ state.setFocusedKey(nextKey);
216
+ }
217
+ break;
218
+ }
219
+ case "ArrowUp": {
220
+ e.preventDefault();
221
+ const currentKey = state.focusedKey();
222
+ const prevKey = findNextNonDisabledKey(collection, currentKey, "prev", isDisabled, wrap);
223
+ if (prevKey != null) {
224
+ state.setFocusedKey(prevKey);
225
+ }
226
+ break;
227
+ }
228
+ case "Home": {
229
+ e.preventDefault();
230
+ // Find first non-disabled key
231
+ let firstKey = collection.getFirstKey();
232
+ while (firstKey != null && isDisabled(firstKey)) {
233
+ firstKey = collection.getKeyAfter(firstKey);
234
+ }
235
+ if (firstKey != null) {
236
+ state.setFocusedKey(firstKey);
237
+ }
238
+ break;
239
+ }
240
+ case "End": {
241
+ e.preventDefault();
242
+ // Find last non-disabled key
243
+ let lastKey = collection.getLastKey();
244
+ while (lastKey != null && isDisabled(lastKey)) {
245
+ lastKey = collection.getKeyBefore(lastKey);
246
+ }
247
+ if (lastKey != null) {
248
+ state.setFocusedKey(lastKey);
249
+ }
250
+ break;
251
+ }
252
+ case " ":
253
+ case "Enter": {
254
+ e.preventDefault();
255
+ const focusedKey = state.focusedKey();
256
+ // Don't activate disabled items
257
+ if (focusedKey != null && !isDisabled(focusedKey)) {
258
+ state.select(focusedKey, e, collection);
259
+ p.onAction?.(focusedKey);
260
+ p.onClose?.();
261
+ }
262
+ break;
263
+ }
264
+ case "Escape": {
265
+ e.preventDefault();
266
+ p.onClose?.();
267
+ break;
268
+ }
269
+ case "PageDown": {
270
+ e.preventDefault();
271
+ const currentKey = state.focusedKey();
272
+ const el = ref?.();
273
+
274
+ if (el) {
275
+ // Use DOM measurements to calculate how many items fit in a page
276
+ const visibleHeight = el.clientHeight;
277
+ let traveled = 0;
278
+ let targetKey = currentKey;
279
+
280
+ while (targetKey != null && traveled < visibleHeight) {
281
+ const nextKey = collection.getKeyAfter(targetKey);
282
+ if (nextKey == null) break;
283
+
284
+ // Try to measure the item height
285
+ const itemElement = el.querySelector(`[data-key="${targetKey}"]`);
286
+ traveled += itemElement?.clientHeight ?? 32;
287
+
288
+ // Skip disabled items
289
+ if (!isDisabled(nextKey)) {
290
+ targetKey = nextKey;
291
+ } else {
292
+ // Skip over disabled items without counting them
293
+ const afterDisabled = findNextNonDisabledKey(
294
+ collection,
295
+ nextKey,
296
+ "next",
297
+ isDisabled,
298
+ false,
299
+ );
300
+ if (afterDisabled != null) {
301
+ targetKey = afterDisabled;
302
+ } else {
303
+ break;
304
+ }
305
+ }
306
+ }
307
+
308
+ if (targetKey != null && targetKey !== currentKey) {
309
+ state.setFocusedKey(targetKey);
310
+ }
311
+ } else {
312
+ // Fallback: move by DEFAULT_PAGE_SIZE items
313
+ let count = DEFAULT_PAGE_SIZE;
314
+ let targetKey = currentKey;
315
+
316
+ while (count > 0 && targetKey != null) {
317
+ const nextKey = findNextNonDisabledKey(
318
+ collection,
319
+ targetKey,
320
+ "next",
321
+ isDisabled,
322
+ false,
323
+ );
324
+ if (nextKey == null) break;
325
+ targetKey = nextKey;
326
+ count--;
327
+ }
328
+
329
+ if (targetKey != null) {
330
+ state.setFocusedKey(targetKey);
331
+ }
332
+ }
333
+ break;
334
+ }
335
+ case "PageUp": {
336
+ e.preventDefault();
337
+ const currentKey = state.focusedKey();
338
+ const el = ref?.();
339
+
340
+ if (el) {
341
+ // Use DOM measurements to calculate how many items fit in a page
342
+ const visibleHeight = el.clientHeight;
343
+ let traveled = 0;
344
+ let targetKey = currentKey;
345
+
346
+ while (targetKey != null && traveled < visibleHeight) {
347
+ const prevKey = collection.getKeyBefore(targetKey);
348
+ if (prevKey == null) break;
349
+
350
+ // Try to measure the item height
351
+ const itemElement = el.querySelector(`[data-key="${targetKey}"]`);
352
+ traveled += itemElement?.clientHeight ?? 32;
353
+
354
+ // Skip disabled items
355
+ if (!isDisabled(prevKey)) {
356
+ targetKey = prevKey;
357
+ } else {
358
+ // Skip over disabled items without counting them
359
+ const beforeDisabled = findNextNonDisabledKey(
360
+ collection,
361
+ prevKey,
362
+ "prev",
363
+ isDisabled,
364
+ false,
365
+ );
366
+ if (beforeDisabled != null) {
367
+ targetKey = beforeDisabled;
368
+ } else {
369
+ break;
370
+ }
371
+ }
372
+ }
373
+
374
+ if (targetKey != null && targetKey !== currentKey) {
375
+ state.setFocusedKey(targetKey);
376
+ }
377
+ } else {
378
+ // Fallback: move by DEFAULT_PAGE_SIZE items
379
+ let count = DEFAULT_PAGE_SIZE;
380
+ let targetKey = currentKey;
381
+
382
+ while (count > 0 && targetKey != null) {
383
+ const prevKey = findNextNonDisabledKey(
384
+ collection,
385
+ targetKey,
386
+ "prev",
387
+ isDisabled,
388
+ false,
389
+ );
390
+ if (prevKey == null) break;
391
+ targetKey = prevKey;
392
+ count--;
393
+ }
394
+
395
+ if (targetKey != null) {
396
+ state.setFocusedKey(targetKey);
397
+ }
398
+ }
399
+ break;
400
+ }
401
+ }
402
+ };
403
+
404
+ return {
405
+ get labelProps() {
406
+ return labelProps as JSX.HTMLAttributes<HTMLElement>;
407
+ },
408
+ get menuProps() {
409
+ const p = getProps();
410
+
411
+ const baseProps = mergeProps(
412
+ domProps(),
413
+ focusWithinProps as Record<string, unknown>,
414
+ fieldProps as Record<string, unknown>,
415
+ {
416
+ role: "menu",
417
+ tabIndex: p.isDisabled ? undefined : 0,
418
+ "aria-disabled": p.isDisabled || undefined,
419
+ onKeyDown,
420
+ } as Record<string, unknown>,
421
+ );
422
+
423
+ // Add type-select props if enabled
424
+ if (!p.disallowTypeAhead) {
425
+ return mergeProps(
426
+ baseProps,
427
+ typeSelectProps as Record<string, unknown>,
428
+ ) as JSX.HTMLAttributes<HTMLElement>;
429
+ }
430
+
431
+ return baseProps as JSX.HTMLAttributes<HTMLElement>;
432
+ },
433
+ };
434
+ }