@noxlovette/material 0.3.3 → 0.4.1

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 (289) hide show
  1. package/README.md +1 -0
  2. package/dist/actions/index.d.ts +1 -0
  3. package/dist/actions/index.js +1 -0
  4. package/dist/actions/rovingFocusGroup.d.ts +20 -0
  5. package/dist/actions/rovingFocusGroup.js +82 -0
  6. package/dist/components/badge/theme.d.ts +8 -8
  7. package/dist/components/buttons/button-group/ButtonGroup.stories.svelte +83 -0
  8. package/dist/components/buttons/button-group/ButtonGroup.stories.svelte.d.ts +19 -0
  9. package/dist/components/buttons/button-group/ButtonGroup.svelte +10 -29
  10. package/dist/components/buttons/button-group/ButtonGroup.svelte.d.ts +7 -3
  11. package/dist/components/buttons/button-group/index.d.ts +0 -1
  12. package/dist/components/buttons/button-group/index.js +3 -1
  13. package/dist/components/buttons/button-group/theme.d.ts +17 -103
  14. package/dist/components/buttons/button-group/theme.js +7 -35
  15. package/dist/components/buttons/button-group/types.d.ts +9 -20
  16. package/dist/components/buttons/connected/ConnectedButtonGroup.stories.svelte +118 -0
  17. package/dist/components/buttons/connected/ConnectedButtonGroup.stories.svelte.d.ts +19 -0
  18. package/dist/components/buttons/connected/ConnectedButtonGroup.svelte +52 -0
  19. package/dist/components/buttons/connected/ConnectedButtonGroup.svelte.d.ts +12 -0
  20. package/dist/components/buttons/connected/ConnectedButtonGroupItem.svelte +37 -0
  21. package/dist/components/buttons/connected/ConnectedButtonGroupItem.svelte.d.ts +9 -0
  22. package/dist/components/buttons/connected/index.d.ts +3 -1
  23. package/dist/components/buttons/connected/index.js +3 -1
  24. package/dist/components/buttons/connected/theme.d.ts +125 -0
  25. package/dist/components/buttons/connected/theme.js +38 -0
  26. package/dist/components/buttons/connected/types.d.ts +32 -13
  27. package/dist/components/buttons/index.d.ts +1 -0
  28. package/dist/components/buttons/index.js +1 -0
  29. package/dist/components/buttons/split-button/SplitButton.stories.svelte +103 -0
  30. package/dist/components/buttons/split-button/SplitButton.stories.svelte.d.ts +19 -0
  31. package/dist/components/buttons/split-button/SplitButton.svelte +104 -0
  32. package/dist/components/buttons/split-button/SplitButton.svelte.d.ts +19 -0
  33. package/dist/components/buttons/split-button/index.d.ts +3 -0
  34. package/dist/components/{containers/panes → buttons/split-button}/index.js +1 -3
  35. package/dist/components/buttons/split-button/theme.d.ts +35 -0
  36. package/dist/components/buttons/split-button/theme.js +26 -0
  37. package/dist/components/buttons/split-button/types.d.ts +33 -0
  38. package/dist/components/buttons/theme.d.ts +142 -142
  39. package/dist/components/buttons/theme.js +2 -2
  40. package/dist/components/cards/Card.stories.svelte +58 -0
  41. package/dist/components/cards/Card.stories.svelte.d.ts +2 -17
  42. package/dist/components/cards/Card.svelte +76 -8
  43. package/dist/components/cards/theme.d.ts +26 -14
  44. package/dist/components/cards/theme.js +5 -1
  45. package/dist/components/cards/types.d.ts +39 -1
  46. package/dist/components/chips/Chip.stories.svelte +64 -0
  47. package/dist/components/chips/Chip.stories.svelte.d.ts +19 -0
  48. package/dist/components/chips/Chip.svelte +115 -0
  49. package/dist/components/chips/Chip.svelte.d.ts +14 -0
  50. package/dist/components/chips/index.d.ts +3 -0
  51. package/dist/components/{containers/merger → chips}/index.js +2 -1
  52. package/dist/components/chips/theme.d.ts +78 -0
  53. package/dist/components/chips/theme.js +72 -0
  54. package/dist/components/chips/types.d.ts +43 -0
  55. package/dist/components/containers/action-rail/ActionRail.stories.svelte +36 -0
  56. package/dist/components/containers/{panes/SinglePane.stories.svelte.d.ts → action-rail/ActionRail.stories.svelte.d.ts} +4 -4
  57. package/dist/components/containers/action-rail/ActionRail.svelte +35 -0
  58. package/dist/components/containers/action-rail/ActionRail.svelte.d.ts +17 -0
  59. package/dist/components/containers/action-rail/index.d.ts +3 -0
  60. package/dist/components/containers/action-rail/index.js +6 -0
  61. package/dist/components/containers/action-rail/theme.d.ts +45 -0
  62. package/dist/components/containers/action-rail/theme.js +26 -0
  63. package/dist/components/containers/action-rail/types.d.ts +20 -0
  64. package/dist/components/containers/action-rail/types.js +1 -0
  65. package/dist/components/containers/app/App.svelte +6 -6
  66. package/dist/components/containers/app/App.svelte.d.ts +4 -2
  67. package/dist/components/containers/app/theme.d.ts +1 -1
  68. package/dist/components/containers/app/types.d.ts +9 -4
  69. package/dist/components/containers/bottom-sheet/BottomSheet.stories.svelte +1 -1
  70. package/dist/components/containers/bottom-sheet/BottomSheet.svelte +1 -1
  71. package/dist/components/containers/context-menu/ContextMenu.stories.svelte +44 -0
  72. package/dist/components/containers/context-menu/ContextMenu.svelte +21 -5
  73. package/dist/components/containers/context-menu/ContextMenu.svelte.d.ts +11 -0
  74. package/dist/components/containers/context-menu/theme.d.ts +20 -2
  75. package/dist/components/containers/context-menu/theme.js +31 -8
  76. package/dist/components/containers/context-menu/types.d.ts +14 -2
  77. package/dist/components/containers/dialogue/theme.d.ts +20 -20
  78. package/dist/components/containers/divider/theme.d.ts +17 -17
  79. package/dist/components/containers/index.d.ts +2 -3
  80. package/dist/components/containers/index.js +2 -3
  81. package/dist/components/containers/link-preview/theme.d.ts +11 -11
  82. package/dist/components/containers/list/theme.d.ts +14 -14
  83. package/dist/components/containers/list/theme.js +1 -1
  84. package/dist/components/containers/menu/Menu.stories.svelte +105 -3
  85. package/dist/components/containers/menu/Menu.stories.svelte.d.ts +2 -17
  86. package/dist/components/containers/menu/Menu.svelte +9 -7
  87. package/dist/components/containers/menu/MenuCheckboxItem.svelte +55 -0
  88. package/dist/components/containers/menu/MenuCheckboxItem.svelte.d.ts +25 -0
  89. package/dist/components/containers/menu/MenuGroup.svelte +43 -0
  90. package/dist/components/containers/menu/MenuGroup.svelte.d.ts +28 -0
  91. package/dist/components/containers/menu/MenuRadioGroup.svelte +39 -0
  92. package/dist/components/containers/menu/MenuRadioGroup.svelte.d.ts +27 -0
  93. package/dist/components/containers/menu/MenuRadioItem.svelte +49 -0
  94. package/dist/components/containers/menu/MenuRadioItem.svelte.d.ts +17 -0
  95. package/dist/components/containers/menu/MenuSub.svelte +91 -0
  96. package/dist/components/containers/menu/MenuSub.svelte.d.ts +29 -0
  97. package/dist/components/containers/menu/index.d.ts +7 -0
  98. package/dist/components/containers/menu/index.js +8 -0
  99. package/dist/components/containers/menu/menu-item/MenuItem.svelte +71 -0
  100. package/dist/components/containers/{menu-item → menu/menu-item}/MenuItem.svelte.d.ts +2 -1
  101. package/dist/components/containers/{menu-item → menu/menu-item}/types.d.ts +5 -1
  102. package/dist/components/containers/menu/menu-item/types.js +1 -0
  103. package/dist/components/containers/menu/theme.d.ts +68 -0
  104. package/dist/components/containers/menu/theme.js +36 -0
  105. package/dist/components/containers/menu/types.d.ts +113 -2
  106. package/dist/components/containers/pane/DraggablePane.stories.svelte +199 -0
  107. package/dist/components/containers/pane/DraggablePane.stories.svelte.d.ts +4 -0
  108. package/dist/components/containers/pane/DraggablePane.svelte +533 -0
  109. package/dist/components/containers/pane/DraggablePane.svelte.d.ts +29 -0
  110. package/dist/components/containers/pane/Pane.stories.svelte +104 -0
  111. package/dist/components/containers/pane/Pane.stories.svelte.d.ts +19 -0
  112. package/dist/components/containers/pane/Pane.svelte +78 -0
  113. package/dist/components/containers/pane/Pane.svelte.d.ts +18 -0
  114. package/dist/components/containers/pane/PaneGrid.stories.svelte +134 -0
  115. package/dist/components/containers/pane/PaneGrid.stories.svelte.d.ts +19 -0
  116. package/dist/components/containers/pane/PaneGrid.svelte +43 -0
  117. package/dist/components/containers/pane/PaneGrid.svelte.d.ts +13 -0
  118. package/dist/components/containers/pane/PaneHandle.svelte +90 -0
  119. package/dist/components/containers/pane/PaneHandle.svelte.d.ts +12 -0
  120. package/dist/components/containers/pane/dragStore.svelte.d.ts +16 -0
  121. package/dist/components/containers/pane/dragStore.svelte.js +38 -0
  122. package/dist/components/containers/pane/index.d.ts +8 -0
  123. package/dist/components/containers/pane/index.js +11 -0
  124. package/dist/components/containers/pane/resizeStore.svelte.d.ts +10 -0
  125. package/dist/components/containers/pane/resizeStore.svelte.js +30 -0
  126. package/dist/components/containers/pane/theme.d.ts +571 -0
  127. package/dist/components/containers/pane/theme.js +211 -0
  128. package/dist/components/containers/pane/types.d.ts +249 -0
  129. package/dist/components/containers/pane/types.js +1 -0
  130. package/dist/components/containers/popover/Popover.stories.svelte +4 -4
  131. package/dist/components/containers/popover/Popover.svelte +3 -1
  132. package/dist/components/containers/popover/theme.d.ts +20 -20
  133. package/dist/components/containers/popover/types.d.ts +6 -2
  134. package/dist/components/containers/scroll-area/theme.d.ts +2 -2
  135. package/dist/components/containers/side-sheet/SideSheet.stories.svelte +16 -24
  136. package/dist/components/containers/side-sheet/SideSheet.svelte +73 -7
  137. package/dist/components/containers/side-sheet/SideSheet.svelte.d.ts +5 -0
  138. package/dist/components/containers/stack/theme.d.ts +44 -44
  139. package/dist/components/date/DateField.stories.svelte +57 -0
  140. package/dist/components/{containers/panes/SplitPane.stories.svelte.d.ts → date/DateField.stories.svelte.d.ts} +4 -4
  141. package/dist/components/date/DateField.svelte +11 -2
  142. package/dist/components/date/DateRangeField.stories.svelte +53 -0
  143. package/dist/components/{containers/panes/SupportingPane.stories.svelte.d.ts → date/DateRangeField.stories.svelte.d.ts} +4 -4
  144. package/dist/components/date/DateRangeField.svelte +2 -1
  145. package/dist/components/date/theme.d.ts +73 -4
  146. package/dist/components/date/theme.js +95 -26
  147. package/dist/components/date/types.d.ts +5 -0
  148. package/dist/components/forms/checkbox/Checkbox.svelte +7 -9
  149. package/dist/components/forms/checkbox/theme.d.ts +8 -8
  150. package/dist/components/forms/checkbox/theme.js +31 -9
  151. package/dist/components/forms/command/theme.d.ts +35 -35
  152. package/dist/components/forms/pin/theme.d.ts +2 -2
  153. package/dist/components/forms/radio-group/theme.d.ts +2 -2
  154. package/dist/components/forms/search/theme.d.ts +8 -8
  155. package/dist/components/forms/select/Select.svelte +3 -2
  156. package/dist/components/forms/select/theme.d.ts +26 -2
  157. package/dist/components/forms/select/theme.js +56 -22
  158. package/dist/components/forms/slider/theme.d.ts +20 -20
  159. package/dist/components/forms/switch/theme.d.ts +2 -2
  160. package/dist/components/forms/textfield/Textfield.stories.svelte +22 -0
  161. package/dist/components/forms/textfield/Textfield.svelte +10 -1
  162. package/dist/components/forms/textfield/theme.d.ts +44 -2
  163. package/dist/components/forms/textfield/theme.js +56 -16
  164. package/dist/components/forms/toggle-group/ToggleGroup.svelte +2 -2
  165. package/dist/components/forms/toggle-group/ToggleGroup.svelte.d.ts +2 -2
  166. package/dist/components/forms/toggle-group/ToggleGroupItem.svelte +1 -1
  167. package/dist/components/forms/toggle-group/ToggleGroupItem.svelte.d.ts +1 -1
  168. package/dist/components/forms/toggle-group/theme.d.ts +16 -16
  169. package/dist/components/forms/toggle-group/types.d.ts +2 -2
  170. package/dist/components/forms/tooltip/Tooltip.svelte +1 -1
  171. package/dist/components/forms/tooltip/theme.d.ts +2 -2
  172. package/dist/components/index.d.ts +1 -0
  173. package/dist/components/index.js +1 -0
  174. package/dist/components/misc/Avatar.stories.svelte +8 -0
  175. package/dist/components/misc/Avatar.svelte +35 -10
  176. package/dist/components/misc/DicebearAvatarBuilder.d.ts +59 -0
  177. package/dist/components/misc/DicebearAvatarBuilder.js +115 -0
  178. package/dist/components/misc/ThemeSettings.svelte +1 -1
  179. package/dist/components/misc/ThemeSwitcher.svelte +2 -2
  180. package/dist/components/misc/dicebearStyles.d.ts +21 -0
  181. package/dist/components/misc/dicebearStyles.js +169 -0
  182. package/dist/components/misc/index.d.ts +3 -0
  183. package/dist/components/misc/index.js +3 -0
  184. package/dist/components/misc/materialAvatarPalette.d.ts +6 -0
  185. package/dist/components/misc/materialAvatarPalette.js +44 -0
  186. package/dist/components/misc/theme.d.ts +20 -2
  187. package/dist/components/misc/theme.js +7 -1
  188. package/dist/components/misc/types.d.ts +20 -2
  189. package/dist/components/nav/appbar/AppBar.stories.svelte +1 -1
  190. package/dist/components/nav/appbar/AppBar.svelte +46 -15
  191. package/dist/components/nav/appbar/AppBar.svelte.d.ts +5 -0
  192. package/dist/components/nav/appbar/theme.d.ts +20 -14
  193. package/dist/components/nav/appbar/theme.js +11 -7
  194. package/dist/components/nav/appbar/types.d.ts +3 -1
  195. package/dist/components/nav/breadcrumb/Breadcrumb.stories.svelte +50 -0
  196. package/dist/components/nav/breadcrumb/Breadcrumb.stories.svelte.d.ts +19 -0
  197. package/dist/components/nav/breadcrumb/Breadcrumb.svelte +46 -0
  198. package/dist/components/nav/breadcrumb/Breadcrumb.svelte.d.ts +13 -0
  199. package/dist/components/nav/breadcrumb/index.d.ts +3 -0
  200. package/dist/components/nav/breadcrumb/index.js +6 -0
  201. package/dist/components/nav/breadcrumb/theme.d.ts +84 -0
  202. package/dist/components/nav/breadcrumb/theme.js +35 -0
  203. package/dist/components/nav/breadcrumb/types.d.ts +14 -0
  204. package/dist/components/nav/breadcrumb/types.js +1 -0
  205. package/dist/components/nav/index.d.ts +1 -0
  206. package/dist/components/nav/index.js +1 -0
  207. package/dist/components/nav/navbar/theme.d.ts +19 -19
  208. package/dist/components/nav/rail/Rail.stories.svelte +1 -5
  209. package/dist/components/nav/rail/Rail.svelte +3 -25
  210. package/dist/components/nav/rail/theme.d.ts +4 -4
  211. package/dist/components/nav/rail/types.d.ts +0 -5
  212. package/dist/components/nav/tabs/TabHolder.svelte +2 -1
  213. package/dist/components/nav/tabs/theme.d.ts +21 -21
  214. package/dist/components/nav/tabs/theme.js +6 -0
  215. package/dist/components/nav/tabs/types.d.ts +2 -2
  216. package/dist/components/pill/theme.d.ts +35 -35
  217. package/dist/components/snackbar/theme.d.ts +8 -8
  218. package/dist/components/table/Table.stories.svelte +267 -0
  219. package/dist/components/table/Table.stories.svelte.d.ts +19 -0
  220. package/dist/components/table/Table.svelte +1 -1
  221. package/dist/components/table/TableBody.svelte +16 -3
  222. package/dist/components/table/TableBody.svelte.d.ts +5 -1
  223. package/dist/components/table/TableRow.svelte +1 -1
  224. package/dist/components/table/theme.d.ts +2 -2
  225. package/dist/components/table/theme.js +2 -2
  226. package/dist/components/table/types.d.ts +7 -0
  227. package/dist/components/time/theme.d.ts +29 -29
  228. package/dist/components/toolbar/Toolbar.stories.svelte +71 -0
  229. package/dist/components/toolbar/Toolbar.stories.svelte.d.ts +19 -0
  230. package/dist/components/toolbar/Toolbar.svelte +19 -3
  231. package/dist/components/toolbar/Toolbar.svelte.d.ts +8 -2
  232. package/dist/components/toolbar/ToolbarButton.svelte +28 -4
  233. package/dist/components/toolbar/ToolbarDivider.svelte +4 -3
  234. package/dist/components/toolbar/ToolbarGroup.svelte +7 -2
  235. package/dist/components/toolbar/ToolbarGroupItem.svelte +29 -4
  236. package/dist/components/toolbar/ToolbarSection.svelte +35 -0
  237. package/dist/components/toolbar/ToolbarSection.svelte.d.ts +9 -0
  238. package/dist/components/toolbar/ToolbarSpacer.svelte +18 -0
  239. package/dist/components/toolbar/ToolbarSpacer.svelte.d.ts +9 -0
  240. package/dist/components/toolbar/index.d.ts +2 -0
  241. package/dist/components/toolbar/index.js +2 -0
  242. package/dist/components/toolbar/theme.d.ts +36 -21
  243. package/dist/components/toolbar/theme.js +27 -11
  244. package/dist/components/toolbar/types.d.ts +37 -4
  245. package/dist/components/typography/body/theme.d.ts +14 -14
  246. package/dist/components/typography/display/theme.d.ts +14 -14
  247. package/dist/components/typography/headline/theme.d.ts +14 -14
  248. package/dist/components/typography/kbd/Kbd.stories.svelte +1 -1
  249. package/dist/components/typography/kbd/theme.d.ts +8 -8
  250. package/dist/components/typography/label/theme.d.ts +14 -14
  251. package/dist/components/typography/title/theme.d.ts +14 -14
  252. package/dist/styles/component.css +126 -4
  253. package/dist/styles/motion.css +6 -3
  254. package/dist/utils/Layer.svelte +7 -3
  255. package/dist/utils/Theme.svelte +20 -20
  256. package/dist/utils/ThemeScript.svelte +1 -1
  257. package/dist/utils/icon/theme.d.ts +14 -14
  258. package/dist/utils/theme.svelte.js +1 -1
  259. package/package.json +39 -38
  260. package/bin/install-skill.js +0 -29
  261. package/dist/components/buttons/button-group/ButtonGroupItem.svelte +0 -41
  262. package/dist/components/buttons/button-group/ButtonGroupItem.svelte.d.ts +0 -8
  263. package/dist/components/buttons/connected/ConnectedButtons.svelte +0 -14
  264. package/dist/components/buttons/connected/ConnectedButtons.svelte.d.ts +0 -8
  265. package/dist/components/containers/menu-item/MenuItem.svelte +0 -74
  266. package/dist/components/containers/merger/InputMerger.svelte +0 -24
  267. package/dist/components/containers/merger/InputMerger.svelte.d.ts +0 -14
  268. package/dist/components/containers/merger/index.d.ts +0 -2
  269. package/dist/components/containers/merger/theme.d.ts +0 -1
  270. package/dist/components/containers/merger/theme.js +0 -4
  271. package/dist/components/containers/panes/SinglePane.stories.svelte +0 -67
  272. package/dist/components/containers/panes/SinglePane.svelte +0 -32
  273. package/dist/components/containers/panes/SinglePane.svelte.d.ts +0 -5
  274. package/dist/components/containers/panes/SplitPane.stories.svelte +0 -124
  275. package/dist/components/containers/panes/SplitPane.svelte +0 -144
  276. package/dist/components/containers/panes/SplitPane.svelte.d.ts +0 -8
  277. package/dist/components/containers/panes/SupportingPane.stories.svelte +0 -113
  278. package/dist/components/containers/panes/SupportingPane.svelte +0 -175
  279. package/dist/components/containers/panes/SupportingPane.svelte.d.ts +0 -9
  280. package/dist/components/containers/panes/index.d.ts +0 -5
  281. package/dist/components/containers/panes/theme.d.ts +0 -490
  282. package/dist/components/containers/panes/theme.js +0 -185
  283. package/dist/components/containers/panes/types.d.ts +0 -108
  284. package/dist/components/nav/rail/RailNavContext.svelte +0 -14
  285. package/dist/components/nav/rail/RailNavContext.svelte.d.ts +0 -8
  286. /package/dist/components/{containers/menu-item → buttons/split-button}/types.js +0 -0
  287. /package/dist/components/{containers/panes → chips}/types.js +0 -0
  288. /package/dist/components/containers/{menu-item → menu/menu-item}/index.d.ts +0 -0
  289. /package/dist/components/containers/{menu-item → menu/menu-item}/index.js +0 -0
@@ -0,0 +1,533 @@
1
+ <!--
2
+ @component
3
+ A floating panel that can be dragged anywhere within `bounds` by its header,
4
+ resized from any edge/corner when `resizable`, and collapsed into a small
5
+ fixed-corner pill when `collapsible`. Unlike `Pane`/`PaneGrid`, which lay out
6
+ fixed regions in normal flow, a `DraggablePane` floats above content
7
+ (`position: fixed`, elevated surface) and is positioned by `x`/`y` rather than
8
+ participating in flex layout. With `persistKey`, its last dragged position and
9
+ size survive reloads via `localStorage`.
10
+
11
+ Even with `width`/`height` unset (content-sized), the panel always carries a
12
+ standing `max-width`/`max-height` — `maxWidth`/`maxHeight` capped by `bounds`
13
+ (see `sizeCaps()`) — so content taller/wider than that ceiling scrolls inside
14
+ the `content` slot instead of rendering off-screen with no way to reach it.
15
+
16
+ `onClickOutside` fires on any pointer click landing outside the panel (header,
17
+ content, and resize handles all count as inside) while expanded — pass
18
+ `onClose` there to dismiss on outside click, or drive `collapsed` for a
19
+ minimize-on-outside-click panel.
20
+
21
+ Note: with `bounds` set to an element, the clamp is computed from that
22
+ element's rect at drag/resize/nudge time; a `ResizeObserver` on `bounds`
23
+ plus a capturing window `scroll` listener keep it recomputed as that
24
+ element resizes or scrolls (itself or via any scrolling ancestor), since
25
+ the pane itself stays `position: fixed` and doesn't move with either.
26
+ -->
27
+ <script lang="ts">
28
+ import clsx from 'clsx';
29
+ import { onMount } from 'svelte';
30
+ import { Icon, Layer } from '../../../utils/index.js';
31
+ import { ButtonIcon } from '../../buttons/index.js';
32
+ import { clickOutside } from '../../../actions/index.js';
33
+ import { draggablePane, type ResizeEdge } from './theme.js';
34
+ import { dragPositions } from './dragStore.svelte.js';
35
+ import type { DraggablePaneProps } from './types.js';
36
+
37
+ let {
38
+ children,
39
+ header,
40
+ title,
41
+ onClose,
42
+ onClickOutside,
43
+ x = $bindable(undefined),
44
+ y = $bindable(undefined),
45
+ initialX = 24,
46
+ initialY = 24,
47
+ persistKey,
48
+ bounds = 'viewport',
49
+ boundsPadding = 8,
50
+ width = $bindable(undefined),
51
+ height = $bindable(undefined),
52
+ resizable = false,
53
+ minWidth = 200,
54
+ minHeight = 160,
55
+ maxWidth,
56
+ maxHeight,
57
+ disableDrag = false,
58
+ collapsible = false,
59
+ collapsed = $bindable(false),
60
+ minimizedTitle,
61
+ minimizedCorner = 'bottom-left',
62
+ minimizedClass,
63
+ class: className,
64
+ contentClass,
65
+ ...rest
66
+ }: DraggablePaneProps = $props();
67
+
68
+ let panelEl: HTMLDivElement | undefined = $state();
69
+ let dragging = $state(false);
70
+ let resizeDir: ResizeEdge | null = $state(null);
71
+ /**
72
+ * The standing `max-width`/`max-height` ceiling (`sizeCaps()`, tracked
73
+ * live) — applied via `style` regardless of whether `height`/`width` are
74
+ * set, so a content-sized pane (the default — see `height`'s docs) can't
75
+ * render taller/wider than `bounds` with no way to reach the rest of it.
76
+ * Undefined only before the first `onMount`/`recomputeBounds` run — which
77
+ * includes SSR, since both only run client-side. Also read directly for
78
+ * the resize handles' `aria-valuemax` instead of calling `sizeCaps()`
79
+ * fresh in the template: that call site runs during SSR too (it's a plain
80
+ * expression producing HTML), and `sizeCaps()` → `boundsRect()` touches
81
+ * `window`/`HTMLElement`, which don't exist there.
82
+ */
83
+ let capWidth: number | undefined = $state();
84
+ let capHeight: number | undefined = $state();
85
+
86
+ const active = $derived(dragging || resizeDir !== null);
87
+
88
+ const { base, headerBar, grip, headline, actions, content, miniBase, miniIcon, miniLabel } =
89
+ $derived(draggablePane({ dragging: active, disableDrag, corner: minimizedCorner }));
90
+
91
+ // Once resizable, min-width/min-height move from the base slot's static
92
+ // `min-w-72` class to inline styles driven by the minWidth/minHeight props
93
+ // — a class-based min-width would win over a smaller inline `width`
94
+ // regardless of what those props say, silently overriding the safety-net
95
+ // floor a consumer configured. A non-resizable pane keeps the plain
96
+ // `min-w-72` class fallback (unaffected by minWidth/minHeight).
97
+ const style = $derived(
98
+ clsx(
99
+ x !== undefined && `left: ${x}px;`,
100
+ y !== undefined && `top: ${y}px;`,
101
+ width !== undefined && `width: ${width}px;`,
102
+ height !== undefined && `height: ${height}px;`,
103
+ resizable && `min-width: ${minWidth}px;`,
104
+ resizable && `min-height: ${minHeight}px;`,
105
+ capWidth !== undefined && `max-width: ${capWidth}px;`,
106
+ capHeight !== undefined && `max-height: ${capHeight}px;`
107
+ )
108
+ );
109
+
110
+ function persist() {
111
+ if (!persistKey) return;
112
+ dragPositions.set(persistKey, { x: x ?? initialX, y: y ?? initialY, width, height });
113
+ }
114
+
115
+ function boundsRect() {
116
+ if (bounds instanceof HTMLElement) {
117
+ const rect = bounds.getBoundingClientRect();
118
+ return { left: rect.left, top: rect.top, right: rect.right, bottom: rect.bottom };
119
+ }
120
+ return { left: 0, top: 0, right: window.innerWidth, bottom: window.innerHeight };
121
+ }
122
+
123
+ function clamp(
124
+ nextX: number,
125
+ nextY: number,
126
+ w = width ?? panelEl?.offsetWidth ?? 0,
127
+ h = height ?? panelEl?.offsetHeight ?? 0
128
+ ) {
129
+ const rect = boundsRect();
130
+ const minX = rect.left + boundsPadding;
131
+ const maxX = Math.max(minX, rect.right - w - boundsPadding);
132
+ const minY = rect.top + boundsPadding;
133
+ const maxY = Math.max(minY, rect.bottom - h - boundsPadding);
134
+ return {
135
+ x: Math.min(Math.max(nextX, minX), maxX),
136
+ y: Math.min(Math.max(nextY, minY), maxY)
137
+ };
138
+ }
139
+
140
+ /** The effective width/height ceiling right now: `maxWidth`/`maxHeight` capped by `bounds`. */
141
+ function sizeCaps() {
142
+ const rect = boundsRect();
143
+ const availW = rect.right - rect.left - boundsPadding * 2;
144
+ const availH = rect.bottom - rect.top - boundsPadding * 2;
145
+ return {
146
+ width: Math.max(minWidth, Math.min(maxWidth ?? Infinity, availW)),
147
+ height: Math.max(minHeight, Math.min(maxHeight ?? Infinity, availH))
148
+ };
149
+ }
150
+
151
+ /** Refreshes `capWidth`/`capHeight` from `sizeCaps()` — call whenever `bounds`'s rect or the cap inputs may have changed. */
152
+ function updateCaps() {
153
+ const caps = sizeCaps();
154
+ capWidth = caps.width;
155
+ capHeight = caps.height;
156
+ }
157
+
158
+ /** Clamps a candidate size to `minWidth`/`minHeight` (a hard floor) and `maxWidth`/`maxHeight`/`bounds` (a ceiling). */
159
+ function clampSize(w: number, h: number) {
160
+ const caps = sizeCaps();
161
+ return {
162
+ width: Math.min(Math.max(w, minWidth), caps.width),
163
+ height: Math.min(Math.max(h, minHeight), caps.height)
164
+ };
165
+ }
166
+
167
+ function moveTo(nextX: number, nextY: number) {
168
+ const next = clamp(nextX, nextY);
169
+ x = next.x;
170
+ y = next.y;
171
+ persist();
172
+ }
173
+
174
+ /**
175
+ * Grows/shrinks from `dir`'s edge(s), keeping the opposite edge(s) fixed —
176
+ * pure math from an explicit (baseW, baseH, baseX, baseY) baseline plus a
177
+ * (dx, dy) offset from it, so callers can pick their own baseline: the
178
+ * pointer-drag start position (cumulative offset, recomputed fresh each
179
+ * move so drift can't accumulate — see `moveResize`), or the current state
180
+ * (a one-shot incremental nudge — see `resizeKeydown`).
181
+ */
182
+ function computeResize(
183
+ dir: ResizeEdge,
184
+ baseW: number,
185
+ baseH: number,
186
+ baseX: number,
187
+ baseY: number,
188
+ dx: number,
189
+ dy: number
190
+ ) {
191
+ let w = baseW;
192
+ let h = baseH;
193
+ if (dir.includes('e')) w = baseW + dx;
194
+ if (dir.includes('w')) w = baseW - dx;
195
+ if (dir.includes('s')) h = baseH + dy;
196
+ if (dir.includes('n')) h = baseH - dy;
197
+
198
+ const clamped = clampSize(w, h);
199
+
200
+ let nextX = baseX;
201
+ let nextY = baseY;
202
+ if (dir.includes('w')) nextX = baseX + (baseW - clamped.width);
203
+ if (dir.includes('n')) nextY = baseY + (baseH - clamped.height);
204
+
205
+ return {
206
+ width: clamped.width,
207
+ height: clamped.height,
208
+ x: nextX,
209
+ y: nextY,
210
+ moved: dir.includes('w') || dir.includes('n')
211
+ };
212
+ }
213
+
214
+ function applyResize(result: ReturnType<typeof computeResize>) {
215
+ let w = result.width;
216
+ let h = result.height;
217
+ if (result.moved) {
218
+ const posClamped = clamp(result.x, result.y, w, h);
219
+ // A w/n resize keeps its opposite (anchor) edge fixed by construction
220
+ // (see computeResize) — but if boundsPadding then clamps the position
221
+ // further, the anchor would drift unless the size shrinks by the same
222
+ // amount the position got held back.
223
+ if (posClamped.x !== result.x) w = Math.max(minWidth, w - (posClamped.x - result.x));
224
+ if (posClamped.y !== result.y) h = Math.max(minHeight, h - (posClamped.y - result.y));
225
+ x = posClamped.x;
226
+ y = posClamped.y;
227
+ }
228
+ width = w;
229
+ height = h;
230
+ persist();
231
+ }
232
+
233
+ /** One-shot incremental resize from the current state — for keyboard nudges. */
234
+ function nudgeResize(dir: ResizeEdge, dx: number, dy: number) {
235
+ applyResize(
236
+ computeResize(
237
+ dir,
238
+ width ?? panelEl?.offsetWidth ?? minWidth,
239
+ height ?? panelEl?.offsetHeight ?? minHeight,
240
+ x ?? initialX,
241
+ y ?? initialY,
242
+ dx,
243
+ dy
244
+ )
245
+ );
246
+ }
247
+
248
+ /** Re-clamps the current position/size, and the standing size cap, against `bounds`'s current rect — call whenever that rect may have changed. */
249
+ function recomputeBounds() {
250
+ updateCaps();
251
+ moveTo(x ?? initialX, y ?? initialY);
252
+ if (width !== undefined || height !== undefined) nudgeResize('se', 0, 0);
253
+ }
254
+
255
+ onMount(() => {
256
+ const fallback = { x: x ?? initialX, y: y ?? initialY, width, height };
257
+ const hydrated = persistKey ? dragPositions.hydrate(persistKey, fallback) : fallback;
258
+ width = hydrated.width;
259
+ height = hydrated.height;
260
+ updateCaps();
261
+ const clamped = clamp(
262
+ hydrated.x,
263
+ hydrated.y,
264
+ hydrated.width ?? panelEl?.offsetWidth ?? 0,
265
+ hydrated.height ?? panelEl?.offsetHeight ?? 0
266
+ );
267
+ x = clamped.x;
268
+ y = clamped.y;
269
+ persist();
270
+
271
+ window.addEventListener('resize', recomputeBounds);
272
+ return () => window.removeEventListener('resize', recomputeBounds);
273
+ });
274
+
275
+ // `bounds` can be an element that resizes or scrolls independently of the
276
+ // window (e.g. via a scrolling ancestor) — a plain window `resize`
277
+ // listener misses both, so its rect is tracked directly whenever it's an
278
+ // element. Capturing `scroll` catches any scrolling ancestor, not just
279
+ // `bounds` itself, since scroll events don't bubble. Reading
280
+ // maxWidth/maxHeight/minWidth/minHeight up front (via updateCaps) also
281
+ // makes this effect re-run — and the cap refresh — when those change.
282
+ $effect(() => {
283
+ updateCaps();
284
+ if (!(bounds instanceof HTMLElement)) return;
285
+ const target = bounds;
286
+ const ro = new ResizeObserver(recomputeBounds);
287
+ ro.observe(target);
288
+ window.addEventListener('scroll', recomputeBounds, true);
289
+ return () => {
290
+ ro.disconnect();
291
+ window.removeEventListener('scroll', recomputeBounds, true);
292
+ };
293
+ });
294
+
295
+ $effect(() => {
296
+ if (!persistKey) return;
297
+ const stored = dragPositions.get(persistKey);
298
+ if (stored) {
299
+ x = stored.x;
300
+ y = stored.y;
301
+ }
302
+ });
303
+
304
+ let dragStartX = 0;
305
+ let dragStartY = 0;
306
+ let originX = 0;
307
+ let originY = 0;
308
+
309
+ function startDrag(event: PointerEvent) {
310
+ if (disableDrag) return;
311
+ dragging = true;
312
+ dragStartX = event.clientX;
313
+ dragStartY = event.clientY;
314
+ originX = x ?? initialX;
315
+ originY = y ?? initialY;
316
+ (event.currentTarget as HTMLElement).setPointerCapture(event.pointerId);
317
+ }
318
+
319
+ function moveDrag(event: PointerEvent) {
320
+ if (!dragging) return;
321
+ moveTo(originX + (event.clientX - dragStartX), originY + (event.clientY - dragStartY));
322
+ }
323
+
324
+ function endDrag() {
325
+ dragging = false;
326
+ }
327
+
328
+ const NUDGE = 8;
329
+
330
+ function onKeydown(event: KeyboardEvent) {
331
+ if (disableDrag) return;
332
+ const step = event.shiftKey ? NUDGE * 4 : NUDGE;
333
+ const deltas: Record<string, [number, number]> = {
334
+ ArrowUp: [0, -step],
335
+ ArrowDown: [0, step],
336
+ ArrowLeft: [-step, 0],
337
+ ArrowRight: [step, 0]
338
+ };
339
+ const delta = deltas[event.key];
340
+ if (!delta) return;
341
+ event.preventDefault();
342
+ moveTo((x ?? initialX) + delta[0], (y ?? initialY) + delta[1]);
343
+ }
344
+
345
+ let resizeStartClientX = 0;
346
+ let resizeStartClientY = 0;
347
+ let resizeStartWidth = 0;
348
+ let resizeStartHeight = 0;
349
+ let resizeStartPosX = 0;
350
+ let resizeStartPosY = 0;
351
+
352
+ function startResize(dir: ResizeEdge) {
353
+ return (event: PointerEvent) => {
354
+ if (!resizable) return;
355
+ event.stopPropagation();
356
+ resizeDir = dir;
357
+ resizeStartClientX = event.clientX;
358
+ resizeStartClientY = event.clientY;
359
+ resizeStartWidth = width ?? panelEl?.offsetWidth ?? minWidth;
360
+ resizeStartHeight = height ?? panelEl?.offsetHeight ?? minHeight;
361
+ resizeStartPosX = x ?? initialX;
362
+ resizeStartPosY = y ?? initialY;
363
+ (event.currentTarget as HTMLElement).setPointerCapture(event.pointerId);
364
+ };
365
+ }
366
+
367
+ // Deliberately recomputed from the fixed (resizeStartClientX/Y) baseline on
368
+ // every move rather than accumulated via `event.movementX`/`movementY` —
369
+ // the latter isn't reliably populated across every input path (some
370
+ // synthetic/automated drag sequences leave it 0), which would silently
371
+ // drop the resize. Matches `moveDrag`'s baseline-delta approach.
372
+ function moveResize(event: PointerEvent) {
373
+ if (!resizeDir) return;
374
+ applyResize(
375
+ computeResize(
376
+ resizeDir,
377
+ resizeStartWidth,
378
+ resizeStartHeight,
379
+ resizeStartPosX,
380
+ resizeStartPosY,
381
+ event.clientX - resizeStartClientX,
382
+ event.clientY - resizeStartClientY
383
+ )
384
+ );
385
+ }
386
+
387
+ function endResize() {
388
+ resizeDir = null;
389
+ }
390
+
391
+ const edgeAxis: Record<'n' | 's' | 'e' | 'w', 'horizontal' | 'vertical'> = {
392
+ n: 'horizontal',
393
+ s: 'horizontal',
394
+ e: 'vertical',
395
+ w: 'vertical'
396
+ };
397
+
398
+ const edgeLabel: Record<'n' | 's' | 'e' | 'w', string> = {
399
+ n: 'top edge',
400
+ s: 'bottom edge',
401
+ e: 'right edge',
402
+ w: 'left edge'
403
+ };
404
+
405
+ function resizeKeydown(dir: 'n' | 's' | 'e' | 'w') {
406
+ return (event: KeyboardEvent) => {
407
+ if (!resizable) return;
408
+ const step = event.shiftKey ? NUDGE * 4 : NUDGE;
409
+ const deltas: Record<string, [number, number]> = {
410
+ ArrowRight: [step, 0],
411
+ ArrowLeft: [-step, 0],
412
+ ArrowDown: [0, step],
413
+ ArrowUp: [0, -step]
414
+ };
415
+ const delta = deltas[event.key];
416
+ if (!delta) return;
417
+ event.preventDefault();
418
+ nudgeResize(dir, delta[0], delta[1]);
419
+ };
420
+ }
421
+
422
+ const edges = ['n', 's', 'e', 'w'] as const;
423
+ const corners = ['ne', 'nw', 'se', 'sw'] as const;
424
+ </script>
425
+
426
+ {#if collapsed}
427
+ <button
428
+ type="button"
429
+ class={miniBase({ class: minimizedClass })}
430
+ onclick={() => (collapsed = false)}
431
+ aria-label={`Expand ${minimizedTitle ?? title ?? 'panel'}`}
432
+ >
433
+ <Icon name="open_in_full" size="sm" class={miniIcon()} />
434
+ <span class={miniLabel()}>{minimizedTitle ?? title}</span>
435
+ </button>
436
+ {:else}
437
+ <div
438
+ bind:this={panelEl}
439
+ class={base({ class: className })}
440
+ {style}
441
+ role="group"
442
+ aria-label={title}
443
+ use:clickOutside={() => onClickOutside?.()}
444
+ {...rest}
445
+ >
446
+ <div
447
+ class={headerBar()}
448
+ role="button"
449
+ tabindex={disableDrag ? undefined : 0}
450
+ aria-label={disableDrag ? undefined : title ? `Drag to move ${title}` : 'Drag to move'}
451
+ aria-keyshortcuts={disableDrag ? undefined : 'ArrowUp ArrowDown ArrowLeft ArrowRight'}
452
+ onpointerdown={disableDrag ? undefined : startDrag}
453
+ onpointermove={disableDrag ? undefined : moveDrag}
454
+ onpointerup={disableDrag ? undefined : endDrag}
455
+ onpointercancel={disableDrag ? undefined : endDrag}
456
+ onkeydown={disableDrag ? undefined : onKeydown}
457
+ >
458
+ {#if !disableDrag}
459
+ <Layer />
460
+ {/if}
461
+ {#if header}
462
+ {@render header()}
463
+ {:else}
464
+ {#if !disableDrag}
465
+ <Icon name="drag_indicator" class={grip()} />
466
+ {/if}
467
+ {#if title}
468
+ <span class={headline()}>{title}</span>
469
+ {/if}
470
+ {#if collapsible || onClose}
471
+ <div
472
+ class={actions()}
473
+ role="presentation"
474
+ onpointerdown={(event) => event.stopPropagation()}
475
+ >
476
+ {#if collapsible}
477
+ <ButtonIcon
478
+ variant="text"
479
+ size="sm"
480
+ iconProps={{ name: 'collapse_all' }}
481
+ aria-label="Minimize"
482
+ onclick={() => (collapsed = true)}
483
+ />
484
+ {/if}
485
+ {#if onClose}
486
+ <ButtonIcon
487
+ variant="text"
488
+ size="sm"
489
+ iconProps={{ name: 'close' }}
490
+ aria-label="Close"
491
+ onclick={onClose}
492
+ />
493
+ {/if}
494
+ </div>
495
+ {/if}
496
+ {/if}
497
+ </div>
498
+ <div class={content({ class: clsx(contentClass) })}>
499
+ {@render children()}
500
+ </div>
501
+ {#if resizable}
502
+ {#each edges as dir (dir)}
503
+ <div
504
+ class={draggablePane({ edge: dir }).resizeHandle()}
505
+ role="slider"
506
+ aria-orientation={edgeAxis[dir]}
507
+ aria-label={`Resize ${edgeLabel[dir]}`}
508
+ aria-valuenow={dir === 'e' || dir === 'w'
509
+ ? (width ?? panelEl?.offsetWidth)
510
+ : (height ?? panelEl?.offsetHeight)}
511
+ aria-valuemin={dir === 'e' || dir === 'w' ? minWidth : minHeight}
512
+ aria-valuemax={dir === 'e' || dir === 'w' ? capWidth : capHeight}
513
+ tabindex="0"
514
+ onpointerdown={startResize(dir)}
515
+ onpointermove={moveResize}
516
+ onpointerup={endResize}
517
+ onpointercancel={endResize}
518
+ onkeydown={resizeKeydown(dir)}
519
+ ></div>
520
+ {/each}
521
+ {#each corners as dir (dir)}
522
+ <div
523
+ class={draggablePane({ edge: dir }).resizeHandle()}
524
+ role="presentation"
525
+ onpointerdown={startResize(dir)}
526
+ onpointermove={moveResize}
527
+ onpointerup={endResize}
528
+ onpointercancel={endResize}
529
+ ></div>
530
+ {/each}
531
+ {/if}
532
+ </div>
533
+ {/if}
@@ -0,0 +1,29 @@
1
+ import type { DraggablePaneProps } from './types.js';
2
+ /**
3
+ * A floating panel that can be dragged anywhere within `bounds` by its header,
4
+ * resized from any edge/corner when `resizable`, and collapsed into a small
5
+ * fixed-corner pill when `collapsible`. Unlike `Pane`/`PaneGrid`, which lay out
6
+ * fixed regions in normal flow, a `DraggablePane` floats above content
7
+ * (`position: fixed`, elevated surface) and is positioned by `x`/`y` rather than
8
+ * participating in flex layout. With `persistKey`, its last dragged position and
9
+ * size survive reloads via `localStorage`.
10
+ *
11
+ * Even with `width`/`height` unset (content-sized), the panel always carries a
12
+ * standing `max-width`/`max-height` — `maxWidth`/`maxHeight` capped by `bounds`
13
+ * (see `sizeCaps()`) — so content taller/wider than that ceiling scrolls inside
14
+ * the `content` slot instead of rendering off-screen with no way to reach it.
15
+ *
16
+ * `onClickOutside` fires on any pointer click landing outside the panel (header,
17
+ * content, and resize handles all count as inside) while expanded — pass
18
+ * `onClose` there to dismiss on outside click, or drive `collapsed` for a
19
+ * minimize-on-outside-click panel.
20
+ *
21
+ * Note: with `bounds` set to an element, the clamp is computed from that
22
+ * element's rect at drag/resize/nudge time; a `ResizeObserver` on `bounds`
23
+ * plus a capturing window `scroll` listener keep it recomputed as that
24
+ * element resizes or scrolls (itself or via any scrolling ancestor), since
25
+ * the pane itself stays `position: fixed` and doesn't move with either.
26
+ */
27
+ declare const DraggablePane: import("svelte").Component<DraggablePaneProps, {}, "x" | "y" | "width" | "height" | "collapsed">;
28
+ type DraggablePane = ReturnType<typeof DraggablePane>;
29
+ export default DraggablePane;
@@ -0,0 +1,104 @@
1
+ <script module lang="ts">
2
+ import { defineMeta } from '@storybook/addon-svelte-csf';
3
+ import Pane from './Pane.svelte';
4
+ import AppBar from '../../nav/appbar/AppBar.svelte';
5
+
6
+ const { Story } = defineMeta({
7
+ title: 'Containers/Pane',
8
+ component: Pane,
9
+ argTypes: {
10
+ padding: {
11
+ control: 'select',
12
+ options: ['none', 'sm', 'md', 'lg']
13
+ },
14
+ gap: {
15
+ control: 'select',
16
+ options: ['none', 'sm', 'md', 'lg', 'xl']
17
+ },
18
+ background: { control: 'boolean' },
19
+ full: { control: 'boolean' },
20
+ rounded: { control: 'boolean' }
21
+ },
22
+ args: {
23
+ padding: 'md',
24
+ gap: 'md',
25
+ background: true,
26
+ full: false,
27
+ rounded: true
28
+ }
29
+ });
30
+ </script>
31
+
32
+ <!-- Standalone usage: a single page-level content region, the same role SinglePane used to play. -->
33
+ <Story name="Standalone">
34
+ {#snippet template(args)}
35
+ <Pane
36
+ padding={args.padding}
37
+ gap={args.gap}
38
+ background={args.background}
39
+ full={args.full}
40
+ rounded={args.rounded}
41
+ >
42
+ <div class="bg-md-sys-color-surface-container-high rounded-lg p-6">Block one</div>
43
+ <div class="bg-md-sys-color-surface-container-high rounded-lg p-6">Block two</div>
44
+ <div class="bg-md-sys-color-surface-container-high rounded-lg p-6">Block three</div>
45
+ </Pane>
46
+ {/snippet}
47
+ </Story>
48
+
49
+ <!-- Pane has no built-in centered-width variant — center content by passing `contentClass`. -->
50
+ <Story name="Centered Widths" asChild>
51
+ <div class="flex flex-col gap-6">
52
+ <Pane contentClass="max-w-2xl mx-auto" background={false}>
53
+ <div class="bg-md-sys-color-secondary-container rounded-lg p-4 text-sm">narrow</div>
54
+ </Pane>
55
+ <Pane contentClass="max-w-5xl mx-auto" background={false}>
56
+ <div class="bg-md-sys-color-secondary-container rounded-lg p-4 text-sm">medium</div>
57
+ </Pane>
58
+ <Pane background={false}>
59
+ <div class="bg-md-sys-color-secondary-container rounded-lg p-4 text-sm">
60
+ none (full width)
61
+ </div>
62
+ </Pane>
63
+ </div>
64
+ </Story>
65
+
66
+ <!--
67
+ As a PaneGrid child: an unset `width` makes a pane flexible (grows to fill
68
+ remaining space). See PaneGrid's own stories for direction/gap/margin/resizable
69
+ demos — this story is scoped to Pane's own props.
70
+ -->
71
+ <!--
72
+ A mounted AppBar's measured height is published to appbarStore.svelte.ts;
73
+ a `full` Pane (the default) reads it and subtracts it from `100dvh` so the
74
+ two don't stack into an overflow-scrolling page. No props needed on either
75
+ side — AppBar just needs to actually be mounted somewhere on the page.
76
+ -->
77
+ <Story name="With AppBar" asChild parameters={{ viewport: { defaultViewport: 'mobile1' } }}>
78
+ <AppBar title="Inbox" ghost />
79
+ <Pane>
80
+ <div class="bg-md-sys-color-secondary-container rounded-lg p-4 text-sm">
81
+ This pane's min-height is <code>100dvh</code> minus the AppBar's measured height above —
82
+ automatic, via <code>appbarStore.svelte.ts</code>.
83
+ </div>
84
+ </Pane>
85
+ </Story>
86
+
87
+ <Story name="As Grid Item" asChild>
88
+ <div
89
+ class="border-md-sys-color-outline-variant relative h-[280px] overflow-hidden rounded-lg border"
90
+ >
91
+ <div class="flex h-full">
92
+ <Pane width={200} background={false} padding="sm">
93
+ <div class="bg-md-sys-color-secondary-container h-full rounded-lg p-4 text-sm">
94
+ width=200 (fixed)
95
+ </div>
96
+ </Pane>
97
+ <Pane background={false} padding="sm">
98
+ <div class="bg-md-sys-color-surface-container-high h-full rounded-lg p-4 text-sm">
99
+ width unset (flexible, grows)
100
+ </div>
101
+ </Pane>
102
+ </div>
103
+ </div>
104
+ </Story>
@@ -0,0 +1,19 @@
1
+ import Pane from './Pane.svelte';
2
+ interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
3
+ new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
4
+ $$bindings?: Bindings;
5
+ } & Exports;
6
+ (internal: unknown, props: {
7
+ $$events?: Events;
8
+ $$slots?: Slots;
9
+ }): Exports & {
10
+ $set?: any;
11
+ $on?: any;
12
+ };
13
+ z_$$bindings?: Bindings;
14
+ }
15
+ declare const Pane: $$__sveltets_2_IsomorphicComponent<Record<string, never>, {
16
+ [evt: string]: CustomEvent<any>;
17
+ }, {}, {}, string>;
18
+ type Pane = InstanceType<typeof Pane>;
19
+ export default Pane;