@vuu-ui/vuu-layout 2.1.18 → 2.1.19-beta.2
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.
- package/package.json +15 -18
- package/src/Component.js +14 -0
- package/src/LayoutContainer.css.js +24 -0
- package/src/LayoutContainer.js +26 -0
- package/src/debug.js +16 -0
- package/src/dock-layout/DockLayout.css.js +36 -0
- package/src/dock-layout/DockLayout.js +43 -0
- package/src/dock-layout/Drawer.css.js +150 -0
- package/src/dock-layout/Drawer.js +82 -0
- package/src/dock-layout/index.js +2 -0
- package/src/drag-drop/BoxModel.js +337 -0
- package/src/drag-drop/DragState.js +119 -0
- package/src/drag-drop/Draggable.js +140 -0
- package/src/drag-drop/DropTarget.js +286 -0
- package/src/drag-drop/DropTargetRenderer.js +275 -0
- package/src/drag-drop/dragDropTypes.js +0 -0
- package/src/drag-drop/index.js +3 -0
- package/src/flexbox/Flexbox.css.js +45 -0
- package/src/flexbox/Flexbox.js +45 -0
- package/src/flexbox/FlexboxLayout.js +27 -0
- package/src/flexbox/Splitter.css.js +57 -0
- package/src/flexbox/Splitter.js +112 -0
- package/src/flexbox/flexbox-utils.js +92 -0
- package/src/flexbox/flexboxTypes.js +0 -0
- package/src/flexbox/index.js +2 -0
- package/src/flexbox/useSplitterResizing.js +181 -0
- package/src/index.js +20 -0
- package/src/layout-action.js +20 -0
- package/src/layout-header/ActionButton.js +15 -0
- package/src/layout-header/Header.css.js +32 -0
- package/src/layout-header/Header.js +99 -0
- package/src/layout-header/index.js +1 -0
- package/src/layout-header/useHeader.js +76 -0
- package/src/layout-provider/LayoutProvider.js +242 -0
- package/src/layout-provider/LayoutProviderContext.js +13 -0
- package/src/layout-provider/index.js +2 -0
- package/src/layout-provider/useLayoutDragDrop.js +147 -0
- package/src/layout-reducer/flexUtils.js +186 -0
- package/src/layout-reducer/index.js +4 -0
- package/src/layout-reducer/insert-layout-element.js +179 -0
- package/src/layout-reducer/layout-reducer.js +121 -0
- package/src/layout-reducer/layoutTypes.js +34 -0
- package/src/layout-reducer/layoutUtils.js +178 -0
- package/src/layout-reducer/move-layout-element.js +18 -0
- package/src/layout-reducer/remove-layout-element.js +161 -0
- package/src/layout-reducer/replace-layout-element.js +70 -0
- package/src/layout-reducer/resize-flex-children.js +48 -0
- package/src/layout-reducer/wrap-layout-element.js +134 -0
- package/src/layout-view/View.css.js +76 -0
- package/src/layout-view/View.js +116 -0
- package/src/layout-view/useView.js +69 -0
- package/src/layout-view/useViewBroadcastChannel.js +29 -0
- package/src/layout-view/useViewResize.js +27 -0
- package/src/layout-view/viewTypes.js +0 -0
- package/src/layout-view-actions/ViewContext.js +11 -0
- package/src/layout-view-actions/useViewActionDispatcher.js +116 -0
- package/src/layout-view-actions/useViewContributions.js +31 -0
- package/src/palette/Palette.css.js +31 -0
- package/src/palette/Palette.js +85 -0
- package/src/palette/index.js +1 -0
- package/src/placeholder/LayoutStartPanel.css.js +35 -0
- package/src/placeholder/LayoutStartPanel.js +57 -0
- package/src/placeholder/Placeholder.css.js +20 -0
- package/src/placeholder/Placeholder.js +33 -0
- package/src/placeholder/index.js +1 -0
- package/src/responsive/index.js +2 -0
- package/src/responsive/measureMinimumNodeSize.js +24 -0
- package/src/responsive/useResizeObserver.js +109 -0
- package/src/responsive/utils.js +27 -0
- package/src/stack/Stack.css.js +44 -0
- package/src/stack/Stack.js +98 -0
- package/src/stack/StackLayout.js +116 -0
- package/src/stack/index.js +3 -0
- package/src/stack/stackTypes.js +0 -0
- package/src/tabs/TabPanel.css.js +17 -0
- package/src/tabs/TabPanel.js +11 -0
- package/src/tabs/index.js +1 -0
- package/src/tools/config-wrapper/ConfigWrapper.js +55 -0
- package/src/tools/config-wrapper/index.js +1 -0
- package/src/tools/devtools-box/layout-configurator.css.js +113 -0
- package/src/tools/devtools-tree/layout-tree-viewer.css.js +17 -0
- package/src/tools/index.js +3 -0
- package/src/use-persistent-state.js +43 -0
- package/src/utils/index.js +5 -0
- package/src/utils/pathUtils.js +212 -0
- package/src/utils/propUtils.js +15 -0
- package/src/utils/refUtils.js +5 -0
- package/src/utils/styleUtils.js +9 -0
- package/src/utils/typeOf.js +15 -0
- package/types/dock-layout/DockLayout.d.ts +4 -4
- package/types/dock-layout/Drawer.d.ts +4 -4
- package/types/drag-drop/BoxModel.d.ts +7 -7
- package/types/flexbox/FlexboxLayout.d.ts +4 -4
- package/types/flexbox/Splitter.d.ts +1 -1
- package/types/layout-reducer/layoutUtils.d.ts +1 -1
- package/types/layout-reducer/remove-layout-element.d.ts +1 -1
- package/types/layout-reducer/replace-layout-element.d.ts +2 -2
- package/types/layout-reducer/resize-flex-children.d.ts +2 -2
- package/types/layout-view/useView.d.ts +1 -1
- package/types/placeholder/Placeholder.d.ts +4 -4
- package/types/responsive/overflowUtils.d.ts +2 -2
- package/types/stack/StackLayout.d.ts +4 -4
- package/types/tools/devtools-box/layout-configurator.d.ts +26 -26
- package/types/tools/devtools-tree/layout-tree-viewer.d.ts +2 -2
- package/types/utils/pathUtils.d.ts +1 -1
- package/cjs/Component.js +0 -14
- package/cjs/Component.js.map +0 -1
- package/cjs/LayoutContainer.css.js +0 -6
- package/cjs/LayoutContainer.css.js.map +0 -1
- package/cjs/LayoutContainer.js +0 -33
- package/cjs/LayoutContainer.js.map +0 -1
- package/cjs/dock-layout/DockLayout.css.js +0 -6
- package/cjs/dock-layout/DockLayout.css.js.map +0 -1
- package/cjs/dock-layout/DockLayout.js +0 -41
- package/cjs/dock-layout/DockLayout.js.map +0 -1
- package/cjs/dock-layout/Drawer.css.js +0 -6
- package/cjs/dock-layout/Drawer.css.js.map +0 -1
- package/cjs/dock-layout/Drawer.js +0 -95
- package/cjs/dock-layout/Drawer.js.map +0 -1
- package/cjs/drag-drop/BoxModel.js +0 -416
- package/cjs/drag-drop/BoxModel.js.map +0 -1
- package/cjs/drag-drop/DragState.js +0 -161
- package/cjs/drag-drop/DragState.js.map +0 -1
- package/cjs/drag-drop/Draggable.js +0 -192
- package/cjs/drag-drop/Draggable.js.map +0 -1
- package/cjs/drag-drop/DropTarget.js +0 -257
- package/cjs/drag-drop/DropTarget.js.map +0 -1
- package/cjs/drag-drop/DropTargetRenderer.js +0 -218
- package/cjs/drag-drop/DropTargetRenderer.js.map +0 -1
- package/cjs/flexbox/Flexbox.css.js +0 -6
- package/cjs/flexbox/Flexbox.css.js.map +0 -1
- package/cjs/flexbox/Flexbox.js +0 -69
- package/cjs/flexbox/Flexbox.js.map +0 -1
- package/cjs/flexbox/FlexboxLayout.js +0 -30
- package/cjs/flexbox/FlexboxLayout.js.map +0 -1
- package/cjs/flexbox/Splitter.css.js +0 -6
- package/cjs/flexbox/Splitter.css.js.map +0 -1
- package/cjs/flexbox/Splitter.js +0 -122
- package/cjs/flexbox/Splitter.js.map +0 -1
- package/cjs/flexbox/flexbox-utils.js +0 -95
- package/cjs/flexbox/flexbox-utils.js.map +0 -1
- package/cjs/flexbox/useSplitterResizing.js +0 -197
- package/cjs/flexbox/useSplitterResizing.js.map +0 -1
- package/cjs/index.js +0 -122
- package/cjs/index.js.map +0 -1
- package/cjs/layout-action.js +0 -24
- package/cjs/layout-action.js.map +0 -1
- package/cjs/layout-header/Header.css.js +0 -6
- package/cjs/layout-header/Header.css.js.map +0 -1
- package/cjs/layout-header/Header.js +0 -152
- package/cjs/layout-header/Header.js.map +0 -1
- package/cjs/layout-header/useHeader.js +0 -85
- package/cjs/layout-header/useHeader.js.map +0 -1
- package/cjs/layout-provider/LayoutProvider.js +0 -304
- package/cjs/layout-provider/LayoutProvider.js.map +0 -1
- package/cjs/layout-provider/LayoutProviderContext.js +0 -23
- package/cjs/layout-provider/LayoutProviderContext.js.map +0 -1
- package/cjs/layout-provider/useLayoutDragDrop.js +0 -177
- package/cjs/layout-provider/useLayoutDragDrop.js.map +0 -1
- package/cjs/layout-reducer/flexUtils.js +0 -227
- package/cjs/layout-reducer/flexUtils.js.map +0 -1
- package/cjs/layout-reducer/insert-layout-element.js +0 -286
- package/cjs/layout-reducer/insert-layout-element.js.map +0 -1
- package/cjs/layout-reducer/layout-reducer.js +0 -202
- package/cjs/layout-reducer/layout-reducer.js.map +0 -1
- package/cjs/layout-reducer/layoutTypes.js +0 -40
- package/cjs/layout-reducer/layoutTypes.js.map +0 -1
- package/cjs/layout-reducer/layoutUtils.js +0 -237
- package/cjs/layout-reducer/layoutUtils.js.map +0 -1
- package/cjs/layout-reducer/move-layout-element.js +0 -31
- package/cjs/layout-reducer/move-layout-element.js.map +0 -1
- package/cjs/layout-reducer/remove-layout-element.js +0 -237
- package/cjs/layout-reducer/remove-layout-element.js.map +0 -1
- package/cjs/layout-reducer/replace-layout-element.js +0 -96
- package/cjs/layout-reducer/replace-layout-element.js.map +0 -1
- package/cjs/layout-reducer/resize-flex-children.js +0 -62
- package/cjs/layout-reducer/resize-flex-children.js.map +0 -1
- package/cjs/layout-reducer/wrap-layout-element.js +0 -211
- package/cjs/layout-reducer/wrap-layout-element.js.map +0 -1
- package/cjs/layout-view/View.css.js +0 -6
- package/cjs/layout-view/View.css.js.map +0 -1
- package/cjs/layout-view/View.js +0 -160
- package/cjs/layout-view/View.js.map +0 -1
- package/cjs/layout-view/useView.js +0 -75
- package/cjs/layout-view/useView.js.map +0 -1
- package/cjs/layout-view/useViewBroadcastChannel.js +0 -35
- package/cjs/layout-view/useViewBroadcastChannel.js.map +0 -1
- package/cjs/layout-view/useViewResize.js +0 -42
- package/cjs/layout-view/useViewResize.js.map +0 -1
- package/cjs/layout-view-actions/ViewContext.js +0 -16
- package/cjs/layout-view-actions/ViewContext.js.map +0 -1
- package/cjs/layout-view-actions/useViewActionDispatcher.js +0 -112
- package/cjs/layout-view-actions/useViewActionDispatcher.js.map +0 -1
- package/cjs/layout-view-actions/useViewContributions.js +0 -33
- package/cjs/layout-view-actions/useViewContributions.js.map +0 -1
- package/cjs/palette/Palette.css.js +0 -6
- package/cjs/palette/Palette.css.js.map +0 -1
- package/cjs/palette/Palette.js +0 -115
- package/cjs/palette/Palette.js.map +0 -1
- package/cjs/placeholder/LayoutStartPanel.css.js +0 -6
- package/cjs/placeholder/LayoutStartPanel.css.js.map +0 -1
- package/cjs/placeholder/LayoutStartPanel.js +0 -56
- package/cjs/placeholder/LayoutStartPanel.js.map +0 -1
- package/cjs/placeholder/Placeholder.css.js +0 -6
- package/cjs/placeholder/Placeholder.css.js.map +0 -1
- package/cjs/placeholder/Placeholder.js +0 -34
- package/cjs/placeholder/Placeholder.js.map +0 -1
- package/cjs/responsive/useResizeObserver.js +0 -118
- package/cjs/responsive/useResizeObserver.js.map +0 -1
- package/cjs/responsive/utils.js +0 -34
- package/cjs/responsive/utils.js.map +0 -1
- package/cjs/stack/Stack.css.js +0 -6
- package/cjs/stack/Stack.css.js.map +0 -1
- package/cjs/stack/Stack.js +0 -150
- package/cjs/stack/Stack.js.map +0 -1
- package/cjs/stack/StackLayout.js +0 -116
- package/cjs/stack/StackLayout.js.map +0 -1
- package/cjs/use-persistent-state.js +0 -63
- package/cjs/use-persistent-state.js.map +0 -1
- package/cjs/utils/pathUtils.js +0 -293
- package/cjs/utils/pathUtils.js.map +0 -1
- package/cjs/utils/propUtils.js +0 -27
- package/cjs/utils/propUtils.js.map +0 -1
- package/cjs/utils/refUtils.js +0 -12
- package/cjs/utils/refUtils.js.map +0 -1
- package/cjs/utils/styleUtils.js +0 -15
- package/cjs/utils/styleUtils.js.map +0 -1
- package/cjs/utils/typeOf.js +0 -27
- package/cjs/utils/typeOf.js.map +0 -1
- package/esm/Component.js +0 -12
- package/esm/Component.js.map +0 -1
- package/esm/LayoutContainer.css.js +0 -4
- package/esm/LayoutContainer.css.js.map +0 -1
- package/esm/LayoutContainer.js +0 -31
- package/esm/LayoutContainer.js.map +0 -1
- package/esm/dock-layout/DockLayout.css.js +0 -4
- package/esm/dock-layout/DockLayout.css.js.map +0 -1
- package/esm/dock-layout/DockLayout.js +0 -39
- package/esm/dock-layout/DockLayout.js.map +0 -1
- package/esm/dock-layout/Drawer.css.js +0 -4
- package/esm/dock-layout/Drawer.css.js.map +0 -1
- package/esm/dock-layout/Drawer.js +0 -93
- package/esm/dock-layout/Drawer.js.map +0 -1
- package/esm/drag-drop/BoxModel.js +0 -409
- package/esm/drag-drop/BoxModel.js.map +0 -1
- package/esm/drag-drop/DragState.js +0 -159
- package/esm/drag-drop/DragState.js.map +0 -1
- package/esm/drag-drop/Draggable.js +0 -190
- package/esm/drag-drop/Draggable.js.map +0 -1
- package/esm/drag-drop/DropTarget.js +0 -253
- package/esm/drag-drop/DropTarget.js.map +0 -1
- package/esm/drag-drop/DropTargetRenderer.js +0 -216
- package/esm/drag-drop/DropTargetRenderer.js.map +0 -1
- package/esm/flexbox/Flexbox.css.js +0 -4
- package/esm/flexbox/Flexbox.css.js.map +0 -1
- package/esm/flexbox/Flexbox.js +0 -67
- package/esm/flexbox/Flexbox.js.map +0 -1
- package/esm/flexbox/FlexboxLayout.js +0 -28
- package/esm/flexbox/FlexboxLayout.js.map +0 -1
- package/esm/flexbox/Splitter.css.js +0 -4
- package/esm/flexbox/Splitter.css.js.map +0 -1
- package/esm/flexbox/Splitter.js +0 -120
- package/esm/flexbox/Splitter.js.map +0 -1
- package/esm/flexbox/flexbox-utils.js +0 -89
- package/esm/flexbox/flexbox-utils.js.map +0 -1
- package/esm/flexbox/useSplitterResizing.js +0 -195
- package/esm/flexbox/useSplitterResizing.js.map +0 -1
- package/esm/index.js +0 -33
- package/esm/index.js.map +0 -1
- package/esm/layout-action.js +0 -22
- package/esm/layout-action.js.map +0 -1
- package/esm/layout-header/Header.css.js +0 -4
- package/esm/layout-header/Header.css.js.map +0 -1
- package/esm/layout-header/Header.js +0 -150
- package/esm/layout-header/Header.js.map +0 -1
- package/esm/layout-header/useHeader.js +0 -83
- package/esm/layout-header/useHeader.js.map +0 -1
- package/esm/layout-provider/LayoutProvider.js +0 -297
- package/esm/layout-provider/LayoutProvider.js.map +0 -1
- package/esm/layout-provider/LayoutProviderContext.js +0 -20
- package/esm/layout-provider/LayoutProviderContext.js.map +0 -1
- package/esm/layout-provider/useLayoutDragDrop.js +0 -175
- package/esm/layout-provider/useLayoutDragDrop.js.map +0 -1
- package/esm/layout-reducer/flexUtils.js +0 -218
- package/esm/layout-reducer/flexUtils.js.map +0 -1
- package/esm/layout-reducer/insert-layout-element.js +0 -282
- package/esm/layout-reducer/insert-layout-element.js.map +0 -1
- package/esm/layout-reducer/layout-reducer.js +0 -200
- package/esm/layout-reducer/layout-reducer.js.map +0 -1
- package/esm/layout-reducer/layoutTypes.js +0 -36
- package/esm/layout-reducer/layoutTypes.js.map +0 -1
- package/esm/layout-reducer/layoutUtils.js +0 -226
- package/esm/layout-reducer/layoutUtils.js.map +0 -1
- package/esm/layout-reducer/move-layout-element.js +0 -29
- package/esm/layout-reducer/move-layout-element.js.map +0 -1
- package/esm/layout-reducer/remove-layout-element.js +0 -235
- package/esm/layout-reducer/remove-layout-element.js.map +0 -1
- package/esm/layout-reducer/replace-layout-element.js +0 -92
- package/esm/layout-reducer/replace-layout-element.js.map +0 -1
- package/esm/layout-reducer/resize-flex-children.js +0 -59
- package/esm/layout-reducer/resize-flex-children.js.map +0 -1
- package/esm/layout-reducer/wrap-layout-element.js +0 -209
- package/esm/layout-reducer/wrap-layout-element.js.map +0 -1
- package/esm/layout-view/View.css.js +0 -4
- package/esm/layout-view/View.css.js.map +0 -1
- package/esm/layout-view/View.js +0 -158
- package/esm/layout-view/View.js.map +0 -1
- package/esm/layout-view/useView.js +0 -73
- package/esm/layout-view/useView.js.map +0 -1
- package/esm/layout-view/useViewBroadcastChannel.js +0 -33
- package/esm/layout-view/useViewBroadcastChannel.js.map +0 -1
- package/esm/layout-view/useViewResize.js +0 -40
- package/esm/layout-view/useViewResize.js.map +0 -1
- package/esm/layout-view-actions/ViewContext.js +0 -12
- package/esm/layout-view-actions/ViewContext.js.map +0 -1
- package/esm/layout-view-actions/useViewActionDispatcher.js +0 -110
- package/esm/layout-view-actions/useViewActionDispatcher.js.map +0 -1
- package/esm/layout-view-actions/useViewContributions.js +0 -31
- package/esm/layout-view-actions/useViewContributions.js.map +0 -1
- package/esm/palette/Palette.css.js +0 -4
- package/esm/palette/Palette.css.js.map +0 -1
- package/esm/palette/Palette.js +0 -112
- package/esm/palette/Palette.js.map +0 -1
- package/esm/placeholder/LayoutStartPanel.css.js +0 -4
- package/esm/placeholder/LayoutStartPanel.css.js.map +0 -1
- package/esm/placeholder/LayoutStartPanel.js +0 -54
- package/esm/placeholder/LayoutStartPanel.js.map +0 -1
- package/esm/placeholder/Placeholder.css.js +0 -4
- package/esm/placeholder/Placeholder.css.js.map +0 -1
- package/esm/placeholder/Placeholder.js +0 -32
- package/esm/placeholder/Placeholder.js.map +0 -1
- package/esm/responsive/useResizeObserver.js +0 -112
- package/esm/responsive/useResizeObserver.js.map +0 -1
- package/esm/responsive/utils.js +0 -31
- package/esm/responsive/utils.js.map +0 -1
- package/esm/stack/Stack.css.js +0 -4
- package/esm/stack/Stack.css.js.map +0 -1
- package/esm/stack/Stack.js +0 -148
- package/esm/stack/Stack.js.map +0 -1
- package/esm/stack/StackLayout.js +0 -114
- package/esm/stack/StackLayout.js.map +0 -1
- package/esm/use-persistent-state.js +0 -58
- package/esm/use-persistent-state.js.map +0 -1
- package/esm/utils/pathUtils.js +0 -280
- package/esm/utils/pathUtils.js.map +0 -1
- package/esm/utils/propUtils.js +0 -23
- package/esm/utils/propUtils.js.map +0 -1
- package/esm/utils/refUtils.js +0 -10
- package/esm/utils/refUtils.js.map +0 -1
- package/esm/utils/styleUtils.js +0 -13
- package/esm/utils/styleUtils.js.map +0 -1
- package/esm/utils/typeOf.js +0 -23
- package/esm/utils/typeOf.js.map +0 -1
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { useCallback, useRef, useState } from "react";
|
|
2
|
+
import { useViewDispatch } from "../layout-view-actions/ViewContext.js";
|
|
3
|
+
import { queryClosest } from "@vuu-ui/vuu-utils";
|
|
4
|
+
const useHeader = ({ onCollapse, onEditTitle, onExpand, title })=>{
|
|
5
|
+
const [editing, setEditing] = useState(false);
|
|
6
|
+
const [value, setValue] = useState(title);
|
|
7
|
+
const labelFieldRef = useRef(null);
|
|
8
|
+
const viewDispatch = useViewDispatch();
|
|
9
|
+
const handleClose = useCallback((evt)=>viewDispatch?.({
|
|
10
|
+
type: "remove"
|
|
11
|
+
}, evt), [
|
|
12
|
+
viewDispatch
|
|
13
|
+
]);
|
|
14
|
+
const focusTitle = useCallback(()=>{
|
|
15
|
+
labelFieldRef.current?.focus();
|
|
16
|
+
}, []);
|
|
17
|
+
const handleClickEdit = useCallback(()=>{
|
|
18
|
+
focusTitle();
|
|
19
|
+
setEditing((isEditing)=>!isEditing);
|
|
20
|
+
}, [
|
|
21
|
+
focusTitle
|
|
22
|
+
]);
|
|
23
|
+
const handleTitleKeyDown = (evt)=>{
|
|
24
|
+
if ("Enter" === evt.key) setEditing(true);
|
|
25
|
+
};
|
|
26
|
+
const handleMouseDown = useCallback((e)=>{
|
|
27
|
+
const button = queryClosest(e.target, ".saltButton");
|
|
28
|
+
if (null === button) viewDispatch?.({
|
|
29
|
+
type: "mousedown"
|
|
30
|
+
}, e);
|
|
31
|
+
}, [
|
|
32
|
+
viewDispatch
|
|
33
|
+
]);
|
|
34
|
+
const handleExitEditMode = (originalValue = "", finalValue = "", allowDeactivation = true, editCancelled = false)=>{
|
|
35
|
+
setEditing(false);
|
|
36
|
+
if (editCancelled) setValue(originalValue);
|
|
37
|
+
else if (finalValue !== originalValue) {
|
|
38
|
+
setValue(finalValue);
|
|
39
|
+
onEditTitle?.(finalValue);
|
|
40
|
+
}
|
|
41
|
+
if (false === allowDeactivation) labelFieldRef.current?.focus();
|
|
42
|
+
};
|
|
43
|
+
const handleToggleCollapse = useCallback((e)=>{
|
|
44
|
+
viewDispatch?.({
|
|
45
|
+
type: "collapse"
|
|
46
|
+
}, e);
|
|
47
|
+
onCollapse?.();
|
|
48
|
+
}, [
|
|
49
|
+
onCollapse,
|
|
50
|
+
viewDispatch
|
|
51
|
+
]);
|
|
52
|
+
const handleToggleExpand = useCallback((e)=>{
|
|
53
|
+
viewDispatch?.({
|
|
54
|
+
type: "expand"
|
|
55
|
+
}, e);
|
|
56
|
+
onExpand?.();
|
|
57
|
+
}, [
|
|
58
|
+
onExpand,
|
|
59
|
+
viewDispatch
|
|
60
|
+
]);
|
|
61
|
+
return {
|
|
62
|
+
editing,
|
|
63
|
+
focusTitle,
|
|
64
|
+
labelFieldRef,
|
|
65
|
+
onClickEdit: handleClickEdit,
|
|
66
|
+
onClose: handleClose,
|
|
67
|
+
onExitEditMode: handleExitEditMode,
|
|
68
|
+
onMouseDown: handleMouseDown,
|
|
69
|
+
onToggleCollapse: handleToggleCollapse,
|
|
70
|
+
onToggleExpand: handleToggleExpand,
|
|
71
|
+
onTitleKeyDown: handleTitleKeyDown,
|
|
72
|
+
setValue,
|
|
73
|
+
value
|
|
74
|
+
};
|
|
75
|
+
};
|
|
76
|
+
export { useHeader };
|
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
import { jsx } from "react/jsx-runtime";
|
|
2
|
+
import { VuuShellLocation, usePlaceholderJSON } from "@vuu-ui/vuu-utils";
|
|
3
|
+
import { useCallback, useContext, useEffect, useMemo, useRef, useState } from "react";
|
|
4
|
+
import { LayoutActionType, cloneElementAddLayoutProps, layoutFromJson, layoutQuery, layoutReducer, layoutToJSON } from "../layout-reducer/index.js";
|
|
5
|
+
import { findTarget, getChildProp, getProp, getProps, typeOf } from "../utils/index.js";
|
|
6
|
+
import { LayoutProviderContext } from "./LayoutProviderContext.js";
|
|
7
|
+
import { useLayoutDragDrop } from "./useLayoutDragDrop.js";
|
|
8
|
+
const isWorkspaceContainer = (props)=>props.id === VuuShellLocation.WorkspaceContainer;
|
|
9
|
+
const isMultiWorkspaceContainer = (props)=>props.id === VuuShellLocation.MultiWorkspaceContainer;
|
|
10
|
+
const shouldSave = (action)=>[
|
|
11
|
+
"add",
|
|
12
|
+
"drag-drop",
|
|
13
|
+
"remove",
|
|
14
|
+
"set-title",
|
|
15
|
+
"splitter-resize",
|
|
16
|
+
"switch-tab"
|
|
17
|
+
].includes(action.type);
|
|
18
|
+
const getLayoutChangeReason = (action)=>{
|
|
19
|
+
switch(action.type){
|
|
20
|
+
case "switch-tab":
|
|
21
|
+
if (action.id === VuuShellLocation.Workspace) return "switch-active-layout";
|
|
22
|
+
return "switch-active-tab";
|
|
23
|
+
case "save":
|
|
24
|
+
return "save-feature-props";
|
|
25
|
+
case "drag-drop":
|
|
26
|
+
return "drag-drop-operation";
|
|
27
|
+
case "add":
|
|
28
|
+
return "add-component";
|
|
29
|
+
case "remove":
|
|
30
|
+
return "remove-component";
|
|
31
|
+
case "splitter-resize":
|
|
32
|
+
return "resize-component";
|
|
33
|
+
case "set-title":
|
|
34
|
+
return "edit-feature-title";
|
|
35
|
+
default:
|
|
36
|
+
throw Error("unknown layout action");
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
const LayoutProviderVersion = ()=>{
|
|
40
|
+
const version = useLayoutProviderVersion();
|
|
41
|
+
return /*#__PURE__*/ jsx("div", {
|
|
42
|
+
children: `Context: ${version} `
|
|
43
|
+
});
|
|
44
|
+
};
|
|
45
|
+
const pathToDropTarget = `#${VuuShellLocation.Workspace}.ACTIVE_CHILD`;
|
|
46
|
+
const LayoutProvider = (props)=>{
|
|
47
|
+
const { children, createNewChild, workspaceJSON, onLayoutChange } = props;
|
|
48
|
+
const state = useRef(void 0);
|
|
49
|
+
const childrenRef = useRef(children);
|
|
50
|
+
const [, forceRefresh] = useState(null);
|
|
51
|
+
const serializeState = useCallback((source, layoutChangeReason)=>{
|
|
52
|
+
if (onLayoutChange) {
|
|
53
|
+
const workspaceContainer = findTarget(source, isWorkspaceContainer) || state.current;
|
|
54
|
+
const isLayoutContainer = "LayoutContainer" === typeOf(workspaceContainer);
|
|
55
|
+
const target = isLayoutContainer ? getProps(workspaceContainer).children[0] : workspaceContainer;
|
|
56
|
+
const serializedModel = layoutToJSON(target);
|
|
57
|
+
onLayoutChange(serializedModel, layoutChangeReason);
|
|
58
|
+
}
|
|
59
|
+
}, [
|
|
60
|
+
onLayoutChange
|
|
61
|
+
]);
|
|
62
|
+
const dispatchLayoutAction = useCallback((action, suppressSave = false)=>{
|
|
63
|
+
const nextState = layoutReducer(state.current, action);
|
|
64
|
+
if (nextState !== state.current) {
|
|
65
|
+
state.current = nextState;
|
|
66
|
+
forceRefresh({});
|
|
67
|
+
if (!suppressSave && shouldSave(action)) serializeState(nextState, getLayoutChangeReason(action));
|
|
68
|
+
}
|
|
69
|
+
}, [
|
|
70
|
+
forceRefresh,
|
|
71
|
+
serializeState
|
|
72
|
+
]);
|
|
73
|
+
const addComponentToWorkspace = useCallback((component)=>{
|
|
74
|
+
dispatchLayoutAction({
|
|
75
|
+
type: "add",
|
|
76
|
+
path: `#${VuuShellLocation.Workspace}`,
|
|
77
|
+
component
|
|
78
|
+
});
|
|
79
|
+
}, [
|
|
80
|
+
dispatchLayoutAction
|
|
81
|
+
]);
|
|
82
|
+
const switchWorkspace = useCallback((idx)=>{
|
|
83
|
+
dispatchLayoutAction({
|
|
84
|
+
type: "switch-tab",
|
|
85
|
+
nextIdx: idx,
|
|
86
|
+
path: `#${VuuShellLocation.MultiWorkspaceContainer}`
|
|
87
|
+
});
|
|
88
|
+
}, [
|
|
89
|
+
dispatchLayoutAction
|
|
90
|
+
]);
|
|
91
|
+
const showComponentInContextPanel = useCallback((component, title, onContextPanelClose)=>{
|
|
92
|
+
dispatchLayoutAction({
|
|
93
|
+
type: "set-props",
|
|
94
|
+
path: `#${VuuShellLocation.ContextPanel}`,
|
|
95
|
+
props: {
|
|
96
|
+
expanded: true,
|
|
97
|
+
content: component,
|
|
98
|
+
onClose: onContextPanelClose,
|
|
99
|
+
title
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
}, [
|
|
103
|
+
dispatchLayoutAction
|
|
104
|
+
]);
|
|
105
|
+
const layoutActionDispatcher = useCallback((action)=>{
|
|
106
|
+
switch(action.type){
|
|
107
|
+
case "drag-start":
|
|
108
|
+
prepareToDragLayout(action);
|
|
109
|
+
break;
|
|
110
|
+
case "save":
|
|
111
|
+
if (state.current) serializeState(state.current, getLayoutChangeReason(action));
|
|
112
|
+
break;
|
|
113
|
+
case "query":
|
|
114
|
+
if ("PARENT_CONTAINER" === action.query) return layoutQuery(action.query, action.path, state.current);
|
|
115
|
+
break;
|
|
116
|
+
default:
|
|
117
|
+
dispatchLayoutAction(action);
|
|
118
|
+
break;
|
|
119
|
+
}
|
|
120
|
+
}, [
|
|
121
|
+
dispatchLayoutAction,
|
|
122
|
+
serializeState
|
|
123
|
+
]);
|
|
124
|
+
const prepareToDragLayout = useLayoutDragDrop(state, layoutActionDispatcher, pathToDropTarget);
|
|
125
|
+
useEffect(()=>{
|
|
126
|
+
if (workspaceJSON) if (Array.isArray(workspaceJSON)) {
|
|
127
|
+
const targetContainer = findTarget(state.current, isMultiWorkspaceContainer);
|
|
128
|
+
if (targetContainer) {
|
|
129
|
+
const { path: targetContainerPath } = targetContainer.props;
|
|
130
|
+
const target = getChildProp(targetContainer);
|
|
131
|
+
const newLayouts = workspaceJSON.map((ws, i)=>layoutFromJson(ws, `${targetContainerPath}.${i}`));
|
|
132
|
+
const action = target ? {
|
|
133
|
+
type: LayoutActionType.REPLACE,
|
|
134
|
+
target,
|
|
135
|
+
replacement: newLayouts
|
|
136
|
+
} : {
|
|
137
|
+
type: LayoutActionType.ADD,
|
|
138
|
+
path: targetContainerPath,
|
|
139
|
+
component: newLayouts
|
|
140
|
+
};
|
|
141
|
+
dispatchLayoutAction(action, true);
|
|
142
|
+
}
|
|
143
|
+
} else {
|
|
144
|
+
const targetContainer = findTarget(state.current, isWorkspaceContainer);
|
|
145
|
+
if (targetContainer) {
|
|
146
|
+
const { path: targetContainerPath } = targetContainer.props;
|
|
147
|
+
const target = getChildProp(targetContainer);
|
|
148
|
+
const newLayout = layoutFromJson(workspaceJSON, `${targetContainerPath}.0`);
|
|
149
|
+
const action = target ? {
|
|
150
|
+
type: LayoutActionType.REPLACE,
|
|
151
|
+
target,
|
|
152
|
+
replacement: newLayout
|
|
153
|
+
} : {
|
|
154
|
+
type: LayoutActionType.ADD,
|
|
155
|
+
path: targetContainerPath,
|
|
156
|
+
component: newLayout
|
|
157
|
+
};
|
|
158
|
+
dispatchLayoutAction(action, true);
|
|
159
|
+
} else if (workspaceJSON.id === getProp(state.current, "id")) {
|
|
160
|
+
const newLayout = layoutFromJson(workspaceJSON, "0");
|
|
161
|
+
const action = {
|
|
162
|
+
type: LayoutActionType.REPLACE,
|
|
163
|
+
target: state.current,
|
|
164
|
+
replacement: newLayout
|
|
165
|
+
};
|
|
166
|
+
dispatchLayoutAction(action, true);
|
|
167
|
+
} else throw Error(`LayoutProvider unable to render new workspaceJson, no valid target container. Use a valid Shell Layout Template or include a container with the standard workspace id '${VuuShellLocation.Workspace}' `);
|
|
168
|
+
}
|
|
169
|
+
}, [
|
|
170
|
+
dispatchLayoutAction,
|
|
171
|
+
workspaceJSON
|
|
172
|
+
]);
|
|
173
|
+
if (void 0 === state.current) state.current = cloneElementAddLayoutProps(children);
|
|
174
|
+
else if (children !== childrenRef.current) {
|
|
175
|
+
state.current = cloneElementAddLayoutProps(children, state.current);
|
|
176
|
+
childrenRef.current = children;
|
|
177
|
+
}
|
|
178
|
+
return /*#__PURE__*/ jsx(LayoutProviderContext.Provider, {
|
|
179
|
+
value: {
|
|
180
|
+
addComponentToWorkspace,
|
|
181
|
+
createNewChild,
|
|
182
|
+
dispatchLayoutProvider: layoutActionDispatcher,
|
|
183
|
+
showComponentInContextPanel,
|
|
184
|
+
switchWorkspace,
|
|
185
|
+
version: 0
|
|
186
|
+
},
|
|
187
|
+
children: state.current
|
|
188
|
+
});
|
|
189
|
+
};
|
|
190
|
+
const useLayoutProviderDispatch = ()=>{
|
|
191
|
+
const { dispatchLayoutProvider } = useContext(LayoutProviderContext);
|
|
192
|
+
return dispatchLayoutProvider;
|
|
193
|
+
};
|
|
194
|
+
const useLayoutOperation = ()=>{
|
|
195
|
+
const { addComponentToWorkspace, showComponentInContextPanel, switchWorkspace } = useContext(LayoutProviderContext);
|
|
196
|
+
return {
|
|
197
|
+
addComponentToWorkspace,
|
|
198
|
+
showComponentInContextPanel,
|
|
199
|
+
switchWorkspace
|
|
200
|
+
};
|
|
201
|
+
};
|
|
202
|
+
const useLayoutCreateNewChild = ()=>{
|
|
203
|
+
const layoutPlaceholderJSON = usePlaceholderJSON();
|
|
204
|
+
const { createNewChild } = useContext(LayoutProviderContext);
|
|
205
|
+
const defaultCreateNewChild = useMemo(()=>function() {
|
|
206
|
+
if (layoutPlaceholderJSON) {
|
|
207
|
+
const { props } = layoutPlaceholderJSON;
|
|
208
|
+
return layoutFromJson({
|
|
209
|
+
...layoutPlaceholderJSON,
|
|
210
|
+
props: {
|
|
211
|
+
...props,
|
|
212
|
+
resizeable: true,
|
|
213
|
+
style: {
|
|
214
|
+
...props?.style,
|
|
215
|
+
flexGrow: 1,
|
|
216
|
+
flexShrink: 0,
|
|
217
|
+
flexBasis: 0
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
}, "0");
|
|
221
|
+
}
|
|
222
|
+
return layoutFromJson({
|
|
223
|
+
type: "Placeholder",
|
|
224
|
+
props: {
|
|
225
|
+
resizeable: true,
|
|
226
|
+
style: {
|
|
227
|
+
flexGrow: 1,
|
|
228
|
+
flexShrink: 0,
|
|
229
|
+
flexBasis: 0
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
}, "0");
|
|
233
|
+
}, [
|
|
234
|
+
layoutPlaceholderJSON
|
|
235
|
+
]);
|
|
236
|
+
return createNewChild ?? defaultCreateNewChild;
|
|
237
|
+
};
|
|
238
|
+
const useLayoutProviderVersion = ()=>{
|
|
239
|
+
const { version } = useContext(LayoutProviderContext);
|
|
240
|
+
return version;
|
|
241
|
+
};
|
|
242
|
+
export { LayoutProvider, LayoutProviderVersion, useLayoutCreateNewChild, useLayoutOperation, useLayoutProviderDispatch, useLayoutProviderVersion };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { createContext } from "react";
|
|
2
|
+
const unconfiguredLayoutProviderDispatch = (action)=>console.log(`dispatch ${action.type}, have you forgotten to provide a LayoutProvider ?`);
|
|
3
|
+
const unconfiguredService = (message)=>()=>console.log(`${message}, have you forgotten to provide a LayoutProvider ?`);
|
|
4
|
+
const MissingLayoutContextPanel = unconfiguredService("showComponentInContextPanel");
|
|
5
|
+
const isUnconfiguredProperty = (property)=>property === MissingLayoutContextPanel;
|
|
6
|
+
const LayoutProviderContext = createContext({
|
|
7
|
+
addComponentToWorkspace: unconfiguredService("addComponentToWorkspace"),
|
|
8
|
+
dispatchLayoutProvider: unconfiguredLayoutProviderDispatch,
|
|
9
|
+
showComponentInContextPanel: MissingLayoutContextPanel,
|
|
10
|
+
switchWorkspace: unconfiguredService("switchWorkspace"),
|
|
11
|
+
version: -1
|
|
12
|
+
});
|
|
13
|
+
export { LayoutProviderContext, isUnconfiguredProperty };
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import { useCallback, useRef } from "react";
|
|
2
|
+
import { Draggable } from "../drag-drop/index.js";
|
|
3
|
+
import { getIntrinsicSize } from "../layout-reducer/flexUtils.js";
|
|
4
|
+
import { followPath, resolvePath } from "../utils/index.js";
|
|
5
|
+
const NO_INSTRUCTIONS = {};
|
|
6
|
+
const NO_OFFSETS = [
|
|
7
|
+
0,
|
|
8
|
+
0
|
|
9
|
+
];
|
|
10
|
+
const getDragElement = (rect, id, dragElement)=>{
|
|
11
|
+
const wrapper = document.createElement("div");
|
|
12
|
+
wrapper.className = "vuuSimpleDraggableWrapper";
|
|
13
|
+
wrapper.classList.add("vuuSimpleDraggableWrapper", "salt-theme", "salt-density-medium");
|
|
14
|
+
wrapper.dataset.dragging = "true";
|
|
15
|
+
const div = dragElement ?? document.createElement("div");
|
|
16
|
+
div.id = id;
|
|
17
|
+
wrapper.appendChild(div);
|
|
18
|
+
document.body.appendChild(wrapper);
|
|
19
|
+
const cssText = `top:${rect.top}px;left:${rect.left}px;width:${rect.width}px;height:${rect.height}px;`;
|
|
20
|
+
return [
|
|
21
|
+
wrapper,
|
|
22
|
+
cssText,
|
|
23
|
+
rect.left,
|
|
24
|
+
rect.top
|
|
25
|
+
];
|
|
26
|
+
};
|
|
27
|
+
const determineDragOffsets = (draggedElement)=>{
|
|
28
|
+
const { offsetParent } = draggedElement;
|
|
29
|
+
if (null === offsetParent) return NO_OFFSETS;
|
|
30
|
+
{
|
|
31
|
+
const { left: offsetLeft, top: offsetTop } = offsetParent.getBoundingClientRect();
|
|
32
|
+
return [
|
|
33
|
+
offsetLeft,
|
|
34
|
+
offsetTop
|
|
35
|
+
];
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
const useLayoutDragDrop = (rootLayoutRef, dispatch, pathToDropTarget)=>{
|
|
39
|
+
const dragActionRef = useRef(void 0);
|
|
40
|
+
const dragOperationRef = useRef(void 0);
|
|
41
|
+
const draggableHTMLElementRef = useRef(void 0);
|
|
42
|
+
const handleDrag = useCallback((x, y)=>{
|
|
43
|
+
if (dragOperationRef.current && draggableHTMLElementRef.current) {
|
|
44
|
+
const { dragOffsets: [offsetX, offsetY], targetPosition } = dragOperationRef.current;
|
|
45
|
+
const left = "number" == typeof x ? x - offsetX : targetPosition.left;
|
|
46
|
+
const top = "number" == typeof y ? y - offsetY : targetPosition.top;
|
|
47
|
+
if (left !== targetPosition.left || top !== targetPosition.top) {
|
|
48
|
+
dragOperationRef.current.targetPosition.left = left;
|
|
49
|
+
dragOperationRef.current.targetPosition.top = top;
|
|
50
|
+
draggableHTMLElementRef.current.style.top = top + "px";
|
|
51
|
+
draggableHTMLElementRef.current.style.left = left + "px";
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}, []);
|
|
55
|
+
const handleDrop = useCallback((dropTarget)=>{
|
|
56
|
+
if (dragOperationRef.current) {
|
|
57
|
+
const { dragInstructions, payload: draggedReactElement, originalCSS } = dragOperationRef.current;
|
|
58
|
+
if (dropTarget) dispatch({
|
|
59
|
+
type: "drag-drop",
|
|
60
|
+
draggedReactElement,
|
|
61
|
+
dragInstructions,
|
|
62
|
+
dropTarget
|
|
63
|
+
});
|
|
64
|
+
if (draggableHTMLElementRef.current) if (!dropTarget && dragInstructions.DriftHomeIfNoDropTarget) {
|
|
65
|
+
console.log("drift back to start");
|
|
66
|
+
document.body.removeChild(draggableHTMLElementRef.current);
|
|
67
|
+
} else if (dragInstructions.RemoveDraggableOnDragEnd) document.body.removeChild(draggableHTMLElementRef.current);
|
|
68
|
+
else {
|
|
69
|
+
draggableHTMLElementRef.current.style.cssText = originalCSS;
|
|
70
|
+
delete draggableHTMLElementRef.current.dataset.dragging;
|
|
71
|
+
}
|
|
72
|
+
dragActionRef.current = void 0;
|
|
73
|
+
dragOperationRef.current = void 0;
|
|
74
|
+
draggableHTMLElementRef.current = void 0;
|
|
75
|
+
}
|
|
76
|
+
}, [
|
|
77
|
+
dispatch
|
|
78
|
+
]);
|
|
79
|
+
const handleDragStart = useCallback((evt)=>{
|
|
80
|
+
if (dragActionRef.current) {
|
|
81
|
+
const { payload: component, dragContainerPath, dragElement, dragRect, instructions = NO_INSTRUCTIONS, path } = dragActionRef.current;
|
|
82
|
+
const { current: rootLayout } = rootLayoutRef;
|
|
83
|
+
const dragPos = {
|
|
84
|
+
x: evt.clientX,
|
|
85
|
+
y: evt.clientY
|
|
86
|
+
};
|
|
87
|
+
const dragPayload = component ?? followPath(rootLayout, path, true);
|
|
88
|
+
const { id: dragPayloadId } = dragPayload.props;
|
|
89
|
+
const intrinsicSize = getIntrinsicSize(dragPayload);
|
|
90
|
+
let originalCSS = "", dragCSS = "", dragTransform = "";
|
|
91
|
+
let dragStartLeft = -1;
|
|
92
|
+
let dragStartTop = -1;
|
|
93
|
+
let dragOffsets = NO_OFFSETS;
|
|
94
|
+
let element = document.getElementById(dragPayloadId);
|
|
95
|
+
if (null === element) [element, dragCSS, dragStartLeft, dragStartTop] = getDragElement(dragRect, dragPayloadId, dragElement);
|
|
96
|
+
else {
|
|
97
|
+
dragOffsets = determineDragOffsets(element);
|
|
98
|
+
const [offsetLeft, offsetTop] = dragOffsets;
|
|
99
|
+
const { width, height, left, top } = element.getBoundingClientRect();
|
|
100
|
+
dragStartLeft = left - offsetLeft;
|
|
101
|
+
dragStartTop = top - offsetTop;
|
|
102
|
+
dragCSS = `width:${width}px;height:${height}px;left:${dragStartLeft}px;top:${dragStartTop}px;z-index: 100;background-color:#ccc;opacity: 0.6;`;
|
|
103
|
+
element.dataset.dragging = "true";
|
|
104
|
+
originalCSS = element.style.cssText;
|
|
105
|
+
}
|
|
106
|
+
dragTransform = Draggable.initDrag(rootLayoutRef.current, dragContainerPath, dragRect, dragPos, {
|
|
107
|
+
drag: handleDrag,
|
|
108
|
+
drop: handleDrop
|
|
109
|
+
}, intrinsicSize);
|
|
110
|
+
element.style.cssText = dragCSS + dragTransform;
|
|
111
|
+
draggableHTMLElementRef.current = element;
|
|
112
|
+
dragOperationRef.current = {
|
|
113
|
+
payload: dragPayload,
|
|
114
|
+
originalCSS,
|
|
115
|
+
dragRect,
|
|
116
|
+
dragOffsets,
|
|
117
|
+
dragInstructions: instructions,
|
|
118
|
+
targetPosition: {
|
|
119
|
+
left: dragStartLeft,
|
|
120
|
+
top: dragStartTop
|
|
121
|
+
}
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
}, [
|
|
125
|
+
handleDrag,
|
|
126
|
+
handleDrop,
|
|
127
|
+
rootLayoutRef
|
|
128
|
+
]);
|
|
129
|
+
const prepareToDrag = useCallback((action)=>{
|
|
130
|
+
const { evt, ...options } = action;
|
|
131
|
+
try {
|
|
132
|
+
dragActionRef.current = {
|
|
133
|
+
...options,
|
|
134
|
+
dragContainerPath: resolvePath(rootLayoutRef.current, pathToDropTarget)
|
|
135
|
+
};
|
|
136
|
+
Draggable.handleMousedown(evt, handleDragStart, options.instructions);
|
|
137
|
+
} catch (err) {
|
|
138
|
+
console.warn(`[useLayoutDragDrop] path ${pathToDropTarget} not resolved, the application layout does not have the required elements to support drag drop`);
|
|
139
|
+
}
|
|
140
|
+
}, [
|
|
141
|
+
handleDragStart,
|
|
142
|
+
pathToDropTarget,
|
|
143
|
+
rootLayoutRef
|
|
144
|
+
]);
|
|
145
|
+
return prepareToDrag;
|
|
146
|
+
};
|
|
147
|
+
export { useLayoutDragDrop };
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
import { getLayoutComponent, uuid } from "@vuu-ui/vuu-utils";
|
|
2
|
+
import react from "react";
|
|
3
|
+
import { getProps, resetPath } from "../utils/index.js";
|
|
4
|
+
const placeHolderProps = {
|
|
5
|
+
"data-placeholder": true,
|
|
6
|
+
"data-resizeable": true
|
|
7
|
+
};
|
|
8
|
+
const NO_STYLE = {};
|
|
9
|
+
const auto = "auto";
|
|
10
|
+
const defaultFlexStyle = {
|
|
11
|
+
flexBasis: 0,
|
|
12
|
+
flexGrow: 1,
|
|
13
|
+
flexShrink: 1,
|
|
14
|
+
height: auto,
|
|
15
|
+
width: auto
|
|
16
|
+
};
|
|
17
|
+
const CROSS_DIMENSION = {
|
|
18
|
+
height: "width",
|
|
19
|
+
width: "height"
|
|
20
|
+
};
|
|
21
|
+
const getFlexDimensions = (flexDirection = "row")=>{
|
|
22
|
+
if ("row" === flexDirection) return [
|
|
23
|
+
"width",
|
|
24
|
+
"height",
|
|
25
|
+
"column"
|
|
26
|
+
];
|
|
27
|
+
return [
|
|
28
|
+
"height",
|
|
29
|
+
"width",
|
|
30
|
+
"row"
|
|
31
|
+
];
|
|
32
|
+
};
|
|
33
|
+
const isPercentageSize = (value)=>"string" == typeof value && value.endsWith("%");
|
|
34
|
+
const getIntrinsicSize = (component)=>{
|
|
35
|
+
const { style: { width = auto, height = auto } = NO_STYLE } = component.props;
|
|
36
|
+
const numHeight = "number" == typeof height;
|
|
37
|
+
const numWidth = "number" == typeof width;
|
|
38
|
+
if (numHeight && numWidth) return {
|
|
39
|
+
height,
|
|
40
|
+
width
|
|
41
|
+
};
|
|
42
|
+
if (numHeight) return {
|
|
43
|
+
height
|
|
44
|
+
};
|
|
45
|
+
if (numWidth) return {
|
|
46
|
+
width
|
|
47
|
+
};
|
|
48
|
+
};
|
|
49
|
+
function getFlexStyle(component, dimension, pos) {
|
|
50
|
+
const crossDimension = CROSS_DIMENSION[dimension];
|
|
51
|
+
const { style: { [crossDimension]: intrinsicCrossSize = auto, ...intrinsicStyles } = NO_STYLE } = component.props;
|
|
52
|
+
if (pos && pos[dimension]) return {
|
|
53
|
+
...intrinsicStyles,
|
|
54
|
+
...defaultFlexStyle,
|
|
55
|
+
flexBasis: pos[dimension],
|
|
56
|
+
flexGrow: 0,
|
|
57
|
+
flexShrink: 0
|
|
58
|
+
};
|
|
59
|
+
return {
|
|
60
|
+
...intrinsicStyles,
|
|
61
|
+
...defaultFlexStyle,
|
|
62
|
+
[crossDimension]: intrinsicCrossSize
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
function hasUnboundedFlexStyle(component) {
|
|
66
|
+
const { style: { flex, flexGrow, flexShrink, flexBasis } = NO_STYLE } = component.props;
|
|
67
|
+
if ("number" == typeof flex) return true;
|
|
68
|
+
if (0 === flexBasis && 1 === flexGrow && 1 === flexShrink) return true;
|
|
69
|
+
if ("number" == typeof flexBasis) return false;
|
|
70
|
+
return true;
|
|
71
|
+
}
|
|
72
|
+
function getFlexOrIntrinsicStyle(component, dimension, pos) {
|
|
73
|
+
const crossDimension = CROSS_DIMENSION[dimension];
|
|
74
|
+
const { style: { [dimension]: intrinsicSize = auto, [crossDimension]: intrinsicCrossSize = auto, ...intrinsicStyles } = NO_STYLE } = component.props;
|
|
75
|
+
if (intrinsicSize !== auto) {
|
|
76
|
+
if (isPercentageSize(intrinsicSize)) return {
|
|
77
|
+
flexBasis: 0,
|
|
78
|
+
flexGrow: 1,
|
|
79
|
+
flexShrink: 1,
|
|
80
|
+
[dimension]: void 0,
|
|
81
|
+
[crossDimension]: intrinsicCrossSize
|
|
82
|
+
};
|
|
83
|
+
return {
|
|
84
|
+
flexBasis: intrinsicSize,
|
|
85
|
+
flexGrow: 0,
|
|
86
|
+
flexShrink: 0,
|
|
87
|
+
[dimension]: intrinsicSize,
|
|
88
|
+
[crossDimension]: intrinsicCrossSize
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
if (pos && pos[dimension]) return {
|
|
92
|
+
...intrinsicStyles,
|
|
93
|
+
...defaultFlexStyle,
|
|
94
|
+
flexBasis: pos[dimension],
|
|
95
|
+
flexGrow: 0,
|
|
96
|
+
flexShrink: 0
|
|
97
|
+
};
|
|
98
|
+
return {
|
|
99
|
+
...intrinsicStyles,
|
|
100
|
+
[crossDimension]: intrinsicCrossSize
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
function wrapIntrinsicSizeComponentWithFlexbox(component, flexDirection, path, clientRect, dropRect) {
|
|
104
|
+
const wrappedChildren = [];
|
|
105
|
+
let pathIndex = 0;
|
|
106
|
+
let endPlaceholder;
|
|
107
|
+
if (clientRect && dropRect) {
|
|
108
|
+
let startPlaceholder;
|
|
109
|
+
const [dropLeft, dropTop, dropRight, dropBottom] = dropRect;
|
|
110
|
+
[startPlaceholder, endPlaceholder] = "column" === flexDirection ? [
|
|
111
|
+
dropTop - clientRect.top,
|
|
112
|
+
clientRect.bottom - dropBottom
|
|
113
|
+
] : [
|
|
114
|
+
dropLeft - clientRect.left,
|
|
115
|
+
clientRect.right - dropRight
|
|
116
|
+
];
|
|
117
|
+
if (startPlaceholder) wrappedChildren.push(createPlaceHolder(`${path}.${pathIndex++}`, startPlaceholder, {
|
|
118
|
+
flexGrow: 0,
|
|
119
|
+
flexShrink: 0
|
|
120
|
+
}));
|
|
121
|
+
} else endPlaceholder = true;
|
|
122
|
+
const { version = 0, style } = getProps(component);
|
|
123
|
+
wrappedChildren.push(resetPath(component, `${path}.${pathIndex++}`, {
|
|
124
|
+
version: version + 1,
|
|
125
|
+
style: {
|
|
126
|
+
...style,
|
|
127
|
+
flexBasis: "auto",
|
|
128
|
+
flexGrow: 0,
|
|
129
|
+
flexShrink: 0
|
|
130
|
+
}
|
|
131
|
+
}));
|
|
132
|
+
if (endPlaceholder) wrappedChildren.push(createPlaceHolder(`${path}.${pathIndex++}`, 0, void 0, {
|
|
133
|
+
[`data-${flexDirection}-placeholder`]: true
|
|
134
|
+
}));
|
|
135
|
+
return createFlexbox(flexDirection, {
|
|
136
|
+
resizeable: false,
|
|
137
|
+
style: {
|
|
138
|
+
flexBasis: "auto"
|
|
139
|
+
}
|
|
140
|
+
}, wrappedChildren, path);
|
|
141
|
+
}
|
|
142
|
+
const getFlexValue = (flexBasis, flexFill)=>{
|
|
143
|
+
if (flexFill) return;
|
|
144
|
+
return 0 === flexBasis ? 1 : 0;
|
|
145
|
+
};
|
|
146
|
+
function createFlexbox(flexDirection, props, children, path) {
|
|
147
|
+
const id = uuid();
|
|
148
|
+
const { flexFill, style, resizeable = true } = props;
|
|
149
|
+
const { flexBasis = flexFill ? void 0 : "auto" } = style;
|
|
150
|
+
const flex = getFlexValue(flexBasis, flexFill);
|
|
151
|
+
const FlexboxLayout = getLayoutComponent("Flexbox");
|
|
152
|
+
return react.createElement(FlexboxLayout, {
|
|
153
|
+
id,
|
|
154
|
+
key: id,
|
|
155
|
+
path,
|
|
156
|
+
flexFill,
|
|
157
|
+
style: {
|
|
158
|
+
...style,
|
|
159
|
+
flexDirection,
|
|
160
|
+
flexBasis,
|
|
161
|
+
flexGrow: flex,
|
|
162
|
+
flexShrink: flex
|
|
163
|
+
},
|
|
164
|
+
resizeable
|
|
165
|
+
}, children);
|
|
166
|
+
}
|
|
167
|
+
const baseStyle = {
|
|
168
|
+
flexGrow: 1,
|
|
169
|
+
flexShrink: 1
|
|
170
|
+
};
|
|
171
|
+
function createPlaceHolder(path, size, style, props) {
|
|
172
|
+
const id = uuid();
|
|
173
|
+
return react.createElement("div", {
|
|
174
|
+
...placeHolderProps,
|
|
175
|
+
...props,
|
|
176
|
+
"data-path": path,
|
|
177
|
+
id,
|
|
178
|
+
key: id,
|
|
179
|
+
style: {
|
|
180
|
+
...baseStyle,
|
|
181
|
+
...style,
|
|
182
|
+
flexBasis: size
|
|
183
|
+
}
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
export { createFlexbox, createPlaceHolder, getFlexDimensions, getFlexOrIntrinsicStyle, getFlexStyle, getIntrinsicSize, hasUnboundedFlexStyle, wrapIntrinsicSizeComponentWithFlexbox };
|