@noxlovette/material 0.5.0 → 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 (316) 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 +60 -0
  8. package/dist/animation/Shapes.stories.svelte.d.ts +3 -0
  9. package/dist/animation/TransitionPatterns.stories.svelte +32 -20
  10. package/dist/animation/containerTransform.d.ts +11 -0
  11. package/dist/animation/containerTransform.js +11 -0
  12. package/dist/animation/enterExit.d.ts +9 -0
  13. package/dist/animation/enterExit.js +6 -3
  14. package/dist/animation/index.d.ts +1 -0
  15. package/dist/animation/index.js +1 -0
  16. package/dist/animation/shapeMorph.svelte.d.ts +52 -0
  17. package/dist/animation/shapeMorph.svelte.js +112 -0
  18. package/dist/animation/shapesAnimatableSmall.d.ts +28 -22
  19. package/dist/animation/shapesAnimatableSmall.js +32 -23
  20. package/dist/animation/sharedAxisTransition.d.ts +22 -0
  21. package/dist/animation/sharedAxisTransition.js +25 -1
  22. package/dist/animation/skeleton.d.ts +6 -1
  23. package/dist/animation/skeleton.js +6 -1
  24. package/dist/components/badge/Badge.mdx +70 -0
  25. package/dist/components/badge/Badge.stories.svelte +38 -20
  26. package/dist/components/badge/Badge.svelte +12 -5
  27. package/dist/components/badge/theme.d.ts +30 -7
  28. package/dist/components/badge/theme.js +24 -4
  29. package/dist/components/badge/types.d.ts +18 -4
  30. package/dist/components/buttons/Button.mdx +85 -0
  31. package/dist/components/buttons/Button.stories.svelte +62 -27
  32. package/dist/components/buttons/Button.svelte +29 -25
  33. package/dist/components/buttons/Button.svelte.d.ts +11 -9
  34. package/dist/components/buttons/ButtonIcon.mdx +52 -0
  35. package/dist/components/buttons/ButtonIcon.stories.svelte +72 -48
  36. package/dist/components/buttons/ButtonIcon.svelte +58 -36
  37. package/dist/components/buttons/ButtonIcon.svelte.d.ts +9 -7
  38. package/dist/components/buttons/FAB.mdx +84 -0
  39. package/dist/components/buttons/FAB.stories.svelte +103 -24
  40. package/dist/components/buttons/FAB.stories.svelte.d.ts +2 -17
  41. package/dist/components/buttons/FAB.svelte +353 -29
  42. package/dist/components/buttons/FAB.svelte.d.ts +11 -6
  43. package/dist/components/buttons/FABMenu.svelte +27 -8
  44. package/dist/components/buttons/FABMenu.svelte.d.ts +7 -3
  45. package/dist/components/buttons/FABMenuItem.svelte +20 -16
  46. package/dist/components/buttons/FABMenuItem.svelte.d.ts +3 -3
  47. package/dist/components/buttons/Toggle.stories.svelte +31 -23
  48. package/dist/components/buttons/Toggle.stories.svelte.d.ts +2 -17
  49. package/dist/components/buttons/Toggle.svelte +28 -25
  50. package/dist/components/buttons/Toggle.svelte.d.ts +5 -5
  51. package/dist/components/buttons/button-group/ButtonGroup.mdx +39 -0
  52. package/dist/components/buttons/button-group/ButtonGroup.stories.svelte +62 -43
  53. package/dist/components/buttons/button-group/ButtonGroup.stories.svelte.d.ts +2 -17
  54. package/dist/components/buttons/button-group/ButtonGroup.svelte +102 -8
  55. package/dist/components/buttons/button-group/ButtonGroup.svelte.d.ts +6 -7
  56. package/dist/components/buttons/button-group/theme.d.ts +45 -15
  57. package/dist/components/buttons/button-group/theme.js +13 -8
  58. package/dist/components/buttons/button-group/types.d.ts +13 -7
  59. package/dist/components/buttons/connected/ConnectedButtonGroup.mdx +43 -0
  60. package/dist/components/buttons/connected/ConnectedButtonGroup.stories.svelte +56 -74
  61. package/dist/components/buttons/connected/ConnectedButtonGroup.stories.svelte.d.ts +2 -17
  62. package/dist/components/buttons/connected/ConnectedButtonGroup.svelte +16 -4
  63. package/dist/components/buttons/connected/ConnectedButtonGroup.svelte.d.ts +4 -4
  64. package/dist/components/buttons/connected/ConnectedButtonGroupItem.svelte +35 -8
  65. package/dist/components/buttons/connected/ConnectedButtonGroupItem.svelte.d.ts +2 -3
  66. package/dist/components/buttons/connected/theme.d.ts +33 -18
  67. package/dist/components/buttons/connected/theme.js +32 -9
  68. package/dist/components/buttons/connected/types.d.ts +36 -9
  69. package/dist/components/buttons/shapeMorph.d.ts +26 -0
  70. package/dist/components/buttons/shapeMorph.js +142 -0
  71. package/dist/components/buttons/split-button/SplitButton.mdx +48 -0
  72. package/dist/components/buttons/split-button/SplitButton.stories.svelte +9 -14
  73. package/dist/components/buttons/split-button/SplitButton.svelte +65 -48
  74. package/dist/components/buttons/split-button/SplitButton.svelte.d.ts +6 -11
  75. package/dist/components/buttons/split-button/theme.d.ts +110 -17
  76. package/dist/components/buttons/split-button/theme.js +74 -16
  77. package/dist/components/buttons/split-button/types.d.ts +24 -18
  78. package/dist/components/buttons/theme.d.ts +422 -230
  79. package/dist/components/buttons/theme.js +286 -380
  80. package/dist/components/buttons/types.d.ts +130 -125
  81. package/dist/components/cards/Card.mdx +44 -0
  82. package/dist/components/cards/Card.stories.svelte +11 -11
  83. package/dist/components/cards/theme.js +5 -5
  84. package/dist/components/chips/Chip.mdx +68 -0
  85. package/dist/components/chips/Chip.stories.svelte +4 -4
  86. package/dist/components/chips/theme.js +3 -3
  87. package/dist/components/containers/action-rail/ActionRail.stories.svelte +1 -0
  88. package/dist/components/containers/action-rail/theme.js +1 -1
  89. package/dist/components/containers/bottom-sheet/BottomSheet.mdx +64 -0
  90. package/dist/components/containers/bottom-sheet/BottomSheet.stories.svelte +108 -12
  91. package/dist/components/containers/bottom-sheet/BottomSheet.svelte +179 -109
  92. package/dist/components/containers/bottom-sheet/BottomSheet.svelte.d.ts +10 -5
  93. package/dist/components/containers/bottom-sheet/index.d.ts +1 -0
  94. package/dist/components/containers/bottom-sheet/index.js +1 -0
  95. package/dist/components/containers/bottom-sheet/theme.d.ts +45 -0
  96. package/dist/components/containers/bottom-sheet/theme.js +42 -0
  97. package/dist/components/containers/bottom-sheet/types.d.ts +37 -5
  98. package/dist/components/containers/carousel/Carousel.mdx +80 -0
  99. package/dist/components/containers/carousel/Carousel.stories.svelte +131 -0
  100. package/dist/components/containers/carousel/Carousel.stories.svelte.d.ts +4 -0
  101. package/dist/components/containers/carousel/Carousel.svelte +194 -0
  102. package/dist/components/containers/carousel/Carousel.svelte.d.ts +25 -0
  103. package/dist/components/containers/carousel/index.d.ts +3 -0
  104. package/dist/components/containers/{stack → carousel}/index.js +1 -2
  105. package/dist/components/containers/carousel/keylines.d.ts +32 -0
  106. package/dist/components/containers/carousel/keylines.js +88 -0
  107. package/dist/components/containers/carousel/theme.d.ts +162 -0
  108. package/dist/components/containers/carousel/theme.js +67 -0
  109. package/dist/components/containers/carousel/types.d.ts +52 -0
  110. package/dist/components/containers/context-menu/ContextMenu.stories.svelte +1 -0
  111. package/dist/components/containers/context-menu/ContextMenu.svelte +2 -2
  112. package/dist/components/containers/context-menu/ContextMenu.svelte.d.ts +1 -1
  113. package/dist/components/containers/context-menu/theme.js +10 -10
  114. package/dist/components/containers/dialogue/Dialogue.mdx +65 -0
  115. package/dist/components/containers/dialogue/Dialogue.stories.svelte +4 -4
  116. package/dist/components/containers/dialogue/Dialogue.svelte +1 -1
  117. package/dist/components/containers/dialogue/theme.js +3 -3
  118. package/dist/components/containers/divider/Divider.stories.svelte +2 -1
  119. package/dist/components/containers/divider/Divider.svelte +2 -2
  120. package/dist/components/containers/divider/theme.d.ts +6 -6
  121. package/dist/components/containers/divider/theme.js +2 -2
  122. package/dist/components/containers/index.d.ts +1 -1
  123. package/dist/components/containers/index.js +1 -1
  124. package/dist/components/containers/link-preview/theme.js +2 -2
  125. package/dist/components/containers/list/List.svelte +18 -0
  126. package/dist/components/containers/list/List.svelte.d.ts +4 -0
  127. package/dist/components/containers/list/ListItem.mdx +100 -0
  128. package/dist/components/containers/list/ListItem.stories.svelte +177 -42
  129. package/dist/components/containers/list/ListItem.stories.svelte.d.ts +2 -17
  130. package/dist/components/containers/list/ListItem.svelte +92 -37
  131. package/dist/components/containers/list/ListItem.svelte.d.ts +1 -1
  132. package/dist/components/containers/list/context.d.ts +6 -0
  133. package/dist/components/containers/list/context.js +4 -0
  134. package/dist/components/containers/list/index.d.ts +1 -0
  135. package/dist/components/containers/list/index.js +1 -0
  136. package/dist/components/containers/list/theme.d.ts +487 -12
  137. package/dist/components/containers/list/theme.js +140 -13
  138. package/dist/components/containers/list/types.d.ts +39 -5
  139. package/dist/components/containers/menu/Menu.mdx +52 -0
  140. package/dist/components/containers/menu/Menu.stories.svelte +14 -14
  141. package/dist/components/containers/menu/Menu.svelte +1 -1
  142. package/dist/components/containers/menu/MenuGroup.svelte +1 -1
  143. package/dist/components/containers/menu/MenuGroup.svelte.d.ts +1 -1
  144. package/dist/components/containers/menu/menu-item/MenuItem.svelte +1 -1
  145. package/dist/components/containers/menu/theme.js +8 -8
  146. package/dist/components/containers/pane/DraggablePane.stories.svelte +4 -3
  147. package/dist/components/containers/pane/DraggablePane.svelte +2 -2
  148. package/dist/components/containers/pane/Pane.stories.svelte +11 -10
  149. package/dist/components/containers/pane/Pane.svelte +24 -2
  150. package/dist/components/containers/pane/PaneGrid.stories.svelte +19 -18
  151. package/dist/components/containers/pane/PaneGrid.svelte +3 -2
  152. package/dist/components/containers/pane/PaneGrid.svelte.d.ts +2 -1
  153. package/dist/components/containers/pane/PaneHandle.svelte +48 -2
  154. package/dist/components/containers/pane/PaneHandle.svelte.d.ts +4 -0
  155. package/dist/components/containers/pane/resizeStore.svelte.d.ts +10 -1
  156. package/dist/components/containers/pane/resizeStore.svelte.js +13 -2
  157. package/dist/components/containers/pane/theme.js +129 -45
  158. package/dist/components/containers/pane/types.d.ts +3 -2
  159. package/dist/components/containers/popover/Popover.mdx +45 -0
  160. package/dist/components/containers/popover/Popover.stories.svelte +1 -1
  161. package/dist/components/containers/popover/Popover.svelte +1 -1
  162. package/dist/components/containers/popover/theme.js +3 -3
  163. package/dist/components/containers/scroll-area/theme.js +2 -2
  164. package/dist/components/containers/side-sheet/SideSheet.mdx +71 -0
  165. package/dist/components/containers/side-sheet/SideSheet.stories.svelte +113 -17
  166. package/dist/components/containers/side-sheet/SideSheet.svelte +113 -66
  167. package/dist/components/containers/side-sheet/SideSheet.svelte.d.ts +8 -7
  168. package/dist/components/containers/side-sheet/index.d.ts +1 -0
  169. package/dist/components/containers/side-sheet/index.js +1 -0
  170. package/dist/components/containers/side-sheet/theme.d.ts +108 -0
  171. package/dist/components/containers/side-sheet/theme.js +72 -0
  172. package/dist/components/containers/side-sheet/types.d.ts +35 -7
  173. package/dist/components/date/DateField.stories.svelte +4 -3
  174. package/dist/components/date/DateField.svelte +49 -26
  175. package/dist/components/date/DateField.svelte.d.ts +2 -0
  176. package/dist/components/date/DateRangeField.stories.svelte +4 -3
  177. package/dist/components/date/DateRangeField.svelte +54 -31
  178. package/dist/components/date/DateRangeField.svelte.d.ts +2 -0
  179. package/dist/components/date/calendarMotion.d.ts +9 -0
  180. package/dist/components/date/calendarMotion.js +23 -0
  181. package/dist/components/date/theme.d.ts +7 -7
  182. package/dist/components/date/theme.js +34 -30
  183. package/dist/components/forms/checkbox/Checkbox.mdx +35 -0
  184. package/dist/components/forms/checkbox/Checkbox.stories.svelte +2 -2
  185. package/dist/components/forms/checkbox/Checkbox.svelte +1 -1
  186. package/dist/components/forms/checkbox/theme.js +3 -3
  187. package/dist/components/forms/command/Command.stories.svelte +1 -0
  188. package/dist/components/forms/command/theme.js +9 -9
  189. package/dist/components/forms/pin/theme.js +4 -4
  190. package/dist/components/forms/radio-group/RadioGroup.svelte +1 -1
  191. package/dist/components/forms/radio-group/theme.js +5 -5
  192. package/dist/components/forms/search/Search.mdx +38 -0
  193. package/dist/components/forms/search/Search.stories.svelte +19 -9
  194. package/dist/components/forms/search/Search.svelte +40 -17
  195. package/dist/components/forms/search/Search.svelte.d.ts +2 -2
  196. package/dist/components/forms/search/theme.d.ts +45 -12
  197. package/dist/components/forms/search/theme.js +13 -8
  198. package/dist/components/forms/search/types.d.ts +18 -12
  199. package/dist/components/forms/select/Select.mdx +53 -0
  200. package/dist/components/forms/select/Select.stories.svelte +4 -4
  201. package/dist/components/forms/select/Select.svelte +10 -2
  202. package/dist/components/forms/select/SelectItem.svelte +1 -1
  203. package/dist/components/forms/select/theme.js +12 -12
  204. package/dist/components/forms/slider/Slider.mdx +85 -0
  205. package/dist/components/forms/slider/Slider.stories.svelte +7 -7
  206. package/dist/components/forms/slider/Slider.svelte +46 -28
  207. package/dist/components/forms/slider/theme.d.ts +14 -0
  208. package/dist/components/forms/slider/theme.js +28 -17
  209. package/dist/components/forms/slider/types.d.ts +3 -2
  210. package/dist/components/forms/switch/Switch.mdx +38 -0
  211. package/dist/components/forms/switch/Switch.stories.svelte +3 -3
  212. package/dist/components/forms/switch/theme.js +6 -6
  213. package/dist/components/forms/textfield/Textfield.mdx +53 -0
  214. package/dist/components/forms/textfield/Textfield.stories.svelte +6 -6
  215. package/dist/components/forms/textfield/Textfield.svelte +1 -0
  216. package/dist/components/forms/textfield/theme.d.ts +3 -0
  217. package/dist/components/forms/textfield/theme.js +22 -19
  218. package/dist/components/forms/toggle-group/theme.js +2 -2
  219. package/dist/components/forms/tooltip/Tooltip.stories.svelte +1 -0
  220. package/dist/components/forms/tooltip/theme.js +3 -3
  221. package/dist/components/misc/Avatar.stories.svelte +5 -4
  222. package/dist/components/misc/ThemeSettings.svelte +9 -9
  223. package/dist/components/misc/ThemeSwitcher.svelte +3 -3
  224. package/dist/components/misc/theme.js +4 -4
  225. package/dist/components/nav/appbar/AppBar.mdx +71 -0
  226. package/dist/components/nav/appbar/AppBar.stories.svelte +93 -3
  227. package/dist/components/nav/appbar/AppBar.stories.svelte.d.ts +2 -17
  228. package/dist/components/nav/appbar/AppBar.svelte +90 -37
  229. package/dist/components/nav/appbar/AppBar.svelte.d.ts +9 -2
  230. package/dist/components/nav/appbar/theme.d.ts +85 -18
  231. package/dist/components/nav/appbar/theme.js +159 -23
  232. package/dist/components/nav/appbar/types.d.ts +46 -9
  233. package/dist/components/nav/breadcrumb/Breadcrumb.stories.svelte +1 -0
  234. package/dist/components/nav/breadcrumb/theme.js +5 -5
  235. package/dist/components/nav/navbar/Navbar.mdx +38 -0
  236. package/dist/components/nav/navbar/Navbar.svelte +1 -1
  237. package/dist/components/nav/navbar/NavbarItem.svelte +12 -9
  238. package/dist/components/nav/navbar/theme.js +6 -6
  239. package/dist/components/nav/rail/Rail.mdx +73 -0
  240. package/dist/components/nav/rail/Rail.stories.svelte +3 -7
  241. package/dist/components/nav/rail/Rail.svelte +1 -0
  242. package/dist/components/nav/rail/RailItem.svelte +12 -9
  243. package/dist/components/nav/rail/theme.js +13 -13
  244. package/dist/components/nav/rail/types.d.ts +4 -1
  245. package/dist/components/nav/tabs/TabHolder.svelte +29 -3
  246. package/dist/components/nav/tabs/TabHolder.svelte.d.ts +3 -1
  247. package/dist/components/nav/tabs/Tabs.mdx +62 -0
  248. package/dist/components/nav/tabs/Tabs.stories.svelte +1 -1
  249. package/dist/components/nav/tabs/theme.js +4 -4
  250. package/dist/components/pill/Pill.mdx +32 -0
  251. package/dist/components/pill/Pill.stories.svelte +1 -1
  252. package/dist/components/pill/theme.d.ts +1 -1
  253. package/dist/components/pill/theme.js +1 -1
  254. package/dist/components/progress/LinearProgress.svelte +1 -1
  255. package/dist/components/progress/Progress.mdx +50 -0
  256. package/dist/components/progress/Progress.stories.svelte +6 -6
  257. package/dist/components/snackbar/Snackbar.mdx +52 -0
  258. package/dist/components/snackbar/Snackbar.stories.svelte +5 -5
  259. package/dist/components/snackbar/Snackbar.svelte +1 -1
  260. package/dist/components/snackbar/theme.d.ts +3 -3
  261. package/dist/components/snackbar/theme.js +4 -4
  262. package/dist/components/table/Table.stories.svelte +1 -0
  263. package/dist/components/table/TableHeader.svelte +1 -1
  264. package/dist/components/table/theme.js +3 -3
  265. package/dist/components/time/TimeField.stories.svelte +3 -2
  266. package/dist/components/time/TimeField.svelte +14 -8
  267. package/dist/components/time/TimeField.svelte.d.ts +6 -0
  268. package/dist/components/time/TimepickerInput.svelte +9 -5
  269. package/dist/components/time/theme.js +5 -5
  270. package/dist/components/time/types.d.ts +11 -1
  271. package/dist/components/toolbar/Toolbar.stories.svelte +1 -0
  272. package/dist/components/toolbar/Toolbar.svelte +1 -1
  273. package/dist/components/toolbar/Toolbar.svelte.d.ts +1 -1
  274. package/dist/components/toolbar/theme.js +14 -14
  275. package/dist/components/typography/Typography.mdx +67 -0
  276. package/dist/components/typography/body/Body.stories.svelte +2 -1
  277. package/dist/components/typography/body/theme.d.ts +15 -12
  278. package/dist/components/typography/body/theme.js +19 -4
  279. package/dist/components/typography/body/types.d.ts +2 -1
  280. package/dist/components/typography/display/Display.stories.svelte +2 -1
  281. package/dist/components/typography/display/theme.d.ts +15 -12
  282. package/dist/components/typography/display/theme.js +19 -4
  283. package/dist/components/typography/display/types.d.ts +2 -1
  284. package/dist/components/typography/headline/Headline.stories.svelte +2 -1
  285. package/dist/components/typography/headline/theme.d.ts +15 -12
  286. package/dist/components/typography/headline/theme.js +19 -4
  287. package/dist/components/typography/headline/types.d.ts +2 -1
  288. package/dist/components/typography/kbd/Kbd.stories.svelte +2 -1
  289. package/dist/components/typography/kbd/theme.d.ts +4 -4
  290. package/dist/components/typography/kbd/theme.js +2 -2
  291. package/dist/components/typography/label/Label.stories.svelte +2 -1
  292. package/dist/components/typography/label/theme.d.ts +15 -12
  293. package/dist/components/typography/label/theme.js +19 -4
  294. package/dist/components/typography/label/types.d.ts +2 -1
  295. package/dist/components/typography/title/Title.stories.svelte +2 -1
  296. package/dist/components/typography/title/theme.d.ts +15 -12
  297. package/dist/components/typography/title/theme.js +19 -4
  298. package/dist/components/typography/title/types.d.ts +2 -1
  299. package/dist/index.css +1 -0
  300. package/dist/styles/component.css +78 -175
  301. package/dist/styles/elevation.css +9 -0
  302. package/dist/styles/spacing.css +29 -0
  303. package/dist/styles/typescale.css +635 -20
  304. package/dist/utils/Layer.svelte +1 -1
  305. package/dist/utils/icon/Icon.svelte +8 -6
  306. package/dist/utils/icon/loadingShapes.js +11 -10
  307. package/package.json +19 -15
  308. package/dist/components/containers/stack/HStack.svelte +0 -23
  309. package/dist/components/containers/stack/HStack.svelte.d.ts +0 -5
  310. package/dist/components/containers/stack/VStack.svelte +0 -23
  311. package/dist/components/containers/stack/VStack.svelte.d.ts +0 -5
  312. package/dist/components/containers/stack/index.d.ts +0 -4
  313. package/dist/components/containers/stack/theme.d.ts +0 -66
  314. package/dist/components/containers/stack/theme.js +0 -26
  315. package/dist/components/containers/stack/types.d.ts +0 -12
  316. /package/dist/components/containers/{stack → carousel}/types.js +0 -0
@@ -2,10 +2,10 @@ import { tv } from 'tailwind-variants';
2
2
  export const dateRangeField = tv({
3
3
  slots: {
4
4
  base: `
5
- group w-full h-14 relative flex items-center
5
+ group w-full h-spacing-700 relative flex items-center
6
6
  `,
7
7
  inputWrapper: `
8
- relative flex-1 px-4 h-full flex items-center
8
+ relative flex-1 px-spacing-200 h-full flex items-center
9
9
  `,
10
10
  input: `
11
11
  bg-transparent outline-none flex items-center
@@ -13,19 +13,19 @@ export const dateRangeField = tv({
13
13
  disabled:text-md-sys-color-on-surface/38 w-full
14
14
  `,
15
15
  leadingIcon: `
16
- text-md-sys-color-on-surface-variant size-6
16
+ text-md-sys-color-on-surface-variant size-spacing-300
17
17
  group-focus-within:text-md-sys-color-primary
18
- group-data-[invalid]:text-md-sys-color-error ml-3 text-[24px]
18
+ group-data-[invalid]:text-md-sys-color-error ml-spacing-150 text-[24px]
19
19
  `,
20
20
  trailingIcon: `
21
- mr-1 shrink-0 text-md-sys-color-on-surface-variant
21
+ mr-spacing-50 shrink-0 text-md-sys-color-on-surface-variant
22
22
  group-data-[invalid]:text-md-sys-color-error
23
23
  `,
24
24
  separator: `
25
25
  text-md-sys-color-on-surface-variant select-none shrink-0
26
26
  `,
27
27
  label: `
28
- absolute left-4 top-1.5
28
+ absolute left-spacing-200 top-spacing-75
29
29
  md-sys-typescale-body-small
30
30
  text-md-sys-color-on-surface-variant
31
31
  pointer-events-none
@@ -34,13 +34,13 @@ export const dateRangeField = tv({
34
34
  z-20
35
35
  `,
36
36
  requiredAsterisk: `
37
- ml-0.5
37
+ ml-spacing-25
38
38
  text-md-sys-color-error
39
39
  group-focus-within:text-md-sys-color-primary
40
40
  transition-colors md-sys-motion-effects
41
41
  `,
42
42
  supportingText: `
43
- px-4 pt-1 flex justify-between
43
+ px-spacing-200 pt-spacing-50 flex justify-between
44
44
  md-sys-typescale-body-small
45
45
  text-md-sys-color-on-surface-variant
46
46
  `
@@ -50,7 +50,7 @@ export const dateRangeField = tv({
50
50
  filled: {
51
51
  base: `
52
52
  bg-md-sys-color-surface-container-highest rounded-t-xs
53
- after:absolute after:bottom-0 after:left-0 after:right-0
53
+ after:absolute after:bottom-spacing-0 after:left-spacing-0 after:right-spacing-0
54
54
  state-layer before:rounded-xs hover:before:bg-md-sys-color-on-surface/8
55
55
  after:h-px after:bg-md-sys-color-on-surface-variant
56
56
  after:transition-[height,background-color] after:md-sys-motion-fast-spatial
@@ -108,10 +108,10 @@ export const dateRangeField = tv({
108
108
  export const dateField = tv({
109
109
  slots: {
110
110
  base: `
111
- group w-full h-14 relative flex items-center justify-between
111
+ group w-full h-spacing-700 relative flex items-center justify-between
112
112
  `,
113
113
  inputWrapper: `
114
- relative flex-1 px-4 h-full flex items-center
114
+ relative flex-1 px-spacing-200 h-full flex items-center
115
115
  `,
116
116
  input: `
117
117
  w-full bg-transparent outline-none
@@ -122,16 +122,16 @@ export const dateField = tv({
122
122
  flex w-full flex-col tabular-nums
123
123
  `,
124
124
  leadingIcon: `
125
- text-md-sys-color-on-surface-variant size-6
125
+ text-md-sys-color-on-surface-variant size-spacing-300
126
126
  group-focus-within:text-md-sys-color-primary
127
- group-data-[invalid]:text-md-sys-color-error ml-3 text-[24px]
127
+ group-data-[invalid]:text-md-sys-color-error ml-spacing-150 text-[24px]
128
128
  `,
129
129
  trailingIcon: `
130
- mr-1 shrink-0 text-md-sys-color-on-surface-variant
130
+ mr-spacing-50 shrink-0 text-md-sys-color-on-surface-variant
131
131
  group-data-[invalid]:text-md-sys-color-error
132
132
  `,
133
133
  label: `
134
- absolute left-4 top-1.5
134
+ absolute left-spacing-200 top-spacing-75
135
135
  md-sys-typescale-body-small
136
136
  text-md-sys-color-on-surface-variant
137
137
  pointer-events-none
@@ -140,18 +140,18 @@ export const dateField = tv({
140
140
  z-20
141
141
  `,
142
142
  requiredAsterisk: `
143
- ml-0.5
143
+ ml-spacing-25
144
144
  text-md-sys-color-error
145
145
  group-focus-within:text-md-sys-color-primary
146
146
  transition-colors md-sys-motion-effects
147
147
  `,
148
148
  supportingText: `
149
- px-4 pt-1 flex justify-between
149
+ px-spacing-200 pt-spacing-50 flex justify-between
150
150
  md-sys-typescale-body-small
151
151
  text-md-sys-color-on-surface-variant
152
152
  `,
153
153
  fieldset: `
154
- absolute -top-[5px] left-0 right-0 bottom-0 m-0 px-2
154
+ absolute -top-[5px] left-spacing-0 right-spacing-0 bottom-spacing-0 m-spacing-0 px-spacing-100
155
155
  pointer-events-none rounded-xs border border-md-sys-color-outline
156
156
  transition-colors md-sys-motion-fast-effects
157
157
 
@@ -163,7 +163,7 @@ export const dateField = tv({
163
163
  whitespace-nowrap md-sys-typescale-body-small
164
164
  `,
165
165
  legendLabel: `
166
- px-1
166
+ px-spacing-50
167
167
  `
168
168
  },
169
169
  variants: {
@@ -171,7 +171,7 @@ export const dateField = tv({
171
171
  filled: {
172
172
  base: `
173
173
  bg-md-sys-color-surface-container-highest rounded-t-xs
174
- after:absolute after:bottom-0 after:left-0 after:right-0
174
+ after:absolute after:bottom-spacing-0 after:left-spacing-0 after:right-spacing-0
175
175
  state-layer before:rounded-xs hover:before:bg-md-sys-color-on-surface/8
176
176
  after:h-px after:bg-md-sys-color-on-surface-variant
177
177
  after:transition-[height,background-color] after:md-sys-motion-fast-spatial
@@ -180,11 +180,11 @@ export const dateField = tv({
180
180
  disabled:bg-md-sys-color-on-surface/4
181
181
  disabled:after:bg-md-sys-color-on-surface/12
182
182
  `,
183
- segments: 'pt-4'
183
+ segments: 'pt-spacing-200'
184
184
  },
185
185
  outlined: {
186
186
  label: `
187
- top-0 -translate-y-1/2
187
+ top-spacing-0 -translate-y-1/2
188
188
  `
189
189
  }
190
190
  },
@@ -217,12 +217,12 @@ export const dateField = tv({
217
217
  /** Segments of the typed date (`DatePicker.Segment` / `DateRangePicker.Segment`). */
218
218
  export const dateSegment = tv({
219
219
  base: `
220
- rounded-xs px-0.5 py-0.5 select-none cursor-default outline-none
220
+ rounded-xs px-spacing-25 py-spacing-25 select-none cursor-default outline-none
221
221
  transition-colors md-sys-motion-fast-effects
222
222
  `,
223
223
  variants: {
224
224
  part: {
225
- literal: 'text-md-sys-color-on-surface-variant px-0',
225
+ literal: 'text-md-sys-color-on-surface-variant px-spacing-0',
226
226
  value: `
227
227
  text-md-sys-color-on-surface
228
228
  aria-[valuetext=Empty]:text-md-sys-color-on-surface-variant
@@ -243,12 +243,12 @@ export const dateSegment = tv({
243
243
  export const dateCalendar = tv({
244
244
  slots: {
245
245
  surface: `
246
- w-90 rounded-lg px-3 pb-3
246
+ w-90 rounded-lg px-spacing-150 pb-spacing-150
247
247
  bg-md-sys-color-surface-container-high shadow-elevation-3
248
248
  text-md-sys-color-on-surface
249
249
  `,
250
250
  header: `
251
- flex h-14 items-center justify-between pl-4 pr-1
251
+ flex h-spacing-700 items-center justify-between pl-spacing-200 pr-spacing-50
252
252
  `,
253
253
  heading: `
254
254
  md-sys-typescale-label-large text-md-sys-color-on-surface-variant
@@ -263,21 +263,25 @@ export const dateCalendar = tv({
263
263
  flex w-full
264
264
  `,
265
265
  weekday: `
266
- flex size-12 items-center justify-center
266
+ flex size-spacing-600 items-center justify-center
267
267
  md-sys-typescale-body-large text-md-sys-color-on-surface
268
268
  `,
269
+ /* The range band runs behind every day in the range. On the endpoints it covers only the inner
270
+ half, so it meets the selected circle instead of sticking out past it. A one-day range has
271
+ no band. */
269
272
  cell: `
270
- relative flex size-12 items-center justify-center p-0
271
- before:absolute before:inset-x-0 before:h-10 before:bg-md-sys-color-secondary-container
273
+ relative flex size-spacing-600 items-center justify-center p-spacing-0
274
+ before:absolute before:inset-x-spacing-0 before:h-spacing-500 before:bg-md-sys-color-secondary-container
272
275
  before:opacity-0 before:transition-opacity before:md-sys-motion-fast-effects
273
276
  data-range-middle:before:opacity-100
274
277
  data-highlighted:before:opacity-100
278
+ data-range-start:before:opacity-100 data-range-end:before:opacity-100
275
279
  data-range-start:before:left-1/2 data-range-end:before:right-1/2
276
280
  data-range-start:data-range-end:before:opacity-0
277
281
  data-outside-month:before:opacity-0
278
282
  `,
279
283
  day: `
280
- relative flex size-10 items-center justify-center rounded-full
284
+ relative flex size-spacing-500 items-center justify-center rounded-full
281
285
  md-sys-typescale-body-large text-md-sys-color-on-surface
282
286
  cursor-pointer outline-none
283
287
  transition-colors md-sys-motion-fast-effects
@@ -0,0 +1,35 @@
1
+ import { Meta, Title, Subtitle, Canvas, Controls } from '@storybook/addon-docs/blocks';
2
+ import * as CheckboxStories from './Checkbox.stories.svelte';
3
+
4
+ <Meta of={CheckboxStories} />
5
+
6
+ <Title />
7
+
8
+ <Subtitle>
9
+ Checkboxes let users select one or more items from a list, or turn a single item on or off.
10
+ </Subtitle>
11
+
12
+ [M3 spec](https://m3.material.io/components/checkbox/specs) ·
13
+ `import { Checkbox } from '@noxlovette/material';`
14
+
15
+ <Canvas of={CheckboxStories.Playground} />
16
+
17
+ <Controls of={CheckboxStories.Playground} />
18
+
19
+ ## States
20
+
21
+ Bind `checked` for the value. Bind `indeterminate` for a "select all" checkbox whose list is
22
+ only partly selected; it wins over `checked` while set. `error` marks the control invalid.
23
+
24
+ ```svelte
25
+ <Checkbox labelText="Accept terms and conditions" bind:checked={accepted} />
26
+ ```
27
+
28
+ <Canvas of={CheckboxStories.States} />
29
+
30
+ ## Accessibility
31
+
32
+ - **Label.** `labelText` is required and tied to the control by id, so clicking the text toggles
33
+ the checkbox too.
34
+ - **Target size.** The state layer extends the target well past the 18dp box, to 48dp.
35
+ - **Keyboard.** Space toggles; focus draws the M3 focus indicator.
@@ -24,14 +24,14 @@
24
24
 
25
25
  <Story name="Playground">
26
26
  {#snippet template(args)}
27
- <div class="p-6">
27
+ <div class="p-spacing-300">
28
28
  <Checkbox {...args} />
29
29
  </div>
30
30
  {/snippet}
31
31
  </Story>
32
32
 
33
33
  <Story name="States" asChild>
34
- <div class="flex flex-col gap-4 p-6">
34
+ <div class="gap-spacing-200 p-spacing-300 flex flex-col">
35
35
  <Checkbox labelText="Unchecked" checked={false} />
36
36
  <Checkbox labelText="Checked" checked={true} />
37
37
  <Checkbox labelText="Indeterminate" indeterminate={true} />
@@ -28,7 +28,7 @@ Checkboxes let users select one or more items from a list, or turn an item on or
28
28
  const cls = $derived(checkbox({ state, error, disabled }));
29
29
  </script>
30
30
 
31
- <div class="flex cursor-pointer items-center space-x-3">
31
+ <div class="space-x-spacing-150 flex cursor-pointer items-center">
32
32
  <Checkbox.Root
33
33
  bind:checked
34
34
  bind:indeterminate
@@ -1,12 +1,12 @@
1
1
  import { tv } from 'tailwind-variants';
2
2
  export const checkbox = tv({
3
3
  slots: {
4
- root: 'group inline-flex min-h-10 select-none items-start gap-3 text-md-sys-color-on-surface min-h-4.5 cursor-pointer',
4
+ root: 'group inline-flex min-h-spacing-500 select-none items-start gap-spacing-150 text-md-sys-color-on-surface min-h-4.5 cursor-pointer',
5
5
  container: 'relative inline-flex size-[18px] shrink-0',
6
6
  control: 'layer-container absolute -inset-[11px] rounded-full text-md-sys-color-on-surface-variant state-layer before:rounded-full group-focus-visible:outline group-focus-visible:outline-3 group-focus-visible:outline-offset-2 group-focus-visible:outline-md-sys-color-secondary transition-colors md-sys-motion-fast-effects',
7
7
  box: 'absolute inset-[11px] rounded-[4px] border-2 border-current bg-md-sys-color-surface transition-colors md-sys-motion-fast-effects',
8
- checkIcon: 'pointer-events-none absolute inset-0 m-auto size-3.5 text-md-sys-color-on-primary opacity-0 scale-75',
9
- indeterminateIcon: 'pointer-events-none absolute inset-0 m-auto block h-0.5 w-3 rounded-full bg-md-sys-color-on-primary opacity-0 scale-75',
8
+ checkIcon: 'pointer-events-none absolute inset-spacing-0 m-auto size-spacing-175 text-md-sys-color-on-primary opacity-0 scale-75',
9
+ indeterminateIcon: 'pointer-events-none absolute inset-spacing-0 m-auto block h-spacing-25 w-spacing-150 rounded-full bg-md-sys-color-on-primary opacity-0 scale-75',
10
10
  label: 'md-sys-typescale-body-large leading-5 text-md-sys-color-on-surface cursor-pointer'
11
11
  },
12
12
  variants: {
@@ -14,6 +14,7 @@
14
14
 
15
15
  const { Story } = defineMeta({
16
16
  title: 'Forms/Command',
17
+ tags: ['autodocs'],
17
18
  component: Command
18
19
  });
19
20
  </script>
@@ -2,14 +2,14 @@ import { tv } from 'tailwind-variants';
2
2
  export const command = tv({
3
3
  slots: {
4
4
  base: 'flex h-full w-full flex-col overflow-hidden rounded-2xl bg-md-sys-color-surface-container-high text-md-sys-color-on-surface shadow-elevation-3 ring-1 ring-md-sys-color-outline/20',
5
- inputWrapper: 'flex items-center border-b border-md-sys-color-outline-variant px-4',
6
- inputIcon: 'mr-3 h-5 w-5 shrink-0 text-md-sys-color-on-surface-variant',
7
- input: 'flex h-12 w-full rounded-md bg-transparent py-3 md-sys-typescale-body-large outline-none placeholder:text-md-sys-color-on-surface-variant disabled:cursor-not-allowed disabled:opacity-50',
8
- list: 'max-h-[300px] overflow-y-auto overflow-x-hidden p-2 scrollbar-thin scrollbar-thumb-md-sys-color-outline-variant scrollbar-track-transparent',
9
- empty: 'py-6 text-center md-sys-typescale-body-medium text-md-sys-color-on-surface-variant',
10
- group: 'overflow-hidden p-1 text-md-sys-color-on-surface-variant [&_[data-command-group-heading]]:px-3 [&_[data-command-group-heading]]:py-2 [&_[data-command-group-heading]]:md-sys-typescale-label-medium [&_[data-command-group-heading]]:text-md-sys-color-on-surface-variant',
11
- separator: '-mx-1 h-px bg-md-sys-color-outline-variant',
12
- item: 'relative flex cursor-default select-none items-center rounded-lg px-3 py-3 md-sys-typescale-body-medium outline-none data-[selected=true]:bg-md-sys-color-secondary-container data-[selected=true]:text-md-sys-color-on-secondary-container data-[disabled=true]:cursor-not-allowed data-[disabled=true]:opacity-50 transition-colors md-sys-motion-fast-effects',
13
- itemIcon: 'mr-3 h-5 w-5 shrink-0'
5
+ inputWrapper: 'flex items-center border-b border-md-sys-color-outline-variant px-spacing-200',
6
+ inputIcon: 'mr-spacing-150 h-spacing-250 w-spacing-250 shrink-0 text-md-sys-color-on-surface-variant',
7
+ input: 'flex h-spacing-600 w-full rounded-md bg-transparent py-spacing-150 md-sys-typescale-body-large outline-none placeholder:text-md-sys-color-on-surface-variant disabled:cursor-not-allowed disabled:opacity-50',
8
+ list: 'max-h-[300px] overflow-y-auto overflow-x-hidden p-spacing-100 scrollbar-thin scrollbar-thumb-md-sys-color-outline-variant scrollbar-track-transparent',
9
+ empty: 'py-spacing-300 text-center md-sys-typescale-body-medium text-md-sys-color-on-surface-variant',
10
+ group: 'overflow-hidden p-spacing-50 text-md-sys-color-on-surface-variant [&_[data-command-group-heading]]:px-spacing-150 [&_[data-command-group-heading]]:py-spacing-100 [&_[data-command-group-heading]]:md-sys-typescale-label-medium [&_[data-command-group-heading]]:text-md-sys-color-on-surface-variant',
11
+ separator: '-mx-spacing-50 h-px bg-md-sys-color-outline-variant',
12
+ item: 'relative flex cursor-default select-none items-center rounded-lg px-spacing-150 py-spacing-150 md-sys-typescale-body-medium outline-none data-[selected=true]:bg-md-sys-color-secondary-container data-[selected=true]:text-md-sys-color-on-secondary-container data-[disabled=true]:cursor-not-allowed data-[disabled=true]:opacity-50 transition-colors md-sys-motion-fast-effects',
13
+ itemIcon: 'mr-spacing-150 h-spacing-250 w-spacing-250 shrink-0'
14
14
  }
15
15
  });
@@ -1,15 +1,15 @@
1
1
  import { tv } from 'tailwind-variants';
2
2
  export const pinInput = tv({
3
3
  slots: {
4
- root: 'flex flex-col gap-2',
4
+ root: 'flex flex-col gap-spacing-100',
5
5
  label: 'md-sys-typescale-label-large text-md-sys-color-on-surface-variant',
6
- container: 'flex items-center gap-2',
6
+ container: 'flex items-center gap-spacing-100',
7
7
  cell: `
8
- relative flex h-14 w-12 items-center justify-center
8
+ relative flex h-spacing-700 w-spacing-600 items-center justify-center
9
9
  bg-md-sys-color-surface-container-highest rounded-t-xs
10
10
  md-sys-typescale-headline-small text-md-sys-color-on-surface
11
11
  transition-colors md-sys-motion-fast-effects
12
- after:absolute after:bottom-0 after:left-0 after:right-0 after:h-px after:bg-md-sys-color-on-surface-variant
12
+ after:absolute after:bottom-spacing-0 after:left-spacing-0 after:right-spacing-0 after:h-px after:bg-md-sys-color-on-surface-variant
13
13
  after:transition-[height,background-color] after:md-sys-motion-fast-spatial
14
14
  data-[focus]:after:bg-md-sys-color-primary data-[focus]:after:h-[2px]
15
15
  data-[placeholder]:text-md-sys-color-on-surface-variant/38
@@ -49,7 +49,7 @@ Radio buttons let users select one option from a set.
49
49
  <div class={itemCls.outerRing()}></div>
50
50
  <div class={itemCls.innerDot()}></div>
51
51
  </div>
52
- <div class="flex flex-col gap-0.5 text-left">
52
+ <div class="gap-spacing-25 flex flex-col text-left">
53
53
  <span class={itemCls.label()}>{item.label}</span>
54
54
  {#if item.supportingText}
55
55
  <span class={itemCls.supporting()}>{item.supportingText}</span>
@@ -2,18 +2,18 @@ import { tv } from 'tailwind-variants';
2
2
  export const radioGroup = tv({
3
3
  slots: {
4
4
  root: 'flex',
5
- item: 'inline-flex min-h-10 cursor-pointer select-none items-center gap-3 text-md-sys-color-on-surface',
5
+ item: 'inline-flex min-h-spacing-500 cursor-pointer select-none items-center gap-spacing-150 text-md-sys-color-on-surface',
6
6
  indicator: 'relative inline-flex size-[20px] shrink-0',
7
7
  control: 'relative layer-container absolute -inset-[10px] rounded-full text-md-sys-color-on-surface-variant state-layer before:rounded-full',
8
- outerRing: 'absolute inset-0 rounded-full border-2 border-md-sys-color-outline transition-colors md-sys-motion-fast-effects',
9
- innerDot: 'absolute inset-0 m-auto size-2.5 scale-0 rounded-full bg-md-sys-color-on-primary-container transition-transform md-sys-motion-fast-spatial',
8
+ outerRing: 'absolute inset-spacing-0 rounded-full border-2 border-md-sys-color-outline transition-colors md-sys-motion-fast-effects',
9
+ innerDot: 'absolute inset-spacing-0 m-auto size-spacing-125 scale-0 rounded-full bg-md-sys-color-on-primary-container transition-transform md-sys-motion-fast-spatial',
10
10
  label: 'md-sys-typescale-body-large text-md-sys-color-on-surface',
11
11
  supporting: 'md-sys-typescale-body-medium text-md-sys-color-on-surface-variant'
12
12
  },
13
13
  variants: {
14
14
  orientation: {
15
- vertical: { root: 'flex-col gap-1' },
16
- horizontal: { root: 'flex-row flex-wrap gap-6' }
15
+ vertical: { root: 'flex-col gap-spacing-50' },
16
+ horizontal: { root: 'flex-row flex-wrap gap-spacing-300' }
17
17
  },
18
18
  checked: {
19
19
  true: {
@@ -0,0 +1,38 @@
1
+ import { Meta, Title, Subtitle, Canvas, Controls } from '@storybook/addon-docs/blocks';
2
+ import * as SearchStories from './Search.stories.svelte';
3
+
4
+ <Meta of={SearchStories} />
5
+
6
+ <Title />
7
+
8
+ <Subtitle>The search bar lets users enter a query to find information in an app.</Subtitle>
9
+
10
+ [M3 spec](https://m3.material.io/components/search/specs) ·
11
+ `import { Search } from '@noxlovette/material';`
12
+
13
+ <Canvas of={SearchStories.Playground} />
14
+
15
+ <Controls of={SearchStories.Playground} />
16
+
17
+ ## Search bar, not search view
18
+
19
+ This is M3's search bar: a 56dp, fully rounded `surface-container-high` field with a leading
20
+ search icon. It's a different thing from the full-screen search view, and from a filled text
21
+ field. Once there's a value, a clear button appears at the end. Other native `<input>` attributes
22
+ pass straight through to the input.
23
+
24
+ ```svelte
25
+ <Search placeholder="Search" bind:value={query} />
26
+ ```
27
+
28
+ <Canvas of={SearchStories.WithActions} />
29
+
30
+ For a search field inside a top app bar, use `AppBar`'s `search` prop instead.
31
+
32
+ ## Accessibility
33
+
34
+ - **Label.** The `type="search"` input sits inside a `<label>` with its own id, so the whole bar
35
+ is a target and several bars can share a page.
36
+ - **Clear button.** A 48dp `type="button"` labelled by `clearLabel` (default "Clear search"). It
37
+ never submits a form and returns focus to the input.
38
+ - **Focus.** Keyboard focus draws the M3 focus indicator around the bar.
@@ -1,6 +1,7 @@
1
1
  <script module lang="ts">
2
2
  import { defineMeta } from '@storybook/addon-svelte-csf';
3
3
  import Search from './Search.svelte';
4
+ import ButtonIcon from '../../buttons/ButtonIcon.svelte';
4
5
 
5
6
  const { Story } = defineMeta({
6
7
  title: 'Forms/Search',
@@ -18,24 +19,33 @@
18
19
 
19
20
  <Story name="Playground">
20
21
  {#snippet template(args)}
21
- <div class="max-w-md p-6">
22
+ <div class="p-spacing-300 max-w-md">
22
23
  <Search {...args} />
23
24
  </div>
24
25
  {/snippet}
25
26
  </Story>
26
27
 
27
28
  <Story name="With Value" asChild>
28
- <div class="max-w-md p-6">
29
+ <div class="p-spacing-300 max-w-md">
29
30
  <Search value="Material Design" />
30
31
  </div>
31
32
  </Story>
32
33
 
33
- <Story name="Custom Icons" asChild>
34
- <div class="max-w-md p-6">
35
- <Search
36
- value="query"
37
- leadingIconProps={{ name: 'search' }}
38
- trailingIconProps={{ name: 'mic' }}
39
- />
34
+ <Story name="With actions" asChild>
35
+ <div class="gap-spacing-200 p-spacing-300 flex max-w-md flex-col">
36
+ <Search>
37
+ {#snippet leading()}
38
+ <ButtonIcon variant="standard" iconProps={{ name: 'menu' }} aria-label="Menu" />
39
+ {/snippet}
40
+ {#snippet trailing()}
41
+ <ButtonIcon variant="standard" iconProps={{ name: 'mic' }} aria-label="Voice search" />
42
+ <ButtonIcon
43
+ variant="standard"
44
+ iconProps={{ name: 'account_circle' }}
45
+ aria-label="Account"
46
+ />
47
+ {/snippet}
48
+ </Search>
49
+ <Search value="query" leadingIconProps={null} placeholder="No leading icon" />
40
50
  </div>
41
51
  </Story>
@@ -1,52 +1,75 @@
1
1
  <!--
2
2
  @component
3
- Material 3 Search Bar.
3
+ Material 3 Search Bar (contained, M3 Expressive).
4
4
 
5
5
  Search bars allow users to enter a query to find specific information within an app.
6
6
 
7
- @see https://m3.material.io/components/search/overview
7
+ @see https://m3.material.io/components/search/specs
8
8
  -->
9
9
  <script lang="ts">
10
10
  import { search } from './theme.js';
11
11
  import clsx from 'clsx';
12
12
  import type { SearchProps } from './types.js';
13
13
  import { Icon } from '../../../utils/index.js';
14
+ import ButtonIcon from '../../buttons/ButtonIcon.svelte';
15
+
16
+ const uid = $props.id();
14
17
 
15
18
  let {
16
- children,
17
- placeholder = 'Поиск',
19
+ placeholder = 'Search',
18
20
  value = $bindable(),
19
21
  elementRef = $bindable(),
22
+ leading,
23
+ trailing,
20
24
  trailingIconProps = { name: 'close' },
21
25
  leadingIconProps = { name: 'search' },
26
+ clearLabel = 'Clear search',
22
27
  class: className,
28
+ id = uid,
23
29
  trailingClick = () => {
24
30
  value = '';
31
+ elementRef?.focus();
25
32
  },
26
33
  ...restProps
27
34
  }: SearchProps = $props();
28
35
 
29
- const { base, leadingIcon, trailingIcon, input } = $derived(search());
36
+ const showClear = $derived(!!trailingIconProps && !!value);
37
+
38
+ const s = $derived(
39
+ search({
40
+ hasLeading: !!leading || !!leadingIconProps,
41
+ hasTrailing: !!trailing || showClear
42
+ })
43
+ );
30
44
  </script>
31
45
 
32
- <label for="search" class={base({ class: clsx(className) })}>
33
- {#if leadingIconProps}
34
- <Icon {...leadingIconProps} class={leadingIcon()} />
46
+ <label for={id} class={s.base({ class: clsx(className) })}>
47
+ {#if leading}
48
+ <span class={s.leading()}>{@render leading()}</span>
49
+ {:else if leadingIconProps}
50
+ <span class={s.leadingIcon()} aria-hidden="true"><Icon {...leadingIconProps} /></span>
35
51
  {/if}
36
52
  <input
37
- id="search"
38
53
  {...restProps}
54
+ {id}
39
55
  {placeholder}
40
56
  bind:this={elementRef}
41
57
  bind:value
42
- type="text"
43
- class={input()}
44
- oncancel={() => (value = undefined)}
58
+ type="search"
59
+ class={s.input()}
45
60
  />
46
-
47
- {#if trailingIconProps && value}
48
- <button onclick={trailingClick} class="z-10">
49
- <Icon {...trailingIconProps} class={trailingIcon()} />
50
- </button>
61
+ {#if showClear || trailing}
62
+ <span class={s.trailing()}>
63
+ {#if showClear}
64
+ <ButtonIcon
65
+ variant="standard"
66
+ type="button"
67
+ iconProps={trailingIconProps!}
68
+ aria-label={clearLabel}
69
+ onclick={trailingClick}
70
+ />
71
+ {/if}
72
+ {@render trailing?.()}
73
+ </span>
51
74
  {/if}
52
75
  </label>
@@ -1,10 +1,10 @@
1
1
  import type { SearchProps } from './types.js';
2
2
  /**
3
- * Material 3 Search Bar.
3
+ * Material 3 Search Bar (contained, M3 Expressive).
4
4
  *
5
5
  * Search bars allow users to enter a query to find specific information within an app.
6
6
  *
7
- * @see https://m3.material.io/components/search/overview
7
+ * @see https://m3.material.io/components/search/specs
8
8
  */
9
9
  declare const Search: import("svelte").Component<SearchProps, {}, "value" | "elementRef">;
10
10
  type Search = ReturnType<typeof Search>;
@@ -1,33 +1,66 @@
1
1
  import { type VariantProps } from 'tailwind-variants';
2
2
  export type SearchVariants = VariantProps<typeof search>;
3
+ /**
4
+ * M3 Expressive contained search bar (https://m3.material.io/components/search/specs):
5
+ * 56dp, circular, surface-container-high, flat. 48dp leading/trailing targets at a 4dp inset,
6
+ * 4dp between the leading element and the label, 0 between trailing actions; 16dp at an edge
7
+ * with no action. Hover 8% / pressed 10% on-surface; focus 3dp secondary outline, 2dp offset.
8
+ */
3
9
  export declare const search: import("tailwind-variants").TVReturnType<{
4
- shadow: {
5
- true: "shadow-elevation-3";
6
- false: "";
10
+ hasLeading: {
11
+ true: "";
12
+ false: {
13
+ input: string;
14
+ };
15
+ };
16
+ hasTrailing: {
17
+ true: "";
18
+ false: {
19
+ input: string;
20
+ };
7
21
  };
8
22
  }, {
9
23
  base: string;
24
+ leading: string;
10
25
  leadingIcon: string;
11
- trailingIcon: string;
12
26
  input: string;
27
+ trailing: string;
13
28
  }, undefined, {
14
- shadow: {
15
- true: "shadow-elevation-3";
16
- false: "";
29
+ hasLeading: {
30
+ true: "";
31
+ false: {
32
+ input: string;
33
+ };
34
+ };
35
+ hasTrailing: {
36
+ true: "";
37
+ false: {
38
+ input: string;
39
+ };
17
40
  };
18
41
  }, {
19
42
  base: string;
43
+ leading: string;
20
44
  leadingIcon: string;
21
- trailingIcon: string;
22
45
  input: string;
46
+ trailing: string;
23
47
  }, import("tailwind-variants").TVReturnTypeLike<{
24
- shadow: {
25
- true: "shadow-elevation-3";
26
- false: "";
48
+ hasLeading: {
49
+ true: "";
50
+ false: {
51
+ input: string;
52
+ };
53
+ };
54
+ hasTrailing: {
55
+ true: "";
56
+ false: {
57
+ input: string;
58
+ };
27
59
  };
28
60
  }, {
29
61
  base: string;
62
+ leading: string;
30
63
  leadingIcon: string;
31
- trailingIcon: string;
32
64
  input: string;
65
+ trailing: string;
33
66
  }>>;