@svgrid/grid 1.2.34 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (490) hide show
  1. package/README.md +6 -5
  2. package/dist/FlexRender.svelte +96 -96
  3. package/dist/GridFooter.svelte +178 -178
  4. package/dist/SvAccordion.svelte +109 -0
  5. package/dist/SvAccordion.svelte.d.ts +28 -0
  6. package/dist/SvAlert.svelte +92 -0
  7. package/dist/SvAlert.svelte.d.ts +27 -0
  8. package/dist/SvAutoComplete.svelte +47 -18
  9. package/dist/SvAutoComplete.svelte.d.ts +2 -5
  10. package/dist/SvAvatar.svelte +75 -0
  11. package/dist/SvAvatar.svelte.d.ts +14 -0
  12. package/dist/SvAvatarGroup.svelte +48 -0
  13. package/dist/SvAvatarGroup.svelte.d.ts +16 -0
  14. package/dist/SvBadge.svelte +54 -0
  15. package/dist/SvBadge.svelte.d.ts +23 -0
  16. package/dist/SvBreadcrumb.svelte +88 -0
  17. package/dist/SvBreadcrumb.svelte.d.ts +23 -0
  18. package/dist/SvButtonGroup.svelte +121 -0
  19. package/dist/SvButtonGroup.svelte.d.ts +16 -0
  20. package/dist/SvCalendar.svelte +72 -9
  21. package/dist/SvCalendar.svelte.d.ts +34 -1
  22. package/dist/SvCard.svelte +71 -0
  23. package/dist/SvCard.svelte.d.ts +28 -0
  24. package/dist/SvCarousel.svelte +134 -0
  25. package/dist/SvCarousel.svelte.d.ts +28 -0
  26. package/dist/SvCheckBox.svelte +36 -21
  27. package/dist/SvCheckBox.svelte.d.ts +2 -5
  28. package/dist/SvChip.svelte +88 -0
  29. package/dist/SvChip.svelte.d.ts +31 -0
  30. package/dist/SvCircularProgress.svelte +109 -0
  31. package/dist/SvCircularProgress.svelte.d.ts +31 -0
  32. package/dist/SvColorInput.svelte +54 -27
  33. package/dist/SvColorInput.svelte.d.ts +10 -6
  34. package/dist/SvComboBox.svelte +119 -33
  35. package/dist/SvComboBox.svelte.d.ts +18 -6
  36. package/dist/SvCommand.svelte +197 -0
  37. package/dist/SvCommand.svelte.d.ts +26 -0
  38. package/dist/SvContextMenu.svelte +96 -0
  39. package/dist/SvContextMenu.svelte.d.ts +25 -0
  40. package/dist/SvCountryInput.svelte +56 -21
  41. package/dist/SvCountryInput.svelte.d.ts +9 -5
  42. package/dist/SvDateRangeInput.svelte +256 -0
  43. package/dist/SvDateRangeInput.svelte.d.ts +37 -0
  44. package/dist/SvDateTimePicker.svelte +57 -20
  45. package/dist/SvDateTimePicker.svelte.d.ts +12 -4
  46. package/dist/SvDivider.svelte +61 -0
  47. package/dist/SvDivider.svelte.d.ts +22 -0
  48. package/dist/SvDrawer.svelte +226 -0
  49. package/dist/SvDrawer.svelte.d.ts +43 -0
  50. package/dist/SvDropDownList.svelte +114 -35
  51. package/dist/SvDropDownList.svelte.d.ts +7 -6
  52. package/dist/SvDurationInput.svelte +108 -0
  53. package/dist/SvDurationInput.svelte.d.ts +15 -0
  54. package/dist/SvEmptyState.svelte +59 -0
  55. package/dist/SvEmptyState.svelte.d.ts +25 -0
  56. package/dist/SvField.svelte +85 -0
  57. package/dist/SvField.svelte.d.ts +30 -0
  58. package/dist/SvFileUpload.svelte +169 -0
  59. package/dist/SvFileUpload.svelte.d.ts +24 -0
  60. package/dist/SvForm.svelte +7 -1
  61. package/dist/SvForm.svelte.d.ts +3 -0
  62. package/dist/SvGauge.svelte +7 -1
  63. package/dist/SvGauge.svelte.d.ts +11 -0
  64. package/dist/SvGrid.controller.svelte.d.ts +6 -0
  65. package/dist/SvGrid.controller.svelte.js +64 -9
  66. package/dist/SvGrid.css +2376 -2343
  67. package/dist/SvGrid.svelte +2764 -2651
  68. package/dist/SvGrid.types.d.ts +366 -0
  69. package/dist/SvGridBoard.svelte +2281 -0
  70. package/dist/SvGridBoard.svelte.d.ts +31 -0
  71. package/dist/SvGridDropdown.svelte +666 -665
  72. package/dist/SvGridSelect.svelte +255 -0
  73. package/dist/SvGridSelect.svelte.d.ts +32 -0
  74. package/dist/SvGroupCell.svelte +109 -0
  75. package/dist/SvGroupCell.svelte.d.ts +41 -0
  76. package/dist/SvListBox.svelte +123 -36
  77. package/dist/SvListBox.svelte.d.ts +12 -8
  78. package/dist/SvMaskedInput.svelte +53 -13
  79. package/dist/SvMaskedInput.svelte.d.ts +16 -6
  80. package/dist/SvMenu.svelte +101 -0
  81. package/dist/SvMenu.svelte.d.ts +26 -0
  82. package/dist/SvMenuList.svelte +143 -0
  83. package/dist/SvMenuList.svelte.d.ts +24 -0
  84. package/dist/SvModal.svelte +220 -0
  85. package/dist/SvModal.svelte.d.ts +31 -0
  86. package/dist/SvMultiSelect.svelte +277 -0
  87. package/dist/SvMultiSelect.svelte.d.ts +31 -0
  88. package/dist/SvNavPane.svelte +314 -0
  89. package/dist/SvNavPane.svelte.d.ts +59 -0
  90. package/dist/SvNumberInput.svelte +23 -9
  91. package/dist/SvNumberInput.svelte.d.ts +2 -0
  92. package/dist/SvOtpInput.svelte +157 -0
  93. package/dist/SvOtpInput.svelte.d.ts +16 -0
  94. package/dist/SvPagination.svelte +100 -0
  95. package/dist/SvPagination.svelte.d.ts +16 -0
  96. package/dist/SvPasswordInput.svelte +42 -12
  97. package/dist/SvPasswordInput.svelte.d.ts +13 -6
  98. package/dist/SvPhoneInput.svelte +43 -11
  99. package/dist/SvPhoneInput.svelte.d.ts +10 -11
  100. package/dist/SvPopover.svelte +127 -0
  101. package/dist/SvPopover.svelte.d.ts +35 -0
  102. package/dist/SvProgress.svelte +116 -0
  103. package/dist/SvProgress.svelte.d.ts +32 -0
  104. package/dist/SvRadioGroup.svelte +40 -22
  105. package/dist/SvRadioGroup.svelte.d.ts +2 -10
  106. package/dist/SvRating.svelte +51 -30
  107. package/dist/SvRating.svelte.d.ts +10 -7
  108. package/dist/SvRichText.svelte +192 -0
  109. package/dist/SvRichText.svelte.d.ts +16 -0
  110. package/dist/SvRowGroupPanel.svelte +147 -0
  111. package/dist/SvRowGroupPanel.svelte.d.ts +17 -0
  112. package/dist/SvScrollArea.svelte +50 -0
  113. package/dist/SvScrollArea.svelte.d.ts +22 -0
  114. package/dist/SvSkeleton.svelte +76 -0
  115. package/dist/SvSkeleton.svelte.d.ts +25 -0
  116. package/dist/SvSlider.svelte +41 -9
  117. package/dist/SvSlider.svelte.d.ts +4 -4
  118. package/dist/SvSparkline.svelte +77 -0
  119. package/dist/SvSparkline.svelte.d.ts +28 -0
  120. package/dist/SvSplitter.svelte +138 -0
  121. package/dist/SvSplitter.svelte.d.ts +32 -0
  122. package/dist/SvStat.svelte +86 -0
  123. package/dist/SvStat.svelte.d.ts +30 -0
  124. package/dist/SvStepper.svelte +91 -0
  125. package/dist/SvStepper.svelte.d.ts +24 -0
  126. package/dist/SvSwitchButton.svelte +39 -24
  127. package/dist/SvSwitchButton.svelte.d.ts +2 -5
  128. package/dist/SvTabs.svelte +147 -28
  129. package/dist/SvTabs.svelte.d.ts +16 -4
  130. package/dist/SvTagsInput.svelte +59 -22
  131. package/dist/SvTagsInput.svelte.d.ts +9 -4
  132. package/dist/SvTextArea.svelte +113 -0
  133. package/dist/SvTextArea.svelte.d.ts +18 -0
  134. package/dist/SvTextInput.svelte +115 -0
  135. package/dist/SvTextInput.svelte.d.ts +20 -0
  136. package/dist/SvTimePicker.svelte +19 -5
  137. package/dist/SvTimePicker.svelte.d.ts +12 -0
  138. package/dist/SvTimeline.svelte +75 -0
  139. package/dist/SvTimeline.svelte.d.ts +24 -0
  140. package/dist/SvToaster.svelte +124 -0
  141. package/dist/SvToaster.svelte.d.ts +10 -0
  142. package/dist/SvToggleButton.svelte +37 -12
  143. package/dist/SvToggleButton.svelte.d.ts +2 -4
  144. package/dist/SvTooltip.svelte +113 -0
  145. package/dist/SvTooltip.svelte.d.ts +22 -0
  146. package/dist/SvTour.svelte +151 -0
  147. package/dist/SvTour.svelte.d.ts +25 -0
  148. package/dist/SvTree.svelte +286 -44
  149. package/dist/SvTree.svelte.d.ts +26 -9
  150. package/dist/SvTreeSelect.svelte +222 -0
  151. package/dist/SvTreeSelect.svelte.d.ts +24 -0
  152. package/dist/a11y/dismissable.d.ts +32 -0
  153. package/dist/a11y/dismissable.js +54 -0
  154. package/dist/a11y/focus-trap.d.ts +39 -0
  155. package/dist/a11y/focus-trap.js +142 -0
  156. package/dist/a11y/live-region.d.ts +8 -0
  157. package/dist/a11y/live-region.js +60 -0
  158. package/dist/a11y/scroll-lock.d.ts +4 -0
  159. package/dist/a11y/scroll-lock.js +41 -0
  160. package/dist/a11y.d.ts +3 -1
  161. package/dist/a11y.js +1 -1
  162. package/dist/avatar.d.ts +10 -0
  163. package/dist/avatar.js +22 -0
  164. package/dist/builtin-editors.d.ts +5 -0
  165. package/dist/builtin-editors.js +55 -0
  166. package/dist/cdn/svgrid.js +16022 -8235
  167. package/dist/cdn/svgrid.svelte-external.js +14543 -6765
  168. package/dist/columns.js +3 -2
  169. package/dist/core.d.ts +7 -1
  170. package/dist/countries.d.ts +12 -0
  171. package/dist/countries.js +24 -0
  172. package/dist/createAccordion.svelte.d.ts +71 -0
  173. package/dist/createAccordion.svelte.js +99 -0
  174. package/dist/createAutocomplete.svelte.d.ts +13 -4
  175. package/dist/createAutocomplete.svelte.js +11 -1
  176. package/dist/createButtonGroup.svelte.d.ts +62 -0
  177. package/dist/createButtonGroup.svelte.js +154 -0
  178. package/dist/createCalendar.svelte.d.ts +5 -0
  179. package/dist/createCalendar.svelte.js +2 -0
  180. package/dist/createCheckbox.svelte.d.ts +9 -17
  181. package/dist/createCheckbox.svelte.js +28 -1
  182. package/dist/createColorInput.svelte.d.ts +12 -22
  183. package/dist/createColorInput.svelte.js +13 -0
  184. package/dist/createCombobox.svelte.d.ts +16 -5
  185. package/dist/createCombobox.svelte.js +13 -2
  186. package/dist/createCountryInput.svelte.d.ts +14 -3
  187. package/dist/createCountryInput.svelte.js +12 -2
  188. package/dist/createDateTimePicker.svelte.d.ts +17 -2
  189. package/dist/createDateTimePicker.svelte.js +12 -2
  190. package/dist/createDropdownList.svelte.d.ts +14 -5
  191. package/dist/createDropdownList.svelte.js +50 -1
  192. package/dist/createFileUpload.svelte.d.ts +68 -0
  193. package/dist/createFileUpload.svelte.js +122 -0
  194. package/dist/createListbox.svelte.d.ts +10 -1
  195. package/dist/createListbox.svelte.js +48 -1
  196. package/dist/createMaskedInput.svelte.d.ts +11 -2
  197. package/dist/createMaskedInput.svelte.js +11 -1
  198. package/dist/createNumberInput.svelte.d.ts +1 -0
  199. package/dist/createNumberInput.svelte.js +1 -0
  200. package/dist/createPasswordInput.svelte.d.ts +19 -21
  201. package/dist/createPasswordInput.svelte.js +16 -4
  202. package/dist/createPhoneInput.svelte.d.ts +26 -7
  203. package/dist/createPhoneInput.svelte.js +24 -3
  204. package/dist/createPopoverSelect.svelte.d.ts +86 -0
  205. package/dist/createPopoverSelect.svelte.js +196 -0
  206. package/dist/createRadioGroup.svelte.d.ts +9 -0
  207. package/dist/createRadioGroup.svelte.js +11 -1
  208. package/dist/createRating.svelte.d.ts +11 -0
  209. package/dist/createRating.svelte.js +12 -1
  210. package/dist/createSlider.svelte.d.ts +2 -0
  211. package/dist/createSlider.svelte.js +16 -5
  212. package/dist/createSplitter.svelte.d.ts +67 -0
  213. package/dist/createSplitter.svelte.js +99 -0
  214. package/dist/createSwitch.svelte.d.ts +9 -16
  215. package/dist/createSwitch.svelte.js +28 -1
  216. package/dist/createTabs.svelte.d.ts +7 -0
  217. package/dist/createTabs.svelte.js +17 -2
  218. package/dist/createTagsInput.svelte.d.ts +13 -1
  219. package/dist/createTagsInput.svelte.js +12 -3
  220. package/dist/createToggle.svelte.d.ts +9 -0
  221. package/dist/createToggle.svelte.js +12 -1
  222. package/dist/createTree.svelte.d.ts +19 -0
  223. package/dist/createTree.svelte.js +108 -15
  224. package/dist/debounce.d.ts +11 -0
  225. package/dist/debounce.js +30 -0
  226. package/dist/duration.d.ts +15 -0
  227. package/dist/duration.js +51 -0
  228. package/dist/editor-contract.d.ts +62 -7
  229. package/dist/editor-contract.js +45 -5
  230. package/dist/editor-registry.d.ts +67 -0
  231. package/dist/editor-registry.js +38 -0
  232. package/dist/editors/cell-editors.d.ts +1 -1
  233. package/dist/editors/cell-editors.js +5 -0
  234. package/dist/fuzzy.d.ts +3 -0
  235. package/dist/fuzzy.js +41 -0
  236. package/dist/grid-select.d.ts +9 -0
  237. package/dist/grid-select.js +8 -0
  238. package/dist/index.d.ts +79 -6
  239. package/dist/index.js +78 -4
  240. package/dist/keyboard-handlers.js +19 -0
  241. package/dist/list-option.d.ts +36 -0
  242. package/dist/list-option.js +68 -0
  243. package/dist/otp.d.ts +16 -0
  244. package/dist/otp.js +26 -0
  245. package/dist/paginate.d.ts +20 -0
  246. package/dist/paginate.js +40 -0
  247. package/dist/popover.d.ts +15 -1
  248. package/dist/popover.js +29 -3
  249. package/dist/recurrence.d.ts +36 -0
  250. package/dist/recurrence.js +90 -0
  251. package/dist/server-data-source.d.ts +89 -0
  252. package/dist/server-data-source.js +4 -0
  253. package/dist/server-group-model.d.ts +98 -0
  254. package/dist/server-group-model.js +263 -0
  255. package/dist/toast-store.svelte.d.ts +41 -0
  256. package/dist/toast-store.svelte.js +113 -0
  257. package/dist/tree-select.d.ts +19 -0
  258. package/dist/tree-select.js +40 -0
  259. package/dist/ui-app.types.d.ts +80 -0
  260. package/dist/ui-app.types.js +7 -0
  261. package/dist/validators.d.ts +43 -0
  262. package/dist/validators.js +53 -0
  263. package/dist/virtual.d.ts +35 -0
  264. package/dist/virtual.js +34 -0
  265. package/package.json +85 -85
  266. package/src/FlexRender.svelte +96 -96
  267. package/src/GridFooter.svelte +178 -178
  268. package/src/SvAccordion.svelte +109 -0
  269. package/src/SvAccordion.test.ts +66 -0
  270. package/src/SvAlert.svelte +92 -0
  271. package/src/SvAutoComplete.svelte +47 -18
  272. package/src/SvAvatar.svelte +75 -0
  273. package/src/SvAvatarGroup.svelte +48 -0
  274. package/src/SvBadge.svelte +54 -0
  275. package/src/SvBreadcrumb.svelte +88 -0
  276. package/src/SvButtonGroup.svelte +121 -0
  277. package/src/SvButtonGroup.test.ts +72 -0
  278. package/src/SvCalendar.svelte +72 -9
  279. package/src/SvCard.svelte +71 -0
  280. package/src/SvCarousel.svelte +134 -0
  281. package/src/SvCheckBox.svelte +36 -21
  282. package/src/SvChip.svelte +88 -0
  283. package/src/SvCircularProgress.svelte +109 -0
  284. package/src/SvColorInput.svelte +54 -27
  285. package/src/SvComboBox.svelte +119 -33
  286. package/src/SvCommand.svelte +197 -0
  287. package/src/SvContextMenu.svelte +96 -0
  288. package/src/SvCountryInput.svelte +56 -21
  289. package/src/SvDateRangeInput.svelte +256 -0
  290. package/src/SvDateRangeInput.test.ts +80 -0
  291. package/src/SvDateTimePicker.svelte +57 -20
  292. package/src/SvDivider.svelte +61 -0
  293. package/src/SvDrawer.svelte +226 -0
  294. package/src/SvDrawer.test.ts +125 -0
  295. package/src/SvDropDownList.svelte +114 -35
  296. package/src/SvDurationInput.svelte +108 -0
  297. package/src/SvEmptyState.svelte +59 -0
  298. package/src/SvField.svelte +85 -0
  299. package/src/SvFileUpload.svelte +169 -0
  300. package/src/SvFileUpload.test.ts +59 -0
  301. package/src/SvForm.svelte +7 -1
  302. package/src/SvGauge.svelte +7 -1
  303. package/src/SvGrid.controller.svelte.ts +2553 -2494
  304. package/src/SvGrid.css +2376 -2343
  305. package/src/SvGrid.svelte +2764 -2651
  306. package/src/SvGrid.types.ts +944 -570
  307. package/src/SvGridBoard.svelte +2281 -0
  308. package/src/SvGridDropdown.svelte +666 -665
  309. package/src/SvGridSelect.svelte +255 -0
  310. package/src/SvGridSelect.test.ts +100 -0
  311. package/src/SvGroupCell.svelte +109 -0
  312. package/src/SvListBox.svelte +123 -36
  313. package/src/SvMaskedInput.svelte +53 -13
  314. package/src/SvMenu.svelte +101 -0
  315. package/src/SvMenu.test.ts +73 -0
  316. package/src/SvMenuList.svelte +143 -0
  317. package/src/SvModal.svelte +220 -0
  318. package/src/SvMultiSelect.svelte +277 -0
  319. package/src/SvMultiSelect.test.ts +167 -0
  320. package/src/SvNavPane.svelte +314 -0
  321. package/src/SvNavPane.test.ts +70 -0
  322. package/src/SvNumberInput.svelte +23 -9
  323. package/src/SvOtpInput.svelte +157 -0
  324. package/src/SvPagination.svelte +100 -0
  325. package/src/SvPasswordInput.svelte +42 -12
  326. package/src/SvPhoneInput.svelte +43 -11
  327. package/src/SvPopover.svelte +127 -0
  328. package/src/SvProgress.svelte +116 -0
  329. package/src/SvRadioGroup.svelte +40 -22
  330. package/src/SvRating.svelte +51 -30
  331. package/src/SvRichText.svelte +192 -0
  332. package/src/SvRowGroupPanel.svelte +147 -0
  333. package/src/SvScrollArea.svelte +50 -0
  334. package/src/SvSkeleton.svelte +76 -0
  335. package/src/SvSlider.svelte +41 -9
  336. package/src/SvSparkline.svelte +77 -0
  337. package/src/SvSplitter.svelte +138 -0
  338. package/src/SvSplitter.test.ts +55 -0
  339. package/src/SvStat.svelte +86 -0
  340. package/src/SvStepper.svelte +91 -0
  341. package/src/SvSwitchButton.svelte +39 -24
  342. package/src/SvTabs.svelte +147 -28
  343. package/src/SvTagsInput.svelte +59 -22
  344. package/src/SvTextArea.svelte +113 -0
  345. package/src/SvTextInput.svelte +115 -0
  346. package/src/SvTimePicker.svelte +19 -5
  347. package/src/SvTimeline.svelte +75 -0
  348. package/src/SvToaster.svelte +124 -0
  349. package/src/SvToaster.test.ts +63 -0
  350. package/src/SvToggleButton.svelte +37 -12
  351. package/src/SvTooltip.svelte +113 -0
  352. package/src/SvTour.svelte +151 -0
  353. package/src/SvTree.svelte +286 -44
  354. package/src/SvTreeSelect.svelte +222 -0
  355. package/src/SvTreeSelect.test.ts +87 -0
  356. package/src/a11y/dismissable.test.ts +95 -0
  357. package/src/a11y/dismissable.ts +94 -0
  358. package/src/a11y/focus-trap.test.ts +110 -0
  359. package/src/a11y/focus-trap.ts +134 -0
  360. package/src/a11y/live-region.test.ts +40 -0
  361. package/src/a11y/live-region.ts +65 -0
  362. package/src/a11y/scroll-lock.test.ts +38 -0
  363. package/src/a11y/scroll-lock.ts +41 -0
  364. package/src/a11y.contract.test.ts +49 -49
  365. package/src/a11y.test.ts +59 -59
  366. package/src/a11y.ts +61 -59
  367. package/src/avatar.test.ts +32 -0
  368. package/src/avatar.ts +21 -0
  369. package/src/board.test.ts +927 -0
  370. package/src/build-api.ts +798 -798
  371. package/src/builtin-editors.grid.test.ts +85 -0
  372. package/src/builtin-editors.test.ts +58 -0
  373. package/src/builtin-editors.ts +56 -0
  374. package/src/cell-formatting.ts +169 -169
  375. package/src/cell-render.ts +469 -469
  376. package/src/collaboration.test.ts +104 -104
  377. package/src/collaboration.ts +167 -167
  378. package/src/columns.ts +3 -2
  379. package/src/core.performance.test.ts +30 -30
  380. package/src/core.ts +1111 -1101
  381. package/src/countries.ts +25 -0
  382. package/src/createAccordion.svelte.ts +126 -0
  383. package/src/createAutocomplete.svelte.ts +18 -1
  384. package/src/createButtonGroup.svelte.ts +166 -0
  385. package/src/createCalendar.svelte.ts +6 -0
  386. package/src/createCheckbox.svelte.ts +23 -1
  387. package/src/createColorInput.svelte.ts +20 -0
  388. package/src/createCombobox.svelte.ts +22 -2
  389. package/src/createCountryInput.svelte.ts +21 -2
  390. package/src/createDateTimePicker.svelte.ts +23 -2
  391. package/src/createDropdownList.svelte.ts +31 -2
  392. package/src/createFileUpload.svelte.ts +144 -0
  393. package/src/createGrid.svelte.ts +42 -42
  394. package/src/createGrid.test.ts +10 -10
  395. package/src/createGridState.svelte.ts +17 -17
  396. package/src/createListbox.svelte.ts +35 -3
  397. package/src/createMaskedInput.svelte.ts +18 -1
  398. package/src/createNumberInput.svelte.ts +2 -0
  399. package/src/createPasswordInput.svelte.ts +31 -5
  400. package/src/createPhoneInput.svelte.ts +38 -4
  401. package/src/createPopoverSelect.svelte.ts +208 -0
  402. package/src/createRadioGroup.svelte.ts +23 -1
  403. package/src/createRating.svelte.ts +26 -1
  404. package/src/createSlider.svelte.ts +14 -3
  405. package/src/createSplitter.svelte.ts +119 -0
  406. package/src/createSwitch.svelte.ts +26 -3
  407. package/src/createTabs.svelte.ts +20 -3
  408. package/src/createTagsInput.svelte.ts +24 -3
  409. package/src/createToggle.svelte.ts +25 -2
  410. package/src/createTree.svelte.ts +104 -14
  411. package/src/debounce.test.ts +50 -0
  412. package/src/debounce.ts +41 -0
  413. package/src/duration.test.ts +41 -0
  414. package/src/duration.ts +51 -0
  415. package/src/editing.test.ts +859 -859
  416. package/src/editing.ts +675 -675
  417. package/src/editor-contract.ts +87 -8
  418. package/src/editor-registry.grid.test.ts +98 -0
  419. package/src/editor-registry.test.ts +86 -0
  420. package/src/editor-registry.ts +106 -0
  421. package/src/editors/cell-editors.ts +10 -1
  422. package/src/export-data-api.test.ts +126 -126
  423. package/src/export-format.test.ts +107 -107
  424. package/src/export-format.ts +598 -598
  425. package/src/flex-render.ts +3 -3
  426. package/src/fuzzy.test.ts +40 -0
  427. package/src/fuzzy.ts +39 -0
  428. package/src/grid-select.test.ts +28 -0
  429. package/src/grid-select.ts +20 -0
  430. package/src/index.ts +463 -318
  431. package/src/keyboard-handlers.ts +20 -0
  432. package/src/keyboard.test.ts +59 -59
  433. package/src/keyboard.ts +97 -97
  434. package/src/list-option.ts +74 -0
  435. package/src/list-power.test.ts +71 -0
  436. package/src/menus.ts +582 -582
  437. package/src/merge-objects.ts +48 -48
  438. package/src/otp.test.ts +28 -0
  439. package/src/otp.ts +28 -0
  440. package/src/overlays.test.ts +85 -0
  441. package/src/paginate.test.ts +41 -0
  442. package/src/paginate.ts +61 -0
  443. package/src/phone-valid.test.ts +26 -0
  444. package/src/popover.ts +31 -3
  445. package/src/progress.test.ts +55 -0
  446. package/src/recurrence.test.ts +91 -0
  447. package/src/recurrence.ts +111 -0
  448. package/src/render-component.ts +28 -28
  449. package/src/selection.test.ts +754 -754
  450. package/src/selection.ts +600 -600
  451. package/src/server-data-source.test.ts +289 -289
  452. package/src/server-data-source.ts +413 -311
  453. package/src/server-group-model.test.ts +294 -0
  454. package/src/server-group-model.ts +370 -0
  455. package/src/sparkline.test.ts +68 -68
  456. package/src/sparkline.ts +169 -169
  457. package/src/spreadsheet.test.ts +489 -489
  458. package/src/spreadsheet.ts +304 -304
  459. package/src/static-functions.ts +11 -11
  460. package/src/subscribe.ts +38 -38
  461. package/src/svgrid-wrapper.types.ts +439 -439
  462. package/src/svgrid.behavior.test.ts +706 -706
  463. package/src/svgrid.features.test.ts +157 -157
  464. package/src/svgrid.new-features.wrapper.test.ts +251 -251
  465. package/src/svgrid.responsive.test.ts +72 -0
  466. package/src/svgrid.wrapper.test.ts +40 -40
  467. package/src/toast-store.svelte.ts +148 -0
  468. package/src/toast-store.test.ts +86 -0
  469. package/src/tree-edit.test.ts +49 -0
  470. package/src/tree-filter.test.ts +56 -0
  471. package/src/tree-select.test.ts +48 -0
  472. package/src/tree-select.ts +62 -0
  473. package/src/ui-app.test.ts +130 -0
  474. package/src/ui-app.types.ts +88 -0
  475. package/src/ui-display.test.ts +79 -0
  476. package/src/ui-inputs.test.ts +1 -1
  477. package/src/ui-status.test.ts +141 -0
  478. package/src/ui-tier1.test.ts +142 -0
  479. package/src/ui-tier2.test.ts +124 -0
  480. package/src/ui-tier3.test.ts +139 -0
  481. package/src/validators.test.ts +58 -0
  482. package/src/validators.ts +105 -0
  483. package/src/virtual.test.ts +72 -0
  484. package/src/virtual.ts +67 -0
  485. package/src/virtualization/column-virtualizer.test.ts +27 -27
  486. package/src/virtualization/column-virtualizer.ts +30 -30
  487. package/src/virtualization/svelte-virtualizer.svelte.ts +26 -26
  488. package/src/virtualization/types.ts +30 -30
  489. package/src/virtualization/virtualizer.test.ts +47 -47
  490. package/src/virtualization/virtualizer.ts +296 -296
@@ -1,178 +1,178 @@
1
- <script lang="ts" generics="TFeatures extends TableFeatures = TableFeatures, TData extends RowData = RowData">
2
- import {
3
- getGridCellA11yProps,
4
- getGridCellDomId,
5
- getGridHeaderA11yProps,
6
- getGridRootA11yProps,
7
- getGridRowA11yProps,
8
- type EditorContext,
9
- type CellEditorOption,
10
- type Column,
11
- type Row,
12
- type RowData,
13
- type TableFeatures,
14
- } from "./index";
15
- import "./sv-grid-scrollbar";
16
- import type { Snippet } from "svelte";
17
- import {
18
- RenderSnippetConfig,
19
- RenderComponentConfig,
20
- } from "./render-component";
21
- import {
22
- buildSparkline,
23
- toSparklineValues,
24
- } from "./sparkline";
25
- import SvGridDropdown from "./SvGridDropdown.svelte";
26
- import type {
27
- Props,
28
- SelectionPoint,
29
- SelectionRange,
30
- CellEditState,
31
- FilterOperator,
32
- FilterOption,
33
- MenuPosition,
34
- } from "./SvGrid.types";
35
- import {
36
- cfTextStyle,
37
- fmtStat,
38
- getEditableInputValue,
39
- getEditorInputType,
40
- toValueArray,
41
- getOptionLabel,
42
- getOptionColor,
43
- colorfulChipStyle,
44
- getEditorClass,
45
- } from "./SvGrid.helpers";
46
- import {
47
- } from "./SvGrid.controller.svelte";
48
- import type { SvGridController } from "./SvGrid.controller.svelte";
49
-
50
- let {
51
- ctrl,
52
- pager = true,
53
- showStatus = true,
54
- top = false,
55
- pageSizeOptions,
56
- }: {
57
- ctrl: SvGridController<TFeatures, TData>;
58
- /** Render the pagination controls in this instance. */
59
- pager?: boolean;
60
- /** Render the status bar in this instance. */
61
- showStatus?: boolean;
62
- /** This is a top-positioned footer (styling only). */
63
- top?: boolean;
64
- /** Page-size choices for the selector. Defaults to `[10, 25, 50, 100]`. */
65
- pageSizeOptions?: number[];
66
- } = $props();
67
-
68
- // View facade: re-bind the controller's reactive members so the markup
69
- // (moved verbatim from SvGrid.svelte) stays identical.
70
- const paginationEnabled = $derived(ctrl.paginationEnabled);
71
- const grid = $derived(ctrl.grid);
72
- const paginationState = $derived(ctrl.paginationState);
73
- const allRowsBeforePagination = $derived(ctrl.allRowsBeforePagination);
74
- const statusBarEnabled = $derived(ctrl.statusBarEnabled);
75
- const statusBarAggregates = $derived(ctrl.statusBarAggregates);
76
- const statusBarStats = $derived(ctrl.statusBarStats);
77
- const changePage = $derived(ctrl.changePage);
78
- const goToPage = $derived(ctrl.goToPage);
79
- const setPageSize = $derived(ctrl.setPageSize);
80
- </script>
81
-
82
- {#if showStatus && statusBarEnabled && statusBarStats}
83
- {@const s = statusBarStats}
84
- <div class="sv-grid-status-bar" role="status" aria-live="polite">
85
- {#each statusBarAggregates as agg (agg)}
86
- {#if agg === "count"}
87
- <span class="sv-grid-status-item"
88
- ><span class="sv-grid-status-label">Count</span>{fmtStat(s.count)}</span
89
- >
90
- {:else if agg === "numericCount"}
91
- <span class="sv-grid-status-item"
92
- ><span class="sv-grid-status-label">Numeric</span>{fmtStat(s.numericCount)}</span
93
- >
94
- {:else if s.numericCount > 0 && agg === "sum"}
95
- <span class="sv-grid-status-item"
96
- ><span class="sv-grid-status-label">Sum</span>{fmtStat(s.sum)}</span
97
- >
98
- {:else if s.numericCount > 0 && agg === "avg"}
99
- <span class="sv-grid-status-item"
100
- ><span class="sv-grid-status-label">Avg</span>{fmtStat(s.avg)}</span
101
- >
102
- {:else if s.numericCount > 0 && agg === "min"}
103
- <span class="sv-grid-status-item"
104
- ><span class="sv-grid-status-label">Min</span>{fmtStat(s.min)}</span
105
- >
106
- {:else if s.numericCount > 0 && agg === "max"}
107
- <span class="sv-grid-status-item"
108
- ><span class="sv-grid-status-label">Max</span>{fmtStat(s.max)}</span
109
- >
110
- {/if}
111
- {/each}
112
- </div>
113
- {/if}
114
-
115
- {#if pager && paginationEnabled}
116
- {@const totalRows = ctrl.paginationTotalRows}
117
- {@const pageSize = ctrl.paginationPageSize}
118
- {@const pageCount = Math.max(1, Math.ceil(totalRows / pageSize))}
119
- {@const currentPage = Math.min(ctrl.paginationPageIndex + 1, pageCount)}
120
- {@const rangeStart =
121
- totalRows === 0 ? 0 : (currentPage - 1) * pageSize + 1}
122
- {@const rangeEnd = Math.min(totalRows, currentPage * pageSize)}
123
- {@const onFirst = currentPage <= 1}
124
- {@const onLast = currentPage >= pageCount}
125
- {@const sizes = pageSizeOptions && pageSizeOptions.length ? pageSizeOptions : [10, 25, 50, 100]}
126
- <div class="sv-grid-pagination" class:sv-grid-pagination-top={top} role="navigation" aria-label="Pagination">
127
- <div class="sv-grid-pagination-pagesize">
128
- <span>Page Size:</span>
129
- <div class="sv-grid-pagination-pagesize-dd">
130
- <SvGridDropdown
131
- options={sizes.map((n) => ({ value: n, label: String(n) }))}
132
- value={pageSize}
133
- autoOpen={false}
134
- onChange={(v) => setPageSize(Number(v))}
135
- />
136
- </div>
137
- </div>
138
- <span class="sv-grid-pagination-range">
139
- <strong>{rangeStart.toLocaleString()}</strong> to
140
- <strong>{rangeEnd.toLocaleString()}</strong> of
141
- <strong>{totalRows.toLocaleString()}</strong>
142
- </span>
143
- <div class="sv-grid-pagination-nav">
144
- <button
145
- type="button"
146
- class="sv-grid-pagination-btn"
147
- disabled={onFirst}
148
- onclick={() => goToPage(0)}
149
- aria-label="First page">⇤</button
150
- >
151
- <button
152
- type="button"
153
- class="sv-grid-pagination-btn"
154
- disabled={onFirst}
155
- onclick={() => changePage(-1)}
156
- aria-label="Previous page">‹</button
157
- >
158
- <span class="sv-grid-pagination-label">
159
- Page <strong>{currentPage.toLocaleString()}</strong> of
160
- <strong>{pageCount.toLocaleString()}</strong>
161
- </span>
162
- <button
163
- type="button"
164
- class="sv-grid-pagination-btn"
165
- disabled={onLast}
166
- onclick={() => changePage(1)}
167
- aria-label="Next page">›</button
168
- >
169
- <button
170
- type="button"
171
- class="sv-grid-pagination-btn"
172
- disabled={onLast}
173
- onclick={() => goToPage(pageCount - 1)}
174
- aria-label="Last page">⇥</button
175
- >
176
- </div>
177
- </div>
178
- {/if}
1
+ <script lang="ts" generics="TFeatures extends TableFeatures = TableFeatures, TData extends RowData = RowData">
2
+ import {
3
+ getGridCellA11yProps,
4
+ getGridCellDomId,
5
+ getGridHeaderA11yProps,
6
+ getGridRootA11yProps,
7
+ getGridRowA11yProps,
8
+ type EditorContext,
9
+ type CellEditorOption,
10
+ type Column,
11
+ type Row,
12
+ type RowData,
13
+ type TableFeatures,
14
+ } from "./index";
15
+ import "./sv-grid-scrollbar";
16
+ import type { Snippet } from "svelte";
17
+ import {
18
+ RenderSnippetConfig,
19
+ RenderComponentConfig,
20
+ } from "./render-component";
21
+ import {
22
+ buildSparkline,
23
+ toSparklineValues,
24
+ } from "./sparkline";
25
+ import SvGridDropdown from "./SvGridDropdown.svelte";
26
+ import type {
27
+ Props,
28
+ SelectionPoint,
29
+ SelectionRange,
30
+ CellEditState,
31
+ FilterOperator,
32
+ FilterOption,
33
+ MenuPosition,
34
+ } from "./SvGrid.types";
35
+ import {
36
+ cfTextStyle,
37
+ fmtStat,
38
+ getEditableInputValue,
39
+ getEditorInputType,
40
+ toValueArray,
41
+ getOptionLabel,
42
+ getOptionColor,
43
+ colorfulChipStyle,
44
+ getEditorClass,
45
+ } from "./SvGrid.helpers";
46
+ import {
47
+ } from "./SvGrid.controller.svelte";
48
+ import type { SvGridController } from "./SvGrid.controller.svelte";
49
+
50
+ let {
51
+ ctrl,
52
+ pager = true,
53
+ showStatus = true,
54
+ top = false,
55
+ pageSizeOptions,
56
+ }: {
57
+ ctrl: SvGridController<TFeatures, TData>;
58
+ /** Render the pagination controls in this instance. */
59
+ pager?: boolean;
60
+ /** Render the status bar in this instance. */
61
+ showStatus?: boolean;
62
+ /** This is a top-positioned footer (styling only). */
63
+ top?: boolean;
64
+ /** Page-size choices for the selector. Defaults to `[10, 25, 50, 100]`. */
65
+ pageSizeOptions?: number[];
66
+ } = $props();
67
+
68
+ // View facade: re-bind the controller's reactive members so the markup
69
+ // (moved verbatim from SvGrid.svelte) stays identical.
70
+ const paginationEnabled = $derived(ctrl.paginationEnabled);
71
+ const grid = $derived(ctrl.grid);
72
+ const paginationState = $derived(ctrl.paginationState);
73
+ const allRowsBeforePagination = $derived(ctrl.allRowsBeforePagination);
74
+ const statusBarEnabled = $derived(ctrl.statusBarEnabled);
75
+ const statusBarAggregates = $derived(ctrl.statusBarAggregates);
76
+ const statusBarStats = $derived(ctrl.statusBarStats);
77
+ const changePage = $derived(ctrl.changePage);
78
+ const goToPage = $derived(ctrl.goToPage);
79
+ const setPageSize = $derived(ctrl.setPageSize);
80
+ </script>
81
+
82
+ {#if showStatus && statusBarEnabled && statusBarStats}
83
+ {@const s = statusBarStats}
84
+ <div class="sv-grid-status-bar" role="status" aria-live="polite">
85
+ {#each statusBarAggregates as agg (agg)}
86
+ {#if agg === "count"}
87
+ <span class="sv-grid-status-item"
88
+ ><span class="sv-grid-status-label">Count</span>{fmtStat(s.count)}</span
89
+ >
90
+ {:else if agg === "numericCount"}
91
+ <span class="sv-grid-status-item"
92
+ ><span class="sv-grid-status-label">Numeric</span>{fmtStat(s.numericCount)}</span
93
+ >
94
+ {:else if s.numericCount > 0 && agg === "sum"}
95
+ <span class="sv-grid-status-item"
96
+ ><span class="sv-grid-status-label">Sum</span>{fmtStat(s.sum)}</span
97
+ >
98
+ {:else if s.numericCount > 0 && agg === "avg"}
99
+ <span class="sv-grid-status-item"
100
+ ><span class="sv-grid-status-label">Avg</span>{fmtStat(s.avg)}</span
101
+ >
102
+ {:else if s.numericCount > 0 && agg === "min"}
103
+ <span class="sv-grid-status-item"
104
+ ><span class="sv-grid-status-label">Min</span>{fmtStat(s.min)}</span
105
+ >
106
+ {:else if s.numericCount > 0 && agg === "max"}
107
+ <span class="sv-grid-status-item"
108
+ ><span class="sv-grid-status-label">Max</span>{fmtStat(s.max)}</span
109
+ >
110
+ {/if}
111
+ {/each}
112
+ </div>
113
+ {/if}
114
+
115
+ {#if pager && paginationEnabled}
116
+ {@const totalRows = ctrl.paginationTotalRows}
117
+ {@const pageSize = ctrl.paginationPageSize}
118
+ {@const pageCount = Math.max(1, Math.ceil(totalRows / pageSize))}
119
+ {@const currentPage = Math.min(ctrl.paginationPageIndex + 1, pageCount)}
120
+ {@const rangeStart =
121
+ totalRows === 0 ? 0 : (currentPage - 1) * pageSize + 1}
122
+ {@const rangeEnd = Math.min(totalRows, currentPage * pageSize)}
123
+ {@const onFirst = currentPage <= 1}
124
+ {@const onLast = currentPage >= pageCount}
125
+ {@const sizes = pageSizeOptions && pageSizeOptions.length ? pageSizeOptions : [10, 25, 50, 100]}
126
+ <div class="sv-grid-pagination" class:sv-grid-pagination-top={top} role="navigation" aria-label="Pagination">
127
+ <div class="sv-grid-pagination-pagesize">
128
+ <span>Page Size:</span>
129
+ <div class="sv-grid-pagination-pagesize-dd">
130
+ <SvGridDropdown
131
+ options={sizes.map((n) => ({ value: n, label: String(n) }))}
132
+ value={pageSize}
133
+ autoOpen={false}
134
+ onChange={(v) => setPageSize(Number(v))}
135
+ />
136
+ </div>
137
+ </div>
138
+ <span class="sv-grid-pagination-range">
139
+ <strong>{rangeStart.toLocaleString()}</strong> to
140
+ <strong>{rangeEnd.toLocaleString()}</strong> of
141
+ <strong>{totalRows.toLocaleString()}</strong>
142
+ </span>
143
+ <div class="sv-grid-pagination-nav">
144
+ <button
145
+ type="button"
146
+ class="sv-grid-pagination-btn"
147
+ disabled={onFirst}
148
+ onclick={() => goToPage(0)}
149
+ aria-label="First page">⇤</button
150
+ >
151
+ <button
152
+ type="button"
153
+ class="sv-grid-pagination-btn"
154
+ disabled={onFirst}
155
+ onclick={() => changePage(-1)}
156
+ aria-label="Previous page">‹</button
157
+ >
158
+ <span class="sv-grid-pagination-label">
159
+ Page <strong>{currentPage.toLocaleString()}</strong> of
160
+ <strong>{pageCount.toLocaleString()}</strong>
161
+ </span>
162
+ <button
163
+ type="button"
164
+ class="sv-grid-pagination-btn"
165
+ disabled={onLast}
166
+ onclick={() => changePage(1)}
167
+ aria-label="Next page">›</button
168
+ >
169
+ <button
170
+ type="button"
171
+ class="sv-grid-pagination-btn"
172
+ disabled={onLast}
173
+ onclick={() => goToPage(pageCount - 1)}
174
+ aria-label="Last page">⇥</button
175
+ >
176
+ </div>
177
+ </div>
178
+ {/if}
@@ -0,0 +1,109 @@
1
+ <script lang="ts" module>
2
+ export type { AccordionItem, AccordionExpandMode } from './createAccordion.svelte'
3
+ </script>
4
+
5
+ <script lang="ts">
6
+ /**
7
+ * SvAccordion - a WAI-ARIA accordion (collapsible sections) with single- or
8
+ * multiple-expand and roving header focus (Up/Down/Home/End). Parity: Smart
9
+ * `smart-accordion`. Controlled via `expanded` + `onChange`; each panel's body
10
+ * is rendered through the `panel` snippet (receives the item).
11
+ *
12
+ * Behavior (expand state, keyboard, ARIA) lives in the headless `createAccordion`
13
+ * core; this component is one styled renderer over it.
14
+ */
15
+ import type { Snippet } from 'svelte'
16
+ import { type EditorDir } from './editor-contract'
17
+ import { createAccordion, type AccordionItem, type AccordionExpandMode } from './createAccordion.svelte'
18
+
19
+ type Props = {
20
+ items: ReadonlyArray<AccordionItem>
21
+ /** Expanded item ids (controlled). */
22
+ expanded?: string[]
23
+ onChange?: (expandedIds: string[]) => void
24
+ /** 'single' (at most one open) or 'multiple'. Default single. */
25
+ expandMode?: AccordionExpandMode
26
+ disabled?: boolean
27
+ dir?: EditorDir
28
+ /** Panel body for an item. */
29
+ panel?: Snippet<[AccordionItem]>
30
+ }
31
+
32
+ let {
33
+ items,
34
+ expanded = $bindable([]),
35
+ onChange,
36
+ expandMode = 'single',
37
+ disabled = false,
38
+ dir,
39
+ panel,
40
+ }: Props = $props()
41
+
42
+ const resolvedDir = $derived(dir === 'ltr' || dir === 'rtl' ? dir : undefined)
43
+
44
+ const acc = createAccordion({
45
+ items: () => items,
46
+ expanded: () => expanded,
47
+ onChange: (ids) => { expanded = ids; onChange?.(ids) },
48
+ expandMode: () => expandMode,
49
+ disabled: () => disabled,
50
+ dir: () => dir,
51
+ })
52
+
53
+ // DOM focus movement is a render concern: follow the core's roving focus header.
54
+ let rootEl: HTMLDivElement | null = null
55
+ let lastFocusTick = 0
56
+ $effect(() => {
57
+ if (acc.focusTick !== lastFocusTick) {
58
+ lastFocusTick = acc.focusTick
59
+ const i = acc.focusIndex
60
+ queueMicrotask(() => rootEl?.querySelector<HTMLElement>(`[data-idx="${i}"]`)?.focus())
61
+ }
62
+ })
63
+ </script>
64
+
65
+ <div bind:this={rootEl} class="sv-acc" class:is-disabled={disabled} dir={resolvedDir} {...acc.rootProps()}>
66
+ {#each items as item, i (item.id)}
67
+ {@const open = acc.isExpanded(item.id)}
68
+ <div class="sv-acc__item" class:is-open={open}>
69
+ <h3 class="sv-acc__heading">
70
+ <button class="sv-acc__header" {...acc.headerProps(i)}>
71
+ <svg class="sv-acc__chevron" viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m9 18 6-6-6-6" /></svg>
72
+ <span class="sv-acc__label">{item.label}</span>
73
+ </button>
74
+ </h3>
75
+ {#if open}
76
+ <div class="sv-acc__panel" {...acc.panelProps(i)}>
77
+ <div class="sv-acc__body">{#if panel}{@render panel(item)}{/if}</div>
78
+ </div>
79
+ {/if}
80
+ </div>
81
+ {/each}
82
+ </div>
83
+
84
+ <style>
85
+ .sv-acc {
86
+ --_accent: var(--sg-accent, #2563eb);
87
+ --_border: var(--sg-border, #e2e8f0);
88
+ --_radius: var(--sg-radius, 8px);
89
+ display: flex; flex-direction: column; width: 100%;
90
+ background: var(--sg-bg, #fff); color: var(--sg-fg, #0f172a);
91
+ border: 1px solid var(--_border); border-radius: var(--_radius); overflow: hidden;
92
+ }
93
+ .sv-acc.is-disabled { opacity: 0.6; }
94
+ .sv-acc__item + .sv-acc__item { border-top: 1px solid var(--_border); }
95
+ .sv-acc__heading { margin: 0; font: inherit; }
96
+ .sv-acc__header {
97
+ display: flex; align-items: center; gap: 8px; width: 100%;
98
+ padding: 12px 14px; background: none; border: 0; font: inherit; font-size: 14px; font-weight: 600;
99
+ color: inherit; cursor: pointer; text-align: start;
100
+ }
101
+ .sv-acc__header:hover:not(:disabled) { background: var(--sg-row-hover-bg, #f1f5f9); }
102
+ .sv-acc__header:disabled { opacity: 0.5; cursor: not-allowed; }
103
+ .sv-acc__header:focus-visible { outline: 2px solid var(--sg-focus-ring, var(--_accent)); outline-offset: -2px; }
104
+ .sv-acc__chevron { flex: none; color: var(--sg-muted, #64748b); transition: transform 0.16s; }
105
+ .sv-acc__item.is-open .sv-acc__chevron { transform: rotate(90deg); }
106
+ .sv-acc[dir='rtl'] .sv-acc__item:not(.is-open) .sv-acc__chevron { transform: scaleX(-1); }
107
+ .sv-acc__label { flex: 1; }
108
+ .sv-acc__body { padding: 4px 14px 16px; font-size: 13.5px; line-height: 1.6; color: var(--sg-fg, #0f172a); }
109
+ </style>
@@ -0,0 +1,66 @@
1
+ /**
2
+ * Component tests for SvAccordion: single vs multiple expand, ARIA wiring
3
+ * (aria-expanded / aria-controls / region), and toggle behavior.
4
+ */
5
+ import { describe, expect, it } from 'vitest'
6
+ import { mount, unmount, flushSync } from 'svelte'
7
+ import { createRawSnippet } from 'svelte'
8
+ import SvAccordion from './SvAccordion.svelte'
9
+
10
+ const items = [
11
+ { id: 'a', label: 'First' },
12
+ { id: 'b', label: 'Second' },
13
+ { id: 'c', label: 'Third' },
14
+ ]
15
+
16
+ // A trivial panel snippet so the body renders.
17
+ const panel = createRawSnippet((item: () => { id: string; label: string }) => ({
18
+ render: () => `<p>body-${item().id}</p>`,
19
+ }))
20
+
21
+ function mountAcc(props: Record<string, unknown>) {
22
+ const target = document.createElement('div')
23
+ document.body.appendChild(target)
24
+ const app = mount(SvAccordion, { target, props: { panel, ...props } as any })
25
+ flushSync()
26
+ return { target, destroy: () => { unmount(app); target.remove() } }
27
+ }
28
+
29
+ describe('SvAccordion', () => {
30
+ it('renders headers with aria-expanded + aria-controls and shows only the open panel', () => {
31
+ const { target, destroy } = mountAcc({ items, expanded: ['a'] })
32
+ try {
33
+ const headers = [...target.querySelectorAll<HTMLButtonElement>('.sv-acc__header')]
34
+ expect(headers).toHaveLength(3)
35
+ expect(headers[0].getAttribute('aria-expanded')).toBe('true')
36
+ expect(headers[1].getAttribute('aria-expanded')).toBe('false')
37
+ const region = target.querySelector<HTMLElement>('.sv-acc__panel')!
38
+ expect(region.getAttribute('role')).toBe('region')
39
+ expect(region.getAttribute('aria-labelledby')).toBe(headers[0].id)
40
+ // Only one panel region is rendered (the open one).
41
+ expect(target.querySelectorAll('.sv-acc__panel')).toHaveLength(1)
42
+ } finally { destroy() }
43
+ })
44
+
45
+ it('single mode: opening one closes the previous', () => {
46
+ let got: string[] | undefined
47
+ const { target, destroy } = mountAcc({ items, expanded: ['a'], expandMode: 'single', onChange: (ids: string[]) => (got = ids) })
48
+ try {
49
+ const headers = target.querySelectorAll<HTMLButtonElement>('.sv-acc__header')
50
+ headers[1].click()
51
+ flushSync()
52
+ expect(got).toEqual(['b'])
53
+ } finally { destroy() }
54
+ })
55
+
56
+ it('multiple mode: toggling accumulates open panels', () => {
57
+ let got: string[] | undefined
58
+ const { target, destroy } = mountAcc({ items, expanded: ['a'], expandMode: 'multiple', onChange: (ids: string[]) => (got = ids) })
59
+ try {
60
+ const headers = target.querySelectorAll<HTMLButtonElement>('.sv-acc__header')
61
+ headers[2].click()
62
+ flushSync()
63
+ expect(got).toEqual(['a', 'c'])
64
+ } finally { destroy() }
65
+ })
66
+ })
@@ -0,0 +1,92 @@
1
+ <script lang="ts">
2
+ /**
3
+ * SvAlert - an inline, persistent contextual message (info / success / warning
4
+ * / danger / neutral) with an icon, optional title, dismiss button and trailing
5
+ * actions. Unlike SvToast (transient, floating), an alert stays in the layout.
6
+ * Theme-driven via `--sg-*` semantic tokens. Parity: Smart alert / message.
7
+ */
8
+ import type { Snippet } from 'svelte'
9
+
10
+ type Variant = 'info' | 'success' | 'warning' | 'danger' | 'neutral'
11
+
12
+ type Props = {
13
+ variant?: Variant
14
+ title?: string
15
+ /** Show a close (x) button. */
16
+ dismissible?: boolean
17
+ onDismiss?: () => void
18
+ /** Hide the leading status icon. */
19
+ hideIcon?: boolean
20
+ /** Softer, borderless tint vs the default bordered card. */
21
+ soft?: boolean
22
+ children?: Snippet
23
+ /** Trailing action buttons / links. */
24
+ actions?: Snippet
25
+ /** Custom leading icon (overrides the default glyph). */
26
+ icon?: Snippet
27
+ }
28
+
29
+ let {
30
+ variant = 'info',
31
+ title,
32
+ dismissible = false,
33
+ onDismiss,
34
+ hideIcon = false,
35
+ soft = false,
36
+ children,
37
+ actions,
38
+ icon,
39
+ }: Props = $props()
40
+
41
+ let open = $state(true)
42
+ function dismiss() { open = false; onDismiss?.() }
43
+ const glyph = (v: Variant) =>
44
+ v === 'success' ? '✓' : v === 'warning' ? '⚠' : v === 'danger' ? '✕' : v === 'neutral' ? '•' : 'ℹ'
45
+ </script>
46
+
47
+ {#if open}
48
+ <div
49
+ class="sv-alert sv-alert--{variant}"
50
+ class:is-soft={soft}
51
+ role={variant === 'danger' || variant === 'warning' ? 'alert' : 'status'}
52
+ >
53
+ {#if !hideIcon}
54
+ <span class="sv-alert__icon" aria-hidden="true">{#if icon}{@render icon()}{:else}{glyph(variant)}{/if}</span>
55
+ {/if}
56
+ <div class="sv-alert__body">
57
+ {#if title}<div class="sv-alert__title">{title}</div>{/if}
58
+ {#if children}<div class="sv-alert__msg">{@render children()}</div>{/if}
59
+ {#if actions}<div class="sv-alert__actions">{@render actions()}</div>{/if}
60
+ </div>
61
+ {#if dismissible}
62
+ <button type="button" class="sv-alert__x" aria-label="Dismiss" onclick={dismiss}>&times;</button>
63
+ {/if}
64
+ </div>
65
+ {/if}
66
+
67
+ <style>
68
+ .sv-alert {
69
+ --_c: var(--sg-info, #0891b2);
70
+ display: flex; align-items: flex-start; gap: 10px; box-sizing: border-box;
71
+ padding: 11px 12px; border-radius: 10px; font-size: 13px; line-height: 1.5;
72
+ background: var(--sg-bg, #fff); color: var(--sg-fg, #0f172a);
73
+ border: 1px solid color-mix(in srgb, var(--_c) 30%, var(--sg-border, #e2e8f0));
74
+ border-inline-start: 3px solid var(--_c);
75
+ }
76
+ .sv-alert.is-soft { border: 0; background: color-mix(in srgb, var(--_c) 12%, transparent); }
77
+ .sv-alert--info { --_c: var(--sg-info, #0891b2); }
78
+ .sv-alert--success { --_c: var(--sg-success, #16a34a); }
79
+ .sv-alert--warning { --_c: var(--sg-warning, #d97706); }
80
+ .sv-alert--danger { --_c: var(--sg-danger, #dc2626); }
81
+ .sv-alert--neutral { --_c: var(--sg-muted, #64748b); }
82
+ .sv-alert__icon { flex: none; width: 18px; height: 18px; display: grid; place-items: center; color: var(--_c); font-weight: 700; }
83
+ .sv-alert__body { flex: 1; min-width: 0; }
84
+ .sv-alert__title { font-weight: 650; margin-bottom: 1px; }
85
+ .sv-alert__msg { color: var(--sg-fg, #0f172a); overflow-wrap: anywhere; }
86
+ .sv-alert__actions { display: flex; gap: 8px; margin-top: 8px; }
87
+ .sv-alert__x {
88
+ flex: none; width: 22px; height: 22px; display: grid; place-items: center; margin: -2px -2px 0 0;
89
+ background: none; border: 0; color: var(--sg-muted, #64748b); cursor: pointer; border-radius: 5px; font-size: 17px; line-height: 1;
90
+ }
91
+ .sv-alert__x:hover { background: var(--sg-row-hover-bg, #f1f5f9); color: var(--sg-fg, #0f172a); }
92
+ </style>