@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
@@ -6,6 +6,7 @@
6
6
 
7
7
  const { Story } = defineMeta({
8
8
  title: 'Containers/Pane Grid',
9
+ tags: ['autodocs'],
9
10
  component: PaneGrid
10
11
  });
11
12
  </script>
@@ -20,7 +21,7 @@
20
21
  <div
21
22
  class="border-md-sys-color-outline-variant relative h-[420px] overflow-hidden rounded-lg border"
22
23
  >
23
- <PaneGrid gap="none" class="h-full">
24
+ <PaneGrid direction="row" gap="none" class="h-full">
24
25
  <Pane
25
26
  width={320}
26
27
  resizable
@@ -29,8 +30,8 @@
29
30
  background={false}
30
31
  full={false}
31
32
  >
32
- <div class="p-4">
33
- <p class="md-sys-typescale-title-small mb-2">Left pane</p>
33
+ <div class="p-spacing-200">
34
+ <p class="md-sys-typescale-title-small mb-spacing-100">Left pane</p>
34
35
  <p class="text-md-sys-color-on-surface-variant text-sm">
35
36
  Drag the handle to resize — persisted to localStorage, and snaps near 360/412px.
36
37
  </p>
@@ -38,8 +39,8 @@
38
39
  </Pane>
39
40
  <PaneHandle persistKey="storybook:pane-grid-split" min={240} max={560} />
40
41
  <Pane rounded={false} full={false}>
41
- <div class="p-4">
42
- <p class="md-sys-typescale-title-small mb-2">Right pane</p>
42
+ <div class="p-spacing-200">
43
+ <p class="md-sys-typescale-title-small mb-spacing-100">Right pane</p>
43
44
  <p class="text-md-sys-color-on-surface-variant text-sm">Main content area.</p>
44
45
  </div>
45
46
  </Pane>
@@ -56,19 +57,19 @@
56
57
  -->
57
58
  <Story name="Sticky Sidebar" asChild>
58
59
  <div class="border-md-sys-color-outline-variant h-[420px] overflow-y-auto rounded-lg border">
59
- <PaneGrid rounded>
60
+ <PaneGrid direction="row" rounded>
60
61
  <Pane width={240} sticky rounded={false}>
61
- <div class="p-4">
62
- <p class="md-sys-typescale-title-small mb-2">Sticky nav</p>
62
+ <div class="p-spacing-200">
63
+ <p class="md-sys-typescale-title-small mb-spacing-100">Sticky nav</p>
63
64
  <p class="text-md-sys-color-on-surface-variant text-sm">
64
65
  Stays pinned to the top of the scroll container while the right pane scrolls past it.
65
66
  </p>
66
67
  </div>
67
68
  </Pane>
68
69
  <Pane rounded={false}>
69
- <div class="flex flex-col gap-4 p-4">
70
+ <div class="gap-spacing-200 p-spacing-200 flex flex-col">
70
71
  {#each Array(12) as _, i}
71
- <div class="bg-md-sys-color-surface-container-high rounded-lg p-6">
72
+ <div class="bg-md-sys-color-surface-container-high p-spacing-300 rounded-lg">
72
73
  Scrollable content block {i + 1}
73
74
  </div>
74
75
  {/each}
@@ -87,17 +88,17 @@
87
88
  <div class="border-md-sys-color-outline-variant h-[420px] overflow-y-auto rounded-lg border">
88
89
  <PaneGrid direction={{ small: 'column', large: 'row' }} gap="lg" padding="md">
89
90
  <Pane background={false} padding="none">
90
- <div class="flex flex-col gap-4">
91
+ <div class="gap-spacing-200 flex flex-col">
91
92
  {#each Array(6) as _, i}
92
- <div class="bg-md-sys-color-surface-container-high rounded-lg p-6">
93
+ <div class="bg-md-sys-color-surface-container-high p-spacing-300 rounded-lg">
93
94
  Main content block {i + 1}
94
95
  </div>
95
96
  {/each}
96
97
  </div>
97
98
  </Pane>
98
99
  <Pane width={280} sticky background={false} padding="none">
99
- <div class="bg-md-sys-color-surface-container rounded-lg p-4">
100
- <p class="md-sys-typescale-title-small mb-2">Supporting content</p>
100
+ <div class="bg-md-sys-color-surface-container p-spacing-200 rounded-lg">
101
+ <p class="md-sys-typescale-title-small mb-spacing-100">Supporting content</p>
101
102
  <p class="text-md-sys-color-on-surface-variant text-sm">
102
103
  Fixed-width panel — e.g. a table of contents or contextual actions.
103
104
  </p>
@@ -118,14 +119,14 @@
118
119
  >
119
120
  <PaneGrid full>
120
121
  <Pane width={320} rounded={false} background={false}>
121
- <div class="p-4">
122
- <p class="md-sys-typescale-title-small mb-2">List</p>
122
+ <div class="p-spacing-200">
123
+ <p class="md-sys-typescale-title-small mb-spacing-100">List</p>
123
124
  <p class="text-md-sys-color-on-surface-variant text-sm">Always visible.</p>
124
125
  </div>
125
126
  </Pane>
126
127
  <Pane visibleFrom="medium" rounded={false}>
127
- <div class="p-4">
128
- <p class="md-sys-typescale-title-small mb-2">Detail</p>
128
+ <div class="p-spacing-200">
129
+ <p class="md-sys-typescale-title-small mb-spacing-100">Detail</p>
129
130
  <p class="text-md-sys-color-on-surface-variant text-sm">Visible from `medium` up only.</p>
130
131
  </div>
131
132
  </Pane>
@@ -2,7 +2,8 @@
2
2
  @component
3
3
  Arranges Pane children relative to one another: direction, gap, and outer
4
4
  margin/padding, each independently responsive across viewport tiers
5
- (small/medium/large/extraLarge). PaneGrid owns layout only — sizing, stickiness,
5
+ (small/medium/large/extraLarge). `direction` defaults to M3's canonical layouts: panes stack
6
+ below `large` and sit side by side from `large` (expanded) up. PaneGrid owns layout only — sizing, stickiness,
6
7
  resizing, and breakpoint visibility are declared per-Pane.
7
8
 
8
9
  With `full`, min-height is `100dvh` minus `--appbar-height` — see Pane.svelte's
@@ -15,7 +16,7 @@ doc comment for how that CSS custom property gets set.
15
16
 
16
17
  const {
17
18
  children,
18
- direction = 'row',
19
+ direction = { small: 'column', large: 'row' },
19
20
  gap = 'md',
20
21
  padding = 'none',
21
22
  margin = 'none',
@@ -2,7 +2,8 @@ import type { PaneGridProps } from './types.js';
2
2
  /**
3
3
  * Arranges Pane children relative to one another: direction, gap, and outer
4
4
  * margin/padding, each independently responsive across viewport tiers
5
- * (small/medium/large/extraLarge). PaneGrid owns layout only — sizing, stickiness,
5
+ * (small/medium/large/extraLarge). `direction` defaults to M3's canonical layouts: panes stack
6
+ * below `large` and sit side by side from `large` (expanded) up. PaneGrid owns layout only — sizing, stickiness,
6
7
  * resizing, and breakpoint visibility are declared per-Pane.
7
8
  *
8
9
  * With `full`, min-height is `100dvh` minus `--appbar-height` — see Pane.svelte's
@@ -6,10 +6,16 @@ resizes and its neighbor. Unlike a handle absolutely-positioned inside a Pane
6
6
  sits in the grid's flex flow — a real sibling with room to breathe in the
7
7
  gutter. Dragging it writes to the shared resize store; any `Pane` with a
8
8
  matching `persistKey` picks the new width up reactively.
9
+
10
+ Motion matches Slider: the pane tracks the pointer 1:1 while dragged, and springs on the fast
11
+ spatial spring into and out of snap points and on keyboard steps (arrows ±16px, Shift ±64px,
12
+ Home/End to `min`/`max`).
9
13
  -->
10
14
  <script lang="ts">
11
15
  import clsx from 'clsx';
12
16
  import { onMount } from 'svelte';
17
+ import { springTokens } from '../../../animation/spring.js';
18
+ import { SpringValue } from '../../../animation/springValue.svelte.js';
13
19
  import { paneHandle } from './theme.js';
14
20
  import { paneWidths } from './resizeStore.svelte.js';
15
21
  import type { PaneHandleProps } from './types.js';
@@ -29,6 +35,16 @@ matching `persistKey` picks the new width up reactively.
29
35
 
30
36
  const { base, grip } = $derived(paneHandle({ dragging, snapped }));
31
37
 
38
+ /* Grip size in px, sprung: 4×32 at rest, 2×32 while dragged, 6×40 on a snap point. */
39
+ const gripWidth = new SpringValue(
40
+ () => (snapped ? 6 : dragging ? 2 : 4),
41
+ springTokens.fastSpatial
42
+ );
43
+ const gripHeight = new SpringValue(() => (snapped ? 40 : 32), springTokens.fastSpatial);
44
+
45
+ const KEY_STEP = 16;
46
+ const KEY_STEP_LARGE = 64;
47
+
32
48
  const clampWidth = (next: number) => Math.min(max, Math.max(min, next));
33
49
 
34
50
  /** Nearest snap point within `snapThreshold` of `value`, if any. */
@@ -63,16 +79,44 @@ matching `persistKey` picks the new width up reactively.
63
79
  if (!dragging) return;
64
80
  const raw = clampWidth(dragStartWidth + (event.clientX - dragStartX));
65
81
  const snap = nearestSnap(raw);
82
+ /* Entering or leaving a snap point springs; everywhere else the pane tracks the pointer. */
83
+ const snapChanged = (snap !== undefined) !== snapped;
66
84
  snapped = snap !== undefined;
67
- paneWidths.set(persistKey, snap ?? raw);
85
+ paneWidths.set(persistKey, snap ?? raw, { spring: snapChanged });
68
86
  };
69
87
 
70
88
  const endDrag = () => {
71
89
  dragging = false;
72
90
  snapped = false;
73
91
  };
92
+
93
+ const onKeydown = (event: KeyboardEvent) => {
94
+ const current = paneWidths.get(persistKey) ?? min;
95
+ const step = event.shiftKey ? KEY_STEP_LARGE : KEY_STEP;
96
+ let next: number;
97
+ switch (event.key) {
98
+ case 'ArrowLeft':
99
+ next = current - step;
100
+ break;
101
+ case 'ArrowRight':
102
+ next = current + step;
103
+ break;
104
+ case 'Home':
105
+ next = min;
106
+ break;
107
+ case 'End':
108
+ next = max;
109
+ break;
110
+ default:
111
+ return;
112
+ }
113
+ event.preventDefault();
114
+ paneWidths.set(persistKey, clampWidth(next), { spring: true });
115
+ };
74
116
  </script>
75
117
 
118
+ <!-- A focusable separator is the WAI-ARIA window splitter, an interactive widget. -->
119
+ <!-- svelte-ignore a11y_no_noninteractive_tabindex -->
76
120
  <div
77
121
  class={base({ class: clsx(className) })}
78
122
  role="separator"
@@ -80,11 +124,13 @@ matching `persistKey` picks the new width up reactively.
80
124
  aria-valuenow={paneWidths.get(persistKey)}
81
125
  aria-valuemin={min}
82
126
  aria-valuemax={max}
127
+ tabindex="0"
128
+ onkeydown={onKeydown}
83
129
  onpointerdown={startDrag}
84
130
  onpointermove={moveDrag}
85
131
  onpointerup={endDrag}
86
132
  onpointercancel={endDrag}
87
133
  {...rest}
88
134
  >
89
- <div class={grip()}></div>
135
+ <div class={grip()} style="width: {gripWidth.current}px; height: {gripHeight.current}px"></div>
90
136
  </div>
@@ -6,6 +6,10 @@ import type { PaneHandleProps } from './types.js';
6
6
  * sits in the grid's flex flow — a real sibling with room to breathe in the
7
7
  * gutter. Dragging it writes to the shared resize store; any `Pane` with a
8
8
  * matching `persistKey` picks the new width up reactively.
9
+ *
10
+ * Motion matches Slider: the pane tracks the pointer 1:1 while dragged, and springs on the fast
11
+ * spatial spring into and out of snap points and on keyboard steps (arrows ±16px, Shift ±64px,
12
+ * Home/End to `min`/`max`).
9
13
  */
10
14
  declare const PaneHandle: import("svelte").Component<PaneHandleProps, {}, "">;
11
15
  type PaneHandle = ReturnType<typeof PaneHandle>;
@@ -1,10 +1,19 @@
1
1
  declare function get(key: string): number | undefined;
2
2
  /** Seeds `key` from localStorage (or `fallback`) the first time it's read; a no-op after that. */
3
3
  declare function hydrate(key: string, fallback: number): number;
4
- declare function set(key: string, value: number): void;
4
+ /** Whether the pane should spring to `key`'s latest width instead of jumping to it. */
5
+ declare function shouldSpring(key: string): boolean;
6
+ /**
7
+ * Writes `key`'s width. `spring: true` asks the pane to spring there; otherwise it jumps (a drag
8
+ * tracking the pointer 1:1), unless a spring is still in flight, which it retargets instead.
9
+ */
10
+ declare function set(key: string, value: number, { spring }?: {
11
+ spring?: boolean;
12
+ }): void;
5
13
  export declare const paneWidths: {
6
14
  get: typeof get;
7
15
  hydrate: typeof hydrate;
8
16
  set: typeof set;
17
+ shouldSpring: typeof shouldSpring;
9
18
  };
10
19
  export {};
@@ -6,6 +6,8 @@ import { SvelteMap } from 'svelte/reactivity';
6
6
  * writes on drag, the pane reads reactively.
7
7
  */
8
8
  const widths = new SvelteMap();
9
+ /** Whether the last write to a key should spring (a snap, a keyboard step) rather than jump. */
10
+ const springs = new SvelteMap();
9
11
  function get(key) {
10
12
  return widths.get(key);
11
13
  }
@@ -22,9 +24,18 @@ function hydrate(key, fallback) {
22
24
  widths.set(key, initial);
23
25
  return initial;
24
26
  }
25
- function set(key, value) {
27
+ /** Whether the pane should spring to `key`'s latest width instead of jumping to it. */
28
+ function shouldSpring(key) {
29
+ return springs.get(key) ?? false;
30
+ }
31
+ /**
32
+ * Writes `key`'s width. `spring: true` asks the pane to spring there; otherwise it jumps (a drag
33
+ * tracking the pointer 1:1), unless a spring is still in flight, which it retargets instead.
34
+ */
35
+ function set(key, value, { spring = false } = {}) {
36
+ springs.set(key, spring);
26
37
  widths.set(key, value);
27
38
  if (typeof localStorage !== 'undefined')
28
39
  localStorage.setItem(key, String(value));
29
40
  }
30
- export const paneWidths = { get, hydrate, set };
41
+ export const paneWidths = { get, hydrate, set, shouldSpring };
@@ -3,22 +3,94 @@ import { tv } from 'tailwind-variants';
3
3
  // literal Tailwind candidate, so the JIT scanner picks it up even though it's only
4
4
  // ever read through object indexing at runtime (see PaneGrid.svelte's resolveResponsive).
5
5
  const gapClasses = {
6
- small: { none: 'gap-0', sm: 'gap-2', md: 'gap-3', lg: 'gap-4', xl: 'gap-6' },
7
- medium: { none: 'md:gap-0', sm: 'md:gap-2', md: 'md:gap-3', lg: 'md:gap-4', xl: 'md:gap-6' },
8
- large: { none: 'lg:gap-0', sm: 'lg:gap-2', md: 'lg:gap-3', lg: 'lg:gap-4', xl: 'lg:gap-6' },
9
- extraLarge: { none: 'xl:gap-0', sm: 'xl:gap-2', md: 'xl:gap-3', lg: 'xl:gap-4', xl: 'xl:gap-6' }
6
+ small: {
7
+ none: 'gap-spacing-0',
8
+ sm: 'gap-spacing-100',
9
+ md: 'gap-spacing-150',
10
+ lg: 'gap-spacing-200',
11
+ xl: 'gap-spacing-300'
12
+ },
13
+ medium: {
14
+ none: 'md:gap-spacing-0',
15
+ sm: 'md:gap-spacing-100',
16
+ md: 'md:gap-spacing-150',
17
+ lg: 'md:gap-spacing-200',
18
+ xl: 'md:gap-spacing-300'
19
+ },
20
+ large: {
21
+ none: 'lg:gap-spacing-0',
22
+ sm: 'lg:gap-spacing-100',
23
+ md: 'lg:gap-spacing-150',
24
+ lg: 'lg:gap-spacing-200',
25
+ xl: 'lg:gap-spacing-300'
26
+ },
27
+ extraLarge: {
28
+ none: 'xl:gap-spacing-0',
29
+ sm: 'xl:gap-spacing-100',
30
+ md: 'xl:gap-spacing-150',
31
+ lg: 'xl:gap-spacing-200',
32
+ xl: 'xl:gap-spacing-300'
33
+ }
10
34
  };
11
35
  const paddingClasses = {
12
- small: { none: 'p-0', sm: 'p-3', md: 'p-4', lg: 'p-6', xl: 'p-8' },
13
- medium: { none: 'md:p-0', sm: 'md:p-3', md: 'md:p-4', lg: 'md:p-6', xl: 'md:p-8' },
14
- large: { none: 'lg:p-0', sm: 'lg:p-3', md: 'lg:p-4', lg: 'lg:p-6', xl: 'lg:p-8' },
15
- extraLarge: { none: 'xl:p-0', sm: 'xl:p-3', md: 'xl:p-4', lg: 'xl:p-6', xl: 'xl:p-8' }
36
+ small: {
37
+ none: 'p-spacing-0',
38
+ sm: 'p-spacing-150',
39
+ md: 'p-spacing-200',
40
+ lg: 'p-spacing-300',
41
+ xl: 'p-spacing-400'
42
+ },
43
+ medium: {
44
+ none: 'md:p-spacing-0',
45
+ sm: 'md:p-spacing-150',
46
+ md: 'md:p-spacing-200',
47
+ lg: 'md:p-spacing-300',
48
+ xl: 'md:p-spacing-400'
49
+ },
50
+ large: {
51
+ none: 'lg:p-spacing-0',
52
+ sm: 'lg:p-spacing-150',
53
+ md: 'lg:p-spacing-200',
54
+ lg: 'lg:p-spacing-300',
55
+ xl: 'lg:p-spacing-400'
56
+ },
57
+ extraLarge: {
58
+ none: 'xl:p-spacing-0',
59
+ sm: 'xl:p-spacing-150',
60
+ md: 'xl:p-spacing-200',
61
+ lg: 'xl:p-spacing-300',
62
+ xl: 'xl:p-spacing-400'
63
+ }
16
64
  };
17
65
  const marginClasses = {
18
- small: { none: 'm-0', sm: 'm-3', md: 'm-4', lg: 'm-6', xl: 'm-8' },
19
- medium: { none: 'md:m-0', sm: 'md:m-3', md: 'md:m-4', lg: 'md:m-6', xl: 'md:m-8' },
20
- large: { none: 'lg:m-0', sm: 'lg:m-3', md: 'lg:m-4', lg: 'lg:m-6', xl: 'lg:m-8' },
21
- extraLarge: { none: 'xl:m-0', sm: 'xl:m-3', md: 'xl:m-4', lg: 'xl:m-6', xl: 'xl:m-8' }
66
+ small: {
67
+ none: 'm-spacing-0',
68
+ sm: 'm-spacing-150',
69
+ md: 'm-spacing-200',
70
+ lg: 'm-spacing-300',
71
+ xl: 'm-spacing-400'
72
+ },
73
+ medium: {
74
+ none: 'md:m-spacing-0',
75
+ sm: 'md:m-spacing-150',
76
+ md: 'md:m-spacing-200',
77
+ lg: 'md:m-spacing-300',
78
+ xl: 'md:m-spacing-400'
79
+ },
80
+ large: {
81
+ none: 'lg:m-spacing-0',
82
+ sm: 'lg:m-spacing-150',
83
+ md: 'lg:m-spacing-200',
84
+ lg: 'lg:m-spacing-300',
85
+ xl: 'lg:m-spacing-400'
86
+ },
87
+ extraLarge: {
88
+ none: 'xl:m-spacing-0',
89
+ sm: 'xl:m-spacing-150',
90
+ md: 'xl:m-spacing-200',
91
+ lg: 'xl:m-spacing-300',
92
+ xl: 'xl:m-spacing-400'
93
+ }
22
94
  };
23
95
  const directionClasses = {
24
96
  small: { row: 'flex-row', column: 'flex-col' },
@@ -59,7 +131,7 @@ export function resolveResponsive(value, table) {
59
131
  }
60
132
  export const pane = tv({
61
133
  slots: {
62
- base: 'relative flex min-w-0 flex-col box-border overflow-clip items-center',
134
+ base: 'relative flex min-w-spacing-0 flex-col box-border overflow-clip items-center',
63
135
  content: 'flex flex-1 flex-col w-full h-full'
64
136
  },
65
137
  variants: {
@@ -79,20 +151,24 @@ export const pane = tv({
79
151
  false: { base: '' }
80
152
  },
81
153
  padding: {
82
- none: { content: 'p-0' },
83
- sm: { content: 'px-3 md:px-4 py-2 md:py-3' },
84
- md: { content: 'px-4 md:px-6 lg:px-8 py-3 md:py-4 lg: py-6' },
85
- lg: { content: 'px-6 md:px-8 lg:px-12 py-4 md:py-6 lg:py-8' }
154
+ none: { content: 'p-spacing-0' },
155
+ sm: { content: 'px-spacing-150 md:px-spacing-200 py-spacing-100 md:py-spacing-150' },
156
+ md: {
157
+ content: 'px-spacing-200 md:px-spacing-300 lg:px-spacing-400 py-spacing-150 md:py-spacing-200 lg:py-spacing-300'
158
+ },
159
+ lg: {
160
+ content: 'px-spacing-300 md:px-spacing-400 lg:px-spacing-600 py-spacing-200 md:py-spacing-300 lg:py-spacing-400'
161
+ }
86
162
  },
87
163
  gap: {
88
- none: { content: 'gap-0' },
89
- sm: { content: 'gap-2' },
90
- md: { content: 'gap-3' },
91
- lg: { content: 'gap-4' },
92
- xl: { content: 'gap-6' }
164
+ none: { content: 'gap-spacing-0' },
165
+ sm: { content: 'gap-spacing-100' },
166
+ md: { content: 'gap-spacing-150' },
167
+ lg: { content: 'gap-spacing-200' },
168
+ xl: { content: 'gap-spacing-300' }
93
169
  },
94
170
  flexible: {
95
- true: { base: 'min-w-0 grow basis-0' },
171
+ true: { base: 'min-w-spacing-0 grow basis-spacing-0' },
96
172
  false: { base: 'shrink-0' }
97
173
  },
98
174
  sticky: {
@@ -116,8 +192,9 @@ export const pane = tv({
116
192
  */
117
193
  export const paneHandle = tv({
118
194
  slots: {
119
- base: 'group relative flex shrink-0 w-3 self-stretch cursor-col-resize touch-none items-center justify-center rounded-full bg-transparent hover:bg-md-sys-color-outline/20',
120
- grip: 'rounded-full transition-[background-color,height,width] md-sys-motion-fast-spatial'
195
+ base: 'group relative flex shrink-0 w-spacing-150 self-stretch cursor-col-resize touch-none items-center justify-center rounded-full bg-transparent outline-none hover:bg-md-sys-color-outline/20 focus-visible:outline-2 focus-visible:outline-md-sys-color-secondary',
196
+ // Size is sprung inline by PaneHandle.svelte; only color transitions here.
197
+ grip: 'rounded-full transition-colors md-sys-motion-effects'
121
198
  },
122
199
  variants: {
123
200
  dragging: {
@@ -125,24 +202,23 @@ export const paneHandle = tv({
125
202
  false: ''
126
203
  },
127
204
  snapped: {
128
- true: { grip: 'h-10 w-1.5 bg-md-sys-color-tertiary' },
205
+ true: { grip: 'bg-md-sys-color-tertiary' },
129
206
  false: {
130
- grip: 'h-8 w-1 bg-md-sys-color-on-surface-variant/40 group-hover:bg-md-sys-color-primary'
207
+ grip: 'bg-md-sys-color-on-surface-variant/40 group-hover:bg-md-sys-color-primary'
131
208
  }
132
209
  }
133
- },
134
- compoundVariants: [{ dragging: true, snapped: false, class: { grip: 'w-0.5' } }]
210
+ }
135
211
  });
136
212
  export const draggablePane = tv({
137
213
  slots: {
138
214
  base: 'fixed z-[100] flex min-w-72 flex-col rounded-md bg-md-sys-color-surface-container-highest shadow-elevation-3 transition-shadow md-sys-motion-effects',
139
- headerBar: 'relative flex shrink-0 items-center gap-2 rounded-t-2xl px-3 py-2 touch-none select-none md-sys-state-focus-indicator',
215
+ headerBar: 'relative flex shrink-0 items-center gap-spacing-100 rounded-t-2xl px-spacing-150 py-spacing-100 touch-none select-none md-sys-state-focus-indicator',
140
216
  grip: 'shrink-0 text-md-sys-color-on-surface-variant',
141
217
  headline: 'flex-1 truncate md-sys-typescale-title-small text-md-sys-color-on-surface',
142
- actions: 'flex shrink-0 items-center gap-1',
143
- content: 'flex flex-1 flex-col min-h-0 min-w-0 overflow-auto p-4 pt-2',
218
+ actions: 'flex shrink-0 items-center gap-spacing-50',
219
+ content: 'flex flex-1 flex-col min-h-spacing-0 min-w-spacing-0 overflow-auto p-spacing-200 pt-spacing-100',
144
220
  resizeHandle: 'absolute touch-none',
145
- miniBase: 'fixed z-[100] flex cursor-pointer items-center gap-2 rounded-full bg-md-sys-color-surface-container-high px-4 py-2 shadow-elevation-2 md-sys-state-focus-indicator hover:shadow-elevation-3',
221
+ miniBase: 'fixed z-[100] flex cursor-pointer items-center gap-spacing-100 rounded-full bg-md-sys-color-surface-container-high px-spacing-200 py-spacing-100 shadow-elevation-2 md-sys-state-focus-indicator hover:shadow-elevation-3',
146
222
  miniIcon: 'shrink-0 text-md-sys-color-on-surface-variant',
147
223
  miniLabel: 'md-sys-typescale-label-large max-w-48 truncate text-md-sys-color-on-surface'
148
224
  },
@@ -156,28 +232,36 @@ export const draggablePane = tv({
156
232
  false: ''
157
233
  },
158
234
  edge: {
159
- n: { resizeHandle: 'top-0 inset-x-3 h-1.5 -translate-y-1/2 cursor-ns-resize' },
160
- s: { resizeHandle: 'bottom-0 inset-x-3 h-1.5 translate-y-1/2 cursor-ns-resize' },
161
- e: { resizeHandle: 'right-0 inset-y-3 w-1.5 translate-x-1/2 cursor-ew-resize' },
162
- w: { resizeHandle: 'left-0 inset-y-3 w-1.5 -translate-x-1/2 cursor-ew-resize' },
235
+ n: {
236
+ resizeHandle: 'top-spacing-0 inset-x-spacing-150 h-spacing-75 -translate-y-1/2 cursor-ns-resize'
237
+ },
238
+ s: {
239
+ resizeHandle: 'bottom-spacing-0 inset-x-spacing-150 h-spacing-75 translate-y-1/2 cursor-ns-resize'
240
+ },
241
+ e: {
242
+ resizeHandle: 'right-spacing-0 inset-y-spacing-150 w-spacing-75 translate-x-1/2 cursor-ew-resize'
243
+ },
244
+ w: {
245
+ resizeHandle: 'left-spacing-0 inset-y-spacing-150 w-spacing-75 -translate-x-1/2 cursor-ew-resize'
246
+ },
163
247
  ne: {
164
- resizeHandle: 'top-0 right-0 size-3 -translate-y-1/2 translate-x-1/2 cursor-nesw-resize'
248
+ resizeHandle: 'top-spacing-0 right-spacing-0 size-spacing-150 -translate-y-1/2 translate-x-1/2 cursor-nesw-resize'
165
249
  },
166
250
  nw: {
167
- resizeHandle: 'top-0 left-0 size-3 -translate-y-1/2 -translate-x-1/2 cursor-nwse-resize'
251
+ resizeHandle: 'top-spacing-0 left-spacing-0 size-spacing-150 -translate-y-1/2 -translate-x-1/2 cursor-nwse-resize'
168
252
  },
169
253
  se: {
170
- resizeHandle: 'bottom-0 right-0 size-3 translate-y-1/2 translate-x-1/2 cursor-nwse-resize'
254
+ resizeHandle: 'bottom-spacing-0 right-spacing-0 size-spacing-150 translate-y-1/2 translate-x-1/2 cursor-nwse-resize'
171
255
  },
172
256
  sw: {
173
- resizeHandle: 'bottom-0 left-0 size-3 translate-y-1/2 -translate-x-1/2 cursor-nesw-resize'
257
+ resizeHandle: 'bottom-spacing-0 left-spacing-0 size-spacing-150 translate-y-1/2 -translate-x-1/2 cursor-nesw-resize'
174
258
  }
175
259
  },
176
260
  corner: {
177
- 'bottom-left': { miniBase: 'bottom-4 left-4' },
178
- 'bottom-right': { miniBase: 'bottom-4 right-4' },
179
- 'top-left': { miniBase: 'top-4 left-4' },
180
- 'top-right': { miniBase: 'top-4 right-4' }
261
+ 'bottom-left': { miniBase: 'bottom-spacing-200 left-spacing-200' },
262
+ 'bottom-right': { miniBase: 'bottom-spacing-200 right-spacing-200' },
263
+ 'top-left': { miniBase: 'top-spacing-200 left-spacing-200' },
264
+ 'top-right': { miniBase: 'top-spacing-200 right-spacing-200' }
181
265
  }
182
266
  },
183
267
  defaultVariants: {
@@ -63,8 +63,9 @@ export type PaneGridProps = PaneGridVariants & DivAttrs & {
63
63
  /** Optional root class. */
64
64
  class?: string;
65
65
  /**
66
- * Row (side by side) or column (stacked), per breakpoint.
67
- * @default 'row'
66
+ * Row (side by side) or column (stacked), per breakpoint. Defaults to M3's canonical layouts:
67
+ * one pane per row below the expanded window class, side by side from `large` up.
68
+ * @default { small: 'column', large: 'row' }
68
69
  */
69
70
  direction?: Responsive<'row' | 'column'>;
70
71
  /**
@@ -0,0 +1,45 @@
1
+ import { Meta, Title, Subtitle, Canvas, Controls } from '@storybook/addon-docs/blocks';
2
+ import * as PopoverStories from './Popover.stories.svelte';
3
+
4
+ <Meta of={PopoverStories} />
5
+
6
+ <Title />
7
+
8
+ <Subtitle>
9
+ A non-modal surface anchored to a trigger, for supplementary content or a few controls.
10
+ </Subtitle>
11
+
12
+ `import { Popover } from '@noxlovette/material';`
13
+
14
+ <Canvas of={PopoverStories.Playground} />
15
+
16
+ <Controls of={PopoverStories.Playground} />
17
+
18
+ ## When to use it
19
+
20
+ M3 has no popover component; this one sits between its patterns. It opens on click and can hold
21
+ interactive content, unlike a `Tooltip`. It doesn't block the page and has no scrim, unlike a
22
+ `Dialogue`.
23
+
24
+ - **Popover:** supplementary information or a few controls tied to one button.
25
+ - **`Menu`:** a list of actions to choose from.
26
+ - **`Dialogue`:** anything that must be resolved before the user continues.
27
+
28
+ Pass the trigger as a snippet and spread the props it receives onto it:
29
+
30
+ ```svelte
31
+ <Popover title="Storage">
32
+ {#snippet trigger(triggerProps)}
33
+ <Button variant="outlined" {...triggerProps}>Show info</Button>
34
+ {/snippet}
35
+ <Body>75% of your storage has been used.</Body>
36
+ </Popover>
37
+ ```
38
+
39
+ <Canvas of={PopoverStories.IconTriggerNoTitle} />
40
+
41
+ ## Accessibility
42
+
43
+ - **Dismissal.** Escape closes the popover and returns focus to the trigger.
44
+ - **Non-modal.** The rest of the page stays interactive while it's open, so don't use it for
45
+ content that must block the user.
@@ -55,7 +55,7 @@
55
55
  <div class="p-24">
56
56
  <Popover showClose={false}>
57
57
  {#snippet trigger(triggerProps)}
58
- <ButtonIcon iconProps={{ name: 'info' }} variant="text" {...triggerProps} />
58
+ <ButtonIcon iconProps={{ name: 'info' }} variant="standard" {...triggerProps} />
59
59
  {/snippet}
60
60
  <Body class="text-md-sys-color-on-surface-variant">
61
61
  A minimal popover with no header — just an icon trigger and body text.
@@ -55,7 +55,7 @@ Popovers display rich content in a non-modal overlay anchored to a trigger eleme
55
55
  <ButtonIcon
56
56
  {...closeProps}
57
57
  iconProps={{ name: 'close' }}
58
- variant="text"
58
+ variant="standard"
59
59
  size="sm"
60
60
  />
61
61
  </div>
@@ -1,9 +1,9 @@
1
1
  import { tv } from 'tailwind-variants';
2
2
  export const popover = tv({
3
3
  slots: {
4
- base: 'relative z-[100] min-w-48 max-w-sm rounded-2xl bg-md-sys-color-surface-container-high p-4 shadow-elevation-3 ring-1 ring-md-sys-color-outline/20',
5
- close: 'absolute top-3 right-3',
6
- header: 'mb-2 flex items-center justify-between gap-4',
4
+ base: 'relative z-[100] min-w-48 max-w-sm rounded-2xl bg-md-sys-color-surface-container-high p-spacing-200 shadow-elevation-3 ring-1 ring-md-sys-color-outline/20',
5
+ close: 'absolute top-spacing-150 right-spacing-150',
6
+ header: 'mb-spacing-100 flex items-center justify-between gap-spacing-200',
7
7
  title: 'md-sys-typescale-title-small text-md-sys-color-on-surface',
8
8
  body: 'md-sys-typescale-body-medium text-md-sys-color-on-surface-variant'
9
9
  }
@@ -10,10 +10,10 @@ export const scrollArea = tv({
10
10
  variants: {
11
11
  orientation: {
12
12
  vertical: {
13
- scrollbar: 'h-full w-2 border-l border-l-transparent p-px'
13
+ scrollbar: 'h-full w-spacing-100 border-l border-l-transparent p-px'
14
14
  },
15
15
  horizontal: {
16
- scrollbar: 'h-2 w-full border-t border-t-transparent p-px'
16
+ scrollbar: 'h-spacing-100 w-full border-t border-t-transparent p-px'
17
17
  },
18
18
  both: {
19
19
  scrollbar: ''