sveltacular 0.0.77 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (376) hide show
  1. package/README.md +142 -15
  2. package/dist/forms/base-input-wrapper.svelte +99 -0
  3. package/dist/forms/base-input-wrapper.svelte.d.ts +15 -0
  4. package/dist/forms/bool-box/bool-box.svelte +30 -16
  5. package/dist/forms/bool-box/bool-box.svelte.d.ts +9 -23
  6. package/dist/forms/button/button.svelte +153 -89
  7. package/dist/forms/button/button.svelte.d.ts +25 -31
  8. package/dist/forms/check-box/check-box-group.svelte +69 -31
  9. package/dist/forms/check-box/check-box-group.svelte.d.ts +11 -29
  10. package/dist/forms/check-box/check-box.svelte +57 -33
  11. package/dist/forms/check-box/check-box.svelte.d.ts +15 -27
  12. package/dist/forms/check-box/index.d.ts +2 -0
  13. package/dist/forms/check-box/index.js +2 -0
  14. package/dist/forms/combo/new-or-existing-combo.svelte +37 -18
  15. package/dist/forms/combo/new-or-existing-combo.svelte.d.ts +15 -27
  16. package/dist/forms/combo-box/combo-box.svelte +643 -0
  17. package/dist/forms/combo-box/combo-box.svelte.d.ts +42 -0
  18. package/dist/forms/combo-box/index.d.ts +1 -0
  19. package/dist/forms/combo-box/index.js +1 -0
  20. package/dist/forms/date-box/date-box.svelte +82 -53
  21. package/dist/forms/date-box/date-box.svelte.d.ts +21 -34
  22. package/dist/forms/file-area/file-area.svelte +109 -57
  23. package/dist/forms/file-area/file-area.svelte.d.ts +12 -24
  24. package/dist/forms/file-box/file-box.svelte +38 -23
  25. package/dist/forms/file-box/file-box.svelte.d.ts +14 -27
  26. package/dist/forms/form-field.svelte +76 -13
  27. package/dist/forms/form-field.svelte.d.ts +15 -20
  28. package/dist/forms/form-footer.svelte +6 -3
  29. package/dist/forms/form-footer.svelte.d.ts +6 -28
  30. package/dist/forms/form-header.svelte +15 -4
  31. package/dist/forms/form-header.svelte.d.ts +8 -20
  32. package/dist/forms/form-label.svelte +15 -6
  33. package/dist/forms/form-label.svelte.d.ts +8 -21
  34. package/dist/forms/form-row.svelte +29 -0
  35. package/dist/forms/form-row.svelte.d.ts +7 -0
  36. package/dist/forms/form-section.svelte +15 -4
  37. package/dist/forms/form-section.svelte.d.ts +8 -20
  38. package/dist/forms/form.svelte +36 -13
  39. package/dist/forms/form.svelte.d.ts +11 -24
  40. package/dist/forms/index.d.ts +26 -0
  41. package/dist/forms/index.js +31 -0
  42. package/dist/forms/info-box/info-box.svelte +17 -10
  43. package/dist/forms/info-box/info-box.svelte.d.ts +8 -21
  44. package/dist/forms/list-box/index.d.ts +2 -0
  45. package/dist/forms/list-box/index.js +1 -0
  46. package/dist/forms/list-box/list-box.svelte +188 -111
  47. package/dist/forms/list-box/list-box.svelte.d.ts +16 -28
  48. package/dist/forms/money-box/money-box.svelte +224 -178
  49. package/dist/forms/money-box/money-box.svelte.d.ts +16 -30
  50. package/dist/forms/number-box/number-box.svelte +82 -62
  51. package/dist/forms/number-box/number-box.svelte.d.ts +17 -30
  52. package/dist/forms/phone-box/index.d.ts +1 -0
  53. package/dist/forms/phone-box/index.js +1 -0
  54. package/dist/forms/phone-box/phone-box.svelte +156 -116
  55. package/dist/forms/phone-box/phone-box.svelte.d.ts +8 -22
  56. package/dist/forms/radio-group/index.d.ts +2 -0
  57. package/dist/forms/radio-group/index.js +2 -0
  58. package/dist/forms/radio-group/radio-box.svelte +23 -8
  59. package/dist/forms/radio-group/radio-box.svelte.d.ts +10 -21
  60. package/dist/forms/radio-group/radio-group.svelte +25 -15
  61. package/dist/forms/radio-group/radio-group.svelte.d.ts +10 -23
  62. package/dist/forms/slider/slider.svelte +206 -0
  63. package/dist/forms/slider/slider.svelte.d.ts +17 -0
  64. package/dist/forms/switch-box/switch-box.svelte +35 -21
  65. package/dist/forms/switch-box/switch-box.svelte.d.ts +9 -22
  66. package/dist/forms/text-area/text-area.svelte +94 -17
  67. package/dist/forms/text-area/text-area.svelte.d.ts +15 -25
  68. package/dist/forms/text-box/text-box.svelte +244 -79
  69. package/dist/forms/text-box/text-box.svelte.d.ts +28 -38
  70. package/dist/forms/time-box/time-box.svelte +63 -0
  71. package/dist/forms/time-box/time-box.svelte.d.ts +12 -0
  72. package/dist/forms/url-box/url-box.svelte +32 -18
  73. package/dist/forms/url-box/url-box.svelte.d.ts +9 -22
  74. package/dist/forms/validation.d.ts +60 -0
  75. package/dist/forms/validation.js +123 -0
  76. package/dist/generic/address/address.svelte +22 -11
  77. package/dist/generic/address/address.svelte.d.ts +9 -21
  78. package/dist/generic/avatar/avatar.svelte +87 -0
  79. package/dist/generic/avatar/avatar.svelte.d.ts +10 -0
  80. package/dist/generic/badge/badge.svelte +82 -0
  81. package/dist/generic/badge/badge.svelte.d.ts +11 -0
  82. package/dist/generic/card/card-container.svelte +41 -12
  83. package/dist/generic/card/card-container.svelte.d.ts +8 -20
  84. package/dist/generic/card/card.svelte +47 -27
  85. package/dist/generic/card/card.svelte.d.ts +9 -21
  86. package/dist/generic/card/index.d.ts +3 -0
  87. package/dist/generic/card/index.js +2 -0
  88. package/dist/generic/chip/chip.svelte +91 -0
  89. package/dist/generic/chip/chip.svelte.d.ts +11 -0
  90. package/dist/generic/date/date-time.svelte +86 -58
  91. package/dist/generic/date/date-time.svelte.d.ts +10 -22
  92. package/dist/generic/divider/divider.svelte.d.ts +22 -21
  93. package/dist/generic/dot/dot.svelte +13 -4
  94. package/dist/generic/dot/dot.svelte.d.ts +7 -19
  95. package/dist/generic/dropdown-item/dropdown-item.svelte +24 -12
  96. package/dist/generic/dropdown-item/dropdown-item.svelte.d.ts +10 -23
  97. package/dist/generic/email/email.svelte +6 -4
  98. package/dist/generic/email/email.svelte.d.ts +5 -17
  99. package/dist/generic/empty/empty.svelte +57 -26
  100. package/dist/generic/empty/empty.svelte.d.ts +11 -23
  101. package/dist/generic/header/header.svelte +26 -10
  102. package/dist/generic/header/header.svelte.d.ts +10 -22
  103. package/dist/generic/index.d.ts +28 -0
  104. package/dist/generic/index.js +31 -0
  105. package/dist/generic/link/link.svelte +20 -7
  106. package/dist/generic/link/link.svelte.d.ts +11 -23
  107. package/dist/generic/list/index.d.ts +4 -0
  108. package/dist/generic/list/index.js +3 -0
  109. package/dist/generic/list/list-item.svelte +17 -13
  110. package/dist/generic/list/list-item.svelte.d.ts +6 -17
  111. package/dist/generic/list/list.d.ts +2 -2
  112. package/dist/generic/list/list.svelte +28 -15
  113. package/dist/generic/list/list.svelte.d.ts +9 -21
  114. package/dist/generic/menu/menu.svelte +163 -54
  115. package/dist/generic/menu/menu.svelte.d.ts +16 -26
  116. package/dist/generic/notice/notice.svelte +119 -80
  117. package/dist/generic/notice/notice.svelte.d.ts +17 -28
  118. package/dist/generic/overlay.svelte +40 -14
  119. package/dist/generic/overlay.svelte.d.ts +9 -21
  120. package/dist/generic/panel/panel.svelte +16 -6
  121. package/dist/generic/panel/panel.svelte.d.ts +8 -20
  122. package/dist/generic/phone/phone.svelte +30 -20
  123. package/dist/generic/phone/phone.svelte.d.ts +6 -18
  124. package/dist/generic/pill/pill.svelte +47 -33
  125. package/dist/generic/pill/pill.svelte.d.ts +10 -23
  126. package/dist/generic/popover/popover.svelte +226 -0
  127. package/dist/generic/popover/popover.svelte.d.ts +15 -0
  128. package/dist/generic/rating/rating.svelte +85 -0
  129. package/dist/generic/rating/rating.svelte.d.ts +11 -0
  130. package/dist/generic/scorecard/scorecard.svelte +34 -18
  131. package/dist/generic/scorecard/scorecard.svelte.d.ts +9 -21
  132. package/dist/generic/section/section.svelte +28 -9
  133. package/dist/generic/section/section.svelte.d.ts +11 -23
  134. package/dist/generic/spinner/spinner.svelte +64 -0
  135. package/dist/generic/spinner/spinner.svelte.d.ts +8 -0
  136. package/dist/generic/theme-provider/index.d.ts +1 -0
  137. package/dist/generic/theme-provider/index.js +1 -0
  138. package/dist/generic/theme-provider/theme-provider-demo.svelte +182 -0
  139. package/dist/generic/theme-provider/theme-provider-demo.svelte.d.ts +3 -0
  140. package/dist/generic/theme-provider/theme-provider.svelte +83 -0
  141. package/dist/generic/theme-provider/theme-provider.svelte.d.ts +44 -0
  142. package/dist/generic/toaster/toaster.svelte +31 -6
  143. package/dist/generic/toaster/toaster.svelte.d.ts +7 -17
  144. package/dist/generic/tooltip/tooltip.svelte +389 -0
  145. package/dist/generic/tooltip/tooltip.svelte.d.ts +21 -0
  146. package/dist/helpers/ago.d.ts +6 -0
  147. package/dist/helpers/ago.js +6 -0
  148. package/dist/helpers/animation-actions.d.ts +124 -0
  149. package/dist/helpers/animation-actions.js +299 -0
  150. package/dist/helpers/animations.d.ts +198 -0
  151. package/dist/helpers/animations.js +280 -0
  152. package/dist/helpers/announcer.d.ts +118 -0
  153. package/dist/helpers/announcer.js +250 -0
  154. package/dist/helpers/copy-to-clipboard.svelte.d.ts +5 -0
  155. package/dist/helpers/copy-to-clipboard.svelte.js +28 -0
  156. package/dist/helpers/debounce.d.ts +7 -0
  157. package/dist/helpers/debounce.js +7 -0
  158. package/dist/helpers/focus.d.ts +123 -0
  159. package/dist/helpers/focus.js +335 -0
  160. package/dist/helpers/fuzzy-search.d.ts +41 -0
  161. package/dist/helpers/fuzzy-search.js +114 -0
  162. package/dist/helpers/index.d.ts +24 -0
  163. package/dist/helpers/index.js +24 -0
  164. package/dist/helpers/navigate-to.d.ts +4 -0
  165. package/dist/helpers/navigate-to.js +4 -0
  166. package/dist/helpers/positioning.d.ts +97 -0
  167. package/dist/helpers/positioning.js +230 -0
  168. package/dist/helpers/round-to-decimals.d.ts +7 -5
  169. package/dist/helpers/round-to-decimals.js +7 -5
  170. package/dist/helpers/spring.svelte.d.ts +97 -0
  171. package/dist/helpers/spring.svelte.js +216 -0
  172. package/dist/helpers/subscribable.d.ts +1 -1
  173. package/dist/helpers/theme.svelte.d.ts +63 -0
  174. package/dist/helpers/theme.svelte.js +123 -0
  175. package/dist/helpers/unique-id.d.ts +4 -0
  176. package/dist/helpers/unique-id.js +4 -0
  177. package/dist/helpers/use-position.svelte.d.ts +96 -0
  178. package/dist/helpers/use-position.svelte.js +189 -0
  179. package/dist/helpers/use-virtual-list.svelte.d.ts +121 -0
  180. package/dist/helpers/use-virtual-list.svelte.js +239 -0
  181. package/dist/icons/angle-right-icon.svelte +2 -1
  182. package/dist/icons/angle-right-icon.svelte.d.ts +16 -14
  183. package/dist/icons/angle-up-icon.svelte.d.ts +22 -21
  184. package/dist/icons/check-icon.svelte.d.ts +22 -21
  185. package/dist/icons/copy-icon.svelte +46 -0
  186. package/dist/icons/copy-icon.svelte.d.ts +6 -0
  187. package/dist/icons/envelope-icon.svelte.d.ts +22 -21
  188. package/dist/icons/folder-open-icon.svelte.d.ts +22 -21
  189. package/dist/icons/hamburger-icon.svelte.d.ts +22 -21
  190. package/dist/icons/home-icon.svelte +2 -1
  191. package/dist/icons/home-icon.svelte.d.ts +16 -14
  192. package/dist/icons/index.d.ts +13 -0
  193. package/dist/icons/index.js +13 -0
  194. package/dist/icons/link-icon.svelte.d.ts +22 -21
  195. package/dist/icons/mobile-phone-icon.svelte.d.ts +22 -21
  196. package/dist/icons/phone-icon.svelte.d.ts +22 -21
  197. package/dist/icons/svg-icon.svelte +46 -10
  198. package/dist/icons/svg-icon.svelte.d.ts +13 -25
  199. package/dist/icons/upload-icon.svelte.d.ts +22 -21
  200. package/dist/images/icon.svelte +9 -3
  201. package/dist/images/icon.svelte.d.ts +6 -18
  202. package/dist/images/image.svelte +28 -8
  203. package/dist/images/image.svelte.d.ts +14 -28
  204. package/dist/images/index.d.ts +2 -0
  205. package/dist/images/index.js +2 -0
  206. package/dist/index.d.ts +13 -122
  207. package/dist/index.js +27 -135
  208. package/dist/layout/flex-col.svelte +65 -16
  209. package/dist/layout/flex-col.svelte.d.ts +12 -24
  210. package/dist/layout/flex-item.svelte +13 -3
  211. package/dist/layout/flex-item.svelte.d.ts +8 -20
  212. package/dist/layout/flex-row.svelte +70 -15
  213. package/dist/layout/flex-row.svelte.d.ts +14 -26
  214. package/dist/layout/grid.svelte +7 -1
  215. package/dist/layout/grid.svelte.d.ts +6 -28
  216. package/dist/layout/index.d.ts +4 -0
  217. package/dist/layout/index.js +4 -0
  218. package/dist/modals/alert.svelte +42 -28
  219. package/dist/modals/alert.svelte.d.ts +13 -26
  220. package/dist/modals/confirm.svelte +54 -37
  221. package/dist/modals/confirm.svelte.d.ts +16 -29
  222. package/dist/modals/dialog-body.svelte +10 -4
  223. package/dist/modals/dialog-body.svelte.d.ts +6 -28
  224. package/dist/modals/dialog-close-button.svelte +15 -9
  225. package/dist/modals/dialog-close-button.svelte.d.ts +6 -19
  226. package/dist/modals/dialog-footer.svelte +6 -3
  227. package/dist/modals/dialog-footer.svelte.d.ts +6 -28
  228. package/dist/modals/dialog-header.svelte +13 -1
  229. package/dist/modals/dialog-header.svelte.d.ts +7 -28
  230. package/dist/modals/dialog-window.svelte +42 -14
  231. package/dist/modals/dialog-window.svelte.d.ts +9 -19
  232. package/dist/modals/index.d.ts +9 -0
  233. package/dist/modals/index.js +9 -0
  234. package/dist/modals/modal.svelte +88 -23
  235. package/dist/modals/modal.svelte.d.ts +14 -24
  236. package/dist/modals/prompt.svelte +71 -49
  237. package/dist/modals/prompt.svelte.d.ts +19 -32
  238. package/dist/navigation/accordion/accordion.svelte +104 -0
  239. package/dist/navigation/accordion/accordion.svelte.d.ts +9 -0
  240. package/dist/navigation/app-bar/app-bar.svelte +26 -12
  241. package/dist/navigation/app-bar/app-bar.svelte.d.ts +10 -22
  242. package/dist/navigation/app-bar/app-branding.svelte +10 -5
  243. package/dist/navigation/app-bar/app-branding.svelte.d.ts +6 -17
  244. package/dist/navigation/app-bar/app-logo.svelte +20 -5
  245. package/dist/navigation/app-bar/app-logo.svelte.d.ts +9 -21
  246. package/dist/navigation/app-bar/app-nav-item.svelte +26 -13
  247. package/dist/navigation/app-bar/app-nav-item.svelte.d.ts +9 -22
  248. package/dist/navigation/app-bar/app-nav.svelte +39 -12
  249. package/dist/navigation/app-bar/app-nav.svelte.d.ts +8 -20
  250. package/dist/navigation/app-bar/index.d.ts +5 -0
  251. package/dist/navigation/app-bar/index.js +5 -0
  252. package/dist/navigation/breadcrumbs/breadcrumbs.svelte +54 -27
  253. package/dist/navigation/breadcrumbs/breadcrumbs.svelte.d.ts +12 -23
  254. package/dist/navigation/command-palette/command-palette.svelte +758 -0
  255. package/dist/navigation/command-palette/command-palette.svelte.d.ts +65 -0
  256. package/dist/navigation/command-palette/index.d.ts +2 -0
  257. package/dist/navigation/command-palette/index.js +1 -0
  258. package/dist/navigation/context-menu/README.md +147 -0
  259. package/dist/navigation/context-menu/context-menu-divider.svelte +22 -0
  260. package/dist/navigation/context-menu/context-menu-divider.svelte.d.ts +18 -0
  261. package/dist/navigation/context-menu/context-menu-item.svelte +268 -0
  262. package/dist/navigation/context-menu/context-menu-item.svelte.d.ts +19 -0
  263. package/dist/navigation/context-menu/context-menu.svelte +226 -0
  264. package/dist/navigation/context-menu/context-menu.svelte.d.ts +38 -0
  265. package/dist/navigation/context-menu/index.d.ts +3 -0
  266. package/dist/navigation/context-menu/index.js +3 -0
  267. package/dist/navigation/drawer/drawer.svelte +137 -0
  268. package/dist/navigation/drawer/drawer.svelte.d.ts +11 -0
  269. package/dist/navigation/dropdown-button/dropdown-button.svelte +58 -19
  270. package/dist/navigation/dropdown-button/dropdown-button.svelte.d.ts +10 -22
  271. package/dist/navigation/index.d.ts +11 -0
  272. package/dist/navigation/index.js +14 -0
  273. package/dist/navigation/pagination/pagination.svelte +55 -37
  274. package/dist/navigation/pagination/pagination.svelte.d.ts +10 -23
  275. package/dist/navigation/side-bar/side-bar.svelte +18 -9
  276. package/dist/navigation/side-bar/side-bar.svelte.d.ts +7 -19
  277. package/dist/navigation/tabs/index.d.ts +4 -0
  278. package/dist/navigation/tabs/index.js +3 -0
  279. package/dist/navigation/tabs/tab-context.d.ts +12 -6
  280. package/dist/navigation/tabs/tab-group.svelte +268 -52
  281. package/dist/navigation/tabs/tab-group.svelte.d.ts +9 -22
  282. package/dist/navigation/tabs/tab.svelte +64 -33
  283. package/dist/navigation/tabs/tab.svelte.d.ts +11 -24
  284. package/dist/navigation/wizard/index.d.ts +3 -0
  285. package/dist/navigation/wizard/index.js +2 -0
  286. package/dist/navigation/wizard/wizard-context.d.ts +13 -8
  287. package/dist/navigation/wizard/wizard-step.svelte +38 -13
  288. package/dist/navigation/wizard/wizard-step.svelte.d.ts +8 -20
  289. package/dist/navigation/wizard/wizard.svelte +123 -81
  290. package/dist/navigation/wizard/wizard.svelte.d.ts +15 -28
  291. package/dist/placeholders/index.d.ts +6 -0
  292. package/dist/placeholders/index.js +6 -0
  293. package/dist/placeholders/loading.svelte +39 -23
  294. package/dist/placeholders/loading.svelte.d.ts +10 -19
  295. package/dist/placeholders/progress.svelte +7 -6
  296. package/dist/placeholders/progress.svelte.d.ts +5 -17
  297. package/dist/placeholders/skeleton-input.svelte +66 -38
  298. package/dist/placeholders/skeleton-input.svelte.d.ts +5 -17
  299. package/dist/placeholders/skeleton-paragraph.svelte +25 -0
  300. package/dist/placeholders/skeleton-paragraph.svelte.d.ts +8 -0
  301. package/dist/placeholders/skeleton-table.svelte +75 -0
  302. package/dist/placeholders/skeleton-table.svelte.d.ts +8 -0
  303. package/dist/placeholders/skeleton-text.svelte +46 -15
  304. package/dist/placeholders/skeleton-text.svelte.d.ts +7 -19
  305. package/dist/tables/cell-renderers.d.ts +24 -0
  306. package/dist/tables/cell-renderers.js +228 -0
  307. package/dist/tables/data-grid.svelte +332 -118
  308. package/dist/tables/data-grid.svelte.d.ts +34 -35
  309. package/dist/tables/index.d.ts +10 -0
  310. package/dist/tables/index.js +12 -0
  311. package/dist/tables/table-caption.svelte +13 -4
  312. package/dist/tables/table-caption.svelte.d.ts +8 -20
  313. package/dist/tables/table-cell.svelte +45 -14
  314. package/dist/tables/table-cell.svelte.d.ts +10 -21
  315. package/dist/tables/table-context.svelte.d.ts +32 -0
  316. package/dist/tables/table-context.svelte.js +160 -0
  317. package/dist/tables/table-header-cell.svelte +158 -18
  318. package/dist/tables/table-header-cell.svelte.d.ts +15 -21
  319. package/dist/tables/table-header.svelte +31 -6
  320. package/dist/tables/table-header.svelte.d.ts +7 -28
  321. package/dist/tables/table-row.svelte +87 -7
  322. package/dist/tables/table-row.svelte.d.ts +10 -28
  323. package/dist/tables/table.svelte +61 -2
  324. package/dist/tables/table.svelte.d.ts +13 -28
  325. package/dist/test-utils/accessibility-helpers.d.ts +80 -0
  326. package/dist/test-utils/accessibility-helpers.js +220 -0
  327. package/dist/test-utils/index.d.ts +8 -0
  328. package/dist/test-utils/index.js +8 -0
  329. package/dist/test-utils/mock-helpers.d.ts +68 -0
  330. package/dist/test-utils/mock-helpers.js +165 -0
  331. package/dist/test-utils/render-helpers.d.ts +55 -0
  332. package/dist/test-utils/render-helpers.js +114 -0
  333. package/dist/test-utils/setup.d.ts +5 -0
  334. package/dist/test-utils/setup.js +91 -0
  335. package/dist/test-utils/test-data.d.ts +102 -0
  336. package/dist/test-utils/test-data.js +99 -0
  337. package/dist/timeline/index.d.ts +2 -0
  338. package/dist/timeline/index.js +2 -0
  339. package/dist/timeline/timeline-item.svelte +26 -9
  340. package/dist/timeline/timeline-item.svelte.d.ts +13 -25
  341. package/dist/timeline/timeline.svelte +12 -6
  342. package/dist/timeline/timeline.svelte.d.ts +6 -28
  343. package/dist/types/data.d.ts +61 -0
  344. package/dist/types/date.d.ts +1 -1
  345. package/dist/types/form.d.ts +20 -2
  346. package/dist/types/index.d.ts +5 -0
  347. package/dist/types/index.js +5 -0
  348. package/dist/types/size.d.ts +22 -0
  349. package/dist/types/size.js +22 -0
  350. package/dist/typography/code-block.svelte +89 -10
  351. package/dist/typography/code-block.svelte.d.ts +7 -19
  352. package/dist/typography/code.svelte +89 -0
  353. package/dist/typography/code.svelte.d.ts +7 -0
  354. package/dist/typography/headline.svelte +29 -9
  355. package/dist/typography/headline.svelte.d.ts +8 -20
  356. package/dist/typography/index.d.ts +6 -0
  357. package/dist/typography/index.js +6 -0
  358. package/dist/typography/paragraph.svelte +18 -10
  359. package/dist/typography/paragraph.svelte.d.ts +6 -28
  360. package/dist/typography/subtitle.svelte +18 -4
  361. package/dist/typography/subtitle.svelte.d.ts +8 -20
  362. package/dist/typography/text.svelte +20 -5
  363. package/dist/typography/text.svelte.d.ts +9 -21
  364. package/package.json +31 -21
  365. package/dist/navigation/accordian/accordian.svelte +0 -62
  366. package/dist/navigation/accordian/accordian.svelte.d.ts +0 -21
  367. package/dist/tables/table-body.svelte +0 -3
  368. package/dist/tables/table-body.svelte.d.ts +0 -29
  369. package/dist/tables/table-footer-cell.svelte +0 -22
  370. package/dist/tables/table-footer-cell.svelte.d.ts +0 -20
  371. package/dist/tables/table-footer-row.svelte +0 -3
  372. package/dist/tables/table-footer-row.svelte.d.ts +0 -29
  373. package/dist/tables/table-footer.svelte +0 -13
  374. package/dist/tables/table-footer.svelte.d.ts +0 -29
  375. package/dist/tables/table-header-row.svelte +0 -4
  376. package/dist/tables/table-header-row.svelte.d.ts +0 -29
@@ -0,0 +1,643 @@
1
+ <script lang="ts">
2
+ /**
3
+ * Combobox Component
4
+ *
5
+ * A searchable select component with typeahead, multi-select support, and virtual scrolling.
6
+ * Follows the ARIA 1.2 Combobox pattern for full accessibility.
7
+ *
8
+ * @component
9
+ * @example
10
+ * ```svelte
11
+ * <ComboBox
12
+ * bind:value
13
+ * items={[
14
+ * { value: '1', name: 'Option 1' },
15
+ * { value: '2', name: 'Option 2' }
16
+ * ]}
17
+ * label="Select an option"
18
+ * searchable
19
+ * />
20
+ * ```
21
+ */
22
+ import { untrack } from 'svelte';
23
+ import type { DropdownOption, FormFieldSizeOptions } from '../../types/form.js';
24
+ import FormField from '../form-field.svelte';
25
+ import { uniqueId } from '../../helpers/unique-id.js';
26
+ import Menu from '../../generic/menu/menu.svelte';
27
+ import AngleUpIcon from '../../icons/angle-up-icon.svelte';
28
+ import Chip from '../../generic/chip/chip.svelte';
29
+ import debounce from '../../helpers/debounce.js';
30
+ import { browser } from '$app/environment';
31
+ import { announce } from '../../helpers/announcer.js';
32
+
33
+ let {
34
+ value = $bindable(null as string | string[] | null),
35
+ items = [] as DropdownOption[],
36
+ size = 'full' as FormFieldSizeOptions,
37
+ disabled = false,
38
+ required = false,
39
+ searchable = true,
40
+ multiSelect = false,
41
+ placeholder = '',
42
+ label = undefined,
43
+ helperText = undefined,
44
+ errorText = undefined,
45
+ successText = undefined,
46
+ maxSelections = undefined as number | undefined,
47
+ virtualScroll = false,
48
+ itemHeight = 40,
49
+ closeOnSelect = true,
50
+ onChange = undefined as ((value: string | string[] | null) => void) | undefined,
51
+ onSearch = undefined as ((query: string) => Promise<DropdownOption[]> | DropdownOption[]) | undefined
52
+ }: {
53
+ /** Current selected value(s) - string for single-select, string[] for multi-select */
54
+ value?: string | string[] | null;
55
+ /** Available options to select from */
56
+ items?: DropdownOption[];
57
+ /** Size of the form field */
58
+ size?: FormFieldSizeOptions;
59
+ /** Whether the combobox is disabled */
60
+ disabled?: boolean;
61
+ /** Whether selection is required */
62
+ required?: boolean;
63
+ /** Whether to enable search/typeahead functionality */
64
+ searchable?: boolean;
65
+ /** Enable multi-select mode with chips */
66
+ multiSelect?: boolean;
67
+ /** Placeholder text for the input */
68
+ placeholder?: string;
69
+ /** Label text for the combobox */
70
+ label?: string;
71
+ /** Helper text displayed below the input */
72
+ helperText?: string;
73
+ /** Error message to display */
74
+ errorText?: string;
75
+ /** Success message to display */
76
+ successText?: string;
77
+ /** Maximum number of selections allowed (multi-select only) */
78
+ maxSelections?: number;
79
+ /** Enable virtual scrolling for large lists */
80
+ virtualScroll?: boolean;
81
+ /** Height of each item in pixels (for virtual scrolling) */
82
+ itemHeight?: number;
83
+ /** Close dropdown after selection (ignored in multi-select) */
84
+ closeOnSelect?: boolean;
85
+ /** Callback when value changes */
86
+ onChange?: (value: string | string[] | null) => void;
87
+ /** Async search function for dynamic options */
88
+ onSearch?: (query: string) => Promise<DropdownOption[]> | DropdownOption[];
89
+ } = $props();
90
+
91
+ const id = uniqueId();
92
+ const listboxId = `${id}-listbox`;
93
+
94
+ let searchQuery = $state('');
95
+ let isMenuOpen = $state(false);
96
+ let highlightIndex = $state(-1);
97
+ let filteredItems = $state<DropdownOption[]>([]);
98
+ let isSearching = $state(false);
99
+
100
+ // Normalize value to always be an array internally for multi-select
101
+ let selectedValues = $derived(
102
+ multiSelect
103
+ ? (Array.isArray(value) ? value : (value ? [value] : []))
104
+ : []
105
+ );
106
+
107
+ // Get selected items for chip display
108
+ let selectedItems = $derived(
109
+ multiSelect
110
+ ? items.filter((item) => selectedValues.includes(item.value as string))
111
+ : []
112
+ );
113
+
114
+ // Display text for single-select mode
115
+ let displayText = $derived(
116
+ !multiSelect && value
117
+ ? items.find((item) => item.value === value)?.name || ''
118
+ : ''
119
+ );
120
+
121
+ // Update search query when value changes in single-select mode
122
+ $effect(() => {
123
+ if (!multiSelect && !isMenuOpen) {
124
+ // When menu is closed, show the display text
125
+ searchQuery = displayText;
126
+ }
127
+ });
128
+
129
+ // Show placeholder when appropriate
130
+ let showPlaceholder = $derived(
131
+ !searchQuery &&
132
+ (!multiSelect ? !displayText : selectedValues.length === 0)
133
+ );
134
+
135
+ // Get the ID of the highlighted option for ARIA
136
+ let activeDescendant = $derived(
137
+ highlightIndex >= 0 && filteredItems[highlightIndex]
138
+ ? `${listboxId}-option-${highlightIndex}`
139
+ : undefined
140
+ );
141
+
142
+ // Check if max selections reached
143
+ let maxSelectionsReached = $derived(
144
+ multiSelect && maxSelections !== undefined && selectedValues.length >= maxSelections
145
+ );
146
+
147
+ /**
148
+ * Handle item selection
149
+ */
150
+ const onSelect = (item: DropdownOption) => {
151
+ if (disabled) return;
152
+
153
+ if (multiSelect) {
154
+ const itemValue = item.value as string;
155
+ let newValues: string[];
156
+
157
+ if (selectedValues.includes(itemValue)) {
158
+ // Deselect
159
+ newValues = selectedValues.filter((v) => v !== itemValue);
160
+ } else {
161
+ // Select (check max selections)
162
+ if (maxSelectionsReached) {
163
+ announce(`Maximum ${maxSelections} selections allowed`, { priority: 'polite' });
164
+ return;
165
+ }
166
+ newValues = [...selectedValues, itemValue];
167
+ }
168
+
169
+ value = newValues;
170
+ onChange?.(newValues);
171
+ announce(`${item.name} ${selectedValues.includes(itemValue) ? 'selected' : 'deselected'}`, { priority: 'polite' });
172
+ } else {
173
+ // Single select
174
+ value = item.value;
175
+ onChange?.(item.value);
176
+ searchQuery = '';
177
+ applyFilter();
178
+
179
+ if (closeOnSelect) {
180
+ isMenuOpen = false;
181
+ }
182
+
183
+ announce(`${item.name} selected`, { priority: 'polite' });
184
+ }
185
+ };
186
+
187
+ /**
188
+ * Remove a chip in multi-select mode
189
+ */
190
+ const removeChip = (itemValue: string) => {
191
+ if (disabled || !multiSelect) return;
192
+
193
+ const newValues = selectedValues.filter((v) => v !== itemValue);
194
+ value = newValues;
195
+ onChange?.(newValues);
196
+
197
+ const item = items.find((i) => i.value === itemValue);
198
+ if (item) {
199
+ announce(`${item.name} removed`, { priority: 'polite' });
200
+ }
201
+
202
+ focusOnInput();
203
+ };
204
+
205
+ /**
206
+ * Focus on the input element
207
+ */
208
+ const focusOnInput = () => {
209
+ if (browser) {
210
+ const input = document.getElementById(id) as HTMLInputElement;
211
+ input?.focus();
212
+ }
213
+ };
214
+
215
+ /**
216
+ * Toggle dropdown open/closed
217
+ */
218
+ const toggle = () => {
219
+ if (disabled) return;
220
+ isMenuOpen = !isMenuOpen;
221
+ if (isMenuOpen) {
222
+ focusOnInput();
223
+ highlightIndex = 0;
224
+ }
225
+ };
226
+
227
+ /**
228
+ * Clear all selections
229
+ */
230
+ const clear = () => {
231
+ if (disabled) return;
232
+
233
+ if (multiSelect) {
234
+ value = [];
235
+ onChange?.([]);
236
+ announce('All selections cleared', { priority: 'polite' });
237
+ } else {
238
+ value = null;
239
+ onChange?.(null);
240
+ searchQuery = '';
241
+ announce('Selection cleared', { priority: 'polite' });
242
+ }
243
+
244
+ applyFilter();
245
+ focusOnInput();
246
+ };
247
+
248
+ /**
249
+ * Handle keyboard navigation
250
+ */
251
+ const onInputKeyPress = (e: KeyboardEvent) => {
252
+ if (disabled) return;
253
+
254
+ switch (e.key) {
255
+ case 'Escape':
256
+ isMenuOpen = false;
257
+ searchQuery = '';
258
+ applyFilter();
259
+ break;
260
+
261
+ case 'Enter':
262
+ e.preventDefault();
263
+ if (isMenuOpen && highlightIndex >= 0 && highlightIndex < filteredItems.length) {
264
+ onSelect(filteredItems[highlightIndex]);
265
+ } else {
266
+ isMenuOpen = !isMenuOpen;
267
+ }
268
+ break;
269
+
270
+ case 'Tab':
271
+ if (isMenuOpen && highlightIndex >= 0 && highlightIndex < filteredItems.length) {
272
+ onSelect(filteredItems[highlightIndex]);
273
+ }
274
+ isMenuOpen = false;
275
+ break;
276
+
277
+ case 'ArrowDown':
278
+ e.preventDefault();
279
+ if (!isMenuOpen) {
280
+ isMenuOpen = true;
281
+ highlightIndex = 0;
282
+ } else {
283
+ highlightIndex = Math.min(highlightIndex + 1, filteredItems.length - 1);
284
+ }
285
+ break;
286
+
287
+ case 'ArrowUp':
288
+ e.preventDefault();
289
+ if (isMenuOpen) {
290
+ if (highlightIndex <= 0) {
291
+ isMenuOpen = false;
292
+ highlightIndex = -1;
293
+ } else {
294
+ highlightIndex = Math.max(highlightIndex - 1, 0);
295
+ }
296
+ }
297
+ break;
298
+
299
+ case 'Home':
300
+ if (isMenuOpen) {
301
+ e.preventDefault();
302
+ highlightIndex = 0;
303
+ }
304
+ break;
305
+
306
+ case 'End':
307
+ if (isMenuOpen) {
308
+ e.preventDefault();
309
+ highlightIndex = filteredItems.length - 1;
310
+ }
311
+ break;
312
+
313
+ case 'Backspace':
314
+ if (multiSelect && searchQuery === '' && selectedValues.length > 0) {
315
+ // Remove last chip on backspace when input is empty
316
+ removeChip(selectedValues[selectedValues.length - 1]);
317
+ }
318
+ break;
319
+
320
+ default:
321
+ // Any other key opens the menu and triggers search
322
+ if (e.key.length === 1) {
323
+ isMenuOpen = true;
324
+ if (highlightIndex === -1) {
325
+ highlightIndex = 0;
326
+ }
327
+ triggerSearch();
328
+ }
329
+ break;
330
+ }
331
+ };
332
+
333
+ /**
334
+ * Trigger search with debounce
335
+ */
336
+ const triggerSearch = debounce(async () => {
337
+ if (onSearch && searchable) {
338
+ isSearching = true;
339
+ try {
340
+ const results = await onSearch(searchQuery);
341
+ items = results;
342
+ } catch (error) {
343
+ console.error('Search error:', error);
344
+ } finally {
345
+ isSearching = false;
346
+ }
347
+ }
348
+ applyFilter();
349
+ }, 300);
350
+
351
+ /**
352
+ * Filter items based on search query
353
+ */
354
+ const applyFilter = () => {
355
+ const query = searchQuery.trim().toLowerCase();
356
+
357
+ if (query && searchable) {
358
+ filteredItems = items.filter((item) =>
359
+ item.name.toLowerCase().includes(query)
360
+ );
361
+ } else {
362
+ filteredItems = [...items];
363
+ }
364
+
365
+ // Reset highlight if out of bounds
366
+ if (highlightIndex >= filteredItems.length) {
367
+ highlightIndex = Math.max(0, filteredItems.length - 1);
368
+ }
369
+ };
370
+
371
+ // Filter items when items or searchQuery changes
372
+ // Use untrack to prevent reading filteredItems/highlightIndex from triggering the effect
373
+ $effect(() => {
374
+ // Track only the dependencies we care about
375
+ const query = searchQuery.trim().toLowerCase();
376
+ const currentItems = items;
377
+
378
+ // Use untrack to write to state without triggering this effect again
379
+ untrack(() => {
380
+ if (query && searchable) {
381
+ filteredItems = currentItems.filter((item) =>
382
+ item.name.toLowerCase().includes(query)
383
+ );
384
+ } else {
385
+ filteredItems = [...currentItems];
386
+ }
387
+
388
+ // Reset highlight if out of bounds
389
+ if (highlightIndex >= filteredItems.length) {
390
+ highlightIndex = Math.max(0, filteredItems.length - 1);
391
+ }
392
+ });
393
+ });
394
+
395
+ // Derived state for open/closed
396
+ let open = $derived(isMenuOpen && !disabled && filteredItems.length > 0);
397
+
398
+ // Clear search query when menu closes in single-select mode
399
+ $effect(() => {
400
+ if (!isMenuOpen && !multiSelect) {
401
+ // Use untrack to prevent triggering other effects
402
+ untrack(() => {
403
+ searchQuery = '';
404
+ });
405
+ }
406
+ });
407
+ </script>
408
+
409
+ <FormField {size} {label} {id} {required} {disabled} {helperText} {errorText} {successText}>
410
+ <div class="combobox-wrapper {open ? 'open' : 'closed'} {disabled ? 'disabled' : 'enabled'}">
411
+ <!-- Multi-select chip display -->
412
+ {#if multiSelect && selectedItems.length > 0}
413
+ <div class="chips" role="list" aria-label="Selected items">
414
+ {#each selectedItems as item (item.value)}
415
+ <div role="listitem">
416
+ <Chip
417
+ label={item.name}
418
+ removable={!disabled}
419
+ size="sm"
420
+ onRemove={() => removeChip(item.value as string)}
421
+ />
422
+ </div>
423
+ {/each}
424
+ </div>
425
+ {/if}
426
+
427
+ <!-- Input wrapper -->
428
+ <div class="input-wrapper">
429
+ <input
430
+ type="text"
431
+ {id}
432
+ bind:value={searchQuery}
433
+ {required}
434
+ {disabled}
435
+ placeholder={showPlaceholder ? placeholder : ''}
436
+ readonly={!searchable}
437
+ role="combobox"
438
+ aria-expanded={open}
439
+ aria-controls={listboxId}
440
+ aria-autocomplete={searchable ? 'list' : 'none'}
441
+ aria-activedescendant={activeDescendant}
442
+ aria-haspopup="listbox"
443
+ aria-label={label}
444
+ aria-describedby={helperText || errorText || successText ? `${id}-helper ${id}-error ${id}-success` : undefined}
445
+ aria-invalid={errorText ? 'true' : undefined}
446
+ onfocus={() => {
447
+ if (!disabled) {
448
+ isMenuOpen = true;
449
+ }
450
+ }}
451
+ onkeydown={onInputKeyPress}
452
+ oninput={() => {
453
+ if (searchable) {
454
+ triggerSearch();
455
+ }
456
+ }}
457
+ />
458
+
459
+ <!-- Clear button -->
460
+ {#if (multiSelect ? selectedValues.length > 0 : value) && !disabled}
461
+ <button
462
+ type="button"
463
+ class="clear-button"
464
+ onclick={clear}
465
+ aria-label="Clear all selections"
466
+ tabindex="-1"
467
+ >
468
+ ×
469
+ </button>
470
+ {/if}
471
+
472
+ <!-- Dropdown toggle button -->
473
+ <button
474
+ type="button"
475
+ class="toggle-button"
476
+ onclick={toggle}
477
+ {disabled}
478
+ aria-label={open ? 'Close options' : 'Open options'}
479
+ tabindex="-1"
480
+ >
481
+ <AngleUpIcon />
482
+ </button>
483
+
484
+ <!-- Loading indicator -->
485
+ {#if isSearching}
486
+ <div class="loading-indicator" aria-label="Searching...">
487
+ <span class="spinner"></span>
488
+ </div>
489
+ {/if}
490
+ </div>
491
+
492
+ <!-- Dropdown menu -->
493
+ <div class="dropdown">
494
+ <Menu
495
+ items={filteredItems.map((item, index) => ({ ...item, index }))}
496
+ {open}
497
+ closeAfterSelect={false}
498
+ searchText={searchQuery}
499
+ onSelect={onSelect}
500
+ size="full"
501
+ bind:highlightIndex
502
+ value={multiSelect ? null : (typeof value === 'string' ? value : null)}
503
+ {listboxId}
504
+ {virtualScroll}
505
+ {itemHeight}
506
+ />
507
+ </div>
508
+ </div>
509
+
510
+ <!-- Max selections indicator -->
511
+ {#if multiSelect && maxSelections !== undefined}
512
+ <div class="max-selections-indicator">
513
+ {selectedValues.length} / {maxSelections} selected
514
+ </div>
515
+ {/if}
516
+ </FormField>
517
+
518
+ <style>.combobox-wrapper {
519
+ position: relative;
520
+ }
521
+ .combobox-wrapper.disabled {
522
+ opacity: 0.5;
523
+ cursor: not-allowed;
524
+ pointer-events: none;
525
+ }
526
+
527
+ .chips {
528
+ display: flex;
529
+ flex-wrap: wrap;
530
+ gap: 0.5rem;
531
+ margin-bottom: 0.5rem;
532
+ padding: 0.5rem;
533
+ background-color: var(--form-input-bg);
534
+ border: var(--border-thin) solid var(--form-input-border);
535
+ border-radius: var(--radius-md);
536
+ min-height: 2.5rem;
537
+ }
538
+
539
+ .input-wrapper {
540
+ position: relative;
541
+ display: flex;
542
+ align-items: center;
543
+ }
544
+
545
+ input {
546
+ width: 100%;
547
+ padding: var(--spacing-sm) var(--spacing-base);
548
+ padding-right: 5rem; /* Space for buttons */
549
+ border-radius: var(--radius-md);
550
+ border: var(--border-thin) solid var(--form-input-border);
551
+ background-color: var(--form-input-bg);
552
+ color: var(--form-input-fg);
553
+ font-size: var(--font-base);
554
+ font-weight: 500;
555
+ line-height: 1.25rem;
556
+ transition: background-color var(--transition-base) var(--ease-in-out), border-color var(--transition-base) var(--ease-in-out), color var(--transition-base) var(--ease-in-out);
557
+ }
558
+ input:focus {
559
+ outline: none;
560
+ border-color: var(--primary);
561
+ }
562
+ input[aria-invalid=true] {
563
+ border-color: var(--danger);
564
+ }
565
+
566
+ button {
567
+ border: 0;
568
+ appearance: none;
569
+ background: transparent;
570
+ padding: 0;
571
+ margin: 0;
572
+ position: absolute;
573
+ width: 1rem;
574
+ height: 1rem;
575
+ color: var(--form-input-fg);
576
+ cursor: pointer;
577
+ z-index: 2;
578
+ }
579
+ button:hover {
580
+ opacity: 0.7;
581
+ }
582
+ button:focus-visible {
583
+ outline: 2px solid var(--focus-ring-color);
584
+ outline-offset: 2px;
585
+ border-radius: var(--radius-sm);
586
+ }
587
+
588
+ .clear-button {
589
+ right: 3rem;
590
+ font-size: 1.5rem;
591
+ line-height: 1;
592
+ top: 50%;
593
+ transform: translateY(-50%);
594
+ }
595
+
596
+ .toggle-button {
597
+ right: 1rem;
598
+ top: 50%;
599
+ transform: translateY(-50%) rotate(180deg);
600
+ transition: transform 0.3s var(--ease-in-out);
601
+ }
602
+ .open .toggle-button {
603
+ transform: translateY(-50%) rotate(0deg);
604
+ }
605
+
606
+ .loading-indicator {
607
+ position: absolute;
608
+ right: 5rem;
609
+ top: 50%;
610
+ transform: translateY(-50%);
611
+ z-index: 2;
612
+ }
613
+ .loading-indicator .spinner {
614
+ display: inline-block;
615
+ width: 1rem;
616
+ height: 1rem;
617
+ border: 2px solid var(--gray-300);
618
+ border-top-color: var(--primary);
619
+ border-radius: 50%;
620
+ animation: spin 0.6s linear infinite;
621
+ }
622
+
623
+ @keyframes spin {
624
+ to {
625
+ transform: rotate(360deg);
626
+ }
627
+ }
628
+ .dropdown {
629
+ position: absolute;
630
+ top: 100%;
631
+ left: 0;
632
+ width: 100%;
633
+ z-index: 1000;
634
+ margin-top: 0.25rem;
635
+ }
636
+
637
+ .max-selections-indicator {
638
+ margin-top: 0.5rem;
639
+ font-size: var(--font-sm);
640
+ color: var(--gray-600);
641
+ text-align: right;
642
+ }</style>
643
+
@@ -0,0 +1,42 @@
1
+ import type { DropdownOption, FormFieldSizeOptions } from '../../types/form.js';
2
+ type $$ComponentProps = {
3
+ /** Current selected value(s) - string for single-select, string[] for multi-select */
4
+ value?: string | string[] | null;
5
+ /** Available options to select from */
6
+ items?: DropdownOption[];
7
+ /** Size of the form field */
8
+ size?: FormFieldSizeOptions;
9
+ /** Whether the combobox is disabled */
10
+ disabled?: boolean;
11
+ /** Whether selection is required */
12
+ required?: boolean;
13
+ /** Whether to enable search/typeahead functionality */
14
+ searchable?: boolean;
15
+ /** Enable multi-select mode with chips */
16
+ multiSelect?: boolean;
17
+ /** Placeholder text for the input */
18
+ placeholder?: string;
19
+ /** Label text for the combobox */
20
+ label?: string;
21
+ /** Helper text displayed below the input */
22
+ helperText?: string;
23
+ /** Error message to display */
24
+ errorText?: string;
25
+ /** Success message to display */
26
+ successText?: string;
27
+ /** Maximum number of selections allowed (multi-select only) */
28
+ maxSelections?: number;
29
+ /** Enable virtual scrolling for large lists */
30
+ virtualScroll?: boolean;
31
+ /** Height of each item in pixels (for virtual scrolling) */
32
+ itemHeight?: number;
33
+ /** Close dropdown after selection (ignored in multi-select) */
34
+ closeOnSelect?: boolean;
35
+ /** Callback when value changes */
36
+ onChange?: (value: string | string[] | null) => void;
37
+ /** Async search function for dynamic options */
38
+ onSearch?: (query: string) => Promise<DropdownOption[]> | DropdownOption[];
39
+ };
40
+ declare const ComboBox: import("svelte").Component<$$ComponentProps, {}, "value">;
41
+ type ComboBox = ReturnType<typeof ComboBox>;
42
+ export default ComboBox;
@@ -0,0 +1 @@
1
+ export { default as ComboBox } from './combo-box.svelte';
@@ -0,0 +1 @@
1
+ export { default as ComboBox } from './combo-box.svelte';