@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,179 @@
|
|
|
1
|
+
import { uuid } from "@vuu-ui/vuu-utils";
|
|
2
|
+
import react from "react";
|
|
3
|
+
import { getProp, getProps, nextStep, resetPath, typeOf } from "../utils/index.js";
|
|
4
|
+
import { createPlaceHolder, getFlexDimensions, getFlexOrIntrinsicStyle, getIntrinsicSize, wrapIntrinsicSizeComponentWithFlexbox } from "./flexUtils.js";
|
|
5
|
+
import { getDefaultTabLabel, getManagedDimension } from "./layoutUtils.js";
|
|
6
|
+
function getInsertTabBeforeAfter(stack, pos) {
|
|
7
|
+
const { children: tabs } = stack.props;
|
|
8
|
+
const tabCount = tabs.length;
|
|
9
|
+
const { index = -1, positionRelativeToTab = "after" } = pos.tab || {};
|
|
10
|
+
return -1 === index || index >= tabCount ? [
|
|
11
|
+
tabs[tabCount - 1],
|
|
12
|
+
"after"
|
|
13
|
+
] : [
|
|
14
|
+
tabs[index] ?? null,
|
|
15
|
+
positionRelativeToTab
|
|
16
|
+
];
|
|
17
|
+
}
|
|
18
|
+
function insertIntoContainer(container, targetContainer, newComponent) {
|
|
19
|
+
const { active: containerActive, children: containerChildren = [], path: containerPath } = getProps(container);
|
|
20
|
+
const existingComponentPath = getProp(targetContainer, "path");
|
|
21
|
+
const { idx, finalStep } = nextStep(containerPath, existingComponentPath, true);
|
|
22
|
+
const [insertedIdx, children] = finalStep ? insertIntoChildren(container, containerChildren, newComponent) : [
|
|
23
|
+
containerActive,
|
|
24
|
+
containerChildren?.map((child, index)=>index === idx ? insertIntoContainer(child, targetContainer, newComponent) : child)
|
|
25
|
+
];
|
|
26
|
+
const active = "Stack" === typeOf(container) ? Array.isArray(insertedIdx) ? insertedIdx[0] : insertedIdx : containerActive;
|
|
27
|
+
return react.cloneElement(container, {
|
|
28
|
+
active
|
|
29
|
+
}, children);
|
|
30
|
+
}
|
|
31
|
+
const getDefaultTitle = (containerType, component, index, existingLabels)=>"Stack" === containerType ? getDefaultTabLabel(component, index, existingLabels) : void 0;
|
|
32
|
+
const getChildrenTitles = (children)=>children.map((child)=>child.props.title);
|
|
33
|
+
function insertIntoChildren(container, containerChildren, newComponent) {
|
|
34
|
+
if (Array.isArray(newComponent)) {
|
|
35
|
+
const [firstChild, ...rest] = newComponent;
|
|
36
|
+
let [idx, children] = insertIntoChildren(container, containerChildren, firstChild);
|
|
37
|
+
for (const child of rest)[, children] = insertIntoChildren(container, children, child);
|
|
38
|
+
return [
|
|
39
|
+
idx,
|
|
40
|
+
children
|
|
41
|
+
];
|
|
42
|
+
}
|
|
43
|
+
const containerPath = getProp(container, "path");
|
|
44
|
+
const count = containerChildren?.length;
|
|
45
|
+
const { id = uuid(), title = getDefaultTitle(typeOf(container), newComponent, count ?? 0, getChildrenTitles(containerChildren)) } = getProps(newComponent);
|
|
46
|
+
if (count) return [
|
|
47
|
+
count,
|
|
48
|
+
containerChildren.concat(resetPath(newComponent, `${containerPath}.${count}`, {
|
|
49
|
+
id,
|
|
50
|
+
key: id,
|
|
51
|
+
title
|
|
52
|
+
}))
|
|
53
|
+
];
|
|
54
|
+
return [
|
|
55
|
+
0,
|
|
56
|
+
[
|
|
57
|
+
resetPath(newComponent, `${containerPath}.0`, {
|
|
58
|
+
id,
|
|
59
|
+
title
|
|
60
|
+
})
|
|
61
|
+
]
|
|
62
|
+
];
|
|
63
|
+
}
|
|
64
|
+
function insertBesideChild(container, existingComponent, newComponent, insertionPosition, pos, clientRect, dropRect) {
|
|
65
|
+
const { active: containerActive, children: containerChildren, path: containerPath } = getProps(container);
|
|
66
|
+
const existingComponentPath = getProp(existingComponent, "path");
|
|
67
|
+
const { idx, finalStep } = nextStep(containerPath, existingComponentPath);
|
|
68
|
+
const [insertedIdx, children] = finalStep ? updateChildren(container, containerChildren, idx, newComponent, insertionPosition, pos, clientRect, dropRect) : [
|
|
69
|
+
containerActive,
|
|
70
|
+
containerChildren.map((child, index)=>index === idx ? insertBesideChild(child, existingComponent, newComponent, insertionPosition, pos, clientRect, dropRect) : child)
|
|
71
|
+
];
|
|
72
|
+
const active = "Stack" === typeOf(container) ? insertedIdx : containerActive;
|
|
73
|
+
return react.cloneElement(container, {
|
|
74
|
+
active
|
|
75
|
+
}, children);
|
|
76
|
+
}
|
|
77
|
+
function updateChildren(container, containerChildren, idx, newComponent, insertionPosition, pos, clientRect, dropRect) {
|
|
78
|
+
const intrinsicSize = getIntrinsicSize(newComponent);
|
|
79
|
+
if (intrinsicSize?.width && intrinsicSize?.height) return insertIntrinsicSizedComponent(container, containerChildren, idx, newComponent, insertionPosition, clientRect, dropRect);
|
|
80
|
+
return insertFlexComponent(container, containerChildren, idx, newComponent, insertionPosition, pos?.width || pos?.height, clientRect);
|
|
81
|
+
}
|
|
82
|
+
const getLeadingPlaceholderSize = (flexDirection, insertionPosition, { top, right, bottom, left }, [rectLeft, rectTop, rectRight, rectBottom])=>{
|
|
83
|
+
if ("column" === flexDirection && "before" === insertionPosition) return rectTop - top;
|
|
84
|
+
if ("column" === flexDirection) return bottom - rectBottom;
|
|
85
|
+
if ("row" === flexDirection && "before" === insertionPosition) return rectLeft - left;
|
|
86
|
+
if ("row" === flexDirection) return right - rectRight;
|
|
87
|
+
};
|
|
88
|
+
function insertIntrinsicSizedComponent(container, containerChildren, idx, newComponent, insertionPosition, clientRect, dropRect) {
|
|
89
|
+
const { style: { flexDirection } } = getProps(container);
|
|
90
|
+
const [dimension, crossDimension, contraDirection] = getFlexDimensions(flexDirection);
|
|
91
|
+
const { [crossDimension]: intrinsicCrossSize, [dimension]: intrinsicSize } = getIntrinsicSize(newComponent);
|
|
92
|
+
const path = getProp(containerChildren[idx], "path");
|
|
93
|
+
const placeholderSize = getLeadingPlaceholderSize(flexDirection, insertionPosition, clientRect, dropRect);
|
|
94
|
+
const [itemToInsert, size] = intrinsicCrossSize < clientRect[crossDimension] ? [
|
|
95
|
+
wrapIntrinsicSizeComponentWithFlexbox(newComponent, contraDirection, path, clientRect, dropRect),
|
|
96
|
+
intrinsicSize
|
|
97
|
+
] : [
|
|
98
|
+
newComponent,
|
|
99
|
+
void 0
|
|
100
|
+
];
|
|
101
|
+
const placeholder = placeholderSize ? createPlaceHolder(path, placeholderSize, {
|
|
102
|
+
flexGrow: 0,
|
|
103
|
+
flexShrink: 0
|
|
104
|
+
}) : void 0;
|
|
105
|
+
if (intrinsicCrossSize > clientRect[crossDimension]) containerChildren = containerChildren.map((child)=>{
|
|
106
|
+
if (getProp(child, "placeholder")) return child;
|
|
107
|
+
{
|
|
108
|
+
const { [crossDimension]: intrinsicCrossChildSize } = getIntrinsicSize(child);
|
|
109
|
+
if (intrinsicCrossChildSize && intrinsicCrossChildSize < intrinsicCrossSize) return wrapIntrinsicSizeComponentWithFlexbox(child, contraDirection, getProp(child, "path"));
|
|
110
|
+
return child;
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
return insertFlexComponent(container, containerChildren, idx, itemToInsert, insertionPosition, size, clientRect, placeholder);
|
|
114
|
+
}
|
|
115
|
+
function insertFlexComponent(container, containerChildren, idx, newComponent, insertionPosition, size, targetRect, placeholder) {
|
|
116
|
+
const containerPath = getProp(container, "path");
|
|
117
|
+
let insertedIdx = 0;
|
|
118
|
+
const children = containerChildren && 0 !== containerChildren.length ? containerChildren.reduce((arr, child, i)=>{
|
|
119
|
+
if (idx === i) {
|
|
120
|
+
const [existingComponent, insertedComponent] = getStyledComponents(container, child, newComponent, targetRect);
|
|
121
|
+
if ("before" === insertionPosition) if (placeholder) arr.push(placeholder, insertedComponent, existingComponent);
|
|
122
|
+
else arr.push(insertedComponent, existingComponent);
|
|
123
|
+
else if (placeholder) arr.push(existingComponent, insertedComponent, placeholder);
|
|
124
|
+
else arr.push(existingComponent, insertedComponent);
|
|
125
|
+
insertedIdx = arr.indexOf(insertedComponent);
|
|
126
|
+
} else arr.push(child);
|
|
127
|
+
return arr;
|
|
128
|
+
}, []).map((child, i)=>i < insertedIdx ? child : resetPath(child, `${containerPath}.${i}`)) : [
|
|
129
|
+
newComponent
|
|
130
|
+
];
|
|
131
|
+
return [
|
|
132
|
+
insertedIdx,
|
|
133
|
+
children
|
|
134
|
+
];
|
|
135
|
+
}
|
|
136
|
+
function getStyledComponents(container, existingComponent, newComponent, targetRect) {
|
|
137
|
+
const id = uuid();
|
|
138
|
+
let { version = 0 } = getProps(newComponent);
|
|
139
|
+
version += 1;
|
|
140
|
+
if ("Flexbox" === typeOf(container)) {
|
|
141
|
+
const { style: containerStyle } = container.props;
|
|
142
|
+
const [dim] = getManagedDimension(containerStyle);
|
|
143
|
+
const splitterSize = 6;
|
|
144
|
+
const size = {
|
|
145
|
+
[dim]: (targetRect[dim] - splitterSize) / 2
|
|
146
|
+
};
|
|
147
|
+
const existingComponentStyle = getFlexOrIntrinsicStyle(existingComponent, dim, size);
|
|
148
|
+
const newComponentStyle = getFlexOrIntrinsicStyle(newComponent, dim, size);
|
|
149
|
+
return [
|
|
150
|
+
react.cloneElement(existingComponent, {
|
|
151
|
+
style: existingComponentStyle
|
|
152
|
+
}),
|
|
153
|
+
react.cloneElement(newComponent, {
|
|
154
|
+
id,
|
|
155
|
+
version,
|
|
156
|
+
style: newComponentStyle
|
|
157
|
+
})
|
|
158
|
+
];
|
|
159
|
+
}
|
|
160
|
+
{
|
|
161
|
+
const { style: { left: _1, top: _2, flex: _3, ...style } = {
|
|
162
|
+
left: void 0,
|
|
163
|
+
top: void 0,
|
|
164
|
+
flex: void 0
|
|
165
|
+
} } = getProps(newComponent);
|
|
166
|
+
return [
|
|
167
|
+
existingComponent,
|
|
168
|
+
react.cloneElement(newComponent, {
|
|
169
|
+
id,
|
|
170
|
+
version,
|
|
171
|
+
style: {
|
|
172
|
+
...style,
|
|
173
|
+
flex: "1 1 0px"
|
|
174
|
+
}
|
|
175
|
+
})
|
|
176
|
+
];
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
export { getInsertTabBeforeAfter, insertBesideChild, insertIntoContainer };
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import { isContainer } from "@vuu-ui/vuu-utils";
|
|
2
|
+
import react from "react";
|
|
3
|
+
import { findTarget, followPath, followPathToParent, getProp, getProps, typeOf } from "../utils/index.js";
|
|
4
|
+
import { getIntrinsicSize } from "./flexUtils.js";
|
|
5
|
+
import { getInsertTabBeforeAfter, insertBesideChild, insertIntoContainer } from "./insert-layout-element.js";
|
|
6
|
+
import { moveChild } from "./move-layout-element.js";
|
|
7
|
+
import { LayoutActionType } from "./layoutTypes.js";
|
|
8
|
+
import { removeChild } from "./remove-layout-element.js";
|
|
9
|
+
import { _replaceChild, replaceChild, swapChild } from "./replace-layout-element.js";
|
|
10
|
+
import { resizeFlexChild, resizeFlexChildren } from "./resize-flex-children.js";
|
|
11
|
+
import { wrap } from "./wrap-layout-element.js";
|
|
12
|
+
const layoutReducer = (state, action)=>{
|
|
13
|
+
switch(action.type){
|
|
14
|
+
case LayoutActionType.ADD:
|
|
15
|
+
return addChild(state, action);
|
|
16
|
+
case LayoutActionType.DRAG_DROP:
|
|
17
|
+
return dragDrop(state, action);
|
|
18
|
+
case "collapse":
|
|
19
|
+
case "expand":
|
|
20
|
+
return setChildProps(state, action);
|
|
21
|
+
case LayoutActionType.REMOVE:
|
|
22
|
+
return removeChild(state, action);
|
|
23
|
+
case LayoutActionType.REPLACE:
|
|
24
|
+
return replaceChild(state, action);
|
|
25
|
+
case LayoutActionType.SET_PROP:
|
|
26
|
+
return setProp(state, action);
|
|
27
|
+
case LayoutActionType.SET_PROPS:
|
|
28
|
+
return setProps(state, action);
|
|
29
|
+
case LayoutActionType.SET_TITLE:
|
|
30
|
+
return setProp(state, {
|
|
31
|
+
type: "set-prop",
|
|
32
|
+
path: action.path,
|
|
33
|
+
propName: "title",
|
|
34
|
+
propValue: action.title
|
|
35
|
+
});
|
|
36
|
+
case LayoutActionType.SPLITTER_RESIZE:
|
|
37
|
+
return resizeFlexChildren(state, action);
|
|
38
|
+
case LayoutActionType.LAYOUT_RESIZE:
|
|
39
|
+
return resizeFlexChild(state, action);
|
|
40
|
+
case LayoutActionType.SWITCH_TAB:
|
|
41
|
+
return switchTab(state, action);
|
|
42
|
+
case LayoutActionType.MOVE_CHILD:
|
|
43
|
+
return moveChild(state, action);
|
|
44
|
+
default:
|
|
45
|
+
return state;
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
const switchTab = (state, { path, nextIdx })=>{
|
|
49
|
+
const target = followPath(state, path, true);
|
|
50
|
+
const replacement = react.cloneElement(target, {
|
|
51
|
+
active: nextIdx
|
|
52
|
+
});
|
|
53
|
+
return swapChild(state, target, replacement);
|
|
54
|
+
};
|
|
55
|
+
const setProp = (state, { path, propName, propValue })=>{
|
|
56
|
+
const target = followPath(state, path, true);
|
|
57
|
+
const replacement = react.cloneElement(target, {
|
|
58
|
+
[propName]: propValue
|
|
59
|
+
});
|
|
60
|
+
return swapChild(state, target, replacement);
|
|
61
|
+
};
|
|
62
|
+
const setProps = (state, { path, props })=>{
|
|
63
|
+
const target = followPath(state, path, true);
|
|
64
|
+
const replacement = react.cloneElement(target, props);
|
|
65
|
+
return swapChild(state, target, replacement);
|
|
66
|
+
};
|
|
67
|
+
const setChildProps = (state, { path, type })=>{
|
|
68
|
+
if (!path) return state;
|
|
69
|
+
{
|
|
70
|
+
const target = followPath(state, path, true);
|
|
71
|
+
return swapChild(state, target, target, type);
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
const dragDrop = (layoutRoot, action)=>{
|
|
75
|
+
const { draggedReactElement: newComponent, dragInstructions, dropTarget } = action;
|
|
76
|
+
const existingComponent = dropTarget.component;
|
|
77
|
+
const { pos } = dropTarget;
|
|
78
|
+
const destinationTabstrip = pos?.position?.Header && "Stack" === typeOf(existingComponent);
|
|
79
|
+
const { id, version } = getProps(newComponent);
|
|
80
|
+
const intrinsicSize = getIntrinsicSize(newComponent);
|
|
81
|
+
let newLayoutRoot;
|
|
82
|
+
if (destinationTabstrip) {
|
|
83
|
+
const [targetTab, insertionPosition] = getInsertTabBeforeAfter(existingComponent, pos);
|
|
84
|
+
newLayoutRoot = void 0 === targetTab ? insertIntoContainer(layoutRoot, existingComponent, newComponent) : insertBesideChild(layoutRoot, targetTab, newComponent, insertionPosition);
|
|
85
|
+
} else newLayoutRoot = !intrinsicSize && pos?.position?.Centre ? _replaceChild(layoutRoot, existingComponent, newComponent) : dropLayoutIntoContainer(layoutRoot, dropTarget, newComponent);
|
|
86
|
+
if (dragInstructions.DoNotRemove) return newLayoutRoot;
|
|
87
|
+
const finalTarget = findTarget(newLayoutRoot, (props)=>props.id === id && props.version === version);
|
|
88
|
+
const finalPath = getProp(finalTarget, "path");
|
|
89
|
+
return removeChild(newLayoutRoot, {
|
|
90
|
+
path: finalPath,
|
|
91
|
+
type: "remove"
|
|
92
|
+
});
|
|
93
|
+
};
|
|
94
|
+
const addChild = (layoutRoot, { path: containerPath, component })=>insertIntoContainer(layoutRoot, followPath(layoutRoot, containerPath), component);
|
|
95
|
+
const dropLayoutIntoContainer = (layoutRoot, dropTarget, newComponent)=>{
|
|
96
|
+
const { component, pos, clientRect, dropRect } = dropTarget;
|
|
97
|
+
const existingComponent = component;
|
|
98
|
+
const existingComponentPath = getProp(existingComponent, "path");
|
|
99
|
+
if ("0.0" === existingComponentPath) return wrap(layoutRoot, existingComponent, newComponent, pos);
|
|
100
|
+
const targetContainer = followPathToParent(layoutRoot, existingComponentPath);
|
|
101
|
+
if (withTheGrain(pos, targetContainer)) {
|
|
102
|
+
const insertionPosition = pos.position.SouthOrEast ? "after" : "before";
|
|
103
|
+
return insertBesideChild(layoutRoot, existingComponent, newComponent, insertionPosition, pos, clientRect, dropRect);
|
|
104
|
+
}
|
|
105
|
+
if (!withTheGrain(pos, targetContainer)) return wrap(layoutRoot, existingComponent, newComponent, pos, clientRect, dropRect);
|
|
106
|
+
if (isContainer(typeOf(targetContainer))) return wrap(layoutRoot, existingComponent, newComponent, pos);
|
|
107
|
+
throw Error(`no support right now for position = ${pos.position}`);
|
|
108
|
+
};
|
|
109
|
+
const withTheGrain = (pos, container)=>{
|
|
110
|
+
if (pos.position.Centre) return isTerrace(container) || isTower(container);
|
|
111
|
+
return pos.position.NorthOrSouth ? isTower(container) : pos.position.EastOrWest ? isTerrace(container) : false;
|
|
112
|
+
};
|
|
113
|
+
const isTower = (container)=>{
|
|
114
|
+
const { style } = container.props;
|
|
115
|
+
return "Flexbox" === typeOf(container) && "column" === style.flexDirection;
|
|
116
|
+
};
|
|
117
|
+
const isTerrace = (container)=>{
|
|
118
|
+
const { style } = container.props;
|
|
119
|
+
return "Flexbox" === typeOf(container) && "column" !== style.flexDirection;
|
|
120
|
+
};
|
|
121
|
+
export { layoutReducer };
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
const LayoutActionType = {
|
|
2
|
+
ADD: "add",
|
|
3
|
+
DRAG_START: "drag-start",
|
|
4
|
+
DRAG_DROP: "drag-drop",
|
|
5
|
+
LAYOUT_RESIZE: "layout-resize",
|
|
6
|
+
MAXIMIZE: "maximize",
|
|
7
|
+
MINIMIZE: "minimize",
|
|
8
|
+
MOVE_CHILD: "move-child",
|
|
9
|
+
QUERY: "query",
|
|
10
|
+
REMOVE: "remove",
|
|
11
|
+
REPLACE: "replace",
|
|
12
|
+
RESTORE: "restore",
|
|
13
|
+
SET_PROP: "set-prop",
|
|
14
|
+
SET_PROPS: "set-props",
|
|
15
|
+
SET_TITLE: "set-title",
|
|
16
|
+
SPLITTER_RESIZE: "splitter-resize",
|
|
17
|
+
SWITCH_TAB: "switch-tab",
|
|
18
|
+
TEAROUT: "tearout"
|
|
19
|
+
};
|
|
20
|
+
const isApplicationLevelChange = (layoutChangeReason)=>[
|
|
21
|
+
"switch-active-layout",
|
|
22
|
+
"open-layout",
|
|
23
|
+
"close-layout",
|
|
24
|
+
"rename-layout"
|
|
25
|
+
].includes(layoutChangeReason);
|
|
26
|
+
const isLayoutLevelChange = (layoutChangeReason)=>[
|
|
27
|
+
"switch-active-tab",
|
|
28
|
+
"edit-feature-title",
|
|
29
|
+
"save-feature-props",
|
|
30
|
+
"remove-component",
|
|
31
|
+
"resize-component",
|
|
32
|
+
"drag-drop-operation"
|
|
33
|
+
].includes(layoutChangeReason);
|
|
34
|
+
export { LayoutActionType, isApplicationLevelChange, isLayoutLevelChange };
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
import { getLayoutComponent, isContainer, isLayoutComponent, uuid } from "@vuu-ui/vuu-utils";
|
|
2
|
+
import react, { cloneElement } from "react";
|
|
3
|
+
import { getPersistentState, hasPersistentState, setPersistentState } from "../use-persistent-state.js";
|
|
4
|
+
import { expandFlex, followPathToParent, getProps, typeOf } from "../utils/index.js";
|
|
5
|
+
const getManagedDimension = (style)=>"column" === style.flexDirection ? [
|
|
6
|
+
"height",
|
|
7
|
+
"width"
|
|
8
|
+
] : [
|
|
9
|
+
"width",
|
|
10
|
+
"height"
|
|
11
|
+
];
|
|
12
|
+
const theKidHasNoStyle = {};
|
|
13
|
+
const applyLayoutProps = (component, path = "0")=>{
|
|
14
|
+
const [layoutProps, children] = getChildLayoutProps(typeOf(component), component.props, path);
|
|
15
|
+
return react.cloneElement(component, layoutProps, children);
|
|
16
|
+
};
|
|
17
|
+
const cloneElementAddLayoutProps = (layoutElement, previousLayout)=>{
|
|
18
|
+
const type = typeOf(layoutElement);
|
|
19
|
+
const [layoutProps, children] = getChildLayoutProps(type, layoutElement.props, "0", void 0, previousLayout);
|
|
20
|
+
return cloneElement(layoutElement, layoutProps, children);
|
|
21
|
+
};
|
|
22
|
+
const applyLayout = (type, props, previousLayout)=>{
|
|
23
|
+
const [layoutProps, children] = getChildLayoutProps(type, props, "0", void 0, previousLayout);
|
|
24
|
+
return {
|
|
25
|
+
...props,
|
|
26
|
+
...layoutProps,
|
|
27
|
+
type,
|
|
28
|
+
children
|
|
29
|
+
};
|
|
30
|
+
};
|
|
31
|
+
function getLayoutProps(type, props, path = "0", parentType = null, previousLayout) {
|
|
32
|
+
const { active: prevActive = 0, "data-path": dataPath, path: prevPath = dataPath, id: prevId, style: prevStyle } = getProps(previousLayout);
|
|
33
|
+
const prevMatch = typeOf(previousLayout) === type && path === prevPath;
|
|
34
|
+
const id = prevMatch ? prevId : props.id ?? uuid();
|
|
35
|
+
const active = "Stack" === type ? props.active ?? prevActive : void 0;
|
|
36
|
+
const key = id;
|
|
37
|
+
const style = prevMatch ? prevStyle : getStyle(type, props, parentType);
|
|
38
|
+
return isLayoutComponent(type) ? {
|
|
39
|
+
id,
|
|
40
|
+
key,
|
|
41
|
+
path,
|
|
42
|
+
style,
|
|
43
|
+
type,
|
|
44
|
+
active
|
|
45
|
+
} : {
|
|
46
|
+
id,
|
|
47
|
+
key,
|
|
48
|
+
style,
|
|
49
|
+
"data-path": path
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
function getChildLayoutProps(type, props, path, parentType = null, previousLayout) {
|
|
53
|
+
const layoutProps = getLayoutProps(type, props, path, parentType, previousLayout);
|
|
54
|
+
if (props.layout && !previousLayout) return [
|
|
55
|
+
layoutProps,
|
|
56
|
+
[
|
|
57
|
+
layoutFromJson(props.layout, `${path}.0`)
|
|
58
|
+
]
|
|
59
|
+
];
|
|
60
|
+
const previousChildren = previousLayout?.children ?? previousLayout?.props?.children;
|
|
61
|
+
const hasDynamicChildren = props.dropTarget && previousChildren;
|
|
62
|
+
const children = hasDynamicChildren ? previousChildren : getLayoutChildren(type, props.children, path, previousChildren);
|
|
63
|
+
return [
|
|
64
|
+
layoutProps,
|
|
65
|
+
children
|
|
66
|
+
];
|
|
67
|
+
}
|
|
68
|
+
function getLayoutChildren(type, children, path = "0", previousChildren) {
|
|
69
|
+
const kids = Array.isArray(children) ? children : react.isValidElement(children) ? [
|
|
70
|
+
children
|
|
71
|
+
] : [];
|
|
72
|
+
return isContainer(type) ? kids.map((child, i)=>{
|
|
73
|
+
const childType = typeOf(child);
|
|
74
|
+
const previousType = typeOf(previousChildren?.[i]);
|
|
75
|
+
if (!previousType || childType === previousType) {
|
|
76
|
+
const [layoutProps, children] = getChildLayoutProps(childType, child.props, `${path}.${i}`, type, previousChildren?.[i]);
|
|
77
|
+
return react.cloneElement(child, layoutProps, children);
|
|
78
|
+
}
|
|
79
|
+
return previousChildren?.[i];
|
|
80
|
+
}) : children;
|
|
81
|
+
}
|
|
82
|
+
const getStyle = (type, props, parentType)=>{
|
|
83
|
+
let { style = theKidHasNoStyle } = props;
|
|
84
|
+
if ("Flexbox" === type) style = {
|
|
85
|
+
flexDirection: props.column ? "column" : "row",
|
|
86
|
+
...style,
|
|
87
|
+
display: "flex"
|
|
88
|
+
};
|
|
89
|
+
if (style.flex) {
|
|
90
|
+
const { flex, ...otherStyles } = style;
|
|
91
|
+
style = {
|
|
92
|
+
...otherStyles,
|
|
93
|
+
...expandFlex("number" == typeof flex ? flex : 0)
|
|
94
|
+
};
|
|
95
|
+
} else if ("Stack" === parentType) style = {
|
|
96
|
+
...style,
|
|
97
|
+
...expandFlex(1)
|
|
98
|
+
};
|
|
99
|
+
else if ("Flexbox" === parentType && (style.width || style.height) && void 0 === style.flexBasis) style = {
|
|
100
|
+
...style,
|
|
101
|
+
flexBasis: "auto",
|
|
102
|
+
flexGrow: 0,
|
|
103
|
+
flexShrink: 0
|
|
104
|
+
};
|
|
105
|
+
return style;
|
|
106
|
+
};
|
|
107
|
+
function layoutFromJson({ active, id = uuid(), type, children, props, state }, path) {
|
|
108
|
+
const componentType = type.match(/^[a-z]/) ? type : getLayoutComponent(type);
|
|
109
|
+
if (void 0 === componentType) throw Error(`layoutUtils unable to create component from JSON, unknown type ${type}`);
|
|
110
|
+
if (state) setPersistentState(id, state);
|
|
111
|
+
return react.createElement(componentType, {
|
|
112
|
+
active,
|
|
113
|
+
id,
|
|
114
|
+
...props,
|
|
115
|
+
key: id,
|
|
116
|
+
path
|
|
117
|
+
}, children ? children.map((child, i)=>layoutFromJson(child, `${path}.${i}`)) : void 0);
|
|
118
|
+
}
|
|
119
|
+
function layoutToJSON(component) {
|
|
120
|
+
return componentToJson(component);
|
|
121
|
+
}
|
|
122
|
+
function componentToJson(component) {
|
|
123
|
+
const type = typeOf(component);
|
|
124
|
+
const { id, children, type: _omit, ...props } = getProps(component);
|
|
125
|
+
const state = hasPersistentState(id) ? getPersistentState(id) : void 0;
|
|
126
|
+
return {
|
|
127
|
+
id,
|
|
128
|
+
type,
|
|
129
|
+
props: serializeProps(props),
|
|
130
|
+
state,
|
|
131
|
+
children: react.Children.map(children, componentToJson)
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
function serializeProps(props) {
|
|
135
|
+
if (props) {
|
|
136
|
+
const { path, ...otherProps } = props;
|
|
137
|
+
const result = {};
|
|
138
|
+
for (const [key, value] of Object.entries(otherProps))result[key] = serializeValue(value);
|
|
139
|
+
return result;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
function serializeValue(value) {
|
|
143
|
+
if ("string" == typeof value || "number" == typeof value || "boolean" == typeof value) return value;
|
|
144
|
+
if (Array.isArray(value)) return value.map(serializeValue);
|
|
145
|
+
if ("object" == typeof value && null !== value) {
|
|
146
|
+
const result = {};
|
|
147
|
+
for (const [k, v] of Object.entries(value))result[k] = serializeValue(v);
|
|
148
|
+
return result;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
const layoutQuery = (query, path, layoutRoot)=>{
|
|
152
|
+
if (path && layoutRoot) {
|
|
153
|
+
const parentElement = followPathToParent(layoutRoot, path);
|
|
154
|
+
if (parentElement) {
|
|
155
|
+
const { id: parentContainerId } = getProps(parentElement);
|
|
156
|
+
const parentContainerType = typeOf(parentElement);
|
|
157
|
+
return {
|
|
158
|
+
parentContainerId,
|
|
159
|
+
parentContainerType
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
return {
|
|
163
|
+
parentContainerType: "Stack",
|
|
164
|
+
parentContainerId: "blah"
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
};
|
|
168
|
+
const getDefaultTabLabel = (component, tabIndex, existingLabels = [])=>{
|
|
169
|
+
let label = component.props?.title ?? component.props?.["data-tab-title"] ?? existingLabels[tabIndex];
|
|
170
|
+
if (label) return label;
|
|
171
|
+
{
|
|
172
|
+
let count = tabIndex;
|
|
173
|
+
do label = `Tab ${++count}`;
|
|
174
|
+
while (existingLabels.includes(label))
|
|
175
|
+
return label;
|
|
176
|
+
}
|
|
177
|
+
};
|
|
178
|
+
export { applyLayout, applyLayoutProps, cloneElementAddLayoutProps, componentToJson, getDefaultTabLabel, getManagedDimension, layoutFromJson, layoutQuery, layoutToJSON, serializeProps };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { cloneElement } from "react";
|
|
2
|
+
import { followPath, getProps } from "../utils/index.js";
|
|
3
|
+
import { swapChild } from "./replace-layout-element.js";
|
|
4
|
+
function moveChild(layoutRoot, { fromIndex, path, toIndex }) {
|
|
5
|
+
const target = followPath(layoutRoot, path, true);
|
|
6
|
+
const { children } = getProps(target);
|
|
7
|
+
const replacementChildren = moveChildWithinChildren(children, fromIndex, toIndex);
|
|
8
|
+
const replacement = cloneElement(target, void 0, replacementChildren);
|
|
9
|
+
return swapChild(layoutRoot, target, replacement);
|
|
10
|
+
}
|
|
11
|
+
function moveChildWithinChildren(children, fromIndex, toIndex) {
|
|
12
|
+
const newChildren = children.slice();
|
|
13
|
+
const [child] = newChildren.splice(fromIndex, 1);
|
|
14
|
+
if (-1 === toIndex) return newChildren.concat(child);
|
|
15
|
+
newChildren.splice(toIndex, 0, child);
|
|
16
|
+
return newChildren;
|
|
17
|
+
}
|
|
18
|
+
export { moveChild };
|