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
package/README.md CHANGED
@@ -1,6 +1,13 @@
1
1
  # Zabi Components
2
2
 
3
- Svelte **5** UI primitives (runes, `onclick` / `oninput`, …), Tailwind **v4** design tokens, SSR-safe. Requires **Svelte ≥ 5.43.8**.
3
+ [![npm version](https://img.shields.io/npm/v/zabi-components.svg)](https://www.npmjs.com/package/zabi-components)
4
+ [![license](https://img.shields.io/npm/l/zabi-components.svg)](./LICENSE)
5
+
6
+ A Svelte 5 UI component library with TypeScript types, Tailwind CSS v4 design tokens, light and dark themes, and server-side rendering support.
7
+
8
+ Live examples and docs: **[zabi-components.vercel.app](https://zabi-components.vercel.app/)**
9
+
10
+ Requires **Svelte ≥ 5.43.8**. Components are written with runes and take DOM-style props (`onclick` / `oninput`, …).
4
11
 
5
12
  ---
6
13
 
@@ -12,7 +19,15 @@ Svelte **5** UI primitives (runes, `onclick` / `oninput`, …), Tailwind **v4**
12
19
  npm install zabi-components
13
20
  ```
14
21
 
15
- Ensure `svelte@^5.43.8` is installed — SvelteKit apps usually already match; add `@sveltejs/kit@^2` only for Kit. Optional: `react@^18` if you use `zabi-components/react`.
22
+ Ensure `svelte@^5.43.8` is installed — SvelteKit apps usually already match; add `@sveltejs/kit@^2` only for Kit. The package is Svelte-only (the unmaintained `zabi-components/react` export was removed in 8.0.0).
23
+
24
+ **Icons.** The library uses [`@lucide/svelte`](https://lucide.dev) for its own icons and re-exports only the dozen it needs. For your own tab, navigation and action icons, install it in your app at the range the library depends on, so both use one copy:
25
+
26
+ ```bash
27
+ npm install @lucide/svelte@"^0.544.0"
28
+ ```
29
+
30
+ Import each icon from its own file, `import House from "@lucide/svelte/icons/house"`, not from the package's barrel, which makes a bundler compile every icon. See [docs/lucide-icons.md](./docs/lucide-icons.md).
16
31
 
17
32
  **2. Global CSS** (e.g. SvelteKit `src/app.css` — adjust for your bundler entry)
18
33
 
@@ -22,7 +37,9 @@ Ensure `svelte@^5.43.8` is installed — SvelteKit apps usually already match; a
22
37
  @import "zabi-components/theme-dark-only";
23
38
  ```
24
39
 
25
- No Tailwind? See [docs/theme-imports.md](./docs/theme-imports.md) (`colors` or full `css`).
40
+ No Tailwind? Import the compiled stylesheet instead: `@import "zabi-components/css";`. See [docs/theme-imports.md](./docs/theme-imports.md).
41
+
42
+ > **On 8.0.0 or earlier?** The theme files in those versions leave components unstyled. Upgrade to the latest release, or import `zabi-components/css`.
26
43
 
27
44
  **3. Use a component** (`+page.svelte` or any Svelte 5 component)
28
45
 
@@ -39,7 +56,24 @@ No Tailwind? See [docs/theme-imports.md](./docs/theme-imports.md) (`colors` or f
39
56
  </div>
40
57
  ```
41
58
 
42
- Without the theme CSS, token classes (`bg-input`, `text-body`, …) look unstyled — always import the theme.
59
+ Without the theme CSS, components render unstyled — always import it.
60
+
61
+ ---
62
+
63
+ ## What is included
64
+
65
+ - **Components in three layers.** Atoms (buttons, inputs, date and time fields, checkboxes, sliders, ratings, badges, tooltips), molecules (form fields, segmented controls, calendars, dropdowns, tabs, modals, drawers, bottom sheets, confirm dialogs, collapsible sections, sortable lists, alerts, toasts) and organisms (a top navigation bar, a sidebar and an app shell).
66
+ - **Made for phones too.** `AppShell`, `AppBar` and `BottomTabBar` lay out an app screen; `BottomSheet`, `StickyActionBar` and `FloatingActionButton` put actions within reach of a thumb; `SegmentedControl`, `Rating`, `DateField`, `TimeField` and `Calendar` are sized for touch. On a touch screen controls grow to 44px targets, and the phone components keep clear of the notch and the home indicator. Each one has a page with a live example and its props at [zabi-components.vercel.app/components](https://zabi-components.vercel.app/components).
67
+ - **Svelte 5 only.** Runes, snippets and DOM-style event props. There is no Svelte 4 or React build.
68
+ - **TypeScript.** Props are typed, and the shared unions are exported from `zabi-components/types`.
69
+ - **Theming by tokens.** Colours, surfaces, radius and shadows are Tailwind CSS v4 design tokens, so a rebrand is one generated file of token overrides rather than a change to each component: `npx zabi-theme --brand "#C17B00" --out src/lib/brand.generated.css`. The [theming guide](./THEMING.md) lists the tokens an app may set; the same guide is on the docs site at [/theming](https://zabi-components.vercel.app/theming), with a brand switcher.
70
+ - **Light and dark themes.** Every colour token has a dark value; put `data-theme="dark"` or the `dark` class on the `html` element to switch, or `data-theme="auto"` to follow the system.
71
+ - **Server-side rendering.** Components render on the server in SvelteKit, and browser-only APIs are guarded.
72
+ - **Accessibility work already done.** Labels, hints and errors are connected to their control. RadioGroup and Dropdown handle the arrow keys. Modal, Drawer and SlideUp keep focus inside while open and return it to the trigger. Focus rings are visible by default, in forced-colours mode too.
73
+ - **Your classes win.** `class` is merged last through tailwind-merge, so a utility you pass replaces the component's own.
74
+ - **MIT licensed.**
75
+
76
+ The rest of this file is reference: import paths, the two component styles, tokens, constraints and common pitfalls.
43
77
 
44
78
  ---
45
79
 
@@ -51,6 +85,7 @@ Without the theme CSS, token classes (`bg-input`, `text-body`, …) look unstyle
51
85
  | **Category** `zabi-components/atoms`, `/molecules`, `/organisms` | Larger bundles where you want imports to mirror structure, or you only pull one layer in a given file. |
52
86
  | **Types** `zabi-components/types` | Shared prop unions / enums in your app code. |
53
87
  | **Helpers** `zabi-components`, `zabi-components/lib/ssr-safe`, `lib/variant-utils` | Utilities the package publishes — not app internals. |
88
+ | **Dates** `import { formatDate, formatTime } from "zabi-components"` | The value of a DateField or TimeField (`2026-10-06`, `19:00`) as text in a named language: `formatDate("2026-10-06", "sv")` is "6 okt. 2026". Never shifted by a time zone. |
54
89
 
55
90
  Stick to **documented package subpaths** from `package.json` `exports`. Do not reach into `node_modules/zabi-components/dist/...` by hand.
56
91
 
@@ -100,6 +135,24 @@ Stick to **documented package subpaths** from `package.json` `exports`. Do not r
100
135
  </NavigationMenu>
101
136
  ```
102
137
 
138
+ Some components ship both ways. `SidebarNavigation` is the data-driven one — one
139
+ component, ~39 props, excellent when your sidebar is shaped like that one.
140
+ `SidebarShell` is the same chrome with the regions left open, for when it isn't:
141
+
142
+ ```svelte
143
+ <SidebarShell mode="collapsed">
144
+ {#snippet header({ collapsed })}
145
+ <SidebarBrandHeader {collapsed} brandName="Zabi" />
146
+ {/snippet}
147
+
148
+ <SidebarNavSection title="Main" sectionKey="main">…</SidebarNavSection>
149
+
150
+ {#snippet footer({ collapsed, insetX })}
151
+ <SidebarFooter {collapsed} class={insetX} />
152
+ {/snippet}
153
+ </SidebarShell>
154
+ ```
155
+
103
156
  Wrong mental model: treating composable roots as optional — see **Common pitfalls**.
104
157
 
105
158
  ---
@@ -113,10 +166,11 @@ Components use **DOM-style props** (`onclick`, `oninput`), not legacy `on:click`
113
166
  ```svelte
114
167
  <script lang="ts">
115
168
  import { List } from "zabi-components"; // or …/atoms
116
- import { Home } from "@lucide/svelte";
169
+ // One file per icon: the `@lucide/svelte` barrel makes a bundler compile every icon.
170
+ import House from "@lucide/svelte/icons/house";
117
171
 
118
172
  const items = [
119
- { id: "1", label: "Home", icon: Home },
173
+ { id: "1", label: "Home", icon: House },
120
174
  { id: "2", label: "Settings", href: "/settings" },
121
175
  ];
122
176
  </script>
@@ -162,10 +216,22 @@ Components use **DOM-style props** (`onclick`, `oninput`), not legacy `on:click`
162
216
 
163
217
  | Token / class | Role |
164
218
  |---------------|------|
165
- | `surface-1` / `surface-2` | Layered backgrounds — prefer over raw neutrals so light/dark stay aligned. |
219
+ | `bg-surface-base` · `raised` · `elevated` · `overlay` | The four surface levels. Anything floating above content uses `overlay`. In dark mode each level is the one below it with more light on it — shadows don't read on a dark page. |
220
+ | `bg-surface-inset` | A recessed area on a card: a well, a stat strip, a code sample. Darker than the card in both themes. |
221
+ | `surface-1` / `surface-2` | Compatibility aliases for `raised` / `elevated`. Prefer the named levels in new code. |
222
+ | `shadow-sm` / `shadow-lg` | Elevation is **two steps**: raised, and floating. `shadow-none` is the explicit absence of one. `shadow-md`, `shadow-xl` and a bare `shadow` fail the build. |
223
+ | `rounded-control` · `container` · `overlay` · `pill` | Radius is chosen by **role**, never by size. A large button is a bigger box with the same corner as a small one. |
224
+ | `hover:bg-surface-hover` / `active:bg-surface-active` | Interaction fills. Surface-relative on purpose — a fixed ramp step can land on exactly the colour it sits on. |
166
225
  | `.focus-ring` / `focus-ring--nav` | Keyboard focus rings — don’t replace with `outline-none` unless you substitute an equivalent visible focus style. |
167
226
 
168
- Details: [THEME.md](./THEME.md).
227
+ Spacing rides a **4px grid**: `gap-*`, `space-*` and padding land on whole steps.
228
+ Half-steps survive only as optical nudges, and only on margins (`mt-0.5` on an
229
+ icon beside a first line of text).
230
+
231
+ `Heading` and `Text` share **one** type scale, so `<Text size="md">` sits on the
232
+ same line box as an `h6` and `size="lg"` as an `h5`.
233
+
234
+ Details: [THEME.md](./THEME.md) · [THEMING.md](./THEMING.md).
169
235
 
170
236
  ---
171
237
 
@@ -184,7 +250,17 @@ import Button from "some-path/node_modules/zabi-components/dist/atoms/Button.sve
184
250
 
185
251
  **Consumers — styling**
186
252
 
187
- Load theme CSS (Quick start). Unstyled components usually mean missing `@import "zabi-components/theme-only"` (and dark overrides if you use `.dark`).
253
+ Load theme CSS (Quick start). Unstyled components usually mean a missing `@import "zabi-components/theme-only"` (and dark overrides if you use `.dark`), or version 8.0.0 or earlier.
254
+
255
+ `class` is the public prop on every component and is merged **last**, through
256
+ [tailwind-merge](https://github.com/dcastil/tailwind-merge), so your utility
257
+ wins outright rather than racing the component's own:
258
+
259
+ ```svelte
260
+ <Card class="rounded-pill" /> <!-- rounded-container is dropped, not fought -->
261
+ ```
262
+
263
+ `className` still works everywhere as a deprecated alias.
188
264
 
189
265
  **Library code (contributors)**
190
266
 
@@ -195,7 +271,7 @@ import { analytics } from "../../routes/lib/analytics";
195
271
  // ✅ Shared helpers live next to components
196
272
  import { generateId } from "../util/ssr-safe.js";
197
273
 
198
- // ❌ Packaging: escaping `dist/` layout (CI fails `npm run check`)
274
+ // ❌ Packaging: escaping `dist/` layout (`npm run check` fails)
199
275
  import type { Foo } from "../../types/variants";
200
276
 
201
277
  // ✅ Depth matches publish layout
@@ -204,6 +280,200 @@ import type { Foo } from "../types/variants.js";
204
280
 
205
281
  ---
206
282
 
283
+ ## Phones: safe areas
284
+
285
+ Components that touch the edge of a phone screen keep clear of the notch and
286
+ the home indicator by reading `env(safe-area-inset-*)`: `AppShell`, `AppBar`,
287
+ `BottomTabBar`, `BottomSheet`, `StickyActionBar`, `FloatingActionButton`,
288
+ `Toaster`, a `Modal` with `fullScreen`, and `Page`. A browser reports those
289
+ insets as zero until the page asks to be drawn under them, so add
290
+ `viewport-fit=cover` to the viewport meta tag of the app:
291
+
292
+ ```html
293
+ <meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />
294
+ ```
295
+
296
+ `Page` pads its left, right and bottom by the insets; inside an `AppShell` it
297
+ adds nothing, because the shell has already done it, and `safeArea={false}`
298
+ turns it off where your own layout does. `Toaster` sits above an `AppShell`'s
299
+ tab bar by itself; for a bar of your own that is fixed to the bottom, give it
300
+ that bar's height through its bottom-offset custom property (see the Toaster
301
+ page of the docs). Full heights use `dvh`, so the browser's own bars do not
302
+ cut content off.
303
+
304
+ A `Tooltip` opens on a tap as well as on hover and focus, and stays until it is
305
+ dismissed. Do not put information the user needs in one.
306
+
307
+ ## Texts and other languages
308
+
309
+ Every word a component says by itself, shown or only read out, can be
310
+ replaced. The defaults are English.
311
+
312
+ ### Once, for the whole app
313
+
314
+ Put a `ZabiStringsProvider` around the app with its words, and every component
315
+ inside says those instead of English, without a prop on any of them:
316
+
317
+ ```svelte
318
+ <!-- src/routes/+layout.svelte -->
319
+ <script lang="ts">
320
+ import { ZabiStringsProvider, type ZabiStrings } from "zabi-components";
321
+
322
+ let { children } = $props();
323
+
324
+ const sv: ZabiStrings = {
325
+ // Words that many components' single-text props default to.
326
+ common: {
327
+ close: "Stäng",
328
+ back: "Tillbaka",
329
+ expand: "Visa mer",
330
+ collapse: "Visa mindre",
331
+ required: "(obligatoriskt)",
332
+ showPassword: "Visa lösenordet",
333
+ search: "Sök…",
334
+ confirm: "Bekräfta",
335
+ cancel: "Avbryt",
336
+ },
337
+ // One entry per component that has a `strings` object: the same keys.
338
+ select: {
339
+ placeholder: "Välj ett alternativ",
340
+ searchPlaceholder: "Sök",
341
+ noResults: "Inga träffar",
342
+ loading: "Hämtar alternativ…",
343
+ emptyTitle: "Inga alternativ",
344
+ emptyDescription: "Lägg till ett alternativ för att kunna välja.",
345
+ listLabel: "Alternativ",
346
+ },
347
+ stepper: {
348
+ position: (step, total) => `Steg ${step} av ${total}`,
349
+ stepLabel: (step, total, label, state) =>
350
+ `Steg ${step} av ${total}: ${label}, ${{ completed: "klart", current: "pågår", upcoming: "kommer" }[state]}`,
351
+ announcement: (step, total, label) => `Steg ${step} av ${total}: ${label}`,
352
+ },
353
+ calendar: {
354
+ previousMonth: "Föregående månad",
355
+ nextMonth: "Nästa månad",
356
+ today: "i dag",
357
+ selected: "vald",
358
+ unavailable: "inte valbar",
359
+ },
360
+ };
361
+ </script>
362
+
363
+ <ZabiStringsProvider strings={sv}>
364
+ {@render children()}
365
+ <!-- Inside the provider: the toaster reads the words of the provider it is mounted under. -->
366
+ <Toaster />
367
+ </ZabiStringsProvider>
368
+ ```
369
+
370
+ Mount the `Toaster` inside the provider. It is mounted once, at the root, and
371
+ a toaster placed beside the provider instead of in it says its own words in
372
+ English.
373
+
374
+ What a component says is decided in this order, the later winning:
375
+
376
+ 1. its built-in English;
377
+ 2. the provider's entry for it (`select`, `stepper`, …), or `common` for a
378
+ single-text prop such as `closeLabel`;
379
+ 3. the `strings` object passed to that one component;
380
+ 4. a single-text prop passed to it.
381
+
382
+ So a provider changes nothing for a component that already has its texts set,
383
+ and outside a provider everything is as it was. The entries are `alert`,
384
+ `avatarGroup`, `calendar`, `codeBlock`, `colorPicker`, `componentDemo`,
385
+ `contactForm`, `imageUpload`, `mediaGrid`, `photoGrid`, `photoViewer`,
386
+ `propsTable`, `pullToRefresh`, `rating`, `select`, `sidebarAccountPanel`,
387
+ `sidebarBrandHeader`, `sidebarFooter`, `sidebarNavigation`, `sortableList`,
388
+ `stepper`, `swipeableListItem`, `themeToggle`, `toast`, `toaster`, `topNavbar`
389
+ and `unsavedChangesBar`; the type is `ZabiStrings`, and `ZabiCommonStrings`
390
+ lists the common words. For Alert, CodeBlock, ImageUpload, Toast and
391
+ UnsavedChangesBar the entry's keys are the names of their text props
392
+ (`alert: { closeLabel }`, `codeBlock: { copyLabel, copiedLabel }`). Leave out what the app does not
393
+ use: there is nothing to translate for a component it never renders.
394
+
395
+ The provider is Svelte context. On a server it belongs to the request being
396
+ rendered, so two languages can be served at once; a provider inside another
397
+ replaces only the words it gives, for its part of the page; and a dialog or
398
+ sheet drawn in `<body>` still reads the provider it was written under. It adds
399
+ no element to the page. `getZabiStrings()` gives app code the same words: call
400
+ it while a component initialises and read `.current` where they are used.
401
+
402
+ The library ships no translations. The object is the app's.
403
+
404
+ What is not behind the provider is the names of landmarks and regions, which
405
+ say what a part of the app is and so are the app's to give: `ariaLabel` and
406
+ `label` props such as SidebarNavigation's "Sidebar navigation", a
407
+ PhotoViewer's, a Stepper's or a BottomTabBar's. Set those on the component.
408
+
409
+ ### On one component
410
+
411
+ A component with one or two such texts has a prop for each; one with several
412
+ takes a `strings` object, and whatever you leave out of it keeps its default.
413
+ A `strings` key and an older prop for the same text: the prop wins.
414
+
415
+ | Component | Prop that carries its texts |
416
+ |-----------|-----------------------------|
417
+ | Alert | `closeLabel` |
418
+ | AppBar | `backLabel` |
419
+ | BottomSheet | `closeLabel`, `expandLabel`, `collapseLabel` |
420
+ | BottomTabBar | `label`, `badgeLabel` |
421
+ | Calendar | `strings` |
422
+ | CodeBlock | `copyLabel`, `copiedLabel` |
423
+ | ColorPicker | `strings` |
424
+ | ComponentDemo | `strings` |
425
+ | ConfirmDialog | `confirmLabel`, `cancelLabel`, `loadingLabel` |
426
+ | ContactForm | `strings` (the whole form is ready-made English: pass them all, or build your own from Form and FormField) |
427
+ | Drawer, Modal, SlideUp | `closeLabel` |
428
+ | Dropdown | `ariaLabel`; in a sheet also `sheetTitle`, `sheetCloseLabel`, `sheetExpandLabel`, `sheetCollapseLabel` |
429
+ | FormField | `requiredLabel` |
430
+ | ImageUpload | `placeholder`, `browseText`, `changeText`, `removeText`, `selectedText`, `removedText`, `errorTitle` |
431
+ | List | `ariaLabel` |
432
+ | AvatarGroup, PullToRefresh, SwipeableListItem | `strings` (and `label` on AvatarGroup) |
433
+ | MediaGrid, PhotoGrid, PhotoViewer, SortableList, Stepper, Rating | `strings` (and `label` on PhotoViewer and Stepper) |
434
+ | NavigationMenu | `ariaLabel` |
435
+ | PropsTable | `caption`, `strings` |
436
+ | Select | `strings` (every text, the name of the option list included); the older `placeholder`, `searchPlaceholder`, `noResultsText`, `loadingText`, `emptyStateTitle`, `emptyStateDescription` still work and win over it |
437
+ | SidebarAccountPanel | `strings`, `logoutLabel` |
438
+ | SidebarBrandHeader | `logoAlt`, `strings` |
439
+ | SidebarFooter | `strings` |
440
+ | SidebarNavigation | `strings` (its own, the footer's and the brand header's), `ariaLabel`, `searchPlaceholder`, `logoutLabel`, `emptyStateTitle`, `emptyStateDescription`, `emptyStateActionLabel` |
441
+ | SidebarPanel | `ariaLabel`, `title`, `subtitle`, `searchPlaceholder`, `emptyStateTitle`, `emptyStateDescription`, `selectLabel`, `closeLabel` |
442
+ | SidebarShell | `ariaLabel` |
443
+ | Skeleton | `aria-label` |
444
+ | ThemeToggle | `labels` |
445
+ | Toast | `closeLabel` |
446
+ | Toaster | `strings`, `aria-label` |
447
+ | Toggle | `label`, or `aria-label` / `aria-labelledby` (without any of them it is called "Toggle") |
448
+ | TopNavbar | `strings`, `ariaLabel`, `themeLabels` |
449
+ | UnsavedChangesBar | `message`, `label`, `saveLabel`, `discardLabel` |
450
+
451
+ The name of the list in a SidebarShell is its `label` prop. One text is the
452
+ browser's, not the library's: when a `required` Select is sent empty, the
453
+ message under it is the browser's own validation message, in the browser's
454
+ language; pass `error` to say it yourself.
455
+
456
+ A toast shows what it was pushed with, so its text is yours already. The
457
+ toaster's own words are the names of its buttons and of its region, and the
458
+ sentence about the time a toast has left:
459
+
460
+ ```svelte
461
+ <Toaster
462
+ strings={{
463
+ regionLabel: "Aviseringar",
464
+ dismiss: "Stäng aviseringen",
465
+ expand: "Visa mer",
466
+ collapse: "Visa mindre",
467
+ okay: "Okej",
468
+ closesIn: (seconds) => `Stängs om ${seconds} sekunder.`,
469
+ pausedClosesIn: (seconds) => `Pausad. Stängs om ${seconds} sekunder.`,
470
+ actionAvailable: (label) => `${label} finns.`,
471
+ }}
472
+ />
473
+
474
+ pushToast({ message: "Utkastet är sparat.", type: "success" });
475
+ ```
476
+
207
477
  ## Common pitfalls
208
478
 
209
479
  | Issue | What goes wrong | Fix |
@@ -232,12 +502,18 @@ import type { Foo } from "../types/variants.js";
232
502
  |-------|---------|---------|
233
503
  | Unit / component | `npm run test` | Vitest + Testing Library — logic and regressions |
234
504
  | Interaction | `npm run test:e2e` | Playwright — overlays, focus, keyboard flows |
505
+ | Types & structure | `npm run check` | `svelte-check`, import-path and layout-width rules, plus `check:design` |
506
+ | Design system | `npm run check:design` | Ramp lightness, WCAG AA on every rendered pair, the focus ring at 3:1, interaction fills and hover tints that read on their surface, control geometry, token violations (raw palette classes, off-scale shadows, half-step spacing), and state variants that cannot win |
507
+ | Theme output | `npm run test:themes` | Built CSS is reproducible and matches the frozen hashes |
508
+
509
+ There is no CI: every gate runs locally, and releases are published by hand. See
510
+ [RELEASING.md](https://github.com/sabnor/zabi-components/blob/main/RELEASING.md) in the repository for the order to run them in.
235
511
 
236
512
  ---
237
513
 
238
514
  ## More documentation
239
515
 
240
- [THEME.md](./THEME.md) · [THEMING.md](./THEMING.md) · [docs/theme-imports.md](./docs/theme-imports.md) · [CHANGELOG.md](./CHANGELOG.md)
516
+ [THEME.md](./THEME.md) · [THEMING.md](./THEMING.md) · [docs/theme-imports.md](./docs/theme-imports.md) · [docs/lucide-icons.md](./docs/lucide-icons.md) · [CHANGELOG.md](./CHANGELOG.md) · [RELEASING.md](https://github.com/sabnor/zabi-components/blob/main/RELEASING.md) (in the repository; it is not part of the package)
241
517
 
242
518
  ## License
243
519