@svgrid/grid 1.2.34 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (490) hide show
  1. package/README.md +6 -5
  2. package/dist/FlexRender.svelte +96 -96
  3. package/dist/GridFooter.svelte +178 -178
  4. package/dist/SvAccordion.svelte +109 -0
  5. package/dist/SvAccordion.svelte.d.ts +28 -0
  6. package/dist/SvAlert.svelte +92 -0
  7. package/dist/SvAlert.svelte.d.ts +27 -0
  8. package/dist/SvAutoComplete.svelte +47 -18
  9. package/dist/SvAutoComplete.svelte.d.ts +2 -5
  10. package/dist/SvAvatar.svelte +75 -0
  11. package/dist/SvAvatar.svelte.d.ts +14 -0
  12. package/dist/SvAvatarGroup.svelte +48 -0
  13. package/dist/SvAvatarGroup.svelte.d.ts +16 -0
  14. package/dist/SvBadge.svelte +54 -0
  15. package/dist/SvBadge.svelte.d.ts +23 -0
  16. package/dist/SvBreadcrumb.svelte +88 -0
  17. package/dist/SvBreadcrumb.svelte.d.ts +23 -0
  18. package/dist/SvButtonGroup.svelte +121 -0
  19. package/dist/SvButtonGroup.svelte.d.ts +16 -0
  20. package/dist/SvCalendar.svelte +72 -9
  21. package/dist/SvCalendar.svelte.d.ts +34 -1
  22. package/dist/SvCard.svelte +71 -0
  23. package/dist/SvCard.svelte.d.ts +28 -0
  24. package/dist/SvCarousel.svelte +134 -0
  25. package/dist/SvCarousel.svelte.d.ts +28 -0
  26. package/dist/SvCheckBox.svelte +36 -21
  27. package/dist/SvCheckBox.svelte.d.ts +2 -5
  28. package/dist/SvChip.svelte +88 -0
  29. package/dist/SvChip.svelte.d.ts +31 -0
  30. package/dist/SvCircularProgress.svelte +109 -0
  31. package/dist/SvCircularProgress.svelte.d.ts +31 -0
  32. package/dist/SvColorInput.svelte +54 -27
  33. package/dist/SvColorInput.svelte.d.ts +10 -6
  34. package/dist/SvComboBox.svelte +119 -33
  35. package/dist/SvComboBox.svelte.d.ts +18 -6
  36. package/dist/SvCommand.svelte +197 -0
  37. package/dist/SvCommand.svelte.d.ts +26 -0
  38. package/dist/SvContextMenu.svelte +96 -0
  39. package/dist/SvContextMenu.svelte.d.ts +25 -0
  40. package/dist/SvCountryInput.svelte +56 -21
  41. package/dist/SvCountryInput.svelte.d.ts +9 -5
  42. package/dist/SvDateRangeInput.svelte +256 -0
  43. package/dist/SvDateRangeInput.svelte.d.ts +37 -0
  44. package/dist/SvDateTimePicker.svelte +57 -20
  45. package/dist/SvDateTimePicker.svelte.d.ts +12 -4
  46. package/dist/SvDivider.svelte +61 -0
  47. package/dist/SvDivider.svelte.d.ts +22 -0
  48. package/dist/SvDrawer.svelte +226 -0
  49. package/dist/SvDrawer.svelte.d.ts +43 -0
  50. package/dist/SvDropDownList.svelte +114 -35
  51. package/dist/SvDropDownList.svelte.d.ts +7 -6
  52. package/dist/SvDurationInput.svelte +108 -0
  53. package/dist/SvDurationInput.svelte.d.ts +15 -0
  54. package/dist/SvEmptyState.svelte +59 -0
  55. package/dist/SvEmptyState.svelte.d.ts +25 -0
  56. package/dist/SvField.svelte +85 -0
  57. package/dist/SvField.svelte.d.ts +30 -0
  58. package/dist/SvFileUpload.svelte +169 -0
  59. package/dist/SvFileUpload.svelte.d.ts +24 -0
  60. package/dist/SvForm.svelte +7 -1
  61. package/dist/SvForm.svelte.d.ts +3 -0
  62. package/dist/SvGauge.svelte +7 -1
  63. package/dist/SvGauge.svelte.d.ts +11 -0
  64. package/dist/SvGrid.controller.svelte.d.ts +6 -0
  65. package/dist/SvGrid.controller.svelte.js +64 -9
  66. package/dist/SvGrid.css +2376 -2343
  67. package/dist/SvGrid.svelte +2764 -2651
  68. package/dist/SvGrid.types.d.ts +366 -0
  69. package/dist/SvGridBoard.svelte +2281 -0
  70. package/dist/SvGridBoard.svelte.d.ts +31 -0
  71. package/dist/SvGridDropdown.svelte +666 -665
  72. package/dist/SvGridSelect.svelte +255 -0
  73. package/dist/SvGridSelect.svelte.d.ts +32 -0
  74. package/dist/SvGroupCell.svelte +109 -0
  75. package/dist/SvGroupCell.svelte.d.ts +41 -0
  76. package/dist/SvListBox.svelte +123 -36
  77. package/dist/SvListBox.svelte.d.ts +12 -8
  78. package/dist/SvMaskedInput.svelte +53 -13
  79. package/dist/SvMaskedInput.svelte.d.ts +16 -6
  80. package/dist/SvMenu.svelte +101 -0
  81. package/dist/SvMenu.svelte.d.ts +26 -0
  82. package/dist/SvMenuList.svelte +143 -0
  83. package/dist/SvMenuList.svelte.d.ts +24 -0
  84. package/dist/SvModal.svelte +220 -0
  85. package/dist/SvModal.svelte.d.ts +31 -0
  86. package/dist/SvMultiSelect.svelte +277 -0
  87. package/dist/SvMultiSelect.svelte.d.ts +31 -0
  88. package/dist/SvNavPane.svelte +314 -0
  89. package/dist/SvNavPane.svelte.d.ts +59 -0
  90. package/dist/SvNumberInput.svelte +23 -9
  91. package/dist/SvNumberInput.svelte.d.ts +2 -0
  92. package/dist/SvOtpInput.svelte +157 -0
  93. package/dist/SvOtpInput.svelte.d.ts +16 -0
  94. package/dist/SvPagination.svelte +100 -0
  95. package/dist/SvPagination.svelte.d.ts +16 -0
  96. package/dist/SvPasswordInput.svelte +42 -12
  97. package/dist/SvPasswordInput.svelte.d.ts +13 -6
  98. package/dist/SvPhoneInput.svelte +43 -11
  99. package/dist/SvPhoneInput.svelte.d.ts +10 -11
  100. package/dist/SvPopover.svelte +127 -0
  101. package/dist/SvPopover.svelte.d.ts +35 -0
  102. package/dist/SvProgress.svelte +116 -0
  103. package/dist/SvProgress.svelte.d.ts +32 -0
  104. package/dist/SvRadioGroup.svelte +40 -22
  105. package/dist/SvRadioGroup.svelte.d.ts +2 -10
  106. package/dist/SvRating.svelte +51 -30
  107. package/dist/SvRating.svelte.d.ts +10 -7
  108. package/dist/SvRichText.svelte +192 -0
  109. package/dist/SvRichText.svelte.d.ts +16 -0
  110. package/dist/SvRowGroupPanel.svelte +147 -0
  111. package/dist/SvRowGroupPanel.svelte.d.ts +17 -0
  112. package/dist/SvScrollArea.svelte +50 -0
  113. package/dist/SvScrollArea.svelte.d.ts +22 -0
  114. package/dist/SvSkeleton.svelte +76 -0
  115. package/dist/SvSkeleton.svelte.d.ts +25 -0
  116. package/dist/SvSlider.svelte +41 -9
  117. package/dist/SvSlider.svelte.d.ts +4 -4
  118. package/dist/SvSparkline.svelte +77 -0
  119. package/dist/SvSparkline.svelte.d.ts +28 -0
  120. package/dist/SvSplitter.svelte +138 -0
  121. package/dist/SvSplitter.svelte.d.ts +32 -0
  122. package/dist/SvStat.svelte +86 -0
  123. package/dist/SvStat.svelte.d.ts +30 -0
  124. package/dist/SvStepper.svelte +91 -0
  125. package/dist/SvStepper.svelte.d.ts +24 -0
  126. package/dist/SvSwitchButton.svelte +39 -24
  127. package/dist/SvSwitchButton.svelte.d.ts +2 -5
  128. package/dist/SvTabs.svelte +147 -28
  129. package/dist/SvTabs.svelte.d.ts +16 -4
  130. package/dist/SvTagsInput.svelte +59 -22
  131. package/dist/SvTagsInput.svelte.d.ts +9 -4
  132. package/dist/SvTextArea.svelte +113 -0
  133. package/dist/SvTextArea.svelte.d.ts +18 -0
  134. package/dist/SvTextInput.svelte +115 -0
  135. package/dist/SvTextInput.svelte.d.ts +20 -0
  136. package/dist/SvTimePicker.svelte +19 -5
  137. package/dist/SvTimePicker.svelte.d.ts +12 -0
  138. package/dist/SvTimeline.svelte +75 -0
  139. package/dist/SvTimeline.svelte.d.ts +24 -0
  140. package/dist/SvToaster.svelte +124 -0
  141. package/dist/SvToaster.svelte.d.ts +10 -0
  142. package/dist/SvToggleButton.svelte +37 -12
  143. package/dist/SvToggleButton.svelte.d.ts +2 -4
  144. package/dist/SvTooltip.svelte +113 -0
  145. package/dist/SvTooltip.svelte.d.ts +22 -0
  146. package/dist/SvTour.svelte +151 -0
  147. package/dist/SvTour.svelte.d.ts +25 -0
  148. package/dist/SvTree.svelte +286 -44
  149. package/dist/SvTree.svelte.d.ts +26 -9
  150. package/dist/SvTreeSelect.svelte +222 -0
  151. package/dist/SvTreeSelect.svelte.d.ts +24 -0
  152. package/dist/a11y/dismissable.d.ts +32 -0
  153. package/dist/a11y/dismissable.js +54 -0
  154. package/dist/a11y/focus-trap.d.ts +39 -0
  155. package/dist/a11y/focus-trap.js +142 -0
  156. package/dist/a11y/live-region.d.ts +8 -0
  157. package/dist/a11y/live-region.js +60 -0
  158. package/dist/a11y/scroll-lock.d.ts +4 -0
  159. package/dist/a11y/scroll-lock.js +41 -0
  160. package/dist/a11y.d.ts +3 -1
  161. package/dist/a11y.js +1 -1
  162. package/dist/avatar.d.ts +10 -0
  163. package/dist/avatar.js +22 -0
  164. package/dist/builtin-editors.d.ts +5 -0
  165. package/dist/builtin-editors.js +55 -0
  166. package/dist/cdn/svgrid.js +16022 -8235
  167. package/dist/cdn/svgrid.svelte-external.js +14543 -6765
  168. package/dist/columns.js +3 -2
  169. package/dist/core.d.ts +7 -1
  170. package/dist/countries.d.ts +12 -0
  171. package/dist/countries.js +24 -0
  172. package/dist/createAccordion.svelte.d.ts +71 -0
  173. package/dist/createAccordion.svelte.js +99 -0
  174. package/dist/createAutocomplete.svelte.d.ts +13 -4
  175. package/dist/createAutocomplete.svelte.js +11 -1
  176. package/dist/createButtonGroup.svelte.d.ts +62 -0
  177. package/dist/createButtonGroup.svelte.js +154 -0
  178. package/dist/createCalendar.svelte.d.ts +5 -0
  179. package/dist/createCalendar.svelte.js +2 -0
  180. package/dist/createCheckbox.svelte.d.ts +9 -17
  181. package/dist/createCheckbox.svelte.js +28 -1
  182. package/dist/createColorInput.svelte.d.ts +12 -22
  183. package/dist/createColorInput.svelte.js +13 -0
  184. package/dist/createCombobox.svelte.d.ts +16 -5
  185. package/dist/createCombobox.svelte.js +13 -2
  186. package/dist/createCountryInput.svelte.d.ts +14 -3
  187. package/dist/createCountryInput.svelte.js +12 -2
  188. package/dist/createDateTimePicker.svelte.d.ts +17 -2
  189. package/dist/createDateTimePicker.svelte.js +12 -2
  190. package/dist/createDropdownList.svelte.d.ts +14 -5
  191. package/dist/createDropdownList.svelte.js +50 -1
  192. package/dist/createFileUpload.svelte.d.ts +68 -0
  193. package/dist/createFileUpload.svelte.js +122 -0
  194. package/dist/createListbox.svelte.d.ts +10 -1
  195. package/dist/createListbox.svelte.js +48 -1
  196. package/dist/createMaskedInput.svelte.d.ts +11 -2
  197. package/dist/createMaskedInput.svelte.js +11 -1
  198. package/dist/createNumberInput.svelte.d.ts +1 -0
  199. package/dist/createNumberInput.svelte.js +1 -0
  200. package/dist/createPasswordInput.svelte.d.ts +19 -21
  201. package/dist/createPasswordInput.svelte.js +16 -4
  202. package/dist/createPhoneInput.svelte.d.ts +26 -7
  203. package/dist/createPhoneInput.svelte.js +24 -3
  204. package/dist/createPopoverSelect.svelte.d.ts +86 -0
  205. package/dist/createPopoverSelect.svelte.js +196 -0
  206. package/dist/createRadioGroup.svelte.d.ts +9 -0
  207. package/dist/createRadioGroup.svelte.js +11 -1
  208. package/dist/createRating.svelte.d.ts +11 -0
  209. package/dist/createRating.svelte.js +12 -1
  210. package/dist/createSlider.svelte.d.ts +2 -0
  211. package/dist/createSlider.svelte.js +16 -5
  212. package/dist/createSplitter.svelte.d.ts +67 -0
  213. package/dist/createSplitter.svelte.js +99 -0
  214. package/dist/createSwitch.svelte.d.ts +9 -16
  215. package/dist/createSwitch.svelte.js +28 -1
  216. package/dist/createTabs.svelte.d.ts +7 -0
  217. package/dist/createTabs.svelte.js +17 -2
  218. package/dist/createTagsInput.svelte.d.ts +13 -1
  219. package/dist/createTagsInput.svelte.js +12 -3
  220. package/dist/createToggle.svelte.d.ts +9 -0
  221. package/dist/createToggle.svelte.js +12 -1
  222. package/dist/createTree.svelte.d.ts +19 -0
  223. package/dist/createTree.svelte.js +108 -15
  224. package/dist/debounce.d.ts +11 -0
  225. package/dist/debounce.js +30 -0
  226. package/dist/duration.d.ts +15 -0
  227. package/dist/duration.js +51 -0
  228. package/dist/editor-contract.d.ts +62 -7
  229. package/dist/editor-contract.js +45 -5
  230. package/dist/editor-registry.d.ts +67 -0
  231. package/dist/editor-registry.js +38 -0
  232. package/dist/editors/cell-editors.d.ts +1 -1
  233. package/dist/editors/cell-editors.js +5 -0
  234. package/dist/fuzzy.d.ts +3 -0
  235. package/dist/fuzzy.js +41 -0
  236. package/dist/grid-select.d.ts +9 -0
  237. package/dist/grid-select.js +8 -0
  238. package/dist/index.d.ts +79 -6
  239. package/dist/index.js +78 -4
  240. package/dist/keyboard-handlers.js +19 -0
  241. package/dist/list-option.d.ts +36 -0
  242. package/dist/list-option.js +68 -0
  243. package/dist/otp.d.ts +16 -0
  244. package/dist/otp.js +26 -0
  245. package/dist/paginate.d.ts +20 -0
  246. package/dist/paginate.js +40 -0
  247. package/dist/popover.d.ts +15 -1
  248. package/dist/popover.js +29 -3
  249. package/dist/recurrence.d.ts +36 -0
  250. package/dist/recurrence.js +90 -0
  251. package/dist/server-data-source.d.ts +89 -0
  252. package/dist/server-data-source.js +4 -0
  253. package/dist/server-group-model.d.ts +98 -0
  254. package/dist/server-group-model.js +263 -0
  255. package/dist/toast-store.svelte.d.ts +41 -0
  256. package/dist/toast-store.svelte.js +113 -0
  257. package/dist/tree-select.d.ts +19 -0
  258. package/dist/tree-select.js +40 -0
  259. package/dist/ui-app.types.d.ts +80 -0
  260. package/dist/ui-app.types.js +7 -0
  261. package/dist/validators.d.ts +43 -0
  262. package/dist/validators.js +53 -0
  263. package/dist/virtual.d.ts +35 -0
  264. package/dist/virtual.js +34 -0
  265. package/package.json +85 -85
  266. package/src/FlexRender.svelte +96 -96
  267. package/src/GridFooter.svelte +178 -178
  268. package/src/SvAccordion.svelte +109 -0
  269. package/src/SvAccordion.test.ts +66 -0
  270. package/src/SvAlert.svelte +92 -0
  271. package/src/SvAutoComplete.svelte +47 -18
  272. package/src/SvAvatar.svelte +75 -0
  273. package/src/SvAvatarGroup.svelte +48 -0
  274. package/src/SvBadge.svelte +54 -0
  275. package/src/SvBreadcrumb.svelte +88 -0
  276. package/src/SvButtonGroup.svelte +121 -0
  277. package/src/SvButtonGroup.test.ts +72 -0
  278. package/src/SvCalendar.svelte +72 -9
  279. package/src/SvCard.svelte +71 -0
  280. package/src/SvCarousel.svelte +134 -0
  281. package/src/SvCheckBox.svelte +36 -21
  282. package/src/SvChip.svelte +88 -0
  283. package/src/SvCircularProgress.svelte +109 -0
  284. package/src/SvColorInput.svelte +54 -27
  285. package/src/SvComboBox.svelte +119 -33
  286. package/src/SvCommand.svelte +197 -0
  287. package/src/SvContextMenu.svelte +96 -0
  288. package/src/SvCountryInput.svelte +56 -21
  289. package/src/SvDateRangeInput.svelte +256 -0
  290. package/src/SvDateRangeInput.test.ts +80 -0
  291. package/src/SvDateTimePicker.svelte +57 -20
  292. package/src/SvDivider.svelte +61 -0
  293. package/src/SvDrawer.svelte +226 -0
  294. package/src/SvDrawer.test.ts +125 -0
  295. package/src/SvDropDownList.svelte +114 -35
  296. package/src/SvDurationInput.svelte +108 -0
  297. package/src/SvEmptyState.svelte +59 -0
  298. package/src/SvField.svelte +85 -0
  299. package/src/SvFileUpload.svelte +169 -0
  300. package/src/SvFileUpload.test.ts +59 -0
  301. package/src/SvForm.svelte +7 -1
  302. package/src/SvGauge.svelte +7 -1
  303. package/src/SvGrid.controller.svelte.ts +2553 -2494
  304. package/src/SvGrid.css +2376 -2343
  305. package/src/SvGrid.svelte +2764 -2651
  306. package/src/SvGrid.types.ts +944 -570
  307. package/src/SvGridBoard.svelte +2281 -0
  308. package/src/SvGridDropdown.svelte +666 -665
  309. package/src/SvGridSelect.svelte +255 -0
  310. package/src/SvGridSelect.test.ts +100 -0
  311. package/src/SvGroupCell.svelte +109 -0
  312. package/src/SvListBox.svelte +123 -36
  313. package/src/SvMaskedInput.svelte +53 -13
  314. package/src/SvMenu.svelte +101 -0
  315. package/src/SvMenu.test.ts +73 -0
  316. package/src/SvMenuList.svelte +143 -0
  317. package/src/SvModal.svelte +220 -0
  318. package/src/SvMultiSelect.svelte +277 -0
  319. package/src/SvMultiSelect.test.ts +167 -0
  320. package/src/SvNavPane.svelte +314 -0
  321. package/src/SvNavPane.test.ts +70 -0
  322. package/src/SvNumberInput.svelte +23 -9
  323. package/src/SvOtpInput.svelte +157 -0
  324. package/src/SvPagination.svelte +100 -0
  325. package/src/SvPasswordInput.svelte +42 -12
  326. package/src/SvPhoneInput.svelte +43 -11
  327. package/src/SvPopover.svelte +127 -0
  328. package/src/SvProgress.svelte +116 -0
  329. package/src/SvRadioGroup.svelte +40 -22
  330. package/src/SvRating.svelte +51 -30
  331. package/src/SvRichText.svelte +192 -0
  332. package/src/SvRowGroupPanel.svelte +147 -0
  333. package/src/SvScrollArea.svelte +50 -0
  334. package/src/SvSkeleton.svelte +76 -0
  335. package/src/SvSlider.svelte +41 -9
  336. package/src/SvSparkline.svelte +77 -0
  337. package/src/SvSplitter.svelte +138 -0
  338. package/src/SvSplitter.test.ts +55 -0
  339. package/src/SvStat.svelte +86 -0
  340. package/src/SvStepper.svelte +91 -0
  341. package/src/SvSwitchButton.svelte +39 -24
  342. package/src/SvTabs.svelte +147 -28
  343. package/src/SvTagsInput.svelte +59 -22
  344. package/src/SvTextArea.svelte +113 -0
  345. package/src/SvTextInput.svelte +115 -0
  346. package/src/SvTimePicker.svelte +19 -5
  347. package/src/SvTimeline.svelte +75 -0
  348. package/src/SvToaster.svelte +124 -0
  349. package/src/SvToaster.test.ts +63 -0
  350. package/src/SvToggleButton.svelte +37 -12
  351. package/src/SvTooltip.svelte +113 -0
  352. package/src/SvTour.svelte +151 -0
  353. package/src/SvTree.svelte +286 -44
  354. package/src/SvTreeSelect.svelte +222 -0
  355. package/src/SvTreeSelect.test.ts +87 -0
  356. package/src/a11y/dismissable.test.ts +95 -0
  357. package/src/a11y/dismissable.ts +94 -0
  358. package/src/a11y/focus-trap.test.ts +110 -0
  359. package/src/a11y/focus-trap.ts +134 -0
  360. package/src/a11y/live-region.test.ts +40 -0
  361. package/src/a11y/live-region.ts +65 -0
  362. package/src/a11y/scroll-lock.test.ts +38 -0
  363. package/src/a11y/scroll-lock.ts +41 -0
  364. package/src/a11y.contract.test.ts +49 -49
  365. package/src/a11y.test.ts +59 -59
  366. package/src/a11y.ts +61 -59
  367. package/src/avatar.test.ts +32 -0
  368. package/src/avatar.ts +21 -0
  369. package/src/board.test.ts +927 -0
  370. package/src/build-api.ts +798 -798
  371. package/src/builtin-editors.grid.test.ts +85 -0
  372. package/src/builtin-editors.test.ts +58 -0
  373. package/src/builtin-editors.ts +56 -0
  374. package/src/cell-formatting.ts +169 -169
  375. package/src/cell-render.ts +469 -469
  376. package/src/collaboration.test.ts +104 -104
  377. package/src/collaboration.ts +167 -167
  378. package/src/columns.ts +3 -2
  379. package/src/core.performance.test.ts +30 -30
  380. package/src/core.ts +1111 -1101
  381. package/src/countries.ts +25 -0
  382. package/src/createAccordion.svelte.ts +126 -0
  383. package/src/createAutocomplete.svelte.ts +18 -1
  384. package/src/createButtonGroup.svelte.ts +166 -0
  385. package/src/createCalendar.svelte.ts +6 -0
  386. package/src/createCheckbox.svelte.ts +23 -1
  387. package/src/createColorInput.svelte.ts +20 -0
  388. package/src/createCombobox.svelte.ts +22 -2
  389. package/src/createCountryInput.svelte.ts +21 -2
  390. package/src/createDateTimePicker.svelte.ts +23 -2
  391. package/src/createDropdownList.svelte.ts +31 -2
  392. package/src/createFileUpload.svelte.ts +144 -0
  393. package/src/createGrid.svelte.ts +42 -42
  394. package/src/createGrid.test.ts +10 -10
  395. package/src/createGridState.svelte.ts +17 -17
  396. package/src/createListbox.svelte.ts +35 -3
  397. package/src/createMaskedInput.svelte.ts +18 -1
  398. package/src/createNumberInput.svelte.ts +2 -0
  399. package/src/createPasswordInput.svelte.ts +31 -5
  400. package/src/createPhoneInput.svelte.ts +38 -4
  401. package/src/createPopoverSelect.svelte.ts +208 -0
  402. package/src/createRadioGroup.svelte.ts +23 -1
  403. package/src/createRating.svelte.ts +26 -1
  404. package/src/createSlider.svelte.ts +14 -3
  405. package/src/createSplitter.svelte.ts +119 -0
  406. package/src/createSwitch.svelte.ts +26 -3
  407. package/src/createTabs.svelte.ts +20 -3
  408. package/src/createTagsInput.svelte.ts +24 -3
  409. package/src/createToggle.svelte.ts +25 -2
  410. package/src/createTree.svelte.ts +104 -14
  411. package/src/debounce.test.ts +50 -0
  412. package/src/debounce.ts +41 -0
  413. package/src/duration.test.ts +41 -0
  414. package/src/duration.ts +51 -0
  415. package/src/editing.test.ts +859 -859
  416. package/src/editing.ts +675 -675
  417. package/src/editor-contract.ts +87 -8
  418. package/src/editor-registry.grid.test.ts +98 -0
  419. package/src/editor-registry.test.ts +86 -0
  420. package/src/editor-registry.ts +106 -0
  421. package/src/editors/cell-editors.ts +10 -1
  422. package/src/export-data-api.test.ts +126 -126
  423. package/src/export-format.test.ts +107 -107
  424. package/src/export-format.ts +598 -598
  425. package/src/flex-render.ts +3 -3
  426. package/src/fuzzy.test.ts +40 -0
  427. package/src/fuzzy.ts +39 -0
  428. package/src/grid-select.test.ts +28 -0
  429. package/src/grid-select.ts +20 -0
  430. package/src/index.ts +463 -318
  431. package/src/keyboard-handlers.ts +20 -0
  432. package/src/keyboard.test.ts +59 -59
  433. package/src/keyboard.ts +97 -97
  434. package/src/list-option.ts +74 -0
  435. package/src/list-power.test.ts +71 -0
  436. package/src/menus.ts +582 -582
  437. package/src/merge-objects.ts +48 -48
  438. package/src/otp.test.ts +28 -0
  439. package/src/otp.ts +28 -0
  440. package/src/overlays.test.ts +85 -0
  441. package/src/paginate.test.ts +41 -0
  442. package/src/paginate.ts +61 -0
  443. package/src/phone-valid.test.ts +26 -0
  444. package/src/popover.ts +31 -3
  445. package/src/progress.test.ts +55 -0
  446. package/src/recurrence.test.ts +91 -0
  447. package/src/recurrence.ts +111 -0
  448. package/src/render-component.ts +28 -28
  449. package/src/selection.test.ts +754 -754
  450. package/src/selection.ts +600 -600
  451. package/src/server-data-source.test.ts +289 -289
  452. package/src/server-data-source.ts +413 -311
  453. package/src/server-group-model.test.ts +294 -0
  454. package/src/server-group-model.ts +370 -0
  455. package/src/sparkline.test.ts +68 -68
  456. package/src/sparkline.ts +169 -169
  457. package/src/spreadsheet.test.ts +489 -489
  458. package/src/spreadsheet.ts +304 -304
  459. package/src/static-functions.ts +11 -11
  460. package/src/subscribe.ts +38 -38
  461. package/src/svgrid-wrapper.types.ts +439 -439
  462. package/src/svgrid.behavior.test.ts +706 -706
  463. package/src/svgrid.features.test.ts +157 -157
  464. package/src/svgrid.new-features.wrapper.test.ts +251 -251
  465. package/src/svgrid.responsive.test.ts +72 -0
  466. package/src/svgrid.wrapper.test.ts +40 -40
  467. package/src/toast-store.svelte.ts +148 -0
  468. package/src/toast-store.test.ts +86 -0
  469. package/src/tree-edit.test.ts +49 -0
  470. package/src/tree-filter.test.ts +56 -0
  471. package/src/tree-select.test.ts +48 -0
  472. package/src/tree-select.ts +62 -0
  473. package/src/ui-app.test.ts +130 -0
  474. package/src/ui-app.types.ts +88 -0
  475. package/src/ui-display.test.ts +79 -0
  476. package/src/ui-inputs.test.ts +1 -1
  477. package/src/ui-status.test.ts +141 -0
  478. package/src/ui-tier1.test.ts +142 -0
  479. package/src/ui-tier2.test.ts +124 -0
  480. package/src/ui-tier3.test.ts +139 -0
  481. package/src/validators.test.ts +58 -0
  482. package/src/validators.ts +105 -0
  483. package/src/virtual.test.ts +72 -0
  484. package/src/virtual.ts +67 -0
  485. package/src/virtualization/column-virtualizer.test.ts +27 -27
  486. package/src/virtualization/column-virtualizer.ts +30 -30
  487. package/src/virtualization/svelte-virtualizer.svelte.ts +26 -26
  488. package/src/virtualization/types.ts +30 -30
  489. package/src/virtualization/virtualizer.test.ts +47 -47
  490. package/src/virtualization/virtualizer.ts +296 -296
@@ -22,7 +22,7 @@
22
22
  *
23
23
  * The styled <SvListBox> is just one renderer over this core.
24
24
  */
25
- import type { ListOption } from './list-option';
25
+ import { type ListOption } from './list-option';
26
26
  export type ListboxValue = string | number | Array<string | number> | null;
27
27
  /** Reactive inputs are passed as getters so the core tracks live prop changes
28
28
  * (the same controlled pattern Svelte headless libraries use). */
@@ -33,6 +33,11 @@ export type ListboxConfig = {
33
33
  multiple?: () => boolean;
34
34
  disabled?: () => boolean;
35
35
  ariaLabel?: () => string | undefined;
36
+ id?: () => string | undefined;
37
+ invalid?: () => boolean;
38
+ required?: () => boolean;
39
+ error?: () => string | undefined;
40
+ hint?: () => string | undefined;
36
41
  };
37
42
  export type OptionProps = {
38
43
  role: 'option';
@@ -47,10 +52,14 @@ export type OptionProps = {
47
52
  };
48
53
  export type ListboxRootProps = {
49
54
  role: 'listbox';
55
+ id: string | undefined;
50
56
  'aria-multiselectable': boolean;
51
57
  'aria-label': string | undefined;
52
58
  'aria-disabled': boolean;
53
59
  'aria-activedescendant': string | undefined;
60
+ 'aria-invalid': 'true' | undefined;
61
+ 'aria-required': 'true' | undefined;
62
+ 'aria-describedby': string | undefined;
54
63
  tabindex: number;
55
64
  onkeydown: (e: KeyboardEvent) => void;
56
65
  };
@@ -1,3 +1,29 @@
1
+ /**
2
+ * createListbox - the HEADLESS core behind <SvListBox>, in the same spirit as
3
+ * `createSvGrid` for the grid: a runes-based state machine (roving active index,
4
+ * single/multi selection, full keyboard) with **prop-getters** you spread onto
5
+ * YOUR OWN markup. No styles, no DOM assumptions - render it however you like.
6
+ *
7
+ * ```svelte
8
+ * <script lang="ts">
9
+ * import { createListbox } from '@svgrid/grid'
10
+ * let value = $state<string | null>(null)
11
+ * const lb = createListbox({
12
+ * options: () => options, value: () => value,
13
+ * onChange: (v) => (value = v),
14
+ * })
15
+ * </script>
16
+ * <ul {...lb.rootProps()}>
17
+ * {#each options as opt, i}
18
+ * <li {...lb.optionProps(i)}>{opt.label}</li>
19
+ * {/each}
20
+ * </ul>
21
+ * ```
22
+ *
23
+ * The styled <SvListBox> is just one renderer over this core.
24
+ */
25
+ import { createTypeaheadBuffer, isTypeaheadKey, nextTypeaheadIndex } from './list-option';
26
+ import { editorAria } from './editor-contract';
1
27
  let uid = 0;
2
28
  /** Normalize a listbox value to an array (pure). */
3
29
  export function toSelectedArray(value, multiple) {
@@ -52,6 +78,14 @@ export function createListbox(config) {
52
78
  }
53
79
  const first = () => { active = enabledIdx[0] ?? 0; };
54
80
  const last = () => { active = enabledIdx.at(-1) ?? 0; };
81
+ // Type-ahead: typing a label prefix jumps the active highlight to it.
82
+ const typeahead = createTypeaheadBuffer();
83
+ function onTypeahead(char) {
84
+ const buffer = typeahead.push(char.toLowerCase());
85
+ const next = nextTypeaheadIndex(opts(), buffer, active);
86
+ if (next >= 0)
87
+ active = next;
88
+ }
55
89
  function onKeydown(e) {
56
90
  if (disabled())
57
91
  return;
@@ -77,8 +111,19 @@ export function createListbox(config) {
77
111
  e.preventDefault();
78
112
  pick(active);
79
113
  break;
114
+ default: if (isTypeaheadKey(e))
115
+ onTypeahead(e.key);
80
116
  }
81
117
  }
118
+ // Editor-contract ARIA state, folded onto the focusable listbox root.
119
+ const ariaState = () => ({
120
+ id: config.id?.(),
121
+ invalid: config.invalid?.(),
122
+ required: config.required?.(),
123
+ error: config.error?.(),
124
+ hint: config.hint?.(),
125
+ ariaLabel: config.ariaLabel?.(),
126
+ });
82
127
  return {
83
128
  get activeIndex() { return active; },
84
129
  get selectedValues() { return selected; },
@@ -92,10 +137,12 @@ export function createListbox(config) {
92
137
  onKeydown,
93
138
  rootProps: () => ({
94
139
  role: 'listbox',
140
+ id: config.id?.(),
95
141
  'aria-multiselectable': multiple(),
96
- 'aria-label': config.ariaLabel?.(),
97
142
  'aria-disabled': disabled(),
98
143
  'aria-activedescendant': opts()[active] ? optionId(active) : undefined,
144
+ // aria-label + aria-invalid/required/describedby from the editor contract.
145
+ ...editorAria(ariaState()),
99
146
  tabindex: disabled() ? -1 : 0,
100
147
  onkeydown: onKeydown,
101
148
  }),
@@ -7,6 +7,11 @@ export type MaskedInputConfig = {
7
7
  placeholder?: () => string | undefined;
8
8
  disabled?: () => boolean;
9
9
  readonly?: () => boolean;
10
+ id?: () => string | undefined;
11
+ invalid?: () => boolean;
12
+ required?: () => boolean;
13
+ error?: () => string | undefined;
14
+ hint?: () => string | undefined;
10
15
  ariaLabel?: () => string | undefined;
11
16
  };
12
17
  export declare function createMaskedInput(config: MaskedInputConfig): {
@@ -18,13 +23,17 @@ export declare function createMaskedInput(config: MaskedInputConfig): {
18
23
  readonly complete: boolean;
19
24
  /** Spread onto the text input element. */
20
25
  inputProps: () => {
26
+ oninput: (e: Event) => void;
27
+ 'aria-invalid': "true" | undefined;
28
+ 'aria-required': "true" | undefined;
29
+ 'aria-describedby': string | undefined;
30
+ 'aria-label': string | undefined;
31
+ id: string | undefined;
21
32
  value: string;
22
33
  type: "text";
23
34
  placeholder: string;
24
35
  disabled: boolean;
25
36
  readonly: boolean;
26
- 'aria-label': string | undefined;
27
- oninput: (e: Event) => void;
28
37
  };
29
38
  };
30
39
  export type MaskedInputCore = ReturnType<typeof createMaskedInput>;
@@ -16,6 +16,7 @@
16
16
  * The styled <SvMaskedInput> is just one renderer over this core.
17
17
  */
18
18
  import { applyMask, unmask, isMaskComplete } from './datetime/mask';
19
+ import { editorAria } from './editor-contract';
19
20
  export function createMaskedInput(config) {
20
21
  const mask = () => config.mask?.() ?? '';
21
22
  const disabled = () => config.disabled?.() ?? false;
@@ -41,6 +42,14 @@ export function createMaskedInput(config) {
41
42
  el.value = masked;
42
43
  config.onChange?.(masked, raw, m ? isMaskComplete(masked, m) : true);
43
44
  }
45
+ const ariaState = () => ({
46
+ id: config.id?.(),
47
+ invalid: config.invalid?.(),
48
+ required: config.required?.(),
49
+ error: config.error?.(),
50
+ hint: config.hint?.(),
51
+ ariaLabel: config.ariaLabel?.(),
52
+ });
44
53
  return {
45
54
  /** The current masked display text. */
46
55
  get masked() { return text; },
@@ -50,12 +59,13 @@ export function createMaskedInput(config) {
50
59
  get complete() { return mask() ? isMaskComplete(text, mask()) : true; },
51
60
  /** Spread onto the text input element. */
52
61
  inputProps: () => ({
62
+ id: config.id?.(),
53
63
  value: text,
54
64
  type: 'text',
55
65
  placeholder: config.placeholder?.() ?? mask(),
56
66
  disabled: disabled(),
57
67
  readonly: readonly(),
58
- 'aria-label': config.ariaLabel?.(),
68
+ ...editorAria(ariaState()),
59
69
  oninput: onInput,
60
70
  }),
61
71
  };
@@ -17,6 +17,7 @@ export type NumberInputConfig = {
17
17
  invalid?: () => boolean;
18
18
  required?: () => boolean;
19
19
  error?: () => string | undefined;
20
+ hint?: () => string | undefined;
20
21
  ariaLabel?: () => string | undefined;
21
22
  };
22
23
  export declare function createNumberInput(config: NumberInputConfig): {
@@ -115,6 +115,7 @@ export function createNumberInput(config) {
115
115
  invalid: config.invalid?.(),
116
116
  required: config.required?.(),
117
117
  error: config.error?.(),
118
+ hint: config.hint?.(),
118
119
  ariaLabel: config.ariaLabel?.(),
119
120
  });
120
121
  return {
@@ -1,20 +1,3 @@
1
- /**
2
- * createPasswordInput - the HEADLESS core behind <SvPasswordInput>: a runes-based
3
- * state machine that owns the reveal toggle + a 4-level strength heuristic,
4
- * exposed as **prop-getters** you spread onto YOUR OWN markup. No styles, no DOM.
5
- *
6
- * ```svelte
7
- * <script lang="ts">
8
- * import { createPasswordInput } from '@svgrid/grid'
9
- * let value = $state('')
10
- * const pw = createPasswordInput({ value: () => value, onChange: (v) => (value = v) })
11
- * </script>
12
- * <input {...pw.inputProps()} />
13
- * <button {...pw.toggleProps()}>{pw.revealed ? 'Hide' : 'Show'}</button>
14
- * ```
15
- *
16
- * The styled <SvPasswordInput> is just one renderer over this core.
17
- */
18
1
  export declare const STRENGTH_LABELS: string[];
19
2
  /** Score a password 0-4 by length + character-class variety (pure). */
20
3
  export declare function passwordStrength(v: string): number;
@@ -25,27 +8,42 @@ export type PasswordInputConfig = {
25
8
  placeholder?: () => string | undefined;
26
9
  disabled?: () => boolean;
27
10
  readonly?: () => boolean;
28
- ariaLabel?: () => string | undefined;
29
11
  autocomplete?: () => string | undefined;
12
+ /** Accessible label for the reveal toggle when the value is hidden. */
13
+ showLabel?: () => string | undefined;
14
+ /** Accessible label for the reveal toggle when the value is shown. */
15
+ hideLabel?: () => string | undefined;
16
+ /** Strength labels indexed 0-4 (index 0 unused; 1..4 = weak..strong). */
17
+ strengthLabels?: () => readonly string[];
18
+ id?: () => string | undefined;
19
+ invalid?: () => boolean;
20
+ required?: () => boolean;
21
+ error?: () => string | undefined;
22
+ hint?: () => string | undefined;
23
+ ariaLabel?: () => string | undefined;
30
24
  };
31
25
  export declare function createPasswordInput(config: PasswordInputConfig): {
32
26
  /** Whether the value is currently shown as plain text. */
33
27
  readonly revealed: boolean;
34
28
  /** Strength score, 0-4. */
35
29
  readonly strength: number;
36
- /** Human label for the strength score. */
30
+ /** Human label for the strength score (localizable via `strengthLabels`). */
37
31
  readonly strengthLabel: string | undefined;
38
32
  toggle: () => boolean;
39
33
  /** Spread onto the text/password input element. */
40
34
  inputProps: () => {
35
+ oninput: (e: Event) => void;
36
+ 'aria-invalid': "true" | undefined;
37
+ 'aria-required': "true" | undefined;
38
+ 'aria-describedby': string | undefined;
39
+ 'aria-label': string | undefined;
40
+ id: string | undefined;
41
41
  value: string;
42
42
  type: "text" | "password";
43
43
  placeholder: string | undefined;
44
44
  disabled: boolean;
45
45
  readonly: boolean;
46
46
  autocomplete: AutoFill;
47
- 'aria-label': string | undefined;
48
- oninput: (e: Event) => void;
49
47
  };
50
48
  /** Spread onto the reveal (show/hide) toggle button. */
51
49
  toggleProps: () => {
@@ -15,6 +15,7 @@
15
15
  *
16
16
  * The styled <SvPasswordInput> is just one renderer over this core.
17
17
  */
18
+ import { editorAria } from './editor-contract';
18
19
  export const STRENGTH_LABELS = ['', 'Weak', 'Fair', 'Good', 'Strong'];
19
20
  /** Score a password 0-4 by length + character-class variety (pure). */
20
21
  export function passwordStrength(v) {
@@ -40,29 +41,40 @@ export function createPasswordInput(config) {
40
41
  config.onChange?.(e.currentTarget.value);
41
42
  }
42
43
  const toggle = () => (revealed = !revealed);
44
+ const ariaState = () => ({
45
+ id: config.id?.(),
46
+ invalid: config.invalid?.(),
47
+ required: config.required?.(),
48
+ error: config.error?.(),
49
+ hint: config.hint?.(),
50
+ ariaLabel: config.ariaLabel?.(),
51
+ });
43
52
  return {
44
53
  /** Whether the value is currently shown as plain text. */
45
54
  get revealed() { return revealed; },
46
55
  /** Strength score, 0-4. */
47
56
  get strength() { return strength; },
48
- /** Human label for the strength score. */
49
- get strengthLabel() { return STRENGTH_LABELS[strength]; },
57
+ /** Human label for the strength score (localizable via `strengthLabels`). */
58
+ get strengthLabel() { return (config.strengthLabels?.() ?? STRENGTH_LABELS)[strength]; },
50
59
  toggle,
51
60
  /** Spread onto the text/password input element. */
52
61
  inputProps: () => ({
62
+ id: config.id?.(),
53
63
  value: config.value(),
54
64
  type: (revealed ? 'text' : 'password'),
55
65
  placeholder: config.placeholder?.(),
56
66
  disabled: disabled(),
57
67
  readonly: readonly(),
58
68
  autocomplete: (config.autocomplete?.() ?? 'current-password'),
59
- 'aria-label': config.ariaLabel?.(),
69
+ ...editorAria(ariaState()),
60
70
  oninput: onInput,
61
71
  }),
62
72
  /** Spread onto the reveal (show/hide) toggle button. */
63
73
  toggleProps: () => ({
64
74
  type: 'button',
65
- 'aria-label': revealed ? 'Hide password' : 'Show password',
75
+ 'aria-label': revealed
76
+ ? (config.hideLabel?.() ?? 'Hide password')
77
+ : (config.showLabel?.() ?? 'Show password'),
66
78
  'aria-pressed': revealed,
67
79
  disabled: disabled(),
68
80
  tabindex: -1,
@@ -1,16 +1,27 @@
1
+ /** Emitted alongside the phone value: parsed parts + per-country validity. */
2
+ export type PhoneParts = {
3
+ country: string;
4
+ dial: string;
5
+ national: string;
6
+ valid: boolean;
7
+ complete: boolean;
8
+ };
1
9
  /** Reactive inputs are passed as getters so the core tracks live prop changes. */
2
10
  export type PhoneInputConfig = {
3
11
  value: () => string;
4
- onChange?: (value: string, parts: {
5
- country: string;
6
- dial: string;
7
- national: string;
8
- }) => void;
12
+ onChange?: (value: string, parts: PhoneParts) => void;
9
13
  /** Default country ISO code. */
10
14
  country?: () => string;
11
15
  disabled?: () => boolean;
12
16
  readonly?: () => boolean;
13
17
  placeholder?: () => string | undefined;
18
+ /** Accessible name for the country `<select>` (localizable). */
19
+ countryLabel?: () => string | undefined;
20
+ id?: () => string | undefined;
21
+ invalid?: () => boolean;
22
+ required?: () => boolean;
23
+ error?: () => string | undefined;
24
+ hint?: () => string | undefined;
14
25
  ariaLabel?: () => string | undefined;
15
26
  };
16
27
  export declare function createPhoneInput(config: PhoneInputConfig): {
@@ -24,6 +35,10 @@ export declare function createPhoneInput(config: PhoneInputConfig): {
24
35
  readonly displayNational: string;
25
36
  /** The full emitted value (`+<dial><digits>`). */
26
37
  readonly value: string;
38
+ /** Whether the national number is a plausible length for the country. */
39
+ readonly valid: boolean;
40
+ /** Whether a non-empty number matches the country's expected length. */
41
+ readonly complete: boolean;
27
42
  /** Spread onto the country `<select>` element. */
28
43
  selectProps: () => {
29
44
  value: string;
@@ -33,14 +48,18 @@ export declare function createPhoneInput(config: PhoneInputConfig): {
33
48
  };
34
49
  /** Spread onto the national number input element. */
35
50
  inputProps: () => {
51
+ 'aria-label': string;
52
+ oninput: (e: Event) => void;
53
+ 'aria-invalid': "true" | undefined;
54
+ 'aria-required': "true" | undefined;
55
+ 'aria-describedby': string | undefined;
56
+ id: string | undefined;
36
57
  value: string;
37
58
  type: "tel";
38
59
  inputmode: "tel";
39
60
  placeholder: string;
40
61
  disabled: boolean;
41
62
  readonly: boolean;
42
- 'aria-label': string;
43
- oninput: (e: Event) => void;
44
63
  };
45
64
  };
46
65
  export type PhoneInputCore = ReturnType<typeof createPhoneInput>;
@@ -17,8 +17,9 @@
17
17
  *
18
18
  * The styled <SvPhoneInput> is just one renderer over this core.
19
19
  */
20
- import { COUNTRIES, COUNTRY_BY_CODE, flagEmoji } from './countries';
20
+ import { COUNTRIES, COUNTRY_BY_CODE, flagEmoji, phoneDigitsValid } from './countries';
21
21
  import { applyMask } from './datetime/mask';
22
+ import { editorAria } from './editor-contract';
22
23
  /** Best-effort parse: strip to the longest matching dial code. */
23
24
  function matchCountry(v) {
24
25
  return [...COUNTRIES].sort((a, b) => b.dial.length - a.dial.length).find((c) => v.startsWith(c.dial));
@@ -58,8 +59,12 @@ export function createPhoneInput(config) {
58
59
  }
59
60
  }
60
61
  });
62
+ // Per-country length validity: empty is valid (required handles emptiness);
63
+ // a non-empty number must match the country's expected national length.
64
+ const complete = $derived(national.length > 0 && phoneDigitsValid(iso, national));
65
+ const valid = $derived(national.length === 0 || phoneDigitsValid(iso, national));
61
66
  function emit() {
62
- config.onChange?.(`${dial}${national}`, { country: iso, dial, national });
67
+ config.onChange?.(`${dial}${national}`, { country: iso, dial, national, valid, complete });
63
68
  }
64
69
  function onNumberInput(e) {
65
70
  const raw = e.currentTarget.value.replace(/\D/g, '');
@@ -72,6 +77,14 @@ export function createPhoneInput(config) {
72
77
  lastVal = `${dial}${national}`;
73
78
  emit();
74
79
  }
80
+ const ariaState = () => ({
81
+ id: config.id?.(),
82
+ invalid: config.invalid?.(),
83
+ required: config.required?.(),
84
+ error: config.error?.(),
85
+ hint: config.hint?.(),
86
+ ariaLabel: config.ariaLabel?.(),
87
+ });
75
88
  return {
76
89
  /** Selected country ISO code. */
77
90
  get iso() { return iso; },
@@ -83,21 +96,29 @@ export function createPhoneInput(config) {
83
96
  get displayNational() { return displayNational; },
84
97
  /** The full emitted value (`+<dial><digits>`). */
85
98
  get value() { return `${dial}${national}`; },
99
+ /** Whether the national number is a plausible length for the country. */
100
+ get valid() { return valid; },
101
+ /** Whether a non-empty number matches the country's expected length. */
102
+ get complete() { return complete; },
86
103
  /** Spread onto the country `<select>` element. */
87
104
  selectProps: () => ({
88
105
  value: iso,
89
106
  disabled: disabled(),
90
- 'aria-label': 'Country',
107
+ 'aria-label': config.countryLabel?.() ?? 'Country',
91
108
  onchange: onCountryChange,
92
109
  }),
93
110
  /** Spread onto the national number input element. */
94
111
  inputProps: () => ({
112
+ id: config.id?.(),
95
113
  value: displayNational,
96
114
  type: 'tel',
97
115
  inputmode: 'tel',
98
116
  placeholder: config.placeholder?.() ?? 'Phone number',
99
117
  disabled: disabled(),
100
118
  readonly: readonly(),
119
+ // aria-invalid/required/describedby come from the editor contract; the
120
+ // aria-label default stays 'Phone number' so the field is always named.
121
+ ...editorAria(ariaState()),
101
122
  'aria-label': config.ariaLabel?.() ?? 'Phone number',
102
123
  oninput: onNumberInput,
103
124
  }),
@@ -0,0 +1,86 @@
1
+ /**
2
+ * createPopoverSelect - the shared HEADLESS engine behind the kit's dropdown
3
+ * selects (SvMultiSelect, SvTreeSelect, SvGridSelect and any future one). It
4
+ * owns the parts every anchored-panel select repeats: open/close state, the
5
+ * `anchoredRect` positioning (reposition on scroll/resize), outside/Escape
6
+ * dismissal via the shared layer stack, a roving `active` index over the visible
7
+ * items, the WAI-ARIA combobox wiring (`aria-expanded` / `aria-controls` /
8
+ * `aria-activedescendant` + stable option ids), and focus management (focus
9
+ * moves into the panel on open, back to the trigger on close).
10
+ *
11
+ * The component owns its own `bind:this` refs and item rendering; it passes the
12
+ * refs in as getters and spreads the returned prop-getters onto its trigger,
13
+ * panel and items. Runes-based, like `createListbox`.
14
+ */
15
+ import { type AnchoredRect } from './popover';
16
+ export type PopoverSelectConfig = {
17
+ /** Number of currently-visible/navigable items (post-filter). */
18
+ itemCount: () => number;
19
+ /** Whether item `i` is disabled (skipped by roving, not selectable). */
20
+ disabled?: (index: number) => boolean;
21
+ /** Commit the item at `index` (Enter or a click the component forwards). */
22
+ onSelect: (index: number) => void;
23
+ /** Notified whenever the open state changes. */
24
+ onOpenChange?: (open: boolean) => void;
25
+ /** The trigger element (component owns `bind:this`, passes a getter). */
26
+ getTrigger: () => HTMLElement | null;
27
+ /** The panel element. */
28
+ getPanel: () => HTMLElement | null;
29
+ /** Element focused when the panel opens (e.g. a search input). Defaults to the
30
+ * panel itself. Its id-holder also carries `aria-activedescendant`. */
31
+ getInitialFocus?: () => HTMLElement | null;
32
+ /** Estimated panel height, for the flip-up decision. Default 280. */
33
+ estimatedHeight?: () => number;
34
+ /** Minimum panel width. Default 200. */
35
+ minWidth?: () => number;
36
+ /** Close after a selection (single-select). Default true. */
37
+ closeOnSelect?: () => boolean;
38
+ /** Active index to start on when opening (e.g. the selected row). Default 0. */
39
+ initialActive?: () => number;
40
+ /** Handle a key the core doesn't (e.g. tree ArrowLeft/Right). Return true if
41
+ * handled to stop the core's default handling. */
42
+ onExtraKey?: (event: KeyboardEvent, active: number) => boolean;
43
+ idPrefix?: string;
44
+ };
45
+ export declare function createPopoverSelect(config: PopoverSelectConfig): {
46
+ open: boolean;
47
+ active: number;
48
+ readonly rect: AnchoredRect;
49
+ /** Stable id of the panel element (for aria-controls / labelling). */
50
+ panelId: string;
51
+ /** Stable id of the option at `i` (for aria-activedescendant + item id). */
52
+ optionId: (i: number) => string;
53
+ activeDescendant: () => string | undefined;
54
+ openPanel: () => void;
55
+ closePanel: () => void;
56
+ toggle: () => void;
57
+ move: (delta: number) => void;
58
+ first: () => void;
59
+ last: () => void;
60
+ selectActive: () => void;
61
+ updatePos: () => void;
62
+ onPanelKeydown: (e: KeyboardEvent) => void;
63
+ /** True when item `i` is the roving-active one. */
64
+ isActive: (i: number) => boolean;
65
+ /** Spread onto the trigger button. */
66
+ triggerProps: () => {
67
+ 'aria-haspopup': "listbox";
68
+ 'aria-expanded': boolean;
69
+ 'aria-controls': string | undefined;
70
+ onkeydown: (e: KeyboardEvent) => void;
71
+ };
72
+ /** Attributes for the element that OWNS focus + activedescendant (the panel,
73
+ * or a search input). Pass the ARIA role the panel should expose. */
74
+ focusOwnerProps: (role?: "listbox" | "tree" | "grid") => {
75
+ role: "listbox" | "grid" | "tree";
76
+ 'aria-activedescendant': string | undefined;
77
+ onkeydown: (e: KeyboardEvent) => void;
78
+ };
79
+ /** Spread onto the item element at `i`. */
80
+ itemProps: (i: number) => {
81
+ id: string;
82
+ 'data-active': string | undefined;
83
+ onpointermove: () => void;
84
+ };
85
+ };
86
+ export type PopoverSelect = ReturnType<typeof createPopoverSelect>;