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
@@ -2,6 +2,7 @@
2
2
  import Badge from "./Badge.svelte";
3
3
  import type { ExtendedSemanticVariant } from "../types/variants.js";
4
4
 
5
+ import { cn } from "../util/cn.js";
5
6
  interface Props {
6
7
  title: string;
7
8
  description: string;
@@ -13,6 +14,8 @@
13
14
  badgeVariant?: ExtendedSemanticVariant;
14
15
  /** Overrides the default accessible name for the clickable region. */
15
16
  ariaLabel?: string;
17
+ class?: string;
18
+ /** @deprecated use `class`. */
16
19
  className?: string;
17
20
  target?: HTMLAnchorElement["target"];
18
21
  rel?: string;
@@ -28,12 +31,17 @@
28
31
  badgeText,
29
32
  badgeVariant = "neutral",
30
33
  ariaLabel,
31
- className = "",
34
+ class: classAttr = "",
35
+ className: legacyClass = "",
32
36
  target,
33
37
  rel,
34
38
  ...restProps
35
39
  }: Props = $props();
36
40
 
41
+ /** `class` is the public prop; `className` is a deprecated alias.
42
+ * Both are merged here so existing call sites keep working. */
43
+ const className = $derived(`${classAttr} ${legacyClass}`.trim());
44
+
37
45
  const isDisabled = $derived(disabled || loading);
38
46
 
39
47
  const computedAriaLabel = $derived(
@@ -41,18 +49,25 @@
41
49
  );
42
50
 
43
51
  const baseClasses =
44
- "group focus-ring focus-ring--muted block rounded-2xl border border-base-200 bg-base-0 p-6 text-left transition-all duration-200 hover:border-headline/30 hover:bg-base-50 active:scale-[0.99] active:bg-base-100";
52
+ "group focus-ring focus-ring--muted block rounded-container border border-border bg-card p-6 text-left transition-colors duration-150";
53
+
54
+ /**
55
+ * The hover and pressed tints are translucent, so they are drawn as a
56
+ * background image over the card fill rather than in place of it: swapping
57
+ * `bg-card` for a tint would let the page show through the panel. (A
58
+ * `hover:bg-*` beside `bg-card` also never applies; see THEMING.md, state
59
+ * variants.)
60
+ */
61
+ const interactiveClasses =
62
+ "bg-linear-to-b from-transparent to-transparent hover:border-border-medium hover:from-surface-hover hover:to-surface-hover active:scale-[0.99] active:from-surface-active active:to-surface-active";
45
63
 
46
- const disabledClasses =
47
- "opacity-50 cursor-not-allowed pointer-events-none hover:border-base-200 hover:bg-base-0 active:scale-100";
64
+ const disabledClasses = "opacity-50 cursor-not-allowed pointer-events-none";
48
65
 
49
66
  const panelClasses = $derived(
50
- [baseClasses, isDisabled ? disabledClasses : "", className]
51
- .filter(Boolean)
52
- .join(" ")
53
- .trim(),
67
+ cn(baseClasses, isDisabled ? disabledClasses : interactiveClasses, className),
54
68
  );
55
69
 
70
+
56
71
  function handleKeydown(event: KeyboardEvent) {
57
72
  if (isDisabled) return;
58
73
  if (!href && onclick && (event.key === "Enter" || event.key === " ")) {
@@ -78,7 +93,7 @@
78
93
  {/if}
79
94
  {#if loading}
80
95
  <span
81
- class="inline-block size-5 shrink-0 animate-spin rounded-full border-2 border-description border-t-transparent opacity-70"
96
+ class="inline-block size-5 shrink-0 animate-spin rounded-full border-2 border-description border-t-transparent opacity-70 motion-reduce:animate-pulse"
82
97
  aria-hidden="true"
83
98
  ></span>
84
99
  {/if}
@@ -10,6 +10,8 @@ interface Props {
10
10
  badgeVariant?: ExtendedSemanticVariant;
11
11
  /** Overrides the default accessible name for the clickable region. */
12
12
  ariaLabel?: string;
13
+ class?: string;
14
+ /** @deprecated use `class`. */
13
15
  className?: string;
14
16
  target?: HTMLAnchorElement["target"];
15
17
  rel?: string;
@@ -0,0 +1,104 @@
1
+ <script lang="ts">
2
+ import User from "@lucide/svelte/icons/user";
3
+ import { untrack } from "svelte";
4
+ import type { HTMLAttributes } from "svelte/elements";
5
+ import { initialsOf, type AvatarSize } from "../util/avatar.js";
6
+ import { cn } from "../util/cn.js";
7
+
8
+ /**
9
+ * A round picture of a person, which falls back to their initials.
10
+ *
11
+ * It is one image with one name, the person's: the picture, the initials
12
+ * and the icon inside are presentational. Not interactive: put it in a
13
+ * link or a button of your own.
14
+ *
15
+ * Other attributes (`id`, `data-*`, ...) land on the root element.
16
+ */
17
+ type Props = Omit<HTMLAttributes<HTMLSpanElement>, "class" | "role" | "aria-label"> & {
18
+ /** The person's name: the accessible name, and where the initials come from. */
19
+ name: string;
20
+ /** Address of the picture. Without it, or when it fails to load, the initials show. */
21
+ src?: string;
22
+ /** Diameter: 24, 32 and 48px. It does not grow with the text size. */
23
+ size?: "sm" | "md" | "lg";
24
+ /**
25
+ * Accessible name, when it should differ from `name`. `alt=""` makes
26
+ * the avatar decorative: for a name that is printed beside it.
27
+ */
28
+ alt?: string;
29
+ /**
30
+ * Language the initials are upper-cased in ("tr" turns "i" into "İ").
31
+ * The page's own (`<html lang>`) by default, which the server cannot
32
+ * read: pass it where that matters.
33
+ */
34
+ locale?: string;
35
+ /** Extra classes for the root element. */
36
+ class?: string;
37
+ };
38
+
39
+ let {
40
+ name,
41
+ src,
42
+ size = "md",
43
+ alt,
44
+ locale,
45
+ class: className = "",
46
+ ...restProps
47
+ }: Props = $props();
48
+
49
+ const pageLocale = typeof document !== "undefined" ? document.documentElement.lang : "";
50
+ const initials = $derived(initialsOf(name, locale || pageLocale));
51
+ const label = $derived(alt ?? name);
52
+
53
+ /** The address that did not load. Another address gets its own try. */
54
+ let failedSrc = $state<string>();
55
+ const failed = $derived(!!src && failedSrc === src);
56
+
57
+ /** A picture that had already failed before the page hydrated fired its `error` to nobody. */
58
+ function settled(image: HTMLImageElement) {
59
+ if (image.complete && image.naturalWidth === 0) untrack(() => (failedSrc = src));
60
+ }
61
+
62
+ // The circle and the type in it are in px: a face in a row of people is
63
+ // the same size whatever the text size is, and the initials stay inside.
64
+ const SIZES: Record<AvatarSize, string> = {
65
+ sm: "size-[24px] text-[10px]",
66
+ md: "size-[32px] text-[12px]",
67
+ lg: "size-[48px] text-[16px]",
68
+ };
69
+ </script>
70
+
71
+ <!-- The subtle primary pair, as a selected pill tab has: held to 4.5:1 in both
72
+ themes by scripts/contrast-pairs.js. The border is for forced colours, where
73
+ the fill is gone and a transparent border is drawn. -->
74
+ <span
75
+ class={cn(
76
+ "relative inline-flex shrink-0 items-center justify-center overflow-hidden rounded-pill border border-transparent bg-action-primary-subtle align-middle leading-none font-semibold text-link select-none",
77
+ SIZES[size] ?? SIZES.md,
78
+ className,
79
+ )}
80
+ data-avatar
81
+ data-size={size}
82
+ role={label ? "img" : undefined}
83
+ aria-label={label || undefined}
84
+ aria-hidden={label ? undefined : "true"}
85
+ {...restProps}
86
+ >
87
+ <!-- Under the picture from the start, in the server's markup too: nothing
88
+ moves when the picture arrives, or when it does not. -->
89
+ {#if initials}
90
+ <span aria-hidden="true" data-avatar-initials>{initials}</span>
91
+ {:else}
92
+ <User class="size-[60%]" aria-hidden="true" />
93
+ {/if}
94
+ {#if src && !failed}
95
+ <img
96
+ {src}
97
+ alt=""
98
+ class="absolute inset-0 size-full object-cover"
99
+ draggable="false"
100
+ onerror={() => (failedSrc = src)}
101
+ {@attach settled}
102
+ />
103
+ {/if}
104
+ </span>
@@ -0,0 +1,34 @@
1
+ import type { HTMLAttributes } from "svelte/elements";
2
+ /**
3
+ * A round picture of a person, which falls back to their initials.
4
+ *
5
+ * It is one image with one name, the person's: the picture, the initials
6
+ * and the icon inside are presentational. Not interactive: put it in a
7
+ * link or a button of your own.
8
+ *
9
+ * Other attributes (`id`, `data-*`, ...) land on the root element.
10
+ */
11
+ type Props = Omit<HTMLAttributes<HTMLSpanElement>, "class" | "role" | "aria-label"> & {
12
+ /** The person's name: the accessible name, and where the initials come from. */
13
+ name: string;
14
+ /** Address of the picture. Without it, or when it fails to load, the initials show. */
15
+ src?: string;
16
+ /** Diameter: 24, 32 and 48px. It does not grow with the text size. */
17
+ size?: "sm" | "md" | "lg";
18
+ /**
19
+ * Accessible name, when it should differ from `name`. `alt=""` makes
20
+ * the avatar decorative: for a name that is printed beside it.
21
+ */
22
+ alt?: string;
23
+ /**
24
+ * Language the initials are upper-cased in ("tr" turns "i" into "İ").
25
+ * The page's own (`<html lang>`) by default, which the server cannot
26
+ * read: pass it where that matters.
27
+ */
28
+ locale?: string;
29
+ /** Extra classes for the root element. */
30
+ class?: string;
31
+ };
32
+ declare const Avatar: import("svelte").Component<Props, {}, "">;
33
+ type Avatar = ReturnType<typeof Avatar>;
34
+ export default Avatar;
@@ -1,82 +1,148 @@
1
1
  <script lang="ts">
2
- import { Check, AlertTriangle, X, Info } from "@lucide/svelte";
2
+ import type { Snippet } from "svelte";
3
+ import type { HTMLAttributes } from "svelte/elements";
4
+ import Check from "@lucide/svelte/icons/check";
5
+ import TriangleAlert from "@lucide/svelte/icons/triangle-alert";
6
+ import X from "@lucide/svelte/icons/x";
7
+ import Info from "@lucide/svelte/icons/info";
8
+ import Zap from "@lucide/svelte/icons/zap";
9
+ import { cn } from "../util/cn.js";
3
10
  import type {
4
- ExtendedSemanticVariant,
11
+ BadgeVariant,
5
12
  SizeVariant,
6
13
  } from "../types/variants.js";
7
14
 
8
- interface Props {
9
- variant?: ExtendedSemanticVariant;
15
+ /**
16
+ * `subtle` is the default because a page full of saturated fills is noise —
17
+ * a badge is a label, not a button. `solid` is there for the one badge on
18
+ * a screen that has to shout.
19
+ */
20
+ type BadgeEmphasis = "subtle" | "solid";
21
+
22
+ type Props = Omit<HTMLAttributes<HTMLSpanElement>, "class"> & {
23
+ variant?: BadgeVariant;
10
24
  size?: SizeVariant;
11
- text: string;
25
+ emphasis?: BadgeEmphasis;
26
+ /** Label text. Ignored when `children` is provided. */
27
+ text?: string;
12
28
  showIcon?: boolean;
13
- }
29
+ class?: string;
30
+ children?: Snippet;
31
+ };
14
32
 
15
33
  let {
16
34
  variant = "default",
17
35
  size = "md",
36
+ emphasis = "subtle",
18
37
  text = "",
19
38
  showIcon = false,
39
+ class: className = "",
40
+ children,
41
+ ...restProps
20
42
  }: Props = $props();
21
43
 
22
- const classes = $derived(() => {
23
- const baseClasses =
24
- "inline-flex items-center font-medium border rounded-xs";
25
-
26
- const sizeClass =
27
- size === "sm"
28
- ? "px-2 py-0.5 text-xs"
29
- : size === "lg"
30
- ? "px-4 py-2 text-base"
31
- : "px-3 py-1 text-sm";
32
-
33
- const variantClass =
34
- variant === "success"
35
- ? "bg-success border-success text-card"
36
- : variant === "warning"
37
- ? "bg-warning border-warning text-card"
38
- : variant === "error"
39
- ? "bg-error border-error text-card"
40
- : variant === "info"
41
- ? "bg-info border-info text-card"
42
- : variant === "neutral"
43
- ? "bg-neutral border-neutral text-card"
44
- : variant === "energetic"
45
- ? "bg-energetic border-energetic text-card"
46
- : "bg-secondary border-secondary text-card";
47
-
48
- return `${baseClasses} ${sizeClass} ${variantClass}`.trim();
44
+ /**
45
+ * 20, 24 and 28px tall for a label on one line, as a minimum: a label that
46
+ * does not fit wraps and the badge grows. It used to be a fixed height
47
+ * with `whitespace-nowrap`, and a long label beside a flexible name made
48
+ * the page wider than a phone at 200% text.
49
+ *
50
+ * The vertical padding is what is left of the height after one line of
51
+ * text and the 1px border on each side (16 + 2 + 2, 16 + 6 + 2 and
52
+ * 20 + 6 + 2), so a one-line badge is exactly as tall as it was.
53
+ *
54
+ * The corner is half of that one-line height, not the pill radius: for
55
+ * one line that is the same full round end, and a badge of two lines
56
+ * keeps the same corner and becomes a rounded rectangle, where a pill
57
+ * radius would have turned it into a lozenge with its text in the curve.
58
+ */
59
+ const sizeClass = $derived.by(() => {
60
+ if (size === "sm") return { box: "min-h-5 py-px px-2 gap-1 text-xs rounded-[0.625rem]", icon: 12 };
61
+ if (size === "lg") return { box: "min-h-7 py-[3px] px-3 gap-2 text-sm rounded-[0.875rem]", icon: 16 };
62
+ return { box: "min-h-6 py-[3px] px-2 gap-1 text-xs rounded-[0.75rem]", icon: 14 };
49
63
  });
50
64
 
51
- const iconSize = $derived(() => {
52
- return size === "sm" ? 12 : size === "lg" ? 20 : 16;
65
+ /**
66
+ * Both emphases are built from the SAME step of each family's ramp, so
67
+ * every variant reads at the same weight. Subtle is 100/200/800 (8.2:1),
68
+ * solid is 600 with its `-text` foreground (4.9:1). Before the ramps were
69
+ * calibrated, a solid warning badge sat at 2.15:1 and energetic at 1.97:1.
70
+ */
71
+ const variantClass = $derived.by(() => {
72
+ const solid = emphasis === "solid";
73
+ switch (variant) {
74
+ case "success":
75
+ return solid
76
+ ? "bg-success text-card border-transparent"
77
+ : "bg-success-subtle text-success-text border-success-border";
78
+ case "warning":
79
+ return solid
80
+ ? "bg-warning text-card border-transparent"
81
+ : "bg-warning-subtle text-warning-text border-warning-border";
82
+ case "error":
83
+ return solid
84
+ ? "bg-error text-card border-transparent"
85
+ : "bg-error-subtle text-error-text border-error-border";
86
+ case "info":
87
+ return solid
88
+ ? "bg-info text-card border-transparent"
89
+ : "bg-info-subtle text-info-text border-info-border";
90
+ case "energetic":
91
+ return solid
92
+ ? "bg-energetic text-card border-transparent"
93
+ : "bg-energetic-subtle text-energetic-text border-energetic-border";
94
+ // The app's second brand colour. Its solid label is the "on accent"
95
+ // role, not the card surface: an app with a light accent (a
96
+ // yellow) sets a dark label there, and white would be unreadable.
97
+ case "accent":
98
+ return solid
99
+ ? "bg-accent text-on-accent border-transparent"
100
+ : "bg-accent-subtle text-accent-text border-accent-border";
101
+ case "neutral":
102
+ case "default":
103
+ default:
104
+ return solid
105
+ ? "bg-neutral text-card border-transparent"
106
+ : "bg-neutral-subtle text-neutral-text border-neutral-border";
107
+ }
53
108
  });
54
109
 
55
- const iconSpacingClass = $derived(() => {
56
- return size === "sm" ? "mr-1" : size === "lg" ? "mr-2" : "mr-1.5";
110
+ const badgeClasses = $derived(
111
+ // Never wider than what it is in, and its words break onto the next
112
+ // line before they push anything out; a word longer than the line
113
+ // breaks inside. The icon stays centred beside the lines.
114
+ cn(`inline-flex [max-inline-size:100%] min-w-0 items-center justify-center border font-medium [overflow-wrap:anywhere] ${sizeClass.box} ${variantClass} ${className}`),
115
+ );
116
+
117
+ /** One outline icon family, so the variants don't look like a rummage. */
118
+ const Icon = $derived.by(() => {
119
+ switch (variant) {
120
+ case "success":
121
+ return Check;
122
+ case "warning":
123
+ return TriangleAlert;
124
+ case "error":
125
+ return X;
126
+ case "energetic":
127
+ return Zap;
128
+ default:
129
+ return Info;
130
+ }
57
131
  });
132
+
133
+ const hasLabel = $derived(Boolean(children) || Boolean(text));
58
134
  </script>
59
135
 
60
- <span class={classes()}>
61
- {#if showIcon}
62
- {#if variant === "success"}
63
- <Check size={iconSize()} class="{iconSpacingClass()} text-card" />
64
- {:else if variant === "warning"}
65
- <AlertTriangle
66
- size={iconSize()}
67
- class="{iconSpacingClass()} text-card"
68
- />
69
- {:else if variant === "error"}
70
- <X size={iconSize()} class="{iconSpacingClass()} text-card" />
71
- {:else if variant === "info"}
72
- <Info size={iconSize()} class="{iconSpacingClass()} text-card" />
73
- {:else if variant === "neutral"}
74
- <Info size={iconSize()} class="{iconSpacingClass()} text-card" />
75
- {:else if variant === "energetic"}
76
- <Info size={iconSize()} class="{iconSpacingClass()} text-card" />
136
+ {#if hasLabel}
137
+ <span class={badgeClasses} {...restProps}>
138
+ {#if showIcon}
139
+ {@const BadgeIcon = Icon}
140
+ <BadgeIcon size={sizeClass.icon} class="shrink-0" aria-hidden="true" />
141
+ {/if}
142
+ {#if children}
143
+ {@render children()}
77
144
  {:else}
78
- <Info size={iconSize()} class="{iconSpacingClass()} text-card" />
145
+ {text}
79
146
  {/if}
80
- {/if}
81
- {text}
82
- </span>
147
+ </span>
148
+ {/if}
@@ -1,10 +1,22 @@
1
- import type { ExtendedSemanticVariant, SizeVariant } from "../types/variants.js";
2
- interface Props {
3
- variant?: ExtendedSemanticVariant;
1
+ import type { Snippet } from "svelte";
2
+ import type { HTMLAttributes } from "svelte/elements";
3
+ import type { BadgeVariant, SizeVariant } from "../types/variants.js";
4
+ /**
5
+ * `subtle` is the default because a page full of saturated fills is noise —
6
+ * a badge is a label, not a button. `solid` is there for the one badge on
7
+ * a screen that has to shout.
8
+ */
9
+ type BadgeEmphasis = "subtle" | "solid";
10
+ type Props = Omit<HTMLAttributes<HTMLSpanElement>, "class"> & {
11
+ variant?: BadgeVariant;
4
12
  size?: SizeVariant;
5
- text: string;
13
+ emphasis?: BadgeEmphasis;
14
+ /** Label text. Ignored when `children` is provided. */
15
+ text?: string;
6
16
  showIcon?: boolean;
7
- }
17
+ class?: string;
18
+ children?: Snippet;
19
+ };
8
20
  declare const Badge: import("svelte").Component<Props, {}, "">;
9
21
  type Badge = ReturnType<typeof Badge>;
10
22
  export default Badge;