zabi-components 8.0.0 → 9.0.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 (456) hide show
  1. package/CHANGELOG.md +2935 -0
  2. package/README.md +243 -10
  3. package/THEME.md +162 -332
  4. package/THEMING.md +1419 -259
  5. package/dist/atoms/ActionPanel.svelte +15 -5
  6. package/dist/atoms/Avatar.svelte +120 -0
  7. package/dist/atoms/Avatar.svelte.d.ts +46 -0
  8. package/dist/atoms/Badge.svelte +71 -13
  9. package/dist/atoms/Badge.svelte.d.ts +8 -2
  10. package/dist/atoms/Block.svelte +74 -0
  11. package/dist/atoms/Block.svelte.d.ts +29 -0
  12. package/dist/atoms/Button.svelte +217 -30
  13. package/dist/atoms/Button.svelte.d.ts +33 -4
  14. package/dist/atoms/Card.svelte +182 -26
  15. package/dist/atoms/Card.svelte.d.ts +55 -3
  16. package/dist/atoms/CardHeader.svelte +16 -4
  17. package/dist/atoms/Checkbox.svelte +81 -21
  18. package/dist/atoms/Checkbox.svelte.d.ts +31 -2
  19. package/dist/atoms/Chip.svelte +351 -0
  20. package/dist/atoms/Chip.svelte.d.ts +57 -0
  21. package/dist/atoms/CodeBlock.svelte +20 -2
  22. package/dist/atoms/CodeBlock.svelte.d.ts +4 -0
  23. package/dist/atoms/CodeField.svelte +385 -0
  24. package/dist/atoms/CodeField.svelte.d.ts +61 -0
  25. package/dist/atoms/ColorPicker.svelte +260 -49
  26. package/dist/atoms/ColorPicker.svelte.d.ts +3 -0
  27. package/dist/atoms/Container.svelte +16 -8
  28. package/dist/atoms/DateField.svelte +145 -0
  29. package/dist/atoms/DateField.svelte.d.ts +81 -0
  30. package/dist/atoms/FieldMessages.svelte +69 -0
  31. package/dist/atoms/FieldMessages.svelte.d.ts +23 -0
  32. package/dist/atoms/FloatingActionButton.svelte +176 -0
  33. package/dist/atoms/FloatingActionButton.svelte.d.ts +51 -0
  34. package/dist/atoms/Heading.svelte +63 -5
  35. package/dist/atoms/Heading.svelte.d.ts +14 -0
  36. package/dist/atoms/IconButton.svelte +294 -26
  37. package/dist/atoms/IconButton.svelte.d.ts +62 -4
  38. package/dist/atoms/Input.svelte +259 -53
  39. package/dist/atoms/Input.svelte.d.ts +33 -2
  40. package/dist/atoms/List.svelte +5 -1
  41. package/dist/atoms/ListItem.svelte +70 -13
  42. package/dist/atoms/ListItem.svelte.d.ts +11 -0
  43. package/dist/atoms/PickerField.svelte +239 -0
  44. package/dist/atoms/PickerField.svelte.d.ts +67 -0
  45. package/dist/atoms/Progress.svelte +99 -19
  46. package/dist/atoms/Progress.svelte.d.ts +15 -1
  47. package/dist/atoms/Radio.svelte +51 -3
  48. package/dist/atoms/Radio.svelte.d.ts +30 -2
  49. package/dist/atoms/Rating.svelte +620 -0
  50. package/dist/atoms/Rating.svelte.d.ts +77 -0
  51. package/dist/atoms/Select.svelte +438 -98
  52. package/dist/atoms/Select.svelte.d.ts +61 -3
  53. package/dist/atoms/SelectionControl.svelte +193 -23
  54. package/dist/atoms/SelectionControl.svelte.d.ts +29 -3
  55. package/dist/atoms/Skeleton.svelte +114 -18
  56. package/dist/atoms/Skeleton.svelte.d.ts +30 -3
  57. package/dist/atoms/SkeletonGroup.svelte +43 -0
  58. package/dist/atoms/SkeletonGroup.svelte.d.ts +20 -0
  59. package/dist/atoms/Slider.svelte +344 -0
  60. package/dist/atoms/Slider.svelte.d.ts +40 -0
  61. package/dist/atoms/Sparkline.svelte +109 -0
  62. package/dist/atoms/Sparkline.svelte.d.ts +27 -0
  63. package/dist/atoms/SpeechBubble.svelte +187 -0
  64. package/dist/atoms/SpeechBubble.svelte.d.ts +33 -0
  65. package/dist/atoms/Spinner.svelte +57 -0
  66. package/dist/atoms/Spinner.svelte.d.ts +19 -0
  67. package/dist/atoms/Stat.svelte +72 -0
  68. package/dist/atoms/Stat.svelte.d.ts +19 -0
  69. package/dist/atoms/Table.svelte +151 -6
  70. package/dist/atoms/Table.svelte.d.ts +15 -3
  71. package/dist/atoms/TemporalField.svelte +472 -0
  72. package/dist/atoms/TemporalField.svelte.d.ts +48 -0
  73. package/dist/atoms/Text.svelte +23 -11
  74. package/dist/atoms/Text.svelte.d.ts +6 -3
  75. package/dist/atoms/Textarea.svelte +150 -44
  76. package/dist/atoms/Textarea.svelte.d.ts +35 -2
  77. package/dist/atoms/ThemeToggle.svelte +223 -44
  78. package/dist/atoms/ThemeToggle.svelte.d.ts +26 -3
  79. package/dist/atoms/TimeColumn.svelte +150 -0
  80. package/dist/atoms/TimeColumn.svelte.d.ts +25 -0
  81. package/dist/atoms/TimeField.svelte +151 -0
  82. package/dist/atoms/TimeField.svelte.d.ts +85 -0
  83. package/dist/atoms/Toast.svelte +22 -8
  84. package/dist/atoms/Toast.svelte.d.ts +2 -0
  85. package/dist/atoms/Toggle.svelte +98 -14
  86. package/dist/atoms/Toggle.svelte.d.ts +26 -2
  87. package/dist/atoms/Tooltip.svelte +528 -24
  88. package/dist/atoms/Tooltip.svelte.d.ts +18 -0
  89. package/dist/atoms/ZabiStringsProvider.svelte +45 -0
  90. package/dist/atoms/ZabiStringsProvider.svelte.d.ts +27 -0
  91. package/dist/atoms/index.d.ts +38 -0
  92. package/dist/atoms/index.js +29 -0
  93. package/dist/atoms/selection-control.styles.d.ts +47 -5
  94. package/dist/atoms/selection-control.styles.js +52 -10
  95. package/dist/components/atoms/index.d.ts +38 -0
  96. package/dist/components/atoms/index.d.ts.map +1 -1
  97. package/dist/components/atoms/selection-control.styles.d.ts +47 -5
  98. package/dist/components/atoms/selection-control.styles.d.ts.map +1 -1
  99. package/dist/components/index.d.ts +104 -2
  100. package/dist/components/index.d.ts.map +1 -1
  101. package/dist/components/map.d.ts +11 -0
  102. package/dist/components/map.d.ts.map +1 -0
  103. package/dist/components/molecules/index.d.ts +51 -0
  104. package/dist/components/molecules/index.d.ts.map +1 -1
  105. package/dist/components/molecules/toast-store.d.ts +83 -7
  106. package/dist/components/molecules/toast-store.d.ts.map +1 -1
  107. package/dist/components/organisms/index.d.ts +10 -0
  108. package/dist/components/organisms/index.d.ts.map +1 -1
  109. package/dist/components/types/variants.d.ts +24 -1
  110. package/dist/components/types/variants.d.ts.map +1 -1
  111. package/dist/components/util/app-shell.d.ts +79 -0
  112. package/dist/components/util/app-shell.d.ts.map +1 -0
  113. package/dist/components/util/avatar.d.ts +39 -0
  114. package/dist/components/util/avatar.d.ts.map +1 -0
  115. package/dist/components/util/bottom-sheet.d.ts +30 -0
  116. package/dist/components/util/bottom-sheet.d.ts.map +1 -0
  117. package/dist/components/util/bottom-tab-bar.d.ts +41 -0
  118. package/dist/components/util/bottom-tab-bar.d.ts.map +1 -0
  119. package/dist/components/util/calendar.d.ts +56 -0
  120. package/dist/components/util/calendar.d.ts.map +1 -0
  121. package/dist/components/util/chart.d.ts +140 -0
  122. package/dist/components/util/chart.d.ts.map +1 -0
  123. package/dist/components/util/chip.d.ts +66 -0
  124. package/dist/components/util/chip.d.ts.map +1 -0
  125. package/dist/components/util/cn.d.ts.map +1 -1
  126. package/dist/components/util/code-field.d.ts +63 -0
  127. package/dist/components/util/code-field.d.ts.map +1 -0
  128. package/dist/components/util/collapsible.d.ts +64 -0
  129. package/dist/components/util/collapsible.d.ts.map +1 -0
  130. package/dist/components/util/confirm-dialog.d.ts +12 -0
  131. package/dist/components/util/confirm-dialog.d.ts.map +1 -0
  132. package/dist/components/util/date.d.ts +96 -0
  133. package/dist/components/util/date.d.ts.map +1 -0
  134. package/dist/components/util/display-voice.d.ts +10 -0
  135. package/dist/components/util/display-voice.d.ts.map +1 -0
  136. package/dist/components/util/drawer.d.ts +13 -0
  137. package/dist/components/util/drawer.d.ts.map +1 -0
  138. package/dist/components/util/dropdown.d.ts +47 -0
  139. package/dist/components/util/dropdown.d.ts.map +1 -0
  140. package/dist/components/util/field-control.d.ts +30 -0
  141. package/dist/components/util/field-control.d.ts.map +1 -0
  142. package/dist/components/util/field.d.ts +45 -0
  143. package/dist/components/util/field.d.ts.map +1 -0
  144. package/dist/components/util/fit-in-viewport.d.ts +201 -0
  145. package/dist/components/util/fit-in-viewport.d.ts.map +1 -0
  146. package/dist/components/util/focus-utils.d.ts +77 -2
  147. package/dist/components/util/focus-utils.d.ts.map +1 -1
  148. package/dist/components/util/hydration.d.ts +45 -0
  149. package/dist/components/util/hydration.d.ts.map +1 -0
  150. package/dist/components/util/keyboard-inset.d.ts +18 -0
  151. package/dist/components/util/keyboard-inset.d.ts.map +1 -0
  152. package/dist/components/util/map-view.d.ts +144 -0
  153. package/dist/components/util/map-view.d.ts.map +1 -0
  154. package/dist/components/util/media-grid.d.ts +51 -0
  155. package/dist/components/util/media-grid.d.ts.map +1 -0
  156. package/dist/components/util/media.d.ts +6 -0
  157. package/dist/components/util/media.d.ts.map +1 -0
  158. package/dist/components/util/overlay-chrome.d.ts +53 -0
  159. package/dist/components/util/overlay-chrome.d.ts.map +1 -0
  160. package/dist/components/util/overlay.d.ts +72 -0
  161. package/dist/components/util/overlay.d.ts.map +1 -0
  162. package/dist/components/util/photo.d.ts +234 -0
  163. package/dist/components/util/photo.d.ts.map +1 -0
  164. package/dist/components/util/portal.d.ts +23 -0
  165. package/dist/components/util/portal.d.ts.map +1 -0
  166. package/dist/components/util/progress.d.ts +19 -0
  167. package/dist/components/util/progress.d.ts.map +1 -0
  168. package/dist/components/util/pull-to-refresh.d.ts +27 -0
  169. package/dist/components/util/pull-to-refresh.d.ts.map +1 -0
  170. package/dist/components/util/radio-keys.d.ts +25 -0
  171. package/dist/components/util/radio-keys.d.ts.map +1 -0
  172. package/dist/components/util/rating.d.ts +23 -0
  173. package/dist/components/util/rating.d.ts.map +1 -0
  174. package/dist/components/util/ready-made-strings.d.ts +77 -0
  175. package/dist/components/util/ready-made-strings.d.ts.map +1 -0
  176. package/dist/components/util/scroll-edge.d.ts +33 -0
  177. package/dist/components/util/scroll-edge.d.ts.map +1 -0
  178. package/dist/components/util/scroll-padding.d.ts +20 -0
  179. package/dist/components/util/scroll-padding.d.ts.map +1 -0
  180. package/dist/components/util/segmented-control.d.ts +16 -0
  181. package/dist/components/util/segmented-control.d.ts.map +1 -0
  182. package/dist/components/util/select.d.ts +41 -0
  183. package/dist/components/util/select.d.ts.map +1 -0
  184. package/dist/components/util/sheet-drag.d.ts +84 -0
  185. package/dist/components/util/sheet-drag.d.ts.map +1 -0
  186. package/dist/components/util/sidebar.d.ts +63 -0
  187. package/dist/components/util/sidebar.d.ts.map +1 -0
  188. package/dist/components/util/skeleton.d.ts +15 -0
  189. package/dist/components/util/skeleton.d.ts.map +1 -0
  190. package/dist/components/util/sliding-indicator.d.ts +25 -0
  191. package/dist/components/util/sliding-indicator.d.ts.map +1 -0
  192. package/dist/components/util/sortable-list.d.ts +65 -0
  193. package/dist/components/util/sortable-list.d.ts.map +1 -0
  194. package/dist/components/util/stepper.d.ts +40 -0
  195. package/dist/components/util/stepper.d.ts.map +1 -0
  196. package/dist/components/util/swipeable-list-item.d.ts +36 -0
  197. package/dist/components/util/swipeable-list-item.d.ts.map +1 -0
  198. package/dist/components/util/temporal-field.d.ts +89 -0
  199. package/dist/components/util/temporal-field.d.ts.map +1 -0
  200. package/dist/components/util/theme-mode.d.ts +80 -0
  201. package/dist/components/util/theme-mode.d.ts.map +1 -0
  202. package/dist/components/util/toaster.d.ts +133 -0
  203. package/dist/components/util/toaster.d.ts.map +1 -0
  204. package/dist/components/util/tone-surface.d.ts +34 -0
  205. package/dist/components/util/tone-surface.d.ts.map +1 -0
  206. package/dist/components/util/tooltip.d.ts +10 -0
  207. package/dist/components/util/tooltip.d.ts.map +1 -0
  208. package/dist/components/util/top-navbar.d.ts +35 -0
  209. package/dist/components/util/top-navbar.d.ts.map +1 -0
  210. package/dist/components/util/touch-target.d.ts +31 -0
  211. package/dist/components/util/touch-target.d.ts.map +1 -0
  212. package/dist/components/util/zabi-strings.d.ts +142 -0
  213. package/dist/components/util/zabi-strings.d.ts.map +1 -0
  214. package/dist/create-theme/cli.js +173 -0
  215. package/dist/create-theme/index.d.ts +190 -0
  216. package/dist/create-theme/index.js +1034 -0
  217. package/dist/create-theme/lib/ramp-math.js +128 -0
  218. package/dist/create-theme/lib/resolve.js +238 -0
  219. package/dist/create-theme/theme-data.js +2644 -0
  220. package/dist/index.d.ts +104 -2
  221. package/dist/index.js +75 -2
  222. package/dist/map.d.ts +10 -0
  223. package/dist/map.js +9 -0
  224. package/dist/molecules/Alert.svelte +63 -16
  225. package/dist/molecules/Alert.svelte.d.ts +14 -1
  226. package/dist/molecules/AppBar.svelte +674 -0
  227. package/dist/molecules/AppBar.svelte.d.ts +131 -0
  228. package/dist/molecules/AvatarGroup.svelte +116 -0
  229. package/dist/molecules/AvatarGroup.svelte.d.ts +40 -0
  230. package/dist/molecules/BarChart.svelte +381 -0
  231. package/dist/molecules/BarChart.svelte.d.ts +45 -0
  232. package/dist/molecules/BottomSheet.svelte +608 -0
  233. package/dist/molecules/BottomSheet.svelte.d.ts +109 -0
  234. package/dist/molecules/BottomTabBar.svelte +403 -0
  235. package/dist/molecules/BottomTabBar.svelte.d.ts +98 -0
  236. package/dist/molecules/Calendar.svelte +597 -0
  237. package/dist/molecules/Calendar.svelte.d.ts +72 -0
  238. package/dist/molecules/ChipGroup.svelte +325 -0
  239. package/dist/molecules/ChipGroup.svelte.d.ts +41 -0
  240. package/dist/molecules/Collapsible.svelte +347 -0
  241. package/dist/molecules/Collapsible.svelte.d.ts +61 -0
  242. package/dist/molecules/CollapsibleGroup.svelte +136 -0
  243. package/dist/molecules/CollapsibleGroup.svelte.d.ts +14 -0
  244. package/dist/molecules/ComponentDemo.svelte +16 -4
  245. package/dist/molecules/ComponentDemo.svelte.d.ts +3 -0
  246. package/dist/molecules/ConfirmDialog.svelte +257 -0
  247. package/dist/molecules/ConfirmDialog.svelte.d.ts +58 -0
  248. package/dist/molecules/ContactForm.svelte +34 -17
  249. package/dist/molecules/ContactForm.svelte.d.ts +8 -0
  250. package/dist/molecules/Drawer.svelte +415 -0
  251. package/dist/molecules/Drawer.svelte.d.ts +55 -0
  252. package/dist/molecules/Dropdown.svelte +517 -48
  253. package/dist/molecules/Dropdown.svelte.d.ts +47 -6
  254. package/dist/molecules/DropdownItem.svelte +122 -0
  255. package/dist/molecules/DropdownItem.svelte.d.ts +28 -0
  256. package/dist/molecules/EmptyState.svelte +55 -10
  257. package/dist/molecules/EmptyState.svelte.d.ts +8 -0
  258. package/dist/molecules/FormField.svelte +9 -1
  259. package/dist/molecules/FormField.svelte.d.ts +2 -0
  260. package/dist/molecules/Header.svelte +1 -1
  261. package/dist/molecules/ImageUpload.svelte +492 -69
  262. package/dist/molecules/ImageUpload.svelte.d.ts +82 -2
  263. package/dist/molecules/LineChart.svelte +459 -0
  264. package/dist/molecules/LineChart.svelte.d.ts +53 -0
  265. package/dist/molecules/MapView.svelte +565 -0
  266. package/dist/molecules/MapView.svelte.d.ts +88 -0
  267. package/dist/molecules/MediaGrid.svelte +527 -0
  268. package/dist/molecules/MediaGrid.svelte.d.ts +77 -0
  269. package/dist/molecules/Modal.svelte +293 -72
  270. package/dist/molecules/Modal.svelte.d.ts +51 -2
  271. package/dist/molecules/NavigationMenuContent.svelte +58 -1
  272. package/dist/molecules/NavigationMenuItem.svelte +0 -1
  273. package/dist/molecules/NavigationMenuLink.svelte +1 -1
  274. package/dist/molecules/NavigationMenuList.svelte +10 -3
  275. package/dist/molecules/NavigationMenuTrigger.svelte +2 -2
  276. package/dist/molecules/Page.svelte +32 -2
  277. package/dist/molecules/Page.svelte.d.ts +11 -0
  278. package/dist/molecules/PhotoGrid.svelte +523 -0
  279. package/dist/molecules/PhotoGrid.svelte.d.ts +73 -0
  280. package/dist/molecules/PhotoViewer.svelte +1213 -0
  281. package/dist/molecules/PhotoViewer.svelte.d.ts +74 -0
  282. package/dist/molecules/PieChart.svelte +421 -0
  283. package/dist/molecules/PieChart.svelte.d.ts +51 -0
  284. package/dist/molecules/PropsTable.svelte +22 -10
  285. package/dist/molecules/PropsTable.svelte.d.ts +3 -0
  286. package/dist/molecules/PullToRefresh.svelte +263 -0
  287. package/dist/molecules/PullToRefresh.svelte.d.ts +52 -0
  288. package/dist/molecules/RadioGroup.svelte +72 -18
  289. package/dist/molecules/RadioGroup.svelte.d.ts +19 -3
  290. package/dist/molecules/Section.svelte +1 -1
  291. package/dist/molecules/SegmentedControl.svelte +456 -0
  292. package/dist/molecules/SegmentedControl.svelte.d.ts +40 -0
  293. package/dist/molecules/SidebarBrandHeader.svelte +11 -1
  294. package/dist/molecules/SidebarBrandHeader.svelte.d.ts +3 -0
  295. package/dist/molecules/SidebarFooter.svelte +30 -7
  296. package/dist/molecules/SidebarFooter.svelte.d.ts +3 -0
  297. package/dist/molecules/SidebarNavSection.svelte +1 -1
  298. package/dist/molecules/SlideUp.svelte +220 -61
  299. package/dist/molecules/SlideUp.svelte.d.ts +26 -0
  300. package/dist/molecules/SortableList.svelte +633 -0
  301. package/dist/molecules/SortableList.svelte.d.ts +69 -0
  302. package/dist/molecules/Stepper.svelte +562 -0
  303. package/dist/molecules/Stepper.svelte.d.ts +39 -0
  304. package/dist/molecules/StickyActionBar.svelte +250 -0
  305. package/dist/molecules/StickyActionBar.svelte.d.ts +78 -0
  306. package/dist/molecules/SwipeableListItem.svelte +334 -0
  307. package/dist/molecules/SwipeableListItem.svelte.d.ts +54 -0
  308. package/dist/molecules/Tabs.svelte +310 -9
  309. package/dist/molecules/Tabs.svelte.d.ts +7 -0
  310. package/dist/molecules/Toaster.svelte +514 -5
  311. package/dist/molecules/Toaster.svelte.d.ts +153 -2
  312. package/dist/molecules/ToasterToast.svelte +495 -77
  313. package/dist/molecules/ToasterToast.svelte.d.ts +15 -0
  314. package/dist/molecules/UnsavedChangesBar.svelte +223 -0
  315. package/dist/molecules/UnsavedChangesBar.svelte.d.ts +43 -0
  316. package/dist/molecules/index.d.ts +51 -0
  317. package/dist/molecules/index.js +31 -0
  318. package/dist/molecules/toast-store.d.ts +83 -7
  319. package/dist/molecules/toast-store.js +25 -1
  320. package/dist/organisms/AppNavigation.svelte +440 -0
  321. package/dist/organisms/AppNavigation.svelte.d.ts +72 -0
  322. package/dist/organisms/AppShell.svelte +696 -0
  323. package/dist/organisms/AppShell.svelte.d.ts +157 -0
  324. package/dist/organisms/AppShellHeaderPart.svelte +163 -0
  325. package/dist/organisms/AppShellHeaderPart.svelte.d.ts +57 -0
  326. package/dist/organisms/SidebarAccountPanel.svelte +107 -12
  327. package/dist/organisms/SidebarAccountPanel.svelte.d.ts +19 -0
  328. package/dist/organisms/SidebarNavigation.svelte +111 -43
  329. package/dist/organisms/SidebarNavigation.svelte.d.ts +29 -1
  330. package/dist/organisms/SidebarPanel.svelte +34 -17
  331. package/dist/organisms/SidebarPanel.svelte.d.ts +1 -0
  332. package/dist/organisms/SidebarShell.svelte +164 -14
  333. package/dist/organisms/SidebarShell.svelte.d.ts +56 -2
  334. package/dist/organisms/TopNavbar.svelte +353 -39
  335. package/dist/organisms/TopNavbar.svelte.d.ts +47 -0
  336. package/dist/organisms/TopNavbarSheetContent.svelte +145 -0
  337. package/dist/organisms/TopNavbarSheetContent.svelte.d.ts +24 -0
  338. package/dist/organisms/index.d.ts +10 -0
  339. package/dist/organisms/index.js +7 -0
  340. package/dist/types/components.d.ts +21 -1
  341. package/dist/types/components.d.ts.map +1 -1
  342. package/dist/types/index.d.ts +1093 -26
  343. package/dist/types/index.d.ts.map +1 -1
  344. package/dist/types/variants.ts +28 -1
  345. package/dist/util/app-shell.d.ts +78 -0
  346. package/dist/util/app-shell.js +97 -0
  347. package/dist/util/avatar.d.ts +38 -0
  348. package/dist/util/avatar.js +52 -0
  349. package/dist/util/bottom-sheet.d.ts +29 -0
  350. package/dist/util/bottom-sheet.js +43 -0
  351. package/dist/util/bottom-tab-bar.d.ts +40 -0
  352. package/dist/util/bottom-tab-bar.js +54 -0
  353. package/dist/util/calendar.d.ts +55 -0
  354. package/dist/util/calendar.js +74 -0
  355. package/dist/util/chart.d.ts +139 -0
  356. package/dist/util/chart.js +305 -0
  357. package/dist/util/chip.d.ts +65 -0
  358. package/dist/util/chip.js +58 -0
  359. package/dist/util/cn.js +28 -2
  360. package/dist/util/code-field.d.ts +62 -0
  361. package/dist/util/code-field.js +112 -0
  362. package/dist/util/collapsible.d.ts +63 -0
  363. package/dist/util/collapsible.js +23 -0
  364. package/dist/util/confirm-dialog.d.ts +11 -0
  365. package/dist/util/confirm-dialog.js +2 -0
  366. package/dist/util/date.d.ts +95 -0
  367. package/dist/util/date.js +237 -0
  368. package/dist/util/display-voice.d.ts +9 -0
  369. package/dist/util/display-voice.js +9 -0
  370. package/dist/util/drawer.d.ts +12 -0
  371. package/dist/util/drawer.js +7 -0
  372. package/dist/util/dropdown.d.ts +46 -0
  373. package/dist/util/dropdown.js +21 -0
  374. package/dist/util/field-control.d.ts +29 -0
  375. package/dist/util/field-control.js +32 -0
  376. package/dist/util/field.d.ts +44 -0
  377. package/dist/util/field.js +38 -0
  378. package/dist/util/fit-in-viewport.d.ts +200 -0
  379. package/dist/util/fit-in-viewport.js +399 -0
  380. package/dist/util/focus-utils.d.ts +77 -2
  381. package/dist/util/focus-utils.js +186 -9
  382. package/dist/util/hydration.d.ts +44 -0
  383. package/dist/util/hydration.js +58 -0
  384. package/dist/util/keyboard-inset.d.ts +17 -0
  385. package/dist/util/keyboard-inset.js +53 -0
  386. package/dist/util/map-view.d.ts +143 -0
  387. package/dist/util/map-view.js +121 -0
  388. package/dist/util/media-grid.d.ts +50 -0
  389. package/dist/util/media-grid.js +81 -0
  390. package/dist/util/media.d.ts +5 -0
  391. package/dist/util/media.js +10 -0
  392. package/dist/util/overlay-chrome.d.ts +52 -0
  393. package/dist/util/overlay-chrome.js +56 -0
  394. package/dist/util/overlay.d.ts +71 -0
  395. package/dist/util/overlay.js +240 -0
  396. package/dist/util/photo.d.ts +233 -0
  397. package/dist/util/photo.js +209 -0
  398. package/dist/util/portal.d.ts +22 -0
  399. package/dist/util/portal.js +50 -0
  400. package/dist/util/progress.d.ts +18 -0
  401. package/dist/util/progress.js +17 -0
  402. package/dist/util/pull-to-refresh.d.ts +26 -0
  403. package/dist/util/pull-to-refresh.js +30 -0
  404. package/dist/util/radio-keys.d.ts +24 -0
  405. package/dist/util/radio-keys.js +49 -0
  406. package/dist/util/rating.d.ts +22 -0
  407. package/dist/util/rating.js +26 -0
  408. package/dist/util/ready-made-strings.d.ts +76 -0
  409. package/dist/util/ready-made-strings.js +67 -0
  410. package/dist/util/scroll-edge.d.ts +32 -0
  411. package/dist/util/scroll-edge.js +87 -0
  412. package/dist/util/scroll-padding.d.ts +19 -0
  413. package/dist/util/scroll-padding.js +44 -0
  414. package/dist/util/segmented-control.d.ts +15 -0
  415. package/dist/util/segmented-control.js +1 -0
  416. package/dist/util/select.d.ts +40 -0
  417. package/dist/util/select.js +63 -0
  418. package/dist/util/sheet-drag.d.ts +83 -0
  419. package/dist/util/sheet-drag.js +311 -0
  420. package/dist/util/sidebar.d.ts +62 -0
  421. package/dist/util/sidebar.js +38 -0
  422. package/dist/util/skeleton.d.ts +14 -0
  423. package/dist/util/skeleton.js +22 -0
  424. package/dist/util/sliding-indicator.d.ts +24 -0
  425. package/dist/util/sliding-indicator.js +44 -0
  426. package/dist/util/sortable-list.d.ts +64 -0
  427. package/dist/util/sortable-list.js +53 -0
  428. package/dist/util/stepper.d.ts +39 -0
  429. package/dist/util/stepper.js +38 -0
  430. package/dist/util/swipeable-list-item.d.ts +35 -0
  431. package/dist/util/swipeable-list-item.js +32 -0
  432. package/dist/util/temporal-field.d.ts +88 -0
  433. package/dist/util/temporal-field.js +136 -0
  434. package/dist/util/theme-mode.d.ts +79 -0
  435. package/dist/util/theme-mode.js +121 -0
  436. package/dist/util/toaster.d.ts +132 -0
  437. package/dist/util/toaster.js +130 -0
  438. package/dist/util/tone-surface.d.ts +33 -0
  439. package/dist/util/tone-surface.js +35 -0
  440. package/dist/util/tooltip.d.ts +9 -0
  441. package/dist/util/tooltip.js +18 -0
  442. package/dist/util/top-navbar.d.ts +34 -0
  443. package/dist/util/top-navbar.js +28 -0
  444. package/dist/util/touch-target.d.ts +30 -0
  445. package/dist/util/touch-target.js +30 -0
  446. package/dist/util/zabi-strings.d.ts +141 -0
  447. package/dist/util/zabi-strings.js +105 -0
  448. package/dist/zabi-components-colors.css +11 -2
  449. package/dist/zabi-components-theme-dark-only.css +870 -258
  450. package/dist/zabi-components-theme-dark.css +870 -258
  451. package/dist/zabi-components-theme-only.css +2419 -368
  452. package/dist/zabi-components-theme.css +2419 -368
  453. package/dist/zabi-components.css +6032 -711
  454. package/docs/lucide-icons.md +40 -17
  455. package/docs/theme-imports.md +81 -11
  456. package/package.json +45 -8
@@ -0,0 +1,74 @@
1
+ import type { HTMLAttributes } from "svelte/elements";
2
+ import { type Photo, type PhotoViewerAction, type PhotoViewerCloseReason, type PhotoViewerStrings } from "../util/photo.js";
3
+ /**
4
+ * Photos one at a time, on the whole screen: swipe or use the arrows to
5
+ * go between them, pinch or double tap to look closer, swipe down or
6
+ * press Escape to leave.
7
+ *
8
+ * ```svelte
9
+ * <PhotoGrid {photos} onopen={(at) => { index = at; open = true; }} />
10
+ * <PhotoViewer {photos} bind:index bind:isOpen={open} actions={[share, remove]} />
11
+ * ```
12
+ *
13
+ * It is a modal dialog, on the same footing as Modal, Drawer and
14
+ * BottomSheet. When it closes, focus goes to the tile of the photo that
15
+ * was showing, if the `PhotoGrid` it was opened from shows it; otherwise
16
+ * to whatever opened it.
17
+ *
18
+ * It is dark in both themes: the photos are on black. Nothing in it is
19
+ * written on that black: every control, the counter and the caption sit
20
+ * on plates in the theme's own surface colour, so they read over any
21
+ * photo in either theme.
22
+ *
23
+ * It does not take the browser's Back. A history entry made by a
24
+ * component conflicts with the app's router (SvelteKit warns against
25
+ * `history.pushState` outside `$app/navigation`), so open the viewer from
26
+ * the router's own state: push a state on open, read `isOpen` from it,
27
+ * and go back to close (Z-131).
28
+ *
29
+ * Other attributes (`id`, `data-*`, ...) land on the `role="dialog"` panel.
30
+ */
31
+ type Props = Omit<HTMLAttributes<HTMLDivElement>, "class" | "onclose" | "aria-label"> & {
32
+ photos: Photo[];
33
+ /** Place in `photos` of the photo that is showing. Supports `bind:index`. */
34
+ index?: number;
35
+ isOpen?: boolean;
36
+ /**
37
+ * Things to do with the photo that is showing. Up to three are
38
+ * buttons in a bar under the photo; with more, two are, and the
39
+ * rest are in a menu. The viewer does nothing by itself: each action
40
+ * is your own function.
41
+ */
42
+ actions?: PhotoViewerAction[];
43
+ /**
44
+ * Render the overlay in `document.body`, so an ancestor with a
45
+ * transform, filter or clipped overflow cannot trap it; pass `false`
46
+ * to render in place.
47
+ */
48
+ portal?: boolean;
49
+ /** Fired when the viewer closes itself, with what the user did. */
50
+ onclose?: (detail: {
51
+ reason: PhotoViewerCloseReason;
52
+ }) => void;
53
+ /**
54
+ * Called once when a full image cannot be loaded, so the page can
55
+ * answer with a new address (a signed one that has run out). A new
56
+ * `src` for the same photo is tried at once.
57
+ */
58
+ onloaderror?: (photo: Photo, index: number) => void;
59
+ /**
60
+ * Called when "Try again" is pressed on a photo that failed, before
61
+ * the image is asked for again. Return a promise and the button waits
62
+ * for it, busy, so the page has time to fetch a fresh address.
63
+ */
64
+ onretry?: (photo: Photo, index: number) => void | Promise<void>;
65
+ /** Accessible name of the dialog. */
66
+ label?: string;
67
+ /** Overrides for the built-in strings. */
68
+ strings?: Partial<PhotoViewerStrings>;
69
+ /** Extra classes for the dialog panel. */
70
+ class?: string;
71
+ };
72
+ declare const PhotoViewer: import("svelte").Component<Props, {}, "index" | "isOpen">;
73
+ type PhotoViewer = ReturnType<typeof PhotoViewer>;
74
+ export default PhotoViewer;
@@ -0,0 +1,421 @@
1
+ <script lang="ts">
2
+ import type { Snippet } from "svelte";
3
+ import type { HTMLAttributes } from "svelte/elements";
4
+ import Table from "../atoms/Table.svelte";
5
+ import { cn } from "../util/cn.js";
6
+ import {
7
+ CHART_GLASS,
8
+ chartColors,
9
+ chartFormatter,
10
+ pieSlices,
11
+ shareFormatter,
12
+ slicePath,
13
+ type ChartDatum,
14
+ type ChartFormat,
15
+ } from "../util/chart.js";
16
+
17
+ /**
18
+ * A pie chart, or a ring with `donut`, drawn as plain SVG: parts of a
19
+ * whole, clockwise from twelve o'clock in the order given.
20
+ *
21
+ * It is a `figure`: the `label` is its caption, the drawing is hidden
22
+ * from assistive technology, and the same numbers are in a real table
23
+ * (off screen unless `showTable`). The key beside the drawing writes each
24
+ * slice's label, value and share, in the order of the slices, so no slice
25
+ * is told by its colour alone. Keep it to six slices or fewer: after six
26
+ * the colours repeat, and a pie with more is hard to read anyway.
27
+ *
28
+ * Beside the key when there is room for both, over it when there is not
29
+ * (the chart measures its own width, not the window's).
30
+ */
31
+ type Props = Omit<HTMLAttributes<HTMLElement>, "class"> & {
32
+ /** The slices, in order: a `label`, a `value` (above zero), and a `color` of its own if it needs one. */
33
+ data: ChartDatum[];
34
+ /** A ring, not a full disc. */
35
+ donut?: boolean;
36
+ /** What stands in the middle of the ring (`donut`): the total, or the one share that matters. Read by assistive technology, so keep it to what the table does not already say or say it the same way. */
37
+ center?: Snippet;
38
+ /** How a value is written: `number` (default), `percent` (72 is "72 %"), or a function. */
39
+ format?: ChartFormat;
40
+ /** The widest the drawing gets, in px. It shrinks with its container. */
41
+ size?: number;
42
+ /** The caption, and what the chart is called. */
43
+ label: string;
44
+ /** Keeps the caption for assistive technology and takes it off the screen. */
45
+ labelHidden?: boolean;
46
+ /** The key beside the drawing: each slice's label, value and share. */
47
+ legend?: boolean;
48
+ /** Shows the data table under the chart; otherwise it is there for assistive technology only. */
49
+ showTable?: boolean;
50
+ /** The heading of the table's first column. */
51
+ categoryTitle?: string;
52
+ /** The heading of the table's value column. */
53
+ valueTitle?: string;
54
+ /** The heading of the table's share column. */
55
+ shareTitle?: string;
56
+ /** The language of the built-in number formats. Without it, the runtime's. */
57
+ locale?: string;
58
+ /** Stands the chart on a panel of the thick material (frosted glass), for a chart that floats over a wash, a tint or a picture. On a plain card it shows nothing: leave it off there. */
59
+ glass?: boolean;
60
+ class?: string;
61
+ };
62
+
63
+ let {
64
+ data,
65
+ donut = false,
66
+ center,
67
+ format = "number",
68
+ size = 192,
69
+ label,
70
+ labelHidden = false,
71
+ legend = true,
72
+ showTable = false,
73
+ categoryTitle = "Category",
74
+ valueTitle = "Value",
75
+ shareTitle = "Share",
76
+ locale,
77
+ glass = false,
78
+ class: className = "",
79
+ ...restProps
80
+ }: Props = $props();
81
+
82
+ const uid = $props.id();
83
+ const maskId = `${uid}-gaps`;
84
+ const clipId = `${uid}-shape`;
85
+ const veilId = `${uid}-veil`;
86
+ const shineId = `${uid}-shine`;
87
+ const lipId = `${uid}-lip`;
88
+ const softId = `${uid}-soft`;
89
+
90
+ const OUTER = 50;
91
+ /** How far inside the edge the sheen lies, in the drawing's own units (of 100). */
92
+ const SHEEN = 4;
93
+ /** The ring is a third of the radius: a band, with room in the middle for a figure. */
94
+ const inner = $derived(donut ? 33 : 0);
95
+ const write = $derived(chartFormatter(format, locale));
96
+ const share = $derived(shareFormatter(locale));
97
+ const isValue = (value: unknown): value is number => typeof value === "number" && Number.isFinite(value);
98
+
99
+ const colors = $derived(chartColors(data.map((datum) => datum.color)));
100
+ const slices = $derived(
101
+ pieSlices(data).map((slice) => ({
102
+ ...slice,
103
+ color: colors[slice.index],
104
+ text: isValue(slice.value) ? write(slice.value) : "",
105
+ shareText: share(slice.share),
106
+ path: slicePath(50, 50, OUTER, inner, slice.start, slice.end),
107
+ })),
108
+ );
109
+ const drawn = $derived(slices.filter((slice) => slice.path));
110
+ /** The whole disc or ring, as one shape: what the glass is laid over. */
111
+ const whole = $derived(slicePath(50, 50, OUTER, inner, 0, Math.PI * 2));
112
+ /** The width of the gap between two slices, in the drawing's own units (of 100). */
113
+ const GAP = 1;
114
+ const spot = (radius: number, angle: number) =>
115
+ `${Math.round((50 + radius * Math.sin(angle)) * 100) / 100} ${Math.round((50 - radius * Math.cos(angle)) * 100) / 100}`;
116
+ /**
117
+ * Where two slices meet, a thin gap is cut, so they part on any surface
118
+ * without a border colour. Every gap is one line of even width from the
119
+ * exact centre to the rim, with a round end, so in a full pie the gaps
120
+ * meet in one small round point in the middle and each is as wide at the
121
+ * centre as at the rim.
122
+ */
123
+ const cuts = $derived(drawn.length > 1 ? drawn.map((slice) => `M50 50L${spot(OUTER + 1, slice.start)}`) : []);
124
+ </script>
125
+
126
+ <figure class={cn("zabi-chart relative m-0 flex flex-col gap-3", glass && CHART_GLASS, className)} {...restProps}>
127
+ <figcaption class={cn("text-label text-sm font-medium", labelHidden && "sr-only")}>{label}</figcaption>
128
+
129
+ <div class="layout">
130
+ <div class="disc" style:max-inline-size="{size}px">
131
+ <svg class="pie block aspect-square w-full" viewBox="0 0 100 100" aria-hidden="true" focusable="false">
132
+ <defs>
133
+ <clipPath id={clipId}><path d={whole} clip-rule="evenodd" /></clipPath>
134
+ <linearGradient id={veilId} x1="0" y1="0" x2="0" y2="1">
135
+ <stop class="veil-top" offset="0" />
136
+ <stop class="veil-bottom" offset="1" />
137
+ </linearGradient>
138
+ <linearGradient id={shineId} x1="0" y1="0" x2="0" y2="1">
139
+ <stop class="light" offset="0" />
140
+ <stop class="light off" offset="0.35" />
141
+ </linearGradient>
142
+ <linearGradient id={lipId} x1="0" y1="0" x2="0" y2="1">
143
+ <stop class="light off" offset="0.65" />
144
+ <stop class="light" offset="1" />
145
+ </linearGradient>
146
+ <filter id={softId} x="-20%" y="-20%" width="140%" height="140%">
147
+ <feGaussianBlur stdDeviation="1.6" />
148
+ </filter>
149
+ </defs>
150
+ <mask id={maskId} maskUnits="userSpaceOnUse" x="0" y="0" width="100" height="100">
151
+ <rect width="100" height="100" fill="white" />
152
+ {#each cuts as cut, index (index)}
153
+ <path class="cut" d={cut} fill="none" stroke="black" stroke-width={GAP} stroke-linecap="round" />
154
+ {/each}
155
+ </mask>
156
+ {#if drawn.length === 0}
157
+ <!-- Nothing to share out: the empty shape, so the chart keeps its place. -->
158
+ <path class="none" d={whole} />
159
+ {/if}
160
+ <g mask="url(#{maskId})">
161
+ {#each drawn as slice (slice.index)}
162
+ <path class="slice" style:--_c={slice.color} d={slice.path}>
163
+ <title>{slice.label}: {slice.text} ({slice.shareText})</title>
164
+ </path>
165
+ {/each}
166
+ {#if drawn.length > 0}
167
+ <!--
168
+ The glass. The slices keep their colour, opaque; over all of them, as one
169
+ piece, lie the veil of a solid control, a soft sheen under the top edge,
170
+ and a hairline of light on the top of the rim and, on a ring, on the
171
+ lower lip of the hole. Nothing is drawn along the sides of a slice. The
172
+ gaps are cut through it with the slices. Decoration only: it takes no
173
+ pointer, and it is not drawn where the materials are opaque.
174
+ -->
175
+ <g class="glass" clip-path="url(#{clipId})">
176
+ <path class="veil" d={whole} fill="url(#{veilId})" />
177
+ <circle class="sheen" cx="50" cy="50" r={OUTER - SHEEN} stroke="url(#{shineId})" filter="url(#{softId})" />
178
+ <circle class="rim" cx="50" cy="50" r={OUTER} stroke="url(#{shineId})" />
179
+ {#if inner > 0}
180
+ <circle class="rim" cx="50" cy="50" r={inner} stroke="url(#{lipId})" />
181
+ {/if}
182
+ </g>
183
+ {/if}
184
+ </g>
185
+ </svg>
186
+ {#if donut && center}
187
+ <div class="center text-headline">{@render center()}</div>
188
+ {/if}
189
+ </div>
190
+
191
+ {#if legend}
192
+ <!-- The table below says the same to assistive technology. -->
193
+ <ul class="key text-description m-0 list-none p-0 text-sm" aria-hidden="true">
194
+ {#each slices as slice (slice.index)}
195
+ <li>
196
+ <span class="swatch" style:--_c={slice.color}></span>
197
+ <span class="name text-headline font-medium">{slice.label}</span>
198
+ <span class="text-headline tabular-nums">{slice.text}</span>
199
+ <span class="share tabular-nums">{slice.shareText}</span>
200
+ </li>
201
+ {/each}
202
+ </ul>
203
+ {/if}
204
+ </div>
205
+
206
+ <!-- The library's own Table, so the numbers look like every other table in the app. -->
207
+ <Table class={showTable ? "" : "sr-only"}>
208
+ <thead class="border-border bg-surface-elevated border-b">
209
+ <tr>
210
+ <th class="text-headline px-4 py-3 text-start font-medium" scope="col">{categoryTitle}</th>
211
+ <th class="text-headline px-4 py-3 text-end font-medium" scope="col">{valueTitle}</th>
212
+ <th class="text-headline px-4 py-3 text-end font-medium" scope="col">{shareTitle}</th>
213
+ </tr>
214
+ </thead>
215
+ <tbody class="divide-border divide-y">
216
+ {#each slices as slice (slice.index)}
217
+ <tr>
218
+ <th class="text-body px-4 py-3 text-start font-normal" scope="row">{slice.label}</th>
219
+ <td class="text-body px-4 py-3 text-end tabular-nums">{slice.text}</td>
220
+ <td class="text-body px-4 py-3 text-end tabular-nums">{slice.shareText}</td>
221
+ </tr>
222
+ {/each}
223
+ </tbody>
224
+ </Table>
225
+ </figure>
226
+
227
+ <style>
228
+ /*
229
+ * The series colours an app may set, on the chart or on anything around
230
+ * it; read with a fallback (in util/chart.ts) and never declared here:
231
+ * --zabi-chart-1 … --zabi-chart-6
232
+ */
233
+ .zabi-chart {
234
+ container-type: inline-size;
235
+ }
236
+
237
+ /* Side by side: the drawing, then a key that takes the rest of the width,
238
+ as a List does. Both start where the caption starts. */
239
+ .layout {
240
+ display: flex;
241
+ align-items: center;
242
+ gap: 1.5rem 2rem;
243
+ }
244
+
245
+ .disc {
246
+ position: relative;
247
+ flex: none;
248
+ inline-size: 100%;
249
+ }
250
+
251
+ /* The middle of the ring, for the app's figure: centred, and never wider than the hole. */
252
+ .center {
253
+ position: absolute;
254
+ inset: 0;
255
+ display: flex;
256
+ flex-direction: column;
257
+ align-items: center;
258
+ justify-content: center;
259
+ padding: 22%;
260
+ text-align: center;
261
+ line-height: 1.2;
262
+ pointer-events: none;
263
+ }
264
+
265
+ .slice {
266
+ fill: var(--_c);
267
+ }
268
+
269
+ /*
270
+ * The marks are glass, drawn: an SVG shape takes no backdrop blur, so the
271
+ * slices stay their own colour and the depth comes from a soft gradient
272
+ * and a barely-there edge, in the library's own terms.
273
+ * the veil --color-control-gradient-accent-start / -end, the veil of
274
+ * a solid control that is darken-only in light and light at
275
+ * the top in dark, so a slice never loses contrast to it
276
+ * the rim one pixel of light on the top of the outer edge, fading out
277
+ * a third of the way down, and on the lower lip of a ring's
278
+ * hole: the lightest neutral at 30%, the same in light and
279
+ * dark, since the first series colours are the same in both
280
+ * the sheen the same light at a third of that, blurred, just under the
281
+ * top edge
282
+ * the shadow the two shadows of the library's middle step (--shadow-md)
283
+ */
284
+ .pie {
285
+ filter: drop-shadow(0 1px 3px rgb(var(--shadow-color) / var(--shadow-opacity-contact)))
286
+ drop-shadow(0 6px 14px rgb(var(--shadow-color) / var(--shadow-opacity)));
287
+ }
288
+
289
+ .glass {
290
+ pointer-events: none;
291
+ }
292
+
293
+ .veil-top {
294
+ stop-color: var(--color-control-gradient-accent-start);
295
+ }
296
+
297
+ .veil-bottom {
298
+ stop-color: var(--color-control-gradient-accent-end);
299
+ }
300
+
301
+ .light {
302
+ stop-color: color-mix(in srgb, var(--zabi-base-50) 30%, transparent);
303
+ }
304
+
305
+ .light.off {
306
+ stop-opacity: 0;
307
+ }
308
+
309
+ /* Drawn on the outline and clipped to the shape, so the inner half shows: one pixel. */
310
+ .rim {
311
+ fill: none;
312
+ stroke-width: 2px;
313
+ vector-effect: non-scaling-stroke;
314
+ }
315
+
316
+ .sheen {
317
+ fill: none;
318
+ stroke-width: 3.5;
319
+ opacity: 0.35;
320
+ }
321
+
322
+ /* Flat where the library's materials are opaque: the same switches, the same reasons. */
323
+ @media (prefers-reduced-transparency: reduce), (prefers-contrast: more), (forced-colors: active) {
324
+ .glass {
325
+ display: none;
326
+ }
327
+
328
+ .pie {
329
+ filter: none;
330
+ }
331
+ }
332
+
333
+ :global([data-materials="opaque"]) .glass {
334
+ display: none;
335
+ }
336
+
337
+ :global([data-materials="opaque"]) .pie {
338
+ filter: none;
339
+ }
340
+
341
+ /* Nothing yet: the empty track of a Progress, in the round. */
342
+ .none {
343
+ fill: var(--color-progress-track);
344
+ stroke: var(--color-progress-track-border);
345
+ stroke-width: 1;
346
+ vector-effect: non-scaling-stroke;
347
+ }
348
+
349
+ /* The rows of a List: a mark, the name, and what it comes to at the far
350
+ end, in columns that line up down the key. */
351
+ .key {
352
+ display: grid;
353
+ grid-template-columns: auto minmax(0, 1fr) auto auto;
354
+ flex: 1 1 0;
355
+ min-inline-size: 0;
356
+ }
357
+
358
+ .key li {
359
+ display: grid;
360
+ grid-column: 1 / -1;
361
+ grid-template-columns: subgrid;
362
+ align-items: center;
363
+ -moz-column-gap: 0.75rem;
364
+ column-gap: 0.75rem;
365
+ padding-block: 0.75rem;
366
+ border-block-end: 1px solid var(--zabi-list-divider-color, var(--color-border));
367
+ }
368
+
369
+ .key li:last-child {
370
+ border-block-end: 0;
371
+ }
372
+
373
+ .name {
374
+ overflow-wrap: anywhere;
375
+ }
376
+
377
+ .share {
378
+ min-inline-size: 2.5rem;
379
+ text-align: end;
380
+ }
381
+
382
+ .swatch {
383
+ inline-size: 0.625rem;
384
+ block-size: 0.625rem;
385
+ border-radius: var(--radius-pill);
386
+ background-color: var(--_c);
387
+ }
388
+
389
+ /* No room for both: the drawing in the middle, the key under it at full width. */
390
+ @container (max-width: 26rem) {
391
+ .layout {
392
+ flex-direction: column;
393
+ align-items: stretch;
394
+ }
395
+
396
+ .disc {
397
+ align-self: center;
398
+ }
399
+
400
+ .key {
401
+ flex: none;
402
+ }
403
+ }
404
+
405
+ /* Forced colours: the slices are the system's text colour, parted by the
406
+ gaps; the key lists them in the same order, clockwise from the top. */
407
+ @media (forced-colors: active) {
408
+ .slice {
409
+ fill: CanvasText;
410
+ }
411
+
412
+ .none {
413
+ fill: GrayText;
414
+ }
415
+
416
+ .swatch {
417
+ forced-color-adjust: none;
418
+ background-color: CanvasText;
419
+ }
420
+ }
421
+ </style>
@@ -0,0 +1,51 @@
1
+ import type { Snippet } from "svelte";
2
+ import type { HTMLAttributes } from "svelte/elements";
3
+ import { type ChartDatum, type ChartFormat } from "../util/chart.js";
4
+ /**
5
+ * A pie chart, or a ring with `donut`, drawn as plain SVG: parts of a
6
+ * whole, clockwise from twelve o'clock in the order given.
7
+ *
8
+ * It is a `figure`: the `label` is its caption, the drawing is hidden
9
+ * from assistive technology, and the same numbers are in a real table
10
+ * (off screen unless `showTable`). The key beside the drawing writes each
11
+ * slice's label, value and share, in the order of the slices, so no slice
12
+ * is told by its colour alone. Keep it to six slices or fewer: after six
13
+ * the colours repeat, and a pie with more is hard to read anyway.
14
+ *
15
+ * Beside the key when there is room for both, over it when there is not
16
+ * (the chart measures its own width, not the window's).
17
+ */
18
+ type Props = Omit<HTMLAttributes<HTMLElement>, "class"> & {
19
+ /** The slices, in order: a `label`, a `value` (above zero), and a `color` of its own if it needs one. */
20
+ data: ChartDatum[];
21
+ /** A ring, not a full disc. */
22
+ donut?: boolean;
23
+ /** What stands in the middle of the ring (`donut`): the total, or the one share that matters. Read by assistive technology, so keep it to what the table does not already say or say it the same way. */
24
+ center?: Snippet;
25
+ /** How a value is written: `number` (default), `percent` (72 is "72 %"), or a function. */
26
+ format?: ChartFormat;
27
+ /** The widest the drawing gets, in px. It shrinks with its container. */
28
+ size?: number;
29
+ /** The caption, and what the chart is called. */
30
+ label: string;
31
+ /** Keeps the caption for assistive technology and takes it off the screen. */
32
+ labelHidden?: boolean;
33
+ /** The key beside the drawing: each slice's label, value and share. */
34
+ legend?: boolean;
35
+ /** Shows the data table under the chart; otherwise it is there for assistive technology only. */
36
+ showTable?: boolean;
37
+ /** The heading of the table's first column. */
38
+ categoryTitle?: string;
39
+ /** The heading of the table's value column. */
40
+ valueTitle?: string;
41
+ /** The heading of the table's share column. */
42
+ shareTitle?: string;
43
+ /** The language of the built-in number formats. Without it, the runtime's. */
44
+ locale?: string;
45
+ /** Stands the chart on a panel of the thick material (frosted glass), for a chart that floats over a wash, a tint or a picture. On a plain card it shows nothing: leave it off there. */
46
+ glass?: boolean;
47
+ class?: string;
48
+ };
49
+ declare const PieChart: import("svelte").Component<Props, {}, "">;
50
+ type PieChart = ReturnType<typeof PieChart>;
51
+ export default PieChart;
@@ -1,40 +1,52 @@
1
1
  <script lang="ts">
2
+ import { mergeStrings } from "../util/ready-made-strings.js";
3
+ import { zabiStringsFor } from "../util/zabi-strings.js";
2
4
  import type { ComponentProp } from "../types/page.types";
3
5
  import Table from "../atoms/Table.svelte";
4
6
  import { cn } from "../util/cn.js";
7
+ import {
8
+ DEFAULT_PROPS_TABLE_STRINGS,
9
+ type PropsTableStrings,
10
+ } from "../util/ready-made-strings.js";
5
11
 
6
12
  interface Props {
7
13
  /** Extra classes for the host element. */
8
14
  class?: string;
9
15
  props: ComponentProp[];
10
16
  caption?: string;
17
+ /** The column headings, Yes and No, and the line for an empty table. */
18
+ strings?: Partial<PropsTableStrings>;
11
19
  }
12
20
 
13
- let { class: className = "", props, caption = "Props / API" }: Props = $props();
21
+ let { class: className = "", props, caption = "Props / API", strings }: Props = $props();
22
+
23
+ /** The app-wide words for this component, from a `ZabiStringsProvider` above it, if there is one. */
24
+ const provided = zabiStringsFor("propsTable");
25
+ const text = $derived(mergeStrings(DEFAULT_PROPS_TABLE_STRINGS, provided(), strings));
14
26
  </script>
15
27
 
16
28
  {#if props.length === 0}
17
- <div class={cn("rounded-control border border-border bg-base-50 px-4 py-4 text-sm text-description", className)}>
18
- No documented props.
29
+ <div class={cn("rounded-control border border-border bg-card px-4 py-4 text-sm text-description", className)}>
30
+ {text.empty}
19
31
  </div>
20
32
  {:else}
21
33
  <Table caption={caption}>
22
34
  <thead>
23
- <tr class="bg-base-50">
35
+ <tr class="bg-surface-elevated">
24
36
  <th class="border-b border-border px-4 py-3 text-left font-semibold text-headline">
25
- Name
37
+ {text.name}
26
38
  </th>
27
39
  <th class="border-b border-border px-4 py-3 text-left font-semibold text-headline">
28
- Type
40
+ {text.type}
29
41
  </th>
30
42
  <th class="border-b border-border px-4 py-3 text-left font-semibold text-headline">
31
- Required
43
+ {text.required}
32
44
  </th>
33
45
  <th class="border-b border-border px-4 py-3 text-left font-semibold text-headline">
34
- Default
46
+ {text.default}
35
47
  </th>
36
48
  <th class="border-b border-border px-4 py-3 text-left font-semibold text-headline">
37
- Description
49
+ {text.description}
38
50
  </th>
39
51
  </tr>
40
52
  </thead>
@@ -48,7 +60,7 @@
48
60
  {prop.type}
49
61
  </td>
50
62
  <td class="border-b border-border px-4 py-3 text-description">
51
- {prop.required ? "Yes" : "No"}
63
+ {prop.required ? text.yes : text.no}
52
64
  </td>
53
65
  <td class="border-b border-border px-4 py-3 text-description">
54
66
  {prop.defaultValue || "—"}
@@ -1,9 +1,12 @@
1
1
  import type { ComponentProp } from "../types/page.types";
2
+ import { type PropsTableStrings } from "../util/ready-made-strings.js";
2
3
  interface Props {
3
4
  /** Extra classes for the host element. */
4
5
  class?: string;
5
6
  props: ComponentProp[];
6
7
  caption?: string;
8
+ /** The column headings, Yes and No, and the line for an empty table. */
9
+ strings?: Partial<PropsTableStrings>;
7
10
  }
8
11
  declare const PropsTable: import("svelte").Component<Props, {}, "">;
9
12
  type PropsTable = ReturnType<typeof PropsTable>;