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
@@ -0,0 +1,394 @@
1
+ <script lang="ts">
2
+ import { zabiCommonStrings } from "../util/zabi-strings.js";
3
+ import type { Snippet } from "svelte";
4
+ import type { HTMLAttributes } from "svelte/elements";
5
+ import X from "@lucide/svelte/icons/x";
6
+ import { cn } from "../util/cn.js";
7
+ import {
8
+ OVERLAY_CHROME,
9
+ OVERLAY_TITLE_2XL,
10
+ OVERLAY_TITLE_HYPHENS,
11
+ OVERLAY_TITLE_WRAP,
12
+ textIsEnlarged,
13
+ } from "../util/overlay-chrome.js";
14
+ import {
15
+ focusFirstElement,
16
+ getFocusableElements,
17
+ joinOverlayStack,
18
+ recoverStrayFocus,
19
+ returnFocus,
20
+ saveFocus,
21
+ } from "../util/focus-utils.js";
22
+ import {
23
+ followKeyboard,
24
+ lockBodyScroll,
25
+ registerOverlayFooter,
26
+ registerOverlayHeader,
27
+ trapTabKey,
28
+ } from "../util/overlay.js";
29
+ import { TOUCH_HIT_AREA } from "../util/touch-target.js";
30
+ import { portal as portalTo } from "../util/portal.js";
31
+ import { generateId } from "../util/ssr-safe.js";
32
+ import {
33
+ resolveDrawerEdge,
34
+ type DrawerCloseReason,
35
+ type DrawerSide,
36
+ type DrawerSize,
37
+ } from "../util/drawer.js";
38
+
39
+ /** Other attributes (`id`, `data-*`, ...) land on the `role="dialog"` panel. */
40
+ type Props = Omit<
41
+ HTMLAttributes<HTMLDivElement>,
42
+ // `onclose` is also a DOM event handler; ours carries a reason instead.
43
+ "class" | "title" | "onclose" | "onkeydown"
44
+ > & {
45
+ isOpen?: boolean;
46
+ /** Heading of the drawer, and its accessible name. */
47
+ title: string;
48
+ description?: string;
49
+ /**
50
+ * The edge the drawer slides in from. `left` and `right` are physical;
51
+ * `start` and `end` follow the writing direction.
52
+ */
53
+ side?: DrawerSide;
54
+ /** Panel width. On a phone the panel is never wider than the screen. */
55
+ size?: DrawerSize;
56
+ /**
57
+ * Render the overlay in `document.body`, so an ancestor with a
58
+ * transform, filter or clipped overflow cannot trap it; pass `false`
59
+ * to render in place. The theme class belongs on `<html>` or `<body>`;
60
+ * set lower, it does not reach a portalled drawer.
61
+ */
62
+ portal?: boolean;
63
+ /**
64
+ * When false, Escape, a backdrop click and the close button do not
65
+ * close the drawer. Focus stays trapped, and setting `isOpen` yourself
66
+ * still closes it.
67
+ */
68
+ dismissible?: boolean;
69
+ /** Fired when the drawer closes itself, with what the user did. */
70
+ onclose?: (detail: { reason: DrawerCloseReason }) => void;
71
+ /**
72
+ * Hears every keydown in the drawer, after the drawer has handled
73
+ * Escape. The Tab cycle is kept either way.
74
+ */
75
+ onkeydown?: (event: KeyboardEvent) => void;
76
+ /** Accessible name of the close button. */
77
+ closeLabel?: string;
78
+ /**
79
+ * CSS selector, looked up inside the panel, of the control that takes
80
+ * focus when the drawer opens (a search field, say). Without it, or
81
+ * with no match, the first control does: the close button.
82
+ */
83
+ initialFocus?: string;
84
+ /** Extra classes for the dialog panel. */
85
+ class?: string;
86
+ children?: Snippet;
87
+ /** Pinned to the bottom of the panel, below the scrolling content. */
88
+ footer?: Snippet;
89
+ };
90
+
91
+ let {
92
+ isOpen = $bindable<Exclude<Props["isOpen"], undefined>>(),
93
+ title,
94
+ description = "",
95
+ side = "right",
96
+ size = "md",
97
+ portal = true,
98
+ dismissible = true,
99
+ onclose,
100
+ onkeydown,
101
+ closeLabel: closeLabelGiven,
102
+ initialFocus,
103
+ class: className = "",
104
+ children,
105
+ footer,
106
+ ...restProps
107
+ }: Props = $props();
108
+
109
+ /** Words many components share: a `ZabiStringsProvider` above this one may give them; else English. */
110
+ const common = zabiCommonStrings();
111
+ const closeLabel = $derived(closeLabelGiven ?? common().close);
112
+
113
+ // No fallback on a bindable prop: Svelte refuses `bind:…={undefined}` on
114
+ // one that has a fallback (`props_invalid_value`), and a page that throws
115
+ // while it hydrates never becomes interactive. The default is applied
116
+ // here instead: at once, for the server and the first render, and again
117
+ // whenever a parent hands back `undefined`.
118
+ const applyDefaults = () => {
119
+ if (isOpen === undefined) isOpen = false;
120
+ };
121
+ applyDefaults();
122
+ $effect.pre(applyDefaults);
123
+
124
+ const SLIDE_MS = 200;
125
+
126
+ const titleId = generateId("drawer-title");
127
+ const descriptionId = generateId("drawer-description");
128
+
129
+ let panel = $state<HTMLDivElement>();
130
+ let scroller = $state<HTMLDivElement>();
131
+ let footerElement = $state<HTMLDivElement>();
132
+
133
+ /**
134
+ * Read as the overlay opens: with the text enlarged, a long word in the
135
+ * title is hyphenated before it is cut (util/overlay-chrome.ts).
136
+ */
137
+ let enlargedText = $state(false);
138
+ $effect(() => {
139
+ if (isOpen) enlargedText = textIsEnlarged();
140
+ });
141
+ let headerElement = $state<HTMLDivElement>();
142
+ let focusActive = false;
143
+ /**
144
+ * True when the content is taller than its box and holds nothing that can
145
+ * take focus. Only then is the scrolling box itself a Tab stop, so the
146
+ * keyboard can scroll it; content with a control in it is reached, and
147
+ * scrolled, through that control.
148
+ */
149
+ let scrollerNeedsFocus = $state(false);
150
+ /** Position among the open overlays; lifts a drawer opened later above the earlier ones. */
151
+ let depth = $state(0);
152
+
153
+ /** `100%` is the overlay, which is the viewport: the cap for phones. */
154
+ const sizeClasses = $derived(
155
+ {
156
+ "sm": "w-[min(100%,20rem)]",
157
+ "md": "w-[min(100%,28rem)]",
158
+ "lg": "w-[min(100%,42rem)]",
159
+ }[size] ?? "w-[min(100%,28rem)]",
160
+ );
161
+
162
+ /** The border is on the edge that faces the page. */
163
+ const sideClasses = $derived(
164
+ {
165
+ "left": "left-0 border-r",
166
+ "right": "right-0 border-l",
167
+ "start": "start-0 border-e",
168
+ "end": "end-0 border-s",
169
+ }[side] ?? "right-0 border-l",
170
+ );
171
+
172
+ function close(reason: DrawerCloseReason) {
173
+ if (!dismissible) return;
174
+ isOpen = false;
175
+ if (focusActive) {
176
+ focusActive = false;
177
+ returnFocus();
178
+ }
179
+ onclose?.({ reason });
180
+ }
181
+
182
+ /** Slides the panel in from its edge. Skipped where motion is unwanted or unsupported. */
183
+ function slideIn(container: HTMLElement) {
184
+ if (typeof container.animate !== "function") return;
185
+ if (
186
+ typeof window.matchMedia === "function" &&
187
+ window.matchMedia("(prefers-reduced-motion: reduce)").matches
188
+ ) {
189
+ return;
190
+ }
191
+ const rtl = getComputedStyle(container).direction === "rtl";
192
+ const from = resolveDrawerEdge(side, rtl) === "left" ? "-100%" : "100%";
193
+ container.animate(
194
+ [{ transform: `translateX(${from})` }, { transform: "translateX(0)" }],
195
+ { duration: SLIDE_MS, easing: "ease-out" },
196
+ );
197
+ }
198
+
199
+ $effect(() => {
200
+ const box = scroller;
201
+ if (!isOpen || !box) {
202
+ scrollerNeedsFocus = false;
203
+ return;
204
+ }
205
+ const measure = () => {
206
+ scrollerNeedsFocus =
207
+ box.scrollHeight > box.clientHeight &&
208
+ getFocusableElements(box).length === 0;
209
+ };
210
+ measure();
211
+ // The answer changes with the viewport and with the content.
212
+ const resize =
213
+ typeof ResizeObserver === "function" ? new ResizeObserver(measure) : undefined;
214
+ resize?.observe(box);
215
+ const mutation = new MutationObserver(measure);
216
+ mutation.observe(box, { childList: true, subtree: true, characterData: true });
217
+ return () => {
218
+ resize?.disconnect();
219
+ mutation.disconnect();
220
+ };
221
+ });
222
+
223
+ $effect(() => {
224
+ const container = panel;
225
+ if (isOpen && container) {
226
+ saveFocus();
227
+ focusActive = true;
228
+ const unlockScroll = lockBodyScroll();
229
+ const overlay = joinOverlayStack(container);
230
+ depth = overlay.depth;
231
+ slideIn(container);
232
+ const t = setTimeout(() => {
233
+ // Something inside has taken focus already (a field that
234
+ // focuses itself as it mounts): leave it there. `initialFocus`
235
+ // is the consumer saying where focus goes, so it still decides.
236
+ const active = document.activeElement;
237
+ const inside = !!active && active !== container && container.contains(active);
238
+ if (inside && !(initialFocus && container.querySelector(initialFocus))) return;
239
+ focusFirstElement(container, initialFocus);
240
+ }, 0);
241
+ // If the focused control is disabled or removed, focus lands on
242
+ // `<body>`; take Tab and Escape back from there.
243
+ const stopRecovery = recoverStrayFocus(container, {
244
+ onEscape: () => close("escape"),
245
+ });
246
+ // Where the on-screen keyboard covers the page, the overlay
247
+ // keeps to what is left above it.
248
+ const stopKeyboard = container.parentElement
249
+ ? followKeyboard(container.parentElement)
250
+ : undefined;
251
+ return () => {
252
+ clearTimeout(t);
253
+ stopRecovery();
254
+ stopKeyboard?.();
255
+ overlay.leave();
256
+ unlockScroll();
257
+ if (focusActive) {
258
+ focusActive = false;
259
+ returnFocus();
260
+ }
261
+ };
262
+ }
263
+ });
264
+
265
+ // For the toast stack, which stays off a pinned footer.
266
+ $effect(() => {
267
+ const pinned = footerElement;
268
+ if (!isOpen || !pinned) return;
269
+ return registerOverlayFooter(pinned);
270
+ });
271
+
272
+ // And the header, with the close button, which the stack starts below.
273
+ $effect(() => {
274
+ const top = headerElement;
275
+ if (!isOpen || !top) return;
276
+ return registerOverlayHeader(top);
277
+ });
278
+
279
+ function handleBackdropClick(event: Event) {
280
+ if (event.target === event.currentTarget) close("backdrop");
281
+ }
282
+
283
+ function handleKeydown(event: KeyboardEvent) {
284
+ // `defaultPrevented` means a nested dialog already handled the key.
285
+ // Prevented here even when not dismissible, so a dialog underneath
286
+ // does not take the Escape as its own.
287
+ if (event.key === "Escape" && !event.defaultPrevented) {
288
+ event.preventDefault();
289
+ close("escape");
290
+ }
291
+ // The caller's handler, as in Modal: it listens, the trap on the
292
+ // panel is separate and cannot be replaced by it.
293
+ onkeydown?.(event);
294
+ }
295
+ </script>
296
+
297
+ {#if isOpen}
298
+ <!-- svelte-ignore a11y_click_events_have_key_events -->
299
+ <div
300
+ class="group/overlay fixed inset-0 z-modal overflow-hidden {dismissible ? 'cursor-pointer' : 'cursor-default'} bg-overlay"
301
+ style:z-index={depth > 0 ? `calc(var(--z-modal) + ${depth})` : undefined}
302
+ data-overlay-depth={depth}
303
+ use:portalTo={portal}
304
+ onclick={handleBackdropClick}
305
+ onkeydown={handleKeydown}
306
+ role="presentation"
307
+ >
308
+ <div
309
+ bind:this={panel}
310
+ class={cn(
311
+ "absolute inset-y-0 flex cursor-default flex-col border-border-overlay bg-surface-overlay shadow-lg",
312
+ // Above the home indicator: the last row, or the footer, ends
313
+ // where a finger can reach it. Over a keyboard that is under
314
+ // the keyboard.
315
+ "pb-[env(safe-area-inset-bottom,0px)] group-data-keyboard-open/overlay:pb-0",
316
+ sizeClasses,
317
+ sideClasses,
318
+ className,
319
+ )}
320
+ role="dialog"
321
+ aria-modal="true"
322
+ aria-labelledby={titleId}
323
+ aria-describedby={description ? descriptionId : undefined}
324
+ tabindex="-1"
325
+ data-side={side}
326
+ {...restProps}
327
+ onkeydown={(event) => trapTabKey(panel, event)}
328
+ >
329
+ <!-- Chrome: laid out in px, with a title that stops at 1.3 times its
330
+ size (util/overlay-chrome.ts). -->
331
+ <div
332
+ bind:this={headerElement}
333
+ class="flex items-start justify-between gap-4 px-6 pb-3 pt-6 {OVERLAY_CHROME}"
334
+ >
335
+ <div class="min-w-0 flex-1">
336
+ <h2
337
+ id={titleId}
338
+ class="{OVERLAY_TITLE_2XL} font-normal tracking-normal text-headline {OVERLAY_TITLE_WRAP} {enlargedText ? OVERLAY_TITLE_HYPHENS : ''}"
339
+ >
340
+ {title}
341
+ </h2>
342
+ {#if description}
343
+ <p id={descriptionId} class="mt-1 text-sm text-description">
344
+ {description}
345
+ </p>
346
+ {/if}
347
+ </div>
348
+ <!-- `aria-disabled`, not `disabled` or removed: the button may hold focus when `dismissible` turns false, and a disabled or missing element would drop focus out of the trap. -->
349
+ <!-- On a touch screen the hit area grows to 44px around the
350
+ same 32px box. The 6px it adds each way stays inside the
351
+ header's padding and the 16px gap to the title. -->
352
+ <button
353
+ type="button"
354
+ onclick={() => close("close-button")}
355
+ class="focus-ring relative flex size-8 shrink-0 items-center justify-center rounded-control text-description transition-colors motion-reduce:transition-none {TOUCH_HIT_AREA} {dismissible
356
+ ? 'cursor-pointer hover:bg-surface-overlay-hover hover:text-headline active:bg-surface-active'
357
+ : 'cursor-not-allowed opacity-50'}"
358
+ aria-label={closeLabel}
359
+ aria-disabled={dismissible ? undefined : "true"}
360
+ >
361
+ <X size={20} aria-hidden="true" />
362
+ </button>
363
+ </div>
364
+
365
+ <!-- `pt-1`: a scroll container clips, and the focus ring of a
366
+ first control needs the room. -->
367
+ <!-- svelte-ignore a11y_no_noninteractive_tabindex -->
368
+ <div
369
+ bind:this={scroller}
370
+ class={cn(
371
+ "min-h-0 flex-1 overflow-y-auto px-[24px] pb-[24px] pt-[4px]",
372
+ // Inset: a ring outside the box would be cut off at
373
+ // the screen edge the drawer sits on.
374
+ scrollerNeedsFocus &&
375
+ "focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-focus-ring",
376
+ )}
377
+ tabindex={scrollerNeedsFocus ? 0 : undefined}
378
+ role={scrollerNeedsFocus ? "group" : undefined}
379
+ aria-labelledby={scrollerNeedsFocus ? titleId : undefined}
380
+ >
381
+ {@render children?.()}
382
+ </div>
383
+
384
+ {#if footer}
385
+ <div
386
+ bind:this={footerElement}
387
+ class="flex shrink-0 justify-end gap-[12px] border-t border-border-overlay px-[24px] py-[16px]"
388
+ >
389
+ {@render footer()}
390
+ </div>
391
+ {/if}
392
+ </div>
393
+ </div>
394
+ {/if}
@@ -0,0 +1,55 @@
1
+ import type { Snippet } from "svelte";
2
+ import type { HTMLAttributes } from "svelte/elements";
3
+ import { type DrawerCloseReason, type DrawerSide, type DrawerSize } from "../util/drawer.js";
4
+ /** Other attributes (`id`, `data-*`, ...) land on the `role="dialog"` panel. */
5
+ type Props = Omit<HTMLAttributes<HTMLDivElement>, "class" | "title" | "onclose" | "onkeydown"> & {
6
+ isOpen?: boolean;
7
+ /** Heading of the drawer, and its accessible name. */
8
+ title: string;
9
+ description?: string;
10
+ /**
11
+ * The edge the drawer slides in from. `left` and `right` are physical;
12
+ * `start` and `end` follow the writing direction.
13
+ */
14
+ side?: DrawerSide;
15
+ /** Panel width. On a phone the panel is never wider than the screen. */
16
+ size?: DrawerSize;
17
+ /**
18
+ * Render the overlay in `document.body`, so an ancestor with a
19
+ * transform, filter or clipped overflow cannot trap it; pass `false`
20
+ * to render in place. The theme class belongs on `<html>` or `<body>`;
21
+ * set lower, it does not reach a portalled drawer.
22
+ */
23
+ portal?: boolean;
24
+ /**
25
+ * When false, Escape, a backdrop click and the close button do not
26
+ * close the drawer. Focus stays trapped, and setting `isOpen` yourself
27
+ * still closes it.
28
+ */
29
+ dismissible?: boolean;
30
+ /** Fired when the drawer closes itself, with what the user did. */
31
+ onclose?: (detail: {
32
+ reason: DrawerCloseReason;
33
+ }) => void;
34
+ /**
35
+ * Hears every keydown in the drawer, after the drawer has handled
36
+ * Escape. The Tab cycle is kept either way.
37
+ */
38
+ onkeydown?: (event: KeyboardEvent) => void;
39
+ /** Accessible name of the close button. */
40
+ closeLabel?: string;
41
+ /**
42
+ * CSS selector, looked up inside the panel, of the control that takes
43
+ * focus when the drawer opens (a search field, say). Without it, or
44
+ * with no match, the first control does: the close button.
45
+ */
46
+ initialFocus?: string;
47
+ /** Extra classes for the dialog panel. */
48
+ class?: string;
49
+ children?: Snippet;
50
+ /** Pinned to the bottom of the panel, below the scrolling content. */
51
+ footer?: Snippet;
52
+ };
53
+ declare const Drawer: import("svelte").Component<Props, {}, "isOpen">;
54
+ type Drawer = ReturnType<typeof Drawer>;
55
+ export default Drawer;