@vuu-ui/vuu-layout 0.5.10 → 0.5.11
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/LICENSE +201 -0
- package/cjs/index.js +20 -0
- package/cjs/index.js.map +7 -0
- package/esm/index.js +20 -0
- package/esm/index.js.map +7 -0
- package/index.css +2 -0
- package/index.css.map +7 -0
- package/package.json +13 -10
- package/src/Component.css +0 -0
- package/src/Component.tsx +0 -20
- package/src/DraggableLayout.css +0 -18
- package/src/DraggableLayout.tsx +0 -26
- package/src/__tests__/flexbox-utils.spec.js +0 -90
- package/src/chest-of-drawers/Chest.css +0 -36
- package/src/chest-of-drawers/Chest.tsx +0 -42
- package/src/chest-of-drawers/Drawer.css +0 -159
- package/src/chest-of-drawers/Drawer.tsx +0 -118
- package/src/chest-of-drawers/index.ts +0 -2
- package/src/common-types.ts +0 -9
- package/src/debug.ts +0 -16
- package/src/drag-drop/BoxModel.ts +0 -551
- package/src/drag-drop/DragState.ts +0 -219
- package/src/drag-drop/Draggable.ts +0 -282
- package/src/drag-drop/DropMenu.css +0 -71
- package/src/drag-drop/DropMenu.tsx +0 -61
- package/src/drag-drop/DropTarget.ts +0 -393
- package/src/drag-drop/DropTargetRenderer.css +0 -40
- package/src/drag-drop/DropTargetRenderer.tsx +0 -277
- package/src/drag-drop/dragDropTypes.ts +0 -47
- package/src/drag-drop/index.ts +0 -5
- package/src/editable-label/EditableLabel.css +0 -28
- package/src/editable-label/EditableLabel.tsx +0 -99
- package/src/editable-label/index.ts +0 -1
- package/src/flexbox/Flexbox.css +0 -45
- package/src/flexbox/Flexbox.tsx +0 -70
- package/src/flexbox/FlexboxLayout.tsx +0 -28
- package/src/flexbox/FluidGrid.css +0 -134
- package/src/flexbox/FluidGrid.tsx +0 -82
- package/src/flexbox/FluidGridLayout.tsx +0 -9
- package/src/flexbox/Splitter.css +0 -140
- package/src/flexbox/Splitter.tsx +0 -127
- package/src/flexbox/flexbox-utils.ts +0 -128
- package/src/flexbox/flexboxTypes.ts +0 -68
- package/src/flexbox/index.ts +0 -5
- package/src/flexbox/useResponsiveSizing.ts +0 -82
- package/src/flexbox/useSplitterResizing.ts +0 -270
- package/src/index.ts +0 -19
- package/src/layout-action.ts +0 -21
- package/src/layout-header/ActionButton.tsx +0 -23
- package/src/layout-header/Header.css +0 -8
- package/src/layout-header/Header.tsx +0 -216
- package/src/layout-header/index.ts +0 -1
- package/src/layout-provider/LayoutProvider.tsx +0 -161
- package/src/layout-provider/LayoutProviderContext.ts +0 -17
- package/src/layout-provider/index.ts +0 -3
- package/src/layout-provider/useLayoutDragDrop.ts +0 -210
- package/src/layout-reducer/flexUtils.ts +0 -276
- package/src/layout-reducer/index.ts +0 -5
- package/src/layout-reducer/insert-layout-element.ts +0 -365
- package/src/layout-reducer/layout-reducer.ts +0 -237
- package/src/layout-reducer/layoutTypes.ts +0 -159
- package/src/layout-reducer/layoutUtils.ts +0 -288
- package/src/layout-reducer/remove-layout-element.ts +0 -226
- package/src/layout-reducer/replace-layout-element.ts +0 -113
- package/src/layout-reducer/resize-flex-children.ts +0 -55
- package/src/layout-reducer/wrap-layout-element.ts +0 -307
- package/src/layout-view/View.css +0 -61
- package/src/layout-view/View.tsx +0 -143
- package/src/layout-view/ViewContext.ts +0 -30
- package/src/layout-view/index.ts +0 -5
- package/src/layout-view/useView.tsx +0 -104
- package/src/layout-view/useViewActionDispatcher.ts +0 -123
- package/src/layout-view/useViewResize.ts +0 -53
- package/src/layout-view/viewTypes.ts +0 -35
- package/src/palette/Palette.css +0 -33
- package/src/palette/Palette.tsx +0 -140
- package/src/palette/PaletteSalt.css +0 -9
- package/src/palette/PaletteSalt.tsx +0 -79
- package/src/palette/index.ts +0 -3
- package/src/placeholder/Placeholder.css +0 -10
- package/src/placeholder/Placeholder.tsx +0 -38
- package/src/placeholder/index.ts +0 -1
- package/src/registry/ComponentRegistry.ts +0 -44
- package/src/registry/index.ts +0 -1
- package/src/responsive/breakpoints.ts +0 -62
- package/src/responsive/index.ts +0 -3
- package/src/responsive/measureMinimumNodeSize.ts +0 -23
- package/src/responsive/overflowUtils.js +0 -14
- package/src/responsive/use-breakpoints.ts +0 -101
- package/src/responsive/useResizeObserver.ts +0 -154
- package/src/responsive/utils.ts +0 -37
- package/src/stack/Stack.css +0 -39
- package/src/stack/Stack.tsx +0 -173
- package/src/stack/StackLayout.tsx +0 -119
- package/src/stack/index.ts +0 -4
- package/src/stack/stackTypes.ts +0 -22
- package/src/tabs/TabPanel.css +0 -12
- package/src/tabs/TabPanel.tsx +0 -17
- package/src/tabs/index.ts +0 -1
- package/src/tools/config-wrapper/ConfigWrapper.tsx +0 -55
- package/src/tools/config-wrapper/index.ts +0 -1
- package/src/tools/devtools-box/layout-configurator.css +0 -112
- package/src/tools/devtools-box/layout-configurator.jsx +0 -369
- package/src/tools/devtools-tree/layout-tree-viewer.css +0 -15
- package/src/tools/devtools-tree/layout-tree-viewer.jsx +0 -36
- package/src/tools/index.ts +0 -4
- package/src/use-persistent-state.ts +0 -112
- package/src/utils/index.ts +0 -5
- package/src/utils/pathUtils.ts +0 -283
- package/src/utils/propUtils.ts +0 -26
- package/src/utils/refUtils.ts +0 -16
- package/src/utils/styleUtils.ts +0 -13
- package/src/utils/typeOf.ts +0 -25
- package/tsconfig-emit-types.json +0 -11
|
@@ -1,237 +0,0 @@
|
|
|
1
|
-
import React, { ReactElement } from "react";
|
|
2
|
-
import { DropPos } from "../drag-drop/dragDropTypes";
|
|
3
|
-
import { DropTarget } from "../drag-drop/DropTarget";
|
|
4
|
-
import { isContainer } from "../registry/ComponentRegistry";
|
|
5
|
-
import {
|
|
6
|
-
findTarget,
|
|
7
|
-
followPath,
|
|
8
|
-
followPathToParent,
|
|
9
|
-
getProp,
|
|
10
|
-
getProps,
|
|
11
|
-
typeOf
|
|
12
|
-
} from "../utils";
|
|
13
|
-
import { getIntrinsicSize } from "./flexUtils";
|
|
14
|
-
import {
|
|
15
|
-
getInsertTabBeforeAfter,
|
|
16
|
-
insertBesideChild,
|
|
17
|
-
insertIntoContainer
|
|
18
|
-
} from "./insert-layout-element";
|
|
19
|
-
import {
|
|
20
|
-
AddAction,
|
|
21
|
-
DragDropAction, LayoutActionType, LayoutReducerAction, MaximizeAction, SetTitleAction,
|
|
22
|
-
SwitchTabAction
|
|
23
|
-
} from "./layoutTypes";
|
|
24
|
-
import { LayoutProps } from "./layoutUtils";
|
|
25
|
-
import { removeChild } from "./remove-layout-element";
|
|
26
|
-
import {
|
|
27
|
-
replaceChild,
|
|
28
|
-
swapChild,
|
|
29
|
-
_replaceChild
|
|
30
|
-
} from "./replace-layout-element";
|
|
31
|
-
import { resizeFlexChildren } from "./resize-flex-children";
|
|
32
|
-
import { wrap } from "./wrap-layout-element";
|
|
33
|
-
|
|
34
|
-
export const layoutReducer = (
|
|
35
|
-
state: ReactElement,
|
|
36
|
-
action: LayoutReducerAction
|
|
37
|
-
): ReactElement => {
|
|
38
|
-
switch (action.type) {
|
|
39
|
-
case LayoutActionType.ADD:
|
|
40
|
-
return addChild(state, action);
|
|
41
|
-
case LayoutActionType.DRAG_DROP:
|
|
42
|
-
return dragDrop(state, action);
|
|
43
|
-
case LayoutActionType.MAXIMIZE:
|
|
44
|
-
return setChildProps(state, action);
|
|
45
|
-
case LayoutActionType.REMOVE:
|
|
46
|
-
return removeChild(state, action);
|
|
47
|
-
case LayoutActionType.REPLACE:
|
|
48
|
-
return replaceChild(state, action);
|
|
49
|
-
case LayoutActionType.SET_TITLE:
|
|
50
|
-
return setTitle(state, action);
|
|
51
|
-
case LayoutActionType.SPLITTER_RESIZE:
|
|
52
|
-
return resizeFlexChildren(state, action);
|
|
53
|
-
case LayoutActionType.SWITCH_TAB:
|
|
54
|
-
return switchTab(state, action);
|
|
55
|
-
default:
|
|
56
|
-
return state;
|
|
57
|
-
}
|
|
58
|
-
};
|
|
59
|
-
|
|
60
|
-
const switchTab = (state: ReactElement, { path, nextIdx }: SwitchTabAction) => {
|
|
61
|
-
const target = followPath(state, path, true);
|
|
62
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
63
|
-
const replacement = React.cloneElement<any>(target, {
|
|
64
|
-
active: nextIdx,
|
|
65
|
-
});
|
|
66
|
-
return swapChild(state, target, replacement);
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
const setTitle = (state: ReactElement, { path, title }: SetTitleAction) => {
|
|
70
|
-
const target = followPath(state, path, true);
|
|
71
|
-
const replacement = React.cloneElement(target, {
|
|
72
|
-
title,
|
|
73
|
-
});
|
|
74
|
-
return swapChild(state, target, replacement);
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
const setChildProps = (state: ReactElement, { path, type }: MaximizeAction) => {
|
|
78
|
-
if (path) {
|
|
79
|
-
const target = followPath(state, path, true);
|
|
80
|
-
return swapChild(state, target, target, type);
|
|
81
|
-
} else {
|
|
82
|
-
return state;
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
const dragDrop = (
|
|
87
|
-
layoutRoot: ReactElement,
|
|
88
|
-
action: DragDropAction
|
|
89
|
-
): ReactElement => {
|
|
90
|
-
console.log("drag drop");
|
|
91
|
-
const {
|
|
92
|
-
draggedReactElement: newComponent,
|
|
93
|
-
dragInstructions,
|
|
94
|
-
dropTarget,
|
|
95
|
-
} = action;
|
|
96
|
-
const existingComponent = dropTarget.component as ReactElement;
|
|
97
|
-
const { pos } = dropTarget;
|
|
98
|
-
const destinationTabstrip =
|
|
99
|
-
pos?.position?.Header && typeOf(existingComponent) === "Stack";
|
|
100
|
-
const { id, version } = getProps(newComponent);
|
|
101
|
-
const intrinsicSize = getIntrinsicSize(newComponent);
|
|
102
|
-
let newLayoutRoot: ReactElement;
|
|
103
|
-
if (destinationTabstrip) {
|
|
104
|
-
const [targetTab, insertionPosition] = getInsertTabBeforeAfter(
|
|
105
|
-
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
106
|
-
existingComponent!,
|
|
107
|
-
pos
|
|
108
|
-
);
|
|
109
|
-
if (targetTab === undefined) {
|
|
110
|
-
newLayoutRoot = insertIntoContainer(
|
|
111
|
-
layoutRoot,
|
|
112
|
-
existingComponent,
|
|
113
|
-
newComponent
|
|
114
|
-
);
|
|
115
|
-
} else {
|
|
116
|
-
newLayoutRoot = insertBesideChild(
|
|
117
|
-
layoutRoot,
|
|
118
|
-
targetTab,
|
|
119
|
-
newComponent,
|
|
120
|
-
insertionPosition
|
|
121
|
-
);
|
|
122
|
-
}
|
|
123
|
-
} else if (!intrinsicSize && pos?.position?.Centre) {
|
|
124
|
-
newLayoutRoot = _replaceChild(
|
|
125
|
-
layoutRoot,
|
|
126
|
-
existingComponent as ReactElement,
|
|
127
|
-
newComponent
|
|
128
|
-
);
|
|
129
|
-
} else {
|
|
130
|
-
newLayoutRoot = dropLayoutIntoContainer(
|
|
131
|
-
layoutRoot,
|
|
132
|
-
dropTarget as DropTarget,
|
|
133
|
-
newComponent
|
|
134
|
-
);
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
if (dragInstructions.DoNotRemove) {
|
|
138
|
-
return newLayoutRoot;
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
const finalTarget = findTarget(
|
|
142
|
-
newLayoutRoot,
|
|
143
|
-
(props: LayoutProps) => props.id === id && props.version === version
|
|
144
|
-
) as ReactElement;
|
|
145
|
-
const finalPath = getProp(finalTarget, "path");
|
|
146
|
-
return removeChild(newLayoutRoot, { path: finalPath, type: "remove" });
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
const addChild = (
|
|
150
|
-
layoutRoot: ReactElement,
|
|
151
|
-
{ path: containerPath, component }: AddAction
|
|
152
|
-
) => {
|
|
153
|
-
return insertIntoContainer(
|
|
154
|
-
layoutRoot,
|
|
155
|
-
followPath(layoutRoot, containerPath) as ReactElement,
|
|
156
|
-
component
|
|
157
|
-
);
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
const dropLayoutIntoContainer = (
|
|
161
|
-
layoutRoot: ReactElement,
|
|
162
|
-
dropTarget: DropTarget,
|
|
163
|
-
newComponent: ReactElement
|
|
164
|
-
): ReactElement => {
|
|
165
|
-
const {
|
|
166
|
-
component: existingComponent,
|
|
167
|
-
pos,
|
|
168
|
-
clientRect,
|
|
169
|
-
dropRect,
|
|
170
|
-
} = dropTarget;
|
|
171
|
-
const existingComponentPath = getProp(existingComponent, "path");
|
|
172
|
-
|
|
173
|
-
if (existingComponentPath === "0.0") {
|
|
174
|
-
return wrap(layoutRoot, existingComponent, newComponent, pos);
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
const targetContainer = followPathToParent(
|
|
178
|
-
layoutRoot,
|
|
179
|
-
existingComponentPath
|
|
180
|
-
) as ReactElement;
|
|
181
|
-
|
|
182
|
-
if (withTheGrain(pos, targetContainer)) {
|
|
183
|
-
const insertionPosition = pos.position.SouthOrEast ? "after" : "before";
|
|
184
|
-
return insertBesideChild(
|
|
185
|
-
layoutRoot,
|
|
186
|
-
existingComponent,
|
|
187
|
-
newComponent,
|
|
188
|
-
insertionPosition,
|
|
189
|
-
pos,
|
|
190
|
-
clientRect,
|
|
191
|
-
dropRect
|
|
192
|
-
);
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
if (!withTheGrain(pos, targetContainer)) {
|
|
196
|
-
return wrap(
|
|
197
|
-
layoutRoot,
|
|
198
|
-
existingComponent,
|
|
199
|
-
newComponent,
|
|
200
|
-
pos,
|
|
201
|
-
clientRect,
|
|
202
|
-
dropRect
|
|
203
|
-
);
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
if (isContainer(typeOf(targetContainer) as string)) {
|
|
207
|
-
return wrap(layoutRoot, existingComponent, newComponent, pos);
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
throw Error(`no support right now for position = ${pos.position}`);
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
const withTheGrain = (pos: DropPos, container: ReactElement) => {
|
|
214
|
-
if (pos.position.Centre) {
|
|
215
|
-
return isTerrace(container) || isTower(container);
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
return pos.position.NorthOrSouth
|
|
219
|
-
? isTower(container)
|
|
220
|
-
: pos.position.EastOrWest
|
|
221
|
-
? isTerrace(container)
|
|
222
|
-
: false;
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
const isTower = (container: ReactElement) => {
|
|
226
|
-
return (
|
|
227
|
-
typeOf(container) === "Flexbox" &&
|
|
228
|
-
container.props.style.flexDirection === "column"
|
|
229
|
-
);
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
const isTerrace = (container: ReactElement) => {
|
|
233
|
-
return (
|
|
234
|
-
typeOf(container) === "Flexbox" &&
|
|
235
|
-
container.props.style.flexDirection !== "column"
|
|
236
|
-
);
|
|
237
|
-
}
|
|
@@ -1,159 +0,0 @@
|
|
|
1
|
-
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
|
-
import { ReactElement } from "react";
|
|
3
|
-
import { DragDropRect, DragInstructions } from "../drag-drop";
|
|
4
|
-
import { DropTarget } from "../drag-drop/DropTarget";
|
|
5
|
-
|
|
6
|
-
export interface WithProps {
|
|
7
|
-
props?: { [key: string]: any };
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
export interface WithType {
|
|
11
|
-
props?: any;
|
|
12
|
-
title?: string;
|
|
13
|
-
type: string;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export interface LayoutRoot extends WithProps {
|
|
17
|
-
active?: number;
|
|
18
|
-
children?: ReactElement[];
|
|
19
|
-
type: string;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
export interface LayoutJSON extends WithType {
|
|
23
|
-
children?: LayoutJSON[];
|
|
24
|
-
id?: string;
|
|
25
|
-
props?: { [key: string]: any };
|
|
26
|
-
state?: any;
|
|
27
|
-
type: string;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
export interface WithActive {
|
|
31
|
-
active?: number;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
export type LayoutModel = LayoutRoot | ReactElement | WithType;
|
|
35
|
-
|
|
36
|
-
export type layoutType = "Flexbox" | "View" | "DraggableLayout" | "Stack";
|
|
37
|
-
|
|
38
|
-
export const LayoutActionType = {
|
|
39
|
-
ADD: "add",
|
|
40
|
-
DRAG_START: "drag-start",
|
|
41
|
-
DRAG_DROP: "drag-drop",
|
|
42
|
-
MAXIMIZE: "maximize",
|
|
43
|
-
MINIMIZE: "minimize",
|
|
44
|
-
REMOVE: "remove",
|
|
45
|
-
REPLACE: "replace",
|
|
46
|
-
RESTORE: "restore",
|
|
47
|
-
SAVE: "save",
|
|
48
|
-
SET_TITLE: "set-title",
|
|
49
|
-
SPLITTER_RESIZE: "splitter-resize",
|
|
50
|
-
SWITCH_TAB: "switch-tab",
|
|
51
|
-
TEAROUT: "tearout",
|
|
52
|
-
} as const;
|
|
53
|
-
|
|
54
|
-
export type AddAction = {
|
|
55
|
-
component: any;
|
|
56
|
-
path: string;
|
|
57
|
-
type: typeof LayoutActionType.ADD;
|
|
58
|
-
};
|
|
59
|
-
|
|
60
|
-
export type DragDropAction = {
|
|
61
|
-
draggedReactElement: ReactElement;
|
|
62
|
-
dragInstructions: any;
|
|
63
|
-
dropTarget: Partial<DropTarget>;
|
|
64
|
-
type: typeof LayoutActionType.DRAG_DROP;
|
|
65
|
-
};
|
|
66
|
-
|
|
67
|
-
export type MaximizeAction = {
|
|
68
|
-
path?: string;
|
|
69
|
-
type: typeof LayoutActionType.MAXIMIZE;
|
|
70
|
-
};
|
|
71
|
-
|
|
72
|
-
export type MinimizeAction = {
|
|
73
|
-
path?: string;
|
|
74
|
-
type: typeof LayoutActionType.MINIMIZE;
|
|
75
|
-
};
|
|
76
|
-
|
|
77
|
-
export type RemoveAction = {
|
|
78
|
-
path?: string;
|
|
79
|
-
type: typeof LayoutActionType.REMOVE;
|
|
80
|
-
};
|
|
81
|
-
|
|
82
|
-
export type ReplaceAction = {
|
|
83
|
-
replacement: any;
|
|
84
|
-
target: any;
|
|
85
|
-
type: typeof LayoutActionType.REPLACE;
|
|
86
|
-
};
|
|
87
|
-
|
|
88
|
-
export type RestoreAction = {
|
|
89
|
-
path?: string;
|
|
90
|
-
type: typeof LayoutActionType.RESTORE;
|
|
91
|
-
};
|
|
92
|
-
|
|
93
|
-
export type SetTitleAction = {
|
|
94
|
-
path: string;
|
|
95
|
-
title: string;
|
|
96
|
-
type: typeof LayoutActionType.SET_TITLE;
|
|
97
|
-
};
|
|
98
|
-
|
|
99
|
-
export type SplitterResizeAction = {
|
|
100
|
-
path: string;
|
|
101
|
-
sizes: { currentSize: number; flexBasis: number }[];
|
|
102
|
-
type: typeof LayoutActionType.SPLITTER_RESIZE;
|
|
103
|
-
};
|
|
104
|
-
|
|
105
|
-
export type SwitchTabAction = {
|
|
106
|
-
nextIdx: number;
|
|
107
|
-
path: string;
|
|
108
|
-
type: typeof LayoutActionType.SWITCH_TAB;
|
|
109
|
-
};
|
|
110
|
-
|
|
111
|
-
export type TearoutAction = {
|
|
112
|
-
path?: string;
|
|
113
|
-
type: typeof LayoutActionType.TEAROUT;
|
|
114
|
-
};
|
|
115
|
-
|
|
116
|
-
export type LayoutReducerAction =
|
|
117
|
-
| AddAction
|
|
118
|
-
| DragDropAction
|
|
119
|
-
| MaximizeAction
|
|
120
|
-
| MinimizeAction
|
|
121
|
-
| RemoveAction
|
|
122
|
-
| ReplaceAction
|
|
123
|
-
| RestoreAction
|
|
124
|
-
| SetTitleAction
|
|
125
|
-
| SplitterResizeAction
|
|
126
|
-
| SwitchTabAction;
|
|
127
|
-
|
|
128
|
-
export type SaveAction = {
|
|
129
|
-
type: typeof LayoutActionType.SAVE;
|
|
130
|
-
};
|
|
131
|
-
|
|
132
|
-
export type AddToolbarContributionViewAction = {
|
|
133
|
-
content: ReactElement;
|
|
134
|
-
location: string;
|
|
135
|
-
type: "add-toolbar-contribution";
|
|
136
|
-
};
|
|
137
|
-
|
|
138
|
-
export type RemoveToolbarContributionViewAction = {
|
|
139
|
-
location: string;
|
|
140
|
-
type: "remove-toolbar-contribution";
|
|
141
|
-
};
|
|
142
|
-
|
|
143
|
-
export type MousedownViewAction = {
|
|
144
|
-
preDragActivity?: any;
|
|
145
|
-
index?: number;
|
|
146
|
-
type: "mousedown";
|
|
147
|
-
};
|
|
148
|
-
|
|
149
|
-
export type DragStartAction = {
|
|
150
|
-
payload?: ReactElement;
|
|
151
|
-
dragContainerPath?: string;
|
|
152
|
-
dragElement?: HTMLElement;
|
|
153
|
-
dragRect: DragDropRect;
|
|
154
|
-
dropTargets?: string[];
|
|
155
|
-
evt: MouseEvent;
|
|
156
|
-
instructions?: DragInstructions;
|
|
157
|
-
path: string;
|
|
158
|
-
type: typeof LayoutActionType.DRAG_START;
|
|
159
|
-
};
|
|
@@ -1,288 +0,0 @@
|
|
|
1
|
-
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
|
-
import { uuid } from "@vuu-ui/vuu-utils";
|
|
3
|
-
import React, { cloneElement, CSSProperties, ReactElement } from "react";
|
|
4
|
-
import { dimension } from "../common-types";
|
|
5
|
-
import {
|
|
6
|
-
ComponentWithId,
|
|
7
|
-
ComponentRegistry,
|
|
8
|
-
isContainer,
|
|
9
|
-
isLayoutComponent,
|
|
10
|
-
} from "../registry/ComponentRegistry";
|
|
11
|
-
import {
|
|
12
|
-
getPersistentState,
|
|
13
|
-
hasPersistentState,
|
|
14
|
-
setPersistentState,
|
|
15
|
-
} from "../use-persistent-state";
|
|
16
|
-
import { expandFlex, getProps, typeOf } from "../utils";
|
|
17
|
-
import { LayoutJSON, LayoutModel, layoutType } from "./layoutTypes";
|
|
18
|
-
|
|
19
|
-
export const getManagedDimension = (
|
|
20
|
-
style: CSSProperties
|
|
21
|
-
): [dimension, dimension] =>
|
|
22
|
-
style.flexDirection === "column" ? ["height", "width"] : ["width", "height"];
|
|
23
|
-
|
|
24
|
-
const theKidHasNoStyle: CSSProperties = {};
|
|
25
|
-
|
|
26
|
-
export const applyLayoutProps = (component: ReactElement, path = "0") => {
|
|
27
|
-
const [layoutProps, children] = getChildLayoutProps(
|
|
28
|
-
typeOf(component) as string,
|
|
29
|
-
component.props,
|
|
30
|
-
path
|
|
31
|
-
);
|
|
32
|
-
return React.cloneElement(component, layoutProps, children);
|
|
33
|
-
};
|
|
34
|
-
|
|
35
|
-
export interface LayoutProps extends ComponentWithId {
|
|
36
|
-
active?: number;
|
|
37
|
-
"data-path"?: string;
|
|
38
|
-
children?: ReactElement[];
|
|
39
|
-
column?: any;
|
|
40
|
-
dropTarget?: any;
|
|
41
|
-
key: string;
|
|
42
|
-
layout?: any;
|
|
43
|
-
path?: string;
|
|
44
|
-
resizeable?: boolean;
|
|
45
|
-
style: CSSProperties;
|
|
46
|
-
type?: string;
|
|
47
|
-
version?: number;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
export const processLayoutElement = (
|
|
51
|
-
layoutElement: ReactElement,
|
|
52
|
-
previousLayout?: ReactElement
|
|
53
|
-
): ReactElement => {
|
|
54
|
-
const type = typeOf(layoutElement) as string;
|
|
55
|
-
const [layoutProps, children] = getChildLayoutProps(
|
|
56
|
-
type,
|
|
57
|
-
layoutElement.props,
|
|
58
|
-
"0",
|
|
59
|
-
undefined,
|
|
60
|
-
previousLayout
|
|
61
|
-
);
|
|
62
|
-
return cloneElement(layoutElement, layoutProps, children);
|
|
63
|
-
};
|
|
64
|
-
|
|
65
|
-
export const applyLayout = (
|
|
66
|
-
type: layoutType,
|
|
67
|
-
props: LayoutProps,
|
|
68
|
-
previousLayout?: LayoutModel
|
|
69
|
-
): LayoutModel => {
|
|
70
|
-
const [layoutProps, children] = getChildLayoutProps(
|
|
71
|
-
type,
|
|
72
|
-
props,
|
|
73
|
-
"0",
|
|
74
|
-
undefined,
|
|
75
|
-
previousLayout
|
|
76
|
-
);
|
|
77
|
-
return {
|
|
78
|
-
...props,
|
|
79
|
-
...layoutProps,
|
|
80
|
-
type,
|
|
81
|
-
children,
|
|
82
|
-
};
|
|
83
|
-
};
|
|
84
|
-
|
|
85
|
-
function getLayoutProps(
|
|
86
|
-
type: string,
|
|
87
|
-
props: LayoutProps,
|
|
88
|
-
path = "0",
|
|
89
|
-
parentType: string | null = null,
|
|
90
|
-
previousLayout?: LayoutModel
|
|
91
|
-
): LayoutProps {
|
|
92
|
-
const {
|
|
93
|
-
active: prevActive = 0,
|
|
94
|
-
"data-path": dataPath,
|
|
95
|
-
path: prevPath = dataPath,
|
|
96
|
-
id: prevId,
|
|
97
|
-
style: prevStyle,
|
|
98
|
-
} = getProps(previousLayout);
|
|
99
|
-
|
|
100
|
-
const prevMatch = typeOf(previousLayout) === type && path === prevPath;
|
|
101
|
-
const id = prevMatch ? prevId : props.id ?? uuid();
|
|
102
|
-
const active = type === "Stack" ? props.active ?? prevActive : undefined;
|
|
103
|
-
|
|
104
|
-
const key = id;
|
|
105
|
-
const style = prevMatch ? prevStyle : getStyle(type, props, parentType);
|
|
106
|
-
return isLayoutComponent(type)
|
|
107
|
-
? { id, key, path, style, type, active }
|
|
108
|
-
: { id, key, style, "data-path": path };
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
function getChildLayoutProps(
|
|
112
|
-
type: string,
|
|
113
|
-
props: LayoutProps,
|
|
114
|
-
path: string,
|
|
115
|
-
parentType: string | null = null,
|
|
116
|
-
previousLayout?: LayoutModel
|
|
117
|
-
): [LayoutProps, ReactElement[]] {
|
|
118
|
-
const layoutProps = getLayoutProps(
|
|
119
|
-
type,
|
|
120
|
-
props,
|
|
121
|
-
path,
|
|
122
|
-
parentType,
|
|
123
|
-
previousLayout
|
|
124
|
-
);
|
|
125
|
-
|
|
126
|
-
if (props.layout && !previousLayout) {
|
|
127
|
-
return [layoutProps, [layoutFromJson(props.layout, `${path}.0`)]];
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
const previousChildren =
|
|
131
|
-
(previousLayout as any)?.children ?? previousLayout?.props?.children;
|
|
132
|
-
const hasDynamicChildren = props.dropTarget && previousChildren;
|
|
133
|
-
const children = hasDynamicChildren
|
|
134
|
-
? previousChildren
|
|
135
|
-
: getLayoutChildren(type, props.children, path, previousChildren);
|
|
136
|
-
return [layoutProps, children];
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
function getLayoutChildren(
|
|
140
|
-
type: string,
|
|
141
|
-
children?: ReactElement[],
|
|
142
|
-
path = "0",
|
|
143
|
-
previousChildren?: ReactElement[]
|
|
144
|
-
) {
|
|
145
|
-
const kids = Array.isArray(children)
|
|
146
|
-
? children
|
|
147
|
-
: React.isValidElement(children)
|
|
148
|
-
? [children]
|
|
149
|
-
: [];
|
|
150
|
-
return isContainer(type)
|
|
151
|
-
? kids.map((child, i) => {
|
|
152
|
-
const childType = typeOf(child) as string;
|
|
153
|
-
const previousType = typeOf(previousChildren?.[i]);
|
|
154
|
-
|
|
155
|
-
if (!previousType || childType === previousType) {
|
|
156
|
-
const [layoutProps, children] = getChildLayoutProps(
|
|
157
|
-
childType,
|
|
158
|
-
child.props,
|
|
159
|
-
`${path}.${i}`,
|
|
160
|
-
type,
|
|
161
|
-
previousChildren?.[i]
|
|
162
|
-
);
|
|
163
|
-
return React.cloneElement(child, layoutProps, children);
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
return previousChildren?.[i];
|
|
167
|
-
})
|
|
168
|
-
: children;
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
const getStyle = (
|
|
172
|
-
type: string,
|
|
173
|
-
props: LayoutProps,
|
|
174
|
-
parentType?: string | null
|
|
175
|
-
) => {
|
|
176
|
-
let { style = theKidHasNoStyle } = props;
|
|
177
|
-
if (type === "Flexbox") {
|
|
178
|
-
style = {
|
|
179
|
-
flexDirection: props.column ? "column" : "row",
|
|
180
|
-
...style,
|
|
181
|
-
display: "flex",
|
|
182
|
-
};
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
if (style.flex) {
|
|
186
|
-
const { flex, ...otherStyles } = style;
|
|
187
|
-
style = {
|
|
188
|
-
...otherStyles,
|
|
189
|
-
...expandFlex(typeof flex === "number" ? flex : 0),
|
|
190
|
-
};
|
|
191
|
-
} else if (parentType === "Stack") {
|
|
192
|
-
style = {
|
|
193
|
-
...style,
|
|
194
|
-
...expandFlex(1),
|
|
195
|
-
};
|
|
196
|
-
} else if (
|
|
197
|
-
parentType === "Flexbox" &&
|
|
198
|
-
(style.width || style.height) &&
|
|
199
|
-
style.flexBasis === undefined
|
|
200
|
-
) {
|
|
201
|
-
style = {
|
|
202
|
-
...style,
|
|
203
|
-
flexBasis: "auto",
|
|
204
|
-
flexGrow: 0,
|
|
205
|
-
flexShrink: 0,
|
|
206
|
-
};
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
return style;
|
|
210
|
-
};
|
|
211
|
-
|
|
212
|
-
export function layoutFromJson(
|
|
213
|
-
{ id = uuid(), type, children, props, state }: LayoutJSON,
|
|
214
|
-
path: string
|
|
215
|
-
): ReactElement {
|
|
216
|
-
const componentType = type.match(/^[a-z]/) ? type : ComponentRegistry[type];
|
|
217
|
-
|
|
218
|
-
if (componentType === undefined) {
|
|
219
|
-
throw Error(
|
|
220
|
-
`layoutUtils unable to create component from JSON, unknown type ${type}`
|
|
221
|
-
);
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
if (state) {
|
|
225
|
-
setPersistentState(id, state);
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
return React.createElement(
|
|
229
|
-
componentType,
|
|
230
|
-
{
|
|
231
|
-
id,
|
|
232
|
-
...props,
|
|
233
|
-
key: id,
|
|
234
|
-
path,
|
|
235
|
-
},
|
|
236
|
-
children
|
|
237
|
-
? children.map((child, i) => layoutFromJson(child, `${path}.${i}`))
|
|
238
|
-
: undefined
|
|
239
|
-
);
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
export function layoutToJSON(component: ReactElement) {
|
|
243
|
-
return componentToJson(component);
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
export function componentToJson(component: ReactElement): LayoutJSON {
|
|
247
|
-
const type = typeOf(component) as string;
|
|
248
|
-
const { id, children, type: _omit, ...props } = getProps(component);
|
|
249
|
-
|
|
250
|
-
const state = hasPersistentState(id) ? getPersistentState(id) : undefined;
|
|
251
|
-
|
|
252
|
-
return {
|
|
253
|
-
id,
|
|
254
|
-
type,
|
|
255
|
-
props: serializeProps(props as LayoutProps),
|
|
256
|
-
state,
|
|
257
|
-
children: React.Children.map(children, componentToJson),
|
|
258
|
-
};
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
export function serializeProps(props?: LayoutProps) {
|
|
262
|
-
if (props) {
|
|
263
|
-
const { path, ...otherProps } = props;
|
|
264
|
-
const result: { [key: string]: any } = {};
|
|
265
|
-
for (const [key, value] of Object.entries(otherProps)) {
|
|
266
|
-
result[key] = serializeValue(value);
|
|
267
|
-
}
|
|
268
|
-
return result;
|
|
269
|
-
}
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
function serializeValue(value: unknown): any {
|
|
273
|
-
if (
|
|
274
|
-
typeof value === "string" ||
|
|
275
|
-
typeof value === "number" ||
|
|
276
|
-
typeof value === "boolean"
|
|
277
|
-
) {
|
|
278
|
-
return value;
|
|
279
|
-
} else if (Array.isArray(value)) {
|
|
280
|
-
return value.map(serializeValue);
|
|
281
|
-
} else if (typeof value === "object" && value !== null) {
|
|
282
|
-
const result: { [key: string]: any } = {};
|
|
283
|
-
for (const [k, v] of Object.entries(value)) {
|
|
284
|
-
result[k] = serializeValue(v);
|
|
285
|
-
}
|
|
286
|
-
return result;
|
|
287
|
-
}
|
|
288
|
-
}
|