@proyecto-viviana/solid-stately 0.5.1 → 0.6.0-rc.1

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 (418) hide show
  1. package/LICENSE-APACHE-2.0 +201 -0
  2. package/NOTICE +91 -0
  3. package/README.md +59 -29
  4. package/dist/autocomplete/createAutocompleteState.d.ts +2 -1
  5. package/dist/autocomplete/createAutocompleteState.d.ts.map +1 -0
  6. package/dist/autocomplete/index.d.ts +1 -0
  7. package/dist/autocomplete/index.d.ts.map +1 -0
  8. package/dist/calendar/IncompleteDate.d.ts +2 -1
  9. package/dist/calendar/IncompleteDate.d.ts.map +1 -0
  10. package/dist/calendar/createCalendarState.d.ts +10 -9
  11. package/dist/calendar/createCalendarState.d.ts.map +1 -0
  12. package/dist/calendar/createDateFieldState.d.ts +4 -20
  13. package/dist/calendar/createDateFieldState.d.ts.map +1 -0
  14. package/dist/calendar/createDatePickerState.d.ts +4 -7
  15. package/dist/calendar/createDatePickerState.d.ts.map +1 -0
  16. package/dist/calendar/createRangeCalendarState.d.ts +9 -7
  17. package/dist/calendar/createRangeCalendarState.d.ts.map +1 -0
  18. package/dist/calendar/createTimeFieldState.d.ts +5 -24
  19. package/dist/calendar/createTimeFieldState.d.ts.map +1 -0
  20. package/dist/calendar/index.d.ts +1 -0
  21. package/dist/calendar/index.d.ts.map +1 -0
  22. package/dist/calendar/intl/index.d.ts +1 -0
  23. package/dist/calendar/intl/index.d.ts.map +1 -0
  24. package/dist/checkbox/createCheckboxGroupState.d.ts +3 -0
  25. package/dist/checkbox/createCheckboxGroupState.d.ts.map +1 -0
  26. package/dist/checkbox/index.d.ts +1 -0
  27. package/dist/checkbox/index.d.ts.map +1 -0
  28. package/dist/collections/ListCollection.d.ts +5 -0
  29. package/dist/collections/ListCollection.d.ts.map +1 -0
  30. package/dist/collections/createListState.d.ts +2 -6
  31. package/dist/collections/createListState.d.ts.map +1 -0
  32. package/dist/collections/createMenuState.d.ts +74 -13
  33. package/dist/collections/createMenuState.d.ts.map +1 -0
  34. package/dist/collections/createSelectionState.d.ts +2 -5
  35. package/dist/collections/createSelectionState.d.ts.map +1 -0
  36. package/dist/collections/getChildNodes.d.ts +6 -3
  37. package/dist/collections/getChildNodes.d.ts.map +1 -0
  38. package/dist/collections/index.d.ts +2 -1
  39. package/dist/collections/index.d.ts.map +1 -0
  40. package/dist/collections/types.d.ts +36 -2
  41. package/dist/collections/types.d.ts.map +1 -0
  42. package/dist/color/Color.d.ts +7 -1
  43. package/dist/color/Color.d.ts.map +1 -0
  44. package/dist/color/createColorAreaState.d.ts +6 -5
  45. package/dist/color/createColorAreaState.d.ts.map +1 -0
  46. package/dist/color/createColorFieldState.d.ts +4 -5
  47. package/dist/color/createColorFieldState.d.ts.map +1 -0
  48. package/dist/color/createColorSliderState.d.ts +4 -5
  49. package/dist/color/createColorSliderState.d.ts.map +1 -0
  50. package/dist/color/createColorWheelState.d.ts +2 -5
  51. package/dist/color/createColorWheelState.d.ts.map +1 -0
  52. package/dist/color/getColorChannels.d.ts +3 -0
  53. package/dist/color/getColorChannels.d.ts.map +1 -0
  54. package/dist/color/index.d.ts +2 -1
  55. package/dist/color/index.d.ts.map +1 -0
  56. package/dist/color/intl/index.d.ts +1 -0
  57. package/dist/color/intl/index.d.ts.map +1 -0
  58. package/dist/color/types.d.ts +2 -1
  59. package/dist/color/types.d.ts.map +1 -0
  60. package/dist/combobox/createComboBoxState.d.ts +92 -29
  61. package/dist/combobox/createComboBoxState.d.ts.map +1 -0
  62. package/dist/combobox/index.d.ts +2 -1
  63. package/dist/combobox/index.d.ts.map +1 -0
  64. package/dist/data/createAsyncList.d.ts +1 -7
  65. package/dist/data/createAsyncList.d.ts.map +1 -0
  66. package/dist/data/createListData.d.ts +1 -6
  67. package/dist/data/createListData.d.ts.map +1 -0
  68. package/dist/data/createTreeData.d.ts +1 -6
  69. package/dist/data/createTreeData.d.ts.map +1 -0
  70. package/dist/data/index.d.ts +1 -0
  71. package/dist/data/index.d.ts.map +1 -0
  72. package/dist/datepicker/index.d.ts +1 -0
  73. package/dist/datepicker/index.d.ts.map +1 -0
  74. package/dist/disclosure/createDisclosureState.d.ts +2 -5
  75. package/dist/disclosure/createDisclosureState.d.ts.map +1 -0
  76. package/dist/disclosure/index.d.ts +1 -0
  77. package/dist/disclosure/index.d.ts.map +1 -0
  78. package/dist/dnd/createDragState.d.ts +2 -6
  79. package/dist/dnd/createDragState.d.ts.map +1 -0
  80. package/dist/dnd/createDraggableCollectionState.d.ts +44 -11
  81. package/dist/dnd/createDraggableCollectionState.d.ts.map +1 -0
  82. package/dist/dnd/createDropState.d.ts +2 -6
  83. package/dist/dnd/createDropState.d.ts.map +1 -0
  84. package/dist/dnd/createDroppableCollectionState.d.ts +34 -11
  85. package/dist/dnd/createDroppableCollectionState.d.ts.map +1 -0
  86. package/dist/dnd/index.d.ts +3 -2
  87. package/dist/dnd/index.d.ts.map +1 -0
  88. package/dist/dnd/types.d.ts +17 -0
  89. package/dist/dnd/types.d.ts.map +1 -0
  90. package/dist/form/createFormValidationState.d.ts +2 -9
  91. package/{src → dist}/form/createFormValidationState.d.ts.map +1 -1
  92. package/dist/form/index.d.ts +1 -0
  93. package/dist/form/index.d.ts.map +1 -0
  94. package/dist/grid/createGridState.d.ts +4 -3
  95. package/dist/grid/createGridState.d.ts.map +1 -0
  96. package/dist/grid/index.d.ts +1 -0
  97. package/dist/grid/index.d.ts.map +1 -0
  98. package/dist/grid/types.d.ts +23 -1
  99. package/dist/grid/types.d.ts.map +1 -0
  100. package/dist/index.d.ts +7 -5
  101. package/dist/index.d.ts.map +1 -0
  102. package/dist/index.js +2947 -969
  103. package/dist/index.js.map +1 -1
  104. package/dist/menu/index.d.ts +3 -1
  105. package/dist/menu/index.d.ts.map +1 -0
  106. package/dist/numberfield/createNumberFieldState.d.ts +37 -9
  107. package/dist/numberfield/createNumberFieldState.d.ts.map +1 -0
  108. package/dist/numberfield/index.d.ts +1 -0
  109. package/dist/numberfield/index.d.ts.map +1 -0
  110. package/dist/overlays/createOverlayTriggerState.d.ts +12 -1
  111. package/dist/overlays/createOverlayTriggerState.d.ts.map +1 -0
  112. package/dist/overlays/index.d.ts +1 -0
  113. package/dist/overlays/index.d.ts.map +1 -0
  114. package/dist/private/flags/flags.d.ts +5 -0
  115. package/dist/private/flags/flags.d.ts.map +1 -0
  116. package/dist/private/flags/flags.js +26 -0
  117. package/dist/private/flags/flags.js.map +1 -0
  118. package/dist/radio/createRadioGroupState.d.ts +1 -0
  119. package/dist/radio/createRadioGroupState.d.ts.map +1 -0
  120. package/dist/radio/index.d.ts +1 -0
  121. package/dist/radio/index.d.ts.map +1 -0
  122. package/dist/searchfield/createSearchFieldState.d.ts +2 -5
  123. package/dist/searchfield/createSearchFieldState.d.ts.map +1 -0
  124. package/dist/searchfield/index.d.ts +1 -0
  125. package/dist/searchfield/index.d.ts.map +1 -0
  126. package/dist/select/createSelectState.d.ts +100 -33
  127. package/dist/select/createSelectState.d.ts.map +1 -0
  128. package/dist/select/index.d.ts +2 -1
  129. package/dist/select/index.d.ts.map +1 -0
  130. package/dist/selection/Selection.d.ts +2 -1
  131. package/dist/selection/Selection.d.ts.map +1 -0
  132. package/dist/selection/SelectionManager.d.ts +1 -19
  133. package/dist/selection/SelectionManager.d.ts.map +1 -0
  134. package/dist/selection/createMultipleSelectionState.d.ts +2 -13
  135. package/dist/selection/createMultipleSelectionState.d.ts.map +1 -0
  136. package/dist/selection/index.d.ts +1 -0
  137. package/dist/selection/index.d.ts.map +1 -0
  138. package/dist/slider/createSliderState.d.ts +37 -14
  139. package/dist/slider/createSliderState.d.ts.map +1 -0
  140. package/dist/slider/index.d.ts +1 -0
  141. package/dist/slider/index.d.ts.map +1 -0
  142. package/dist/ssr/index.d.ts +2 -13
  143. package/dist/ssr/index.d.ts.map +1 -0
  144. package/dist/steplist/createStepListState.d.ts +10 -18
  145. package/dist/steplist/createStepListState.d.ts.map +1 -0
  146. package/dist/steplist/index.d.ts +1 -0
  147. package/dist/steplist/index.d.ts.map +1 -0
  148. package/dist/table/TableCollection.d.ts +1 -0
  149. package/dist/table/TableCollection.d.ts.map +1 -0
  150. package/dist/table/createTableColumnResizeState.d.ts +2 -9
  151. package/dist/table/createTableColumnResizeState.d.ts.map +1 -0
  152. package/dist/table/createTableState.d.ts +3 -6
  153. package/dist/table/createTableState.d.ts.map +1 -0
  154. package/dist/table/createTreeGridState.d.ts +3 -9
  155. package/dist/table/createTreeGridState.d.ts.map +1 -0
  156. package/dist/table/index.d.ts +1 -0
  157. package/dist/table/index.d.ts.map +1 -0
  158. package/dist/table/types.d.ts +37 -3
  159. package/dist/table/types.d.ts.map +1 -0
  160. package/dist/tabs/createTabListState.d.ts +2 -5
  161. package/dist/tabs/createTabListState.d.ts.map +1 -0
  162. package/dist/tabs/index.d.ts +1 -0
  163. package/dist/tabs/index.d.ts.map +1 -0
  164. package/dist/textfield/createTextFieldState.d.ts +1 -0
  165. package/dist/textfield/createTextFieldState.d.ts.map +1 -0
  166. package/dist/textfield/index.d.ts +1 -0
  167. package/dist/textfield/index.d.ts.map +1 -0
  168. package/dist/toast/createToastState.d.ts +2 -5
  169. package/dist/toast/createToastState.d.ts.map +1 -0
  170. package/dist/toast/index.d.ts +1 -0
  171. package/dist/toast/index.d.ts.map +1 -0
  172. package/dist/toggle/createToggleGroupState.d.ts +1 -0
  173. package/dist/toggle/createToggleGroupState.d.ts.map +1 -0
  174. package/dist/toggle/createToggleState.d.ts +1 -0
  175. package/dist/toggle/createToggleState.d.ts.map +1 -0
  176. package/dist/toggle/index.d.ts +1 -0
  177. package/dist/toggle/index.d.ts.map +1 -0
  178. package/dist/tokenfield/TokenFieldValue.d.ts +96 -0
  179. package/dist/tokenfield/TokenFieldValue.d.ts.map +1 -0
  180. package/dist/tokenfield/createTokenFieldState.d.ts +33 -0
  181. package/dist/tokenfield/createTokenFieldState.d.ts.map +1 -0
  182. package/dist/tokenfield/index.d.ts +3 -0
  183. package/dist/tokenfield/index.d.ts.map +1 -0
  184. package/dist/tooltip/createTooltipTriggerState.d.ts +9 -8
  185. package/dist/tooltip/createTooltipTriggerState.d.ts.map +1 -0
  186. package/dist/tooltip/index.d.ts +1 -0
  187. package/dist/tooltip/index.d.ts.map +1 -0
  188. package/dist/tree/TreeCollection.d.ts +1 -0
  189. package/dist/tree/TreeCollection.d.ts.map +1 -0
  190. package/dist/tree/createTreeState.d.ts +3 -8
  191. package/dist/tree/createTreeState.d.ts.map +1 -0
  192. package/dist/tree/index.d.ts +1 -0
  193. package/dist/tree/index.d.ts.map +1 -0
  194. package/dist/tree/types.d.ts +19 -1
  195. package/dist/tree/types.d.ts.map +1 -0
  196. package/dist/utils/index.d.ts +3 -1
  197. package/dist/utils/index.d.ts.map +1 -0
  198. package/dist/utils/owner.d.ts +9 -0
  199. package/dist/utils/owner.d.ts.map +1 -0
  200. package/dist/utils/reactivity.d.ts +24 -0
  201. package/dist/utils/reactivity.d.ts.map +1 -0
  202. package/package.json +21 -9
  203. package/src/autocomplete/createAutocompleteState.ts +18 -4
  204. package/src/calendar/IncompleteDate.ts +15 -1
  205. package/src/calendar/createCalendarState.ts +321 -125
  206. package/src/calendar/createDateFieldState.ts +45 -31
  207. package/src/calendar/createDatePickerState.ts +47 -26
  208. package/src/calendar/createRangeCalendarState.ts +173 -86
  209. package/src/calendar/createTimeFieldState.ts +26 -7
  210. package/src/calendar/intl/index.ts +37 -2
  211. package/src/checkbox/createCheckboxGroupState.ts +45 -13
  212. package/src/collections/ListCollection.ts +31 -0
  213. package/src/collections/createListState.ts +27 -10
  214. package/src/collections/createMenuState.ts +190 -15
  215. package/src/collections/createSelectionState.ts +33 -13
  216. package/src/collections/getChildNodes.ts +20 -3
  217. package/src/collections/index.ts +6 -0
  218. package/src/collections/types.ts +35 -2
  219. package/src/color/Color.ts +61 -22
  220. package/src/color/createColorAreaState.ts +48 -4
  221. package/src/color/createColorFieldState.ts +114 -38
  222. package/src/color/createColorSliderState.ts +61 -9
  223. package/src/color/createColorWheelState.ts +29 -9
  224. package/src/color/getColorChannels.ts +16 -0
  225. package/src/color/index.ts +1 -0
  226. package/src/color/intl/index.ts +38 -3
  227. package/src/color/types.ts +1 -1
  228. package/src/combobox/createComboBoxState.ts +530 -297
  229. package/src/combobox/index.ts +4 -0
  230. package/src/data/createAsyncList.ts +41 -6
  231. package/src/data/createListData.ts +27 -4
  232. package/src/data/createTreeData.ts +30 -6
  233. package/src/disclosure/createDisclosureState.ts +40 -19
  234. package/src/dnd/createDragState.ts +22 -4
  235. package/src/dnd/createDraggableCollectionState.ts +145 -11
  236. package/src/dnd/createDropState.ts +21 -3
  237. package/src/dnd/createDroppableCollectionState.ts +127 -11
  238. package/src/dnd/index.ts +4 -0
  239. package/src/dnd/types.ts +16 -0
  240. package/src/form/createFormValidationState.ts +69 -37
  241. package/src/grid/createGridState.ts +196 -111
  242. package/src/grid/types.ts +22 -1
  243. package/src/index.ts +33 -2
  244. package/src/menu/index.ts +7 -0
  245. package/src/numberfield/createNumberFieldState.ts +247 -98
  246. package/src/overlays/createOverlayTriggerState.ts +31 -4
  247. package/src/private/flags/flags.ts +25 -0
  248. package/src/radio/createRadioGroupState.ts +23 -6
  249. package/src/searchfield/createSearchFieldState.ts +18 -3
  250. package/src/select/createSelectState.ts +317 -130
  251. package/src/select/index.ts +8 -1
  252. package/src/selection/Selection.ts +15 -1
  253. package/src/selection/SelectionManager.ts +17 -1
  254. package/src/selection/createMultipleSelectionState.ts +45 -26
  255. package/src/slider/createSliderState.ts +243 -104
  256. package/src/ssr/index.ts +34 -4
  257. package/src/steplist/createStepListState.ts +184 -130
  258. package/src/table/TableCollection.ts +14 -0
  259. package/src/table/createTableColumnResizeState.ts +71 -14
  260. package/src/table/createTableState.ts +26 -4
  261. package/src/table/createTreeGridState.ts +22 -6
  262. package/src/table/types.ts +38 -5
  263. package/src/tabs/createTabListState.ts +63 -43
  264. package/src/textfield/createTextFieldState.ts +17 -3
  265. package/src/toast/createToastState.ts +28 -3
  266. package/src/toggle/createToggleGroupState.ts +20 -5
  267. package/src/toggle/createToggleState.ts +19 -4
  268. package/src/tokenfield/TokenFieldValue.ts +499 -0
  269. package/src/tokenfield/createTokenFieldState.ts +88 -0
  270. package/src/tokenfield/index.ts +15 -0
  271. package/src/tooltip/createTooltipTriggerState.ts +49 -13
  272. package/src/tree/TreeCollection.ts +14 -0
  273. package/src/tree/createTreeState.ts +70 -36
  274. package/src/tree/types.ts +18 -1
  275. package/src/utils/index.ts +10 -1
  276. package/src/utils/owner.ts +20 -0
  277. package/src/utils/reactivity.ts +53 -1
  278. package/src/autocomplete/createAutocompleteState.d.ts +0 -48
  279. package/src/autocomplete/createAutocompleteState.d.ts.map +0 -1
  280. package/src/autocomplete/index.d.ts +0 -6
  281. package/src/autocomplete/index.d.ts.map +0 -1
  282. package/src/calendar/createCalendarState.d.ts +0 -152
  283. package/src/calendar/createCalendarState.d.ts.map +0 -1
  284. package/src/calendar/createDateFieldState.d.ts +0 -145
  285. package/src/calendar/createDateFieldState.d.ts.map +0 -1
  286. package/src/calendar/createRangeCalendarState.d.ts +0 -171
  287. package/src/calendar/createRangeCalendarState.d.ts.map +0 -1
  288. package/src/calendar/createTimeFieldState.d.ts +0 -97
  289. package/src/calendar/createTimeFieldState.d.ts.map +0 -1
  290. package/src/calendar/index.d.ts +0 -80
  291. package/src/calendar/index.d.ts.map +0 -1
  292. package/src/checkbox/createCheckboxGroupState.d.ts +0 -73
  293. package/src/checkbox/createCheckboxGroupState.d.ts.map +0 -1
  294. package/src/checkbox/index.d.ts +0 -6
  295. package/src/checkbox/index.d.ts.map +0 -1
  296. package/src/collections/ListCollection.d.ts +0 -40
  297. package/src/collections/ListCollection.d.ts.map +0 -1
  298. package/src/collections/createListState.d.ts +0 -94
  299. package/src/collections/createListState.d.ts.map +0 -1
  300. package/src/collections/createMenuState.d.ts +0 -55
  301. package/src/collections/createMenuState.d.ts.map +0 -1
  302. package/src/collections/createSelectionState.d.ts +0 -89
  303. package/src/collections/createSelectionState.d.ts.map +0 -1
  304. package/src/collections/index.d.ts +0 -38
  305. package/src/collections/index.d.ts.map +0 -1
  306. package/src/collections/types.d.ts +0 -147
  307. package/src/collections/types.d.ts.map +0 -1
  308. package/src/color/Color.d.ts +0 -43
  309. package/src/color/Color.d.ts.map +0 -1
  310. package/src/color/createColorAreaState.d.ts +0 -78
  311. package/src/color/createColorAreaState.d.ts.map +0 -1
  312. package/src/color/createColorFieldState.d.ts +0 -57
  313. package/src/color/createColorFieldState.d.ts.map +0 -1
  314. package/src/color/createColorSliderState.d.ts +0 -69
  315. package/src/color/createColorSliderState.d.ts.map +0 -1
  316. package/src/color/createColorWheelState.d.ts +0 -53
  317. package/src/color/createColorWheelState.d.ts.map +0 -1
  318. package/src/color/index.d.ts +0 -39
  319. package/src/color/index.d.ts.map +0 -1
  320. package/src/color/types.d.ts +0 -111
  321. package/src/color/types.d.ts.map +0 -1
  322. package/src/combobox/createComboBoxState.d.ts +0 -127
  323. package/src/combobox/createComboBoxState.d.ts.map +0 -1
  324. package/src/combobox/index.d.ts +0 -13
  325. package/src/combobox/index.d.ts.map +0 -1
  326. package/src/disclosure/createDisclosureState.d.ts +0 -68
  327. package/src/disclosure/createDisclosureState.d.ts.map +0 -1
  328. package/src/disclosure/index.d.ts +0 -10
  329. package/src/disclosure/index.d.ts.map +0 -1
  330. package/src/dnd/createDragState.d.ts +0 -68
  331. package/src/dnd/createDragState.d.ts.map +0 -1
  332. package/src/dnd/createDraggableCollectionState.d.ts +0 -68
  333. package/src/dnd/createDraggableCollectionState.d.ts.map +0 -1
  334. package/src/dnd/createDropState.d.ts +0 -80
  335. package/src/dnd/createDropState.d.ts.map +0 -1
  336. package/src/dnd/createDroppableCollectionState.d.ts +0 -107
  337. package/src/dnd/createDroppableCollectionState.d.ts.map +0 -1
  338. package/src/dnd/index.d.ts +0 -60
  339. package/src/dnd/index.d.ts.map +0 -1
  340. package/src/dnd/types.d.ts +0 -277
  341. package/src/dnd/types.d.ts.map +0 -1
  342. package/src/form/createFormValidationState.d.ts +0 -102
  343. package/src/form/index.d.ts +0 -16
  344. package/src/form/index.d.ts.map +0 -1
  345. package/src/grid/createGridState.d.ts +0 -15
  346. package/src/grid/createGridState.d.ts.map +0 -1
  347. package/src/grid/index.d.ts +0 -7
  348. package/src/grid/index.d.ts.map +0 -1
  349. package/src/grid/types.d.ts +0 -163
  350. package/src/grid/types.d.ts.map +0 -1
  351. package/src/index.d.ts +0 -311
  352. package/src/index.d.ts.map +0 -1
  353. package/src/numberfield/createNumberFieldState.d.ts +0 -67
  354. package/src/numberfield/createNumberFieldState.d.ts.map +0 -1
  355. package/src/numberfield/index.d.ts +0 -6
  356. package/src/numberfield/index.d.ts.map +0 -1
  357. package/src/overlays/createOverlayTriggerState.d.ts +0 -34
  358. package/src/overlays/createOverlayTriggerState.d.ts.map +0 -1
  359. package/src/overlays/index.d.ts +0 -6
  360. package/src/overlays/index.d.ts.map +0 -1
  361. package/src/radio/createRadioGroupState.d.ts +0 -79
  362. package/src/radio/createRadioGroupState.d.ts.map +0 -1
  363. package/src/radio/index.d.ts +0 -7
  364. package/src/radio/index.d.ts.map +0 -1
  365. package/src/searchfield/createSearchFieldState.d.ts +0 -27
  366. package/src/searchfield/createSearchFieldState.d.ts.map +0 -1
  367. package/src/searchfield/index.d.ts +0 -3
  368. package/src/searchfield/index.d.ts.map +0 -1
  369. package/src/select/createSelectState.d.ts +0 -75
  370. package/src/select/createSelectState.d.ts.map +0 -1
  371. package/src/select/index.d.ts +0 -2
  372. package/src/select/index.d.ts.map +0 -1
  373. package/src/slider/createSliderState.d.ts +0 -72
  374. package/src/slider/createSliderState.d.ts.map +0 -1
  375. package/src/slider/index.d.ts +0 -3
  376. package/src/slider/index.d.ts.map +0 -1
  377. package/src/ssr/index.d.ts +0 -28
  378. package/src/ssr/index.d.ts.map +0 -1
  379. package/src/table/TableCollection.d.ts +0 -54
  380. package/src/table/TableCollection.d.ts.map +0 -1
  381. package/src/table/createTableState.d.ts +0 -15
  382. package/src/table/createTableState.d.ts.map +0 -1
  383. package/src/table/index.d.ts +0 -18
  384. package/src/table/index.d.ts.map +0 -1
  385. package/src/table/types.d.ts +0 -145
  386. package/src/table/types.d.ts.map +0 -1
  387. package/src/tabs/createTabListState.d.ts +0 -70
  388. package/src/tabs/createTabListState.d.ts.map +0 -1
  389. package/src/tabs/index.d.ts +0 -8
  390. package/src/tabs/index.d.ts.map +0 -1
  391. package/src/textfield/createTextFieldState.d.ts +0 -32
  392. package/src/textfield/createTextFieldState.d.ts.map +0 -1
  393. package/src/textfield/index.d.ts +0 -6
  394. package/src/textfield/index.d.ts.map +0 -1
  395. package/src/toast/createToastState.d.ts +0 -129
  396. package/src/toast/createToastState.d.ts.map +0 -1
  397. package/src/toast/index.d.ts +0 -12
  398. package/src/toast/index.d.ts.map +0 -1
  399. package/src/toggle/createToggleState.d.ts +0 -34
  400. package/src/toggle/createToggleState.d.ts.map +0 -1
  401. package/src/toggle/index.d.ts +0 -2
  402. package/src/toggle/index.d.ts.map +0 -1
  403. package/src/tooltip/createTooltipTriggerState.d.ts +0 -39
  404. package/src/tooltip/createTooltipTriggerState.d.ts.map +0 -1
  405. package/src/tooltip/index.d.ts +0 -7
  406. package/src/tooltip/index.d.ts.map +0 -1
  407. package/src/tree/TreeCollection.d.ts +0 -43
  408. package/src/tree/TreeCollection.d.ts.map +0 -1
  409. package/src/tree/createTreeState.d.ts +0 -17
  410. package/src/tree/createTreeState.d.ts.map +0 -1
  411. package/src/tree/index.d.ts +0 -13
  412. package/src/tree/index.d.ts.map +0 -1
  413. package/src/tree/types.d.ts +0 -162
  414. package/src/tree/types.d.ts.map +0 -1
  415. package/src/utils/index.d.ts +0 -2
  416. package/src/utils/index.d.ts.map +0 -1
  417. package/src/utils/reactivity.d.ts +0 -28
  418. package/src/utils/reactivity.d.ts.map +0 -1
@@ -1,3 +1,17 @@
1
+ /*
2
+ * Copyright 2020 Adobe. All rights reserved.
3
+ * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4
+ * you may not use this file except in compliance with the License. You may obtain a copy
5
+ * of the License at http://www.apache.org/licenses/LICENSE-2.0
6
+ *
7
+ * Unless required by applicable law or agreed to in writing, software distributed under
8
+ * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9
+ * OF ANY KIND, either express or implied. See the License for the specific language
10
+ * governing permissions and limitations under the License.
11
+ */
12
+
13
+ // Ported to SolidJS for Proyecto Viviana; based on packages/react-stately/src/combobox/useComboBoxState.ts
14
+
1
15
  /**
2
16
  * State management for ComboBox components.
3
17
  * Based on @react-stately/combobox useComboBoxState.
@@ -6,12 +20,19 @@
6
20
  * either type to filter options or select from a list.
7
21
  */
8
22
 
9
- import { createSignal, createMemo, createEffect, untrack, type Accessor } from "solid-js";
10
- import { access, type MaybeAccessor } from "../utils";
11
- import { createListState } from "../collections/createListState";
23
+ import { createMemo, createEffect, untrack } from "solid-js";
24
+ import type { Accessor } from "solid-js";
25
+ import { createInternalSignal, propsAccessor, type MaybeAccessor } from "../utils";
26
+ import { createListState, type ListState } from "../collections/createListState";
12
27
  import { createOverlayTriggerState } from "../overlays";
28
+ import { ListCollection } from "../collections/ListCollection";
13
29
  import type { Key, CollectionNode, Collection, FocusStrategy } from "../collections/types";
14
30
  import type { SelectionManager } from "../selection/SelectionManager";
31
+ import {
32
+ createFormValidationState,
33
+ type FormValidationState,
34
+ type ValidationFunction,
35
+ } from "../form";
15
36
 
16
37
  export type MenuTriggerAction = "focus" | "input" | "manual";
17
38
 
@@ -19,7 +40,37 @@ export type { FocusStrategy } from "../collections/types";
19
40
 
20
41
  export type FilterFn = (textValue: string, inputValue: string) => boolean;
21
42
 
22
- export interface ComboBoxStateProps<T = unknown> {
43
+ export type ComboBoxSelectionMode = "single" | "multiple";
44
+
45
+ /** Single mode is `Key | null`. Multiple mode is `readonly Key[]`. */
46
+ export type ComboBoxValueType<M extends ComboBoxSelectionMode> = M extends "single"
47
+ ? Key | null
48
+ : readonly Key[];
49
+
50
+ /** `onChange` receives a mutable `Key[]` in multiple mode. */
51
+ export type ComboBoxChangeValueType<M extends ComboBoxSelectionMode> = M extends "single"
52
+ ? Key | null
53
+ : Key[];
54
+
55
+ type ComboBoxValidationType<M extends ComboBoxSelectionMode> = M extends "single"
56
+ ? Key | null
57
+ : Key[];
58
+
59
+ const EMPTY_COMBOBOX_KEYS: readonly Key[] = [];
60
+
61
+ export interface ComboBoxValidationValue<M extends ComboBoxSelectionMode = "single"> {
62
+ /**
63
+ * The selected key in the ComboBox.
64
+ * @deprecated Use `value`.
65
+ */
66
+ selectedKey: Key | null;
67
+ /** The keys of the currently selected items. */
68
+ value: ComboBoxValidationType<M>;
69
+ /** The value of the ComboBox input. */
70
+ inputValue: string;
71
+ }
72
+
73
+ export interface ComboBoxStateProps<T = unknown, M extends ComboBoxSelectionMode = "single"> {
23
74
  /** The items to display in the combobox dropdown. */
24
75
  items?: T[];
25
76
  /** Default items when uncontrolled. */
@@ -32,20 +83,35 @@ export interface ComboBoxStateProps<T = unknown> {
32
83
  getDisabled?: (item: T) => boolean;
33
84
  /** Keys of disabled items. */
34
85
  disabledKeys?: Iterable<Key>;
35
- /** The selection mode for the combobox. */
36
- selectionMode?: "single" | "multiple";
37
- /** The currently selected key (controlled, single mode). */
86
+ /**
87
+ * Whether single or multiple selection is enabled.
88
+ * @default 'single'
89
+ */
90
+ selectionMode?: M;
91
+ /**
92
+ * The current value (controlled).
93
+ * Single mode is `Key | null`. Multiple mode is `readonly Key[]`.
94
+ */
95
+ value?: ComboBoxValueType<M>;
96
+ /** The default value (uncontrolled). */
97
+ defaultValue?: ComboBoxValueType<M>;
98
+ /** Handler called when the value changes. */
99
+ onChange?: (value: ComboBoxChangeValueType<M>) => void;
100
+ /**
101
+ * The currently selected key in the collection (controlled).
102
+ * @deprecated Use `value`.
103
+ */
38
104
  selectedKey?: Key | null;
39
- /** The default selected key (uncontrolled, single mode). */
105
+ /**
106
+ * The initial selected key in the collection (uncontrolled).
107
+ * @deprecated Use `defaultValue`.
108
+ */
40
109
  defaultSelectedKey?: Key | null;
41
- /** The currently selected keys (controlled, multiple mode). */
42
- selectedKeys?: Iterable<Key>;
43
- /** The default selected keys (uncontrolled, multiple mode). */
44
- defaultSelectedKeys?: Iterable<Key>;
45
- /** Handler called when the selection changes (single mode). */
110
+ /**
111
+ * Handler that is called when the selection changes.
112
+ * @deprecated Use `onChange`.
113
+ */
46
114
  onSelectionChange?: (key: Key | null) => void;
47
- /** Handler called when the selection changes (multiple mode). */
48
- onSelectionChangeMultiple?: (keys: Set<Key>) => void;
49
115
  /** The current input value (controlled). */
50
116
  inputValue?: string;
51
117
  /** The default input value (uncontrolled). */
@@ -74,9 +140,25 @@ export interface ComboBoxStateProps<T = unknown> {
74
140
  menuTrigger?: MenuTriggerAction;
75
141
  /** Whether to close the menu on blur. */
76
142
  shouldCloseOnBlur?: boolean;
143
+ /** Whether the combobox is invalid (controlled). */
144
+ isInvalid?: boolean;
145
+ /** @deprecated Use isInvalid instead. */
146
+ validationState?: "valid" | "invalid";
147
+ /** Custom validation function. */
148
+ validate?: ValidationFunction<ComboBoxValidationValue<M> | null>;
149
+ /**
150
+ * Whether to use native HTML form validation or ARIA validation semantics.
151
+ * @default "native"
152
+ */
153
+ validationBehavior?: "aria" | "native";
154
+ /** Field name(s) for server error lookup. */
155
+ name?: string | string[];
77
156
  }
78
157
 
79
- export interface ComboBoxState<T = unknown> {
158
+ export interface ComboBoxState<
159
+ T = unknown,
160
+ M extends ComboBoxSelectionMode = "single",
161
+ > extends FormValidationState {
80
162
  /** The collection of items (may be filtered). */
81
163
  readonly collection: Accessor<Collection<T>>;
82
164
  /**
@@ -93,17 +175,40 @@ export interface ComboBoxState<T = unknown> {
93
175
  close(): void;
94
176
  /** Toggle the combobox dropdown. */
95
177
  toggle(focusStrategy?: FocusStrategy | null, trigger?: MenuTriggerAction): void;
96
- /** The currently selected key (single mode). */
178
+ /**
179
+ * The key for the first selected item. Null in multiple mode.
180
+ * @deprecated Use `value`.
181
+ */
97
182
  readonly selectedKey: Accessor<Key | null>;
98
- /** The default selected key. */
183
+ /**
184
+ * The default selected key.
185
+ * @deprecated Use `defaultValue`.
186
+ */
99
187
  readonly defaultSelectedKey: Key | null;
100
- /** The currently selected item (single mode). */
188
+ /**
189
+ * The value of the first selected item.
190
+ * @deprecated Use `selectedItems`.
191
+ */
101
192
  readonly selectedItem: Accessor<CollectionNode<T> | null>;
102
- /** Set the selected key. */
193
+ /**
194
+ * Sets the selected key.
195
+ * @deprecated Use `setValue`.
196
+ */
103
197
  setSelectedKey(key: Key | null): void;
104
- /** The currently selected keys (multiple mode). */
198
+ /** The current combobox value. */
199
+ readonly value: Accessor<ComboBoxValueType<M>>;
200
+ /** The default combobox value. */
201
+ readonly defaultValue: ComboBoxValueType<M>;
202
+ /** Sets the combobox value. */
203
+ setValue(value: Key | readonly Key[] | null): void;
204
+ /**
205
+ * Selected keys derived from `value`.
206
+ * Kept for the headless Backspace path and the tag/list adapters.
207
+ */
105
208
  readonly selectedKeys: Accessor<Set<Key>>;
106
- /** The currently selected items (multiple mode). */
209
+ /** Replace the selected keys. */
210
+ setSelectedKeys(keys: Iterable<Key>): void;
211
+ /** The currently selected items. */
107
212
  readonly selectedItems: Accessor<CollectionNode<T>[]>;
108
213
  /** Remove a selected key (multiple mode). */
109
214
  removeSelectedKey(key: Key): void;
@@ -132,7 +237,7 @@ export interface ComboBoxState<T = unknown> {
132
237
  /** Select a key and close the menu (for ListState compatibility). */
133
238
  select(key: Key): void;
134
239
  /** The selection mode. */
135
- readonly selectionMode: Accessor<"single" | "multiple">;
240
+ readonly selectionMode: Accessor<M>;
136
241
  /** Check if a key is selected. */
137
242
  isSelected(key: Key): boolean;
138
243
  /** Whether the combobox is disabled. */
@@ -154,59 +259,65 @@ export const defaultContainsFilter: FilterFn = (textValue, inputValue) => {
154
259
  * Creates state for a combobox component.
155
260
  * Combines list state with input value management and filtering.
156
261
  */
157
- export function createComboBoxState<T = unknown>(
158
- props: MaybeAccessor<ComboBoxStateProps<T>>,
159
- ): ComboBoxState<T> {
160
- const getProps = () => access(props);
262
+ export function createComboBoxState<T = unknown, M extends ComboBoxSelectionMode = "single">(
263
+ props: MaybeAccessor<ComboBoxStateProps<T, M>>,
264
+ ): ComboBoxState<T, M> {
265
+ const getProps = propsAccessor(props);
161
266
 
162
267
  // Extract options with defaults
163
268
  const menuTrigger = () => getProps().menuTrigger ?? "input";
164
269
  const allowsEmptyCollection = () => getProps().allowsEmptyCollection ?? false;
165
270
  const allowsCustomValue = () => getProps().allowsCustomValue ?? false;
166
271
  const shouldCloseOnBlur = () => getProps().shouldCloseOnBlur ?? true;
167
- const isMultiple = () => getProps().selectionMode === "multiple";
272
+ const isMultiple = () => (getProps().selectionMode ?? "single") === "multiple";
168
273
 
169
274
  // Track focus strategy for list navigation
170
- const [focusStrategy, setFocusStrategy] = createSignal<FocusStrategy | null>(null);
275
+ const [focusStrategy, setFocusStrategy] = createInternalSignal<FocusStrategy | null>(null);
171
276
 
172
277
  // Track whether we're showing all items (vs filtered)
173
- const [showAllItems, setShowAllItems] = createSignal(false);
278
+ const [showAllItems, setShowAllItems] = createInternalSignal(false);
174
279
 
175
280
  // Track the menu open trigger
176
281
  let menuOpenTrigger: MenuTriggerAction = "focus";
177
282
 
178
- // ---- Multi-select State ----
179
- const isMultiSelectionControlled = () => getProps().selectedKeys !== undefined;
180
- const [internalSelectedKeys, setInternalSelectedKeys] = createSignal<Set<Key>>(
181
- new Set(getProps().defaultSelectedKeys ?? []),
182
- );
283
+ // ---- Value ----
284
+ // One signal matches upstream ValueType<M>. `selectedKey` stays as a
285
+ // deprecated single-mode view. Multiple mode reads and writes `value`.
286
+ type StoredComboBoxValue = Key | readonly Key[] | null;
183
287
 
184
- const selectedKeys: Accessor<Set<Key>> = () => {
185
- return isMultiSelectionControlled()
186
- ? new Set(getProps().selectedKeys ?? [])
187
- : internalSelectedKeys();
288
+ const controlledPropValue = (): StoredComboBoxValue | undefined => {
289
+ const propsNow = getProps();
290
+ if (propsNow.value !== undefined) {
291
+ return propsNow.value as StoredComboBoxValue;
292
+ }
293
+ if (!isMultiple() && propsNow.selectedKey !== undefined) {
294
+ return propsNow.selectedKey;
295
+ }
296
+ return undefined;
188
297
  };
189
298
 
190
- const setSelectedKeys = (keys: Set<Key>) => {
191
- if (!isMultiSelectionControlled()) {
192
- setInternalSelectedKeys(new Set(keys));
299
+ const isValueControlled = () => controlledPropValue() !== undefined;
300
+
301
+ const initialStoredValue = (): StoredComboBoxValue => {
302
+ const propsNow = getProps();
303
+ if (propsNow.defaultValue !== undefined) {
304
+ return propsNow.defaultValue as StoredComboBoxValue;
193
305
  }
194
- getProps().onSelectionChangeMultiple?.(keys);
306
+ if ((propsNow.selectionMode ?? "single") === "multiple") {
307
+ return [];
308
+ }
309
+ return propsNow.defaultSelectedKey ?? null;
195
310
  };
196
311
 
197
- // ---- Selection State (single mode) ----
198
- // Note: Selection state is initialized first because input value may depend on it
199
- const isSelectionControlled = () => getProps().selectedKey !== undefined;
200
- const [internalSelectedKey, setInternalSelectedKey] = createSignal<Key | null>(
201
- getProps().defaultSelectedKey ?? null,
202
- );
312
+ const [internalValue, setInternalValue] =
313
+ createInternalSignal<StoredComboBoxValue>(initialStoredValue());
203
314
 
204
315
  // ---- Input Value State ----
205
316
  // Initialized after selection so we can derive from selected item if needed
206
317
  const isInputControlled = () => getProps().inputValue !== undefined;
207
318
 
208
319
  // We'll set the proper initial value after collection is created
209
- const [internalInputValue, setInternalInputValue] = createSignal(
320
+ const [internalInputValue, setInternalInputValue] = createInternalSignal(
210
321
  getProps().defaultInputValue ?? "",
211
322
  );
212
323
  // Track if we've initialized input from selection
@@ -217,6 +328,9 @@ export function createComboBoxState<T = unknown>(
217
328
  };
218
329
 
219
330
  const setInputValue = (value: string) => {
331
+ // Solid 2 batches writes onto a microtask, so onInputChange and the
332
+ // auto-open effect settle in one flush (CB-OC-03: onInputChange then
333
+ // onOpenChange(true, "input")).
220
334
  if (!isInputControlled()) {
221
335
  setInternalInputValue(value);
222
336
  }
@@ -224,20 +338,130 @@ export function createComboBoxState<T = unknown>(
224
338
  };
225
339
 
226
340
  // Track last committed input value
227
- const [lastValue, setLastValue] = createSignal(inputValue());
341
+ const [lastValue, setLastValue] = createInternalSignal(inputValue());
342
+
343
+ const storedValue = (): StoredComboBoxValue => {
344
+ const controlled = controlledPropValue();
345
+ return controlled !== undefined ? controlled : internalValue();
346
+ };
347
+
348
+ // `Array.isArray` narrows `readonly Key[]` to `any[]` and then fails to
349
+ // exclude that array from the scalar branch. A string/number check keeps
350
+ // the caller's readonly list intact.
351
+ const displayValue = (): Key | readonly Key[] | null => {
352
+ const current = storedValue();
353
+ if (!isMultiple()) {
354
+ return isKeyList(current) ? (current[0] ?? null) : current;
355
+ }
356
+ if (isKeyList(current)) return current;
357
+ if (current == null) return EMPTY_COMBOBOX_KEYS;
358
+ return [current];
359
+ };
228
360
 
229
361
  const selectedKey: Accessor<Key | null> = () => {
230
- return isSelectionControlled() ? (getProps().selectedKey ?? null) : internalSelectedKey();
362
+ if (isMultiple()) return null;
363
+ const current = displayValue();
364
+ return isKeyList(current) ? (current[0] ?? null) : current;
231
365
  };
232
366
 
233
- const setSelectedKey = (key: Key | null) => {
234
- if (!isSelectionControlled()) {
235
- setInternalSelectedKey(key);
367
+ const selectedKeys: Accessor<Set<Key>> = () => {
368
+ const current = displayValue();
369
+ if (isKeyList(current)) return new Set(current);
370
+ return current == null ? new Set() : new Set([current]);
371
+ };
372
+
373
+ const setValue = (next: Key | readonly Key[] | null) => {
374
+ // Solid 2 batches writes onto a microtask, so a fully controlled
375
+ // onSelectionChange that updates the value then inputValue settles in
376
+ // one flush instead of closing then auto-opening.
377
+ if (!isMultiple()) {
378
+ const key: Key | null =
379
+ typeof next === "string" || typeof next === "number"
380
+ ? next
381
+ : next === null
382
+ ? null
383
+ : (next[0] ?? null);
384
+ const previous = untrack(selectedKey);
385
+ if (!isValueControlled()) {
386
+ setInternalValue(key);
387
+ }
388
+ getProps().onChange?.(key as ComboBoxChangeValueType<M>);
389
+ if (key !== previous) {
390
+ getProps().onSelectionChange?.(key);
391
+ }
392
+ return;
236
393
  }
237
- getProps().onSelectionChange?.(key);
394
+
395
+ // Copy into state so the caller's list is never stored or mutated.
396
+ // `onChange` gets a second array, so a callback can mutate its argument
397
+ // without changing state or the input.
398
+ const keys: Key[] =
399
+ typeof next === "string" || typeof next === "number"
400
+ ? [next]
401
+ : next === null
402
+ ? []
403
+ : [...next];
404
+ if (!isValueControlled()) {
405
+ setInternalValue(keys);
406
+ }
407
+ getProps().onChange?.([...keys] as ComboBoxChangeValueType<M>);
238
408
  };
239
409
 
410
+ const setSelectedKey = (key: Key | null) => {
411
+ setValue(key);
412
+ };
413
+
414
+ const defaultValue: ComboBoxValueType<M> = (() => {
415
+ const propsNow = getProps();
416
+ const resolved =
417
+ propsNow.defaultValue !== undefined
418
+ ? propsNow.defaultValue
419
+ : isMultiple()
420
+ ? (EMPTY_COMBOBOX_KEYS as unknown as ComboBoxValueType<M>)
421
+ : ((propsNow.defaultSelectedKey ?? null) as ComboBoxValueType<M>);
422
+ return (resolved ?? untrack(displayValue)) as ComboBoxValueType<M>;
423
+ })();
424
+
425
+ const defaultSelectedKey =
426
+ getProps().defaultSelectedKey ?? (isMultiple() ? null : (untrack(displayValue) as Key | null));
427
+
428
+ const validationValue = createMemo<ComboBoxValidationValue<M> | null>(() => {
429
+ const dVal = displayValue();
430
+ if (isKeyList(dVal) && dVal.length === 0) {
431
+ return null;
432
+ }
433
+ return {
434
+ inputValue: inputValue(),
435
+ value: (isKeyList(dVal) ? [...dVal] : dVal) as ComboBoxValidationType<M>,
436
+ selectedKey: selectedKey(),
437
+ };
438
+ });
439
+
440
+ const validation = createFormValidationState({
441
+ get value() {
442
+ return validationValue();
443
+ },
444
+ get isInvalid() {
445
+ return getProps().isInvalid;
446
+ },
447
+ get validationState() {
448
+ return getProps().validationState;
449
+ },
450
+ get validate() {
451
+ return getProps().validate;
452
+ },
453
+ get name() {
454
+ return getProps().name;
455
+ },
456
+ get validationBehavior() {
457
+ return getProps().validationBehavior ?? "native";
458
+ },
459
+ });
460
+
240
461
  // ---- Overlay State ----
462
+ // Assigned after createListState; onOpenChange only fires after both exist
463
+ // except a defaultOpen init, which we skip via the optional call.
464
+ let listState!: ListState<T>;
241
465
  const overlayState = createOverlayTriggerState({
242
466
  get isOpen() {
243
467
  return getProps().isOpen;
@@ -247,11 +471,16 @@ export function createComboBoxState<T = unknown>(
247
471
  },
248
472
  onOpenChange(isOpen: boolean) {
249
473
  getProps().onOpenChange?.(isOpen, isOpen ? menuOpenTrigger : undefined);
474
+ // RAC useComboBoxState.ts:314-317
475
+ listState?.setFocused(isOpen);
476
+ if (!isOpen) {
477
+ listState?.setFocusedKey(null);
478
+ }
250
479
  },
251
480
  });
252
481
 
253
482
  // ---- List State (unfiltered collection) ----
254
- const listState = createListState<T>({
483
+ listState = createListState<T>({
255
484
  get items() {
256
485
  // Use items or defaultItems
257
486
  return getProps().items ?? getProps().defaultItems ?? [];
@@ -271,34 +500,37 @@ export function createComboBoxState<T = unknown>(
271
500
  get selectionMode() {
272
501
  return isMultiple() ? ("multiple" as const) : ("single" as const);
273
502
  },
274
- disallowEmptySelection: false,
503
+ // RAC useComboBoxState.ts:254-255. Single selection cannot be toggled
504
+ // empty. Duplicate events re-emit the same key so a click on the selected
505
+ // option reaches the reset-and-close branch below. Multiple selection
506
+ // still allows clearing the last key.
507
+ get disallowEmptySelection() {
508
+ return !isMultiple();
509
+ },
510
+ allowDuplicateSelectionEvents: true,
275
511
  get selectedKeys() {
276
- if (isMultiple()) {
277
- return Array.from(selectedKeys());
278
- }
279
- const key = selectedKey();
280
- return key != null ? [key] : [];
512
+ return convertValue(displayValue());
281
513
  },
282
514
  onSelectionChange(keys) {
283
515
  if (keys === "all") return;
284
516
 
285
517
  if (isMultiple()) {
286
- // In multiple mode, toggle selections
287
- const newKeys = new Set(keys);
288
- setSelectedKeys(newKeys);
518
+ setValue([...keys]);
289
519
  return;
290
520
  }
291
521
 
292
522
  const key = keys.size > 0 ? Array.from(keys)[0] : null;
293
523
 
294
- // If same key selected, just reset input and close
524
+ // RAC useComboBoxState.ts:265-270 — same key still notifies, then
525
+ // resets the input and closes (click on the already selected option).
295
526
  if (key === selectedKey()) {
527
+ getProps().onSelectionChange?.(key);
296
528
  resetInputValue();
297
529
  closeMenu();
298
530
  return;
299
531
  }
300
532
 
301
- setSelectedKey(key);
533
+ setValue(key);
302
534
  },
303
535
  });
304
536
 
@@ -307,16 +539,12 @@ export function createComboBoxState<T = unknown>(
307
539
 
308
540
  const filteredCollection = createMemo<Collection<T>>(() => {
309
541
  const collection = originalCollection();
310
- const input = inputValue();
311
542
  const filter = getProps().defaultFilter;
312
-
313
- // If no filter function provided, return original collection
314
- if (!filter) {
543
+ // RAC useComboBoxState.ts:297-302 — no default filter if items are controlled.
544
+ if (getProps().items != null || !filter) {
315
545
  return collection;
316
546
  }
317
-
318
- // Filter the collection based on input value
319
- return filterCollection(collection, input, filter);
547
+ return filterCollection(collection, inputValue(), filter);
320
548
  });
321
549
 
322
550
  // The displayed collection depends on showAllItems flag
@@ -346,13 +574,16 @@ export function createComboBoxState<T = unknown>(
346
574
  // Initialize input value from selected item if not already set
347
575
  // This runs once on creation
348
576
  if (!inputInitialized && !isInputControlled()) {
349
- const defaultKey = getProps().defaultSelectedKey;
350
- if (defaultKey != null && !getProps().defaultInputValue) {
351
- // Get the text value from the collection for the default selected key
352
- const item = originalCollection().getItem(defaultKey);
353
- if (item) {
354
- setInternalInputValue(item.textValue);
355
- setLastValue(item.textValue);
577
+ // RAC getDefaultInputValue: an explicit empty defaultInputValue wins.
578
+ // Multiple mode does not seed the input from the first selected item.
579
+ if (getProps().defaultInputValue == null && !isMultiple()) {
580
+ const key = selectedKey();
581
+ if (key != null) {
582
+ const item = originalCollection().getItem(key);
583
+ if (item) {
584
+ setInternalInputValue(item.textValue);
585
+ setLastValue(item.textValue);
586
+ }
356
587
  }
357
588
  }
358
589
  inputInitialized = true;
@@ -360,8 +591,8 @@ export function createComboBoxState<T = unknown>(
360
591
 
361
592
  // ---- Helper Functions ----
362
593
  const resetInputValue = () => {
363
- const item = selectedItem();
364
- const textValue = item?.textValue ?? "";
594
+ const key = selectedKey();
595
+ const textValue = key != null ? (originalCollection().getItem(key)?.textValue ?? "") : "";
365
596
  setLastValue(textValue);
366
597
  setInputValue(textValue);
367
598
  };
@@ -374,13 +605,12 @@ export function createComboBoxState<T = unknown>(
374
605
 
375
606
  // ---- Open/Toggle Logic ----
376
607
  // Auto-focus the menu on open the way upstream's listbox does via its
377
- // `autoFocus: state.focusStrategy || true` prop (useComboBox.ts:490 → useSelectableCollection):
378
- // the first selectable selected key, else the first/last key for an explicit
379
- // strategy, else nothing. The port drives this from the state (createListBox
380
- // reimplements nav inline and does not honor a listbox `autoFocus` prop), so
381
- // BOTH open() and toggle() must apply it — a button/mouse open routes through
382
- // toggle(), and omitting it there left the menu opened with no active option
383
- // (no aria-activedescendant / no highlighted row) unlike upstream.
608
+ // `autoFocus: state.focusStrategy || true` prop (useComboBox.ts:535 →
609
+ // useSelectableCollection). createListBox does not honor a listbox
610
+ // `autoFocus` prop, so BOTH open() and toggle() apply it here. RAC applies
611
+ // this in a later effect; doing it synchronously keeps the first option
612
+ // paint (slot `aria-labelledby`) stable. createComboBox still announces
613
+ // option count on open.
384
614
  const applyOpenFocus = (strategy: FocusStrategy | null) => {
385
615
  const key = selectedKey();
386
616
  const nextFocusedKey =
@@ -398,15 +628,20 @@ export function createComboBoxState<T = unknown>(
398
628
  const open = (strategy: FocusStrategy | null = null, trigger?: MenuTriggerAction) => {
399
629
  const displayAll = trigger === "manual" || (trigger === "focus" && menuTrigger() === "focus");
400
630
 
401
- // Check if we should open
631
+ // RAC useComboBoxState.ts:331-340 — controlled `items` may open empty;
632
+ // showAllItems only when items are undefined (collection filtering).
402
633
  const filtered = filteredCollection();
403
634
  const original = originalCollection();
635
+ const items = getProps().items;
404
636
  const canOpen =
405
- allowsEmptyCollection() || filtered.size > 0 || (displayAll && original.size > 0);
637
+ allowsEmptyCollection() ||
638
+ filtered.size > 0 ||
639
+ (displayAll && original.size > 0) ||
640
+ items != null;
406
641
 
407
642
  if (!canOpen) return;
408
643
 
409
- if (displayAll && !overlayState.isOpen()) {
644
+ if (displayAll && !overlayState.isOpen() && items === undefined) {
410
645
  setShowAllItems(true);
411
646
  }
412
647
 
@@ -421,17 +656,20 @@ export function createComboBoxState<T = unknown>(
421
656
  const toggle = (strategy: FocusStrategy | null = null, trigger?: MenuTriggerAction) => {
422
657
  const displayAll = trigger === "manual" || (trigger === "focus" && menuTrigger() === "focus");
423
658
 
424
- // Check if we can open (if closed)
425
659
  const filtered = filteredCollection();
426
660
  const original = originalCollection();
661
+ const items = getProps().items;
427
662
  const canOpen =
428
- allowsEmptyCollection() || filtered.size > 0 || (displayAll && original.size > 0);
663
+ allowsEmptyCollection() ||
664
+ filtered.size > 0 ||
665
+ (displayAll && original.size > 0) ||
666
+ items != null;
429
667
 
430
668
  if (!canOpen && !overlayState.isOpen()) return;
431
669
 
432
670
  const willOpen = !overlayState.isOpen();
433
671
 
434
- if (displayAll && willOpen) {
672
+ if (displayAll && willOpen && items === undefined) {
435
673
  setShowAllItems(true);
436
674
  }
437
675
 
@@ -448,19 +686,35 @@ export function createComboBoxState<T = unknown>(
448
686
 
449
687
  // ---- Commit/Revert Logic ----
450
688
  const commitCustomValue = () => {
451
- setSelectedKey(null);
689
+ if (isMultiple()) {
690
+ // Custom text is independent of the selected items.
691
+ setLastValue(inputValue());
692
+ closeMenu();
693
+ return;
694
+ }
695
+ setValue(null);
452
696
  closeMenu();
453
697
  };
454
698
 
455
- const commitSelection = () => {
456
- // If both are controlled, just call onSelectionChange
457
- if (isSelectionControlled() && isInputControlled()) {
458
- getProps().onSelectionChange?.(selectedKey());
459
- const item = selectedItem();
460
- setLastValue(item?.textValue ?? "");
699
+ const commitSelection = (shouldForceSelectionChange = false) => {
700
+ // Both the value and the input are controlled: notify, then close.
701
+ // Otherwise reset the input for the caller.
702
+ if (isValueControlled() && isInputControlled()) {
703
+ const key = selectedKey();
704
+ const itemText = key != null ? (originalCollection().getItem(key)?.textValue ?? "") : "";
705
+ if (shouldForceSelectionChange || isMultiple() || inputValue() !== itemText) {
706
+ getProps().onSelectionChange?.(key);
707
+ const current = displayValue();
708
+ const changeValue = (
709
+ isKeyList(current) ? [...current] : current
710
+ ) as ComboBoxChangeValueType<M>;
711
+ getProps().onChange?.(changeValue);
712
+ }
713
+ // RAC useComboBoxState.ts:543-545 — stop the auto-open-on-input effect
714
+ // from reopening after this close.
715
+ setLastValue(itemText);
461
716
  closeMenu();
462
717
  } else {
463
- // Reset input to selected item's text
464
718
  resetInputValue();
465
719
  closeMenu();
466
720
  }
@@ -483,22 +737,18 @@ export function createComboBoxState<T = unknown>(
483
737
  const commit = () => {
484
738
  const focusedKey = listState.focusedKey();
485
739
 
486
- if (isMultiple()) {
487
- // In multiple mode, toggle the focused item without closing
488
- if (overlayState.isOpen() && focusedKey != null) {
489
- select(focusedKey);
490
- }
491
- return;
492
- }
493
-
494
740
  if (overlayState.isOpen() && focusedKey != null) {
495
- // If focused key is already selected, just commit
496
- if (selectedKey() === focusedKey) {
497
- commitSelection();
741
+ // RAC useComboBoxState.ts:564-572 — an already-selected single key goes
742
+ // through commitSelection. A new single key is `selectionManager.select()`
743
+ // without close; the open/close effect then closes while the menu is
744
+ // still open, so auto-open (input !== last && !isOpen) is skipped.
745
+ // Multiple toggles through setValue and leaves the menu open.
746
+ if (!isMultiple() && selectedKey() === focusedKey) {
747
+ commitSelection(true);
748
+ } else if (isMultiple()) {
749
+ select(focusedKey);
498
750
  } else {
499
- // Select the focused item
500
- setSelectedKey(focusedKey);
501
- closeMenu();
751
+ listState.selectionManager.select(focusedKey);
502
752
  }
503
753
  } else {
504
754
  commitValue();
@@ -514,12 +764,31 @@ export function createComboBoxState<T = unknown>(
514
764
  };
515
765
 
516
766
  // ---- Focus Handling ----
517
- const [isFocused, setIsFocused] = createSignal(false);
518
- let valueOnFocus = "";
767
+ const [isFocused, setIsFocused] = createInternalSignal(false);
768
+
769
+ let valueOnFocus: [string, Key | readonly Key[] | null] = [
770
+ untrack(inputValue),
771
+ untrack(displayValue) as Key | readonly Key[] | null,
772
+ ];
773
+
774
+ const hasMoved = (a: Key | readonly Key[] | null, b: Key | readonly Key[] | null): boolean => {
775
+ if (a === b) return false;
776
+ if (Array.isArray(a) && Array.isArray(b)) {
777
+ if (a.length !== b.length) return true;
778
+ for (let i = 0; i < a.length; i++) {
779
+ if (a[i] !== b[i]) return true;
780
+ }
781
+ return false;
782
+ }
783
+ return true;
784
+ };
519
785
 
786
+ // RAC useComboBoxState.ts:578-593 keeps `valueOnFocus = useRef([inputValue, displayValue])`
787
+ // and, on blur, calls `validation.commitValidation()` when the input value or the display
788
+ // value moved while focused.
520
789
  const setFocused = (focused: boolean) => {
521
790
  if (focused) {
522
- valueOnFocus = inputValue();
791
+ valueOnFocus = [inputValue(), displayValue() as Key | readonly Key[] | null];
523
792
  if (menuTrigger() === "focus" && !getProps().isReadOnly) {
524
793
  open(null, "focus");
525
794
  }
@@ -527,47 +796,93 @@ export function createComboBoxState<T = unknown>(
527
796
  if (shouldCloseOnBlur()) {
528
797
  commitValue();
529
798
  }
799
+ if (
800
+ inputValue() !== valueOnFocus[0] ||
801
+ hasMoved(displayValue() as Key | readonly Key[] | null, valueOnFocus[1])
802
+ ) {
803
+ validation.commitValidation();
804
+ }
530
805
  }
531
806
  setIsFocused(focused);
532
807
  };
533
808
 
534
809
  // ---- Effects for Auto Open/Close ----
535
- createEffect(() => {
536
- const input = inputValue();
537
- const filtered = filteredCollection();
538
- const isOpen = overlayState.isOpen();
539
- const last = lastValue();
540
- const focused = isFocused();
541
-
542
- // Auto-open when typing
543
- if (
544
- focused &&
545
- (filtered.size > 0 || allowsEmptyCollection()) &&
546
- !isOpen &&
547
- input !== last &&
548
- menuTrigger() !== "manual"
549
- ) {
550
- open(null, "input");
551
- }
810
+ // RAC useComboBoxState.ts:408-496 is one effect: auto-open, auto-close,
811
+ // close-on-selection, then lastValue. Close-on-selection must not run as a
812
+ // later effect — after a fully-controlled commit the parent updates
813
+ // inputValue, a trailing close leaves !isOpen && input !== last, and
814
+ // auto-open reopens (D13 Enter re-announces "N options available.").
815
+ // lastDisplayValue starts as the current key so an initial selectedKey is
816
+ // not treated as a selection change (RAC lastValueRef = useRef(displayValue)).
817
+ let lastDisplayValue: Key | null | undefined = untrack(selectedKey);
818
+
819
+ createEffect(
820
+ () => ({
821
+ input: inputValue(),
822
+ filtered: filteredCollection(),
823
+ isOpen: overlayState.isOpen(),
824
+ last: lastValue(),
825
+ focused: isFocused(),
826
+ key: isMultiple() ? null : selectedKey(),
827
+ allowsEmpty: allowsEmptyCollection(),
828
+ trigger: menuTrigger(),
829
+ showingAll: showAllItems(),
830
+ inputControlled: isInputControlled(),
831
+ selectionControlled: isValueControlled(),
832
+ multiple: isMultiple(),
833
+ }),
834
+ ({
835
+ input,
836
+ filtered,
837
+ isOpen,
838
+ last,
839
+ focused,
840
+ key,
841
+ allowsEmpty,
842
+ trigger,
843
+ showingAll,
844
+ inputControlled,
845
+ selectionControlled,
846
+ multiple,
847
+ }) => {
848
+ // Auto-open when typing
849
+ if (
850
+ focused &&
851
+ (filtered.size > 0 || allowsEmpty) &&
852
+ !isOpen &&
853
+ input !== last &&
854
+ trigger !== "manual"
855
+ ) {
856
+ open(null, "input");
857
+ }
552
858
 
553
- // Auto-close when empty (unless showing all)
554
- if (!showAllItems() && !allowsEmptyCollection() && isOpen && filtered.size === 0) {
555
- closeMenu();
556
- }
859
+ // Auto-close when empty (unless showing all)
860
+ if (!showingAll && !allowsEmpty && isOpen && filtered.size === 0) {
861
+ closeMenu();
862
+ }
557
863
 
558
- // Clear focused key when input changes
559
- if (input !== last) {
560
- listState.setFocusedKey(null);
561
- setShowAllItems(false);
864
+ // Close when an item is selected (RAC displayValue !== lastValueRef).
865
+ if (key != null && key !== lastDisplayValue) {
866
+ closeMenu();
867
+ }
868
+
869
+ // Clear focused key when input changes
870
+ if (input !== last) {
871
+ listState.setFocusedKey(null);
872
+ setShowAllItems(false);
873
+
874
+ // Clear selection when the input is cleared. Fully controlled single
875
+ // values, and every multiple value, stay put.
876
+ if (!multiple && input === "" && (!inputControlled || !selectionControlled)) {
877
+ setValue(null);
878
+ }
562
879
 
563
- // Clear selection when input is cleared (if not fully controlled)
564
- if (input === "" && (!isInputControlled() || !isSelectionControlled())) {
565
- setSelectedKey(null);
880
+ setLastValue(input);
566
881
  }
567
882
 
568
- setLastValue(input);
569
- }
570
- });
883
+ lastDisplayValue = key;
884
+ },
885
+ );
571
886
 
572
887
  // Keep the input text in sync with the selected item (single mode only).
573
888
  //
@@ -585,79 +900,82 @@ export function createComboBoxState<T = unknown>(
585
900
  // dependency. `originalCollection()` stays tracked (the unfiltered collection
586
901
  // only changes when `items` change, never on filtering) so a preset selection
587
902
  // still gets its text once async items arrive.
588
- createEffect(() => {
589
- if (isMultiple()) return;
590
- const key = selectedKey();
591
- const item = key != null ? originalCollection().getItem(key) : null;
592
- const textValue = item?.textValue ?? "";
593
-
594
- // Only update if selection changed and not fully controlled
595
- if (!isInputControlled() || !isSelectionControlled()) {
596
- if (key != null && textValue !== untrack(inputValue)) {
597
- setInputValue(textValue);
598
- setLastValue(textValue);
903
+ createEffect(
904
+ () => {
905
+ if (isMultiple()) return null;
906
+ const key = selectedKey();
907
+ const item = key != null ? originalCollection().getItem(key) : null;
908
+ return {
909
+ key,
910
+ textValue: item?.textValue ?? "",
911
+ inputControlled: isInputControlled(),
912
+ selectionControlled: isValueControlled(),
913
+ };
914
+ },
915
+ (data) => {
916
+ if (!data) return;
917
+ const { key, textValue, inputControlled, selectionControlled } = data;
918
+ // Only update if selection changed and not fully controlled
919
+ if (!inputControlled || !selectionControlled) {
920
+ if (key != null && textValue !== untrack(inputValue)) {
921
+ setInputValue(textValue);
922
+ setLastValue(textValue);
923
+ }
599
924
  }
600
- }
601
- });
602
-
603
- // Close when selection changes (only in single mode)
604
- createEffect((prevKey: Key | null | undefined) => {
605
- if (isMultiple()) return undefined;
606
- const key = selectedKey();
607
- if (key != null && key !== prevKey) {
608
- closeMenu();
609
- }
610
- return key;
611
- }, undefined);
925
+ },
926
+ );
612
927
 
613
928
  // ---- Selection Methods for ListState compatibility ----
614
929
  // These methods allow createOption to work with ComboBoxState
615
930
  const select = (key: Key) => {
616
931
  if (isMultiple()) {
617
- // Toggle selection in multiple mode
618
932
  const current = new Set(selectedKeys());
619
933
  if (current.has(key)) {
620
934
  current.delete(key);
621
935
  } else {
622
936
  current.add(key);
623
937
  }
624
- setSelectedKeys(current);
625
- // Don't close menu and don't reset input in multi-select mode
938
+ setValue([...current]);
626
939
  } else {
627
- setSelectedKey(key);
940
+ setValue(key);
628
941
  closeMenu();
629
942
  }
630
943
  };
631
944
 
945
+ const setSelectedKeys = (keys: Iterable<Key>) => {
946
+ setValue([...keys]);
947
+ };
948
+
632
949
  const removeSelectedKey = (key: Key) => {
633
- if (isMultiple()) {
634
- const current = new Set(selectedKeys());
635
- current.delete(key);
636
- setSelectedKeys(current);
637
- }
950
+ if (!isMultiple()) return;
951
+ setValue([...selectedKeys()].filter((selected) => selected !== key));
638
952
  };
639
953
 
640
- const selectionMode: Accessor<"single" | "multiple"> = () => getProps().selectionMode ?? "single";
954
+ const selectionMode: Accessor<M> = () => (getProps().selectionMode ?? "single") as M;
641
955
 
642
- const isSelected = (key: Key) => {
643
- if (isMultiple()) {
644
- return selectedKeys().has(key);
645
- }
646
- return selectedKey() === key;
647
- };
956
+ const isSelected = (key: Key) => selectedKeys().has(key);
648
957
 
649
958
  // ---- Return State ----
650
959
  return {
960
+ realtimeValidation: validation.realtimeValidation,
961
+ displayValidation: validation.displayValidation,
962
+ updateValidation: validation.updateValidation,
963
+ resetValidation: validation.resetValidation,
964
+ commitValidation: validation.commitValidation,
651
965
  collection: displayedCollection,
652
966
  isOpen: overlayState.isOpen,
653
967
  open,
654
968
  close: commitValue,
655
969
  toggle,
656
970
  selectedKey,
657
- defaultSelectedKey: getProps().defaultSelectedKey ?? null,
971
+ defaultSelectedKey,
658
972
  selectedItem,
659
973
  setSelectedKey,
974
+ value: () => displayValue() as ComboBoxValueType<M>,
975
+ defaultValue,
976
+ setValue,
660
977
  selectedKeys,
978
+ setSelectedKeys,
661
979
  selectedItems,
662
980
  removeSelectedKey,
663
981
  inputValue,
@@ -688,8 +1006,21 @@ export function createComboBoxState<T = unknown>(
688
1006
  };
689
1007
  }
690
1008
 
1009
+ function isKeyList(value: Key | readonly Key[] | null): value is readonly Key[] {
1010
+ return value !== null && typeof value !== "string" && typeof value !== "number";
1011
+ }
1012
+
1013
+ function convertValue(value: Key | readonly Key[] | null | undefined): readonly Key[] {
1014
+ if (value == null) return [];
1015
+ if (typeof value === "string" || typeof value === "number") return [value];
1016
+ return value;
1017
+ }
1018
+
691
1019
  /**
692
1020
  * Filter a collection based on input value.
1021
+ * RAC `useComboBoxState.ts:644-672` copies nodes into a new `ListCollection`,
1022
+ * which reassigns `index` (ListCollection.ts:51-53). Keeping the original
1023
+ * `index` makes virtualized `aria-posinset` report the unfiltered position.
693
1024
  */
694
1025
  function filterCollection<T>(
695
1026
  collection: Collection<T>,
@@ -701,19 +1032,18 @@ function filterCollection<T>(
701
1032
  }
702
1033
 
703
1034
  const filteredItems: CollectionNode<T>[] = [];
1035
+ let index = 0;
704
1036
 
705
1037
  for (const item of collection) {
706
1038
  if (item.type === "section") {
707
- // Filter section children
708
1039
  const filteredChildren: CollectionNode<T>[] = [];
709
1040
  if (item.childNodes) {
710
1041
  for (const child of item.childNodes) {
711
1042
  if (child.type === "item" && filter(child.textValue, inputValue)) {
712
- filteredChildren.push(child);
1043
+ filteredChildren.push({ ...child, index: index++ });
713
1044
  }
714
1045
  }
715
1046
  }
716
- // Only include section if it has matching children
717
1047
  if (filteredChildren.length > 0) {
718
1048
  filteredItems.push({
719
1049
  ...item,
@@ -722,109 +1052,12 @@ function filterCollection<T>(
722
1052
  }
723
1053
  } else if (item.type === "item") {
724
1054
  if (filter(item.textValue, inputValue)) {
725
- filteredItems.push(item);
726
- }
727
- }
728
- }
729
-
730
- // Create a new collection from filtered items
731
- return createFilteredCollection(filteredItems, collection);
732
- }
733
-
734
- /**
735
- * Create a filtered collection wrapper.
736
- */
737
- function createFilteredCollection<T>(
738
- items: CollectionNode<T>[],
739
- original: Collection<T>,
740
- ): Collection<T> {
741
- const itemMap = new Map<Key, CollectionNode<T>>();
742
-
743
- for (const item of items) {
744
- itemMap.set(item.key, item);
745
- if (item.childNodes) {
746
- for (const child of item.childNodes) {
747
- itemMap.set(child.key, child);
1055
+ filteredItems.push({ ...item, index: index++ });
748
1056
  }
1057
+ } else {
1058
+ filteredItems.push({ ...item });
749
1059
  }
750
1060
  }
751
1061
 
752
- return {
753
- get size() {
754
- let count = 0;
755
- for (const item of items) {
756
- if (item.type === "item") {
757
- count++;
758
- } else if (item.childNodes) {
759
- count += Array.from(item.childNodes).filter((c) => c.type === "item").length;
760
- }
761
- }
762
- return count;
763
- },
764
- getItem(key: Key) {
765
- return itemMap.get(key) ?? null;
766
- },
767
- getKeys() {
768
- return itemMap.keys();
769
- },
770
- getFirstKey() {
771
- for (const item of items) {
772
- if (item.type === "item") return item.key;
773
- if (item.childNodes) {
774
- for (const child of item.childNodes) {
775
- if (child.type === "item") return child.key;
776
- }
777
- }
778
- }
779
- return null;
780
- },
781
- getLastKey() {
782
- for (let i = items.length - 1; i >= 0; i--) {
783
- const item = items[i];
784
- if (item.type === "item") return item.key;
785
- if (item.childNodes) {
786
- const children = Array.from(item.childNodes);
787
- for (let j = children.length - 1; j >= 0; j--) {
788
- if (children[j].type === "item") return children[j].key;
789
- }
790
- }
791
- }
792
- return null;
793
- },
794
- getKeyBefore(key: Key) {
795
- return original.getKeyBefore(key);
796
- },
797
- getKeyAfter(key: Key) {
798
- return original.getKeyAfter(key);
799
- },
800
- at(index: number) {
801
- // Flatten items for indexing
802
- let currentIndex = 0;
803
- for (const item of items) {
804
- if (item.type === "item") {
805
- if (currentIndex === index) return item;
806
- currentIndex++;
807
- } else if (item.childNodes) {
808
- for (const child of item.childNodes) {
809
- if (child.type === "item") {
810
- if (currentIndex === index) return child;
811
- currentIndex++;
812
- }
813
- }
814
- }
815
- }
816
- return null;
817
- },
818
- getChildren(key: Key) {
819
- const item = itemMap.get(key);
820
- return item?.childNodes ?? [];
821
- },
822
- getTextValue(key: Key) {
823
- const item = itemMap.get(key);
824
- return item?.textValue ?? "";
825
- },
826
- [Symbol.iterator]() {
827
- return items[Symbol.iterator]();
828
- },
829
- };
1062
+ return new ListCollection(filteredItems);
830
1063
  }