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,472 @@
1
+ <script module lang="ts">
2
+ /**
3
+ * Remembered for the page's life: the platform's own picker refused to
4
+ * open (or is not there), so a field that wanted it shows its native input.
5
+ */
6
+ let nativePickerFailed = false;
7
+ </script>
8
+
9
+ <script lang="ts">
10
+ import CalendarIcon from "@lucide/svelte/icons/calendar";
11
+ import Clock from "@lucide/svelte/icons/clock";
12
+ import { onMount, tick } from "svelte";
13
+ import type { SizeVariant } from "../types/variants.js";
14
+ import { cn } from "../util/cn.js";
15
+ import { clampDate, formatDate, formatTime, isIsoDate, monthOf, todayIso } from "../util/date.js";
16
+ import { mergeStrings } from "../util/ready-made-strings.js";
17
+ import { generateId } from "../util/ssr-safe.js";
18
+ import {
19
+ DATE_FIELD_STRINGS,
20
+ TIME_FIELD_STRINGS,
21
+ hasLocale,
22
+ hourChoices,
23
+ minuteChoices,
24
+ minuteStep,
25
+ openingTime,
26
+ parseHourMinute,
27
+ stepFitsLibraryPicker,
28
+ timeInRange,
29
+ type DateFieldStrings,
30
+ type TimeFieldStrings,
31
+ } from "../util/temporal-field.js";
32
+ import { zabiStringsFor } from "../util/zabi-strings.js";
33
+ import BottomSheet from "../molecules/BottomSheet.svelte";
34
+ import Calendar from "../molecules/Calendar.svelte";
35
+ import Button from "./Button.svelte";
36
+ import Input from "./Input.svelte";
37
+ import PickerField from "./PickerField.svelte";
38
+ import TimeColumn from "./TimeColumn.svelte";
39
+
40
+ /**
41
+ * What DateField and TimeField share. Internal: it is not exported from
42
+ * the package, and its props are those of the two fields.
43
+ *
44
+ * Without `locale` it is an `Input` with a native `type`, so the box, the
45
+ * sizes, the label, the hint and the error message are Input's own and
46
+ * cannot drift from it. What is added here is only what a native date or
47
+ * time input needs to look like one: see the classes and the style block
48
+ * below.
49
+ *
50
+ * With `locale`, the same on the server and until the page has run: the
51
+ * native input, which works and submits without scripts. Once mounted the
52
+ * native input stays as the form control, out of sight, the tab order and
53
+ * the accessibility tree, and a field-shaped button (PickerField) takes
54
+ * its place: it shows the value written by `Intl.DateTimeFormat` and opens
55
+ * the library's picker in a BottomSheet (a Calendar; two columns for a
56
+ * time), or, with `picker="native"`, the platform's own.
57
+ */
58
+ interface Props {
59
+ kind: "date" | "time";
60
+ id?: string;
61
+ value?: string;
62
+ name?: string;
63
+ label?: string;
64
+ hideLabel?: boolean;
65
+ hint?: string;
66
+ error?: string;
67
+ min?: string;
68
+ max?: string;
69
+ step?: number | "any";
70
+ required?: boolean;
71
+ disabled?: boolean;
72
+ readonly?: boolean;
73
+ size?: SizeVariant;
74
+ class?: string;
75
+ locale?: string | string[];
76
+ format?: Intl.DateTimeFormatOptions;
77
+ placeholder?: string;
78
+ picker?: "library" | "native";
79
+ strings?: Partial<DateFieldStrings> | Partial<TimeFieldStrings>;
80
+ openAt?: string;
81
+ "aria-describedby"?: string | null;
82
+ }
83
+
84
+ let {
85
+ kind,
86
+ id: idProp,
87
+ value = $bindable<Exclude<Props["value"], undefined>>(),
88
+ name = "",
89
+ label = "",
90
+ hideLabel = false,
91
+ hint = "",
92
+ error = "",
93
+ min,
94
+ max,
95
+ step,
96
+ required = false,
97
+ disabled = false,
98
+ readonly = false,
99
+ size = "md",
100
+ class: className = "",
101
+ locale,
102
+ format,
103
+ placeholder = "",
104
+ picker = "library",
105
+ strings,
106
+ openAt,
107
+ "aria-describedby": describedBy,
108
+ ...restProps
109
+ }: Props = $props();
110
+
111
+ // No fallback on a bindable prop: Svelte refuses `bind:…={undefined}` on
112
+ // one that has a fallback (`props_invalid_value`), and a page that throws
113
+ // while it hydrates never becomes interactive. The default is applied
114
+ // here instead: at once, for the server and the first render, and again
115
+ // whenever a parent hands back `undefined`.
116
+ const applyDefaults = () => {
117
+ if (value === undefined) value = "";
118
+ };
119
+ applyDefaults();
120
+ $effect.pre(applyDefaults);
121
+
122
+ /** The words of a provider above, then this field's own. */
123
+ const dateProvided = zabiStringsFor("dateField");
124
+ const timeProvided = zabiStringsFor("timeField");
125
+ const dateText = $derived(mergeStrings(DATE_FIELD_STRINGS, dateProvided(), strings as Partial<DateFieldStrings>));
126
+ const timeText = $derived(mergeStrings(TIME_FIELD_STRINGS, timeProvided(), strings as Partial<TimeFieldStrings>));
127
+
128
+ // The id of the field. Only a field with a locale needs to know it: the
129
+ // native input and the button must not share one once the button is in.
130
+ // svelte-ignore state_referenced_locally
131
+ const ownId = hasLocale(locale) ? generateId("input") : undefined;
132
+ const baseId = $derived(idProp ?? ownId);
133
+
134
+ let root: HTMLDivElement | undefined = $state();
135
+ let trigger = $state<HTMLButtonElement | HTMLAnchorElement | null>(null);
136
+
137
+ /** True once the page has run. The server and the first render never are. */
138
+ let mounted = $state(false);
139
+ let supportsNativePicker = $state(false);
140
+ let sessionBroken = $state(false);
141
+ /** This field's native input was put back in sight: the platform's picker would not open. */
142
+ let unhidden = $state(false);
143
+ let isOpen = $state(false);
144
+
145
+ onMount(() => {
146
+ supportsNativePicker = typeof HTMLInputElement !== "undefined" && typeof HTMLInputElement.prototype.showPicker === "function";
147
+ sessionBroken = nativePickerFailed;
148
+ mounted = true;
149
+ });
150
+
151
+ /** `library`, unless the app asked for the platform's, or the library's picker cannot serve this `step`. */
152
+ const effectivePicker = $derived(
153
+ picker === "native" || (kind === "time" && !stepFitsLibraryPicker(step)) ? "native" : "library",
154
+ );
155
+ const enhanced = $derived(
156
+ mounted &&
157
+ hasLocale(locale) &&
158
+ !unhidden &&
159
+ (effectivePicker === "library" || (supportsNativePicker && !sessionBroken)),
160
+ );
161
+
162
+ const display = $derived(
163
+ !value
164
+ ? ""
165
+ : kind === "date"
166
+ ? formatDate(value, locale, format)
167
+ : formatTime(value, locale, format),
168
+ );
169
+
170
+ const text = $derived(kind === "date" ? dateText : timeText);
171
+
172
+ /** What the button is named by when the label is not on the page: the label and the value. */
173
+ const hiddenLabelName = $derived(hideLabel && label ? [label, display || placeholder].filter(Boolean).join(", ") : undefined);
174
+
175
+ const nativeInput = () => root?.querySelector<HTMLInputElement>("input[data-temporal-native]") ?? null;
176
+
177
+ /**
178
+ * What the picker chose goes into the native input, which is the form
179
+ * control: its value, and real `input` and `change` events, so a listener
180
+ * the app put on the field hears it as it hears a native change. The
181
+ * binding follows from the `input` event.
182
+ */
183
+ function setValue(next: string) {
184
+ if (next === value) return;
185
+ const input = nativeInput();
186
+ if (input) {
187
+ input.value = next;
188
+ input.dispatchEvent(new Event("input", { bubbles: true }));
189
+ input.dispatchEvent(new Event("change", { bubbles: true }));
190
+ }
191
+ value = next;
192
+ }
193
+
194
+ async function closeAndFocus() {
195
+ isOpen = false;
196
+ await tick();
197
+ trigger?.focus();
198
+ }
199
+
200
+ // ---- the sheet -------------------------------------------------------
201
+
202
+ let calendarMonth = $state<string | undefined>();
203
+ let sheetSnap = $state<"half" | "full">("half");
204
+ let draftHour = $state("");
205
+ let draftMinute = $state("");
206
+ /** Where the columns stand while nothing is chosen. Set as the sheet opens; never written to `value`. */
207
+ let anchorHour = $state("");
208
+ let anchorMinute = $state("");
209
+
210
+ function openPicker() {
211
+ if (disabled || readonly) return;
212
+ if (effectivePicker === "native") {
213
+ openNative();
214
+ return;
215
+ }
216
+ if (kind === "date") {
217
+ calendarMonth = monthOf(isIsoDate(value) ? value : clampDate(todayIso(), min, max)) ?? undefined;
218
+ sheetSnap = typeof window !== "undefined" && window.innerHeight >= 900 ? "half" : "full";
219
+ } else {
220
+ const now = parseHourMinute(value);
221
+ draftHour = now ? String(now[0]).padStart(2, "0") : "";
222
+ draftMinute = now ? String(now[1]).padStart(2, "0") : "";
223
+ const clock = new Date();
224
+ [anchorHour, anchorMinute] = openingTime({
225
+ openAt,
226
+ now: [clock.getHours(), clock.getMinutes()],
227
+ stepMinutes: minuteStep(step),
228
+ min,
229
+ max,
230
+ });
231
+ sheetSnap = typeof window !== "undefined" && window.innerHeight >= 700 ? "half" : "full";
232
+ }
233
+ isOpen = true;
234
+ }
235
+
236
+ /** The platform's picker, from inside the press that asked for it. Where it is refused, the native input comes back. */
237
+ function openNative() {
238
+ const input = nativeInput();
239
+ try {
240
+ if (!input) throw new Error("no input");
241
+ input.showPicker();
242
+ } catch {
243
+ nativePickerFailed = true;
244
+ unhidden = true;
245
+ void tick().then(() => root?.querySelector<HTMLInputElement>("input")?.focus());
246
+ }
247
+ }
248
+
249
+ const canClear = $derived(!required && value !== "");
250
+ const sheetTitle = $derived(label || (kind === "date" ? dateText.chooseDate : timeText.chooseTime));
251
+
252
+ function chooseDay(date: string) {
253
+ setValue(date);
254
+ void closeAndFocus();
255
+ }
256
+
257
+ function clear() {
258
+ setValue("");
259
+ void closeAndFocus();
260
+ }
261
+
262
+ // ---- the time columns -----------------------------------------------
263
+
264
+ const hours = $derived(hourChoices(locale, min, max));
265
+ const minutes = $derived(
266
+ minuteChoices({ locale, stepMinutes: minuteStep(step), hour: draftHour, current: value, min, max }),
267
+ );
268
+
269
+ function chooseHour(hour: string) {
270
+ draftHour = hour;
271
+ const options = minuteChoices({ locale, stepMinutes: minuteStep(step), hour, current: value, min, max });
272
+ // A minute the new hour does not allow: the first one it does. None yet: the one
273
+ // `openAt` asked for if the hour allows it (not the one "now" happens to stand at), else the first.
274
+ if (!draftMinute && parseHourMinute(openAt) && options.find((option) => option.value === anchorMinute)?.disabled === false) {
275
+ draftMinute = anchorMinute;
276
+ } else if (!draftMinute || options.find((option) => option.value === draftMinute)?.disabled !== false) {
277
+ draftMinute = options.find((option) => !option.disabled)?.value ?? draftMinute;
278
+ }
279
+ }
280
+
281
+ const draftValid = $derived(
282
+ draftHour !== "" && draftMinute !== "" && timeInRange(Number(draftHour), Number(draftMinute), min, max),
283
+ );
284
+
285
+ function done() {
286
+ if (!draftValid) return;
287
+ const next = `${draftHour}:${draftMinute}`;
288
+ // The seconds of a value that is kept are kept.
289
+ const kept = parseHourMinute(value);
290
+ setValue(kept && `${String(kept[0]).padStart(2, "0")}:${String(kept[1]).padStart(2, "0")}` === next ? value : next);
291
+ void closeAndFocus();
292
+ }
293
+
294
+ // ---- the native input, out of sight once the button is in -----------
295
+
296
+ const HIDDEN_STYLE =
297
+ "position:absolute;inline-size:1px;block-size:1px;margin:-1px;padding:0;border:0;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;opacity:0;pointer-events:none";
298
+
299
+ /**
300
+ * The browser's own validation (`required` and empty) fires on the hidden
301
+ * input, where its bubble cannot be shown: that is cancelled, and focus
302
+ * goes to the button. The message people read is the field's `error`.
303
+ */
304
+ function handleInvalid(event: Event) {
305
+ (restProps as { oninvalid?: (event: Event) => void }).oninvalid?.(event);
306
+ if (!enhanced) return;
307
+ event.preventDefault();
308
+ trigger?.focus();
309
+ }
310
+
311
+ /** What Input does not declare, but passes on to the `<input>`. */
312
+ const native = $derived({
313
+ min,
314
+ max,
315
+ step,
316
+ readonly: readonly || undefined,
317
+ "data-empty": value ? undefined : "",
318
+ ...restProps,
319
+ ...(hasLocale(locale) ? { oninvalid: handleInvalid } : {}),
320
+ ...(enhanced
321
+ ? {
322
+ tabindex: -1,
323
+ "aria-hidden": "true" as const,
324
+ "data-temporal-native": "",
325
+ style: HIDDEN_STYLE,
326
+ }
327
+ : {}),
328
+ });
329
+
330
+ const fieldClasses = $derived(
331
+ cn(
332
+ "zabi-temporal-field",
333
+ // Its own look off: WebKit on iOS otherwise draws a date input as
334
+ // a button, with its own height and centred text. `block` and
335
+ // `min-w-0`: an empty one there has no intrinsic width.
336
+ "block min-w-0 appearance-none",
337
+ // The format the browser shows in an empty field ("mm/dd/yyyy")
338
+ // is a hint, not a value: in the placeholder colour.
339
+ !value && "text-input-placeholder",
340
+ className,
341
+ ),
342
+ );
343
+ </script>
344
+
345
+ <div bind:this={root}>
346
+ {#if enhanced}
347
+ <PickerField
348
+ bind:element={trigger}
349
+ id={baseId}
350
+ label={hideLabel ? "" : label}
351
+ value={display}
352
+ {placeholder}
353
+ {size}
354
+ {disabled}
355
+ {hint}
356
+ {error}
357
+ expanded={isOpen}
358
+ aria-describedby={describedBy}
359
+ aria-label={hiddenLabelName}
360
+ data-readonly={readonly ? "" : undefined}
361
+ onclick={openPicker}
362
+ >
363
+ {#snippet trailing()}
364
+ {#if kind === "date"}
365
+ <CalendarIcon size={20} aria-hidden="true" />
366
+ {:else}
367
+ <Clock size={20} aria-hidden="true" />
368
+ {/if}
369
+ {/snippet}
370
+ </PickerField>
371
+ {/if}
372
+ <Input
373
+ id={enhanced && baseId ? `${baseId}-native` : baseId}
374
+ type={kind}
375
+ bind:value
376
+ {name}
377
+ {label}
378
+ hideLabel={hideLabel || enhanced}
379
+ {required}
380
+ {disabled}
381
+ {size}
382
+ hint={enhanced ? "" : hint}
383
+ error={enhanced ? "" : error}
384
+ aria-describedby={enhanced ? undefined : describedBy}
385
+ class={fieldClasses}
386
+ {...native}
387
+ />
388
+ </div>
389
+
390
+ {#snippet clearAction()}
391
+ <Button variant="ghost" onclick={clear}>{text.clear}</Button>
392
+ {/snippet}
393
+
394
+ {#snippet doneAction()}
395
+ {#if canClear}
396
+ {@render clearAction()}
397
+ {/if}
398
+ {#if draftHour !== "" && draftMinute !== ""}
399
+ <span data-chosen-time class="me-auto min-w-0 self-center text-sm text-body">
400
+ {timeText.chosenTime}
401
+ <span class="font-semibold">{formatTime(`${draftHour}:${draftMinute}`, locale, format)}</span>
402
+ </span>
403
+ {/if}
404
+ <Button variant="primary" disabled={!draftValid} onclick={done}>{timeText.done}</Button>
405
+ {/snippet}
406
+
407
+ {#if enhanced && effectivePicker === "library"}
408
+ {#if kind === "date"}
409
+ <BottomSheet
410
+ bind:isOpen
411
+ title={sheetTitle}
412
+ snap={sheetSnap}
413
+ initialFocus="[data-date][tabindex='0']"
414
+ data-temporal-sheet="date"
415
+ {...canClear ? { footer: clearAction } : {}}
416
+ >
417
+ <Calendar
418
+ bind:month={calendarMonth}
419
+ selected={isIsoDate(value) ? value : null}
420
+ locale={Array.isArray(locale) ? locale[0] : locale}
421
+ {min}
422
+ {max}
423
+ onselect={chooseDay}
424
+ />
425
+ </BottomSheet>
426
+ {:else}
427
+ <BottomSheet
428
+ bind:isOpen
429
+ title={sheetTitle}
430
+ snap={sheetSnap}
431
+ initialFocus="[role='option'][tabindex='0']"
432
+ data-temporal-sheet="time"
433
+ footer={doneAction}
434
+ >
435
+ <div class="flex gap-3">
436
+ <TimeColumn label={timeText.hours} options={hours} selected={draftHour} openAt={anchorHour} onselect={chooseHour} />
437
+ <TimeColumn label={timeText.minutes} options={minutes} selected={draftMinute} openAt={anchorMinute} onselect={(minute) => (draftMinute = minute)} />
438
+ </div>
439
+ </BottomSheet>
440
+ {/if}
441
+ {/if}
442
+
443
+ <style>
444
+ /*
445
+ * The parts of a native date or time input that utilities cannot reach.
446
+ * Global selectors under one class: the `<input>` is rendered by Input,
447
+ * so a scoped selector would not match it.
448
+ */
449
+
450
+ /* WebKit on iOS centres the value, and gives an empty one no height. */
451
+ :global(.zabi-temporal-field::-webkit-date-and-time-value) {
452
+ min-height: 1.5em;
453
+ text-align: start;
454
+ }
455
+
456
+ /* The editable segments in Chromium and desktop WebKit: no extra box
457
+ inside the field, so the text sits where an Input's does. */
458
+ :global(.zabi-temporal-field::-webkit-datetime-edit) {
459
+ padding: 0;
460
+ }
461
+
462
+ /* The browser's calendar or clock button. It follows `color-scheme`,
463
+ which the theme's dark block sets (see app.css); nothing here has to. */
464
+ :global(.zabi-temporal-field::-webkit-calendar-picker-indicator) {
465
+ cursor: pointer;
466
+ }
467
+ :global(.zabi-temporal-field:disabled::-webkit-calendar-picker-indicator),
468
+ :global(.zabi-temporal-field:read-only::-webkit-calendar-picker-indicator) {
469
+ cursor: default;
470
+ }
471
+
472
+ </style>
@@ -0,0 +1,48 @@
1
+ import type { SizeVariant } from "../types/variants.js";
2
+ import { type DateFieldStrings, type TimeFieldStrings } from "../util/temporal-field.js";
3
+ /**
4
+ * What DateField and TimeField share. Internal: it is not exported from
5
+ * the package, and its props are those of the two fields.
6
+ *
7
+ * Without `locale` it is an `Input` with a native `type`, so the box, the
8
+ * sizes, the label, the hint and the error message are Input's own and
9
+ * cannot drift from it. What is added here is only what a native date or
10
+ * time input needs to look like one: see the classes and the style block
11
+ * below.
12
+ *
13
+ * With `locale`, the same on the server and until the page has run: the
14
+ * native input, which works and submits without scripts. Once mounted the
15
+ * native input stays as the form control, out of sight, the tab order and
16
+ * the accessibility tree, and a field-shaped button (PickerField) takes
17
+ * its place: it shows the value written by `Intl.DateTimeFormat` and opens
18
+ * the library's picker in a BottomSheet (a Calendar; two columns for a
19
+ * time), or, with `picker="native"`, the platform's own.
20
+ */
21
+ interface Props {
22
+ kind: "date" | "time";
23
+ id?: string;
24
+ value?: string;
25
+ name?: string;
26
+ label?: string;
27
+ hideLabel?: boolean;
28
+ hint?: string;
29
+ error?: string;
30
+ min?: string;
31
+ max?: string;
32
+ step?: number | "any";
33
+ required?: boolean;
34
+ disabled?: boolean;
35
+ readonly?: boolean;
36
+ size?: SizeVariant;
37
+ class?: string;
38
+ locale?: string | string[];
39
+ format?: Intl.DateTimeFormatOptions;
40
+ placeholder?: string;
41
+ picker?: "library" | "native";
42
+ strings?: Partial<DateFieldStrings> | Partial<TimeFieldStrings>;
43
+ openAt?: string;
44
+ "aria-describedby"?: string | null;
45
+ }
46
+ declare const TemporalField: import("svelte").Component<Props, {}, "value">;
47
+ type TemporalField = ReturnType<typeof TemporalField>;
48
+ export default TemporalField;
@@ -1,12 +1,15 @@
1
1
  <script lang="ts">
2
2
  import type { Snippet } from 'svelte';
3
+ import type { HTMLAttributes } from 'svelte/elements';
3
4
 
4
5
  import { cn } from "../util/cn.js";
5
- type Tone = 'body' | 'description' | 'caption' | 'headline' | 'label' | 'error';
6
+ import type { OnFillTone } from "../types/variants.js";
7
+ type Tone = 'body' | 'description' | 'caption' | 'headline' | 'label' | 'error' | OnFillTone;
6
8
  type Size = 'xs' | 'sm' | 'md' | 'lg';
7
9
  type Weight = 'normal' | 'medium' | 'semibold' | 'bold';
8
10
 
9
- interface Props {
11
+ /** Other attributes (`id`, `data-*`, `aria-*`, ...) land on the element. */
12
+ type Props = Omit<HTMLAttributes<HTMLElement>, 'class'> & {
10
13
  as?: 'p' | 'span' | 'div';
11
14
  tone?: Tone;
12
15
  size?: Size;
@@ -17,7 +20,7 @@
17
20
  weight?: Weight;
18
21
  class?: string;
19
22
  children?: Snippet;
20
- }
23
+ };
21
24
 
22
25
  let {
23
26
  as: Tag = 'p',
@@ -26,6 +29,7 @@
26
29
  weight,
27
30
  class: className = '',
28
31
  children,
32
+ ...restProps
29
33
  }: Props = $props();
30
34
 
31
35
  const toneClass: Record<Tone, string> = {
@@ -35,6 +39,9 @@
35
39
  headline: 'text-headline',
36
40
  label: 'text-label',
37
41
  error: 'text-error',
42
+ inherit: 'text-inherit',
43
+ 'on-brand': 'text-on-brand',
44
+ 'on-accent': 'text-on-accent',
38
45
  };
39
46
 
40
47
  /**
@@ -63,13 +70,18 @@
63
70
  /** Labels read as labels by default; callers can still override. */
64
71
  const defaultWeight: Weight = $derived(tone === 'label' ? 'medium' : 'normal');
65
72
  const resolvedWeight = $derived(weight ?? defaultWeight);
73
+ const classes = $derived(
74
+ cn(toneClass[tone], sizeClass[size], weightClass[resolvedWeight], className),
75
+ );
66
76
  </script>
67
77
 
68
- <svelte:element
69
- this={Tag}
70
- class={cn(toneClass[tone], sizeClass[size], weightClass[resolvedWeight], className)}
71
- >
72
- {#if children}
73
- {@render children()}
74
- {/if}
75
- </svelte:element>
78
+ <!-- One branch per tag, not a dynamic element: hydration takes a dynamic
79
+ element out and puts it back, which blurs a link or a field inside it that the
80
+ user had already tabbed to. -->
81
+ {#if Tag === 'span'}
82
+ <span class={classes} {...restProps}>{@render children?.()}</span>
83
+ {:else if Tag === 'div'}
84
+ <div class={classes} {...restProps}>{@render children?.()}</div>
85
+ {:else}
86
+ <p class={classes} {...restProps}>{@render children?.()}</p>
87
+ {/if}
@@ -1,8 +1,11 @@
1
1
  import type { Snippet } from 'svelte';
2
- type Tone = 'body' | 'description' | 'caption' | 'headline' | 'label' | 'error';
2
+ import type { HTMLAttributes } from 'svelte/elements';
3
+ import type { OnFillTone } from "../types/variants.js";
4
+ type Tone = 'body' | 'description' | 'caption' | 'headline' | 'label' | 'error' | OnFillTone;
3
5
  type Size = 'xs' | 'sm' | 'md' | 'lg';
4
6
  type Weight = 'normal' | 'medium' | 'semibold' | 'bold';
5
- interface Props {
7
+ /** Other attributes (`id`, `data-*`, `aria-*`, ...) land on the element. */
8
+ type Props = Omit<HTMLAttributes<HTMLElement>, 'class'> & {
6
9
  as?: 'p' | 'span' | 'div';
7
10
  tone?: Tone;
8
11
  size?: Size;
@@ -13,7 +16,7 @@ interface Props {
13
16
  weight?: Weight;
14
17
  class?: string;
15
18
  children?: Snippet;
16
- }
19
+ };
17
20
  declare const Text: import("svelte").Component<Props, {}, "">;
18
21
  type Text = ReturnType<typeof Text>;
19
22
  export default Text;