@vuu-ui/vuu-layout 0.8.35 → 0.8.36

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 (249) hide show
  1. package/README.md +1 -0
  2. package/cjs/Component.js +14 -0
  3. package/cjs/Component.js.map +1 -0
  4. package/cjs/DraggableLayout.css +18 -0
  5. package/cjs/DraggableLayout.js +24 -0
  6. package/cjs/DraggableLayout.js.map +1 -0
  7. package/cjs/dock-layout/DockLayout.css +36 -0
  8. package/cjs/dock-layout/DockLayout.js +27 -0
  9. package/cjs/dock-layout/DockLayout.js.map +1 -0
  10. package/cjs/dock-layout/Drawer.css +159 -0
  11. package/cjs/dock-layout/Drawer.js +87 -0
  12. package/cjs/dock-layout/Drawer.js.map +1 -0
  13. package/cjs/drag-drop/BoxModel.js +422 -0
  14. package/cjs/drag-drop/BoxModel.js.map +1 -0
  15. package/cjs/drag-drop/DragState.js +154 -0
  16. package/cjs/drag-drop/DragState.js.map +1 -0
  17. package/cjs/drag-drop/Draggable.js +192 -0
  18. package/cjs/drag-drop/Draggable.js.map +1 -0
  19. package/cjs/drag-drop/DropMenu.css +71 -0
  20. package/cjs/drag-drop/DropMenu.js +46 -0
  21. package/cjs/drag-drop/DropMenu.js.map +1 -0
  22. package/cjs/drag-drop/DropTarget.js +244 -0
  23. package/cjs/drag-drop/DropTarget.js.map +1 -0
  24. package/cjs/drag-drop/DropTargetRenderer.css +40 -0
  25. package/cjs/drag-drop/DropTargetRenderer.js +233 -0
  26. package/cjs/drag-drop/DropTargetRenderer.js.map +1 -0
  27. package/cjs/flexbox/Flexbox.css +45 -0
  28. package/cjs/flexbox/Flexbox.js +61 -0
  29. package/cjs/flexbox/Flexbox.js.map +1 -0
  30. package/cjs/flexbox/FlexboxLayout.js +30 -0
  31. package/cjs/flexbox/FlexboxLayout.js.map +1 -0
  32. package/cjs/flexbox/FluidGrid.css +134 -0
  33. package/cjs/flexbox/FluidGrid.js +78 -0
  34. package/cjs/flexbox/FluidGrid.js.map +1 -0
  35. package/cjs/flexbox/FluidGridLayout.js +14 -0
  36. package/cjs/flexbox/FluidGridLayout.js.map +1 -0
  37. package/cjs/flexbox/Splitter.css +148 -0
  38. package/cjs/flexbox/Splitter.js +113 -0
  39. package/cjs/flexbox/Splitter.js.map +1 -0
  40. package/cjs/flexbox/flexbox-utils.js +109 -0
  41. package/cjs/flexbox/flexbox-utils.js.map +1 -0
  42. package/cjs/flexbox/useResponsiveSizing.js +62 -0
  43. package/cjs/flexbox/useResponsiveSizing.js.map +1 -0
  44. package/cjs/flexbox/useSplitterResizing.js +209 -0
  45. package/cjs/flexbox/useSplitterResizing.js.map +1 -0
  46. package/cjs/index.js.map +1 -0
  47. package/cjs/layout-action.js +27 -0
  48. package/cjs/layout-action.js.map +1 -0
  49. package/cjs/layout-header/Header.css +9 -0
  50. package/cjs/layout-header/Header.js +122 -0
  51. package/cjs/layout-header/Header.js.map +1 -0
  52. package/cjs/layout-provider/LayoutProvider.js +178 -0
  53. package/cjs/layout-provider/LayoutProvider.js.map +1 -0
  54. package/cjs/layout-provider/LayoutProviderContext.js +14 -0
  55. package/cjs/layout-provider/LayoutProviderContext.js.map +1 -0
  56. package/cjs/layout-provider/useLayoutDragDrop.js +170 -0
  57. package/cjs/layout-provider/useLayoutDragDrop.js.map +1 -0
  58. package/cjs/layout-reducer/flexUtils.js +219 -0
  59. package/cjs/layout-reducer/flexUtils.js.map +1 -0
  60. package/cjs/layout-reducer/insert-layout-element.js +273 -0
  61. package/cjs/layout-reducer/insert-layout-element.js.map +1 -0
  62. package/cjs/layout-reducer/layout-reducer.js +198 -0
  63. package/cjs/layout-reducer/layout-reducer.js.map +1 -0
  64. package/cjs/layout-reducer/layoutTypes.js +41 -0
  65. package/cjs/layout-reducer/layoutTypes.js.map +1 -0
  66. package/cjs/layout-reducer/layoutUtils.js +226 -0
  67. package/cjs/layout-reducer/layoutUtils.js.map +1 -0
  68. package/cjs/layout-reducer/move-layout-element.js +31 -0
  69. package/cjs/layout-reducer/move-layout-element.js.map +1 -0
  70. package/cjs/layout-reducer/remove-layout-element.js +223 -0
  71. package/cjs/layout-reducer/remove-layout-element.js.map +1 -0
  72. package/cjs/layout-reducer/replace-layout-element.js +91 -0
  73. package/cjs/layout-reducer/replace-layout-element.js.map +1 -0
  74. package/cjs/layout-reducer/resize-flex-children.js +61 -0
  75. package/cjs/layout-reducer/resize-flex-children.js.map +1 -0
  76. package/cjs/layout-reducer/wrap-layout-element.js +212 -0
  77. package/cjs/layout-reducer/wrap-layout-element.js.map +1 -0
  78. package/cjs/layout-view/View.css +62 -0
  79. package/cjs/layout-view/View.js +155 -0
  80. package/cjs/layout-view/View.js.map +1 -0
  81. package/cjs/layout-view/useView.js +92 -0
  82. package/cjs/layout-view/useView.js.map +1 -0
  83. package/cjs/layout-view/useViewResize.js +42 -0
  84. package/cjs/layout-view/useViewResize.js.map +1 -0
  85. package/cjs/layout-view-actions/ViewContext.js +16 -0
  86. package/cjs/layout-view-actions/ViewContext.js.map +1 -0
  87. package/cjs/layout-view-actions/useViewActionDispatcher.js +103 -0
  88. package/cjs/layout-view-actions/useViewActionDispatcher.js.map +1 -0
  89. package/cjs/palette/Palette.css +33 -0
  90. package/cjs/palette/Palette.js +118 -0
  91. package/cjs/palette/Palette.js.map +1 -0
  92. package/cjs/placeholder/LayoutStartPanel.css +30 -0
  93. package/cjs/placeholder/LayoutStartPanel.js +51 -0
  94. package/cjs/placeholder/LayoutStartPanel.js.map +1 -0
  95. package/cjs/placeholder/Placeholder.css +17 -0
  96. package/cjs/placeholder/Placeholder.js +25 -0
  97. package/cjs/placeholder/Placeholder.js.map +1 -0
  98. package/cjs/registry/ComponentRegistry.js +27 -0
  99. package/cjs/registry/ComponentRegistry.js.map +1 -0
  100. package/cjs/responsive/breakpoints.js +36 -0
  101. package/cjs/responsive/breakpoints.js.map +1 -0
  102. package/cjs/responsive/use-breakpoints.js +76 -0
  103. package/cjs/responsive/use-breakpoints.js.map +1 -0
  104. package/cjs/responsive/useResizeObserver.js +118 -0
  105. package/cjs/responsive/useResizeObserver.js.map +1 -0
  106. package/cjs/responsive/utils.js +34 -0
  107. package/cjs/responsive/utils.js.map +1 -0
  108. package/cjs/stack/Stack.css +39 -0
  109. package/cjs/stack/Stack.js +139 -0
  110. package/cjs/stack/Stack.js.map +1 -0
  111. package/cjs/stack/StackLayout.js +122 -0
  112. package/cjs/stack/StackLayout.js.map +1 -0
  113. package/cjs/use-persistent-state.js +109 -0
  114. package/cjs/use-persistent-state.js.map +1 -0
  115. package/cjs/utils/pathUtils.js +293 -0
  116. package/cjs/utils/pathUtils.js.map +1 -0
  117. package/cjs/utils/propUtils.js +27 -0
  118. package/cjs/utils/propUtils.js.map +1 -0
  119. package/cjs/utils/refUtils.js +12 -0
  120. package/cjs/utils/refUtils.js.map +1 -0
  121. package/cjs/utils/styleUtils.js +15 -0
  122. package/cjs/utils/styleUtils.js.map +1 -0
  123. package/cjs/utils/typeOf.js +27 -0
  124. package/cjs/utils/typeOf.js.map +1 -0
  125. package/esm/Component.js +12 -0
  126. package/esm/Component.js.map +1 -0
  127. package/esm/DraggableLayout.css +18 -0
  128. package/esm/DraggableLayout.js +22 -0
  129. package/esm/DraggableLayout.js.map +1 -0
  130. package/esm/dock-layout/DockLayout.css +36 -0
  131. package/esm/dock-layout/DockLayout.js +25 -0
  132. package/esm/dock-layout/DockLayout.js.map +1 -0
  133. package/esm/dock-layout/Drawer.css +159 -0
  134. package/esm/dock-layout/Drawer.js +85 -0
  135. package/esm/dock-layout/Drawer.js.map +1 -0
  136. package/esm/drag-drop/BoxModel.js +415 -0
  137. package/esm/drag-drop/BoxModel.js.map +1 -0
  138. package/esm/drag-drop/DragState.js +152 -0
  139. package/esm/drag-drop/DragState.js.map +1 -0
  140. package/esm/drag-drop/Draggable.js +190 -0
  141. package/esm/drag-drop/Draggable.js.map +1 -0
  142. package/esm/drag-drop/DropMenu.css +71 -0
  143. package/esm/drag-drop/DropMenu.js +43 -0
  144. package/esm/drag-drop/DropMenu.js.map +1 -0
  145. package/esm/drag-drop/DropTarget.js +240 -0
  146. package/esm/drag-drop/DropTarget.js.map +1 -0
  147. package/esm/drag-drop/DropTargetRenderer.css +40 -0
  148. package/esm/drag-drop/DropTargetRenderer.js +231 -0
  149. package/esm/drag-drop/DropTargetRenderer.js.map +1 -0
  150. package/esm/flexbox/Flexbox.css +45 -0
  151. package/esm/flexbox/Flexbox.js +59 -0
  152. package/esm/flexbox/Flexbox.js.map +1 -0
  153. package/esm/flexbox/FlexboxLayout.js +28 -0
  154. package/esm/flexbox/FlexboxLayout.js.map +1 -0
  155. package/esm/flexbox/FluidGrid.css +134 -0
  156. package/esm/flexbox/FluidGrid.js +76 -0
  157. package/esm/flexbox/FluidGrid.js.map +1 -0
  158. package/esm/flexbox/FluidGridLayout.js +12 -0
  159. package/esm/flexbox/FluidGridLayout.js.map +1 -0
  160. package/esm/flexbox/Splitter.css +148 -0
  161. package/esm/flexbox/Splitter.js +111 -0
  162. package/esm/flexbox/Splitter.js.map +1 -0
  163. package/esm/flexbox/flexbox-utils.js +103 -0
  164. package/esm/flexbox/flexbox-utils.js.map +1 -0
  165. package/esm/flexbox/useResponsiveSizing.js +60 -0
  166. package/esm/flexbox/useResponsiveSizing.js.map +1 -0
  167. package/esm/flexbox/useSplitterResizing.js +207 -0
  168. package/esm/flexbox/useSplitterResizing.js.map +1 -0
  169. package/esm/index.js +37 -0
  170. package/esm/index.js.map +1 -0
  171. package/esm/layout-action.js +25 -0
  172. package/esm/layout-action.js.map +1 -0
  173. package/esm/layout-header/Header.css +9 -0
  174. package/esm/layout-header/Header.js +120 -0
  175. package/esm/layout-header/Header.js.map +1 -0
  176. package/esm/layout-provider/LayoutProvider.js +172 -0
  177. package/esm/layout-provider/LayoutProvider.js.map +1 -0
  178. package/esm/layout-provider/LayoutProviderContext.js +12 -0
  179. package/esm/layout-provider/LayoutProviderContext.js.map +1 -0
  180. package/esm/layout-provider/useLayoutDragDrop.js +168 -0
  181. package/esm/layout-provider/useLayoutDragDrop.js.map +1 -0
  182. package/esm/layout-reducer/flexUtils.js +210 -0
  183. package/esm/layout-reducer/flexUtils.js.map +1 -0
  184. package/esm/layout-reducer/insert-layout-element.js +269 -0
  185. package/esm/layout-reducer/insert-layout-element.js.map +1 -0
  186. package/esm/layout-reducer/layout-reducer.js +196 -0
  187. package/esm/layout-reducer/layout-reducer.js.map +1 -0
  188. package/esm/layout-reducer/layoutTypes.js +37 -0
  189. package/esm/layout-reducer/layoutTypes.js.map +1 -0
  190. package/esm/layout-reducer/layoutUtils.js +215 -0
  191. package/esm/layout-reducer/layoutUtils.js.map +1 -0
  192. package/esm/layout-reducer/move-layout-element.js +29 -0
  193. package/esm/layout-reducer/move-layout-element.js.map +1 -0
  194. package/esm/layout-reducer/remove-layout-element.js +221 -0
  195. package/esm/layout-reducer/remove-layout-element.js.map +1 -0
  196. package/esm/layout-reducer/replace-layout-element.js +87 -0
  197. package/esm/layout-reducer/replace-layout-element.js.map +1 -0
  198. package/esm/layout-reducer/resize-flex-children.js +58 -0
  199. package/esm/layout-reducer/resize-flex-children.js.map +1 -0
  200. package/esm/layout-reducer/wrap-layout-element.js +210 -0
  201. package/esm/layout-reducer/wrap-layout-element.js.map +1 -0
  202. package/esm/layout-view/View.css +62 -0
  203. package/esm/layout-view/View.js +153 -0
  204. package/esm/layout-view/View.js.map +1 -0
  205. package/esm/layout-view/useView.js +90 -0
  206. package/esm/layout-view/useView.js.map +1 -0
  207. package/esm/layout-view/useViewResize.js +40 -0
  208. package/esm/layout-view/useViewResize.js.map +1 -0
  209. package/esm/layout-view-actions/ViewContext.js +12 -0
  210. package/esm/layout-view-actions/ViewContext.js.map +1 -0
  211. package/esm/layout-view-actions/useViewActionDispatcher.js +101 -0
  212. package/esm/layout-view-actions/useViewActionDispatcher.js.map +1 -0
  213. package/esm/palette/Palette.css +33 -0
  214. package/esm/palette/Palette.js +115 -0
  215. package/esm/palette/Palette.js.map +1 -0
  216. package/esm/placeholder/LayoutStartPanel.css +30 -0
  217. package/esm/placeholder/LayoutStartPanel.js +49 -0
  218. package/esm/placeholder/LayoutStartPanel.js.map +1 -0
  219. package/esm/placeholder/Placeholder.css +17 -0
  220. package/esm/placeholder/Placeholder.js +23 -0
  221. package/esm/placeholder/Placeholder.js.map +1 -0
  222. package/esm/registry/ComponentRegistry.js +21 -0
  223. package/esm/registry/ComponentRegistry.js.map +1 -0
  224. package/esm/responsive/breakpoints.js +33 -0
  225. package/esm/responsive/breakpoints.js.map +1 -0
  226. package/esm/responsive/use-breakpoints.js +74 -0
  227. package/esm/responsive/use-breakpoints.js.map +1 -0
  228. package/esm/responsive/useResizeObserver.js +112 -0
  229. package/esm/responsive/useResizeObserver.js.map +1 -0
  230. package/esm/responsive/utils.js +31 -0
  231. package/esm/responsive/utils.js.map +1 -0
  232. package/esm/stack/Stack.css +39 -0
  233. package/esm/stack/Stack.js +137 -0
  234. package/esm/stack/Stack.js.map +1 -0
  235. package/esm/stack/StackLayout.js +120 -0
  236. package/esm/stack/StackLayout.js.map +1 -0
  237. package/esm/use-persistent-state.js +104 -0
  238. package/esm/use-persistent-state.js.map +1 -0
  239. package/esm/utils/pathUtils.js +280 -0
  240. package/esm/utils/pathUtils.js.map +1 -0
  241. package/esm/utils/propUtils.js +23 -0
  242. package/esm/utils/propUtils.js.map +1 -0
  243. package/esm/utils/refUtils.js +10 -0
  244. package/esm/utils/refUtils.js.map +1 -0
  245. package/esm/utils/styleUtils.js +13 -0
  246. package/esm/utils/styleUtils.js.map +1 -0
  247. package/esm/utils/typeOf.js +23 -0
  248. package/esm/utils/typeOf.js.map +1 -0
  249. package/package.json +10 -8
@@ -0,0 +1,40 @@
1
+ import { useRef, useCallback } from 'react';
2
+ import { useResizeObserver, WidthHeight } from '../responsive/useResizeObserver.js';
3
+
4
+ const NO_MEASUREMENT = [];
5
+ const useViewResize = ({
6
+ mainRef,
7
+ resize = "responsive",
8
+ rootRef
9
+ }) => {
10
+ const deferResize = resize === "defer";
11
+ const mainSize = useRef({});
12
+ const resizeHandle = useRef();
13
+ const setMainSize = useCallback(() => {
14
+ if (mainRef.current) {
15
+ mainRef.current.style.height = mainSize.current.height + "px";
16
+ mainRef.current.style.width = mainSize.current.width + "px";
17
+ }
18
+ resizeHandle.current = void 0;
19
+ }, [mainRef]);
20
+ const onResize = useCallback(
21
+ ({ height, width }) => {
22
+ mainSize.current.height = height;
23
+ mainSize.current.width = width;
24
+ if (resizeHandle.current !== null) {
25
+ clearTimeout(resizeHandle.current);
26
+ }
27
+ resizeHandle.current = window.setTimeout(setMainSize, 40);
28
+ },
29
+ [setMainSize]
30
+ );
31
+ useResizeObserver(
32
+ rootRef,
33
+ deferResize ? WidthHeight : NO_MEASUREMENT,
34
+ onResize,
35
+ deferResize
36
+ );
37
+ };
38
+
39
+ export { useViewResize };
40
+ //# sourceMappingURL=useViewResize.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useViewResize.js","sources":["../../src/layout-view/useViewResize.ts"],"sourcesContent":["import { useResizeObserver, WidthHeight } from \"../responsive\";\nimport { RefObject, useCallback, useRef } from \"react\";\n\nconst NO_MEASUREMENT: string[] = [];\n\ntype size = {\n height?: number;\n width?: number;\n};\n\nexport interface ViewResizeHookProps {\n mainRef: RefObject<HTMLDivElement>;\n resize?: \"defer\" | \"responsive\";\n rootRef: RefObject<HTMLDivElement>;\n}\n\nexport const useViewResize = ({\n mainRef,\n resize = \"responsive\",\n rootRef,\n}: ViewResizeHookProps) => {\n const deferResize = resize === \"defer\";\n\n const mainSize = useRef<size>({});\n const resizeHandle = useRef<number>();\n\n const setMainSize = useCallback(() => {\n if (mainRef.current) {\n mainRef.current.style.height = mainSize.current.height + \"px\";\n mainRef.current.style.width = mainSize.current.width + \"px\";\n }\n resizeHandle.current = undefined;\n }, [mainRef]);\n\n const onResize = useCallback(\n ({ height, width }) => {\n mainSize.current.height = height;\n mainSize.current.width = width;\n if (resizeHandle.current !== null) {\n clearTimeout(resizeHandle.current);\n }\n resizeHandle.current = window.setTimeout(setMainSize, 40);\n },\n [setMainSize]\n );\n\n useResizeObserver(\n rootRef,\n deferResize ? WidthHeight : NO_MEASUREMENT,\n onResize,\n deferResize\n );\n};\n"],"names":[],"mappings":";;;AAGA,MAAM,iBAA2B,EAAC,CAAA;AAa3B,MAAM,gBAAgB,CAAC;AAAA,EAC5B,OAAA;AAAA,EACA,MAAS,GAAA,YAAA;AAAA,EACT,OAAA;AACF,CAA2B,KAAA;AACzB,EAAA,MAAM,cAAc,MAAW,KAAA,OAAA,CAAA;AAE/B,EAAM,MAAA,QAAA,GAAW,MAAa,CAAA,EAAE,CAAA,CAAA;AAChC,EAAA,MAAM,eAAe,MAAe,EAAA,CAAA;AAEpC,EAAM,MAAA,WAAA,GAAc,YAAY,MAAM;AACpC,IAAA,IAAI,QAAQ,OAAS,EAAA;AACnB,MAAA,OAAA,CAAQ,OAAQ,CAAA,KAAA,CAAM,MAAS,GAAA,QAAA,CAAS,QAAQ,MAAS,GAAA,IAAA,CAAA;AACzD,MAAA,OAAA,CAAQ,OAAQ,CAAA,KAAA,CAAM,KAAQ,GAAA,QAAA,CAAS,QAAQ,KAAQ,GAAA,IAAA,CAAA;AAAA,KACzD;AACA,IAAA,YAAA,CAAa,OAAU,GAAA,KAAA,CAAA,CAAA;AAAA,GACzB,EAAG,CAAC,OAAO,CAAC,CAAA,CAAA;AAEZ,EAAA,MAAM,QAAW,GAAA,WAAA;AAAA,IACf,CAAC,EAAE,MAAQ,EAAA,KAAA,EAAY,KAAA;AACrB,MAAA,QAAA,CAAS,QAAQ,MAAS,GAAA,MAAA,CAAA;AAC1B,MAAA,QAAA,CAAS,QAAQ,KAAQ,GAAA,KAAA,CAAA;AACzB,MAAI,IAAA,YAAA,CAAa,YAAY,IAAM,EAAA;AACjC,QAAA,YAAA,CAAa,aAAa,OAAO,CAAA,CAAA;AAAA,OACnC;AACA,MAAA,YAAA,CAAa,OAAU,GAAA,MAAA,CAAO,UAAW,CAAA,WAAA,EAAa,EAAE,CAAA,CAAA;AAAA,KAC1D;AAAA,IACA,CAAC,WAAW,CAAA;AAAA,GACd,CAAA;AAEA,EAAA,iBAAA;AAAA,IACE,OAAA;AAAA,IACA,cAAc,WAAc,GAAA,cAAA;AAAA,IAC5B,QAAA;AAAA,IACA,WAAA;AAAA,GACF,CAAA;AACF;;;;"}
@@ -0,0 +1,12 @@
1
+ import React, { useContext } from 'react';
2
+
3
+ const NO_CONTEXT = { dispatch: null };
4
+ const ViewContext = React.createContext(NO_CONTEXT);
5
+ const useViewDispatch = () => {
6
+ const context = useContext(ViewContext);
7
+ return context?.dispatch ?? null;
8
+ };
9
+ const useViewContext = () => useContext(ViewContext);
10
+
11
+ export { ViewContext, useViewContext, useViewDispatch };
12
+ //# sourceMappingURL=ViewContext.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ViewContext.js","sources":["../../src/layout-view-actions/ViewContext.ts"],"sourcesContent":["import React, { SyntheticEvent, useContext } from \"react\";\nimport { ViewAction } from \"../layout-view/viewTypes\";\n\nexport type QueryReponse = { [key: string]: unknown };\n\nexport type ViewDispatch = <Action extends ViewAction = ViewAction>(\n action: Action,\n evt?: SyntheticEvent\n) => Promise<boolean | QueryReponse | void>;\n\n/**\n * This API is available to any Feature hosted within Vuu (as all Features are wrapped\n * with View component). It offers metadata about the View as well as access to the\n * Vuu persistencew API;\n */\nexport interface ViewContextAPI {\n /**\n * dispatcher for View actions. These are a subset of LayoutActions, specifically for\n * View manipulation\n */\n dispatch?: ViewDispatch | null;\n id?: string;\n load?: (key?: string) => unknown;\n loadSession?: (key?: string) => unknown;\n onConfigChange?: (config: unknown) => void;\n path?: string;\n purge?: (key: string) => void;\n save?: (state: unknown, key: string) => void;\n saveSession?: (state: unknown, key: string) => void;\n setComponentProps: (props: { [key: string]: unknown }) => void;\n title?: string;\n}\n\nconst NO_CONTEXT = { dispatch: null } as ViewContextAPI;\nexport const ViewContext = React.createContext<ViewContextAPI>(NO_CONTEXT);\n\nexport const useViewDispatch = () => {\n const context = useContext(ViewContext);\n return context?.dispatch ?? null;\n};\n\nexport const useViewContext = () => useContext(ViewContext);\n"],"names":[],"mappings":";;AAiCA,MAAM,UAAA,GAAa,EAAE,QAAA,EAAU,IAAK,EAAA,CAAA;AACvB,MAAA,WAAA,GAAc,KAAM,CAAA,aAAA,CAA8B,UAAU,EAAA;AAElE,MAAM,kBAAkB,MAAM;AACnC,EAAM,MAAA,OAAA,GAAU,WAAW,WAAW,CAAA,CAAA;AACtC,EAAA,OAAO,SAAS,QAAY,IAAA,IAAA,CAAA;AAC9B,EAAA;AAEa,MAAA,cAAA,GAAiB,MAAM,UAAA,CAAW,WAAW;;;;"}
@@ -0,0 +1,101 @@
1
+ import { useState, useCallback } from 'react';
2
+ import { useLayoutProviderDispatch } from '../layout-provider/LayoutProvider.js';
3
+ import '../layout-provider/LayoutProviderContext.js';
4
+ import { usePersistentState } from '../use-persistent-state.js';
5
+
6
+ const useViewActionDispatcher = (id, root, viewPath, dropTargets) => {
7
+ const { loadSessionState, purgeSessionState, purgeState, saveSessionState } = usePersistentState();
8
+ const [contributions, setContributions] = useState(
9
+ loadSessionState(id, "contributions") ?? []
10
+ );
11
+ const dispatchLayoutAction = useLayoutProviderDispatch();
12
+ const updateContributions = useCallback(
13
+ (location, content) => {
14
+ const updatedContributions = contributions.concat([
15
+ { location, content }
16
+ ]);
17
+ saveSessionState(id, "contributions", updatedContributions);
18
+ setContributions(updatedContributions);
19
+ },
20
+ [contributions, id, saveSessionState]
21
+ );
22
+ const clearContributions = useCallback(() => {
23
+ purgeSessionState(id, "contributions");
24
+ setContributions([]);
25
+ }, [id, purgeSessionState]);
26
+ const handleRemove = useCallback(() => {
27
+ const ds = loadSessionState(id, "data-source");
28
+ if (ds) {
29
+ ds.unsubscribe();
30
+ }
31
+ purgeSessionState(id);
32
+ purgeState(id);
33
+ dispatchLayoutAction({ type: "remove", path: viewPath });
34
+ }, [
35
+ dispatchLayoutAction,
36
+ id,
37
+ loadSessionState,
38
+ purgeSessionState,
39
+ purgeState,
40
+ viewPath
41
+ ]);
42
+ const handleMouseDown = useCallback(
43
+ async (evt, index, preDragActivity) => {
44
+ evt.stopPropagation();
45
+ const dragRect = root.current?.getBoundingClientRect();
46
+ return new Promise((resolve, reject) => {
47
+ dispatchLayoutAction({
48
+ type: "drag-start",
49
+ evt,
50
+ path: index === void 0 ? viewPath : `${viewPath}.${index}`,
51
+ dragRect,
52
+ preDragActivity,
53
+ dropTargets,
54
+ resolveDragStart: resolve,
55
+ rejectDragStart: reject
56
+ });
57
+ });
58
+ },
59
+ [root, dispatchLayoutAction, viewPath, dropTargets]
60
+ );
61
+ const dispatchAction = useCallback(
62
+ async (action, evt) => {
63
+ const { type } = action;
64
+ switch (type) {
65
+ case "maximize":
66
+ case "minimize":
67
+ case "restore":
68
+ return dispatchLayoutAction({ type, path: action.path ?? viewPath });
69
+ case "remove":
70
+ return handleRemove();
71
+ case "mousedown":
72
+ return handleMouseDown(evt, action.index, action.preDragActivity);
73
+ case "add-toolbar-contribution":
74
+ return updateContributions(action.location, action.content);
75
+ case "remove-toolbar-contribution":
76
+ return clearContributions();
77
+ case "query":
78
+ return dispatchLayoutAction({
79
+ type,
80
+ path: action.path,
81
+ query: action.query
82
+ });
83
+ default: {
84
+ return void 0;
85
+ }
86
+ }
87
+ },
88
+ [
89
+ dispatchLayoutAction,
90
+ viewPath,
91
+ handleRemove,
92
+ handleMouseDown,
93
+ updateContributions,
94
+ clearContributions
95
+ ]
96
+ );
97
+ return [dispatchAction, contributions];
98
+ };
99
+
100
+ export { useViewActionDispatcher };
101
+ //# sourceMappingURL=useViewActionDispatcher.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useViewActionDispatcher.js","sources":["../../src/layout-view-actions/useViewActionDispatcher.ts"],"sourcesContent":["import { DataSource } from \"@vuu-ui/vuu-data-types\";\nimport {\n ReactElement,\n RefObject,\n SyntheticEvent,\n useCallback,\n useState,\n} from \"react\";\nimport { useLayoutProviderDispatch } from \"../layout-provider\";\nimport { DragStartAction } from \"../layout-reducer\";\nimport { usePersistentState } from \"../use-persistent-state\";\nimport { QueryReponse, ViewDispatch } from \"./ViewContext\";\nimport { ViewAction } from \"../layout-view/viewTypes\";\n\nexport type ContributionLocation = \"post-title\" | \"pre-title\";\n\nexport type Contribution = {\n index?: number;\n location?: ContributionLocation;\n content: ReactElement;\n};\n\nexport const useViewActionDispatcher = (\n id: string,\n root: RefObject<HTMLDivElement>,\n viewPath?: string,\n dropTargets?: string[]\n): [ViewDispatch, Contribution[] | undefined] => {\n const { loadSessionState, purgeSessionState, purgeState, saveSessionState } =\n usePersistentState();\n\n const [contributions, setContributions] = useState<Contribution[]>(\n loadSessionState(id, \"contributions\") ?? []\n );\n const dispatchLayoutAction = useLayoutProviderDispatch();\n const updateContributions = useCallback(\n (location: ContributionLocation, content: ReactElement) => {\n const updatedContributions = contributions.concat([\n { location, content },\n ]);\n saveSessionState(id, \"contributions\", updatedContributions);\n setContributions(updatedContributions);\n },\n [contributions, id, saveSessionState]\n );\n\n const clearContributions = useCallback(() => {\n purgeSessionState(id, \"contributions\");\n setContributions([]);\n }, [id, purgeSessionState]);\n\n const handleRemove = useCallback(() => {\n const ds = loadSessionState(id, \"data-source\") as DataSource;\n if (ds) {\n ds.unsubscribe();\n }\n purgeSessionState(id);\n purgeState(id);\n dispatchLayoutAction({ type: \"remove\", path: viewPath });\n }, [\n dispatchLayoutAction,\n id,\n loadSessionState,\n purgeSessionState,\n purgeState,\n viewPath,\n ]);\n\n const handleMouseDown = useCallback(\n async (evt, index, preDragActivity): Promise<boolean> => {\n evt.stopPropagation();\n const dragRect = root.current?.getBoundingClientRect();\n return new Promise((resolve, reject) => {\n dispatchLayoutAction({\n type: \"drag-start\",\n evt,\n path: index === undefined ? viewPath : `${viewPath}.${index}`,\n dragRect,\n preDragActivity,\n dropTargets,\n resolveDragStart: resolve,\n rejectDragStart: reject,\n } as DragStartAction);\n });\n },\n [root, dispatchLayoutAction, viewPath, dropTargets]\n );\n\n const dispatchAction = useCallback(\n async <A extends ViewAction = ViewAction>(\n action: A,\n evt?: SyntheticEvent\n ): Promise<boolean | QueryReponse | void> => {\n const { type } = action;\n switch (type) {\n case \"maximize\":\n case \"minimize\":\n case \"restore\":\n return dispatchLayoutAction({ type, path: action.path ?? viewPath });\n case \"remove\":\n return handleRemove();\n case \"mousedown\":\n return handleMouseDown(evt, action.index, action.preDragActivity);\n case \"add-toolbar-contribution\":\n return updateContributions(action.location, action.content);\n case \"remove-toolbar-contribution\":\n return clearContributions();\n case \"query\":\n return dispatchLayoutAction({\n type,\n path: action.path,\n query: action.query,\n });\n return;\n default: {\n return undefined;\n }\n }\n },\n [\n dispatchLayoutAction,\n viewPath,\n handleRemove,\n handleMouseDown,\n updateContributions,\n clearContributions,\n ]\n );\n\n return [dispatchAction, contributions];\n};\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,33 @@
1
+ .vuuPalette {
2
+ --vuuList-borderStyle: none;
3
+ }
4
+
5
+ .vuuPalette-horizontal {
6
+ align-items: center;
7
+ display: flex;
8
+ }
9
+
10
+ .vuuPaletteItem {
11
+ --vuu-icon-color: var(--salt-content-primary-foreground);
12
+ --vuu-icon-left: 0;
13
+ --vuu-icon-size: 16px;
14
+ --vuu-icon-top: 11px;
15
+ --list-item-text-padding: 0 0 0 calc(var(--salt-size-unit) * 3);
16
+ border-bottom: solid 1px var(--salt-separable-tertiary-borderColor);
17
+ padding-left: 12px;
18
+ font-size: 12px;
19
+ font-weight: 600;
20
+ }
21
+
22
+ .vuuSimpleDraggableWrapper > .vuuPaletteItem {
23
+ --vuu-icon-color: var(--salt-selectable-foreground);
24
+
25
+ }
26
+
27
+ .salt-theme .vuuPaletteItem {
28
+ font-size: 11px;
29
+ font-weight: normal;
30
+
31
+ }
32
+
33
+
@@ -0,0 +1,115 @@
1
+ import { jsx } from 'react/jsx-runtime';
2
+ import { uuid } from '@vuu-ui/vuu-utils';
3
+ import { ListItem, List } from '@vuu-ui/vuu-ui-controls';
4
+ import cx from 'clsx';
5
+ import { memo, cloneElement } from 'react';
6
+ import { useLayoutProviderDispatch } from '../layout-provider/LayoutProvider.js';
7
+ import '../layout-provider/LayoutProviderContext.js';
8
+ import { View as MemoView } from '../layout-view/View.js';
9
+ import { registerComponent } from '../registry/ComponentRegistry.js';
10
+
11
+ const clonePaletteItem = (paletteItem) => {
12
+ const dolly = paletteItem.cloneNode(true);
13
+ dolly.id = "";
14
+ delete dolly.dataset.idx;
15
+ return dolly;
16
+ };
17
+ const PaletteItem = memo(
18
+ ({
19
+ className,
20
+ children: component,
21
+ idx,
22
+ resizeable,
23
+ header,
24
+ closeable,
25
+ ...props
26
+ }) => {
27
+ return /* @__PURE__ */ jsx(
28
+ ListItem,
29
+ {
30
+ className: cx("vuuPaletteItem", className),
31
+ "data-draggable": true,
32
+ "data-icon": "draggable",
33
+ ...props
34
+ }
35
+ );
36
+ }
37
+ );
38
+ PaletteItem.displayName = "PaletteItem";
39
+ const Palette = ({
40
+ ListProps: ListProps2,
41
+ ViewProps: ViewProps2,
42
+ children,
43
+ className,
44
+ itemHeight = 41,
45
+ orientation = "horizontal",
46
+ ...props
47
+ }) => {
48
+ const dispatch = useLayoutProviderDispatch();
49
+ const classBase = "vuuPalette";
50
+ function handleMouseDown(evt) {
51
+ const target = evt.target;
52
+ const listItemElement = target.closest(".vuuPaletteItem");
53
+ const idx = parseInt(listItemElement.dataset?.index ?? "-1");
54
+ const {
55
+ props: { caption, children: payload, template, ...props2 }
56
+ } = children[idx];
57
+ const { ViewProps: componentViewProps } = payload.props;
58
+ const { height, left, top, width } = listItemElement.getBoundingClientRect();
59
+ const id = uuid();
60
+ const identifiers = { id, key: id };
61
+ const component = template ? payload : /* @__PURE__ */ jsx(
62
+ MemoView,
63
+ {
64
+ ...ViewProps2,
65
+ ...identifiers,
66
+ ...props2,
67
+ ...componentViewProps,
68
+ title: props2.label,
69
+ children: payload
70
+ }
71
+ );
72
+ dispatch({
73
+ dragRect: {
74
+ left,
75
+ top,
76
+ right: left + width,
77
+ bottom: top + 150,
78
+ width,
79
+ height
80
+ },
81
+ dragElement: clonePaletteItem(listItemElement),
82
+ evt: evt.nativeEvent,
83
+ instructions: {
84
+ DoNotRemove: true,
85
+ DoNotTransform: true,
86
+ DriftHomeIfNoDropTarget: true,
87
+ RemoveDraggableOnDragEnd: true,
88
+ dragThreshold: 10
89
+ },
90
+ path: "*",
91
+ payload: component,
92
+ type: "drag-start"
93
+ });
94
+ }
95
+ return /* @__PURE__ */ jsx(
96
+ List,
97
+ {
98
+ ...ListProps2,
99
+ ...props,
100
+ className: cx(classBase, className, `${classBase}-${orientation}`),
101
+ itemHeight,
102
+ selected: null,
103
+ children: children.map(
104
+ (child, idx) => child.type === PaletteItem ? cloneElement(child, {
105
+ key: idx,
106
+ onMouseDown: handleMouseDown
107
+ }) : child
108
+ )
109
+ }
110
+ );
111
+ };
112
+ registerComponent("Palette", Palette, "view");
113
+
114
+ export { Palette, PaletteItem };
115
+ //# sourceMappingURL=Palette.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Palette.js","sources":["../../src/palette/Palette.tsx"],"sourcesContent":["import { uuid } from \"@vuu-ui/vuu-utils\";\nimport {\n List,\n ListItem,\n ListItemProps,\n ListProps,\n} from \"@vuu-ui/vuu-ui-controls\";\nimport cx from \"clsx\";\nimport {\n cloneElement,\n HTMLAttributes,\n memo,\n MouseEvent,\n ReactElement,\n} from \"react\";\nimport { useLayoutProviderDispatch } from \"../layout-provider\";\nimport { View, ViewProps } from \"../layout-view\";\nimport { registerComponent } from \"../registry/ComponentRegistry\";\n\nimport \"./Palette.css\";\n\nconst clonePaletteItem = (paletteItem: HTMLElement) => {\n const dolly = paletteItem.cloneNode(true) as HTMLElement;\n dolly.id = \"\";\n delete dolly.dataset.idx;\n return dolly;\n};\n\nexport interface PaletteItemProps extends ListItemProps {\n children: ReactElement;\n closeable?: boolean;\n header?: boolean;\n idx?: number;\n resize?: \"defer\";\n resizeable?: boolean;\n}\n\nexport const PaletteItem = memo(\n ({\n className,\n children: component,\n idx,\n resizeable,\n header,\n closeable,\n ...props\n }: PaletteItemProps) => {\n return (\n <ListItem\n className={cx(\"vuuPaletteItem\", className)}\n data-draggable\n data-icon=\"draggable\"\n {...props}\n />\n );\n }\n);\n\nPaletteItem.displayName = \"PaletteItem\";\n\nexport interface PaletteProps\n extends Omit<\n HTMLAttributes<HTMLDivElement>,\n \"onDragStart\" | \"onDrop\" | \"onSelect\"\n > {\n ListProps?: Partial<ListProps>;\n ViewProps?: Partial<ViewProps>;\n children: ReactElement[];\n itemHeight?: number;\n orientation: \"horizontal\" | \"vertical\";\n selection?: string;\n}\n\nexport const Palette = ({\n ListProps,\n ViewProps,\n children,\n className,\n itemHeight = 41,\n orientation = \"horizontal\",\n ...props\n}: PaletteProps) => {\n const dispatch = useLayoutProviderDispatch();\n const classBase = \"vuuPalette\";\n\n function handleMouseDown(evt: MouseEvent) {\n const target = evt.target as HTMLElement;\n const listItemElement = target.closest(\".vuuPaletteItem\") as HTMLElement;\n const idx = parseInt(listItemElement.dataset?.index ?? \"-1\");\n const {\n props: { caption, children: payload, template, ...props },\n } = children[idx];\n const { ViewProps: componentViewProps } = payload.props;\n const { height, left, top, width } =\n listItemElement.getBoundingClientRect();\n const id = uuid();\n const identifiers = { id, key: id };\n const component = template ? (\n payload\n ) : (\n <View\n {...ViewProps}\n {...identifiers}\n {...props}\n {...componentViewProps}\n title={props.label}\n >\n {payload}\n </View>\n );\n\n dispatch({\n dragRect: {\n left,\n top,\n right: left + width,\n bottom: top + 150,\n width,\n height,\n },\n dragElement: clonePaletteItem(listItemElement),\n evt: evt.nativeEvent,\n instructions: {\n DoNotRemove: true,\n DoNotTransform: true,\n DriftHomeIfNoDropTarget: true,\n RemoveDraggableOnDragEnd: true,\n dragThreshold: 10,\n },\n path: \"*\",\n payload: component,\n type: \"drag-start\",\n });\n }\n\n return (\n <List\n {...ListProps}\n {...props}\n className={cx(classBase, className, `${classBase}-${orientation}`)}\n itemHeight={itemHeight}\n selected={null}\n >\n {children.map((child, idx) =>\n child.type === PaletteItem\n ? cloneElement(child, {\n key: idx,\n onMouseDown: handleMouseDown,\n })\n : child\n )}\n </List>\n );\n};\n\nregisterComponent(\"Palette\", Palette, \"view\");\n"],"names":["ListProps","ViewProps","props","View"],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ .vuuLayoutStartPanel {
2
+ align-items: center;
3
+ flex: 0 0 auto !important;
4
+ display: flex;
5
+ flex-direction: column;
6
+ font-weight: 700;
7
+ gap: 12px;
8
+ }
9
+
10
+ .vuuLayoutStartPanel-title {
11
+ color: var(--vuu-color-gray-80);
12
+ font-size: 28px;
13
+ line-height: 1.5;
14
+ text-align: center;
15
+ }
16
+
17
+ .vuuLayoutStartPanel-text {
18
+ color: var(--vuu-color-gray-50);
19
+ font-size: 18px;
20
+ line-height: 1.5;
21
+ max-width: 460px;
22
+ }
23
+
24
+ .vuuLayoutStartPanel-addButton {
25
+ --vuu-icon-size: 20px;
26
+ --saltButton-borderRadius: 28px !important;
27
+ --saltButton-height: 56px;
28
+ --saltButton-width: 56px;
29
+ box-shadow: 0px 4px 4px 0px rgba(0, 0, 0, 0.25);
30
+ }
@@ -0,0 +1,49 @@
1
+ import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
2
+ import { Button } from '@salt-ds/core';
3
+ import { useState, useMemo } from 'react';
4
+ import '@vuu-ui/vuu-utils';
5
+ import '../layout-provider/LayoutProviderContext.js';
6
+ import '../drag-drop/Draggable.js';
7
+ import 'clsx';
8
+ import '../drag-drop/BoxModel.js';
9
+ import { useViewContext } from '../layout-view-actions/ViewContext.js';
10
+
11
+ const classBase = "vuuLayoutStartPanel";
12
+ const LayoutStartPanel = (htmlAttributes) => {
13
+ const { dispatch, path } = useViewContext();
14
+ const [displayState, setDisplayState] = useState();
15
+ useMemo(() => {
16
+ dispatch?.({
17
+ type: "query",
18
+ path,
19
+ query: "PARENT_CONTAINER"
20
+ }).then((response) => {
21
+ if (response?.parentContainerId === "main-tabs") {
22
+ setDisplayState("initial");
23
+ } else {
24
+ setDisplayState("nested");
25
+ }
26
+ });
27
+ }, [dispatch, path]);
28
+ if (displayState === void 0) {
29
+ return null;
30
+ }
31
+ const showInitialState = displayState === "initial";
32
+ return /* @__PURE__ */ jsxs("div", { ...htmlAttributes, className: classBase, children: [
33
+ showInitialState ? /* @__PURE__ */ jsxs(Fragment, { children: [
34
+ /* @__PURE__ */ jsx("header", { className: `${classBase}-title`, children: "Start by adding a table" }),
35
+ /* @__PURE__ */ jsx("div", { className: `${classBase}-text`, children: "To add a table, drag any of the Vuu Tables to this area or click the button below" })
36
+ ] }) : null,
37
+ /* @__PURE__ */ jsx(
38
+ Button,
39
+ {
40
+ className: `${classBase}-addButton`,
41
+ "data-icon": "add",
42
+ variant: "cta"
43
+ }
44
+ )
45
+ ] });
46
+ };
47
+
48
+ export { LayoutStartPanel };
49
+ //# sourceMappingURL=LayoutStartPanel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LayoutStartPanel.js","sources":["../../src/placeholder/LayoutStartPanel.tsx"],"sourcesContent":["import { Button } from \"@salt-ds/core\";\nimport { HTMLAttributes, useMemo, useState } from \"react\";\nimport { useViewContext, QueryReponse } from \"../layout-view-actions\";\n\nimport \"./LayoutStartPanel.css\";\n\nconst classBase = \"vuuLayoutStartPanel\";\n\nexport interface LayoutStartPanelProps extends HTMLAttributes<HTMLDivElement> {\n label?: string;\n}\n\nexport const LayoutStartPanel = (htmlAttributes: LayoutStartPanelProps) => {\n const { dispatch, path } = useViewContext();\n const [displayState, setDisplayState] = useState<\n \"initial\" | \"nested\" | undefined\n >();\n\n useMemo(() => {\n dispatch?.({\n type: \"query\",\n path,\n query: \"PARENT_CONTAINER\",\n }).then((response) => {\n if ((response as QueryReponse)?.parentContainerId === \"main-tabs\") {\n setDisplayState(\"initial\");\n } else {\n setDisplayState(\"nested\");\n }\n });\n }, [dispatch, path]);\n\n if (displayState === undefined) {\n return null;\n }\n\n const showInitialState = displayState === \"initial\";\n\n return (\n <div {...htmlAttributes} className={classBase}>\n {showInitialState ? (\n <>\n <header className={`${classBase}-title`}>\n Start by adding a table\n </header>\n <div className={`${classBase}-text`}>\n To add a table, drag any of the Vuu Tables to this area or click the\n button below\n </div>\n </>\n ) : null}\n <Button\n className={`${classBase}-addButton`}\n data-icon=\"add\"\n variant=\"cta\"\n />\n </div>\n );\n};\n"],"names":[],"mappings":";;;;;;;;;;AAMA,MAAM,SAAY,GAAA,qBAAA,CAAA;AAML,MAAA,gBAAA,GAAmB,CAAC,cAA0C,KAAA;AACzE,EAAA,MAAM,EAAE,QAAA,EAAU,IAAK,EAAA,GAAI,cAAe,EAAA,CAAA;AAC1C,EAAA,MAAM,CAAC,YAAA,EAAc,eAAe,CAAA,GAAI,QAEtC,EAAA,CAAA;AAEF,EAAA,OAAA,CAAQ,MAAM;AACZ,IAAW,QAAA,GAAA;AAAA,MACT,IAAM,EAAA,OAAA;AAAA,MACN,IAAA;AAAA,MACA,KAAO,EAAA,kBAAA;AAAA,KACR,CAAA,CAAE,IAAK,CAAA,CAAC,QAAa,KAAA;AACpB,MAAK,IAAA,QAAA,EAA2B,sBAAsB,WAAa,EAAA;AACjE,QAAA,eAAA,CAAgB,SAAS,CAAA,CAAA;AAAA,OACpB,MAAA;AACL,QAAA,eAAA,CAAgB,QAAQ,CAAA,CAAA;AAAA,OAC1B;AAAA,KACD,CAAA,CAAA;AAAA,GACA,EAAA,CAAC,QAAU,EAAA,IAAI,CAAC,CAAA,CAAA;AAEnB,EAAA,IAAI,iBAAiB,KAAW,CAAA,EAAA;AAC9B,IAAO,OAAA,IAAA,CAAA;AAAA,GACT;AAEA,EAAA,MAAM,mBAAmB,YAAiB,KAAA,SAAA,CAAA;AAE1C,EAAA,uBACG,IAAA,CAAA,KAAA,EAAA,EAAK,GAAG,cAAA,EAAgB,WAAW,SACjC,EAAA,QAAA,EAAA;AAAA,IAAA,gBAAA,mBAEG,IAAA,CAAA,QAAA,EAAA,EAAA,QAAA,EAAA;AAAA,sBAAA,GAAA,CAAC,QAAO,EAAA,EAAA,SAAA,EAAW,CAAG,EAAA,SAAS,UAAU,QAEzC,EAAA,yBAAA,EAAA,CAAA;AAAA,0BACC,KAAI,EAAA,EAAA,SAAA,EAAW,CAAG,EAAA,SAAS,SAAS,QAGrC,EAAA,mFAAA,EAAA,CAAA;AAAA,KAAA,EACF,CACE,GAAA,IAAA;AAAA,oBACJ,GAAA;AAAA,MAAC,MAAA;AAAA,MAAA;AAAA,QACC,SAAA,EAAW,GAAG,SAAS,CAAA,UAAA,CAAA;AAAA,QACvB,WAAU,EAAA,KAAA;AAAA,QACV,OAAQ,EAAA,KAAA;AAAA,OAAA;AAAA,KACV;AAAA,GACF,EAAA,CAAA,CAAA;AAEJ;;;;"}
@@ -0,0 +1,17 @@
1
+ .vuuPlaceholder {
2
+ --vuuView-justify: center;
3
+ align-items: center;
4
+ display: flex;
5
+ flex-basis: 0;
6
+ flex-grow: 1;
7
+ flex-shrink: 1;
8
+ }
9
+
10
+ .vuuPlaceholder-nested {
11
+ background-color: red;
12
+ }
13
+
14
+ .vuuPlaceholder-shim {
15
+ flex-grow: 0;
16
+ flex-shrink: 0;
17
+ }
@@ -0,0 +1,23 @@
1
+ import { jsx, Fragment } from 'react/jsx-runtime';
2
+ import cx from 'clsx';
3
+ import { registerComponent } from '../registry/ComponentRegistry.js';
4
+ import { LayoutStartPanel } from './LayoutStartPanel.js';
5
+ import { View as MemoView } from '../layout-view/View.js';
6
+
7
+ const classBase = "vuuPlaceholder";
8
+ const PlaceholderCore = ({ showStartMenu = true }) => {
9
+ return /* @__PURE__ */ jsx(Fragment, { children: showStartMenu ? /* @__PURE__ */ jsx(LayoutStartPanel, {}) : null });
10
+ };
11
+ const Placeholder = ({
12
+ className: classNameProp,
13
+ showStartMenu,
14
+ ...viewProps
15
+ }) => {
16
+ const className = cx(classBase, classNameProp);
17
+ return /* @__PURE__ */ jsx(MemoView, { ...viewProps, className, "data-placeholder": true, resizeable: true, children: /* @__PURE__ */ jsx(PlaceholderCore, { showStartMenu }) });
18
+ };
19
+ Placeholder.displayName = "Placeholder";
20
+ registerComponent("Placeholder", Placeholder);
21
+
22
+ export { Placeholder };
23
+ //# sourceMappingURL=Placeholder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Placeholder.js","sources":["../../src/placeholder/Placeholder.tsx"],"sourcesContent":["import cx from \"clsx\";\nimport { registerComponent } from \"../registry/ComponentRegistry\";\nimport { LayoutStartPanel } from \"./LayoutStartPanel\";\nimport { View, ViewProps } from \"../layout-view\";\n\nimport \"./Placeholder.css\";\n\nconst classBase = \"vuuPlaceholder\";\n\nexport interface PlaceholderProps extends ViewProps {\n closeable?: boolean;\n flexFill?: boolean;\n resizeable?: boolean;\n showStartMenu?: boolean;\n /**\n * shim is only when we're dealing with intrinsically sized children, which is never\n * in an actual application. Intrinsic sizing is still experimental.\n */\n shim?: boolean;\n}\n\nconst PlaceholderCore = ({ showStartMenu = true }: PlaceholderProps) => {\n return <>{showStartMenu ? <LayoutStartPanel /> : null}</>;\n};\n\nexport const Placeholder = ({\n className: classNameProp,\n showStartMenu,\n ...viewProps\n}: PlaceholderProps) => {\n const className = cx(classBase, classNameProp);\n\n return (\n <View {...viewProps} className={className} data-placeholder resizeable>\n <PlaceholderCore showStartMenu={showStartMenu} />\n </View>\n );\n};\n\nPlaceholder.displayName = \"Placeholder\";\nregisterComponent(\"Placeholder\", Placeholder);\n"],"names":["View"],"mappings":";;;;;;AAOA,MAAM,SAAY,GAAA,gBAAA,CAAA;AAclB,MAAM,eAAkB,GAAA,CAAC,EAAE,aAAA,GAAgB,MAA6B,KAAA;AACtE,EAAA,uBAAU,GAAA,CAAA,QAAA,EAAA,EAAA,QAAA,EAAA,aAAA,mBAAiB,GAAA,CAAA,gBAAA,EAAA,EAAiB,IAAK,IAAK,EAAA,CAAA,CAAA;AACxD,CAAA,CAAA;AAEO,MAAM,cAAc,CAAC;AAAA,EAC1B,SAAW,EAAA,aAAA;AAAA,EACX,aAAA;AAAA,EACA,GAAG,SAAA;AACL,CAAwB,KAAA;AACtB,EAAM,MAAA,SAAA,GAAY,EAAG,CAAA,SAAA,EAAW,aAAa,CAAA,CAAA;AAE7C,EAAA,uBACG,GAAA,CAAAA,QAAA,EAAA,EAAM,GAAG,SAAA,EAAW,SAAsB,EAAA,kBAAA,EAAgB,IAAC,EAAA,UAAA,EAAU,IACpE,EAAA,QAAA,kBAAA,GAAA,CAAC,eAAgB,EAAA,EAAA,aAAA,EAA8B,CACjD,EAAA,CAAA,CAAA;AAEJ,EAAA;AAEA,WAAA,CAAY,WAAc,GAAA,aAAA,CAAA;AAC1B,iBAAA,CAAkB,eAAe,WAAW,CAAA;;;;"}
@@ -0,0 +1,21 @@
1
+ const _containers = {};
2
+ const _views = {};
3
+ const ComponentRegistry = {};
4
+ function isContainer(componentType) {
5
+ return _containers[componentType] === true;
6
+ }
7
+ function isView(componentType) {
8
+ return _views[componentType] === true;
9
+ }
10
+ const isLayoutComponent = (type) => isContainer(type) || isView(type);
11
+ function registerComponent(componentName, component, type = "component") {
12
+ ComponentRegistry[componentName] = component;
13
+ if (type === "container") {
14
+ _containers[componentName] = true;
15
+ } else if (type === "view") {
16
+ _views[componentName] = true;
17
+ }
18
+ }
19
+
20
+ export { ComponentRegistry, isContainer, isLayoutComponent, isView, registerComponent };
21
+ //# sourceMappingURL=ComponentRegistry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ComponentRegistry.js","sources":["../../src/registry/ComponentRegistry.ts"],"sourcesContent":["import { FunctionComponent } from \"react\";\n\nconst _containers: { [key: string]: boolean } = {};\nconst _views: { [key: string]: boolean } = {};\n\nexport type layoutComponentType = \"component\" | \"container\" | \"view\";\n\nexport interface ComponentWithId {\n id: string;\n [key: string]: unknown;\n}\n\nexport const ComponentRegistry: {\n [key: string]: FunctionComponent<ComponentWithId>;\n} = {};\n\nexport function isContainer(componentType: string) {\n return _containers[componentType] === true;\n}\n\nexport function isView(componentType: string) {\n return _views[componentType] === true;\n}\n\nexport const isLayoutComponent = (type: string) =>\n isContainer(type) || isView(type);\n\n// export const isRegistered = (className: string) =>\n// !!ComponentRegistry[className];\n\nexport function registerComponent(\n componentName: string,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n component: FunctionComponent<any>,\n type: layoutComponentType = \"component\"\n) {\n ComponentRegistry[componentName] = component;\n\n if (type === \"container\") {\n _containers[componentName] = true;\n } else if (type === \"view\") {\n _views[componentName] = true;\n }\n}\n"],"names":[],"mappings":"AAEA,MAAM,cAA0C,EAAC,CAAA;AACjD,MAAM,SAAqC,EAAC,CAAA;AASrC,MAAM,oBAET,GAAC;AAEE,SAAS,YAAY,aAAuB,EAAA;AACjD,EAAO,OAAA,WAAA,CAAY,aAAa,CAAM,KAAA,IAAA,CAAA;AACxC,CAAA;AAEO,SAAS,OAAO,aAAuB,EAAA;AAC5C,EAAO,OAAA,MAAA,CAAO,aAAa,CAAM,KAAA,IAAA,CAAA;AACnC,CAAA;AAEO,MAAM,oBAAoB,CAAC,IAAA,KAChC,YAAY,IAAI,CAAA,IAAK,OAAO,IAAI,EAAA;AAK3B,SAAS,iBACd,CAAA,aAAA,EAEA,SACA,EAAA,IAAA,GAA4B,WAC5B,EAAA;AACA,EAAA,iBAAA,CAAkB,aAAa,CAAI,GAAA,SAAA,CAAA;AAEnC,EAAA,IAAI,SAAS,WAAa,EAAA;AACxB,IAAA,WAAA,CAAY,aAAa,CAAI,GAAA,IAAA,CAAA;AAAA,GAC/B,MAAA,IAAW,SAAS,MAAQ,EAAA;AAC1B,IAAA,MAAA,CAAO,aAAa,CAAI,GAAA,IAAA,CAAA;AAAA,GAC1B;AACF;;;;"}
@@ -0,0 +1,33 @@
1
+ function breakpointReader(themeName, defaultBreakpoints) {
2
+ const themeRoot = document.body.querySelector(`.${themeName}`);
3
+ const handler = {
4
+ get: function(style, stopName) {
5
+ const val = style.getPropertyValue(
6
+ // lets assume we have the following naming convention
7
+ `--${themeName}-breakpoint-${stopName}`
8
+ );
9
+ return val ? parseInt(val) : void 0;
10
+ }
11
+ };
12
+ return themeRoot ? new Proxy(getComputedStyle(themeRoot), handler) : defaultBreakpoints ?? {};
13
+ }
14
+ const byDescendingStopSize = ([, s1], [, s2]) => s2 - s1;
15
+ const breakpointRamp = (breakpoints) => Object.entries(breakpoints).sort(byDescendingStopSize).map(([name, value], i, all) => [
16
+ name,
17
+ value,
18
+ i < all.length - 1 ? all[i + 1][1] : 9999
19
+ ]);
20
+ let documentBreakpoints = null;
21
+ const loadBreakpoints = (themeName = "salt") => {
22
+ const { xs, sm, md, lg, xl } = breakpointReader(themeName);
23
+ return breakpointRamp({ xs, sm, md, lg, xl });
24
+ };
25
+ const getBreakPoints = (themeName) => {
26
+ if (documentBreakpoints === null) {
27
+ documentBreakpoints = loadBreakpoints(themeName);
28
+ }
29
+ return documentBreakpoints;
30
+ };
31
+
32
+ export { breakpointRamp, getBreakPoints };
33
+ //# sourceMappingURL=breakpoints.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"breakpoints.js","sources":["../../src/responsive/breakpoints.ts"],"sourcesContent":["// should we have some global; defaults ?\n\nimport { BreakPointsProp } from \"../flexbox/flexboxTypes\";\n\nexport type BreakPointRamp = [string, number, number];\n\nfunction breakpointReader(\n themeName: string,\n defaultBreakpoints?: BreakPointsProp\n) {\n //TODO ownerDocument\n const themeRoot = document.body.querySelector(`.${themeName}`);\n const handler = {\n get: function (style: CSSStyleDeclaration, stopName: string) {\n const val = style.getPropertyValue(\n // lets assume we have the following naming convention\n `--${themeName}-breakpoint-${stopName}`\n );\n return val ? parseInt(val) : undefined;\n },\n };\n\n return themeRoot\n ? new Proxy(getComputedStyle(themeRoot), handler)\n : defaultBreakpoints ?? {};\n}\n\nconst byDescendingStopSize = (\n [, s1]: [string, number],\n [, s2]: [string, number]\n) => s2 - s1;\n\n// These are assumed to be min-width (aka mobile-first) stops, we could take a\n// paramneter to support max-width as well ?\n// return [stopName, minWidth, maxWidth]\nexport const breakpointRamp = (\n breakpoints: BreakPointsProp\n): BreakPointRamp[] =>\n Object.entries(breakpoints)\n .sort(byDescendingStopSize)\n .map(([name, value], i, all) => [\n name,\n value,\n i < all.length - 1 ? all[i + 1][1] : 9999,\n ]);\n\nlet documentBreakpoints: BreakPointRamp[] | null = null;\n\nconst loadBreakpoints = (themeName = \"salt\") => {\n // TODO would be nice to read these breakpoint labels from a css variable to\n // avoid hard-coding them here ?\n const { xs, sm, md, lg, xl } = breakpointReader(themeName) as BreakPointsProp;\n return breakpointRamp({ xs, sm, md, lg, xl });\n};\n\n//TODO support multiple themes loaded\nexport const getBreakPoints = (themeName?: string) => {\n if (documentBreakpoints === null) {\n documentBreakpoints = loadBreakpoints(themeName);\n }\n return documentBreakpoints;\n};\n"],"names":[],"mappings":"AAMA,SAAS,gBAAA,CACP,WACA,kBACA,EAAA;AAEA,EAAA,MAAM,YAAY,QAAS,CAAA,IAAA,CAAK,aAAc,CAAA,CAAA,CAAA,EAAI,SAAS,CAAE,CAAA,CAAA,CAAA;AAC7D,EAAA,MAAM,OAAU,GAAA;AAAA,IACd,GAAA,EAAK,SAAU,KAAA,EAA4B,QAAkB,EAAA;AAC3D,MAAA,MAAM,MAAM,KAAM,CAAA,gBAAA;AAAA;AAAA,QAEhB,CAAA,EAAA,EAAK,SAAS,CAAA,YAAA,EAAe,QAAQ,CAAA,CAAA;AAAA,OACvC,CAAA;AACA,MAAO,OAAA,GAAA,GAAM,QAAS,CAAA,GAAG,CAAI,GAAA,KAAA,CAAA,CAAA;AAAA,KAC/B;AAAA,GACF,CAAA;AAEA,EAAO,OAAA,SAAA,GACH,IAAI,KAAM,CAAA,gBAAA,CAAiB,SAAS,CAAG,EAAA,OAAO,CAC9C,GAAA,kBAAA,IAAsB,EAAC,CAAA;AAC7B,CAAA;AAEA,MAAM,oBAAA,GAAuB,CAC3B,GAAG,EAAE,GACL,GAAG,EAAE,CAAA,KACF,EAAK,GAAA,EAAA,CAAA;AAKH,MAAM,iBAAiB,CAC5B,WAAA,KAEA,MAAO,CAAA,OAAA,CAAQ,WAAW,CACvB,CAAA,IAAA,CAAK,oBAAoB,CAAA,CACzB,IAAI,CAAC,CAAC,MAAM,KAAK,CAAA,EAAG,GAAG,GAAQ,KAAA;AAAA,EAC9B,IAAA;AAAA,EACA,KAAA;AAAA,EACA,CAAA,GAAI,IAAI,MAAS,GAAA,CAAA,GAAI,IAAI,CAAI,GAAA,CAAC,CAAE,CAAA,CAAC,CAAI,GAAA,IAAA;AACvC,CAAC,EAAA;AAEL,IAAI,mBAA+C,GAAA,IAAA,CAAA;AAEnD,MAAM,eAAA,GAAkB,CAAC,SAAA,GAAY,MAAW,KAAA;AAG9C,EAAM,MAAA,EAAE,IAAI,EAAI,EAAA,EAAA,EAAI,IAAI,EAAG,EAAA,GAAI,iBAAiB,SAAS,CAAA,CAAA;AACzD,EAAA,OAAO,eAAe,EAAE,EAAA,EAAI,IAAI,EAAI,EAAA,EAAA,EAAI,IAAI,CAAA,CAAA;AAC9C,CAAA,CAAA;AAGa,MAAA,cAAA,GAAiB,CAAC,SAAuB,KAAA;AACpD,EAAA,IAAI,wBAAwB,IAAM,EAAA;AAChC,IAAA,mBAAA,GAAsB,gBAAgB,SAAS,CAAA,CAAA;AAAA,GACjD;AACA,EAAO,OAAA,mBAAA,CAAA;AACT;;;;"}
@@ -0,0 +1,74 @@
1
+ import { useState, useRef, useCallback, useEffect } from 'react';
2
+ import { useResizeObserver } from './useResizeObserver.js';
3
+ import { breakpointRamp, getBreakPoints } from './breakpoints.js';
4
+
5
+ const EMPTY_ARRAY = [];
6
+ const useBreakpoints = ({ breakPoints: breakPointsProp, smallerThan }, ref) => {
7
+ const [breakpointMatch, setBreakpointmatch] = useState(
8
+ smallerThan ? false : "lg"
9
+ );
10
+ const bodyRef = useRef(document.body);
11
+ const breakPointsRef = useRef(
12
+ breakPointsProp ? breakpointRamp(breakPointsProp) : getBreakPoints()
13
+ );
14
+ const sizeRef = useRef("lg");
15
+ const stopFromMinWidth = useCallback(
16
+ (w) => {
17
+ if (breakPointsRef.current) {
18
+ for (const [name, size] of breakPointsRef.current) {
19
+ if (w >= size) {
20
+ return name;
21
+ }
22
+ }
23
+ }
24
+ },
25
+ [breakPointsRef]
26
+ );
27
+ const matchSizeAgainstBreakpoints = useCallback(
28
+ (width) => {
29
+ if (smallerThan) {
30
+ const breakPointRamp = breakPointsRef.current.find(
31
+ ([name]) => name === smallerThan
32
+ );
33
+ if (breakPointRamp) {
34
+ const [, , maxValue] = breakPointRamp;
35
+ return width < maxValue;
36
+ }
37
+ } else {
38
+ return stopFromMinWidth(width);
39
+ }
40
+ return width;
41
+ },
42
+ [smallerThan, stopFromMinWidth]
43
+ );
44
+ useResizeObserver(
45
+ ref || bodyRef,
46
+ breakPointsRef.current ? ["width"] : EMPTY_ARRAY,
47
+ ({ width: measuredWidth }) => {
48
+ const result = matchSizeAgainstBreakpoints(measuredWidth);
49
+ if (result !== sizeRef.current) {
50
+ sizeRef.current = result;
51
+ setBreakpointmatch(result);
52
+ }
53
+ },
54
+ true
55
+ );
56
+ useEffect(() => {
57
+ const target = ref || bodyRef;
58
+ if (target.current) {
59
+ const prevSize = sizeRef.current;
60
+ if (breakPointsRef.current) {
61
+ const { clientWidth } = target.current;
62
+ const result = matchSizeAgainstBreakpoints(clientWidth);
63
+ sizeRef.current = result;
64
+ if (result !== prevSize) {
65
+ setBreakpointmatch(result);
66
+ }
67
+ }
68
+ }
69
+ }, [setBreakpointmatch, matchSizeAgainstBreakpoints, ref]);
70
+ return breakpointMatch;
71
+ };
72
+
73
+ export { useBreakpoints };
74
+ //# sourceMappingURL=use-breakpoints.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-breakpoints.js","sources":["../../src/responsive/use-breakpoints.ts"],"sourcesContent":["import { RefObject, useCallback, useEffect, useRef, useState } from \"react\";\nimport { useResizeObserver } from \"./useResizeObserver\";\nimport {\n BreakPointRamp,\n breakpointRamp,\n getBreakPoints as getDocumentBreakpoints,\n} from \"./breakpoints\";\nimport { BreakPoint, BreakPointsProp } from \"../flexbox/flexboxTypes\";\n\nconst EMPTY_ARRAY: BreakPoint[] = [];\n\nexport interface BreakpointsHookProps {\n breakPoints?: BreakPointsProp;\n smallerThan?: string;\n}\n\n// TODO how do we cater for smallerThan/greaterThan breakpoints\nexport const useBreakpoints = (\n { breakPoints: breakPointsProp, smallerThan }: BreakpointsHookProps,\n ref: RefObject<HTMLElement>\n) => {\n const [breakpointMatch, setBreakpointmatch] = useState(\n smallerThan ? false : \"lg\"\n );\n const bodyRef = useRef(document.body);\n const breakPointsRef = useRef<BreakPointRamp[]>(\n breakPointsProp ? breakpointRamp(breakPointsProp) : getDocumentBreakpoints()\n );\n\n // TODO how do we identify the default\n const sizeRef = useRef(\"lg\");\n\n const stopFromMinWidth = useCallback(\n (w) => {\n if (breakPointsRef.current) {\n for (const [name, size] of breakPointsRef.current) {\n if (w >= size) {\n return name;\n }\n }\n }\n },\n [breakPointsRef]\n );\n\n const matchSizeAgainstBreakpoints = useCallback(\n (width) => {\n if (smallerThan) {\n const breakPointRamp = breakPointsRef.current.find(\n ([name]: BreakPointRamp) => name === smallerThan\n );\n if (breakPointRamp) {\n const [, , maxValue] = breakPointRamp;\n return width < maxValue;\n }\n } else {\n return stopFromMinWidth(width);\n }\n // is this right ?\n return width;\n },\n [smallerThan, stopFromMinWidth]\n );\n\n // TODO need to make the dimension a config\n useResizeObserver(\n ref || bodyRef,\n breakPointsRef.current ? [\"width\"] : EMPTY_ARRAY,\n ({ width: measuredWidth }: { width?: number }) => {\n const result = matchSizeAgainstBreakpoints(measuredWidth);\n if (result !== sizeRef.current) {\n sizeRef.current = result;\n setBreakpointmatch(result);\n }\n },\n true\n );\n\n useEffect(() => {\n const target = ref || bodyRef;\n if (target.current) {\n const prevSize = sizeRef.current;\n if (breakPointsRef.current) {\n // We're measuring here when the resizeObserver has also measured\n // There isn't a convenient way to get the Resizeobserver to\n // notify initial size - that's not really its job, unless we\n // set a flag ?\n const { clientWidth } = target.current;\n const result = matchSizeAgainstBreakpoints(clientWidth);\n sizeRef.current = result;\n // If initial size of ref does not match the default, notify client after render\n if (result !== prevSize) {\n setBreakpointmatch(result);\n }\n }\n }\n }, [setBreakpointmatch, matchSizeAgainstBreakpoints, ref]);\n\n // No, just ass the class directly to the ref, no need to render\n return breakpointMatch;\n};\n"],"names":["getDocumentBreakpoints"],"mappings":"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"}