@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
@@ -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,28 @@
1
+ export type { AccordionItem, AccordionExpandMode } from './createAccordion.svelte';
2
+ /**
3
+ * SvAccordion - a WAI-ARIA accordion (collapsible sections) with single- or
4
+ * multiple-expand and roving header focus (Up/Down/Home/End). Parity: Smart
5
+ * `smart-accordion`. Controlled via `expanded` + `onChange`; each panel's body
6
+ * is rendered through the `panel` snippet (receives the item).
7
+ *
8
+ * Behavior (expand state, keyboard, ARIA) lives in the headless `createAccordion`
9
+ * core; this component is one styled renderer over it.
10
+ */
11
+ import type { Snippet } from 'svelte';
12
+ import { type EditorDir } from './editor-contract';
13
+ import { type AccordionItem, type AccordionExpandMode } from './createAccordion.svelte';
14
+ type Props = {
15
+ items: ReadonlyArray<AccordionItem>;
16
+ /** Expanded item ids (controlled). */
17
+ expanded?: string[];
18
+ onChange?: (expandedIds: string[]) => void;
19
+ /** 'single' (at most one open) or 'multiple'. Default single. */
20
+ expandMode?: AccordionExpandMode;
21
+ disabled?: boolean;
22
+ dir?: EditorDir;
23
+ /** Panel body for an item. */
24
+ panel?: Snippet<[AccordionItem]>;
25
+ };
26
+ declare const SvAccordion: import("svelte").Component<Props, {}, "expanded">;
27
+ type SvAccordion = ReturnType<typeof SvAccordion>;
28
+ export default SvAccordion;
@@ -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>
@@ -0,0 +1,27 @@
1
+ /**
2
+ * SvAlert - an inline, persistent contextual message (info / success / warning
3
+ * / danger / neutral) with an icon, optional title, dismiss button and trailing
4
+ * actions. Unlike SvToast (transient, floating), an alert stays in the layout.
5
+ * Theme-driven via `--sg-*` semantic tokens. Parity: Smart alert / message.
6
+ */
7
+ import type { Snippet } from 'svelte';
8
+ type Variant = 'info' | 'success' | 'warning' | 'danger' | 'neutral';
9
+ type Props = {
10
+ variant?: Variant;
11
+ title?: string;
12
+ /** Show a close (x) button. */
13
+ dismissible?: boolean;
14
+ onDismiss?: () => void;
15
+ /** Hide the leading status icon. */
16
+ hideIcon?: boolean;
17
+ /** Softer, borderless tint vs the default bordered card. */
18
+ soft?: boolean;
19
+ children?: Snippet;
20
+ /** Trailing action buttons / links. */
21
+ actions?: Snippet;
22
+ /** Custom leading icon (overrides the default glyph). */
23
+ icon?: Snippet;
24
+ };
25
+ declare const SvAlert: import("svelte").Component<Props, {}, "">;
26
+ type SvAlert = ReturnType<typeof SvAlert>;
27
+ export default SvAlert;
@@ -7,24 +7,43 @@
7
7
  * One styled renderer over the headless `createAutocomplete` core; only
8
8
  * portal/measure render concerns live here.
9
9
  */
10
- import { anchoredRect, portalToBody, type AnchoredRect } from './popover'
10
+ import { anchoredRect, portalToBody, popIn, type AnchoredRect } from './popover'
11
+ import { createDismissableLayer } from './a11y/dismissable'
11
12
  import { type ListOption } from './list-option'
13
+ import SvField from './SvField.svelte'
14
+ import { nextEditorId, type SvEditorProps } from './editor-contract'
12
15
  import { createAutocomplete } from './createAutocomplete.svelte'
13
16
 
14
- type Props = {
17
+ type Props = SvEditorProps & {
15
18
  value?: string
16
19
  onChange?: (value: string) => void
17
20
  /** Suggestions - strings or {value,label} (label is shown, value inserted). */
18
21
  suggestions?: ReadonlyArray<string | ListOption>
19
22
  minChars?: number
20
23
  placeholder?: string
21
- disabled?: boolean
22
- name?: string
23
- size?: 'sm' | 'md' | 'lg'
24
- ariaLabel?: string
25
24
  }
26
25
 
27
- let { value = '', onChange, suggestions = [], minChars = 1, placeholder, disabled = false, name, size = 'md', ariaLabel }: Props = $props()
26
+ let {
27
+ value = '',
28
+ onChange,
29
+ suggestions = [],
30
+ minChars = 1,
31
+ placeholder,
32
+ disabled = false,
33
+ name,
34
+ size = 'md',
35
+ ariaLabel,
36
+ invalid = false,
37
+ required = false,
38
+ error,
39
+ label,
40
+ hint,
41
+ dir,
42
+ id,
43
+ }: Props = $props()
44
+
45
+ const autoId = nextEditorId('sv-ac')
46
+ const uid = $derived(id ?? autoId)
28
47
 
29
48
  let fieldEl = $state<HTMLInputElement | null>(null)
30
49
  let panelEl = $state<HTMLDivElement | null>(null)
@@ -38,6 +57,11 @@
38
57
  disabled: () => disabled,
39
58
  ariaLabel: () => ariaLabel,
40
59
  focusInput: () => fieldEl?.focus(),
60
+ id: () => uid,
61
+ invalid: () => invalid,
62
+ required: () => required,
63
+ error: () => error,
64
+ hint: () => hint,
41
65
  })
42
66
 
43
67
  function updatePos() {
@@ -50,22 +74,25 @@
50
74
  updatePos()
51
75
  const rp = () => updatePos()
52
76
  window.addEventListener('scroll', rp, true); window.addEventListener('resize', rp)
53
- const od = (e: PointerEvent) => { const t = e.target as Node | null; if (t && (fieldEl?.contains(t) || panelEl?.contains(t))) return; ac.close() }
54
- document.addEventListener('pointerdown', od, true)
55
- return () => { window.removeEventListener('scroll', rp, true); window.removeEventListener('resize', rp); document.removeEventListener('pointerdown', od, true) }
77
+ const layer = createDismissableLayer({ element: () => [fieldEl, panelEl], onDismiss: () => ac.close(), closeOnEscape: false })
78
+ layer.activate()
79
+ return () => { window.removeEventListener('scroll', rp, true); window.removeEventListener('resize', rp); layer.release() }
56
80
  })
57
81
  </script>
58
82
 
59
- <input
60
- bind:this={fieldEl}
61
- class="sv-ac sv-ac--{size}"
62
- type="text"
63
- {placeholder}
64
- {...ac.inputProps()}
65
- />
83
+ <SvField id={uid} {label} {hint} {error} {required} {dir}>
84
+ <input
85
+ bind:this={fieldEl}
86
+ class="sv-ac sv-ac--{size}"
87
+ class:is-invalid={invalid}
88
+ type="text"
89
+ {placeholder}
90
+ {...ac.inputProps()}
91
+ />
92
+ </SvField>
66
93
 
67
94
  {#if ac.open}
68
- <div bind:this={panelEl} class="sv-ddl__panel" use:portalToBody style:position="fixed" style:top={`${rect.top}px`} style:left={`${rect.left}px`} style:min-width={`${rect.width}px`} {...ac.listboxProps()}>
95
+ <div bind:this={panelEl} class="sv-ddl__panel" use:portalToBody use:popIn={{ up: rect.openUpward }} style:position="fixed" style:top={`${rect.top}px`} style:left={`${rect.left}px`} style:min-width={`${rect.width}px`} {...ac.listboxProps()}>
69
96
  {#each ac.filtered as opt, i (opt.value)}
70
97
  <!-- svelte-ignore a11y_click_events_have_key_events a11y_interactive_supports_focus -->
71
98
  <div class="sv-ddl__opt" class:is-active={ac.isActive(i)} {...ac.optionProps(i)}>{opt.label}</div>
@@ -86,4 +113,6 @@
86
113
  .sv-ac--md { height: 34px; font-size: 13px; }
87
114
  .sv-ac--lg { height: 40px; font-size: 15px; }
88
115
  .sv-ac:focus { border-color: var(--_accent); box-shadow: 0 0 0 2px color-mix(in srgb, var(--_accent) 22%, transparent); }
116
+ .sv-ac.is-invalid { border-color: var(--sg-danger, #dc2626); }
117
+ .sv-ac.is-invalid:focus { box-shadow: 0 0 0 2px color-mix(in srgb, var(--sg-danger, #dc2626) 22%, transparent); }
89
118
  </style>
@@ -1,15 +1,12 @@
1
1
  import { type ListOption } from './list-option';
2
- type Props = {
2
+ import { type SvEditorProps } from './editor-contract';
3
+ type Props = SvEditorProps & {
3
4
  value?: string;
4
5
  onChange?: (value: string) => void;
5
6
  /** Suggestions - strings or {value,label} (label is shown, value inserted). */
6
7
  suggestions?: ReadonlyArray<string | ListOption>;
7
8
  minChars?: number;
8
9
  placeholder?: string;
9
- disabled?: boolean;
10
- name?: string;
11
- size?: 'sm' | 'md' | 'lg';
12
- ariaLabel?: string;
13
10
  };
14
11
  declare const SvAutoComplete: import("svelte").Component<Props, {}, "">;
15
12
  type SvAutoComplete = ReturnType<typeof SvAutoComplete>;
@@ -0,0 +1,75 @@
1
+ <script lang="ts">
2
+ /**
3
+ * SvAvatar - a user/entity avatar: an image with an initials + colour-hash
4
+ * fallback (used when there is no `src` or the image fails to load), plus an
5
+ * optional presence status dot. Parity: Smart avatar.
6
+ *
7
+ * ```svelte
8
+ * <SvAvatar name="Ada Lovelace" src="/ada.jpg" status="online" />
9
+ * ```
10
+ */
11
+ import { avatarInitials, avatarColorHue } from './avatar'
12
+
13
+ type Props = {
14
+ name?: string
15
+ src?: string
16
+ alt?: string
17
+ /** Preset (sm 28 / md 36 / lg 48) or an explicit pixel size. */
18
+ size?: 'sm' | 'md' | 'lg' | number
19
+ shape?: 'circle' | 'square'
20
+ status?: 'online' | 'offline' | 'busy' | 'away'
21
+ /** Override the hash-derived fallback colour (any CSS colour). */
22
+ color?: string
23
+ }
24
+
25
+ let { name = '', src, alt, size = 'md', shape = 'circle', status, color }: Props = $props()
26
+
27
+ const px = $derived(typeof size === 'number' ? size : size === 'sm' ? 28 : size === 'lg' ? 48 : 36)
28
+ const initials = $derived(avatarInitials(name))
29
+ const bg = $derived(color ?? `hsl(${avatarColorHue(name || '?')} 62% 45%)`)
30
+ // Fall back to initials when the image errors.
31
+ let broken = $state(false)
32
+ const showImg = $derived(!!src && !broken)
33
+ </script>
34
+
35
+ <span
36
+ class="sv-avatar sv-avatar--{shape}"
37
+ style:width={`${px}px`}
38
+ style:height={`${px}px`}
39
+ style:font-size={`${Math.round(px * 0.4)}px`}
40
+ style:background={showImg ? undefined : bg}
41
+ role="img"
42
+ aria-label={alt ?? (name || 'avatar')}
43
+ title={name || undefined}
44
+ >
45
+ {#if showImg}
46
+ <img class="sv-avatar__img" src={src} alt={alt ?? name} onerror={() => (broken = true)} />
47
+ {:else if initials}
48
+ <span class="sv-avatar__initials" aria-hidden="true">{initials}</span>
49
+ {:else}
50
+ <svg class="sv-avatar__ph" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d="M12 12a5 5 0 1 0 0-10 5 5 0 0 0 0 10Zm0 2c-4.4 0-8 2.5-8 5.5V22h16v-2.5C20 16.5 16.4 14 12 14Z" /></svg>
51
+ {/if}
52
+ {#if status}<span class="sv-avatar__status is-{status}" aria-hidden="true"></span>{/if}
53
+ </span>
54
+
55
+ <style>
56
+ .sv-avatar {
57
+ position: relative; display: inline-grid; place-items: center; overflow: visible;
58
+ color: #fff; font-weight: 600; line-height: 1; user-select: none; flex: none;
59
+ vertical-align: middle;
60
+ }
61
+ .sv-avatar--circle { border-radius: 50%; }
62
+ .sv-avatar--square { border-radius: 22%; }
63
+ .sv-avatar__img { width: 100%; height: 100%; object-fit: cover; border-radius: inherit; display: block; }
64
+ .sv-avatar--circle .sv-avatar__img, .sv-avatar--circle { }
65
+ .sv-avatar__initials { letter-spacing: 0.02em; }
66
+ .sv-avatar__ph { width: 62%; height: 62%; opacity: 0.9; }
67
+ .sv-avatar__status {
68
+ position: absolute; right: -1px; bottom: -1px; width: 28%; height: 28%; min-width: 8px; min-height: 8px;
69
+ border-radius: 50%; border: 2px solid var(--sg-bg, #fff);
70
+ }
71
+ .sv-avatar__status.is-online { background: var(--sg-success, #16a34a); }
72
+ .sv-avatar__status.is-offline { background: var(--sg-muted, #94a3b8); }
73
+ .sv-avatar__status.is-busy { background: var(--sg-danger, #dc2626); }
74
+ .sv-avatar__status.is-away { background: var(--sg-warning, #f59e0b); }
75
+ </style>
@@ -0,0 +1,14 @@
1
+ type Props = {
2
+ name?: string;
3
+ src?: string;
4
+ alt?: string;
5
+ /** Preset (sm 28 / md 36 / lg 48) or an explicit pixel size. */
6
+ size?: 'sm' | 'md' | 'lg' | number;
7
+ shape?: 'circle' | 'square';
8
+ status?: 'online' | 'offline' | 'busy' | 'away';
9
+ /** Override the hash-derived fallback colour (any CSS colour). */
10
+ color?: string;
11
+ };
12
+ declare const SvAvatar: import("svelte").Component<Props, {}, "">;
13
+ type SvAvatar = ReturnType<typeof SvAvatar>;
14
+ export default SvAvatar;
@@ -0,0 +1,48 @@
1
+ <script lang="ts">
2
+ /**
3
+ * SvAvatarGroup - overlapping stacked avatars with a "+N" overflow pill, for
4
+ * "assigned to" / "members" rows. Each entry is a set of SvAvatar props.
5
+ *
6
+ * ```svelte
7
+ * <SvAvatarGroup max={3} avatars={[{ name: 'Ada' }, { name: 'Alan' }, { name: 'Grace' }, { name: 'Ken' }]} />
8
+ * ```
9
+ */
10
+ import SvAvatar from './SvAvatar.svelte'
11
+
12
+ type AvatarProps = { name?: string; src?: string; alt?: string; color?: string }
13
+ type Size = 'sm' | 'md' | 'lg' | number
14
+
15
+ type Props = {
16
+ avatars: ReadonlyArray<AvatarProps>
17
+ /** Max avatars shown before collapsing to "+N". */
18
+ max?: number
19
+ size?: Size
20
+ }
21
+
22
+ let { avatars, max = 4, size = 'md' }: Props = $props()
23
+
24
+ const shown = $derived(avatars.slice(0, max))
25
+ const overflow = $derived(Math.max(0, avatars.length - max))
26
+ const px = $derived(typeof size === 'number' ? size : size === 'sm' ? 28 : size === 'lg' ? 48 : 36)
27
+ const overlap = $derived(Math.round(px * 0.28))
28
+ </script>
29
+
30
+ <div class="sv-avgroup" role="group" style:--ov={`${overlap}px`}>
31
+ {#each shown as a, i (i)}
32
+ <span class="sv-avgroup__it" style:z-index={shown.length - i}><SvAvatar {...a} {size} /></span>
33
+ {/each}
34
+ {#if overflow}
35
+ <span class="sv-avgroup__more" style:width={`${px}px`} style:height={`${px}px`} style:font-size={`${Math.round(px * 0.36)}px`}>+{overflow}</span>
36
+ {/if}
37
+ </div>
38
+
39
+ <style>
40
+ .sv-avgroup { display: inline-flex; align-items: center; }
41
+ .sv-avgroup__it { display: inline-flex; margin-inline-start: calc(-1 * var(--ov, 10px)); border-radius: 50%; box-shadow: 0 0 0 2px var(--sg-bg, #fff); }
42
+ .sv-avgroup__it:first-child { margin-inline-start: 0; }
43
+ .sv-avgroup__more {
44
+ display: grid; place-items: center; margin-inline-start: calc(-1 * var(--ov, 10px)); border-radius: 50%;
45
+ background: var(--sg-row-hover-bg, #e2e8f0); color: var(--sg-muted, #64748b); font-weight: 650;
46
+ box-shadow: 0 0 0 2px var(--sg-bg, #fff);
47
+ }
48
+ </style>
@@ -0,0 +1,16 @@
1
+ type AvatarProps = {
2
+ name?: string;
3
+ src?: string;
4
+ alt?: string;
5
+ color?: string;
6
+ };
7
+ type Size = 'sm' | 'md' | 'lg' | number;
8
+ type Props = {
9
+ avatars: ReadonlyArray<AvatarProps>;
10
+ /** Max avatars shown before collapsing to "+N". */
11
+ max?: number;
12
+ size?: Size;
13
+ };
14
+ declare const SvAvatarGroup: import("svelte").Component<Props, {}, "">;
15
+ type SvAvatarGroup = ReturnType<typeof SvAvatarGroup>;
16
+ export default SvAvatarGroup;
@@ -0,0 +1,54 @@
1
+ <script lang="ts">
2
+ /**
3
+ * SvBadge - a small status pill / count label. Themed via `--sg-*` tokens with
4
+ * soft `color-mix` tints so it sits well on light and dark. Parity: Smart badge.
5
+ *
6
+ * ```svelte
7
+ * <SvBadge variant="success">Active</SvBadge>
8
+ * <SvBadge variant="danger" dot /> 3 failed
9
+ * ```
10
+ */
11
+ import type { Snippet } from 'svelte'
12
+
13
+ type Variant = 'neutral' | 'accent' | 'success' | 'warning' | 'danger' | 'info'
14
+
15
+ type Props = {
16
+ variant?: Variant
17
+ size?: 'sm' | 'md'
18
+ /** Rounded-pill shape (default) vs a softer rounded rect. */
19
+ pill?: boolean
20
+ /** Show a leading status dot instead of / before content. */
21
+ dot?: boolean
22
+ children?: Snippet
23
+ }
24
+
25
+ let { variant = 'neutral', size = 'md', pill = true, dot = false, children }: Props = $props()
26
+ </script>
27
+
28
+ <span class="sv-badge sv-badge--{variant} sv-badge--{size}" class:is-pill={pill} class:has-dot={dot}>
29
+ {#if dot}<span class="sv-badge__dot" aria-hidden="true"></span>{/if}
30
+ {@render children?.()}
31
+ </span>
32
+
33
+ <style>
34
+ .sv-badge {
35
+ --_c: var(--sg-muted, #64748b);
36
+ display: inline-flex; align-items: center; gap: 5px; box-sizing: border-box;
37
+ font-weight: 600; line-height: 1; white-space: nowrap;
38
+ color: var(--_c);
39
+ background: color-mix(in srgb, var(--_c) 14%, transparent);
40
+ border: 1px solid color-mix(in srgb, var(--_c) 26%, transparent);
41
+ border-radius: 6px;
42
+ }
43
+ .sv-badge.is-pill { border-radius: 999px; }
44
+ .sv-badge--sm { font-size: 10.5px; padding: 2px 7px; }
45
+ .sv-badge--md { font-size: 12px; padding: 3px 9px; }
46
+ .sv-badge__dot { width: 6px; height: 6px; border-radius: 50%; background: var(--_c); }
47
+
48
+ .sv-badge--neutral { --_c: var(--sg-muted, #64748b); }
49
+ .sv-badge--accent { --_c: var(--sg-accent, #2563eb); }
50
+ .sv-badge--success { --_c: var(--sg-success, #16a34a); }
51
+ .sv-badge--warning { --_c: var(--sg-warning, #d97706); }
52
+ .sv-badge--danger { --_c: var(--sg-danger, #dc2626); }
53
+ .sv-badge--info { --_c: var(--sg-info, #0891b2); }
54
+ </style>
@@ -0,0 +1,23 @@
1
+ /**
2
+ * SvBadge - a small status pill / count label. Themed via `--sg-*` tokens with
3
+ * soft `color-mix` tints so it sits well on light and dark. Parity: Smart badge.
4
+ *
5
+ * ```svelte
6
+ * <SvBadge variant="success">Active</SvBadge>
7
+ * <SvBadge variant="danger" dot /> 3 failed
8
+ * ```
9
+ */
10
+ import type { Snippet } from 'svelte';
11
+ type Variant = 'neutral' | 'accent' | 'success' | 'warning' | 'danger' | 'info';
12
+ type Props = {
13
+ variant?: Variant;
14
+ size?: 'sm' | 'md';
15
+ /** Rounded-pill shape (default) vs a softer rounded rect. */
16
+ pill?: boolean;
17
+ /** Show a leading status dot instead of / before content. */
18
+ dot?: boolean;
19
+ children?: Snippet;
20
+ };
21
+ declare const SvBadge: import("svelte").Component<Props, {}, "">;
22
+ type SvBadge = ReturnType<typeof SvBadge>;
23
+ export default SvBadge;