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
@@ -1,11 +1,34 @@
1
- interface Props {
1
+ import type { HTMLButtonAttributes } from "svelte/elements";
2
+ import { type ThemeMode, type ThemeToggleLabels } from "../util/theme-mode.js";
3
+ /** Other attributes (`data-*`, `aria-*`, `id`, ...) land on the `<button>`. */
4
+ type Props = Omit<HTMLButtonAttributes, "class" | "disabled" | "type" | "onclick" | "children"> & {
2
5
  /** Extra classes for the host element. */
3
6
  class?: string;
4
7
  size?: "sm" | "md" | "lg";
5
8
  variant?: "default" | "ghost" | "outline";
6
9
  disabled?: boolean;
10
+ /**
11
+ * `"two"` (the default) flips light and dark. `"three"` steps through
12
+ * system, light and dark, and always writes `data-theme` on `<html>`.
13
+ */
14
+ modes?: "two" | "three";
15
+ /**
16
+ * The page's mode: `"auto"` (follow the system), `"light"` or `"dark"`.
17
+ * Bindable. It is read from `<html>` when the button mounts and follows
18
+ * the page from then on; assigning it switches the page.
19
+ */
20
+ mode?: ThemeMode;
21
+ /** Called with the new mode when a press changes it. */
22
+ onmodechange?: (mode: ThemeMode) => void;
23
+ /**
24
+ * The `localStorage` key the choice is kept under and restored from when
25
+ * the button mounts. `null` keeps nothing.
26
+ */
27
+ storageKey?: string | null;
28
+ /** Replaces the texts of the accessible name, for another language. */
29
+ labels?: Partial<ThemeToggleLabels>;
7
30
  onclick?: (event: Event) => void;
8
- }
9
- declare const ThemeToggle: import("svelte").Component<Props, {}, "">;
31
+ };
32
+ declare const ThemeToggle: import("svelte").Component<Props, {}, "mode">;
10
33
  type ThemeToggle = ReturnType<typeof ThemeToggle>;
11
34
  export default ThemeToggle;
@@ -0,0 +1,150 @@
1
+ <script lang="ts">
2
+ import { onMount, tick } from "svelte";
3
+ import { cn } from "../util/cn.js";
4
+ import type { TimeChoice } from "../util/temporal-field.js";
5
+
6
+ /**
7
+ * One scrollable column of the time picker in TimeField: the hours, or the
8
+ * minutes. Internal: it is not exported from the package.
9
+ *
10
+ * A listbox of 44px rows. One row is the Tab stop (the chosen one, else
11
+ * the first); Up and Down, Home and End move between rows, Enter and
12
+ * Space choose the focused one, and typing digits jumps to a row. A row
13
+ * that is out of range stays focusable and says `aria-disabled`. With
14
+ * nothing chosen, `openAt` is the row the column stands at and the keyboard
15
+ * starts from; it is not marked chosen.
16
+ */
17
+ interface Props {
18
+ /** Accessible name of the listbox. */
19
+ label: string;
20
+ options: TimeChoice[];
21
+ /** The `value` of the chosen option, or `""`. */
22
+ selected: string;
23
+ onselect: (value: string) => void;
24
+ /** The `value` of the row to stand at while nothing is chosen. It is not chosen. */
25
+ openAt?: string;
26
+ }
27
+
28
+ let { label, options, selected, onselect, openAt = "" }: Props = $props();
29
+
30
+ let box: HTMLDivElement | undefined = $state();
31
+ /** The row that takes Tab: where the keyboard was last, else the chosen one, else the first. */
32
+ let focusedValue = $state<string | null>(null);
33
+
34
+ const tabStop = $derived(
35
+ options.some((option) => option.value === focusedValue)
36
+ ? focusedValue
37
+ : options.some((option) => option.value === selected)
38
+ ? selected
39
+ : options.some((option) => option.value === openAt)
40
+ ? openAt
41
+ : (options[0]?.value ?? null),
42
+ );
43
+
44
+ /**
45
+ * The chosen row, else the `openAt` one, is put in the middle of the
46
+ * column as it opens, and again when the choice changes (a new hour can move the minute). Measured
47
+ * from the two boxes, not `offsetTop`, which counts from the sheet. Set
48
+ * straight on `scrollTop`: nothing here scrolls smoothly, so there is no
49
+ * motion for `prefers-reduced-motion` to remove.
50
+ */
51
+ function centreSelected() {
52
+ const column = box;
53
+ const row =
54
+ column?.querySelector<HTMLElement>('[aria-selected="true"]') ??
55
+ (openAt ? rows().find((element) => element.dataset.value === openAt) : undefined);
56
+ if (!column || !row || !column.clientHeight) return;
57
+ const offset = row.getBoundingClientRect().top - column.getBoundingClientRect().top;
58
+ column.scrollTop += offset - (column.clientHeight - row.offsetHeight) / 2;
59
+ }
60
+
61
+ onMount(centreSelected);
62
+
63
+ $effect(() => {
64
+ void selected;
65
+ void tick().then(centreSelected);
66
+ });
67
+
68
+ const rows = () => [...(box?.querySelectorAll<HTMLElement>('[role="option"]') ?? [])];
69
+
70
+ function focusRow(value: string | undefined) {
71
+ if (value === undefined) return;
72
+ focusedValue = value;
73
+ const row = rows().find((element) => element.dataset.value === value);
74
+ row?.focus();
75
+ row?.scrollIntoView?.({ block: "nearest" });
76
+ }
77
+
78
+ let typed = "";
79
+ let typedTimer: ReturnType<typeof setTimeout> | undefined;
80
+
81
+ function handleKeydown(event: KeyboardEvent) {
82
+ if (event.altKey || event.ctrlKey || event.metaKey) return;
83
+ const values = options.map((option) => option.value);
84
+ const current = values.indexOf((event.target as HTMLElement | null)?.closest<HTMLElement>("[data-value]")?.dataset.value ?? "");
85
+ if (event.key === "ArrowDown") {
86
+ event.preventDefault();
87
+ focusRow(values[Math.min(current + 1, values.length - 1)]);
88
+ } else if (event.key === "ArrowUp") {
89
+ event.preventDefault();
90
+ focusRow(values[Math.max(current - 1, 0)]);
91
+ } else if (event.key === "Home") {
92
+ event.preventDefault();
93
+ focusRow(values[0]);
94
+ } else if (event.key === "End") {
95
+ event.preventDefault();
96
+ focusRow(values[values.length - 1]);
97
+ } else if (event.key === "Enter" || event.key === " ") {
98
+ event.preventDefault();
99
+ const option = options[current];
100
+ if (option && !option.disabled) onselect(option.value);
101
+ } else if (/^[0-9]$/.test(event.key)) {
102
+ event.preventDefault();
103
+ typed += event.key;
104
+ clearTimeout(typedTimer);
105
+ typedTimer = setTimeout(() => (typed = ""), 800);
106
+ // "7" is 07, "30" is 30, "1" then "9" is 19. The value is the 24-hour one, whatever the label says.
107
+ const hit =
108
+ options.find((option) => option.value.startsWith(typed)) ??
109
+ options.find((option) => Number(option.value) === Number(typed)) ??
110
+ options.find((option) => option.value.startsWith(typed.slice(-1)));
111
+ if (hit) focusRow(hit.value);
112
+ }
113
+ }
114
+ </script>
115
+
116
+ <!-- svelte-ignore a11y_no_noninteractive_element_interactions -->
117
+ <div
118
+ bind:this={box}
119
+ role="listbox"
120
+ aria-label={label}
121
+ tabindex="-1"
122
+ data-time-column
123
+ data-sheet-no-drag
124
+ class="h-44 min-w-0 flex-1 overflow-y-auto overscroll-contain rounded-control border border-input-border bg-input p-1"
125
+ onkeydown={handleKeydown}
126
+ >
127
+ {#each options as option (option.value)}
128
+ <!-- svelte-ignore a11y_click_events_have_key_events -->
129
+ <div
130
+ role="option"
131
+ data-value={option.value}
132
+ aria-selected={option.value === selected}
133
+ aria-disabled={option.disabled ? "true" : undefined}
134
+ tabindex={option.value === tabStop ? 0 : -1}
135
+ class={cn(
136
+ "focus-ring flex h-11 shrink-0 cursor-pointer items-center justify-center rounded-control text-base transition-colors duration-(--duration-base) motion-reduce:transition-none focus:outline-none focus-visible:outline-none",
137
+ // Two class lists, never both: the hand-written colour classes
138
+ // sit outside the cascade layers, so a variant cannot beat them.
139
+ option.value === selected
140
+ ? "bg-action-primary text-action-primary font-semibold"
141
+ : "text-body hover:bg-input-hover",
142
+ "aria-disabled:cursor-not-allowed aria-disabled:opacity-50 aria-disabled:hover:bg-transparent",
143
+ )}
144
+ onfocus={() => (focusedValue = option.value)}
145
+ onclick={() => !option.disabled && onselect(option.value)}
146
+ >
147
+ {option.label}
148
+ </div>
149
+ {/each}
150
+ </div>
@@ -0,0 +1,25 @@
1
+ import type { TimeChoice } from "../util/temporal-field.js";
2
+ /**
3
+ * One scrollable column of the time picker in TimeField: the hours, or the
4
+ * minutes. Internal: it is not exported from the package.
5
+ *
6
+ * A listbox of 44px rows. One row is the Tab stop (the chosen one, else
7
+ * the first); Up and Down, Home and End move between rows, Enter and
8
+ * Space choose the focused one, and typing digits jumps to a row. A row
9
+ * that is out of range stays focusable and says `aria-disabled`. With
10
+ * nothing chosen, `openAt` is the row the column stands at and the keyboard
11
+ * starts from; it is not marked chosen.
12
+ */
13
+ interface Props {
14
+ /** Accessible name of the listbox. */
15
+ label: string;
16
+ options: TimeChoice[];
17
+ /** The `value` of the chosen option, or `""`. */
18
+ selected: string;
19
+ onselect: (value: string) => void;
20
+ /** The `value` of the row to stand at while nothing is chosen. It is not chosen. */
21
+ openAt?: string;
22
+ }
23
+ declare const TimeColumn: import("svelte").Component<Props, {}, "">;
24
+ type TimeColumn = ReturnType<typeof TimeColumn>;
25
+ export default TimeColumn;
@@ -0,0 +1,151 @@
1
+ <script lang="ts">
2
+ import type { HTMLInputAttributes } from "svelte/elements";
3
+ import type { SizeVariant } from "../types/variants.js";
4
+ import type { TimeFieldStrings } from "../util/temporal-field.js";
5
+ import TemporalField from "./TemporalField.svelte";
6
+
7
+ /**
8
+ * A time of day, picked with the device's own time picker and styled
9
+ * like Input.
10
+ *
11
+ * It is a native `<input type="time">`. `value` is always 24-hour
12
+ * `HH:mm` (`HH:mm:ss` when `step` asks for seconds), or `""` while empty,
13
+ * whatever the field shows.
14
+ *
15
+ * What the field shows is the browser's decision, unless it has a
16
+ * `locale`: without one, 24-hour or 12-hour with AM and PM, by the
17
+ * settings of the browser or device, not of the page. To show a time as
18
+ * text in the page's language, use `formatTime`:
19
+ *
20
+ * ```svelte
21
+ * <TimeField label="Starts" bind:value={time} step={300} />
22
+ * <p>{formatTime(time, "sv")}</p> <!-- 19:00 -->
23
+ * ```
24
+ *
25
+ * With `locale`, the field shows the value in that language ("18:30" in
26
+ * Swedish, never "06:30 PM") and its own picker opens: two columns in a
27
+ * BottomSheet, hours (written as the locale writes an hour) and minutes
28
+ * (every `step`, five minutes without one), and Done. A value that is not
29
+ * on the step is kept as its own minute. A `step` under 60 seconds, or
30
+ * `"any"`, uses the platform's picker instead, as does `picker="native"`.
31
+ * Until the page has run, and without scripts, it is the native input
32
+ * as above and submits as before.
33
+ *
34
+ * Other attributes (`autocomplete`, `data-*`, `onchange`, ...) land on the
35
+ * `<input>`.
36
+ */
37
+ type Props = Omit<
38
+ HTMLInputAttributes,
39
+ "class" | "type" | "value" | "size" | "min" | "max" | "step" | "required" | "disabled" | "readonly" | "id" | "name"
40
+ > & {
41
+ /** Omit to auto-generate; pair with FormField's `id` when used inside FormField. */
42
+ id?: string;
43
+ /** The time as 24-hour `HH:mm`, or `""` while empty. Supports `bind:value`. */
44
+ value?: string;
45
+ /** Name the value is submitted under in a form. */
46
+ name?: string;
47
+ label?: string;
48
+ /** True when FormField supplies the visible `<label>`. */
49
+ hideLabel?: boolean;
50
+ /** Help text under the field, read out with it. */
51
+ hint?: string;
52
+ /** An error under the field. It marks the field invalid and is announced. */
53
+ error?: string;
54
+ /** Earliest time that can be picked, as `HH:mm`. */
55
+ min?: string;
56
+ /** Latest time that can be picked, as `HH:mm`. */
57
+ max?: string;
58
+ /** Steps between times that can be picked, in seconds: 300 for five minutes. */
59
+ step?: number | "any";
60
+ required?: boolean;
61
+ disabled?: boolean;
62
+ /** Shows the value without letting it be changed; it is still submitted. */
63
+ readonly?: boolean;
64
+ /** Height, on the scale Input and Button use. At least 44px on a touch screen. */
65
+ size?: SizeVariant;
66
+ /** Extra classes for the `<input>`. */
67
+ class?: string;
68
+ /**
69
+ * Language of the field, as a BCP 47 tag (`sv`, `en-GB`) or a list of them. With it the
70
+ * field shows the value in that language, whatever the browser's is, and opens the
71
+ * library's own picker; see above. Left out, the field is the native input.
72
+ */
73
+ locale?: string | string[];
74
+ /** With `locale`: how the value is shown, as options of `Intl.DateTimeFormat`. Default: formatTime gives for the locale. */
75
+ format?: Intl.DateTimeFormatOptions;
76
+ /** With `locale`: shown in the placeholder colour while the field is empty. */
77
+ placeholder?: string;
78
+ /** With `locale`: `library` (default) opens the library's time columns in a sheet; `native` opens the platform's own picker. */
79
+ picker?: "library" | "native";
80
+ /** With `locale`: the words the field says; replace any of them to translate. */
81
+ strings?: Partial<TimeFieldStrings>;
82
+ /**
83
+ * With `locale`, while the field is empty: the time the library's columns stand at when
84
+ * the sheet opens, as `HH:mm` (`"18:30"`). It is only where to scroll to: no row is
85
+ * chosen and `value` stays empty until the person chooses. Left out: now, on the step.
86
+ */
87
+ openAt?: string;
88
+ };
89
+
90
+ let {
91
+ id,
92
+ value = $bindable<Exclude<Props["value"], undefined>>(),
93
+ name = "",
94
+ label = "",
95
+ hideLabel = false,
96
+ hint = "",
97
+ error = "",
98
+ min,
99
+ max,
100
+ step,
101
+ required = false,
102
+ disabled = false,
103
+ readonly = false,
104
+ size = "md",
105
+ class: className = "",
106
+ locale,
107
+ format,
108
+ placeholder,
109
+ picker = "library",
110
+ strings,
111
+ openAt,
112
+ ...restProps
113
+ }: Props = $props();
114
+
115
+ // No fallback on a bindable prop: Svelte refuses `bind:…={undefined}` on
116
+ // one that has a fallback (`props_invalid_value`), and a page that throws
117
+ // while it hydrates never becomes interactive. The default is applied
118
+ // here instead: at once, for the server and the first render, and again
119
+ // whenever a parent hands back `undefined`.
120
+ const applyDefaults = () => {
121
+ if (value === undefined) value = "";
122
+ };
123
+ applyDefaults();
124
+ $effect.pre(applyDefaults);
125
+ </script>
126
+
127
+ <TemporalField
128
+ kind="time"
129
+ {id}
130
+ bind:value
131
+ {name}
132
+ {label}
133
+ {hideLabel}
134
+ {hint}
135
+ {error}
136
+ {min}
137
+ {max}
138
+ {step}
139
+ {required}
140
+ {disabled}
141
+ {readonly}
142
+ {size}
143
+ class={className}
144
+ {locale}
145
+ {format}
146
+ {placeholder}
147
+ {picker}
148
+ {strings}
149
+ {openAt}
150
+ {...restProps}
151
+ />
@@ -0,0 +1,85 @@
1
+ import type { HTMLInputAttributes } from "svelte/elements";
2
+ import type { SizeVariant } from "../types/variants.js";
3
+ import type { TimeFieldStrings } from "../util/temporal-field.js";
4
+ /**
5
+ * A time of day, picked with the device's own time picker and styled
6
+ * like Input.
7
+ *
8
+ * It is a native `<input type="time">`. `value` is always 24-hour
9
+ * `HH:mm` (`HH:mm:ss` when `step` asks for seconds), or `""` while empty,
10
+ * whatever the field shows.
11
+ *
12
+ * What the field shows is the browser's decision, unless it has a
13
+ * `locale`: without one, 24-hour or 12-hour with AM and PM, by the
14
+ * settings of the browser or device, not of the page. To show a time as
15
+ * text in the page's language, use `formatTime`:
16
+ *
17
+ * ```svelte
18
+ * <TimeField label="Starts" bind:value={time} step={300} />
19
+ * <p>{formatTime(time, "sv")}</p> <!-- 19:00 -->
20
+ * ```
21
+ *
22
+ * With `locale`, the field shows the value in that language ("18:30" in
23
+ * Swedish, never "06:30 PM") and its own picker opens: two columns in a
24
+ * BottomSheet, hours (written as the locale writes an hour) and minutes
25
+ * (every `step`, five minutes without one), and Done. A value that is not
26
+ * on the step is kept as its own minute. A `step` under 60 seconds, or
27
+ * `"any"`, uses the platform's picker instead, as does `picker="native"`.
28
+ * Until the page has run, and without scripts, it is the native input
29
+ * as above and submits as before.
30
+ *
31
+ * Other attributes (`autocomplete`, `data-*`, `onchange`, ...) land on the
32
+ * `<input>`.
33
+ */
34
+ type Props = Omit<HTMLInputAttributes, "class" | "type" | "value" | "size" | "min" | "max" | "step" | "required" | "disabled" | "readonly" | "id" | "name"> & {
35
+ /** Omit to auto-generate; pair with FormField's `id` when used inside FormField. */
36
+ id?: string;
37
+ /** The time as 24-hour `HH:mm`, or `""` while empty. Supports `bind:value`. */
38
+ value?: string;
39
+ /** Name the value is submitted under in a form. */
40
+ name?: string;
41
+ label?: string;
42
+ /** True when FormField supplies the visible `<label>`. */
43
+ hideLabel?: boolean;
44
+ /** Help text under the field, read out with it. */
45
+ hint?: string;
46
+ /** An error under the field. It marks the field invalid and is announced. */
47
+ error?: string;
48
+ /** Earliest time that can be picked, as `HH:mm`. */
49
+ min?: string;
50
+ /** Latest time that can be picked, as `HH:mm`. */
51
+ max?: string;
52
+ /** Steps between times that can be picked, in seconds: 300 for five minutes. */
53
+ step?: number | "any";
54
+ required?: boolean;
55
+ disabled?: boolean;
56
+ /** Shows the value without letting it be changed; it is still submitted. */
57
+ readonly?: boolean;
58
+ /** Height, on the scale Input and Button use. At least 44px on a touch screen. */
59
+ size?: SizeVariant;
60
+ /** Extra classes for the `<input>`. */
61
+ class?: string;
62
+ /**
63
+ * Language of the field, as a BCP 47 tag (`sv`, `en-GB`) or a list of them. With it the
64
+ * field shows the value in that language, whatever the browser's is, and opens the
65
+ * library's own picker; see above. Left out, the field is the native input.
66
+ */
67
+ locale?: string | string[];
68
+ /** With `locale`: how the value is shown, as options of `Intl.DateTimeFormat`. Default: formatTime gives for the locale. */
69
+ format?: Intl.DateTimeFormatOptions;
70
+ /** With `locale`: shown in the placeholder colour while the field is empty. */
71
+ placeholder?: string;
72
+ /** With `locale`: `library` (default) opens the library's time columns in a sheet; `native` opens the platform's own picker. */
73
+ picker?: "library" | "native";
74
+ /** With `locale`: the words the field says; replace any of them to translate. */
75
+ strings?: Partial<TimeFieldStrings>;
76
+ /**
77
+ * With `locale`, while the field is empty: the time the library's columns stand at when
78
+ * the sheet opens, as `HH:mm` (`"18:30"`). It is only where to scroll to: no row is
79
+ * chosen and `value` stays empty until the person chooses. Left out: now, on the step.
80
+ */
81
+ openAt?: string;
82
+ };
83
+ declare const TimeField: import("svelte").Component<Props, {}, "value">;
84
+ type TimeField = ReturnType<typeof TimeField>;
85
+ export default TimeField;
@@ -1,10 +1,14 @@
1
1
  <script lang="ts">
2
+ import { DEFAULT_TOAST_TEXTS, zabiStringsFor } from "../util/zabi-strings.js";
2
3
  import { cn } from "../util/cn.js";
4
+ import { TOUCH_HIT_AREA } from "../util/touch-target.js";
3
5
 
4
6
  interface Props {
5
7
  message?: string;
6
8
  type?: 'success' | 'error' | 'warning' | 'info';
7
9
  closable?: boolean;
10
+ /** Accessible name of the close button. */
11
+ closeLabel?: string;
8
12
  onclick?: (event: Event) => void;
9
13
  class?: string;
10
14
  /** `viewport`: fixed corner; `inline`: block in flow (e.g. demos). */
@@ -15,23 +19,30 @@
15
19
  message = '',
16
20
  type = 'info',
17
21
  closable = true,
22
+ closeLabel: closeLabelGiven,
18
23
  onclick,
19
24
  class: className = '',
20
25
  layout = 'viewport',
21
26
  ...restProps
22
27
  }: Props = $props();
23
28
 
29
+ /** Each text: the prop, else the app-wide word from a `ZabiStringsProvider` above this one, else English. */
30
+ const provided = zabiStringsFor("toast");
31
+ const closeLabel = $derived(closeLabelGiven ?? provided()?.closeLabel ?? DEFAULT_TOAST_TEXTS.closeLabel);
32
+
24
33
  let isVisible = $state(true);
25
34
 
26
35
  const typeClasses: Record<NonNullable<Props['type']>, string> = {
27
- success: 'border-success bg-surface-overlay text-success',
28
- error: 'border-error bg-surface-overlay text-error',
29
- warning: 'border-warning bg-surface-overlay text-warning',
30
- info: 'border-border bg-surface-overlay text-body',
36
+ success: 'border-success text-success-text',
37
+ error: 'border-error text-error-text',
38
+ warning: 'border-warning text-warning-text',
39
+ // The material has its own rim: no second edge on the neutral toast.
40
+ info: 'border-transparent text-body',
31
41
  };
32
42
 
43
+ // `min(18rem, 100%)`: 18rem is wider than a 320px screen once the text is enlarged.
33
44
  const cardClasses =
34
- 'box-border w-full min-w-[18rem] max-w-[min(24rem,calc(100vw-2rem))] overflow-hidden rounded-control border p-4 shadow-lg';
45
+ 'box-border w-full min-w-[min(18rem,100%)] max-w-[min(24rem,calc(100vw-2rem))] overflow-hidden rounded-control border p-4 material-thick';
35
46
 
36
47
  function closeToast(event: Event) {
37
48
  isVisible = false;
@@ -46,11 +57,14 @@
46
57
  </div>
47
58
 
48
59
  {#if closable}
60
+ <!-- `px-1` on a touch screen: the 44px layer is centred on the
61
+ button, and around a button as narrow as the glyph it reached a
62
+ pixel past what the card clips. -->
49
63
  <button
50
64
  type="button"
51
- class="focus-ring shrink-0 cursor-pointer rounded-control text-description hover:text-headline focus:outline-none"
65
+ class="focus-ring pointer-coarse:relative shrink-0 cursor-pointer rounded-control text-description hover:text-headline active:text-headline focus:outline-none pointer-coarse:px-1 {TOUCH_HIT_AREA}"
52
66
  onclick={closeToast}
53
- aria-label="Close notification"
67
+ aria-label={closeLabel}
54
68
  >
55
69
  ×
56
70
  </button>
@@ -61,7 +75,7 @@
61
75
  {#if isVisible}
62
76
  {#if layout === 'viewport'}
63
77
  <div
64
- class="pointer-events-none fixed top-4 right-4 left-4 z-toast flex justify-end sm:left-auto"
78
+ class="pointer-events-none fixed top-[calc(max(var(--app-shell-top-inset,0px),env(safe-area-inset-top,0px))_+_1rem)] right-[calc(env(safe-area-inset-right,0px)_+_1rem)] left-[calc(env(safe-area-inset-left,0px)_+_1rem)] z-toast flex justify-end sm:left-auto"
65
79
  >
66
80
  <div
67
81
  class={cn("pointer-events-auto", cardClasses, typeClasses[type], className)}
@@ -2,6 +2,8 @@ interface Props {
2
2
  message?: string;
3
3
  type?: 'success' | 'error' | 'warning' | 'info';
4
4
  closable?: boolean;
5
+ /** Accessible name of the close button. */
6
+ closeLabel?: string;
5
7
  onclick?: (event: Event) => void;
6
8
  class?: string;
7
9
  /** `viewport`: fixed corner; `inline`: block in flow (e.g. demos). */