zabi-components 7.0.2 → 8.1.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 (433) hide show
  1. package/CHANGELOG.md +1924 -0
  2. package/README.md +287 -11
  3. package/THEME.md +149 -332
  4. package/THEMING.md +1329 -163
  5. package/dist/atoms/ActionPanel.svelte +24 -9
  6. package/dist/atoms/ActionPanel.svelte.d.ts +2 -0
  7. package/dist/atoms/Avatar.svelte +104 -0
  8. package/dist/atoms/Avatar.svelte.d.ts +34 -0
  9. package/dist/atoms/Badge.svelte +124 -58
  10. package/dist/atoms/Badge.svelte.d.ts +17 -5
  11. package/dist/atoms/Button.svelte +212 -62
  12. package/dist/atoms/Button.svelte.d.ts +33 -2
  13. package/dist/atoms/Card.svelte +31 -28
  14. package/dist/atoms/Card.svelte.d.ts +5 -2
  15. package/dist/atoms/CardContent.svelte +10 -2
  16. package/dist/atoms/CardContent.svelte.d.ts +2 -0
  17. package/dist/atoms/CardFooter.svelte +10 -2
  18. package/dist/atoms/CardFooter.svelte.d.ts +2 -0
  19. package/dist/atoms/CardHeader.svelte +26 -6
  20. package/dist/atoms/CardHeader.svelte.d.ts +2 -0
  21. package/dist/atoms/Checkbox.svelte +52 -21
  22. package/dist/atoms/Checkbox.svelte.d.ts +6 -2
  23. package/dist/atoms/CodeBlock.svelte +35 -9
  24. package/dist/atoms/CodeBlock.svelte.d.ts +13 -3
  25. package/dist/atoms/ColorPicker.svelte +272 -52
  26. package/dist/atoms/ColorPicker.svelte.d.ts +6 -1
  27. package/dist/atoms/Container.svelte +17 -10
  28. package/dist/atoms/DateField.svelte +107 -0
  29. package/dist/atoms/DateField.svelte.d.ts +53 -0
  30. package/dist/atoms/Divider.svelte +4 -4
  31. package/dist/atoms/FeatureCard.svelte +4 -3
  32. package/dist/atoms/FieldMessages.svelte +69 -0
  33. package/dist/atoms/FieldMessages.svelte.d.ts +23 -0
  34. package/dist/atoms/FloatingActionButton.svelte +174 -0
  35. package/dist/atoms/FloatingActionButton.svelte.d.ts +51 -0
  36. package/dist/atoms/Heading.svelte +93 -32
  37. package/dist/atoms/Heading.svelte.d.ts +24 -4
  38. package/dist/atoms/IconButton.svelte +242 -53
  39. package/dist/atoms/IconButton.svelte.d.ts +49 -4
  40. package/dist/atoms/Input.svelte +267 -74
  41. package/dist/atoms/Input.svelte.d.ts +32 -2
  42. package/dist/atoms/List.svelte +13 -2
  43. package/dist/atoms/List.svelte.d.ts +2 -0
  44. package/dist/atoms/ListItem.svelte +44 -11
  45. package/dist/atoms/ListItem.svelte.d.ts +5 -0
  46. package/dist/atoms/ListItemLeading.svelte +4 -2
  47. package/dist/atoms/ListItemLeading.svelte.d.ts +1 -1
  48. package/dist/atoms/OptimizedImage.svelte +11 -2
  49. package/dist/atoms/OptimizedImage.svelte.d.ts +2 -0
  50. package/dist/atoms/Progress.svelte +31 -9
  51. package/dist/atoms/Progress.svelte.d.ts +6 -0
  52. package/dist/atoms/Radio.svelte +23 -3
  53. package/dist/atoms/Radio.svelte.d.ts +6 -2
  54. package/dist/atoms/Rating.svelte +494 -0
  55. package/dist/atoms/Rating.svelte.d.ts +56 -0
  56. package/dist/atoms/Select.svelte +475 -135
  57. package/dist/atoms/Select.svelte.d.ts +52 -2
  58. package/dist/atoms/SelectionControl.svelte +99 -18
  59. package/dist/atoms/SelectionControl.svelte.d.ts +6 -3
  60. package/dist/atoms/Skeleton.svelte +5 -3
  61. package/dist/atoms/Slider.svelte +309 -0
  62. package/dist/atoms/Slider.svelte.d.ts +40 -0
  63. package/dist/atoms/Spinner.svelte +57 -0
  64. package/dist/atoms/Spinner.svelte.d.ts +19 -0
  65. package/dist/atoms/Table.svelte +152 -6
  66. package/dist/atoms/Table.svelte.d.ts +15 -3
  67. package/dist/atoms/TemporalField.svelte +140 -0
  68. package/dist/atoms/TemporalField.svelte.d.ts +32 -0
  69. package/dist/atoms/Text.svelte +56 -15
  70. package/dist/atoms/Text.svelte.d.ts +13 -4
  71. package/dist/atoms/Textarea.svelte +57 -45
  72. package/dist/atoms/Textarea.svelte.d.ts +14 -2
  73. package/dist/atoms/ThemeToggle.svelte +238 -56
  74. package/dist/atoms/ThemeToggle.svelte.d.ts +28 -3
  75. package/dist/atoms/TimeField.svelte +108 -0
  76. package/dist/atoms/TimeField.svelte.d.ts +54 -0
  77. package/dist/atoms/Toast.svelte +25 -10
  78. package/dist/atoms/Toast.svelte.d.ts +2 -0
  79. package/dist/atoms/Toggle.svelte +60 -19
  80. package/dist/atoms/Toggle.svelte.d.ts +18 -2
  81. package/dist/atoms/Tooltip.svelte +583 -40
  82. package/dist/atoms/Tooltip.svelte.d.ts +26 -0
  83. package/dist/atoms/ZabiStringsProvider.svelte +45 -0
  84. package/dist/atoms/ZabiStringsProvider.svelte.d.ts +27 -0
  85. package/dist/atoms/index.d.ts +17 -0
  86. package/dist/atoms/index.js +12 -0
  87. package/dist/atoms/selection-control.styles.d.ts +36 -5
  88. package/dist/atoms/selection-control.styles.js +40 -9
  89. package/dist/components/atoms/index.d.ts +17 -0
  90. package/dist/components/atoms/index.d.ts.map +1 -1
  91. package/dist/components/atoms/selection-control.styles.d.ts +36 -5
  92. package/dist/components/atoms/selection-control.styles.d.ts.map +1 -1
  93. package/dist/components/index.d.ts +83 -3
  94. package/dist/components/index.d.ts.map +1 -1
  95. package/dist/components/molecules/index.d.ts +46 -0
  96. package/dist/components/molecules/index.d.ts.map +1 -1
  97. package/dist/components/molecules/toast-store.d.ts +53 -7
  98. package/dist/components/molecules/toast-store.d.ts.map +1 -1
  99. package/dist/components/organisms/index.d.ts +6 -0
  100. package/dist/components/organisms/index.d.ts.map +1 -1
  101. package/dist/components/types/variants.d.ts +15 -1
  102. package/dist/components/types/variants.d.ts.map +1 -1
  103. package/dist/components/util/app-shell.d.ts +28 -0
  104. package/dist/components/util/app-shell.d.ts.map +1 -0
  105. package/dist/components/util/avatar.d.ts +36 -0
  106. package/dist/components/util/avatar.d.ts.map +1 -0
  107. package/dist/components/util/bottom-sheet.d.ts +30 -0
  108. package/dist/components/util/bottom-sheet.d.ts.map +1 -0
  109. package/dist/components/util/bottom-tab-bar.d.ts +35 -0
  110. package/dist/components/util/bottom-tab-bar.d.ts.map +1 -0
  111. package/dist/components/util/calendar.d.ts +56 -0
  112. package/dist/components/util/calendar.d.ts.map +1 -0
  113. package/dist/components/util/cn.d.ts +8 -0
  114. package/dist/components/util/cn.d.ts.map +1 -0
  115. package/dist/components/util/collapsible.d.ts +58 -0
  116. package/dist/components/util/collapsible.d.ts.map +1 -0
  117. package/dist/components/util/confirm-dialog.d.ts +12 -0
  118. package/dist/components/util/confirm-dialog.d.ts.map +1 -0
  119. package/dist/components/util/date.d.ts +96 -0
  120. package/dist/components/util/date.d.ts.map +1 -0
  121. package/dist/components/util/drawer.d.ts +13 -0
  122. package/dist/components/util/drawer.d.ts.map +1 -0
  123. package/dist/components/util/dropdown.d.ts +47 -0
  124. package/dist/components/util/dropdown.d.ts.map +1 -0
  125. package/dist/components/util/field.d.ts +39 -0
  126. package/dist/components/util/field.d.ts.map +1 -0
  127. package/dist/components/util/fit-in-viewport.d.ts +201 -0
  128. package/dist/components/util/fit-in-viewport.d.ts.map +1 -0
  129. package/dist/components/util/focus-utils.d.ts +75 -2
  130. package/dist/components/util/focus-utils.d.ts.map +1 -1
  131. package/dist/components/util/hydration.d.ts +45 -0
  132. package/dist/components/util/hydration.d.ts.map +1 -0
  133. package/dist/components/util/keyboard-inset.d.ts +18 -0
  134. package/dist/components/util/keyboard-inset.d.ts.map +1 -0
  135. package/dist/components/util/media-grid.d.ts +51 -0
  136. package/dist/components/util/media-grid.d.ts.map +1 -0
  137. package/dist/components/util/media.d.ts +6 -0
  138. package/dist/components/util/media.d.ts.map +1 -0
  139. package/dist/components/util/overlay-chrome.d.ts +53 -0
  140. package/dist/components/util/overlay-chrome.d.ts.map +1 -0
  141. package/dist/components/util/overlay.d.ts +72 -0
  142. package/dist/components/util/overlay.d.ts.map +1 -0
  143. package/dist/components/util/photo.d.ts +215 -0
  144. package/dist/components/util/photo.d.ts.map +1 -0
  145. package/dist/components/util/portal.d.ts +23 -0
  146. package/dist/components/util/portal.d.ts.map +1 -0
  147. package/dist/components/util/pull-to-refresh.d.ts +27 -0
  148. package/dist/components/util/pull-to-refresh.d.ts.map +1 -0
  149. package/dist/components/util/radio-keys.d.ts +25 -0
  150. package/dist/components/util/radio-keys.d.ts.map +1 -0
  151. package/dist/components/util/rating.d.ts +23 -0
  152. package/dist/components/util/rating.d.ts.map +1 -0
  153. package/dist/components/util/ready-made-strings.d.ts +77 -0
  154. package/dist/components/util/ready-made-strings.d.ts.map +1 -0
  155. package/dist/components/util/scroll-padding.d.ts +20 -0
  156. package/dist/components/util/scroll-padding.d.ts.map +1 -0
  157. package/dist/components/util/segmented-control.d.ts +16 -0
  158. package/dist/components/util/segmented-control.d.ts.map +1 -0
  159. package/dist/components/util/select.d.ts +41 -0
  160. package/dist/components/util/select.d.ts.map +1 -0
  161. package/dist/components/util/sheet-drag.d.ts +60 -0
  162. package/dist/components/util/sheet-drag.d.ts.map +1 -0
  163. package/dist/components/util/sidebar.d.ts +63 -0
  164. package/dist/components/util/sidebar.d.ts.map +1 -0
  165. package/dist/components/util/sortable-list.d.ts +65 -0
  166. package/dist/components/util/sortable-list.d.ts.map +1 -0
  167. package/dist/components/util/ssr-safe.d.ts +4 -4
  168. package/dist/components/util/ssr-safe.d.ts.map +1 -1
  169. package/dist/components/util/stepper.d.ts +40 -0
  170. package/dist/components/util/stepper.d.ts.map +1 -0
  171. package/dist/components/util/swipeable-list-item.d.ts +36 -0
  172. package/dist/components/util/swipeable-list-item.d.ts.map +1 -0
  173. package/dist/components/util/theme-mode.d.ts +80 -0
  174. package/dist/components/util/theme-mode.d.ts.map +1 -0
  175. package/dist/components/util/toaster.d.ts +93 -0
  176. package/dist/components/util/toaster.d.ts.map +1 -0
  177. package/dist/components/util/tooltip.d.ts +10 -0
  178. package/dist/components/util/tooltip.d.ts.map +1 -0
  179. package/dist/components/util/top-navbar.d.ts +11 -0
  180. package/dist/components/util/top-navbar.d.ts.map +1 -0
  181. package/dist/components/util/touch-target.d.ts +31 -0
  182. package/dist/components/util/touch-target.d.ts.map +1 -0
  183. package/dist/components/util/zabi-strings.d.ts +133 -0
  184. package/dist/components/util/zabi-strings.d.ts.map +1 -0
  185. package/dist/create-theme/cli.js +169 -0
  186. package/dist/create-theme/index.d.ts +176 -0
  187. package/dist/create-theme/index.js +817 -0
  188. package/dist/create-theme/lib/ramp-math.js +128 -0
  189. package/dist/create-theme/lib/resolve.js +141 -0
  190. package/dist/create-theme/theme-data.js +1116 -0
  191. package/dist/index.d.ts +83 -3
  192. package/dist/index.js +60 -8
  193. package/dist/molecules/Alert.svelte +73 -66
  194. package/dist/molecules/Alert.svelte.d.ts +9 -1
  195. package/dist/molecules/AppBar.svelte +415 -0
  196. package/dist/molecules/AppBar.svelte.d.ts +69 -0
  197. package/dist/molecules/AvatarGroup.svelte +116 -0
  198. package/dist/molecules/AvatarGroup.svelte.d.ts +40 -0
  199. package/dist/molecules/BottomSheet.svelte +540 -0
  200. package/dist/molecules/BottomSheet.svelte.d.ts +93 -0
  201. package/dist/molecules/BottomTabBar.svelte +297 -0
  202. package/dist/molecules/BottomTabBar.svelte.d.ts +64 -0
  203. package/dist/molecules/Calendar.svelte +597 -0
  204. package/dist/molecules/Calendar.svelte.d.ts +72 -0
  205. package/dist/molecules/Collapsible.svelte +243 -0
  206. package/dist/molecules/Collapsible.svelte.d.ts +44 -0
  207. package/dist/molecules/CollapsibleGroup.svelte +126 -0
  208. package/dist/molecules/CollapsibleGroup.svelte.d.ts +14 -0
  209. package/dist/molecules/ComponentDemo.svelte +25 -5
  210. package/dist/molecules/ComponentDemo.svelte.d.ts +5 -0
  211. package/dist/molecules/ConfirmDialog.svelte +253 -0
  212. package/dist/molecules/ConfirmDialog.svelte.d.ts +55 -0
  213. package/dist/molecules/ContactForm.svelte +46 -19
  214. package/dist/molecules/ContactForm.svelte.d.ts +10 -0
  215. package/dist/molecules/Drawer.svelte +394 -0
  216. package/dist/molecules/Drawer.svelte.d.ts +55 -0
  217. package/dist/molecules/Dropdown.svelte +540 -50
  218. package/dist/molecules/Dropdown.svelte.d.ts +49 -6
  219. package/dist/molecules/DropdownItem.svelte +122 -0
  220. package/dist/molecules/DropdownItem.svelte.d.ts +28 -0
  221. package/dist/molecules/EmptyState.svelte +56 -10
  222. package/dist/molecules/EmptyState.svelte.d.ts +8 -0
  223. package/dist/molecules/Form.svelte +25 -14
  224. package/dist/molecules/Form.svelte.d.ts +13 -5
  225. package/dist/molecules/FormField.svelte +11 -2
  226. package/dist/molecules/FormField.svelte.d.ts +2 -0
  227. package/dist/molecules/Header.svelte +13 -3
  228. package/dist/molecules/Header.svelte.d.ts +2 -0
  229. package/dist/molecules/ImageUpload.svelte +422 -70
  230. package/dist/molecules/ImageUpload.svelte.d.ts +61 -5
  231. package/dist/molecules/MediaGrid.svelte +527 -0
  232. package/dist/molecules/MediaGrid.svelte.d.ts +77 -0
  233. package/dist/molecules/Modal.svelte +340 -45
  234. package/dist/molecules/Modal.svelte.d.ts +59 -7
  235. package/dist/molecules/NavigationMenu.svelte +15 -3
  236. package/dist/molecules/NavigationMenu.svelte.d.ts +4 -0
  237. package/dist/molecules/NavigationMenuContent.svelte +91 -36
  238. package/dist/molecules/NavigationMenuContent.svelte.d.ts +2 -0
  239. package/dist/molecules/NavigationMenuItem.svelte +10 -3
  240. package/dist/molecules/NavigationMenuItem.svelte.d.ts +2 -0
  241. package/dist/molecules/NavigationMenuLink.svelte +10 -2
  242. package/dist/molecules/NavigationMenuLink.svelte.d.ts +2 -0
  243. package/dist/molecules/NavigationMenuList.svelte +19 -4
  244. package/dist/molecules/NavigationMenuList.svelte.d.ts +2 -0
  245. package/dist/molecules/NavigationMenuTrigger.svelte +16 -3
  246. package/dist/molecules/NavigationMenuTrigger.svelte.d.ts +2 -0
  247. package/dist/molecules/Page.svelte +38 -2
  248. package/dist/molecules/Page.svelte.d.ts +13 -0
  249. package/dist/molecules/PhotoGrid.svelte +433 -0
  250. package/dist/molecules/PhotoGrid.svelte.d.ts +62 -0
  251. package/dist/molecules/PhotoViewer.svelte +1116 -0
  252. package/dist/molecules/PhotoViewer.svelte.d.ts +56 -0
  253. package/dist/molecules/PropsTable.svelte +26 -11
  254. package/dist/molecules/PropsTable.svelte.d.ts +5 -0
  255. package/dist/molecules/PullToRefresh.svelte +263 -0
  256. package/dist/molecules/PullToRefresh.svelte.d.ts +52 -0
  257. package/dist/molecules/RadioGroup.svelte +57 -15
  258. package/dist/molecules/RadioGroup.svelte.d.ts +16 -3
  259. package/dist/molecules/Section.svelte +13 -5
  260. package/dist/molecules/Section.svelte.d.ts +3 -1
  261. package/dist/molecules/SegmentedControl.svelte +323 -0
  262. package/dist/molecules/SegmentedControl.svelte.d.ts +34 -0
  263. package/dist/molecules/SidebarBrandHeader.svelte +24 -5
  264. package/dist/molecules/SidebarBrandHeader.svelte.d.ts +5 -0
  265. package/dist/molecules/SidebarFooter.svelte +39 -8
  266. package/dist/molecules/SidebarFooter.svelte.d.ts +5 -0
  267. package/dist/molecules/SidebarNavSection.svelte +12 -4
  268. package/dist/molecules/SidebarNavSection.svelte.d.ts +2 -0
  269. package/dist/molecules/SlideUp.svelte +253 -30
  270. package/dist/molecules/SlideUp.svelte.d.ts +31 -4
  271. package/dist/molecules/SortableList.svelte +632 -0
  272. package/dist/molecules/SortableList.svelte.d.ts +69 -0
  273. package/dist/molecules/Stepper.svelte +548 -0
  274. package/dist/molecules/Stepper.svelte.d.ts +39 -0
  275. package/dist/molecules/StickyActionBar.svelte +191 -0
  276. package/dist/molecules/StickyActionBar.svelte.d.ts +65 -0
  277. package/dist/molecules/SwipeableListItem.svelte +334 -0
  278. package/dist/molecules/SwipeableListItem.svelte.d.ts +54 -0
  279. package/dist/molecules/Tabs.svelte +254 -24
  280. package/dist/molecules/Tabs.svelte.d.ts +15 -4
  281. package/dist/molecules/Toaster.svelte +352 -6
  282. package/dist/molecules/Toaster.svelte.d.ts +95 -2
  283. package/dist/molecules/ToasterToast.svelte +279 -62
  284. package/dist/molecules/ToasterToast.svelte.d.ts +11 -0
  285. package/dist/molecules/UnsavedChangesBar.svelte +212 -0
  286. package/dist/molecules/UnsavedChangesBar.svelte.d.ts +43 -0
  287. package/dist/molecules/index.d.ts +46 -0
  288. package/dist/molecules/index.js +27 -0
  289. package/dist/molecules/toast-store.d.ts +53 -7
  290. package/dist/molecules/toast-store.js +21 -0
  291. package/dist/organisms/AppShell.svelte +196 -0
  292. package/dist/organisms/AppShell.svelte.d.ts +61 -0
  293. package/dist/organisms/SidebarAccountPanel.svelte +111 -12
  294. package/dist/organisms/SidebarAccountPanel.svelte.d.ts +21 -0
  295. package/dist/organisms/SidebarNavigation.svelte +193 -69
  296. package/dist/organisms/SidebarNavigation.svelte.d.ts +31 -1
  297. package/dist/organisms/SidebarPanel.svelte +45 -16
  298. package/dist/organisms/SidebarPanel.svelte.d.ts +2 -0
  299. package/dist/organisms/SidebarShell.svelte +263 -0
  300. package/dist/organisms/SidebarShell.svelte.d.ts +106 -0
  301. package/dist/organisms/TopNavbar.svelte +329 -33
  302. package/dist/organisms/TopNavbar.svelte.d.ts +28 -0
  303. package/dist/organisms/index.d.ts +6 -0
  304. package/dist/organisms/index.js +4 -0
  305. package/dist/routes/lib/variant-utils.d.ts +26 -0
  306. package/dist/routes/lib/{variant-utils.ts → variant-utils.js} +15 -46
  307. package/dist/types/components.d.ts +4 -0
  308. package/dist/types/components.d.ts.map +1 -1
  309. package/dist/types/events.js +1 -0
  310. package/dist/types/index.d.ts +605 -25
  311. package/dist/types/index.d.ts.map +1 -1
  312. package/dist/types/index.js +3 -0
  313. package/dist/types/variants.ts +17 -1
  314. package/dist/util/app-shell.d.ts +27 -0
  315. package/dist/util/app-shell.js +72 -0
  316. package/dist/util/avatar.d.ts +35 -0
  317. package/dist/util/avatar.js +52 -0
  318. package/dist/util/bottom-sheet.d.ts +29 -0
  319. package/dist/util/bottom-sheet.js +43 -0
  320. package/dist/util/bottom-tab-bar.d.ts +34 -0
  321. package/dist/util/bottom-tab-bar.js +54 -0
  322. package/dist/util/calendar.d.ts +55 -0
  323. package/dist/util/calendar.js +74 -0
  324. package/dist/util/cn.d.ts +7 -0
  325. package/dist/util/cn.js +48 -0
  326. package/dist/util/collapsible.d.ts +57 -0
  327. package/dist/util/collapsible.js +23 -0
  328. package/dist/util/confirm-dialog.d.ts +11 -0
  329. package/dist/util/confirm-dialog.js +2 -0
  330. package/dist/util/date.d.ts +95 -0
  331. package/dist/util/date.js +237 -0
  332. package/dist/util/drawer.d.ts +12 -0
  333. package/dist/util/drawer.js +7 -0
  334. package/dist/util/dropdown.d.ts +46 -0
  335. package/dist/util/dropdown.js +21 -0
  336. package/dist/util/field.d.ts +38 -0
  337. package/dist/util/field.js +38 -0
  338. package/dist/util/fit-in-viewport.d.ts +200 -0
  339. package/dist/util/fit-in-viewport.js +399 -0
  340. package/dist/util/focus-utils.d.ts +75 -2
  341. package/dist/util/focus-utils.js +182 -9
  342. package/dist/util/hydration.d.ts +44 -0
  343. package/dist/util/hydration.js +58 -0
  344. package/dist/util/keyboard-inset.d.ts +17 -0
  345. package/dist/util/keyboard-inset.js +53 -0
  346. package/dist/util/media-grid.d.ts +50 -0
  347. package/dist/util/media-grid.js +81 -0
  348. package/dist/util/media.d.ts +5 -0
  349. package/dist/util/media.js +10 -0
  350. package/dist/util/overlay-chrome.d.ts +52 -0
  351. package/dist/util/overlay-chrome.js +56 -0
  352. package/dist/util/overlay.d.ts +71 -0
  353. package/dist/util/overlay.js +240 -0
  354. package/dist/util/photo.d.ts +214 -0
  355. package/dist/util/photo.js +206 -0
  356. package/dist/util/portal.d.ts +22 -0
  357. package/dist/util/portal.js +50 -0
  358. package/dist/util/pull-to-refresh.d.ts +26 -0
  359. package/dist/util/pull-to-refresh.js +30 -0
  360. package/dist/util/radio-keys.d.ts +24 -0
  361. package/dist/util/radio-keys.js +49 -0
  362. package/dist/util/rating.d.ts +22 -0
  363. package/dist/util/rating.js +26 -0
  364. package/dist/util/ready-made-strings.d.ts +76 -0
  365. package/dist/util/ready-made-strings.js +67 -0
  366. package/dist/util/scroll-padding.d.ts +19 -0
  367. package/dist/util/scroll-padding.js +44 -0
  368. package/dist/util/segmented-control.d.ts +15 -0
  369. package/dist/util/segmented-control.js +1 -0
  370. package/dist/util/select.d.ts +40 -0
  371. package/dist/util/select.js +63 -0
  372. package/dist/util/sheet-drag.d.ts +59 -0
  373. package/dist/util/sheet-drag.js +241 -0
  374. package/dist/util/sidebar.d.ts +62 -0
  375. package/dist/util/sidebar.js +38 -0
  376. package/dist/util/sortable-list.d.ts +64 -0
  377. package/dist/util/sortable-list.js +53 -0
  378. package/dist/util/ssr-safe.d.ts +4 -4
  379. package/dist/util/stepper.d.ts +39 -0
  380. package/dist/util/stepper.js +38 -0
  381. package/dist/util/swipeable-list-item.d.ts +35 -0
  382. package/dist/util/swipeable-list-item.js +32 -0
  383. package/dist/util/theme-mode.d.ts +79 -0
  384. package/dist/util/theme-mode.js +121 -0
  385. package/dist/util/toaster.d.ts +92 -0
  386. package/dist/util/toaster.js +75 -0
  387. package/dist/util/tooltip.d.ts +9 -0
  388. package/dist/util/tooltip.js +18 -0
  389. package/dist/util/top-navbar.d.ts +10 -0
  390. package/dist/util/top-navbar.js +5 -0
  391. package/dist/util/touch-target.d.ts +30 -0
  392. package/dist/util/touch-target.js +30 -0
  393. package/dist/util/zabi-strings.d.ts +132 -0
  394. package/dist/util/zabi-strings.js +105 -0
  395. package/dist/zabi-components-colors.css +5 -2
  396. package/dist/zabi-components-theme-dark-only.css +574 -225
  397. package/dist/zabi-components-theme-dark.css +574 -225
  398. package/dist/zabi-components-theme-only.css +1680 -317
  399. package/dist/zabi-components-theme.css +1680 -317
  400. package/dist/zabi-components.css +4473 -1158
  401. package/docs/lucide-icons.md +41 -16
  402. package/docs/theme-imports.md +81 -11
  403. package/package.json +51 -29
  404. package/dist/lib/layout-width-tokens.d.ts +0 -17
  405. package/dist/lib/layout-width-tokens.d.ts.map +0 -1
  406. package/dist/lib/showcase/component-docs/Button.d.ts +0 -3
  407. package/dist/lib/showcase/component-docs/Button.d.ts.map +0 -1
  408. package/dist/lib/showcase/component-docs/Input.d.ts +0 -3
  409. package/dist/lib/showcase/component-docs/Input.d.ts.map +0 -1
  410. package/dist/lib/showcase/component-docs/List.d.ts +0 -3
  411. package/dist/lib/showcase/component-docs/List.d.ts.map +0 -1
  412. package/dist/lib/showcase/component-docs/Modal.d.ts +0 -3
  413. package/dist/lib/showcase/component-docs/Modal.d.ts.map +0 -1
  414. package/dist/lib/showcase/component-docs/Radio.d.ts +0 -3
  415. package/dist/lib/showcase/component-docs/Radio.d.ts.map +0 -1
  416. package/dist/lib/showcase/component-docs/SidebarNavigation.d.ts +0 -3
  417. package/dist/lib/showcase/component-docs/SidebarNavigation.d.ts.map +0 -1
  418. package/dist/lib/showcase/component-docs/Skeleton.d.ts +0 -3
  419. package/dist/lib/showcase/component-docs/Skeleton.d.ts.map +0 -1
  420. package/dist/lib/showcase/component-docs/_shared.d.ts +0 -12
  421. package/dist/lib/showcase/component-docs/_shared.d.ts.map +0 -1
  422. package/dist/lib/showcase/component-docs/index.d.ts +0 -4
  423. package/dist/lib/showcase/component-docs/index.d.ts.map +0 -1
  424. package/dist/lib/showcase/components-catalog.d.ts +0 -3
  425. package/dist/lib/showcase/components-catalog.d.ts.map +0 -1
  426. package/dist/lib/showcase/components-showcase-constants.d.ts +0 -89
  427. package/dist/lib/showcase/components-showcase-constants.d.ts.map +0 -1
  428. package/dist/lib/showcase/docs-sidebar-helpers.d.ts +0 -15
  429. package/dist/lib/showcase/docs-sidebar-helpers.d.ts.map +0 -1
  430. package/dist/routes/lib/focus-utils.d.ts +0 -12
  431. package/dist/routes/lib/focus-utils.ts +0 -110
  432. package/dist/routes/lib/ssr-safe.ts +0 -58
  433. package/scripts/fix-lucide-svelte-icon-dts.js +0 -35
@@ -1,4 +1,23 @@
1
- interface Props {
1
+ import type { HTMLButtonAttributes } from "svelte/elements";
2
+ import { type SelectPresentation, type SelectStrings } from "../util/select.js";
3
+ /**
4
+ * Other attributes (`data-*`, `aria-*`, `onfocus`, ...) land on the
5
+ * trigger, which is a `<button>`: it is the control that takes focus and
6
+ * that the label names.
7
+ *
8
+ * The server's HTML also carries a native `<select>` with the same
9
+ * options. Until the component has mounted, and for good where there are
10
+ * no scripts, that is the control: it is what is seen, pressed and
11
+ * submitted. Once mounted the trigger and the list take over, and the
12
+ * native select stays, out of sight and out of reach, as the form control
13
+ * (`name`, `required`), kept at the same value. With
14
+ * `presentation="native"` it is the control throughout.
15
+ */
16
+ type Props = Omit<HTMLButtonAttributes, "class" | "value" | "name" | "disabled" | "type" | "onchange" | "onclick" | "aria-describedby" | "children"> & {
17
+ /** Extra classes for the host element. */
18
+ class?: string;
19
+ /** Id of the trigger. Omit to auto-generate. */
20
+ id?: string;
2
21
  value?: string | number | undefined;
3
22
  options?: Array<{
4
23
  value: string | number;
@@ -6,9 +25,26 @@ interface Props {
6
25
  disabled?: boolean;
7
26
  }>;
8
27
  searchable?: boolean;
28
+ /**
29
+ * The component's own texts, for another language. Whatever is left
30
+ * out keeps its English default. The six older props for single texts
31
+ * (`placeholder`, `searchPlaceholder`, `noResultsText`,
32
+ * `loadingText`, `emptyStateTitle`, `emptyStateDescription`) win
33
+ * over it.
34
+ */
35
+ strings?: Partial<SelectStrings>;
9
36
  searchPlaceholder?: string;
10
37
  maxMenuHeight?: string;
11
38
  menuWidth?: string;
39
+ /**
40
+ * How the list is shown. `auto`: in a BottomSheet on a phone (a touch
41
+ * screen narrower than 640px), under the trigger everywhere else.
42
+ * `popover` and `sheet` are always the one or the other. `native`:
43
+ * only the browser's own `<select>`, styled as the field, with the
44
+ * platform's picker. It shows the options' labels and nothing else:
45
+ * no search field, and none of the loading or empty states.
46
+ */
47
+ presentation?: SelectPresentation;
12
48
  noResultsText?: string;
13
49
  isLoading?: boolean;
14
50
  loadingText?: string;
@@ -17,14 +53,28 @@ interface Props {
17
53
  emptyStateActionLabel?: string;
18
54
  placeholder?: string;
19
55
  label?: string;
56
+ /** The name the chosen value is submitted under, by the native `<select>`. */
57
+ name?: string;
58
+ /**
59
+ * The form is not sent while nothing is chosen. Checked by the
60
+ * browser on the native `<select>`; once mounted, the browser's own
61
+ * message is shown under the field and focus goes to the trigger.
62
+ */
20
63
  required?: boolean;
21
64
  disabled?: boolean;
22
65
  size?: "sm" | "md" | "lg";
23
66
  variant?: "default" | "success" | "warning" | "error";
67
+ /** Status text under the field. Shown with a `success`, `warning` or `error` variant; for neutral help, use `hint`. */
24
68
  message?: string;
69
+ /** Help text under the field, read out with it. */
70
+ hint?: string;
71
+ /** An error under the field. It marks the field invalid and is announced; it wins over `variant` and `message`. */
72
+ error?: string;
25
73
  onchange?: (event: Event) => void;
26
74
  onEmptyStateAction?: () => void;
27
- }
75
+ /** Ids of other elements that describe the field. The hint and the message are added after them. */
76
+ "aria-describedby"?: string | null;
77
+ };
28
78
  declare const Select: import("svelte").Component<Props, {}, "value">;
29
79
  type Select = ReturnType<typeof Select>;
30
80
  export default Select;
@@ -1,7 +1,11 @@
1
1
  <script lang="ts">
2
- import type { Snippet } from "svelte";
2
+ import { onMount, tick, type Snippet } from "svelte";
3
+ import type { HTMLInputAttributes } from "svelte/elements";
3
4
  import { generateId } from "../util/ssr-safe.js";
5
+ import { cn } from "../util/cn.js";
6
+ import { groupBinding } from "../util/hydration.js";
4
7
  import {
8
+ SELECTION_CONTROL_INPUT,
5
9
  SELECTION_CONTROL_LABEL_ROW,
6
10
  selectionControlRingOverlayClasses,
7
11
  selectionControlShellClasses,
@@ -16,7 +20,12 @@
16
20
  disabled: boolean;
17
21
  };
18
22
 
19
- interface Props {
23
+ type Props = Omit<
24
+ HTMLInputAttributes,
25
+ "class" | "id" | "name" | "value" | "disabled" | "checked" | "type" | "onchange"
26
+ > & {
27
+ /** Extra classes for the host element. */
28
+ class?: string;
20
29
  id?: string;
21
30
  type: SelectionControlType;
22
31
  shape: SelectionControlShape;
@@ -30,9 +39,10 @@
30
39
  onChange?: (event: Event) => void;
31
40
  onchange?: (event: Event) => void;
32
41
  mark?: Snippet<[SelectionControlMarkProps]>;
33
- }
42
+ };
34
43
 
35
44
  let {
45
+ class: className = "",
36
46
  id: idProp,
37
47
  type,
38
48
  shape,
@@ -42,13 +52,24 @@
42
52
  disabled = false,
43
53
  loading = false,
44
54
  defaultChecked = false,
45
- checked = $bindable(defaultChecked),
55
+ checked = $bindable<Exclude<Props["checked"], undefined>>(),
46
56
  onChange,
47
57
  onchange,
48
58
  mark,
49
59
  ...restProps
50
60
  }: Props = $props();
51
61
 
62
+ // No fallback on a bindable prop: Svelte refuses `bind:…={undefined}` on
63
+ // one that has a fallback (`props_invalid_value`), and a page that throws
64
+ // while it hydrates never becomes interactive. The default is applied
65
+ // here instead: at once, for the server and the first render, and again
66
+ // whenever a parent hands back `undefined`.
67
+ const applyDefaults = () => {
68
+ if (checked === undefined) checked = defaultChecked;
69
+ };
70
+ applyDefaults();
71
+ $effect.pre(applyDefaults);
72
+
52
73
  /** Call once per mount — `generateId()` in `$derived` would churn ids every tick. */
53
74
  const fallbackId = generateId("selection-control");
54
75
  const controlId = $derived(idProp ?? fallbackId);
@@ -60,8 +81,50 @@
60
81
 
61
82
  const controlRingClasses = $derived(selectionControlRingOverlayClasses(shape));
62
83
 
84
+ let input: HTMLInputElement | undefined = $state();
85
+
86
+ /**
87
+ * The input is bound, so a tick made before the page hydrated is kept:
88
+ * Svelte's binding finds the input changed and hands its state over here
89
+ * instead of overwriting it (see util/hydration.ts). A form reset arrives
90
+ * the same way.
91
+ *
92
+ * A choice that is adopted like that came without a `change` event that
93
+ * anything heard, and a parent that only listens (`onchange`, no
94
+ * `bind:checked`) would never learn of it. So while the component
95
+ * settles, a change made through the binding is noted, and reported once
96
+ * with a real `change` event on the input: the callbacks get the event
97
+ * they always get, and a form around the control hears it too.
98
+ */
99
+ let settling = true;
100
+ let adopted = false;
101
+
102
+ function take(next: boolean) {
103
+ if (next === !!checked) return;
104
+ checked = next;
105
+ if (settling) adopted = true;
106
+ }
107
+
108
+ /** What a single radio's group is bound to: its own value while it is checked. */
109
+ const NOT_CHOSEN = {};
110
+ const radio = groupBinding<unknown>(
111
+ () => (checked ? value : NOT_CHOSEN),
112
+ (chosen) => take(chosen === value),
113
+ () => take(false),
114
+ );
115
+
116
+ onMount(() => {
117
+ // The bindings adopt in a microtask of their own, queued before this one.
118
+ void tick().then(() => {
119
+ settling = false;
120
+ if (adopted) input?.dispatchEvent(new Event("change", { bubbles: true }));
121
+ });
122
+ });
123
+
63
124
  function handleChange(event: Event) {
64
125
  if (isDisabled) return;
126
+ // A real change is its own report: nothing is left to tell.
127
+ adopted = false;
65
128
  const target = event.target as HTMLInputElement;
66
129
  checked = target.checked;
67
130
  onChange?.(event);
@@ -69,24 +132,42 @@
69
132
  }
70
133
  </script>
71
134
 
72
- <div class="flex items-center gap-2">
135
+ <div class={cn("flex items-center gap-2", className)}>
73
136
  <label for={controlId} class={labelWrapperClasses}>
74
137
  <span class={controlContainerClasses}>
75
- <input
76
- {type}
77
- id={controlId}
78
- {name}
79
- {value}
80
- {checked}
81
- disabled={isDisabled}
82
- class="sr-only"
83
- aria-busy={loading ? "true" : undefined}
84
- onchange={handleChange}
85
- {...restProps}
86
- />
138
+ <!-- One branch per type: a binding needs a type it can read. -->
139
+ {#if type === "checkbox"}
140
+ <input
141
+ bind:this={input}
142
+ type="checkbox"
143
+ id={controlId}
144
+ {name}
145
+ {value}
146
+ bind:checked={() => !!checked, take}
147
+ disabled={isDisabled}
148
+ class={SELECTION_CONTROL_INPUT}
149
+ aria-busy={loading ? "true" : undefined}
150
+ onchange={handleChange}
151
+ {...restProps}
152
+ />
153
+ {:else}
154
+ <input
155
+ bind:this={input}
156
+ type="radio"
157
+ id={controlId}
158
+ {name}
159
+ {value}
160
+ bind:group={radio.value}
161
+ disabled={isDisabled}
162
+ class={SELECTION_CONTROL_INPUT}
163
+ aria-busy={loading ? "true" : undefined}
164
+ onchange={handleChange}
165
+ {...restProps}
166
+ />
167
+ {/if}
87
168
  <span class={controlRingClasses}></span>
88
169
  {#if mark}
89
- {@render mark({ checked, loading, disabled: isDisabled })}
170
+ {@render mark({ checked: !!checked, loading, disabled: isDisabled })}
90
171
  {/if}
91
172
  </span>
92
173
  {#if label}
@@ -1,4 +1,5 @@
1
- import type { Snippet } from "svelte";
1
+ import { type Snippet } from "svelte";
2
+ import type { HTMLInputAttributes } from "svelte/elements";
2
3
  import { type SelectionControlShape } from "./selection-control.styles";
3
4
  type SelectionControlType = "checkbox" | "radio";
4
5
  export type SelectionControlMarkProps = {
@@ -6,7 +7,9 @@ export type SelectionControlMarkProps = {
6
7
  loading: boolean;
7
8
  disabled: boolean;
8
9
  };
9
- interface Props {
10
+ type Props = Omit<HTMLInputAttributes, "class" | "id" | "name" | "value" | "disabled" | "checked" | "type" | "onchange"> & {
11
+ /** Extra classes for the host element. */
12
+ class?: string;
10
13
  id?: string;
11
14
  type: SelectionControlType;
12
15
  shape: SelectionControlShape;
@@ -20,7 +23,7 @@ interface Props {
20
23
  onChange?: (event: Event) => void;
21
24
  onchange?: (event: Event) => void;
22
25
  mark?: Snippet<[SelectionControlMarkProps]>;
23
- }
26
+ };
24
27
  declare const SelectionControl: import("svelte").Component<Props, {}, "checked">;
25
28
  type SelectionControl = ReturnType<typeof SelectionControl>;
26
29
  export default SelectionControl;
@@ -1,4 +1,6 @@
1
1
  <script lang="ts">
2
+ import { cn } from "../util/cn.js";
3
+
2
4
  type Variant = "text" | "circle" | "block";
3
5
 
4
6
  interface Props {
@@ -20,9 +22,9 @@
20
22
  }: Props = $props();
21
23
 
22
24
  const radius: Record<Variant, string> = {
23
- text: "rounded-md",
25
+ text: "rounded-control",
24
26
  circle: "rounded-full",
25
- block: "rounded-lg",
27
+ block: "rounded-control",
26
28
  };
27
29
 
28
30
  const defaultShape: Record<Variant, string> = {
@@ -46,7 +48,7 @@
46
48
  </script>
47
49
 
48
50
  <div
49
- class="animate-pulse bg-surface-2 {defaultShape[variant]} {radius[variant]} {className}"
51
+ class={cn("animate-pulse bg-neutral-subtle", defaultShape[variant], radius[variant], className)}
50
52
  style={inlineStyle || undefined}
51
53
  role="status"
52
54
  aria-busy="true"
@@ -0,0 +1,309 @@
1
+ <script lang="ts">
2
+ import type { HTMLInputAttributes } from "svelte/elements";
3
+ import type { SemanticVariant, SizeVariant } from "../types/variants.js";
4
+ import { generateId } from "../util/ssr-safe.js";
5
+ import { cn } from "../util/cn.js";
6
+
7
+ /** Other attributes (`data-*`, `aria-*`, `list`, ...) land on the `<input>`. */
8
+ type Props = Omit<
9
+ HTMLInputAttributes,
10
+ "class" | "size" | "type" | "value" | "min" | "max" | "step" | "id"
11
+ > & {
12
+ /** Omit to auto-generate; pair with FormField `id` when used inside FormField. */
13
+ id?: string;
14
+ /** Current value; supports `bind:value`. Starts at `min` when not given. */
15
+ value?: number;
16
+ min?: number;
17
+ max?: number;
18
+ step?: number;
19
+ name?: string;
20
+ /** Extra classes for the host element. */
21
+ class?: string;
22
+ label?: string;
23
+ /** True when FormField supplies the visible `<label>`. */
24
+ hideLabel?: boolean;
25
+ disabled?: boolean;
26
+ /** Height of the row, on the scale Input and Button use. */
27
+ size?: SizeVariant;
28
+ /** Colours the message; `error` also marks the input invalid. */
29
+ variant?: SemanticVariant;
30
+ /** Helper or error text below the slider. */
31
+ message?: string;
32
+ /** Shows the current value beside the label. */
33
+ showValue?: boolean;
34
+ /**
35
+ * Turns the value into text ("40 %", "2 h"). It is what `showValue`
36
+ * shows, and what assistive technology reads instead of the bare
37
+ * number.
38
+ */
39
+ formatValue?: (value: number) => string;
40
+ /** Native `input` event: fires while the thumb moves. */
41
+ oninput?: (event: Event) => void;
42
+ /** Native `change` event: fires when the thumb is released. */
43
+ onchange?: (event: Event) => void;
44
+ };
45
+
46
+ let {
47
+ id: idProp,
48
+ min = 0,
49
+ max = 100,
50
+ step = 1,
51
+ value = $bindable<Exclude<Props["value"], undefined>>(),
52
+ name = "",
53
+ class: className = "",
54
+ label = "",
55
+ hideLabel = false,
56
+ disabled = false,
57
+ size = "md",
58
+ variant = "default",
59
+ message = "",
60
+ showValue = false,
61
+ formatValue,
62
+ oninput,
63
+ onchange,
64
+ ...restProps
65
+ }: Props = $props();
66
+
67
+ // No fallback on a bindable prop: Svelte refuses `bind:…={undefined}` on
68
+ // one that has a fallback (`props_invalid_value`), and a page that throws
69
+ // while it hydrates never becomes interactive. The default is applied
70
+ // here instead: at once, for the server and the first render, and again
71
+ // whenever a parent hands back `undefined`.
72
+ const applyDefaults = () => {
73
+ if (value === undefined) value = min;
74
+ };
75
+ applyDefaults();
76
+ $effect.pre(applyDefaults);
77
+
78
+ const fallbackId = generateId("slider");
79
+ const inputId = $derived(idProp ?? fallbackId);
80
+
81
+ /**
82
+ * Row heights on the shared control scale (32 / 40 / 48), so a slider
83
+ * lines up with an Input or a Button of the same size beside it. The
84
+ * `<input>` itself is 44px tall in the two smaller rows, pulled back in
85
+ * with a negative margin: the whole input takes the pointer, so that is
86
+ * the touch target, and the row does not grow for it.
87
+ */
88
+ const sizeClass = $derived.by(() => {
89
+ if (size === "sm") return { box: "h-8 pointer-coarse:min-h-11", input: "h-11 -my-1.5" };
90
+ if (size === "lg") return { box: "h-12", input: "h-12" };
91
+ return { box: "h-10 pointer-coarse:min-h-11", input: "h-11 -my-0.5" };
92
+ });
93
+
94
+ /** Where the thumb sits, 0 to 1; drives the filled part of the track. */
95
+ const ratio = $derived.by(() => {
96
+ if (!(max > min)) return 0;
97
+ return Math.max(0, Math.min(1, (value - min) / (max - min)));
98
+ });
99
+
100
+ const valueText = $derived(formatValue ? formatValue(value) : String(value));
101
+ const labelVisible = $derived(!!label && !hideLabel);
102
+
103
+ // The `-text` step clears 4.5:1 on a page surface, as in Input.
104
+ const messageClasses = $derived.by(() => {
105
+ const base = "text-sm mt-2";
106
+ if (variant === "error") return `text-error-text ${base}`;
107
+ if (variant === "success") return `text-success-text ${base}`;
108
+ if (variant === "warning") return `text-warning-text ${base}`;
109
+ return `text-description ${base}`;
110
+ });
111
+ </script>
112
+
113
+ {#snippet valueOutput()}
114
+ <output
115
+ for={inputId}
116
+ class={cn(
117
+ "shrink-0 text-sm tabular-nums",
118
+ disabled ? "text-action-disabled-text" : "text-description",
119
+ )}
120
+ data-slider-value
121
+ >
122
+ {valueText}
123
+ </output>
124
+ {/snippet}
125
+
126
+ <div class={cn(className)}>
127
+ {#if labelVisible}
128
+ <div class="mb-2 flex items-baseline justify-between gap-3">
129
+ <label for={inputId} class="block text-sm font-medium text-label">{label}</label>
130
+ {#if showValue}
131
+ {@render valueOutput()}
132
+ {/if}
133
+ </div>
134
+ {/if}
135
+ <div class={cn("flex items-center gap-3", sizeClass.box)}>
136
+ <!-- A native range input: keyboard, touch, right-to-left and form
137
+ submission come with it. Only its looks are replaced, below. -->
138
+ <input
139
+ type="range"
140
+ id={inputId}
141
+ class={cn("slider min-w-0 flex-1", sizeClass.input)}
142
+ style:--zabi-slider-ratio={ratio}
143
+ data-size={size}
144
+ bind:value
145
+ {min}
146
+ {max}
147
+ {step}
148
+ name={name || undefined}
149
+ {disabled}
150
+ {oninput}
151
+ {onchange}
152
+ aria-valuetext={formatValue ? valueText : undefined}
153
+ aria-invalid={variant === "error" ? "true" : undefined}
154
+ aria-describedby={message ? `${inputId}-message` : undefined}
155
+ {...restProps}
156
+ />
157
+ {#if showValue && !labelVisible}
158
+ {@render valueOutput()}
159
+ {/if}
160
+ </div>
161
+ {#if message}
162
+ <p
163
+ id={`${inputId}-message`}
164
+ class={messageClasses}
165
+ role={variant === "error" ? "alert" : undefined}
166
+ >
167
+ {message}
168
+ </p>
169
+ {/if}
170
+ </div>
171
+
172
+ <style>
173
+ /*
174
+ * The parts of a range input are vendor pseudo-elements, which utilities
175
+ * cannot reach without an arbitrary variant per declaration. WebKit/Blink
176
+ * and Gecko each get their own rules: one unknown pseudo-element in a
177
+ * selector list drops the whole rule.
178
+ */
179
+ .slider {
180
+ --zabi-slider-thumb: 1.25rem;
181
+ --zabi-slider-track: 0.375rem;
182
+ --zabi-slider-fill: var(--color-action-primary);
183
+ --zabi-slider-rest: var(--color-control-track);
184
+ --zabi-slider-halo: 0 0 0 0 transparent;
185
+ /* The fill ends under the centre of the thumb, which travels less
186
+ than the full width. */
187
+ --zabi-slider-stop: calc(
188
+ var(--zabi-slider-ratio, 0) * (100% - var(--zabi-slider-thumb)) +
189
+ var(--zabi-slider-thumb) / 2
190
+ );
191
+ -webkit-appearance: none;
192
+ -moz-appearance: none;
193
+ appearance: none;
194
+ background: transparent;
195
+ cursor: pointer;
196
+ outline: none;
197
+ /* A touch that starts on the slider moves the thumb; vertical scrolling stays with the page. */
198
+ touch-action: pan-y;
199
+ }
200
+
201
+ .slider[data-size="sm"] {
202
+ --zabi-slider-thumb: 1rem;
203
+ --zabi-slider-track: 0.25rem;
204
+ }
205
+
206
+ .slider[data-size="lg"] {
207
+ --zabi-slider-thumb: 1.5rem;
208
+ --zabi-slider-track: 0.5rem;
209
+ }
210
+
211
+ /* Only where a pointer can hover: after a tap, `:hover` stays on the slider until the next tap elsewhere. */
212
+ @media (hover: hover) {
213
+ .slider:hover {
214
+ --zabi-slider-fill: var(--color-action-primary-hover);
215
+ --zabi-slider-rest: var(--color-control-track-hover);
216
+ --zabi-slider-halo: 0 0 0 4px var(--color-surface-hover);
217
+ }
218
+ }
219
+
220
+ .slider:active {
221
+ --zabi-slider-fill: var(--color-action-primary-active);
222
+ --zabi-slider-rest: var(--color-control-track-active);
223
+ --zabi-slider-halo: 0 0 0 6px var(--color-surface-active);
224
+ }
225
+
226
+ /* Same geometry as `.focus-ring`: a 2px gap, then a 2px ring, on the thumb. */
227
+ .slider:focus-visible {
228
+ --zabi-slider-halo:
229
+ 0 0 0 2px var(--color-focus-ring-offset), 0 0 0 4px var(--color-focus-ring);
230
+ }
231
+
232
+ .slider:disabled {
233
+ --zabi-slider-fill: var(--color-action-disabled-text);
234
+ --zabi-slider-rest: var(--color-action-disabled);
235
+ --zabi-slider-halo: 0 0 0 0 transparent;
236
+ cursor: not-allowed;
237
+ }
238
+
239
+ /* WebKit and Blink: one track, painted in two parts. */
240
+ .slider::-webkit-slider-runnable-track {
241
+ height: var(--zabi-slider-track);
242
+ border-radius: 9999px;
243
+ background: linear-gradient(
244
+ to right,
245
+ var(--zabi-slider-fill) 0 var(--zabi-slider-stop),
246
+ var(--zabi-slider-rest) var(--zabi-slider-stop) 100%
247
+ );
248
+ }
249
+
250
+ .slider:dir(rtl)::-webkit-slider-runnable-track {
251
+ background: linear-gradient(
252
+ to left,
253
+ var(--zabi-slider-fill) 0 var(--zabi-slider-stop),
254
+ var(--zabi-slider-rest) var(--zabi-slider-stop) 100%
255
+ );
256
+ }
257
+
258
+ .slider::-webkit-slider-thumb {
259
+ -webkit-appearance: none;
260
+ appearance: none;
261
+ box-sizing: border-box;
262
+ width: var(--zabi-slider-thumb);
263
+ height: var(--zabi-slider-thumb);
264
+ margin-top: calc((var(--zabi-slider-track) - var(--zabi-slider-thumb)) / 2);
265
+ border: 2px solid var(--zabi-slider-fill);
266
+ border-radius: 9999px;
267
+ background: var(--color-card);
268
+ box-shadow: var(--zabi-slider-halo);
269
+ -webkit-transition: box-shadow 150ms;
270
+ transition: box-shadow 150ms;
271
+ }
272
+
273
+ /* Gecko: the filled part is its own pseudo-element and follows the direction. */
274
+ .slider::-moz-range-track {
275
+ height: var(--zabi-slider-track);
276
+ border-radius: 9999px;
277
+ background: var(--zabi-slider-rest);
278
+ }
279
+
280
+ .slider::-moz-range-progress {
281
+ height: var(--zabi-slider-track);
282
+ border-radius: 9999px;
283
+ background: var(--zabi-slider-fill);
284
+ }
285
+
286
+ .slider::-moz-range-thumb {
287
+ box-sizing: border-box;
288
+ width: var(--zabi-slider-thumb);
289
+ height: var(--zabi-slider-thumb);
290
+ border: 2px solid var(--zabi-slider-fill);
291
+ border-radius: 9999px;
292
+ background: var(--color-card);
293
+ box-shadow: var(--zabi-slider-halo);
294
+ -moz-transition: box-shadow 150ms;
295
+ transition: box-shadow 150ms;
296
+ }
297
+
298
+ @media (prefers-reduced-motion: reduce) {
299
+ .slider::-webkit-slider-thumb {
300
+ -webkit-transition: none;
301
+ transition: none;
302
+ }
303
+
304
+ .slider::-moz-range-thumb {
305
+ -moz-transition: none;
306
+ transition: none;
307
+ }
308
+ }
309
+ </style>
@@ -0,0 +1,40 @@
1
+ import type { HTMLInputAttributes } from "svelte/elements";
2
+ import type { SemanticVariant, SizeVariant } from "../types/variants.js";
3
+ /** Other attributes (`data-*`, `aria-*`, `list`, ...) land on the `<input>`. */
4
+ type Props = Omit<HTMLInputAttributes, "class" | "size" | "type" | "value" | "min" | "max" | "step" | "id"> & {
5
+ /** Omit to auto-generate; pair with FormField `id` when used inside FormField. */
6
+ id?: string;
7
+ /** Current value; supports `bind:value`. Starts at `min` when not given. */
8
+ value?: number;
9
+ min?: number;
10
+ max?: number;
11
+ step?: number;
12
+ name?: string;
13
+ /** Extra classes for the host element. */
14
+ class?: string;
15
+ label?: string;
16
+ /** True when FormField supplies the visible `<label>`. */
17
+ hideLabel?: boolean;
18
+ disabled?: boolean;
19
+ /** Height of the row, on the scale Input and Button use. */
20
+ size?: SizeVariant;
21
+ /** Colours the message; `error` also marks the input invalid. */
22
+ variant?: SemanticVariant;
23
+ /** Helper or error text below the slider. */
24
+ message?: string;
25
+ /** Shows the current value beside the label. */
26
+ showValue?: boolean;
27
+ /**
28
+ * Turns the value into text ("40 %", "2 h"). It is what `showValue`
29
+ * shows, and what assistive technology reads instead of the bare
30
+ * number.
31
+ */
32
+ formatValue?: (value: number) => string;
33
+ /** Native `input` event: fires while the thumb moves. */
34
+ oninput?: (event: Event) => void;
35
+ /** Native `change` event: fires when the thumb is released. */
36
+ onchange?: (event: Event) => void;
37
+ };
38
+ declare const Slider: import("svelte").Component<Props, {}, "value">;
39
+ type Slider = ReturnType<typeof Slider>;
40
+ export default Slider;