@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,134 @@
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
+
20
+ /** Selector for elements that can, in principle, hold keyboard focus. */
21
+ export const FOCUSABLE_SELECTOR = [
22
+ 'a[href]',
23
+ 'area[href]',
24
+ 'button:not([disabled])',
25
+ 'input:not([disabled])',
26
+ 'select:not([disabled])',
27
+ 'textarea:not([disabled])',
28
+ 'iframe',
29
+ 'audio[controls]',
30
+ 'video[controls]',
31
+ '[contenteditable]:not([contenteditable="false"])',
32
+ '[tabindex]',
33
+ ].join(',')
34
+
35
+ /**
36
+ * Whether `el` is visible enough to be Tab-focusable. Detects the common,
37
+ * layout-independent ways of hiding (disabled / hidden attr / aria-hidden /
38
+ * inline display:none|visibility:hidden) so the check is deterministic in both
39
+ * real browsers and jsdom. Class-based `display:none` in a real browser is
40
+ * additionally caught via client rects when layout is available.
41
+ */
42
+ function isVisible(el: HTMLElement): boolean {
43
+ if (el.hasAttribute('disabled')) return false
44
+ if (el.getAttribute('aria-hidden') === 'true') return false
45
+ if (el.hidden || el.closest('[hidden]')) return false
46
+ const style = el.style
47
+ if (style.display === 'none' || style.visibility === 'hidden') return false
48
+ // Only trust layout when the environment actually lays out (real browsers).
49
+ if (typeof el.getClientRects === 'function') {
50
+ const rects = el.getClientRects()
51
+ // jsdom reports 0 rects for everything, so 0 alone is not "hidden" there;
52
+ // treat 0 rects as hidden only when SOME element in the doc has layout.
53
+ if (rects.length === 0 && document.body.getClientRects().length > 0) return false
54
+ }
55
+ return true
56
+ }
57
+
58
+ /** Visible, Tab-focusable descendants of `container`, in DOM order. Elements
59
+ * with `tabindex="-1"` are excluded (script-focusable, not Tab-reachable). */
60
+ export function getFocusable(container: HTMLElement): HTMLElement[] {
61
+ const nodes = Array.from(container.querySelectorAll<HTMLElement>(FOCUSABLE_SELECTOR))
62
+ return nodes.filter((el) => {
63
+ const ti = el.getAttribute('tabindex')
64
+ if (ti !== null && Number(ti) < 0) return false
65
+ return isVisible(el)
66
+ })
67
+ }
68
+
69
+ export type FocusTrapOptions = {
70
+ /** Where focus goes on activate: the first focusable (default), the container
71
+ * itself, a specific element, or a getter resolved at activate time. */
72
+ initialFocus?: 'first' | 'container' | HTMLElement | (() => HTMLElement | null)
73
+ /** Restore focus to the previously-focused element on release. Default true. */
74
+ returnFocus?: boolean
75
+ /** Called on Escape while active. Dismissal is usually owned by the layer
76
+ * manager, so most consumers leave this unset. */
77
+ onEscape?: (e: KeyboardEvent) => void
78
+ }
79
+
80
+ export type FocusTrap = { activate: () => void; release: () => void }
81
+
82
+ /** Create a focus trap for `container`. Inert until `activate()`. */
83
+ export function createFocusTrap(
84
+ container: HTMLElement,
85
+ options: FocusTrapOptions = {},
86
+ ): FocusTrap {
87
+ const { initialFocus = 'first', returnFocus = true } = options
88
+ let previouslyFocused: HTMLElement | null = null
89
+ let active = false
90
+
91
+ function resolveInitial(): HTMLElement | null {
92
+ const f = initialFocus
93
+ if (f === 'container') return container
94
+ if (f === 'first') return getFocusable(container)[0] ?? container
95
+ if (typeof f === 'function') return f()
96
+ return f
97
+ }
98
+
99
+ function onKeydown(e: KeyboardEvent) {
100
+ if (!active) return
101
+ if (e.key === 'Escape' && options.onEscape) { options.onEscape(e); return }
102
+ if (e.key !== 'Tab') return
103
+ const f = getFocusable(container)
104
+ if (!f.length) { e.preventDefault(); container.focus(); return }
105
+ const first = f[0]!
106
+ const last = f[f.length - 1]!
107
+ const activeEl = document.activeElement
108
+ // Focus escaped the container entirely (programmatic blur, etc.): pull back.
109
+ if (!container.contains(activeEl)) { e.preventDefault(); first.focus(); return }
110
+ if (e.shiftKey && activeEl === first) { e.preventDefault(); last.focus() }
111
+ else if (!e.shiftKey && activeEl === last) { e.preventDefault(); first.focus() }
112
+ }
113
+
114
+ function activate() {
115
+ if (active) return
116
+ active = true
117
+ previouslyFocused = document.activeElement as HTMLElement | null
118
+ // Guarantee the container is a focus fallback even without focusable children.
119
+ if (!container.hasAttribute('tabindex')) container.setAttribute('tabindex', '-1')
120
+ document.addEventListener('keydown', onKeydown, true)
121
+ // Focus on the next microtask so a just-opened panel is in the DOM first.
122
+ queueMicrotask(() => { if (active) resolveInitial()?.focus() })
123
+ }
124
+
125
+ function release() {
126
+ if (!active) return
127
+ active = false
128
+ document.removeEventListener('keydown', onKeydown, true)
129
+ if (returnFocus) previouslyFocused?.focus?.()
130
+ previouslyFocused = null
131
+ }
132
+
133
+ return { activate, release }
134
+ }
@@ -0,0 +1,40 @@
1
+ import { afterEach, describe, expect, it } from 'vitest'
2
+ import { _resetLiveRegions, announce } from './live-region'
3
+
4
+ afterEach(() => {
5
+ _resetLiveRegions()
6
+ })
7
+
8
+ describe('announce', () => {
9
+ it('creates a polite status region and sets its text', async () => {
10
+ announce('3 rows selected')
11
+ const region = document.querySelector('[aria-live="polite"]')
12
+ expect(region).not.toBeNull()
13
+ expect(region!.getAttribute('role')).toBe('status')
14
+ await Promise.resolve()
15
+ expect(region!.textContent).toBe('3 rows selected')
16
+ })
17
+
18
+ it('creates a separate assertive alert region', async () => {
19
+ announce('error!', { assertive: true })
20
+ const region = document.querySelector('[aria-live="assertive"]')
21
+ expect(region).not.toBeNull()
22
+ expect(region!.getAttribute('role')).toBe('alert')
23
+ await Promise.resolve()
24
+ expect(region!.textContent).toBe('error!')
25
+ })
26
+
27
+ it('reuses the same region across calls', async () => {
28
+ announce('first')
29
+ announce('second')
30
+ const regions = document.querySelectorAll('[aria-live="polite"]')
31
+ expect(regions).toHaveLength(1)
32
+ await Promise.resolve()
33
+ expect(regions[0]!.textContent).toBe('second')
34
+ })
35
+
36
+ it('ignores empty messages', () => {
37
+ announce('')
38
+ expect(document.querySelector('[aria-live]')).toBeNull()
39
+ })
40
+ })
@@ -0,0 +1,65 @@
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: HTMLElement | null = null
9
+ let assertiveEl: HTMLElement | null = null
10
+
11
+ function make(mode: 'polite' | 'assertive'): HTMLElement {
12
+ const el = document.createElement('div')
13
+ el.setAttribute('aria-live', mode)
14
+ el.setAttribute('aria-atomic', 'true')
15
+ el.setAttribute('role', mode === 'assertive' ? 'alert' : 'status')
16
+ // Visually hidden, but still exposed to assistive technology.
17
+ Object.assign(el.style, {
18
+ position: 'absolute',
19
+ width: '1px',
20
+ height: '1px',
21
+ margin: '-1px',
22
+ border: '0',
23
+ padding: '0',
24
+ overflow: 'hidden',
25
+ clip: 'rect(0 0 0 0)',
26
+ clipPath: 'inset(50%)',
27
+ whiteSpace: 'nowrap',
28
+ })
29
+ document.body.appendChild(el)
30
+ return el
31
+ }
32
+
33
+ export type AnnounceOptions = {
34
+ /** Interrupt the user immediately (role="alert"). Default polite. */
35
+ assertive?: boolean
36
+ }
37
+
38
+ /** Announce `message` to screen readers. Empty messages are ignored. */
39
+ export function announce(message: string, options: AnnounceOptions = {}): void {
40
+ if (typeof document === 'undefined' || !message) return
41
+ const assertive = options.assertive ?? false
42
+ let el = assertive ? assertiveEl : politeEl
43
+ // Recreate when missing OR when a prior DOM reset detached the cached node,
44
+ // so a stale reference can never swallow an announcement silently.
45
+ if (!el || !el.isConnected) {
46
+ el = make(assertive ? 'assertive' : 'polite')
47
+ if (assertive) assertiveEl = el
48
+ else politeEl = el
49
+ }
50
+ // Clear, then set on the next microtask, so an identical consecutive message
51
+ // still triggers a fresh announcement.
52
+ el.textContent = ''
53
+ const target = el
54
+ queueMicrotask(() => {
55
+ target.textContent = message
56
+ })
57
+ }
58
+
59
+ /** Test helper: tear the shared live regions down. */
60
+ export function _resetLiveRegions(): void {
61
+ politeEl?.remove()
62
+ assertiveEl?.remove()
63
+ politeEl = null
64
+ assertiveEl = null
65
+ }
@@ -0,0 +1,38 @@
1
+ import { afterEach, describe, expect, it } from 'vitest'
2
+ import { lockScroll, scrollLockDepth } from './scroll-lock'
3
+
4
+ afterEach(() => {
5
+ // Each test balances its own locks; just reset the inline styles.
6
+ document.body.style.overflow = ''
7
+ document.body.style.paddingRight = ''
8
+ })
9
+
10
+ describe('lockScroll', () => {
11
+ it('hides body overflow while locked and restores it on unlock', () => {
12
+ document.body.style.overflow = 'auto'
13
+ const unlock = lockScroll()
14
+ expect(document.body.style.overflow).toBe('hidden')
15
+ unlock()
16
+ expect(document.body.style.overflow).toBe('auto')
17
+ })
18
+
19
+ it('ref-counts nested locks: only the last unlock restores', () => {
20
+ document.body.style.overflow = 'scroll'
21
+ const a = lockScroll()
22
+ const b = lockScroll()
23
+ expect(scrollLockDepth()).toBe(2)
24
+ a()
25
+ expect(document.body.style.overflow).toBe('hidden') // still locked by b
26
+ b()
27
+ expect(document.body.style.overflow).toBe('scroll')
28
+ })
29
+
30
+ it('unlock is idempotent', () => {
31
+ document.body.style.overflow = 'auto'
32
+ const unlock = lockScroll()
33
+ unlock()
34
+ unlock()
35
+ expect(scrollLockDepth()).toBe(0)
36
+ expect(document.body.style.overflow).toBe('auto')
37
+ })
38
+ })
@@ -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
+
12
+ /** Lock document scroll. Returns an idempotent unlock function. */
13
+ export function lockScroll(): () => void {
14
+ if (typeof document === 'undefined') 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) return
31
+ released = true
32
+ locks = Math.max(0, locks - 1)
33
+ if (locks === 0) {
34
+ body.style.overflow = previousOverflow
35
+ body.style.paddingRight = previousPaddingRight
36
+ }
37
+ }
38
+ }
39
+
40
+ /** Test helper: current lock depth. */
41
+ export function scrollLockDepth(): number { return locks }
package/src/a11y.ts CHANGED
@@ -16,9 +16,11 @@ export function getGridRootA11yProps(input: {
16
16
  activeDescendantId?: string | null
17
17
  rowCount?: number
18
18
  colCount?: number
19
+ /** Use the treegrid role (expandable server group / tree rows are present). */
20
+ treegrid?: boolean
19
21
  } = {}) {
20
22
  return {
21
- role: 'grid',
23
+ role: input.treegrid ? 'treegrid' : 'grid',
22
24
  tabindex: 0,
23
25
  ...(input.activeDescendantId
24
26
  ? { 'aria-activedescendant': input.activeDescendantId }
@@ -0,0 +1,32 @@
1
+ import { describe, expect, it } from 'vitest'
2
+ import { avatarInitials, avatarColorHue } from './avatar'
3
+
4
+ describe('avatarInitials', () => {
5
+ it('uses first + last word initials', () => {
6
+ expect(avatarInitials('Ada Lovelace')).toBe('AL')
7
+ expect(avatarInitials('a b c')).toBe('AC')
8
+ })
9
+
10
+ it('uses the first two letters of a single word', () => {
11
+ expect(avatarInitials('Grace')).toBe('GR')
12
+ })
13
+
14
+ it('returns empty for blank input', () => {
15
+ expect(avatarInitials(' ')).toBe('')
16
+ expect(avatarInitials('')).toBe('')
17
+ })
18
+ })
19
+
20
+ describe('avatarColorHue', () => {
21
+ it('is deterministic and within 0-359', () => {
22
+ const a = avatarColorHue('Ada Lovelace')
23
+ const b = avatarColorHue('Ada Lovelace')
24
+ expect(a).toBe(b)
25
+ expect(a).toBeGreaterThanOrEqual(0)
26
+ expect(a).toBeLessThan(360)
27
+ })
28
+
29
+ it('differs for different names (usually)', () => {
30
+ expect(avatarColorHue('Alice')).not.toBe(avatarColorHue('Zeno'))
31
+ })
32
+ })
package/src/avatar.ts ADDED
@@ -0,0 +1,21 @@
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
+
7
+ /** Up to two uppercase initials for `name` (first + last word, or first two
8
+ * letters of a single word). Empty string for blank input. */
9
+ export function avatarInitials(name: string): string {
10
+ const parts = name.trim().split(/\s+/).filter(Boolean)
11
+ if (!parts.length) return ''
12
+ if (parts.length === 1) return parts[0]!.slice(0, 2).toUpperCase()
13
+ return (parts[0]![0]! + parts[parts.length - 1]![0]!).toUpperCase()
14
+ }
15
+
16
+ /** Deterministic hue (0-359) derived from a string, for the fallback tint. */
17
+ export function avatarColorHue(name: string): number {
18
+ let h = 0
19
+ for (let i = 0; i < name.length; i++) h = (h * 31 + name.charCodeAt(i)) % 360
20
+ return h
21
+ }