@svgrid/grid 1.2.33 → 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
@@ -0,0 +1,32 @@
1
+ /**
2
+ * SvProgress - a linear progress bar (WAI-ARIA `progressbar`). Determinate
3
+ * (value/max) or `indeterminate` (animated), with color intents, sizes, an
4
+ * optional label and an optional secondary `buffer` track. Theme-driven via
5
+ * `--sg-*`; respects prefers-reduced-motion. Parity: Smart progress bar.
6
+ *
7
+ * ```svelte
8
+ * <SvProgress value={64} showLabel />
9
+ * <SvProgress indeterminate color="success" />
10
+ * ```
11
+ */
12
+ type Props = {
13
+ /** Current value (0..max). Ignored when `indeterminate`. */
14
+ value?: number;
15
+ max?: number;
16
+ /** Unknown-duration animated bar. */
17
+ indeterminate?: boolean;
18
+ /** Buffered/secondary value (e.g. streamed-ahead), 0..max. */
19
+ buffer?: number;
20
+ color?: 'accent' | 'success' | 'warning' | 'danger';
21
+ size?: 'sm' | 'md' | 'lg';
22
+ /** Show a percentage label at the end of the bar. */
23
+ showLabel?: boolean;
24
+ /** Format the label (default: rounded percent). */
25
+ formatLabel?: (value: number, max: number) => string;
26
+ /** Diagonal candy-stripe overlay on the fill. */
27
+ striped?: boolean;
28
+ ariaLabel?: string;
29
+ };
30
+ declare const SvProgress: import("svelte").Component<Props, {}, "">;
31
+ type SvProgress = ReturnType<typeof SvProgress>;
32
+ export default SvProgress;
@@ -8,17 +8,15 @@
8
8
  * roving tabindex + arrow-key navigation. Parity: Smart `smart-radio-button`
9
9
  * (as a managed group). Controlled via `value` + `onChange`.
10
10
  */
11
+ import SvField from './SvField.svelte'
12
+ import { nextEditorId, type SvEditorProps } from './editor-contract'
11
13
  import { createRadioGroup, type RadioOption } from './createRadioGroup.svelte'
12
14
 
13
- type Props = {
15
+ type Props = SvEditorProps & {
14
16
  options: ReadonlyArray<RadioOption>
15
17
  value?: string | number | null
16
18
  onChange?: (value: string | number) => void
17
- name?: string
18
- disabled?: boolean
19
19
  orientation?: 'vertical' | 'horizontal'
20
- size?: 'sm' | 'md' | 'lg'
21
- ariaLabel?: string
22
20
  }
23
21
 
24
22
  let {
@@ -30,34 +28,53 @@
30
28
  orientation = 'vertical',
31
29
  size = 'md',
32
30
  ariaLabel,
31
+ invalid = false,
32
+ required = false,
33
+ error,
34
+ label,
35
+ hint,
36
+ dir,
37
+ id,
33
38
  }: Props = $props()
34
39
 
40
+ const autoId = nextEditorId('sv-radio')
41
+ const uid = $derived(id ?? autoId)
42
+
35
43
  // The styled radio group is just a renderer over the headless core.
36
44
  const rg = createRadioGroup({
37
45
  options: () => options,
38
46
  value: () => value,
39
47
  onChange: (v) => onChange?.(v),
40
48
  disabled: () => disabled,
41
- ariaLabel: () => ariaLabel,
49
+ // A visible field `label` also names the group for assistive tech.
50
+ ariaLabel: () => ariaLabel ?? label,
51
+ id: () => uid,
52
+ invalid: () => invalid,
53
+ required: () => required,
54
+ error: () => error,
55
+ hint: () => hint,
42
56
  })
43
57
  </script>
44
58
 
45
- <div
46
- class="sv-radiogroup sv-radiogroup--{orientation} sv-radiogroup--{size}"
47
- {...rg.groupProps()}
48
- >
49
- {#each options as opt (opt.value)}
50
- <button
51
- class="sv-radio"
52
- class:is-checked={opt.value === value}
53
- {...rg.radioProps(opt)}
54
- >
55
- <span class="sv-radio__dot"></span>
56
- <span class="sv-radio__label">{opt.label}</span>
57
- </button>
58
- {/each}
59
- {#if name}<input type="hidden" {name} value={value ?? ''} />{/if}
60
- </div>
59
+ <SvField id={uid} {label} {hint} {error} {required} {dir}>
60
+ <div
61
+ class="sv-radiogroup sv-radiogroup--{orientation} sv-radiogroup--{size}"
62
+ class:is-invalid={invalid}
63
+ {...rg.groupProps()}
64
+ >
65
+ {#each options as opt (opt.value)}
66
+ <button
67
+ class="sv-radio"
68
+ class:is-checked={opt.value === value}
69
+ {...rg.radioProps(opt)}
70
+ >
71
+ <span class="sv-radio__dot"></span>
72
+ <span class="sv-radio__label">{opt.label}</span>
73
+ </button>
74
+ {/each}
75
+ {#if name}<input type="hidden" {name} value={value ?? ''} />{/if}
76
+ </div>
77
+ </SvField>
61
78
 
62
79
  <style>
63
80
  .sv-radiogroup { --_accent: var(--sg-accent, #2563eb); display: flex; gap: 10px; }
@@ -76,6 +93,7 @@
76
93
  border: 1.5px solid var(--sg-border, #cbd5e1); background: var(--sg-input-bg, #fff);
77
94
  display: grid; place-items: center; transition: border-color 0.12s;
78
95
  }
96
+ .sv-radiogroup.is-invalid .sv-radio__dot { border-color: var(--sg-danger, #dc2626); }
79
97
  .sv-radio.is-checked .sv-radio__dot { border-color: var(--_accent); }
80
98
  .sv-radio.is-checked .sv-radio__dot::after {
81
99
  content: ''; width: 9px; height: 9px; border-radius: 50%; background: var(--_accent);
@@ -1,19 +1,11 @@
1
1
  export type { RadioOption } from './createRadioGroup.svelte';
2
- /**
3
- * SvRadioGroup - an accessible radio group (WAI-ARIA radiogroup pattern) with
4
- * roving tabindex + arrow-key navigation. Parity: Smart `smart-radio-button`
5
- * (as a managed group). Controlled via `value` + `onChange`.
6
- */
2
+ import { type SvEditorProps } from './editor-contract';
7
3
  import { type RadioOption } from './createRadioGroup.svelte';
8
- type Props = {
4
+ type Props = SvEditorProps & {
9
5
  options: ReadonlyArray<RadioOption>;
10
6
  value?: string | number | null;
11
7
  onChange?: (value: string | number) => void;
12
- name?: string;
13
- disabled?: boolean;
14
8
  orientation?: 'vertical' | 'horizontal';
15
- size?: 'sm' | 'md' | 'lg';
16
- ariaLabel?: string;
17
9
  };
18
10
  declare const SvRadioGroup: import("svelte").Component<Props, {}, "">;
19
11
  type SvRadioGroup = ReturnType<typeof SvRadioGroup>;
@@ -4,22 +4,24 @@
4
4
  * `smart-rating`. Hover preview, keyboard, optional half steps, readOnly.
5
5
  * Uses the grid's `--sg-rating-*` tokens so it matches the in-grid editor.
6
6
  */
7
+ import SvField from './SvField.svelte'
8
+ import { nextEditorId, resolveMessages, type SvEditorProps } from './editor-contract'
7
9
  import { createRating } from './createRating.svelte'
8
10
 
9
- type Props = {
11
+ /** User-facing strings (localizable via `messages`). */
12
+ type RatingMessages = { label: string; star: string; stars: string }
13
+ const DEFAULT_MESSAGES: RatingMessages = { label: 'Rating', star: 'star', stars: 'stars' }
14
+
15
+ type Props = SvEditorProps & {
10
16
  value?: number
11
17
  onChange?: (value: number) => void
12
18
  max?: number
13
19
  /** Allow half-star precision. */
14
20
  allowHalf?: boolean
15
- /** Read-only: shown but not editable (the kit-standard name). */
16
- readonly?: boolean
17
21
  /** @deprecated use `readonly` - kept for back-compat. */
18
22
  readOnly?: boolean
19
- disabled?: boolean
20
- size?: 'sm' | 'md' | 'lg'
21
- name?: string
22
- ariaLabel?: string
23
+ /** Override the built-in strings (group + per-star aria-labels). */
24
+ messages?: Partial<RatingMessages>
23
25
  }
24
26
 
25
27
  let {
@@ -33,9 +35,20 @@
33
35
  size = 'md',
34
36
  name,
35
37
  ariaLabel,
38
+ invalid = false,
39
+ required = false,
40
+ error,
41
+ label,
42
+ hint,
43
+ dir,
44
+ id,
45
+ messages,
36
46
  }: Props = $props()
37
47
 
38
48
  const ro = $derived(readonly || readOnly)
49
+ const autoId = nextEditorId('sv-rating')
50
+ const uid = $derived(id ?? autoId)
51
+ const M = $derived(resolveMessages(DEFAULT_MESSAGES, messages))
39
52
 
40
53
  // The styled rating is just a renderer over the headless core.
41
54
  const r = createRating({
@@ -45,32 +58,40 @@
45
58
  allowHalf: () => allowHalf,
46
59
  readonly: () => ro,
47
60
  disabled: () => disabled,
48
- ariaLabel: () => ariaLabel,
61
+ ariaLabel: () => ariaLabel ?? label ?? M.label,
62
+ starLabel: (n) => `${n} ${n === 1 ? M.star : M.stars}`,
63
+ id: () => uid,
64
+ invalid: () => invalid,
65
+ required: () => required,
66
+ error: () => error,
67
+ hint: () => hint,
49
68
  })
50
69
  </script>
51
70
 
52
- <div
53
- class="sv-rating sv-rating--{size}"
54
- class:is-readonly={ro}
55
- class:is-disabled={disabled}
56
- {...r.rootProps()}
57
- >
58
- {#each Array(max) as _, i (i)}
59
- <button
60
- class="sv-rating__star is-{r.fillOf(i)}"
61
- {...r.starProps(i)}
62
- >
63
- <svg viewBox="0 0 24 24" aria-hidden="true">
64
- <defs>
65
- <linearGradient id="half-{i}"><stop offset="50%" stop-color="var(--_on)" /><stop offset="50%" stop-color="var(--_off)" /></linearGradient>
66
- </defs>
67
- <path d="M12 2.5l2.9 6.1 6.6.9-4.8 4.6 1.2 6.6L12 18.6 6.1 21.7l1.2-6.6L2.5 9.5l6.6-.9z"
68
- fill={r.fillOf(i) === 'full' ? 'var(--_on)' : r.fillOf(i) === 'half' ? `url(#half-${i})` : 'var(--_off)'} />
69
- </svg>
70
- </button>
71
- {/each}
72
- {#if name}<input type="hidden" {name} value={value} />{/if}
73
- </div>
71
+ <SvField id={uid} {label} {hint} {error} {required} {dir}>
72
+ <div
73
+ class="sv-rating sv-rating--{size}"
74
+ class:is-readonly={ro}
75
+ class:is-disabled={disabled}
76
+ {...r.rootProps()}
77
+ >
78
+ {#each Array(max) as _, i (i)}
79
+ <button
80
+ class="sv-rating__star is-{r.fillOf(i)}"
81
+ {...r.starProps(i)}
82
+ >
83
+ <svg viewBox="0 0 24 24" aria-hidden="true">
84
+ <defs>
85
+ <linearGradient id="half-{uid}-{i}"><stop offset="50%" stop-color="var(--_on)" /><stop offset="50%" stop-color="var(--_off)" /></linearGradient>
86
+ </defs>
87
+ <path d="M12 2.5l2.9 6.1 6.6.9-4.8 4.6 1.2 6.6L12 18.6 6.1 21.7l1.2-6.6L2.5 9.5l6.6-.9z"
88
+ fill={r.fillOf(i) === 'full' ? 'var(--_on)' : r.fillOf(i) === 'half' ? `url(#half-${uid}-${i})` : 'var(--_off)'} />
89
+ </svg>
90
+ </button>
91
+ {/each}
92
+ {#if name}<input type="hidden" {name} value={value} />{/if}
93
+ </div>
94
+ </SvField>
74
95
 
75
96
  <style>
76
97
  .sv-rating {
@@ -1,17 +1,20 @@
1
- type Props = {
1
+ import { type SvEditorProps } from './editor-contract';
2
+ /** User-facing strings (localizable via `messages`). */
3
+ type RatingMessages = {
4
+ label: string;
5
+ star: string;
6
+ stars: string;
7
+ };
8
+ type Props = SvEditorProps & {
2
9
  value?: number;
3
10
  onChange?: (value: number) => void;
4
11
  max?: number;
5
12
  /** Allow half-star precision. */
6
13
  allowHalf?: boolean;
7
- /** Read-only: shown but not editable (the kit-standard name). */
8
- readonly?: boolean;
9
14
  /** @deprecated use `readonly` - kept for back-compat. */
10
15
  readOnly?: boolean;
11
- disabled?: boolean;
12
- size?: 'sm' | 'md' | 'lg';
13
- name?: string;
14
- ariaLabel?: string;
16
+ /** Override the built-in strings (group + per-star aria-labels). */
17
+ messages?: Partial<RatingMessages>;
15
18
  };
16
19
  declare const SvRating: import("svelte").Component<Props, {}, "">;
17
20
  type SvRating = ReturnType<typeof SvRating>;
@@ -0,0 +1,192 @@
1
+ <script lang="ts" module>
2
+ export type RichTextTool =
3
+ | 'bold' | 'italic' | 'underline' | 'strike'
4
+ | 'h1' | 'h2' | 'h3' | 'p'
5
+ | 'ul' | 'ol' | 'quote' | 'code'
6
+ | 'alignLeft' | 'alignCenter' | 'alignRight'
7
+ | 'link' | 'clear' | 'undo' | 'redo'
8
+ | '|'
9
+ </script>
10
+
11
+ <script lang="ts">
12
+ /**
13
+ * SvRichText - a lightweight WYSIWYG editor: a formatting toolbar over a
14
+ * `contentEditable` region, emitting HTML. Parity: Smart `smart-editor` (the
15
+ * common commands). Uses `document.execCommand` - the pragmatic, widely-working
16
+ * approach for a component-kit editor. Bindable `value` (HTML string).
17
+ *
18
+ * ```svelte
19
+ * <SvRichText bind:value={html} placeholder="Write something…" />
20
+ * ```
21
+ */
22
+ import { nextEditorId } from './editor-contract'
23
+
24
+ const DEFAULT_TOOLS: RichTextTool[] = [
25
+ 'bold', 'italic', 'underline', 'strike', '|',
26
+ 'h1', 'h2', 'h3', 'p', '|',
27
+ 'ul', 'ol', 'quote', 'code', '|',
28
+ 'alignLeft', 'alignCenter', 'alignRight', '|',
29
+ 'link', 'clear', '|', 'undo', 'redo',
30
+ ]
31
+
32
+ const META: Record<Exclude<RichTextTool, '|'>, { label: string; glyph: string }> = {
33
+ bold: { label: 'Bold', glyph: 'B' }, italic: { label: 'Italic', glyph: 'I' },
34
+ underline: { label: 'Underline', glyph: 'U' }, strike: { label: 'Strikethrough', glyph: 'S' },
35
+ h1: { label: 'Heading 1', glyph: 'H1' }, h2: { label: 'Heading 2', glyph: 'H2' },
36
+ h3: { label: 'Heading 3', glyph: 'H3' }, p: { label: 'Paragraph', glyph: '¶' },
37
+ ul: { label: 'Bullet list', glyph: '•' }, ol: { label: 'Numbered list', glyph: '1.' },
38
+ quote: { label: 'Quote', glyph: '❝' }, code: { label: 'Code block', glyph: '</>' },
39
+ alignLeft: { label: 'Align left', glyph: '≡' }, alignCenter: { label: 'Align center', glyph: '≣' },
40
+ alignRight: { label: 'Align right', glyph: '≡' }, link: { label: 'Link', glyph: '🔗' },
41
+ clear: { label: 'Clear formatting', glyph: '⌫' }, undo: { label: 'Undo', glyph: '↶' }, redo: { label: 'Redo', glyph: '↷' },
42
+ }
43
+
44
+ type Props = {
45
+ /** HTML string (bindable). */
46
+ value?: string
47
+ onChange?: (html: string) => void
48
+ placeholder?: string
49
+ disabled?: boolean
50
+ readonly?: boolean
51
+ minHeight?: string
52
+ /** Toolbar tools + order; use '|' for a separator. */
53
+ tools?: RichTextTool[]
54
+ ariaLabel?: string
55
+ }
56
+
57
+ let {
58
+ value = $bindable(''),
59
+ onChange,
60
+ placeholder = '',
61
+ disabled = false,
62
+ readonly = false,
63
+ minHeight = '160px',
64
+ tools = DEFAULT_TOOLS,
65
+ ariaLabel = 'Rich text editor',
66
+ }: Props = $props()
67
+
68
+ const uid = nextEditorId('sv-rt')
69
+ let editorEl = $state<HTMLDivElement | null>(null)
70
+ let focused = $state(false)
71
+ let empty = $state(true)
72
+ let activeState = $state<Record<string, boolean>>({})
73
+
74
+ // Push external value into the DOM only when it differs and we're not typing
75
+ // (writing innerHTML while focused would collapse the caret).
76
+ $effect(() => {
77
+ const v = value ?? ''
78
+ if (editorEl && !focused && editorEl.innerHTML !== v) editorEl.innerHTML = v
79
+ if (editorEl) empty = editorEl.textContent!.trim().length === 0
80
+ })
81
+
82
+ function sync() {
83
+ if (!editorEl) return
84
+ const html = editorEl.innerHTML
85
+ empty = editorEl.textContent!.trim().length === 0
86
+ value = html
87
+ onChange?.(html)
88
+ }
89
+ function q(cmd: string): boolean {
90
+ try { return document.queryCommandState(cmd) } catch { return false }
91
+ }
92
+ function refreshState() {
93
+ activeState = {
94
+ bold: q('bold'), italic: q('italic'), underline: q('underline'), strike: q('strikeThrough'),
95
+ ul: q('insertUnorderedList'), ol: q('insertOrderedList'),
96
+ }
97
+ }
98
+ function exec(cmd: string, arg?: string) {
99
+ if (disabled || readonly) return
100
+ editorEl?.focus()
101
+ try { document.execCommand(cmd, false, arg) } catch { /* jsdom / unsupported */ }
102
+ sync()
103
+ refreshState()
104
+ }
105
+
106
+ const run: Record<Exclude<RichTextTool, '|'>, () => void> = {
107
+ bold: () => exec('bold'), italic: () => exec('italic'), underline: () => exec('underline'), strike: () => exec('strikeThrough'),
108
+ h1: () => exec('formatBlock', 'H1'), h2: () => exec('formatBlock', 'H2'), h3: () => exec('formatBlock', 'H3'), p: () => exec('formatBlock', 'P'),
109
+ ul: () => exec('insertUnorderedList'), ol: () => exec('insertOrderedList'),
110
+ quote: () => exec('formatBlock', 'BLOCKQUOTE'), code: () => exec('formatBlock', 'PRE'),
111
+ alignLeft: () => exec('justifyLeft'), alignCenter: () => exec('justifyCenter'), alignRight: () => exec('justifyRight'),
112
+ link: () => { const url = typeof prompt === 'function' ? prompt('Link URL', 'https://') : null; if (url) exec('createLink', url) },
113
+ clear: () => exec('removeFormat'), undo: () => exec('undo'), redo: () => exec('redo'),
114
+ }
115
+ </script>
116
+
117
+ <div class="sv-rt" class:is-disabled={disabled} class:is-readonly={readonly}>
118
+ {#if !readonly}
119
+ <div class="sv-rt__toolbar" role="toolbar" aria-label="Formatting" aria-controls={uid}>
120
+ {#each tools as t, i (i)}
121
+ {#if t === '|'}
122
+ <span class="sv-rt__sep" aria-hidden="true"></span>
123
+ {:else}
124
+ <button
125
+ type="button"
126
+ class="sv-rt__btn"
127
+ class:is-on={activeState[t]}
128
+ data-tool={t}
129
+ title={META[t].label}
130
+ aria-label={META[t].label}
131
+ aria-pressed={activeState[t] ? true : undefined}
132
+ {disabled}
133
+ onmousedown={(e) => e.preventDefault()}
134
+ onclick={run[t]}
135
+ >{META[t].glyph}</button>
136
+ {/if}
137
+ {/each}
138
+ </div>
139
+ {/if}
140
+ <!-- svelte-ignore a11y_no_noninteractive_tabindex -->
141
+ <div
142
+ bind:this={editorEl}
143
+ id={uid}
144
+ class="sv-rt__body"
145
+ class:is-empty={empty}
146
+ style:min-height={minHeight}
147
+ contenteditable={!disabled && !readonly}
148
+ role="textbox"
149
+ aria-multiline="true"
150
+ aria-label={ariaLabel}
151
+ data-placeholder={placeholder}
152
+ tabindex={disabled ? -1 : 0}
153
+ oninput={sync}
154
+ onfocus={() => (focused = true)}
155
+ onblur={() => { focused = false; sync() }}
156
+ onkeyup={refreshState}
157
+ onmouseup={refreshState}
158
+ ></div>
159
+ </div>
160
+
161
+ <style>
162
+ .sv-rt {
163
+ --_accent: var(--sg-accent, #2563eb);
164
+ border: 1px solid var(--sg-input-border, var(--sg-border, #cbd5e1)); border-radius: var(--sg-radius, 8px);
165
+ background: var(--sg-input-bg, #fff); color: var(--sg-fg, #0f172a); overflow: hidden;
166
+ display: flex; flex-direction: column;
167
+ }
168
+ .sv-rt:focus-within { border-color: var(--_accent); box-shadow: 0 0 0 2px color-mix(in srgb, var(--_accent) 20%, transparent); }
169
+ .sv-rt.is-disabled { opacity: 0.6; }
170
+ .sv-rt__toolbar { display: flex; flex-wrap: wrap; align-items: center; gap: 1px; padding: 5px 6px; border-bottom: 1px solid var(--sg-border, #e2e8f0); background: var(--sg-header-bg, #f8fafc); }
171
+ .sv-rt__btn {
172
+ min-width: 28px; height: 28px; padding: 0 6px; display: grid; place-items: center;
173
+ background: none; border: 0; border-radius: 6px; color: var(--sg-fg, #334155); cursor: pointer;
174
+ font-size: 12.5px; font-weight: 600;
175
+ }
176
+ .sv-rt__btn:hover:not(:disabled) { background: var(--sg-row-hover-bg, #eef2f7); }
177
+ .sv-rt__btn.is-on { background: color-mix(in srgb, var(--_accent) 16%, transparent); color: var(--_accent); }
178
+ .sv-rt__btn[data-tool='italic'] { font-style: italic; }
179
+ .sv-rt__btn[data-tool='underline'] { text-decoration: underline; }
180
+ .sv-rt__btn[data-tool='strike'] { text-decoration: line-through; }
181
+ .sv-rt__btn[data-tool='alignRight'] { transform: scaleX(-1); }
182
+ .sv-rt__sep { width: 1px; height: 18px; background: var(--sg-border, #e2e8f0); margin: 0 4px; }
183
+ .sv-rt__body { padding: 10px 12px; outline: none; overflow: auto; font-size: 14px; line-height: 1.6; }
184
+ .sv-rt__body.is-empty::before { content: attr(data-placeholder); color: var(--sg-muted, #94a3b8); pointer-events: none; }
185
+ .sv-rt__body :global(h1) { font-size: 1.5em; font-weight: 700; margin: 0.4em 0; }
186
+ .sv-rt__body :global(h2) { font-size: 1.25em; font-weight: 700; margin: 0.4em 0; }
187
+ .sv-rt__body :global(h3) { font-size: 1.1em; font-weight: 650; margin: 0.4em 0; }
188
+ .sv-rt__body :global(blockquote) { margin: 0.4em 0; padding-inline-start: 12px; border-inline-start: 3px solid var(--sg-border, #cbd5e1); color: var(--sg-muted, #64748b); }
189
+ .sv-rt__body :global(pre) { margin: 0.4em 0; padding: 10px 12px; border-radius: 8px; background: var(--sg-row-hover-bg, #f1f5f9); font: 12.5px/1.6 ui-monospace, monospace; overflow-x: auto; }
190
+ .sv-rt__body :global(a) { color: var(--_accent); }
191
+ .sv-rt__body :global(ul), .sv-rt__body :global(ol) { margin: 0.4em 0; padding-inline-start: 24px; }
192
+ </style>
@@ -0,0 +1,16 @@
1
+ export type RichTextTool = 'bold' | 'italic' | 'underline' | 'strike' | 'h1' | 'h2' | 'h3' | 'p' | 'ul' | 'ol' | 'quote' | 'code' | 'alignLeft' | 'alignCenter' | 'alignRight' | 'link' | 'clear' | 'undo' | 'redo' | '|';
2
+ type Props = {
3
+ /** HTML string (bindable). */
4
+ value?: string;
5
+ onChange?: (html: string) => void;
6
+ placeholder?: string;
7
+ disabled?: boolean;
8
+ readonly?: boolean;
9
+ minHeight?: string;
10
+ /** Toolbar tools + order; use '|' for a separator. */
11
+ tools?: RichTextTool[];
12
+ ariaLabel?: string;
13
+ };
14
+ declare const SvRichText: import("svelte").Component<Props, {}, "value">;
15
+ type SvRichText = ReturnType<typeof SvRichText>;
16
+ export default SvRichText;
@@ -0,0 +1,147 @@
1
+ <!--
2
+ A row-group panel (like the "drag columns to group" bar in enterprise grids).
3
+ Shows the current group-by columns as chips you can remove or drag to reorder,
4
+ plus a "+ Group by" menu to add one. It is also a drop target: a column drag
5
+ that carries `text/sv-column` (its column id) adds that column. Wire `onChange`
6
+ to a server group model's `setGroupBy`, or to client grouping.
7
+
8
+ <SvRowGroupPanel
9
+ columns={[{ id: 'region', label: 'Region' }, { id: 'country', label: 'Country' }]}
10
+ groupBy={view.groupBy}
11
+ onChange={(g) => ctl.setGroupBy(g)}
12
+ />
13
+ -->
14
+ <script lang="ts">
15
+ type Col = { id: string; label: string }
16
+ type Props = {
17
+ /** Columns that can be grouped on. */
18
+ columns: Col[]
19
+ /** Current group-by column ids, outer to inner. */
20
+ groupBy: string[]
21
+ /** Called with the new group-by order. */
22
+ onChange: (groupBy: string[]) => void
23
+ /** Text shown when nothing is grouped. */
24
+ placeholder?: string
25
+ }
26
+ let { columns, groupBy, onChange, placeholder = 'Drag a column here to group by it' }: Props = $props()
27
+
28
+ const labelOf = (id: string) => columns.find((c) => c.id === id)?.label ?? id
29
+ const available = $derived(columns.filter((c) => !groupBy.includes(c.id)))
30
+
31
+ let dragIndex = $state<number | null>(null)
32
+
33
+ function remove(id: string) {
34
+ onChange(groupBy.filter((g) => g !== id))
35
+ }
36
+ function add(id: string) {
37
+ if (id && !groupBy.includes(id)) onChange([...groupBy, id])
38
+ }
39
+ function reorder(to: number) {
40
+ if (dragIndex === null || dragIndex === to) return
41
+ const next = [...groupBy]
42
+ const [moved] = next.splice(dragIndex, 1)
43
+ next.splice(to, 0, moved!)
44
+ dragIndex = null
45
+ onChange(next)
46
+ }
47
+ function onPanelDrop(e: DragEvent) {
48
+ const id = e.dataTransfer?.getData('text/sv-column')
49
+ if (id) add(id)
50
+ }
51
+ </script>
52
+
53
+ <div
54
+ class="sv-rowgroup-panel"
55
+ role="group"
56
+ aria-label="Row groups"
57
+ ondragover={(e) => e.preventDefault()}
58
+ ondrop={onPanelDrop}
59
+ >
60
+ <span class="sv-rgp-label" aria-hidden="true">Group by:</span>
61
+ {#if groupBy.length === 0}
62
+ <span class="sv-rgp-empty">{placeholder}</span>
63
+ {:else}
64
+ {#each groupBy as id, i (id)}
65
+ {#if i > 0}<span class="sv-rgp-sep" aria-hidden="true">›</span>{/if}
66
+ <span
67
+ class="sv-rgp-chip"
68
+ class:sv-rgp-chip-drag={dragIndex === i}
69
+ draggable="true"
70
+ ondragstart={() => (dragIndex = i)}
71
+ ondragend={() => (dragIndex = null)}
72
+ ondragover={(e) => e.preventDefault()}
73
+ ondrop={() => reorder(i)}
74
+ >
75
+ <span class="sv-rgp-grip" aria-hidden="true">⠿</span>
76
+ {labelOf(id)}
77
+ <button type="button" class="sv-rgp-x" onclick={() => remove(id)} aria-label={`Stop grouping by ${labelOf(id)}`}>×</button>
78
+ </span>
79
+ {/each}
80
+ {/if}
81
+ {#if available.length}
82
+ <select
83
+ class="sv-rgp-add"
84
+ aria-label="Add a group column"
85
+ onchange={(e) => { add(e.currentTarget.value); e.currentTarget.value = '' }}
86
+ >
87
+ <option value="">+ Group by</option>
88
+ {#each available as c (c.id)}<option value={c.id}>{c.label}</option>{/each}
89
+ </select>
90
+ {/if}
91
+ </div>
92
+
93
+ <style>
94
+ .sv-rowgroup-panel {
95
+ display: flex;
96
+ align-items: center;
97
+ flex-wrap: wrap;
98
+ gap: 6px;
99
+ padding: 8px 10px;
100
+ border: 1px dashed var(--sg-border, #cbd5e1);
101
+ border-radius: 10px;
102
+ background: var(--sg-header-bg, #f8fafc);
103
+ font-size: 13px;
104
+ }
105
+ .sv-rgp-label { color: var(--sg-muted, #64748b); font-weight: 600; }
106
+ .sv-rgp-empty { color: var(--sg-muted, #94a3b8); font-style: italic; }
107
+ .sv-rgp-sep { color: var(--sg-muted, #94a3b8); }
108
+ .sv-rgp-chip {
109
+ display: inline-flex;
110
+ align-items: center;
111
+ gap: 6px;
112
+ padding: 3px 6px 3px 8px;
113
+ border-radius: 999px;
114
+ background: var(--sg-bg, #fff);
115
+ border: 1px solid var(--sg-border, #e2e8f0);
116
+ cursor: grab;
117
+ user-select: none;
118
+ font-weight: 600;
119
+ }
120
+ .sv-rgp-chip-drag { opacity: 0.5; }
121
+ .sv-rgp-grip { color: var(--sg-muted, #94a3b8); cursor: grab; }
122
+ .sv-rgp-x {
123
+ display: inline-flex;
124
+ align-items: center;
125
+ justify-content: center;
126
+ width: 16px;
127
+ height: 16px;
128
+ border: 0;
129
+ border-radius: 50%;
130
+ background: none;
131
+ color: var(--sg-muted, #64748b);
132
+ cursor: pointer;
133
+ font-size: 14px;
134
+ line-height: 1;
135
+ }
136
+ .sv-rgp-x:hover { background: var(--sg-header-bg, #f1f5f9); color: var(--sg-fg, #0f172a); }
137
+ .sv-rgp-add {
138
+ font: inherit;
139
+ font-size: 13px;
140
+ padding: 4px 8px;
141
+ border-radius: 8px;
142
+ border: 1px solid var(--sg-border, #e2e8f0);
143
+ background: var(--sg-bg, #fff);
144
+ color: var(--sg-accent, #2563eb);
145
+ cursor: pointer;
146
+ }
147
+ </style>
@@ -0,0 +1,17 @@
1
+ type Col = {
2
+ id: string;
3
+ label: string;
4
+ };
5
+ type Props = {
6
+ /** Columns that can be grouped on. */
7
+ columns: Col[];
8
+ /** Current group-by column ids, outer to inner. */
9
+ groupBy: string[];
10
+ /** Called with the new group-by order. */
11
+ onChange: (groupBy: string[]) => void;
12
+ /** Text shown when nothing is grouped. */
13
+ placeholder?: string;
14
+ };
15
+ declare const SvRowGroupPanel: import("svelte").Component<Props, {}, "">;
16
+ type SvRowGroupPanel = ReturnType<typeof SvRowGroupPanel>;
17
+ export default SvRowGroupPanel;