@svgrid/grid 1.2.34 → 2.0.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 (444) hide show
  1. package/README.md +6 -5
  2. package/dist/SvAccordion.svelte +109 -0
  3. package/dist/SvAccordion.svelte.d.ts +28 -0
  4. package/dist/SvAlert.svelte +92 -0
  5. package/dist/SvAlert.svelte.d.ts +27 -0
  6. package/dist/SvAutoComplete.svelte +47 -18
  7. package/dist/SvAutoComplete.svelte.d.ts +2 -5
  8. package/dist/SvAvatar.svelte +75 -0
  9. package/dist/SvAvatar.svelte.d.ts +14 -0
  10. package/dist/SvAvatarGroup.svelte +48 -0
  11. package/dist/SvAvatarGroup.svelte.d.ts +16 -0
  12. package/dist/SvBadge.svelte +54 -0
  13. package/dist/SvBadge.svelte.d.ts +23 -0
  14. package/dist/SvBreadcrumb.svelte +88 -0
  15. package/dist/SvBreadcrumb.svelte.d.ts +23 -0
  16. package/dist/SvButtonGroup.svelte +121 -0
  17. package/dist/SvButtonGroup.svelte.d.ts +16 -0
  18. package/dist/SvCalendar.svelte +72 -9
  19. package/dist/SvCalendar.svelte.d.ts +34 -1
  20. package/dist/SvCard.svelte +71 -0
  21. package/dist/SvCard.svelte.d.ts +28 -0
  22. package/dist/SvCarousel.svelte +134 -0
  23. package/dist/SvCarousel.svelte.d.ts +28 -0
  24. package/dist/SvCheckBox.svelte +36 -21
  25. package/dist/SvCheckBox.svelte.d.ts +2 -5
  26. package/dist/SvChip.svelte +88 -0
  27. package/dist/SvChip.svelte.d.ts +31 -0
  28. package/dist/SvCircularProgress.svelte +109 -0
  29. package/dist/SvCircularProgress.svelte.d.ts +31 -0
  30. package/dist/SvColorInput.svelte +54 -27
  31. package/dist/SvColorInput.svelte.d.ts +10 -6
  32. package/dist/SvComboBox.svelte +119 -33
  33. package/dist/SvComboBox.svelte.d.ts +18 -6
  34. package/dist/SvCommand.svelte +197 -0
  35. package/dist/SvCommand.svelte.d.ts +26 -0
  36. package/dist/SvContextMenu.svelte +96 -0
  37. package/dist/SvContextMenu.svelte.d.ts +25 -0
  38. package/dist/SvCountryInput.svelte +56 -21
  39. package/dist/SvCountryInput.svelte.d.ts +9 -5
  40. package/dist/SvDateRangeInput.svelte +256 -0
  41. package/dist/SvDateRangeInput.svelte.d.ts +37 -0
  42. package/dist/SvDateTimePicker.svelte +57 -20
  43. package/dist/SvDateTimePicker.svelte.d.ts +12 -4
  44. package/dist/SvDivider.svelte +61 -0
  45. package/dist/SvDivider.svelte.d.ts +22 -0
  46. package/dist/SvDrawer.svelte +226 -0
  47. package/dist/SvDrawer.svelte.d.ts +43 -0
  48. package/dist/SvDropDownList.svelte +114 -35
  49. package/dist/SvDropDownList.svelte.d.ts +7 -6
  50. package/dist/SvDurationInput.svelte +108 -0
  51. package/dist/SvDurationInput.svelte.d.ts +15 -0
  52. package/dist/SvEmptyState.svelte +59 -0
  53. package/dist/SvEmptyState.svelte.d.ts +25 -0
  54. package/dist/SvField.svelte +85 -0
  55. package/dist/SvField.svelte.d.ts +30 -0
  56. package/dist/SvFileUpload.svelte +169 -0
  57. package/dist/SvFileUpload.svelte.d.ts +24 -0
  58. package/dist/SvForm.svelte +7 -1
  59. package/dist/SvForm.svelte.d.ts +3 -0
  60. package/dist/SvGauge.svelte +7 -1
  61. package/dist/SvGauge.svelte.d.ts +11 -0
  62. package/dist/SvGrid.controller.svelte.d.ts +6 -0
  63. package/dist/SvGrid.controller.svelte.js +64 -9
  64. package/dist/SvGrid.css +33 -0
  65. package/dist/SvGrid.svelte +116 -3
  66. package/dist/SvGrid.types.d.ts +366 -0
  67. package/dist/SvGridBoard.svelte +2281 -0
  68. package/dist/SvGridBoard.svelte.d.ts +31 -0
  69. package/dist/SvGridDropdown.svelte +2 -1
  70. package/dist/SvGridSelect.svelte +255 -0
  71. package/dist/SvGridSelect.svelte.d.ts +32 -0
  72. package/dist/SvGroupCell.svelte +109 -0
  73. package/dist/SvGroupCell.svelte.d.ts +41 -0
  74. package/dist/SvListBox.svelte +123 -36
  75. package/dist/SvListBox.svelte.d.ts +12 -8
  76. package/dist/SvMaskedInput.svelte +53 -13
  77. package/dist/SvMaskedInput.svelte.d.ts +16 -6
  78. package/dist/SvMenu.svelte +101 -0
  79. package/dist/SvMenu.svelte.d.ts +26 -0
  80. package/dist/SvMenuList.svelte +143 -0
  81. package/dist/SvMenuList.svelte.d.ts +24 -0
  82. package/dist/SvModal.svelte +220 -0
  83. package/dist/SvModal.svelte.d.ts +31 -0
  84. package/dist/SvMultiSelect.svelte +277 -0
  85. package/dist/SvMultiSelect.svelte.d.ts +31 -0
  86. package/dist/SvNavPane.svelte +314 -0
  87. package/dist/SvNavPane.svelte.d.ts +59 -0
  88. package/dist/SvNumberInput.svelte +23 -9
  89. package/dist/SvNumberInput.svelte.d.ts +2 -0
  90. package/dist/SvOtpInput.svelte +157 -0
  91. package/dist/SvOtpInput.svelte.d.ts +16 -0
  92. package/dist/SvPagination.svelte +100 -0
  93. package/dist/SvPagination.svelte.d.ts +16 -0
  94. package/dist/SvPasswordInput.svelte +42 -12
  95. package/dist/SvPasswordInput.svelte.d.ts +13 -6
  96. package/dist/SvPhoneInput.svelte +43 -11
  97. package/dist/SvPhoneInput.svelte.d.ts +10 -11
  98. package/dist/SvPopover.svelte +127 -0
  99. package/dist/SvPopover.svelte.d.ts +35 -0
  100. package/dist/SvProgress.svelte +116 -0
  101. package/dist/SvProgress.svelte.d.ts +32 -0
  102. package/dist/SvRadioGroup.svelte +40 -22
  103. package/dist/SvRadioGroup.svelte.d.ts +2 -10
  104. package/dist/SvRating.svelte +51 -30
  105. package/dist/SvRating.svelte.d.ts +10 -7
  106. package/dist/SvRichText.svelte +192 -0
  107. package/dist/SvRichText.svelte.d.ts +16 -0
  108. package/dist/SvRowGroupPanel.svelte +147 -0
  109. package/dist/SvRowGroupPanel.svelte.d.ts +17 -0
  110. package/dist/SvScrollArea.svelte +50 -0
  111. package/dist/SvScrollArea.svelte.d.ts +22 -0
  112. package/dist/SvSkeleton.svelte +76 -0
  113. package/dist/SvSkeleton.svelte.d.ts +25 -0
  114. package/dist/SvSlider.svelte +41 -9
  115. package/dist/SvSlider.svelte.d.ts +4 -4
  116. package/dist/SvSparkline.svelte +77 -0
  117. package/dist/SvSparkline.svelte.d.ts +28 -0
  118. package/dist/SvSplitter.svelte +138 -0
  119. package/dist/SvSplitter.svelte.d.ts +32 -0
  120. package/dist/SvStat.svelte +86 -0
  121. package/dist/SvStat.svelte.d.ts +30 -0
  122. package/dist/SvStepper.svelte +91 -0
  123. package/dist/SvStepper.svelte.d.ts +24 -0
  124. package/dist/SvSwitchButton.svelte +39 -24
  125. package/dist/SvSwitchButton.svelte.d.ts +2 -5
  126. package/dist/SvTabs.svelte +147 -28
  127. package/dist/SvTabs.svelte.d.ts +16 -4
  128. package/dist/SvTagsInput.svelte +59 -22
  129. package/dist/SvTagsInput.svelte.d.ts +9 -4
  130. package/dist/SvTextArea.svelte +113 -0
  131. package/dist/SvTextArea.svelte.d.ts +18 -0
  132. package/dist/SvTextInput.svelte +115 -0
  133. package/dist/SvTextInput.svelte.d.ts +20 -0
  134. package/dist/SvTimePicker.svelte +19 -5
  135. package/dist/SvTimePicker.svelte.d.ts +12 -0
  136. package/dist/SvTimeline.svelte +75 -0
  137. package/dist/SvTimeline.svelte.d.ts +24 -0
  138. package/dist/SvToaster.svelte +124 -0
  139. package/dist/SvToaster.svelte.d.ts +10 -0
  140. package/dist/SvToggleButton.svelte +37 -12
  141. package/dist/SvToggleButton.svelte.d.ts +2 -4
  142. package/dist/SvTooltip.svelte +113 -0
  143. package/dist/SvTooltip.svelte.d.ts +22 -0
  144. package/dist/SvTour.svelte +151 -0
  145. package/dist/SvTour.svelte.d.ts +25 -0
  146. package/dist/SvTree.svelte +286 -44
  147. package/dist/SvTree.svelte.d.ts +26 -9
  148. package/dist/SvTreeSelect.svelte +222 -0
  149. package/dist/SvTreeSelect.svelte.d.ts +24 -0
  150. package/dist/a11y/dismissable.d.ts +32 -0
  151. package/dist/a11y/dismissable.js +54 -0
  152. package/dist/a11y/focus-trap.d.ts +39 -0
  153. package/dist/a11y/focus-trap.js +142 -0
  154. package/dist/a11y/live-region.d.ts +8 -0
  155. package/dist/a11y/live-region.js +60 -0
  156. package/dist/a11y/scroll-lock.d.ts +4 -0
  157. package/dist/a11y/scroll-lock.js +41 -0
  158. package/dist/a11y.d.ts +3 -1
  159. package/dist/a11y.js +1 -1
  160. package/dist/avatar.d.ts +10 -0
  161. package/dist/avatar.js +22 -0
  162. package/dist/builtin-editors.d.ts +5 -0
  163. package/dist/builtin-editors.js +55 -0
  164. package/dist/cdn/svgrid.js +16021 -8234
  165. package/dist/cdn/svgrid.svelte-external.js +14542 -6764
  166. package/dist/columns.js +3 -2
  167. package/dist/core.d.ts +7 -1
  168. package/dist/countries.d.ts +12 -0
  169. package/dist/countries.js +24 -0
  170. package/dist/createAccordion.svelte.d.ts +71 -0
  171. package/dist/createAccordion.svelte.js +99 -0
  172. package/dist/createAutocomplete.svelte.d.ts +13 -4
  173. package/dist/createAutocomplete.svelte.js +11 -1
  174. package/dist/createButtonGroup.svelte.d.ts +62 -0
  175. package/dist/createButtonGroup.svelte.js +154 -0
  176. package/dist/createCalendar.svelte.d.ts +5 -0
  177. package/dist/createCalendar.svelte.js +2 -0
  178. package/dist/createCheckbox.svelte.d.ts +9 -17
  179. package/dist/createCheckbox.svelte.js +28 -1
  180. package/dist/createColorInput.svelte.d.ts +12 -22
  181. package/dist/createColorInput.svelte.js +13 -0
  182. package/dist/createCombobox.svelte.d.ts +16 -5
  183. package/dist/createCombobox.svelte.js +13 -2
  184. package/dist/createCountryInput.svelte.d.ts +14 -3
  185. package/dist/createCountryInput.svelte.js +12 -2
  186. package/dist/createDateTimePicker.svelte.d.ts +17 -2
  187. package/dist/createDateTimePicker.svelte.js +12 -2
  188. package/dist/createDropdownList.svelte.d.ts +14 -5
  189. package/dist/createDropdownList.svelte.js +50 -1
  190. package/dist/createFileUpload.svelte.d.ts +68 -0
  191. package/dist/createFileUpload.svelte.js +122 -0
  192. package/dist/createListbox.svelte.d.ts +10 -1
  193. package/dist/createListbox.svelte.js +48 -1
  194. package/dist/createMaskedInput.svelte.d.ts +11 -2
  195. package/dist/createMaskedInput.svelte.js +11 -1
  196. package/dist/createNumberInput.svelte.d.ts +1 -0
  197. package/dist/createNumberInput.svelte.js +1 -0
  198. package/dist/createPasswordInput.svelte.d.ts +19 -21
  199. package/dist/createPasswordInput.svelte.js +16 -4
  200. package/dist/createPhoneInput.svelte.d.ts +26 -7
  201. package/dist/createPhoneInput.svelte.js +24 -3
  202. package/dist/createPopoverSelect.svelte.d.ts +86 -0
  203. package/dist/createPopoverSelect.svelte.js +196 -0
  204. package/dist/createRadioGroup.svelte.d.ts +9 -0
  205. package/dist/createRadioGroup.svelte.js +11 -1
  206. package/dist/createRating.svelte.d.ts +11 -0
  207. package/dist/createRating.svelte.js +12 -1
  208. package/dist/createSlider.svelte.d.ts +2 -0
  209. package/dist/createSlider.svelte.js +16 -5
  210. package/dist/createSplitter.svelte.d.ts +67 -0
  211. package/dist/createSplitter.svelte.js +99 -0
  212. package/dist/createSwitch.svelte.d.ts +9 -16
  213. package/dist/createSwitch.svelte.js +28 -1
  214. package/dist/createTabs.svelte.d.ts +7 -0
  215. package/dist/createTabs.svelte.js +17 -2
  216. package/dist/createTagsInput.svelte.d.ts +13 -1
  217. package/dist/createTagsInput.svelte.js +12 -3
  218. package/dist/createToggle.svelte.d.ts +9 -0
  219. package/dist/createToggle.svelte.js +12 -1
  220. package/dist/createTree.svelte.d.ts +19 -0
  221. package/dist/createTree.svelte.js +108 -15
  222. package/dist/debounce.d.ts +11 -0
  223. package/dist/debounce.js +30 -0
  224. package/dist/duration.d.ts +15 -0
  225. package/dist/duration.js +51 -0
  226. package/dist/editor-contract.d.ts +62 -7
  227. package/dist/editor-contract.js +45 -5
  228. package/dist/editor-registry.d.ts +67 -0
  229. package/dist/editor-registry.js +38 -0
  230. package/dist/editors/cell-editors.d.ts +1 -1
  231. package/dist/editors/cell-editors.js +5 -0
  232. package/dist/fuzzy.d.ts +3 -0
  233. package/dist/fuzzy.js +41 -0
  234. package/dist/grid-select.d.ts +9 -0
  235. package/dist/grid-select.js +8 -0
  236. package/dist/index.d.ts +79 -6
  237. package/dist/index.js +78 -4
  238. package/dist/keyboard-handlers.js +19 -0
  239. package/dist/list-option.d.ts +36 -0
  240. package/dist/list-option.js +68 -0
  241. package/dist/otp.d.ts +16 -0
  242. package/dist/otp.js +26 -0
  243. package/dist/paginate.d.ts +20 -0
  244. package/dist/paginate.js +40 -0
  245. package/dist/popover.d.ts +15 -1
  246. package/dist/popover.js +29 -3
  247. package/dist/recurrence.d.ts +36 -0
  248. package/dist/recurrence.js +90 -0
  249. package/dist/server-data-source.d.ts +89 -0
  250. package/dist/server-data-source.js +4 -0
  251. package/dist/server-group-model.d.ts +98 -0
  252. package/dist/server-group-model.js +263 -0
  253. package/dist/toast-store.svelte.d.ts +41 -0
  254. package/dist/toast-store.svelte.js +113 -0
  255. package/dist/tree-select.d.ts +19 -0
  256. package/dist/tree-select.js +40 -0
  257. package/dist/ui-app.types.d.ts +80 -0
  258. package/dist/ui-app.types.js +7 -0
  259. package/dist/validators.d.ts +43 -0
  260. package/dist/validators.js +53 -0
  261. package/dist/virtual.d.ts +35 -0
  262. package/dist/virtual.js +34 -0
  263. package/package.json +1 -1
  264. package/src/SvAccordion.svelte +109 -0
  265. package/src/SvAccordion.test.ts +66 -0
  266. package/src/SvAlert.svelte +92 -0
  267. package/src/SvAutoComplete.svelte +47 -18
  268. package/src/SvAvatar.svelte +75 -0
  269. package/src/SvAvatarGroup.svelte +48 -0
  270. package/src/SvBadge.svelte +54 -0
  271. package/src/SvBreadcrumb.svelte +88 -0
  272. package/src/SvButtonGroup.svelte +121 -0
  273. package/src/SvButtonGroup.test.ts +72 -0
  274. package/src/SvCalendar.svelte +72 -9
  275. package/src/SvCard.svelte +71 -0
  276. package/src/SvCarousel.svelte +134 -0
  277. package/src/SvCheckBox.svelte +36 -21
  278. package/src/SvChip.svelte +88 -0
  279. package/src/SvCircularProgress.svelte +109 -0
  280. package/src/SvColorInput.svelte +54 -27
  281. package/src/SvComboBox.svelte +119 -33
  282. package/src/SvCommand.svelte +197 -0
  283. package/src/SvContextMenu.svelte +96 -0
  284. package/src/SvCountryInput.svelte +56 -21
  285. package/src/SvDateRangeInput.svelte +256 -0
  286. package/src/SvDateRangeInput.test.ts +80 -0
  287. package/src/SvDateTimePicker.svelte +57 -20
  288. package/src/SvDivider.svelte +61 -0
  289. package/src/SvDrawer.svelte +226 -0
  290. package/src/SvDrawer.test.ts +125 -0
  291. package/src/SvDropDownList.svelte +114 -35
  292. package/src/SvDurationInput.svelte +108 -0
  293. package/src/SvEmptyState.svelte +59 -0
  294. package/src/SvField.svelte +85 -0
  295. package/src/SvFileUpload.svelte +169 -0
  296. package/src/SvFileUpload.test.ts +59 -0
  297. package/src/SvForm.svelte +7 -1
  298. package/src/SvGauge.svelte +7 -1
  299. package/src/SvGrid.controller.svelte.ts +68 -9
  300. package/src/SvGrid.css +33 -0
  301. package/src/SvGrid.svelte +116 -3
  302. package/src/SvGrid.types.ts +374 -0
  303. package/src/SvGridBoard.svelte +2281 -0
  304. package/src/SvGridDropdown.svelte +2 -1
  305. package/src/SvGridSelect.svelte +255 -0
  306. package/src/SvGridSelect.test.ts +100 -0
  307. package/src/SvGroupCell.svelte +109 -0
  308. package/src/SvListBox.svelte +123 -36
  309. package/src/SvMaskedInput.svelte +53 -13
  310. package/src/SvMenu.svelte +101 -0
  311. package/src/SvMenu.test.ts +73 -0
  312. package/src/SvMenuList.svelte +143 -0
  313. package/src/SvModal.svelte +220 -0
  314. package/src/SvMultiSelect.svelte +277 -0
  315. package/src/SvMultiSelect.test.ts +167 -0
  316. package/src/SvNavPane.svelte +314 -0
  317. package/src/SvNavPane.test.ts +70 -0
  318. package/src/SvNumberInput.svelte +23 -9
  319. package/src/SvOtpInput.svelte +157 -0
  320. package/src/SvPagination.svelte +100 -0
  321. package/src/SvPasswordInput.svelte +42 -12
  322. package/src/SvPhoneInput.svelte +43 -11
  323. package/src/SvPopover.svelte +127 -0
  324. package/src/SvProgress.svelte +116 -0
  325. package/src/SvRadioGroup.svelte +40 -22
  326. package/src/SvRating.svelte +51 -30
  327. package/src/SvRichText.svelte +192 -0
  328. package/src/SvRowGroupPanel.svelte +147 -0
  329. package/src/SvScrollArea.svelte +50 -0
  330. package/src/SvSkeleton.svelte +76 -0
  331. package/src/SvSlider.svelte +41 -9
  332. package/src/SvSparkline.svelte +77 -0
  333. package/src/SvSplitter.svelte +138 -0
  334. package/src/SvSplitter.test.ts +55 -0
  335. package/src/SvStat.svelte +86 -0
  336. package/src/SvStepper.svelte +91 -0
  337. package/src/SvSwitchButton.svelte +39 -24
  338. package/src/SvTabs.svelte +147 -28
  339. package/src/SvTagsInput.svelte +59 -22
  340. package/src/SvTextArea.svelte +113 -0
  341. package/src/SvTextInput.svelte +115 -0
  342. package/src/SvTimePicker.svelte +19 -5
  343. package/src/SvTimeline.svelte +75 -0
  344. package/src/SvToaster.svelte +124 -0
  345. package/src/SvToaster.test.ts +63 -0
  346. package/src/SvToggleButton.svelte +37 -12
  347. package/src/SvTooltip.svelte +113 -0
  348. package/src/SvTour.svelte +151 -0
  349. package/src/SvTree.svelte +286 -44
  350. package/src/SvTreeSelect.svelte +222 -0
  351. package/src/SvTreeSelect.test.ts +87 -0
  352. package/src/a11y/dismissable.test.ts +95 -0
  353. package/src/a11y/dismissable.ts +94 -0
  354. package/src/a11y/focus-trap.test.ts +110 -0
  355. package/src/a11y/focus-trap.ts +134 -0
  356. package/src/a11y/live-region.test.ts +40 -0
  357. package/src/a11y/live-region.ts +65 -0
  358. package/src/a11y/scroll-lock.test.ts +38 -0
  359. package/src/a11y/scroll-lock.ts +41 -0
  360. package/src/a11y.ts +3 -1
  361. package/src/avatar.test.ts +32 -0
  362. package/src/avatar.ts +21 -0
  363. package/src/board.test.ts +927 -0
  364. package/src/builtin-editors.grid.test.ts +85 -0
  365. package/src/builtin-editors.test.ts +58 -0
  366. package/src/builtin-editors.ts +56 -0
  367. package/src/columns.ts +3 -2
  368. package/src/core.ts +10 -0
  369. package/src/countries.ts +25 -0
  370. package/src/createAccordion.svelte.ts +126 -0
  371. package/src/createAutocomplete.svelte.ts +18 -1
  372. package/src/createButtonGroup.svelte.ts +166 -0
  373. package/src/createCalendar.svelte.ts +6 -0
  374. package/src/createCheckbox.svelte.ts +23 -1
  375. package/src/createColorInput.svelte.ts +20 -0
  376. package/src/createCombobox.svelte.ts +22 -2
  377. package/src/createCountryInput.svelte.ts +21 -2
  378. package/src/createDateTimePicker.svelte.ts +23 -2
  379. package/src/createDropdownList.svelte.ts +31 -2
  380. package/src/createFileUpload.svelte.ts +144 -0
  381. package/src/createListbox.svelte.ts +35 -3
  382. package/src/createMaskedInput.svelte.ts +18 -1
  383. package/src/createNumberInput.svelte.ts +2 -0
  384. package/src/createPasswordInput.svelte.ts +31 -5
  385. package/src/createPhoneInput.svelte.ts +38 -4
  386. package/src/createPopoverSelect.svelte.ts +208 -0
  387. package/src/createRadioGroup.svelte.ts +23 -1
  388. package/src/createRating.svelte.ts +26 -1
  389. package/src/createSlider.svelte.ts +14 -3
  390. package/src/createSplitter.svelte.ts +119 -0
  391. package/src/createSwitch.svelte.ts +26 -3
  392. package/src/createTabs.svelte.ts +20 -3
  393. package/src/createTagsInput.svelte.ts +24 -3
  394. package/src/createToggle.svelte.ts +25 -2
  395. package/src/createTree.svelte.ts +104 -14
  396. package/src/debounce.test.ts +50 -0
  397. package/src/debounce.ts +41 -0
  398. package/src/duration.test.ts +41 -0
  399. package/src/duration.ts +51 -0
  400. package/src/editor-contract.ts +87 -8
  401. package/src/editor-registry.grid.test.ts +98 -0
  402. package/src/editor-registry.test.ts +86 -0
  403. package/src/editor-registry.ts +106 -0
  404. package/src/editors/cell-editors.ts +10 -1
  405. package/src/fuzzy.test.ts +40 -0
  406. package/src/fuzzy.ts +39 -0
  407. package/src/grid-select.test.ts +28 -0
  408. package/src/grid-select.ts +20 -0
  409. package/src/index.ts +150 -5
  410. package/src/keyboard-handlers.ts +20 -0
  411. package/src/list-option.ts +74 -0
  412. package/src/list-power.test.ts +71 -0
  413. package/src/otp.test.ts +28 -0
  414. package/src/otp.ts +28 -0
  415. package/src/overlays.test.ts +85 -0
  416. package/src/paginate.test.ts +41 -0
  417. package/src/paginate.ts +61 -0
  418. package/src/phone-valid.test.ts +26 -0
  419. package/src/popover.ts +31 -3
  420. package/src/progress.test.ts +55 -0
  421. package/src/recurrence.test.ts +91 -0
  422. package/src/recurrence.ts +111 -0
  423. package/src/server-data-source.ts +102 -0
  424. package/src/server-group-model.test.ts +294 -0
  425. package/src/server-group-model.ts +370 -0
  426. package/src/svgrid.responsive.test.ts +72 -0
  427. package/src/toast-store.svelte.ts +148 -0
  428. package/src/toast-store.test.ts +86 -0
  429. package/src/tree-edit.test.ts +49 -0
  430. package/src/tree-filter.test.ts +56 -0
  431. package/src/tree-select.test.ts +48 -0
  432. package/src/tree-select.ts +62 -0
  433. package/src/ui-app.test.ts +130 -0
  434. package/src/ui-app.types.ts +88 -0
  435. package/src/ui-display.test.ts +79 -0
  436. package/src/ui-inputs.test.ts +1 -1
  437. package/src/ui-status.test.ts +141 -0
  438. package/src/ui-tier1.test.ts +142 -0
  439. package/src/ui-tier2.test.ts +124 -0
  440. package/src/ui-tier3.test.ts +139 -0
  441. package/src/validators.test.ts +58 -0
  442. package/src/validators.ts +105 -0
  443. package/src/virtual.test.ts +72 -0
  444. package/src/virtual.ts +67 -0
@@ -0,0 +1,24 @@
1
+ export type { TreeSelectNode } from './ui-app.types';
2
+ /**
3
+ * SvTreeSelect - a single-select dropdown that shows an indented, collapsible
4
+ * tree in its panel (pick a node from a hierarchy). The open / position /
5
+ * dismiss / roving / keyboard / ARIA mechanics come from the shared
6
+ * `createPopoverSelect` core (with ArrowLeft/Right handled via onExtraKey for
7
+ * expand/collapse); this component adds the tree flattening + rendering. Covers
8
+ * the "cascader / tree select" pattern without depending on SvTree.
9
+ */
10
+ import type { TreeSelectNode } from './ui-app.types';
11
+ import { type SvEditorProps } from './editor-contract';
12
+ type Props = Pick<SvEditorProps, 'disabled' | 'label' | 'hint' | 'error' | 'required' | 'invalid' | 'size' | 'id' | 'name' | 'dir' | 'ariaLabel'> & {
13
+ nodes: ReadonlyArray<TreeSelectNode>;
14
+ value?: string | number | null;
15
+ onChange?: (value: string | number) => void;
16
+ onCommit?: (value: string | number) => void;
17
+ onCancel?: () => void;
18
+ placeholder?: string;
19
+ showPath?: boolean;
20
+ expandedIds?: ReadonlyArray<string | number>;
21
+ };
22
+ declare const SvTreeSelect: import("svelte").Component<Props, {}, "value">;
23
+ type SvTreeSelect = ReturnType<typeof SvTreeSelect>;
24
+ export default SvTreeSelect;
@@ -0,0 +1,32 @@
1
+ /**
2
+ * dismissable-layer - a global stack of dismissable overlays (dropdowns,
3
+ * popovers, dialogs). Escape and outside-pointer dismiss only the TOP layer, so
4
+ * a menu opened inside a dialog closes the menu first and the dialog second -
5
+ * the ordering users expect from nested overlays. One set of document listeners
6
+ * is shared by every layer instead of each component wiring its own.
7
+ */
8
+ type Reason = 'escape' | 'outside';
9
+ /** One element, several elements, or a getter of either. A pointerdown counts
10
+ * as "inside" when it lands in ANY of them (e.g. a popover's panel AND its
11
+ * trigger, so clicking the trigger doesn't immediately re-dismiss). */
12
+ export type DismissTarget = HTMLElement | null | ReadonlyArray<HTMLElement | null>;
13
+ export type DismissableOptions = {
14
+ /** The panel element(s); a pointerdown outside ALL of them dismisses the layer.
15
+ * Pass multiple (e.g. panel + trigger) so clicking the trigger doesn't
16
+ * immediately re-dismiss what it just opened. */
17
+ element: () => DismissTarget;
18
+ onDismiss: (reason: Reason) => void;
19
+ /** Dismiss on Escape when topmost. Default true. */
20
+ closeOnEscape?: boolean;
21
+ /** Dismiss on outside pointerdown when topmost. Default true. */
22
+ closeOnOutside?: boolean;
23
+ };
24
+ export type DismissableLayer = {
25
+ activate: () => void;
26
+ release: () => void;
27
+ };
28
+ /** Register a dismissable layer. Inert until `activate()`. */
29
+ export declare function createDismissableLayer(options: DismissableOptions): DismissableLayer;
30
+ /** Test/introspection helper: current number of active layers. */
31
+ export declare function dismissableDepth(): number;
32
+ export {};
@@ -0,0 +1,54 @@
1
+ function containsTarget(target, node) {
2
+ if (!node)
3
+ return false;
4
+ const els = Array.isArray(target) ? target : [target];
5
+ return els.some((el) => el != null && el.contains(node));
6
+ }
7
+ const stack = [];
8
+ let wired = false;
9
+ function ensureWired() {
10
+ if (wired || typeof document === 'undefined')
11
+ return;
12
+ wired = true;
13
+ document.addEventListener('keydown', (e) => {
14
+ if (e.key !== 'Escape')
15
+ return;
16
+ const top = stack[stack.length - 1];
17
+ if (top?.closeOnEscape) {
18
+ e.stopPropagation();
19
+ top.onDismiss('escape');
20
+ }
21
+ }, true);
22
+ document.addEventListener('pointerdown', (e) => {
23
+ const top = stack[stack.length - 1];
24
+ if (!top?.closeOnOutside)
25
+ return;
26
+ if (!containsTarget(top.element(), e.target))
27
+ top.onDismiss('outside');
28
+ }, true);
29
+ }
30
+ /** Register a dismissable layer. Inert until `activate()`. */
31
+ export function createDismissableLayer(options) {
32
+ const layer = {
33
+ element: options.element,
34
+ onDismiss: options.onDismiss,
35
+ closeOnEscape: options.closeOnEscape ?? true,
36
+ closeOnOutside: options.closeOnOutside ?? true,
37
+ };
38
+ return {
39
+ activate() {
40
+ ensureWired();
41
+ if (!stack.includes(layer))
42
+ stack.push(layer);
43
+ },
44
+ release() {
45
+ const i = stack.indexOf(layer);
46
+ if (i >= 0)
47
+ stack.splice(i, 1);
48
+ },
49
+ };
50
+ }
51
+ /** Test/introspection helper: current number of active layers. */
52
+ export function dismissableDepth() {
53
+ return stack.length;
54
+ }
@@ -0,0 +1,39 @@
1
+ /**
2
+ * focus-trap - keep Tab / Shift+Tab focus inside a container while it is active,
3
+ * move focus in on activate, and restore it on release. Shared by SvModal,
4
+ * SvDrawer, SvMenu and any dialog-like overlay so the WAI-ARIA dialog focus
5
+ * behaviour lives in ONE place instead of being re-hand-rolled per component.
6
+ *
7
+ * Framework-free (DOM only): call `createFocusTrap(el).activate()` from a
8
+ * component `$effect` and `release()` from its cleanup.
9
+ *
10
+ * ```ts
11
+ * $effect(() => {
12
+ * if (!open || !panel) return
13
+ * const trap = createFocusTrap(panel)
14
+ * trap.activate()
15
+ * return () => trap.release()
16
+ * })
17
+ * ```
18
+ */
19
+ /** Selector for elements that can, in principle, hold keyboard focus. */
20
+ export declare const FOCUSABLE_SELECTOR: string;
21
+ /** Visible, Tab-focusable descendants of `container`, in DOM order. Elements
22
+ * with `tabindex="-1"` are excluded (script-focusable, not Tab-reachable). */
23
+ export declare function getFocusable(container: HTMLElement): HTMLElement[];
24
+ export type FocusTrapOptions = {
25
+ /** Where focus goes on activate: the first focusable (default), the container
26
+ * itself, a specific element, or a getter resolved at activate time. */
27
+ initialFocus?: 'first' | 'container' | HTMLElement | (() => HTMLElement | null);
28
+ /** Restore focus to the previously-focused element on release. Default true. */
29
+ returnFocus?: boolean;
30
+ /** Called on Escape while active. Dismissal is usually owned by the layer
31
+ * manager, so most consumers leave this unset. */
32
+ onEscape?: (e: KeyboardEvent) => void;
33
+ };
34
+ export type FocusTrap = {
35
+ activate: () => void;
36
+ release: () => void;
37
+ };
38
+ /** Create a focus trap for `container`. Inert until `activate()`. */
39
+ export declare function createFocusTrap(container: HTMLElement, options?: FocusTrapOptions): FocusTrap;
@@ -0,0 +1,142 @@
1
+ /**
2
+ * focus-trap - keep Tab / Shift+Tab focus inside a container while it is active,
3
+ * move focus in on activate, and restore it on release. Shared by SvModal,
4
+ * SvDrawer, SvMenu and any dialog-like overlay so the WAI-ARIA dialog focus
5
+ * behaviour lives in ONE place instead of being re-hand-rolled per component.
6
+ *
7
+ * Framework-free (DOM only): call `createFocusTrap(el).activate()` from a
8
+ * component `$effect` and `release()` from its cleanup.
9
+ *
10
+ * ```ts
11
+ * $effect(() => {
12
+ * if (!open || !panel) return
13
+ * const trap = createFocusTrap(panel)
14
+ * trap.activate()
15
+ * return () => trap.release()
16
+ * })
17
+ * ```
18
+ */
19
+ /** Selector for elements that can, in principle, hold keyboard focus. */
20
+ export const FOCUSABLE_SELECTOR = [
21
+ 'a[href]',
22
+ 'area[href]',
23
+ 'button:not([disabled])',
24
+ 'input:not([disabled])',
25
+ 'select:not([disabled])',
26
+ 'textarea:not([disabled])',
27
+ 'iframe',
28
+ 'audio[controls]',
29
+ 'video[controls]',
30
+ '[contenteditable]:not([contenteditable="false"])',
31
+ '[tabindex]',
32
+ ].join(',');
33
+ /**
34
+ * Whether `el` is visible enough to be Tab-focusable. Detects the common,
35
+ * layout-independent ways of hiding (disabled / hidden attr / aria-hidden /
36
+ * inline display:none|visibility:hidden) so the check is deterministic in both
37
+ * real browsers and jsdom. Class-based `display:none` in a real browser is
38
+ * additionally caught via client rects when layout is available.
39
+ */
40
+ function isVisible(el) {
41
+ if (el.hasAttribute('disabled'))
42
+ return false;
43
+ if (el.getAttribute('aria-hidden') === 'true')
44
+ return false;
45
+ if (el.hidden || el.closest('[hidden]'))
46
+ return false;
47
+ const style = el.style;
48
+ if (style.display === 'none' || style.visibility === 'hidden')
49
+ return false;
50
+ // Only trust layout when the environment actually lays out (real browsers).
51
+ if (typeof el.getClientRects === 'function') {
52
+ const rects = el.getClientRects();
53
+ // jsdom reports 0 rects for everything, so 0 alone is not "hidden" there;
54
+ // treat 0 rects as hidden only when SOME element in the doc has layout.
55
+ if (rects.length === 0 && document.body.getClientRects().length > 0)
56
+ return false;
57
+ }
58
+ return true;
59
+ }
60
+ /** Visible, Tab-focusable descendants of `container`, in DOM order. Elements
61
+ * with `tabindex="-1"` are excluded (script-focusable, not Tab-reachable). */
62
+ export function getFocusable(container) {
63
+ const nodes = Array.from(container.querySelectorAll(FOCUSABLE_SELECTOR));
64
+ return nodes.filter((el) => {
65
+ const ti = el.getAttribute('tabindex');
66
+ if (ti !== null && Number(ti) < 0)
67
+ return false;
68
+ return isVisible(el);
69
+ });
70
+ }
71
+ /** Create a focus trap for `container`. Inert until `activate()`. */
72
+ export function createFocusTrap(container, options = {}) {
73
+ const { initialFocus = 'first', returnFocus = true } = options;
74
+ let previouslyFocused = null;
75
+ let active = false;
76
+ function resolveInitial() {
77
+ const f = initialFocus;
78
+ if (f === 'container')
79
+ return container;
80
+ if (f === 'first')
81
+ return getFocusable(container)[0] ?? container;
82
+ if (typeof f === 'function')
83
+ return f();
84
+ return f;
85
+ }
86
+ function onKeydown(e) {
87
+ if (!active)
88
+ return;
89
+ if (e.key === 'Escape' && options.onEscape) {
90
+ options.onEscape(e);
91
+ return;
92
+ }
93
+ if (e.key !== 'Tab')
94
+ return;
95
+ const f = getFocusable(container);
96
+ if (!f.length) {
97
+ e.preventDefault();
98
+ container.focus();
99
+ return;
100
+ }
101
+ const first = f[0];
102
+ const last = f[f.length - 1];
103
+ const activeEl = document.activeElement;
104
+ // Focus escaped the container entirely (programmatic blur, etc.): pull back.
105
+ if (!container.contains(activeEl)) {
106
+ e.preventDefault();
107
+ first.focus();
108
+ return;
109
+ }
110
+ if (e.shiftKey && activeEl === first) {
111
+ e.preventDefault();
112
+ last.focus();
113
+ }
114
+ else if (!e.shiftKey && activeEl === last) {
115
+ e.preventDefault();
116
+ first.focus();
117
+ }
118
+ }
119
+ function activate() {
120
+ if (active)
121
+ return;
122
+ active = true;
123
+ previouslyFocused = document.activeElement;
124
+ // Guarantee the container is a focus fallback even without focusable children.
125
+ if (!container.hasAttribute('tabindex'))
126
+ container.setAttribute('tabindex', '-1');
127
+ document.addEventListener('keydown', onKeydown, true);
128
+ // Focus on the next microtask so a just-opened panel is in the DOM first.
129
+ queueMicrotask(() => { if (active)
130
+ resolveInitial()?.focus(); });
131
+ }
132
+ function release() {
133
+ if (!active)
134
+ return;
135
+ active = false;
136
+ document.removeEventListener('keydown', onKeydown, true);
137
+ if (returnFocus)
138
+ previouslyFocused?.focus?.();
139
+ previouslyFocused = null;
140
+ }
141
+ return { activate, release };
142
+ }
@@ -0,0 +1,8 @@
1
+ export type AnnounceOptions = {
2
+ /** Interrupt the user immediately (role="alert"). Default polite. */
3
+ assertive?: boolean;
4
+ };
5
+ /** Announce `message` to screen readers. Empty messages are ignored. */
6
+ export declare function announce(message: string, options?: AnnounceOptions): void;
7
+ /** Test helper: tear the shared live regions down. */
8
+ export declare function _resetLiveRegions(): void;
@@ -0,0 +1,60 @@
1
+ /**
2
+ * live-region - a single shared pair of visually-hidden ARIA live regions
3
+ * (polite + assertive) appended to <body> on first use, so any component can
4
+ * push a transient message to screen readers via `announce()` without each one
5
+ * shipping its own live region. Used for things like "3 rows selected",
6
+ * "copied", "no results".
7
+ */
8
+ let politeEl = null;
9
+ let assertiveEl = null;
10
+ function make(mode) {
11
+ const el = document.createElement('div');
12
+ el.setAttribute('aria-live', mode);
13
+ el.setAttribute('aria-atomic', 'true');
14
+ el.setAttribute('role', mode === 'assertive' ? 'alert' : 'status');
15
+ // Visually hidden, but still exposed to assistive technology.
16
+ Object.assign(el.style, {
17
+ position: 'absolute',
18
+ width: '1px',
19
+ height: '1px',
20
+ margin: '-1px',
21
+ border: '0',
22
+ padding: '0',
23
+ overflow: 'hidden',
24
+ clip: 'rect(0 0 0 0)',
25
+ clipPath: 'inset(50%)',
26
+ whiteSpace: 'nowrap',
27
+ });
28
+ document.body.appendChild(el);
29
+ return el;
30
+ }
31
+ /** Announce `message` to screen readers. Empty messages are ignored. */
32
+ export function announce(message, options = {}) {
33
+ if (typeof document === 'undefined' || !message)
34
+ return;
35
+ const assertive = options.assertive ?? false;
36
+ let el = assertive ? assertiveEl : politeEl;
37
+ // Recreate when missing OR when a prior DOM reset detached the cached node,
38
+ // so a stale reference can never swallow an announcement silently.
39
+ if (!el || !el.isConnected) {
40
+ el = make(assertive ? 'assertive' : 'polite');
41
+ if (assertive)
42
+ assertiveEl = el;
43
+ else
44
+ politeEl = el;
45
+ }
46
+ // Clear, then set on the next microtask, so an identical consecutive message
47
+ // still triggers a fresh announcement.
48
+ el.textContent = '';
49
+ const target = el;
50
+ queueMicrotask(() => {
51
+ target.textContent = message;
52
+ });
53
+ }
54
+ /** Test helper: tear the shared live regions down. */
55
+ export function _resetLiveRegions() {
56
+ politeEl?.remove();
57
+ assertiveEl?.remove();
58
+ politeEl = null;
59
+ assertiveEl = null;
60
+ }
@@ -0,0 +1,4 @@
1
+ /** Lock document scroll. Returns an idempotent unlock function. */
2
+ export declare function lockScroll(): () => void;
3
+ /** Test helper: current lock depth. */
4
+ export declare function scrollLockDepth(): number;
@@ -0,0 +1,41 @@
1
+ /**
2
+ * scroll-lock - stop the document scrolling behind an overlay, with REF-COUNTING
3
+ * so nested overlays (a dialog that opens a menu) never fight over
4
+ * `body.style.overflow`. The first lock records the original values; the last
5
+ * unlock restores them. Also pads for the vanishing scrollbar so the page
6
+ * doesn't shift when the lock engages.
7
+ */
8
+ let locks = 0;
9
+ let previousOverflow = '';
10
+ let previousPaddingRight = '';
11
+ /** Lock document scroll. Returns an idempotent unlock function. */
12
+ export function lockScroll() {
13
+ if (typeof document === 'undefined')
14
+ return () => { };
15
+ const body = document.body;
16
+ if (locks === 0) {
17
+ previousOverflow = body.style.overflow;
18
+ previousPaddingRight = body.style.paddingRight;
19
+ // Compensate for the scrollbar width so fixed/full-width layout stays put.
20
+ const sbw = window.innerWidth - document.documentElement.clientWidth;
21
+ if (sbw > 0) {
22
+ const current = parseFloat(getComputedStyle(body).paddingRight) || 0;
23
+ body.style.paddingRight = `${current + sbw}px`;
24
+ }
25
+ body.style.overflow = 'hidden';
26
+ }
27
+ locks++;
28
+ let released = false;
29
+ return () => {
30
+ if (released)
31
+ return;
32
+ released = true;
33
+ locks = Math.max(0, locks - 1);
34
+ if (locks === 0) {
35
+ body.style.overflow = previousOverflow;
36
+ body.style.paddingRight = previousPaddingRight;
37
+ }
38
+ };
39
+ }
40
+ /** Test helper: current lock depth. */
41
+ export function scrollLockDepth() { return locks; }
package/dist/a11y.d.ts CHANGED
@@ -13,11 +13,13 @@ export declare function getGridRootA11yProps(input?: {
13
13
  activeDescendantId?: string | null;
14
14
  rowCount?: number;
15
15
  colCount?: number;
16
+ /** Use the treegrid role (expandable server group / tree rows are present). */
17
+ treegrid?: boolean;
16
18
  }): {
17
19
  readonly 'aria-colcount'?: number | undefined;
18
20
  readonly 'aria-rowcount'?: number | undefined;
19
21
  readonly 'aria-activedescendant'?: string | undefined;
20
- readonly role: "grid";
22
+ readonly role: "grid" | "treegrid";
21
23
  readonly tabindex: 0;
22
24
  };
23
25
  export declare function getGridHeaderA11yProps(input?: GridColumnA11yInput): {
package/dist/a11y.js CHANGED
@@ -1,6 +1,6 @@
1
1
  export function getGridRootA11yProps(input = {}) {
2
2
  return {
3
- role: 'grid',
3
+ role: input.treegrid ? 'treegrid' : 'grid',
4
4
  tabindex: 0,
5
5
  ...(input.activeDescendantId
6
6
  ? { 'aria-activedescendant': input.activeDescendantId }
@@ -0,0 +1,10 @@
1
+ /**
2
+ * avatar - pure helpers behind <SvAvatar>: derive up-to-two-letter initials from
3
+ * a name, and a stable hue from a string so the same name always gets the same
4
+ * fallback colour. Framework-free + pure so they are unit-tested directly.
5
+ */
6
+ /** Up to two uppercase initials for `name` (first + last word, or first two
7
+ * letters of a single word). Empty string for blank input. */
8
+ export declare function avatarInitials(name: string): string;
9
+ /** Deterministic hue (0-359) derived from a string, for the fallback tint. */
10
+ export declare function avatarColorHue(name: string): number;
package/dist/avatar.js ADDED
@@ -0,0 +1,22 @@
1
+ /**
2
+ * avatar - pure helpers behind <SvAvatar>: derive up-to-two-letter initials from
3
+ * a name, and a stable hue from a string so the same name always gets the same
4
+ * fallback colour. Framework-free + pure so they are unit-tested directly.
5
+ */
6
+ /** Up to two uppercase initials for `name` (first + last word, or first two
7
+ * letters of a single word). Empty string for blank input. */
8
+ export function avatarInitials(name) {
9
+ const parts = name.trim().split(/\s+/).filter(Boolean);
10
+ if (!parts.length)
11
+ return '';
12
+ if (parts.length === 1)
13
+ return parts[0].slice(0, 2).toUpperCase();
14
+ return (parts[0][0] + parts[parts.length - 1][0]).toUpperCase();
15
+ }
16
+ /** Deterministic hue (0-359) derived from a string, for the fallback tint. */
17
+ export function avatarColorHue(name) {
18
+ let h = 0;
19
+ for (let i = 0; i < name.length; i++)
20
+ h = (h * 31 + name.charCodeAt(i)) % 360;
21
+ return h;
22
+ }
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Register the config-free UI-kit editors (`otp`, `duration`) as grid cell
3
+ * editors. Idempotent. Returns the list of type names it registered.
4
+ */
5
+ export declare function registerBuiltinEditors(): string[];
@@ -0,0 +1,55 @@
1
+ /**
2
+ * builtin-editors - opt-in registration of the configuration-free UI-kit editors
3
+ * as grid cell editors, so a column can use `editorType: 'otp'` or
4
+ * `editorType: 'duration'` out of the box. Call `registerBuiltinEditors()` once
5
+ * near your app root.
6
+ *
7
+ * It is opt-in (rather than automatic) so the editor components tree-shake away
8
+ * when you don't use them. Option / structured editors (SvMultiSelect,
9
+ * SvTreeSelect, SvGridSelect) need their `options` / `nodes` / `columns`, so
10
+ * register those yourself with a props mapping:
11
+ *
12
+ * ```ts
13
+ * import { registerCellEditor, SvMultiSelect } from '@svgrid/grid'
14
+ * registerCellEditor('tags', {
15
+ * component: SvMultiSelect,
16
+ * props: (ctx) => ({
17
+ * options: TAG_OPTIONS,
18
+ * value: ctx.value,
19
+ * onChange: ctx.onChange, // update the in-progress value
20
+ * onCommit: () => ctx.onCommit(),// e.g. the panel's Done button
21
+ * }),
22
+ * })
23
+ * ```
24
+ */
25
+ import { registerCellEditor } from './editor-registry';
26
+ import SvOtpInput from './SvOtpInput.svelte';
27
+ import SvDurationInput from './SvDurationInput.svelte';
28
+ /**
29
+ * Register the config-free UI-kit editors (`otp`, `duration`) as grid cell
30
+ * editors. Idempotent. Returns the list of type names it registered.
31
+ */
32
+ export function registerBuiltinEditors() {
33
+ registerCellEditor('otp', {
34
+ component: SvOtpInput,
35
+ autoOpen: false,
36
+ props: (ctx) => ({
37
+ value: (ctx.value ?? ''),
38
+ autofocus: true,
39
+ onChange: (v) => ctx.onChange(v),
40
+ // The code is complete -> commit + stop editing.
41
+ onComplete: (v) => ctx.onCommit(v),
42
+ }),
43
+ });
44
+ registerCellEditor('duration', {
45
+ component: SvDurationInput,
46
+ props: (ctx) => ({
47
+ value: (ctx.value ?? null),
48
+ autofocus: true,
49
+ onChange: (v) => ctx.onChange(v),
50
+ onCommit: (v) => ctx.onCommit(v),
51
+ onCancel: () => ctx.onCancel(),
52
+ }),
53
+ });
54
+ return ['otp', 'duration'];
55
+ }