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,38 +1,165 @@
1
1
  <script lang="ts">
2
+ import type { Snippet } from "svelte";
2
3
  import { generateId } from "../util/ssr-safe.js";
4
+ import { cn } from "../util/cn.js";
3
5
 
4
6
  interface Props {
7
+ /** Extra classes for the host element. */
8
+ class?: string;
5
9
  tabs?: Array<{
6
10
  id: string;
7
11
  label: string;
8
12
  disabled?: boolean;
9
13
  }>;
14
+ /** Selected tab id; supports `bind:activeTab`. */
10
15
  activeTab?: string;
11
16
  variant?: "default" | "pills";
17
+ /**
18
+ * The tabs share the row equally. Meant for two or three tabs on a
19
+ * phone. A label too long for its share wraps between words; when a
20
+ * word does not fit, the tabs keep their words whole and the row
21
+ * scrolls sideways instead.
22
+ */
23
+ fullWidth?: boolean;
12
24
  onclick?: (event: Event) => void;
13
25
  onkeydown?: (event: Event) => void;
26
+ children?: Snippet<[{ activeTab: string }]>;
14
27
  }
15
28
 
16
29
  let {
30
+ class: className = "",
17
31
  tabs = [],
18
- activeTab = "",
32
+ activeTab = $bindable<Exclude<Props["activeTab"], undefined>>(),
19
33
  variant = "default",
34
+ fullWidth = false,
20
35
  children,
21
36
  ...restProps
22
- }: Props & { children?: any } = $props();
37
+ }: Props = $props();
38
+
39
+ // No fallback on a bindable prop: Svelte refuses `bind:…={undefined}` on
40
+ // one that has a fallback (`props_invalid_value`), and a page that throws
41
+ // while it hydrates never becomes interactive. The default is applied
42
+ // here instead: at once, for the server and the first render, and again
43
+ // whenever a parent hands back `undefined`.
44
+ const applyDefaults = () => {
45
+ if (activeTab === undefined) activeTab = "";
46
+ };
47
+ applyDefaults();
48
+ $effect.pre(applyDefaults);
23
49
 
24
50
  const tabsBaseId = generateId("tabs");
25
51
 
26
- function selectTab(tabId: string) {
52
+ /** Button refs keyed by tab id — roving tabindex needs focus to follow selection. */
53
+ const tabElements: Record<string, HTMLButtonElement | undefined> = {};
54
+
55
+ function selectTab(tabId: string, moveFocus = false) {
27
56
  activeTab = tabId;
57
+ if (moveFocus) {
58
+ // The list brings the tab into view itself (`handleFocusIn`), with
59
+ // room for the fade; the browser's own jump would come first.
60
+ tabElements[tabId]?.focus({ preventScroll: true });
61
+ }
28
62
  }
29
63
 
30
- function getEnabledTabs() {
31
- return tabs.filter((tab) => !tab.disabled);
64
+ /**
65
+ * When the tabs do not fit, the list scrolls sideways. It used to do
66
+ * neither that nor wrap: in a 160px card the third tab ended 94px outside
67
+ * it. Each edge with more tabs beyond it fades out, so a cut-off label
68
+ * reads as "there is more" and not as a mistake.
69
+ */
70
+ let listElement = $state<HTMLDivElement | null>(null);
71
+ /** Physical sides, since a mask is drawn in physical directions. */
72
+ let fadeLeft = $state(false);
73
+ let fadeRight = $state(false);
74
+
75
+ /** Room kept between a revealed tab and the edge: the fade, and the tab's focus ring. */
76
+ const REVEAL_MARGIN = 32;
77
+
78
+ function updateFades() {
79
+ const list = listElement;
80
+ if (!list) return;
81
+ const hidden = list.scrollWidth - list.clientWidth;
82
+ if (hidden <= 1) {
83
+ fadeLeft = false;
84
+ fadeRight = false;
85
+ return;
86
+ }
87
+ // Right to left, `scrollLeft` runs from 0 down to minus the hidden width.
88
+ const rtl = getComputedStyle(list).direction === "rtl";
89
+ const fromLeft = rtl ? hidden + list.scrollLeft : list.scrollLeft;
90
+ fadeLeft = fromLeft > 1;
91
+ fadeRight = fromLeft < hidden - 1;
32
92
  }
33
93
 
34
- function getTabIndex(tabId: string) {
35
- return tabs.findIndex((tab) => tab.id === tabId);
94
+ /** Scrolls the list, and only the list, until `tab` is clear of both edges. */
95
+ function reveal(tab: HTMLElement | undefined, animate: boolean) {
96
+ const list = listElement;
97
+ if (!list || !tab || list.scrollWidth - list.clientWidth <= 1) return;
98
+ const box = list.getBoundingClientRect();
99
+ const item = tab.getBoundingClientRect();
100
+ let delta = 0;
101
+ if (item.left < box.left + REVEAL_MARGIN) {
102
+ delta = item.left - box.left - REVEAL_MARGIN;
103
+ } else if (item.right > box.right - REVEAL_MARGIN) {
104
+ delta = item.right - box.right + REVEAL_MARGIN;
105
+ }
106
+ if (delta === 0) return;
107
+ const still =
108
+ !animate ||
109
+ (typeof window.matchMedia === "function" &&
110
+ window.matchMedia("(prefers-reduced-motion: reduce)").matches);
111
+ // `scrollBy` with a behaviour is missing from older engines and from jsdom.
112
+ if (typeof list.scrollBy === "function") {
113
+ list.scrollBy({ left: delta, behavior: still ? "instant" : "smooth" });
114
+ } else {
115
+ list.scrollLeft += delta;
116
+ }
117
+ }
118
+
119
+ // The selected tab is brought into view when the list mounts and when the
120
+ // selection changes: at once the first time, so the page does not open on
121
+ // a moving list.
122
+ let revealedOnce = false;
123
+ $effect(() => {
124
+ const tab = tabElements[activeTab];
125
+ if (!listElement) return;
126
+ reveal(tab, revealedOnce);
127
+ revealedOnce = true;
128
+ updateFades();
129
+ });
130
+
131
+ // The fades follow the list's own size and the number of tabs.
132
+ $effect(() => {
133
+ const list = listElement;
134
+ void tabs.length;
135
+ if (!list) return;
136
+ updateFades();
137
+ if (typeof ResizeObserver === "undefined") return;
138
+ const observer = new ResizeObserver(updateFades);
139
+ observer.observe(list);
140
+ return () => observer.disconnect();
141
+ });
142
+
143
+ /**
144
+ * Arrow keys and Tab move focus to a tab that may be out of view. Keyboard
145
+ * focus only: a press focuses the tab on the way down, and moving the list
146
+ * then would take the tab from under the pointer before the click lands.
147
+ * A pressed tab is revealed once it is selected, by the effect above.
148
+ */
149
+ function handleFocusIn(event: FocusEvent) {
150
+ const tab = (event.target as HTMLElement | null)?.closest<HTMLElement>('[role="tab"]');
151
+ if (!tab) return;
152
+ let fromKeyboard = true;
153
+ try {
154
+ fromKeyboard = tab.matches(":focus-visible");
155
+ } catch {
156
+ // An engine without `:focus-visible`: treat every focus as the keyboard's.
157
+ }
158
+ if (fromKeyboard) reveal(tab, true);
159
+ }
160
+
161
+ function getEnabledTabs() {
162
+ return tabs.filter((tab) => !tab.disabled);
36
163
  }
37
164
 
38
165
  function getTabId(tabId: string) {
@@ -72,40 +199,75 @@
72
199
  const nextIndex =
73
200
  (fallbackIndex + direction + enabledTabs.length) %
74
201
  enabledTabs.length;
75
- selectTab(enabledTabs[nextIndex].id);
202
+ selectTab(enabledTabs[nextIndex].id, true);
76
203
  } else if (event.key === "Home") {
77
204
  event.preventDefault();
78
- selectTab(enabledTabs[0].id);
205
+ selectTab(enabledTabs[0].id, true);
79
206
  } else if (event.key === "End") {
80
207
  event.preventDefault();
81
- selectTab(enabledTabs[enabledTabs.length - 1].id);
82
- } else if (event.key === "Enter" || event.key === " ") {
83
- event.preventDefault();
84
- if (currentIndex === -1) {
85
- selectTab(enabledTabs[0].id);
86
- }
208
+ selectTab(enabledTabs[enabledTabs.length - 1].id, true);
87
209
  }
210
+ // Enter/Space: native <button> click already selects the tab.
211
+ }
212
+
213
+ const TAB_BASE =
214
+ "focus-ring cursor-pointer border-b-2 px-4 py-2 pointer-coarse:min-h-11 text-sm font-medium transition-colors focus:outline-none focus-visible:outline-none disabled:cursor-not-allowed";
215
+ // A tab keeps its width and the list scrolls; sharing the row, it may shrink and its label wrap.
216
+ const TAB_NATURAL = "shrink-0 whitespace-nowrap";
217
+ // `min-w-min` is the tab's longest word: a label wraps between words, never
218
+ // inside one, and when the words do not fit the shares the row scrolls like
219
+ // any other.
220
+ const TAB_SHARED = "min-w-min flex-1 basis-0 text-center";
221
+ // A disabled tab is never the selected one, so only this arm carries the disabled state.
222
+ const TAB_IDLE =
223
+ "border-transparent text-description hover:border-border-medium hover:text-body active:bg-surface-active disabled:opacity-50 disabled:hover:border-transparent disabled:hover:text-description disabled:active:bg-transparent";
224
+ const TAB_SELECTED = "border-brand-500 text-body active:bg-surface-active";
225
+ // The pill has a fill of its own, so its pressed state is a further step of
226
+ // that fill; a translucent tint in its place would be a weaker fill, not a
227
+ // stronger one. It is the pressed role, not the hover step: the hover step
228
+ // is 1.24:1 from the resting fill in light, under the 1.25:1 a pressed fill
229
+ // is held to. The label darkens with it (`.text-link:active` in app.css)
230
+ // and keeps 4.89:1 on the pressed fill.
231
+ const TAB_SELECTED_PILL =
232
+ "border-brand-500 bg-action-primary-subtle text-link active:bg-action-primary-subtle-active";
233
+
234
+ function tabClasses(tabId: string): string {
235
+ const base = `${TAB_BASE} ${fullWidth ? TAB_SHARED : TAB_NATURAL}`;
236
+ if (activeTab !== tabId) return `${base} ${TAB_IDLE}`;
237
+ return `${base} ${variant === "pills" ? TAB_SELECTED_PILL : TAB_SELECTED}`;
88
238
  }
89
239
  </script>
90
240
 
91
- <div class="tabs-container">
241
+ <div class={cn("tabs-container", className)}>
242
+ <!-- The tablist keeps the line under the tabs, and the tabs scroll in a
243
+ box of their own inside it, so the line stays put. That box is
244
+ presentational: the tabs are still the tablist's tabs. -->
245
+ <!-- `flow-root`: the inner box's negative margin stays inside this one,
246
+ so the row is as tall as its tabs and its line, as it was. -->
92
247
  <div
93
- class="flex border-b border-base-200"
248
+ class="flow-root border-b border-border"
94
249
  role="tablist"
95
- tabindex="0"
250
+ tabindex="-1"
96
251
  onkeydown={handleKeydown}
252
+ >
253
+ <!-- `tabindex="-1"`: a scrolling box is otherwise a Tab stop of its own. -->
254
+ <div
255
+ bind:this={listElement}
256
+ class="tabs-list flex"
257
+ role="presentation"
258
+ tabindex="-1"
259
+ data-fade-left={fadeLeft ? "" : undefined}
260
+ data-fade-right={fadeRight ? "" : undefined}
261
+ onfocusin={handleFocusIn}
262
+ onscroll={updateFades}
97
263
  >
98
264
  {#each tabs as tab (tab.id)}
99
265
  <button
266
+ bind:this={tabElements[tab.id]}
100
267
  type="button"
101
268
  role="tab"
102
269
  id={getTabId(tab.id)}
103
- class="focus-ring cursor-pointer border-b-2 px-4 py-2 text-sm font-medium transition-colors focus:outline-none focus-visible:outline-none active:bg-base-100 disabled:cursor-not-allowed disabled:opacity-50 disabled:hover:border-transparent disabled:hover:text-description {activeTab ===
104
- tab.id
105
- ? variant === 'pills'
106
- ? 'border-brand-500 bg-brand-100 text-brand-700'
107
- : 'border-brand-500 text-body'
108
- : 'border-transparent text-description hover:border-base-300 hover:text-body'}"
270
+ class={tabClasses(tab.id)}
109
271
  onclick={() => selectTab(tab.id)}
110
272
  disabled={tab.disabled}
111
273
  aria-selected={activeTab === tab.id}
@@ -116,6 +278,7 @@
116
278
  </button>
117
279
  {/each}
118
280
  </div>
281
+ </div>
119
282
 
120
283
  <div
121
284
  class="mt-4"
@@ -126,3 +289,70 @@
126
289
  {@render children?.({ activeTab })}
127
290
  </div>
128
291
  </div>
292
+
293
+ <style>
294
+ /*
295
+ * The list scrolls sideways when its tabs do not fit, with no scrollbar:
296
+ * the fade says there is more. A scroll container clips what is outside
297
+ * it, and a tab's focus ring is 4px outside the tab, so the list is 4px
298
+ * larger on every side than the row it fills and pulled back by the same
299
+ * amount. A list that fits looks exactly as it did.
300
+ */
301
+ .tabs-list {
302
+ --tabs-ring-room: 4px;
303
+ margin: calc(var(--tabs-ring-room) * -1);
304
+ padding: var(--tabs-ring-room);
305
+ overflow-x: auto;
306
+ overflow-y: hidden;
307
+ overscroll-behavior-x: contain;
308
+ scrollbar-width: none;
309
+ }
310
+
311
+ .tabs-list::-webkit-scrollbar {
312
+ display: none;
313
+ }
314
+
315
+ /*
316
+ * A mask, not a gradient laid over the tabs: it fades them into whatever
317
+ * surface is behind, and nothing sits on top of a tab or its focus ring.
318
+ * Only an edge with more tabs beyond it fades, and a list that fits has no
319
+ * mask at all. Left and right are physical here; the script works out
320
+ * which is which in a right-to-left layout.
321
+ */
322
+ .tabs-list[data-fade-left],
323
+ .tabs-list[data-fade-right] {
324
+ --tabs-fade-left: 0px;
325
+ --tabs-fade-right: 0px;
326
+ -webkit-mask-image: linear-gradient(
327
+ to right,
328
+ transparent,
329
+ black var(--tabs-fade-left),
330
+ black calc(100% - var(--tabs-fade-right)),
331
+ transparent
332
+ );
333
+ mask-image: linear-gradient(
334
+ to right,
335
+ transparent,
336
+ black var(--tabs-fade-left),
337
+ black calc(100% - var(--tabs-fade-right)),
338
+ transparent
339
+ );
340
+ }
341
+
342
+ .tabs-list[data-fade-left] {
343
+ --tabs-fade-left: 1.5rem;
344
+ }
345
+
346
+ .tabs-list[data-fade-right] {
347
+ --tabs-fade-right: 1.5rem;
348
+ }
349
+
350
+ /* Forced colours: a half-transparent label is harder to read than a cut-off one. */
351
+ @media (forced-colors: active) {
352
+ .tabs-list[data-fade-left],
353
+ .tabs-list[data-fade-right] {
354
+ -webkit-mask-image: none;
355
+ mask-image: none;
356
+ }
357
+ }
358
+ </style>
@@ -1,17 +1,28 @@
1
+ import type { Snippet } from "svelte";
1
2
  interface Props {
3
+ /** Extra classes for the host element. */
4
+ class?: string;
2
5
  tabs?: Array<{
3
6
  id: string;
4
7
  label: string;
5
8
  disabled?: boolean;
6
9
  }>;
10
+ /** Selected tab id; supports `bind:activeTab`. */
7
11
  activeTab?: string;
8
12
  variant?: "default" | "pills";
13
+ /**
14
+ * The tabs share the row equally. Meant for two or three tabs on a
15
+ * phone. A label too long for its share wraps between words; when a
16
+ * word does not fit, the tabs keep their words whole and the row
17
+ * scrolls sideways instead.
18
+ */
19
+ fullWidth?: boolean;
9
20
  onclick?: (event: Event) => void;
10
21
  onkeydown?: (event: Event) => void;
22
+ children?: Snippet<[{
23
+ activeTab: string;
24
+ }]>;
11
25
  }
12
- type $$ComponentProps = Props & {
13
- children?: any;
14
- };
15
- declare const Tabs: import("svelte").Component<$$ComponentProps, {}, "">;
26
+ declare const Tabs: import("svelte").Component<Props, {}, "activeTab">;
16
27
  type Tabs = ReturnType<typeof Tabs>;
17
28
  export default Tabs;