@noxlovette/material 0.5.1 → 0.6.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 (296) hide show
  1. package/bin/material-claude-skill.js +31 -0
  2. package/claude-skill/material-design/SKILL.md +68 -0
  3. package/claude-skill/material-design/references/accessibility-checklist.md +29 -0
  4. package/claude-skill/material-design/references/component-patterns.md +55 -0
  5. package/claude-skill/material-design/references/motion-guide.md +163 -0
  6. package/claude-skill/material-design/references/tokens-and-styles.md +68 -0
  7. package/dist/animation/Shapes.stories.svelte +10 -6
  8. package/dist/animation/TransitionPatterns.stories.svelte +30 -20
  9. package/dist/animation/containerTransform.d.ts +4 -2
  10. package/dist/animation/containerTransform.js +4 -2
  11. package/dist/animation/enterExit.js +5 -2
  12. package/dist/animation/skeleton.d.ts +1 -1
  13. package/dist/animation/skeleton.js +1 -1
  14. package/dist/components/badge/Badge.mdx +70 -0
  15. package/dist/components/badge/Badge.stories.svelte +38 -20
  16. package/dist/components/badge/Badge.svelte +12 -5
  17. package/dist/components/badge/theme.d.ts +30 -7
  18. package/dist/components/badge/theme.js +24 -4
  19. package/dist/components/badge/types.d.ts +18 -4
  20. package/dist/components/buttons/Button.mdx +85 -0
  21. package/dist/components/buttons/Button.stories.svelte +62 -27
  22. package/dist/components/buttons/Button.svelte +29 -25
  23. package/dist/components/buttons/Button.svelte.d.ts +11 -9
  24. package/dist/components/buttons/ButtonIcon.mdx +52 -0
  25. package/dist/components/buttons/ButtonIcon.stories.svelte +72 -48
  26. package/dist/components/buttons/ButtonIcon.svelte +58 -36
  27. package/dist/components/buttons/ButtonIcon.svelte.d.ts +9 -7
  28. package/dist/components/buttons/FAB.mdx +84 -0
  29. package/dist/components/buttons/FAB.stories.svelte +103 -24
  30. package/dist/components/buttons/FAB.stories.svelte.d.ts +2 -17
  31. package/dist/components/buttons/FAB.svelte +353 -29
  32. package/dist/components/buttons/FAB.svelte.d.ts +11 -6
  33. package/dist/components/buttons/FABMenu.svelte +27 -8
  34. package/dist/components/buttons/FABMenu.svelte.d.ts +7 -3
  35. package/dist/components/buttons/FABMenuItem.svelte +20 -16
  36. package/dist/components/buttons/FABMenuItem.svelte.d.ts +3 -3
  37. package/dist/components/buttons/Toggle.stories.svelte +31 -23
  38. package/dist/components/buttons/Toggle.stories.svelte.d.ts +2 -17
  39. package/dist/components/buttons/Toggle.svelte +28 -25
  40. package/dist/components/buttons/Toggle.svelte.d.ts +5 -5
  41. package/dist/components/buttons/button-group/ButtonGroup.mdx +39 -0
  42. package/dist/components/buttons/button-group/ButtonGroup.stories.svelte +62 -43
  43. package/dist/components/buttons/button-group/ButtonGroup.stories.svelte.d.ts +2 -17
  44. package/dist/components/buttons/button-group/ButtonGroup.svelte +102 -8
  45. package/dist/components/buttons/button-group/ButtonGroup.svelte.d.ts +6 -7
  46. package/dist/components/buttons/button-group/theme.d.ts +45 -15
  47. package/dist/components/buttons/button-group/theme.js +13 -8
  48. package/dist/components/buttons/button-group/types.d.ts +13 -7
  49. package/dist/components/buttons/connected/ConnectedButtonGroup.mdx +43 -0
  50. package/dist/components/buttons/connected/ConnectedButtonGroup.stories.svelte +56 -74
  51. package/dist/components/buttons/connected/ConnectedButtonGroup.stories.svelte.d.ts +2 -17
  52. package/dist/components/buttons/connected/ConnectedButtonGroup.svelte +16 -4
  53. package/dist/components/buttons/connected/ConnectedButtonGroup.svelte.d.ts +4 -4
  54. package/dist/components/buttons/connected/ConnectedButtonGroupItem.svelte +35 -8
  55. package/dist/components/buttons/connected/ConnectedButtonGroupItem.svelte.d.ts +2 -3
  56. package/dist/components/buttons/connected/theme.d.ts +33 -18
  57. package/dist/components/buttons/connected/theme.js +32 -9
  58. package/dist/components/buttons/connected/types.d.ts +36 -9
  59. package/dist/components/buttons/shapeMorph.d.ts +26 -0
  60. package/dist/components/buttons/shapeMorph.js +142 -0
  61. package/dist/components/buttons/split-button/SplitButton.mdx +48 -0
  62. package/dist/components/buttons/split-button/SplitButton.stories.svelte +9 -14
  63. package/dist/components/buttons/split-button/SplitButton.svelte +65 -48
  64. package/dist/components/buttons/split-button/SplitButton.svelte.d.ts +6 -11
  65. package/dist/components/buttons/split-button/theme.d.ts +110 -17
  66. package/dist/components/buttons/split-button/theme.js +74 -16
  67. package/dist/components/buttons/split-button/types.d.ts +24 -18
  68. package/dist/components/buttons/theme.d.ts +422 -230
  69. package/dist/components/buttons/theme.js +286 -380
  70. package/dist/components/buttons/types.d.ts +130 -125
  71. package/dist/components/cards/Card.mdx +44 -0
  72. package/dist/components/cards/Card.stories.svelte +11 -11
  73. package/dist/components/cards/theme.js +5 -5
  74. package/dist/components/chips/Chip.mdx +68 -0
  75. package/dist/components/chips/Chip.stories.svelte +4 -4
  76. package/dist/components/chips/theme.js +3 -3
  77. package/dist/components/containers/action-rail/ActionRail.stories.svelte +1 -0
  78. package/dist/components/containers/action-rail/theme.js +1 -1
  79. package/dist/components/containers/bottom-sheet/BottomSheet.mdx +64 -0
  80. package/dist/components/containers/bottom-sheet/BottomSheet.stories.svelte +108 -12
  81. package/dist/components/containers/bottom-sheet/BottomSheet.svelte +179 -109
  82. package/dist/components/containers/bottom-sheet/BottomSheet.svelte.d.ts +10 -5
  83. package/dist/components/containers/bottom-sheet/index.d.ts +1 -0
  84. package/dist/components/containers/bottom-sheet/index.js +1 -0
  85. package/dist/components/containers/bottom-sheet/theme.d.ts +45 -0
  86. package/dist/components/containers/bottom-sheet/theme.js +42 -0
  87. package/dist/components/containers/bottom-sheet/types.d.ts +37 -5
  88. package/dist/components/containers/carousel/Carousel.mdx +80 -0
  89. package/dist/components/containers/carousel/Carousel.stories.svelte +131 -0
  90. package/dist/components/containers/carousel/Carousel.stories.svelte.d.ts +4 -0
  91. package/dist/components/containers/carousel/Carousel.svelte +194 -0
  92. package/dist/components/containers/carousel/Carousel.svelte.d.ts +25 -0
  93. package/dist/components/containers/carousel/index.d.ts +3 -0
  94. package/dist/components/containers/{stack → carousel}/index.js +1 -2
  95. package/dist/components/containers/carousel/keylines.d.ts +32 -0
  96. package/dist/components/containers/carousel/keylines.js +88 -0
  97. package/dist/components/containers/carousel/theme.d.ts +162 -0
  98. package/dist/components/containers/carousel/theme.js +67 -0
  99. package/dist/components/containers/carousel/types.d.ts +52 -0
  100. package/dist/components/containers/context-menu/ContextMenu.stories.svelte +1 -0
  101. package/dist/components/containers/context-menu/ContextMenu.svelte +2 -2
  102. package/dist/components/containers/context-menu/ContextMenu.svelte.d.ts +1 -1
  103. package/dist/components/containers/context-menu/theme.js +10 -10
  104. package/dist/components/containers/dialogue/Dialogue.mdx +65 -0
  105. package/dist/components/containers/dialogue/Dialogue.stories.svelte +4 -4
  106. package/dist/components/containers/dialogue/Dialogue.svelte +1 -1
  107. package/dist/components/containers/dialogue/theme.js +3 -3
  108. package/dist/components/containers/divider/Divider.stories.svelte +2 -1
  109. package/dist/components/containers/divider/Divider.svelte +2 -2
  110. package/dist/components/containers/divider/theme.d.ts +6 -6
  111. package/dist/components/containers/divider/theme.js +2 -2
  112. package/dist/components/containers/index.d.ts +1 -1
  113. package/dist/components/containers/index.js +1 -1
  114. package/dist/components/containers/link-preview/theme.js +2 -2
  115. package/dist/components/containers/list/List.svelte +18 -0
  116. package/dist/components/containers/list/List.svelte.d.ts +4 -0
  117. package/dist/components/containers/list/ListItem.mdx +100 -0
  118. package/dist/components/containers/list/ListItem.stories.svelte +177 -42
  119. package/dist/components/containers/list/ListItem.stories.svelte.d.ts +2 -17
  120. package/dist/components/containers/list/ListItem.svelte +92 -37
  121. package/dist/components/containers/list/ListItem.svelte.d.ts +1 -1
  122. package/dist/components/containers/list/context.d.ts +6 -0
  123. package/dist/components/containers/list/context.js +4 -0
  124. package/dist/components/containers/list/index.d.ts +1 -0
  125. package/dist/components/containers/list/index.js +1 -0
  126. package/dist/components/containers/list/theme.d.ts +487 -12
  127. package/dist/components/containers/list/theme.js +140 -13
  128. package/dist/components/containers/list/types.d.ts +39 -5
  129. package/dist/components/containers/menu/Menu.mdx +52 -0
  130. package/dist/components/containers/menu/Menu.stories.svelte +14 -14
  131. package/dist/components/containers/menu/Menu.svelte +1 -1
  132. package/dist/components/containers/menu/MenuGroup.svelte +1 -1
  133. package/dist/components/containers/menu/MenuGroup.svelte.d.ts +1 -1
  134. package/dist/components/containers/menu/menu-item/MenuItem.svelte +1 -1
  135. package/dist/components/containers/menu/theme.js +8 -8
  136. package/dist/components/containers/pane/DraggablePane.stories.svelte +4 -3
  137. package/dist/components/containers/pane/DraggablePane.svelte +2 -2
  138. package/dist/components/containers/pane/Pane.stories.svelte +11 -10
  139. package/dist/components/containers/pane/Pane.svelte +24 -2
  140. package/dist/components/containers/pane/PaneGrid.stories.svelte +19 -18
  141. package/dist/components/containers/pane/PaneGrid.svelte +3 -2
  142. package/dist/components/containers/pane/PaneGrid.svelte.d.ts +2 -1
  143. package/dist/components/containers/pane/PaneHandle.svelte +48 -2
  144. package/dist/components/containers/pane/PaneHandle.svelte.d.ts +4 -0
  145. package/dist/components/containers/pane/resizeStore.svelte.d.ts +10 -1
  146. package/dist/components/containers/pane/resizeStore.svelte.js +13 -2
  147. package/dist/components/containers/pane/theme.js +129 -45
  148. package/dist/components/containers/pane/types.d.ts +3 -2
  149. package/dist/components/containers/popover/Popover.mdx +45 -0
  150. package/dist/components/containers/popover/Popover.stories.svelte +1 -1
  151. package/dist/components/containers/popover/Popover.svelte +1 -1
  152. package/dist/components/containers/popover/theme.js +3 -3
  153. package/dist/components/containers/scroll-area/theme.js +2 -2
  154. package/dist/components/containers/side-sheet/SideSheet.mdx +71 -0
  155. package/dist/components/containers/side-sheet/SideSheet.stories.svelte +113 -17
  156. package/dist/components/containers/side-sheet/SideSheet.svelte +113 -66
  157. package/dist/components/containers/side-sheet/SideSheet.svelte.d.ts +8 -7
  158. package/dist/components/containers/side-sheet/index.d.ts +1 -0
  159. package/dist/components/containers/side-sheet/index.js +1 -0
  160. package/dist/components/containers/side-sheet/theme.d.ts +108 -0
  161. package/dist/components/containers/side-sheet/theme.js +72 -0
  162. package/dist/components/containers/side-sheet/types.d.ts +35 -7
  163. package/dist/components/date/DateField.stories.svelte +4 -3
  164. package/dist/components/date/DateField.svelte +11 -2
  165. package/dist/components/date/DateRangeField.stories.svelte +4 -3
  166. package/dist/components/date/DateRangeField.svelte +12 -3
  167. package/dist/components/date/theme.d.ts +7 -7
  168. package/dist/components/date/theme.js +31 -31
  169. package/dist/components/forms/checkbox/Checkbox.mdx +35 -0
  170. package/dist/components/forms/checkbox/Checkbox.stories.svelte +2 -2
  171. package/dist/components/forms/checkbox/Checkbox.svelte +1 -1
  172. package/dist/components/forms/checkbox/theme.js +3 -3
  173. package/dist/components/forms/command/Command.stories.svelte +1 -0
  174. package/dist/components/forms/command/theme.js +9 -9
  175. package/dist/components/forms/pin/theme.js +4 -4
  176. package/dist/components/forms/radio-group/RadioGroup.svelte +1 -1
  177. package/dist/components/forms/radio-group/theme.js +5 -5
  178. package/dist/components/forms/search/Search.mdx +38 -0
  179. package/dist/components/forms/search/Search.stories.svelte +19 -9
  180. package/dist/components/forms/search/Search.svelte +40 -17
  181. package/dist/components/forms/search/Search.svelte.d.ts +2 -2
  182. package/dist/components/forms/search/theme.d.ts +45 -12
  183. package/dist/components/forms/search/theme.js +13 -8
  184. package/dist/components/forms/search/types.d.ts +18 -12
  185. package/dist/components/forms/select/Select.mdx +53 -0
  186. package/dist/components/forms/select/Select.stories.svelte +4 -4
  187. package/dist/components/forms/select/Select.svelte +10 -2
  188. package/dist/components/forms/select/SelectItem.svelte +1 -1
  189. package/dist/components/forms/select/theme.js +12 -12
  190. package/dist/components/forms/slider/Slider.mdx +85 -0
  191. package/dist/components/forms/slider/Slider.stories.svelte +7 -7
  192. package/dist/components/forms/slider/Slider.svelte +46 -28
  193. package/dist/components/forms/slider/theme.d.ts +14 -0
  194. package/dist/components/forms/slider/theme.js +28 -17
  195. package/dist/components/forms/slider/types.d.ts +3 -2
  196. package/dist/components/forms/switch/Switch.mdx +38 -0
  197. package/dist/components/forms/switch/Switch.stories.svelte +3 -3
  198. package/dist/components/forms/switch/theme.js +6 -6
  199. package/dist/components/forms/textfield/Textfield.mdx +53 -0
  200. package/dist/components/forms/textfield/Textfield.stories.svelte +6 -6
  201. package/dist/components/forms/textfield/Textfield.svelte +1 -0
  202. package/dist/components/forms/textfield/theme.js +19 -19
  203. package/dist/components/forms/toggle-group/theme.js +2 -2
  204. package/dist/components/forms/tooltip/Tooltip.stories.svelte +1 -0
  205. package/dist/components/forms/tooltip/theme.js +3 -3
  206. package/dist/components/misc/Avatar.stories.svelte +5 -4
  207. package/dist/components/misc/ThemeSettings.svelte +9 -9
  208. package/dist/components/misc/ThemeSwitcher.svelte +3 -3
  209. package/dist/components/misc/theme.js +4 -4
  210. package/dist/components/nav/appbar/AppBar.mdx +71 -0
  211. package/dist/components/nav/appbar/AppBar.stories.svelte +93 -3
  212. package/dist/components/nav/appbar/AppBar.stories.svelte.d.ts +2 -17
  213. package/dist/components/nav/appbar/AppBar.svelte +90 -37
  214. package/dist/components/nav/appbar/AppBar.svelte.d.ts +9 -2
  215. package/dist/components/nav/appbar/theme.d.ts +85 -18
  216. package/dist/components/nav/appbar/theme.js +159 -23
  217. package/dist/components/nav/appbar/types.d.ts +46 -9
  218. package/dist/components/nav/breadcrumb/Breadcrumb.stories.svelte +1 -0
  219. package/dist/components/nav/breadcrumb/theme.js +5 -5
  220. package/dist/components/nav/navbar/Navbar.mdx +38 -0
  221. package/dist/components/nav/navbar/Navbar.svelte +1 -1
  222. package/dist/components/nav/navbar/NavbarItem.svelte +12 -9
  223. package/dist/components/nav/navbar/theme.js +6 -6
  224. package/dist/components/nav/rail/Rail.mdx +73 -0
  225. package/dist/components/nav/rail/Rail.stories.svelte +3 -7
  226. package/dist/components/nav/rail/Rail.svelte +1 -0
  227. package/dist/components/nav/rail/RailItem.svelte +12 -9
  228. package/dist/components/nav/rail/theme.js +13 -13
  229. package/dist/components/nav/rail/types.d.ts +4 -1
  230. package/dist/components/nav/tabs/Tabs.mdx +62 -0
  231. package/dist/components/nav/tabs/Tabs.stories.svelte +1 -1
  232. package/dist/components/nav/tabs/theme.js +4 -4
  233. package/dist/components/pill/Pill.mdx +32 -0
  234. package/dist/components/pill/Pill.stories.svelte +1 -1
  235. package/dist/components/pill/theme.d.ts +1 -1
  236. package/dist/components/pill/theme.js +1 -1
  237. package/dist/components/progress/LinearProgress.svelte +1 -1
  238. package/dist/components/progress/Progress.mdx +50 -0
  239. package/dist/components/progress/Progress.stories.svelte +6 -6
  240. package/dist/components/snackbar/Snackbar.mdx +52 -0
  241. package/dist/components/snackbar/Snackbar.stories.svelte +5 -5
  242. package/dist/components/snackbar/Snackbar.svelte +1 -1
  243. package/dist/components/snackbar/theme.d.ts +3 -3
  244. package/dist/components/snackbar/theme.js +4 -4
  245. package/dist/components/table/Table.stories.svelte +1 -0
  246. package/dist/components/table/TableHeader.svelte +1 -1
  247. package/dist/components/table/theme.js +3 -3
  248. package/dist/components/time/TimeField.stories.svelte +3 -2
  249. package/dist/components/time/TimeField.svelte +1 -1
  250. package/dist/components/time/TimepickerInput.svelte +1 -1
  251. package/dist/components/time/theme.js +5 -5
  252. package/dist/components/toolbar/Toolbar.stories.svelte +1 -0
  253. package/dist/components/toolbar/Toolbar.svelte +1 -1
  254. package/dist/components/toolbar/Toolbar.svelte.d.ts +1 -1
  255. package/dist/components/toolbar/theme.js +14 -14
  256. package/dist/components/typography/Typography.mdx +67 -0
  257. package/dist/components/typography/body/Body.stories.svelte +2 -1
  258. package/dist/components/typography/body/theme.d.ts +15 -12
  259. package/dist/components/typography/body/theme.js +19 -4
  260. package/dist/components/typography/body/types.d.ts +2 -1
  261. package/dist/components/typography/display/Display.stories.svelte +2 -1
  262. package/dist/components/typography/display/theme.d.ts +15 -12
  263. package/dist/components/typography/display/theme.js +19 -4
  264. package/dist/components/typography/display/types.d.ts +2 -1
  265. package/dist/components/typography/headline/Headline.stories.svelte +2 -1
  266. package/dist/components/typography/headline/theme.d.ts +15 -12
  267. package/dist/components/typography/headline/theme.js +19 -4
  268. package/dist/components/typography/headline/types.d.ts +2 -1
  269. package/dist/components/typography/kbd/Kbd.stories.svelte +2 -1
  270. package/dist/components/typography/kbd/theme.d.ts +4 -4
  271. package/dist/components/typography/kbd/theme.js +2 -2
  272. package/dist/components/typography/label/Label.stories.svelte +2 -1
  273. package/dist/components/typography/label/theme.d.ts +15 -12
  274. package/dist/components/typography/label/theme.js +19 -4
  275. package/dist/components/typography/label/types.d.ts +2 -1
  276. package/dist/components/typography/title/Title.stories.svelte +2 -1
  277. package/dist/components/typography/title/theme.d.ts +15 -12
  278. package/dist/components/typography/title/theme.js +19 -4
  279. package/dist/components/typography/title/types.d.ts +2 -1
  280. package/dist/index.css +1 -0
  281. package/dist/styles/component.css +78 -175
  282. package/dist/styles/elevation.css +9 -0
  283. package/dist/styles/spacing.css +29 -0
  284. package/dist/styles/typescale.css +635 -20
  285. package/dist/utils/Layer.svelte +1 -1
  286. package/dist/utils/icon/Icon.svelte +8 -6
  287. package/package.json +19 -15
  288. package/dist/components/containers/stack/HStack.svelte +0 -23
  289. package/dist/components/containers/stack/HStack.svelte.d.ts +0 -5
  290. package/dist/components/containers/stack/VStack.svelte +0 -23
  291. package/dist/components/containers/stack/VStack.svelte.d.ts +0 -5
  292. package/dist/components/containers/stack/index.d.ts +0 -4
  293. package/dist/components/containers/stack/theme.d.ts +0 -66
  294. package/dist/components/containers/stack/theme.js +0 -26
  295. package/dist/components/containers/stack/types.d.ts +0 -12
  296. /package/dist/components/containers/{stack → carousel}/types.js +0 -0
@@ -5,17 +5,25 @@ Material 3 App Bar.
5
5
  Top app bars provide content and actions related to the current screen.
6
6
  They’re used for branding, screen titles, navigation, and actions.
7
7
 
8
+ Sizes: `small` (64dp, one line) and the Expressive `medium`/`large` flexible bars, whose
9
+ headline block wraps and grows. `size` also takes one value per breakpoint
10
+ (`{ small: 'small', large: 'large' }`), switched in CSS so server rendering needs no JS.
11
+ `align="center"` centres the title. Setting `search` makes it a search app bar.
12
+
13
+ The bar takes its on-scroll color once `scrollContainer` (default: the page) scrolls.
14
+
8
15
  Publishes its measured height as `--appbar-height` on the document root, so any
9
16
  `Pane`/`PaneGrid` on the page (`full`, the default) shrinks its `min-height` by
10
17
  that amount with no props or wiring on either side — see Pane.svelte's doc
11
18
  comment.
12
19
 
13
- @see https://m3.material.io/components/top-app-bar/overview
20
+ @see https://m3.material.io/components/app-bars/specs
14
21
  -->
15
22
  <script lang="ts">
16
- import { appbar } from './theme.js';
23
+ import { appbar, appbarSize } from './theme.js';
17
24
  import type { AppBarProps } from './types.js';
18
25
  import clsx from 'clsx';
26
+ import ButtonIcon from '../../buttons/ButtonIcon.svelte';
19
27
 
20
28
  let {
21
29
  children,
@@ -27,31 +35,46 @@ comment.
27
35
  leading,
28
36
  class: className,
29
37
  rowClass,
30
- showBack,
38
+ showBack = false,
39
+ onback = () => history.back(),
40
+ size = 'small',
41
+ align = 'start',
42
+ search,
43
+ query = $bindable(''),
44
+ searchProps,
45
+ searchTrailing,
46
+ scrollContainer,
31
47
  ghost = false,
32
48
  ...rest
33
49
  }: AppBarProps = $props();
34
50
 
35
- let scrollY = $state(0);
36
- let scrolled = $derived(scrollY > 10);
51
+ let scrolled = $state(false);
37
52
  let barHeight = $state(64);
38
53
 
39
- const noTrailing = $derived(!trailing);
40
- const noLeading = $derived(!leading || !showBack);
54
+ $effect(() => {
55
+ const target = scrollContainer ?? window;
56
+ const read = () =>
57
+ (scrolled = (scrollContainer ? scrollContainer.scrollTop : window.scrollY) > 10);
58
+ read();
59
+ target.addEventListener('scroll', read, { passive: true });
60
+ return () => target.removeEventListener('scroll', read);
61
+ });
62
+
63
+ const isSearch = $derived(search !== undefined);
64
+ const noLeading = $derived(!leading && !showBack);
41
65
 
42
- const {
43
- base,
44
- row,
45
- childrenRow,
46
- ghost: ghostCls,
47
- title: titleCLs,
48
- textContainer,
49
- subtitle: subtitleCls,
50
- leading: leadingCls,
51
- trailing: trailingCls
52
- } = $derived(appbar({ scrolled, noLeading, noTrailing }));
53
- const navClass = $derived(base({ class: clsx(className) }));
54
- const rowFull = $derived(row({ class: clsx(rowClass) }));
66
+ const s = $derived(
67
+ appbar({
68
+ align: isSearch ? 'start' : align,
69
+ scrolled,
70
+ searchContainer: isSearch,
71
+ hasSearchTrailing: !!searchTrailing,
72
+ noLeading,
73
+ noTrailing: !trailing
74
+ })
75
+ );
76
+ // Search app bars are always the small, 64dp bar.
77
+ const sized = $derived(appbarSize(isSearch ? 'small' : size, !!subtitle));
55
78
 
56
79
  function trackHeight(node: HTMLElement) {
57
80
  const observer = new ResizeObserver((entries) => {
@@ -68,33 +91,63 @@ comment.
68
91
  });
69
92
  </script>
70
93
 
71
- <svelte:window bind:scrollY />
72
-
73
- <nav {...rest} class={navClass} {@attach trackHeight}>
74
- <div class={rowFull}>
75
- <div class={leadingCls()}>
76
- {@render leading?.()}
94
+ <nav {...rest} class={s.base({ class: clsx(className) })} {@attach trackHeight}>
95
+ <div class={s.row({ class: clsx(sized.row, rowClass) })}>
96
+ <div class={s.leading()}>
97
+ {#if leading}
98
+ {@render leading()}
99
+ {:else if showBack}
100
+ <ButtonIcon
101
+ variant="standard"
102
+ iconProps={{ name: 'arrow_back' }}
103
+ aria-label="Back"
104
+ onclick={onback}
105
+ />
106
+ {/if}
77
107
  </div>
78
- <div class={textContainer()}>
79
- <h1 class={titleCLs({ class: clsx(titleProps?.class) })} {...titleProps}>
80
- {title}
81
- </h1>
82
- {#if subtitle}
83
- <p class={subtitleCls({ class: clsx(subtitleProps?.class) })} {...subtitleProps}>
84
- {subtitle}
85
- </p>
108
+ <div class={s.textContainer({ class: sized.textContainer })}>
109
+ {#if isSearch}
110
+ {#if title}
111
+ <h1 {...titleProps} class={clsx('sr-only', titleProps?.class)}>{title}</h1>
112
+ {/if}
113
+ <label class={s.search()}>
114
+ <input
115
+ type="search"
116
+ {...searchProps}
117
+ placeholder={search}
118
+ aria-label={searchProps?.['aria-label'] ?? search}
119
+ bind:value={query}
120
+ class={s.searchInput({ class: clsx(searchProps?.class) })}
121
+ />
122
+ {#if searchTrailing}
123
+ <span class={s.searchTrailing()}>{@render searchTrailing()}</span>
124
+ {/if}
125
+ </label>
126
+ {:else}
127
+ <h1 {...titleProps} class={s.title({ class: clsx(sized.title, titleProps?.class) })}>
128
+ {title}
129
+ </h1>
130
+ {#if subtitle}
131
+ <p
132
+ {...subtitleProps}
133
+ class={s.subtitle({ class: clsx(sized.subtitle, subtitleProps?.class) })}
134
+ >
135
+ {subtitle}
136
+ </p>
137
+ {/if}
86
138
  {/if}
87
139
  </div>
88
- <div class={trailingCls()}>
140
+ <div class={s.trailing()}>
89
141
  {@render trailing?.()}
90
142
  </div>
91
143
  </div>
92
144
  {#if children}
93
- <div class={childrenRow()}>
145
+ <div class={s.childrenRow()}>
94
146
  {@render children()}
95
147
  </div>
96
148
  {/if}
97
149
  </nav>
150
+
98
151
  {#if ghost}
99
- <div class={ghostCls()} style="height: {barHeight}px" aria-hidden="true"></div>
152
+ <div class={s.ghost()} style="height: {barHeight}px" aria-hidden="true"></div>
100
153
  {/if}
@@ -5,13 +5,20 @@ import type { AppBarProps } from './types.js';
5
5
  * Top app bars provide content and actions related to the current screen.
6
6
  * They’re used for branding, screen titles, navigation, and actions.
7
7
  *
8
+ * Sizes: `small` (64dp, one line) and the Expressive `medium`/`large` flexible bars, whose
9
+ * headline block wraps and grows. `size` also takes one value per breakpoint
10
+ * (`{ small: 'small', large: 'large' }`), switched in CSS so server rendering needs no JS.
11
+ * `align="center"` centres the title. Setting `search` makes it a search app bar.
12
+ *
13
+ * The bar takes its on-scroll color once `scrollContainer` (default: the page) scrolls.
14
+ *
8
15
  * Publishes its measured height as `--appbar-height` on the document root, so any
9
16
  * `Pane`/`PaneGrid` on the page (`full`, the default) shrinks its `min-height` by
10
17
  * that amount with no props or wiring on either side — see Pane.svelte's doc
11
18
  * comment.
12
19
  *
13
- * @see https://m3.material.io/components/top-app-bar/overview
20
+ * @see https://m3.material.io/components/app-bars/specs
14
21
  */
15
- declare const AppBar: import("svelte").Component<AppBarProps, {}, "">;
22
+ declare const AppBar: import("svelte").Component<AppBarProps, {}, "query">;
16
23
  type AppBar = ReturnType<typeof AppBar>;
17
24
  export default AppBar;
@@ -1,30 +1,54 @@
1
1
  import { type VariantProps } from 'tailwind-variants';
2
+ import type { Breakpoint } from '../../containers/pane/theme.js';
2
3
  export type AppbarVariants = VariantProps<typeof appbar>;
4
+ export type AppBarSize = 'small' | 'medium' | 'large';
5
+ /**
6
+ * Resolves `size` (one value, or one per breakpoint like `PaneGrid`'s props) into per-slot
7
+ * classes. Sizes cascade upward from the smallest breakpoint given, like Tailwind prefixes.
8
+ */
9
+ export declare function appbarSize(size: AppBarSize | Partial<Record<Breakpoint, AppBarSize>>, hasSubtitle: boolean): Record<'row' | 'textContainer' | 'title' | 'subtitle', string>;
3
10
  export declare const appbar: import("tailwind-variants").TVReturnType<{
11
+ align: {
12
+ start: {
13
+ row: string;
14
+ textContainer: string;
15
+ };
16
+ center: {
17
+ row: string;
18
+ textContainer: string;
19
+ };
20
+ };
4
21
  scrolled: {
5
22
  true: {
6
23
  base: string;
24
+ search: string;
7
25
  };
8
26
  false: {
9
27
  base: string;
28
+ search: string;
10
29
  };
11
30
  };
12
31
  searchContainer: {
13
- true: "";
14
- false: "";
15
- };
16
- noTrailing: {
17
32
  true: {
33
+ row: string;
18
34
  textContainer: string;
19
35
  };
20
36
  false: "";
21
37
  };
22
- noLeading: {
38
+ hasSearchTrailing: {
23
39
  true: {
24
- textContainer: string;
40
+ search: string;
25
41
  };
26
42
  false: "";
27
43
  };
44
+ noTrailing: {
45
+ true: "";
46
+ false: "";
47
+ };
48
+ noLeading: {
49
+ true: "";
50
+ false: "";
51
+ };
28
52
  }, {
29
53
  base: string;
30
54
  row: string;
@@ -35,31 +59,51 @@ export declare const appbar: import("tailwind-variants").TVReturnType<{
35
59
  subtitle: string;
36
60
  leading: string;
37
61
  trailing: string;
62
+ search: string;
63
+ searchInput: string;
64
+ searchTrailing: string;
38
65
  }, undefined, {
66
+ align: {
67
+ start: {
68
+ row: string;
69
+ textContainer: string;
70
+ };
71
+ center: {
72
+ row: string;
73
+ textContainer: string;
74
+ };
75
+ };
39
76
  scrolled: {
40
77
  true: {
41
78
  base: string;
79
+ search: string;
42
80
  };
43
81
  false: {
44
82
  base: string;
83
+ search: string;
45
84
  };
46
85
  };
47
86
  searchContainer: {
48
- true: "";
49
- false: "";
50
- };
51
- noTrailing: {
52
87
  true: {
88
+ row: string;
53
89
  textContainer: string;
54
90
  };
55
91
  false: "";
56
92
  };
57
- noLeading: {
93
+ hasSearchTrailing: {
58
94
  true: {
59
- textContainer: string;
95
+ search: string;
60
96
  };
61
97
  false: "";
62
98
  };
99
+ noTrailing: {
100
+ true: "";
101
+ false: "";
102
+ };
103
+ noLeading: {
104
+ true: "";
105
+ false: "";
106
+ };
63
107
  }, {
64
108
  base: string;
65
109
  row: string;
@@ -70,31 +114,51 @@ export declare const appbar: import("tailwind-variants").TVReturnType<{
70
114
  subtitle: string;
71
115
  leading: string;
72
116
  trailing: string;
117
+ search: string;
118
+ searchInput: string;
119
+ searchTrailing: string;
73
120
  }, import("tailwind-variants").TVReturnTypeLike<{
121
+ align: {
122
+ start: {
123
+ row: string;
124
+ textContainer: string;
125
+ };
126
+ center: {
127
+ row: string;
128
+ textContainer: string;
129
+ };
130
+ };
74
131
  scrolled: {
75
132
  true: {
76
133
  base: string;
134
+ search: string;
77
135
  };
78
136
  false: {
79
137
  base: string;
138
+ search: string;
80
139
  };
81
140
  };
82
141
  searchContainer: {
83
- true: "";
84
- false: "";
85
- };
86
- noTrailing: {
87
142
  true: {
143
+ row: string;
88
144
  textContainer: string;
89
145
  };
90
146
  false: "";
91
147
  };
92
- noLeading: {
148
+ hasSearchTrailing: {
93
149
  true: {
94
- textContainer: string;
150
+ search: string;
95
151
  };
96
152
  false: "";
97
153
  };
154
+ noTrailing: {
155
+ true: "";
156
+ false: "";
157
+ };
158
+ noLeading: {
159
+ true: "";
160
+ false: "";
161
+ };
98
162
  }, {
99
163
  base: string;
100
164
  row: string;
@@ -105,4 +169,7 @@ export declare const appbar: import("tailwind-variants").TVReturnType<{
105
169
  subtitle: string;
106
170
  leading: string;
107
171
  trailing: string;
172
+ search: string;
173
+ searchInput: string;
174
+ searchTrailing: string;
108
175
  }>>;
@@ -1,38 +1,174 @@
1
1
  import { tv } from 'tailwind-variants';
2
+ /*
3
+ M3 Expressive app bar (https://m3.material.io/components/app-bars/specs), laid out on one
4
+ 3-column grid (leading · text · trailing) so the size can change per breakpoint in CSS alone:
5
+ - small: 64dp, one row, title between the buttons.
6
+ - medium/large flexible: an actions row (8dp top, 48dp) above a headline block spanning all
7
+ columns (16dp inset, 12dp bottom) that wraps and grows; min height 112/120dp, or 136/152dp
8
+ with a subtitle.
9
+ 4dp container padding and 0 gap between 48dp icon buttons throughout. Every class below is a
10
+ literal so the Tailwind scanner sees it; `appbarSize` picks them per breakpoint.
11
+ */
12
+ const sizeClasses = {
13
+ small: {
14
+ small: {
15
+ row: 'grid-rows-[4rem] pt-spacing-0 min-h-spacing-800',
16
+ rowSubtitle: '',
17
+ textContainer: 'col-start-2 col-span-1 row-start-1 self-center ps-(--lead) pe-(--trail) pt-spacing-0 pb-spacing-0',
18
+ title: 'md-sys-typescale-title-large line-clamp-1',
19
+ subtitle: 'md-sys-typescale-label-medium line-clamp-1'
20
+ },
21
+ medium: {
22
+ row: 'grid-rows-[3rem_1fr] pt-spacing-100 min-h-28',
23
+ rowSubtitle: 'min-h-34',
24
+ textContainer: 'col-start-1 col-span-3 row-start-2 self-end ps-spacing-200 pe-spacing-200 pt-spacing-50 pb-spacing-150',
25
+ title: 'md-sys-typescale-headline-medium line-clamp-none',
26
+ subtitle: 'md-sys-typescale-title-small line-clamp-none'
27
+ },
28
+ large: {
29
+ row: 'grid-rows-[3rem_1fr] pt-spacing-100 min-h-30',
30
+ rowSubtitle: 'min-h-38',
31
+ textContainer: 'col-start-1 col-span-3 row-start-2 self-end ps-spacing-200 pe-spacing-200 pt-spacing-50 pb-spacing-150',
32
+ title: 'md-sys-typescale-display-small line-clamp-none',
33
+ subtitle: 'md-sys-typescale-title-medium line-clamp-none'
34
+ }
35
+ },
36
+ medium: {
37
+ small: {
38
+ row: 'md:grid-rows-[4rem] md:pt-spacing-0 md:min-h-spacing-800',
39
+ rowSubtitle: '',
40
+ textContainer: 'md:col-start-2 md:col-span-1 md:row-start-1 md:self-center md:ps-(--lead) md:pe-(--trail) md:pt-spacing-0 md:pb-spacing-0',
41
+ title: 'md:md-sys-typescale-title-large md:line-clamp-1',
42
+ subtitle: 'md:md-sys-typescale-label-medium md:line-clamp-1'
43
+ },
44
+ medium: {
45
+ row: 'md:grid-rows-[3rem_1fr] md:pt-spacing-100 md:min-h-28',
46
+ rowSubtitle: 'md:min-h-34',
47
+ textContainer: 'md:col-start-1 md:col-span-3 md:row-start-2 md:self-end md:ps-spacing-200 md:pe-spacing-200 md:pt-spacing-50 md:pb-spacing-150',
48
+ title: 'md:md-sys-typescale-headline-medium md:line-clamp-none',
49
+ subtitle: 'md:md-sys-typescale-title-small md:line-clamp-none'
50
+ },
51
+ large: {
52
+ row: 'md:grid-rows-[3rem_1fr] md:pt-spacing-100 md:min-h-30',
53
+ rowSubtitle: 'md:min-h-38',
54
+ textContainer: 'md:col-start-1 md:col-span-3 md:row-start-2 md:self-end md:ps-spacing-200 md:pe-spacing-200 md:pt-spacing-50 md:pb-spacing-150',
55
+ title: 'md:md-sys-typescale-display-small md:line-clamp-none',
56
+ subtitle: 'md:md-sys-typescale-title-medium md:line-clamp-none'
57
+ }
58
+ },
59
+ large: {
60
+ small: {
61
+ row: 'lg:grid-rows-[4rem] lg:pt-spacing-0 lg:min-h-spacing-800',
62
+ rowSubtitle: '',
63
+ textContainer: 'lg:col-start-2 lg:col-span-1 lg:row-start-1 lg:self-center lg:ps-(--lead) lg:pe-(--trail) lg:pt-spacing-0 lg:pb-spacing-0',
64
+ title: 'lg:md-sys-typescale-title-large lg:line-clamp-1',
65
+ subtitle: 'lg:md-sys-typescale-label-medium lg:line-clamp-1'
66
+ },
67
+ medium: {
68
+ row: 'lg:grid-rows-[3rem_1fr] lg:pt-spacing-100 lg:min-h-28',
69
+ rowSubtitle: 'lg:min-h-34',
70
+ textContainer: 'lg:col-start-1 lg:col-span-3 lg:row-start-2 lg:self-end lg:ps-spacing-200 lg:pe-spacing-200 lg:pt-spacing-50 lg:pb-spacing-150',
71
+ title: 'lg:md-sys-typescale-headline-medium lg:line-clamp-none',
72
+ subtitle: 'lg:md-sys-typescale-title-small lg:line-clamp-none'
73
+ },
74
+ large: {
75
+ row: 'lg:grid-rows-[3rem_1fr] lg:pt-spacing-100 lg:min-h-30',
76
+ rowSubtitle: 'lg:min-h-38',
77
+ textContainer: 'lg:col-start-1 lg:col-span-3 lg:row-start-2 lg:self-end lg:ps-spacing-200 lg:pe-spacing-200 lg:pt-spacing-50 lg:pb-spacing-150',
78
+ title: 'lg:md-sys-typescale-display-small lg:line-clamp-none',
79
+ subtitle: 'lg:md-sys-typescale-title-medium lg:line-clamp-none'
80
+ }
81
+ },
82
+ extraLarge: {
83
+ small: {
84
+ row: 'xl:grid-rows-[4rem] xl:pt-spacing-0 xl:min-h-spacing-800',
85
+ rowSubtitle: '',
86
+ textContainer: 'xl:col-start-2 xl:col-span-1 xl:row-start-1 xl:self-center xl:ps-(--lead) xl:pe-(--trail) xl:pt-spacing-0 xl:pb-spacing-0',
87
+ title: 'xl:md-sys-typescale-title-large xl:line-clamp-1',
88
+ subtitle: 'xl:md-sys-typescale-label-medium xl:line-clamp-1'
89
+ },
90
+ medium: {
91
+ row: 'xl:grid-rows-[3rem_1fr] xl:pt-spacing-100 xl:min-h-28',
92
+ rowSubtitle: 'xl:min-h-34',
93
+ textContainer: 'xl:col-start-1 xl:col-span-3 xl:row-start-2 xl:self-end xl:ps-spacing-200 xl:pe-spacing-200 xl:pt-spacing-50 xl:pb-spacing-150',
94
+ title: 'xl:md-sys-typescale-headline-medium xl:line-clamp-none',
95
+ subtitle: 'xl:md-sys-typescale-title-small xl:line-clamp-none'
96
+ },
97
+ large: {
98
+ row: 'xl:grid-rows-[3rem_1fr] xl:pt-spacing-100 xl:min-h-30',
99
+ rowSubtitle: 'xl:min-h-38',
100
+ textContainer: 'xl:col-start-1 xl:col-span-3 xl:row-start-2 xl:self-end xl:ps-spacing-200 xl:pe-spacing-200 xl:pt-spacing-50 xl:pb-spacing-150',
101
+ title: 'xl:md-sys-typescale-display-small xl:line-clamp-none',
102
+ subtitle: 'xl:md-sys-typescale-title-medium xl:line-clamp-none'
103
+ }
104
+ }
105
+ };
106
+ /**
107
+ * Resolves `size` (one value, or one per breakpoint like `PaneGrid`'s props) into per-slot
108
+ * classes. Sizes cascade upward from the smallest breakpoint given, like Tailwind prefixes.
109
+ */
110
+ export function appbarSize(size, hasSubtitle) {
111
+ const tiers = typeof size === 'string' ? { small: size } : { small: 'small', ...size };
112
+ const pick = (slot) => Object.entries(tiers)
113
+ .map(([bp, s]) => sizeClasses[bp][s][slot])
114
+ .join(' ');
115
+ return {
116
+ row: `${pick('row')} ${hasSubtitle ? pick('rowSubtitle') : ''}`,
117
+ textContainer: pick('textContainer'),
118
+ title: pick('title'),
119
+ subtitle: pick('subtitle')
120
+ };
121
+ }
2
122
  export const appbar = tv({
3
123
  slots: {
4
- base: 'fixed top-0 left-0 w-full flex flex-col z-30',
5
- row: 'h-16 py-1 flex w-full items-center justify-between',
6
- childrenRow: 'w-full px-2 pb-2',
124
+ base: 'fixed top-spacing-0 left-spacing-0 w-full flex flex-col z-30 transition-colors md-sys-motion-effects',
125
+ row: 'grid w-full items-center px-spacing-50',
126
+ childrenRow: 'w-full px-spacing-100 pb-spacing-100',
7
127
  ghost: 'w-full shrink-0 pointer-events-none',
8
- textContainer: 'flex flex-col items-start gap-0.5 grow',
9
- title: 'text-md-sys-color-on-surface md-sys-typescale-title-large line-clamp-1 capitalize ',
10
- subtitle: 'text-md-sys-color-on-surface-variant md-sys-typescale-label-medium',
11
- leading: 'text-md-sys-color-on-surface ml-0.5',
12
- trailing: 'text-md-sys-color-on-surface-variant mr-4 md:mr-6 lg:mr-8'
128
+ textContainer: 'flex min-w-spacing-0 flex-col gap-spacing-25 [--lead:0.25rem] [--trail:0.25rem]',
129
+ title: 'text-md-sys-color-on-surface',
130
+ subtitle: 'text-md-sys-color-on-surface-variant',
131
+ leading: 'text-md-sys-color-on-surface col-start-1 row-start-1 flex shrink-0 items-center justify-self-start',
132
+ trailing: 'text-md-sys-color-on-surface-variant col-start-3 row-start-1 flex shrink-0 items-center justify-self-end',
133
+ search: 'state-layer relative flex h-spacing-700 w-full min-w-spacing-0 cursor-text items-center rounded-full ps-spacing-200 pe-spacing-200 transition-colors md-sys-motion-effects before:rounded-full hover:before:bg-md-sys-color-on-surface/8 focus-within:outline-3 focus-within:outline-offset-2 focus-within:outline-md-sys-color-secondary',
134
+ searchInput: 'md-sys-typescale-body-large text-md-sys-color-on-surface placeholder:text-md-sys-color-on-surface-variant w-full min-w-spacing-0 bg-transparent text-start outline-none placeholder-shown:text-center [&::-webkit-search-cancel-button]:hidden',
135
+ searchTrailing: 'text-md-sys-color-on-surface-variant flex shrink-0 items-center'
13
136
  },
14
137
  variants: {
15
- scrolled: {
16
- true: { base: 'shadow-elevation-1 bg-md-sys-color-surface-container' },
17
- false: {
18
- base: 'shadow-elevation-0 bg-md-sys-color-surface md:bg-md-sys-color-surface-container'
19
- }
20
- },
21
- searchContainer: {
22
- true: '',
23
- false: ''
138
+ align: {
139
+ start: { row: 'grid-cols-[auto_1fr_auto]', textContainer: 'items-start text-start' },
140
+ // 1fr side columns centre a small bar's title on the bar, not between uneven button groups.
141
+ center: { row: 'grid-cols-[1fr_auto_1fr]', textContainer: 'items-center text-center' }
24
142
  },
25
- noTrailing: {
143
+ scrolled: {
26
144
  true: {
27
- textContainer: 'pr-4 md:pr-6 lg:pr-8'
145
+ base: 'bg-md-sys-color-surface-container',
146
+ search: 'bg-md-sys-color-surface-container-highest'
28
147
  },
29
- false: ''
148
+ false: { base: 'bg-md-sys-color-surface', search: 'bg-md-sys-color-surface-container' }
30
149
  },
31
- noLeading: {
150
+ // Search app bar: the search container fills the text column, 8dp from the buttons.
151
+ searchContainer: {
32
152
  true: {
33
- textContainer: 'pl-4 md:pl-6 lg:pl-8'
153
+ row: 'grid-cols-[auto_1fr_auto]',
154
+ textContainer: '[--lead:0.5rem] [--trail:0.5rem]'
34
155
  },
35
156
  false: ''
36
- }
157
+ },
158
+ hasSearchTrailing: { true: { search: 'pe-spacing-50' }, false: '' },
159
+ noTrailing: { true: '', false: '' },
160
+ noLeading: { true: '', false: '' }
161
+ },
162
+ compoundVariants: [
163
+ // A title with no button beside it sits at the 16dp inset.
164
+ { align: 'start', noLeading: true, class: { textContainer: '[--lead:1rem]' } },
165
+ { align: 'start', noTrailing: true, class: { textContainer: '[--trail:1rem]' } },
166
+ { searchContainer: true, noLeading: true, class: { textContainer: '[--lead:0.75rem]' } },
167
+ { searchContainer: true, noTrailing: true, class: { textContainer: '[--trail:0.75rem]' } }
168
+ ],
169
+ defaultVariants: {
170
+ align: 'start',
171
+ scrolled: false,
172
+ searchContainer: false
37
173
  }
38
174
  });
@@ -1,14 +1,10 @@
1
1
  import type { Snippet } from 'svelte';
2
- import type { HTMLAttributes } from 'svelte/elements';
3
- import type { AppbarVariants } from './theme.js';
4
- /**
5
- * Props for the AppBar component.
6
- */
7
- export type AppBarProps = AppbarVariants & HTMLAttributes<HTMLElementTagNameMap['nav']> & {
2
+ import type { HTMLAttributes, HTMLInputAttributes } from 'svelte/elements';
3
+ import type { Responsive } from '../../containers/pane/theme.js';
4
+ import type { AppBarSize, AppbarVariants } from './theme.js';
5
+ type AppBarBaseProps = Pick<AppbarVariants, 'align'> & HTMLAttributes<HTMLElementTagNameMap['nav']> & {
8
6
  /** Extra content rendered in a full-width row below the title, e.g. a Breadcrumb trail. */
9
7
  children?: Snippet;
10
- /** The main title of the app bar. */
11
- title: string;
12
8
  /** An optional subtitle displayed below the title. */
13
9
  subtitle?: string;
14
10
  /** Additional props for the title `<h1>` element (e.g. `data-cy`). */
@@ -19,10 +15,51 @@ export type AppBarProps = AppbarVariants & HTMLAttributes<HTMLElementTagNameMap[
19
15
  leading?: Snippet;
20
16
  /** A snippet to be rendered on the right side (e.g., action icons). */
21
17
  trailing?: Snippet;
22
- /** Whether to show a back button in the leading section. */
18
+ /** Renders a back button in the leading section (ignored when `leading` is set). */
23
19
  showBack?: boolean;
20
+ /** Called by the back button. Defaults to `history.back()`. */
21
+ onback?: () => void;
22
+ /**
23
+ * The element whose scroll switches the bar to its on-scroll color. Defaults to the page
24
+ * (`window`); pass a scrolling container, e.g. a `Pane`'s element, when content scrolls there.
25
+ */
26
+ scrollContainer?: HTMLElement | null;
24
27
  /** Renders an invisible same-height spacer after the fixed bar so page content isn't obscured. */
25
28
  ghost?: boolean;
26
29
  /** Additional classes passed onto the row element */
27
30
  rowClass?: string;
28
31
  };
32
+ /** A titled app bar: small, or the Expressive medium/large flexible bars. */
33
+ export type TitleAppBarProps = AppBarBaseProps & {
34
+ /** The main title of the app bar. */
35
+ title: string;
36
+ /**
37
+ * `small` (64dp, one line), `medium` or `large` (flexible, wrapping headline). Pass one per
38
+ * breakpoint to adapt to the window, e.g. `{ small: 'small', large: 'large' }`; tiers you
39
+ * leave out inherit from the one below, and below the first given tier the bar is `small`.
40
+ */
41
+ size?: Responsive<AppBarSize>;
42
+ search?: never;
43
+ query?: never;
44
+ searchProps?: never;
45
+ searchTrailing?: never;
46
+ };
47
+ /** A search app bar: a search field in place of the title, always 64dp. */
48
+ export type SearchAppBarProps = AppBarBaseProps & {
49
+ /** Hint text in the search field. Setting it makes this a search app bar. */
50
+ search: string;
51
+ /** The search query. */
52
+ query?: string;
53
+ /** Screen title; rendered for assistive tech only. */
54
+ title?: string;
55
+ /** Props for the search `<input>`, e.g. `onfocus` to open a search view. */
56
+ searchProps?: HTMLInputAttributes;
57
+ /** An action inside the search field, e.g. a mic icon button. */
58
+ searchTrailing?: Snippet;
59
+ size?: never;
60
+ };
61
+ /**
62
+ * Props for the AppBar component.
63
+ */
64
+ export type AppBarProps = TitleAppBarProps | SearchAppBarProps;
65
+ export {};
@@ -5,6 +5,7 @@
5
5
 
6
6
  const { Story } = defineMeta({
7
7
  title: 'Navigation/Breadcrumb',
8
+ tags: ['autodocs'],
8
9
  component: Breadcrumb,
9
10
  argTypes: {
10
11
  color: { control: 'select', options: ['primary', 'secondary', 'tertiary', 'surface'] }