@vuu-ui/vuu-layout 2.1.19-beta.1 → 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.
Files changed (89) hide show
  1. package/package.json +12 -13
  2. package/src/Component.js +14 -0
  3. package/src/LayoutContainer.css.js +24 -0
  4. package/src/LayoutContainer.js +26 -0
  5. package/src/debug.js +16 -0
  6. package/src/dock-layout/DockLayout.css.js +36 -0
  7. package/src/dock-layout/DockLayout.js +43 -0
  8. package/src/dock-layout/Drawer.css.js +150 -0
  9. package/src/dock-layout/Drawer.js +82 -0
  10. package/src/dock-layout/index.js +2 -0
  11. package/src/drag-drop/BoxModel.js +337 -0
  12. package/src/drag-drop/DragState.js +119 -0
  13. package/src/drag-drop/Draggable.js +140 -0
  14. package/src/drag-drop/DropTarget.js +286 -0
  15. package/src/drag-drop/DropTargetRenderer.js +275 -0
  16. package/src/drag-drop/dragDropTypes.js +0 -0
  17. package/src/drag-drop/index.js +3 -0
  18. package/src/flexbox/Flexbox.css.js +45 -0
  19. package/src/flexbox/Flexbox.js +45 -0
  20. package/src/flexbox/FlexboxLayout.js +27 -0
  21. package/src/flexbox/Splitter.css.js +57 -0
  22. package/src/flexbox/Splitter.js +112 -0
  23. package/src/flexbox/flexbox-utils.js +92 -0
  24. package/src/flexbox/flexboxTypes.js +0 -0
  25. package/src/flexbox/index.js +2 -0
  26. package/src/flexbox/useSplitterResizing.js +181 -0
  27. package/src/index.js +20 -0
  28. package/src/layout-action.js +20 -0
  29. package/src/layout-header/ActionButton.js +15 -0
  30. package/src/layout-header/Header.css.js +32 -0
  31. package/src/layout-header/Header.js +99 -0
  32. package/src/layout-header/index.js +1 -0
  33. package/src/layout-header/useHeader.js +76 -0
  34. package/src/layout-provider/LayoutProvider.js +242 -0
  35. package/src/layout-provider/LayoutProviderContext.js +13 -0
  36. package/src/layout-provider/index.js +2 -0
  37. package/src/layout-provider/useLayoutDragDrop.js +147 -0
  38. package/src/layout-reducer/flexUtils.js +186 -0
  39. package/src/layout-reducer/index.js +4 -0
  40. package/src/layout-reducer/insert-layout-element.js +179 -0
  41. package/src/layout-reducer/layout-reducer.js +121 -0
  42. package/src/layout-reducer/layoutTypes.js +34 -0
  43. package/src/layout-reducer/layoutUtils.js +178 -0
  44. package/src/layout-reducer/move-layout-element.js +18 -0
  45. package/src/layout-reducer/remove-layout-element.js +161 -0
  46. package/src/layout-reducer/replace-layout-element.js +70 -0
  47. package/src/layout-reducer/resize-flex-children.js +48 -0
  48. package/src/layout-reducer/wrap-layout-element.js +134 -0
  49. package/src/layout-view/View.css.js +76 -0
  50. package/src/layout-view/View.js +116 -0
  51. package/src/layout-view/useView.js +69 -0
  52. package/src/layout-view/useViewBroadcastChannel.js +29 -0
  53. package/src/layout-view/useViewResize.js +27 -0
  54. package/src/layout-view/viewTypes.js +0 -0
  55. package/src/layout-view-actions/ViewContext.js +11 -0
  56. package/src/layout-view-actions/useViewActionDispatcher.js +116 -0
  57. package/src/layout-view-actions/useViewContributions.js +31 -0
  58. package/src/palette/Palette.css.js +31 -0
  59. package/src/palette/Palette.js +85 -0
  60. package/src/palette/index.js +1 -0
  61. package/src/placeholder/LayoutStartPanel.css.js +35 -0
  62. package/src/placeholder/LayoutStartPanel.js +57 -0
  63. package/src/placeholder/Placeholder.css.js +20 -0
  64. package/src/placeholder/Placeholder.js +33 -0
  65. package/src/placeholder/index.js +1 -0
  66. package/src/responsive/index.js +2 -0
  67. package/src/responsive/measureMinimumNodeSize.js +24 -0
  68. package/src/responsive/useResizeObserver.js +109 -0
  69. package/src/responsive/utils.js +27 -0
  70. package/src/stack/Stack.css.js +44 -0
  71. package/src/stack/Stack.js +98 -0
  72. package/src/stack/StackLayout.js +116 -0
  73. package/src/stack/index.js +3 -0
  74. package/src/stack/stackTypes.js +0 -0
  75. package/src/tabs/TabPanel.css.js +17 -0
  76. package/src/tabs/TabPanel.js +11 -0
  77. package/src/tabs/index.js +1 -0
  78. package/src/tools/config-wrapper/ConfigWrapper.js +55 -0
  79. package/src/tools/config-wrapper/index.js +1 -0
  80. package/src/tools/devtools-box/layout-configurator.css.js +113 -0
  81. package/src/tools/devtools-tree/layout-tree-viewer.css.js +17 -0
  82. package/src/tools/index.js +3 -0
  83. package/src/use-persistent-state.js +43 -0
  84. package/src/utils/index.js +5 -0
  85. package/src/utils/pathUtils.js +212 -0
  86. package/src/utils/propUtils.js +15 -0
  87. package/src/utils/refUtils.js +5 -0
  88. package/src/utils/styleUtils.js +9 -0
  89. package/src/utils/typeOf.js +15 -0
@@ -0,0 +1,161 @@
1
+ import { VuuShellLocation } from "@vuu-ui/vuu-utils";
2
+ import react from "react";
3
+ import { followPath, followPathToParent, getProp, getProps, nextStep, resetPath, typeOf } from "../utils/index.js";
4
+ import { createPlaceHolder } from "./flexUtils.js";
5
+ import { layoutFromJson } from "./layoutUtils.js";
6
+ import { swapChild } from "./replace-layout-element.js";
7
+ function removeChild(layoutRoot, { path }) {
8
+ const target = followPath(layoutRoot, path);
9
+ let targetParent = followPathToParent(layoutRoot, path);
10
+ if (null === targetParent) return layoutRoot;
11
+ const { children } = getProps(targetParent);
12
+ if (children.length > 1 && "Stack" !== typeOf(targetParent) && allOtherChildrenArePlaceholders(children, path)) {
13
+ const { style: { flexBasis, display, flexDirection, ...style } } = getProps(targetParent);
14
+ let containerPath = getProp(targetParent, "path");
15
+ let newLayout = swapChild(layoutRoot, targetParent, createPlaceHolder(containerPath, flexBasis, style));
16
+ while(targetParent = followPathToParent(newLayout, containerPath)){
17
+ if ("0" === getProp(targetParent, "path")) break;
18
+ const { children } = getProps(targetParent);
19
+ if (allOtherChildrenArePlaceholders(children)) {
20
+ containerPath = getProp(targetParent, "path");
21
+ const { style: { flexBasis, display, flexDirection, ...style } } = getProps(targetParent);
22
+ newLayout = swapChild(layoutRoot, targetParent, createPlaceHolder(containerPath, flexBasis, style));
23
+ } else if (hasAdjacentPlaceholders(children)) newLayout = collapsePlaceholders(layoutRoot, targetParent);
24
+ else break;
25
+ }
26
+ return newLayout;
27
+ }
28
+ return _removeChild(layoutRoot, target);
29
+ }
30
+ function _removeChild(container, child) {
31
+ const props = getProps(container);
32
+ const { children: componentChildren, path, preserve } = props;
33
+ let { active, id: containerId } = props;
34
+ const { idx, finalStep } = nextStep(path, getProp(child, "path"));
35
+ const type = typeOf(container);
36
+ let children = componentChildren.slice();
37
+ if (finalStep) {
38
+ children.splice(idx, 1);
39
+ if (void 0 !== active && active >= idx) active = Math.max(0, active - 1);
40
+ if (0 === children.length && preserve && "Stack" === type) {
41
+ const { path, style: { flexBasis } } = getProps(child);
42
+ const placeHolder = containerId === VuuShellLocation.Workspace ? layoutFromJson({
43
+ props: {
44
+ style: {
45
+ flexGrow: 1,
46
+ flexShrink: 1,
47
+ flexBasis
48
+ },
49
+ title: "Tab 1"
50
+ },
51
+ type: "Placeholder"
52
+ }, path) : createPlaceHolder(path, flexBasis);
53
+ children.push(placeHolder);
54
+ } else if (1 === children.length && !preserve && "0" !== path && type.match(/Flexbox|Stack/)) return unwrap(container, children[0]);
55
+ if (!children.some(isFlexible) && children.some(canBeMadeFlexible)) children = makeFlexible(children);
56
+ } else children[idx] = _removeChild(children[idx], child);
57
+ children = children.map((child, i)=>resetPath(child, `${path}.${i}`));
58
+ return react.cloneElement(container, {
59
+ active
60
+ }, children);
61
+ }
62
+ function unwrap(container, child) {
63
+ const type = typeOf(container);
64
+ const { path, style: { flexBasis, flexGrow, flexShrink, width, height } } = getProps(container);
65
+ let unwrappedChild = resetPath(child, path);
66
+ if ("0" === path) unwrappedChild = react.cloneElement(unwrappedChild, {
67
+ style: {
68
+ ...child.props.style,
69
+ width,
70
+ height
71
+ }
72
+ });
73
+ else if ("Flexbox" === type) {
74
+ const dim = "column" === container.props.style.flexDirection ? "height" : "width";
75
+ const { style: { [dim]: size, ...style } } = unwrappedChild.props;
76
+ unwrappedChild = react.cloneElement(unwrappedChild, {
77
+ flexFill: void 0,
78
+ style: {
79
+ ...style,
80
+ flexGrow,
81
+ flexShrink,
82
+ flexBasis,
83
+ width,
84
+ height
85
+ }
86
+ });
87
+ }
88
+ return unwrappedChild;
89
+ }
90
+ const isFlexible = (element)=>element.props.style?.flexGrow > 0;
91
+ const canBeMadeFlexible = (element)=>{
92
+ if (!element.props.style) return false;
93
+ {
94
+ const { width, height, flexGrow } = element.props.style;
95
+ return 0 === flexGrow && "number" != typeof width && "number" != typeof height;
96
+ }
97
+ };
98
+ const makeFlexible = (children)=>children.map((child)=>canBeMadeFlexible(child) ? react.cloneElement(child, {
99
+ style: {
100
+ ...child.props.style,
101
+ flexGrow: 1
102
+ }
103
+ }) : child);
104
+ const hasAdjacentPlaceholders = (children)=>{
105
+ if (children && children.length > 0) {
106
+ let wasPlaceholder = getProp(children[0], "placeholder");
107
+ let isPlaceholder = false;
108
+ for(let i = 1; i < children.length; i++){
109
+ isPlaceholder = getProp(children[i], "placeholder");
110
+ if (wasPlaceholder && isPlaceholder) return true;
111
+ wasPlaceholder = isPlaceholder;
112
+ }
113
+ }
114
+ };
115
+ const collapsePlaceholders = (container, target)=>{
116
+ const { children: componentChildren, path } = getProps(container);
117
+ const { idx, finalStep } = nextStep(path, getProp(target, "path"));
118
+ let children = componentChildren.slice();
119
+ if (finalStep) children[idx] = _collapsePlaceHolders(target);
120
+ else children[idx] = collapsePlaceholders(children[idx], target);
121
+ children = children.map((child, i)=>resetPath(child, `${path}.${i}`));
122
+ return react.cloneElement(container, void 0, children);
123
+ };
124
+ const _collapsePlaceHolders = (container)=>{
125
+ const { children } = getProps(container);
126
+ const newChildren = [];
127
+ const placeholders = [];
128
+ for(let i = 0; i < children.length; i++)if (getProp(children[i], "placeholder")) placeholders.push(children[i]);
129
+ else {
130
+ if (1 === placeholders.length) newChildren.push(placeholders.pop());
131
+ else if (placeholders.length > 0) {
132
+ newChildren.push(mergePlaceholders(placeholders));
133
+ placeholders.length = 0;
134
+ }
135
+ newChildren.push(children[i]);
136
+ }
137
+ if (1 === placeholders.length) newChildren.push(placeholders.pop());
138
+ else if (placeholders.length > 0) newChildren.push(mergePlaceholders(placeholders));
139
+ const containerPath = getProp(container, "path");
140
+ return react.cloneElement(container, void 0, newChildren.map((child, i)=>resetPath(child, `${containerPath}.${i}`)));
141
+ };
142
+ const mergePlaceholders = ([placeholder, ...placeholders])=>{
143
+ const targetStyle = getProp(placeholder, "style");
144
+ let { flexBasis, flexGrow, flexShrink } = targetStyle;
145
+ for (const placeholder of placeholders){
146
+ const { style } = placeholder.props;
147
+ flexBasis += style.flexBasis;
148
+ flexGrow = Math.max(flexGrow, style.flexGrow);
149
+ flexShrink = Math.max(flexShrink, style.flexShrink);
150
+ }
151
+ return react.cloneElement(placeholder, {
152
+ style: {
153
+ ...targetStyle,
154
+ flexBasis,
155
+ flexGrow,
156
+ flexShrink
157
+ }
158
+ });
159
+ };
160
+ const allOtherChildrenArePlaceholders = (children, path)=>children.every((child)=>getProp(child, "placeholder") || path && getProp(child, "path") === path);
161
+ export { removeChild };
@@ -0,0 +1,70 @@
1
+ import react from "react";
2
+ import { getProp, getProps, nextStep } from "../utils/index.js";
3
+ import { applyLayoutProps } from "./layoutUtils.js";
4
+ function replaceChild(model, { target, replacement }) {
5
+ return _replaceChild(model, target, replacement);
6
+ }
7
+ function _replaceChild(model, child, replacement) {
8
+ const path = getProp(child, "path");
9
+ const resizeable = getProp(child, "resizeable");
10
+ const { style } = getProps(child);
11
+ const newChild = applyLayoutProps(react.cloneElement(replacement, {
12
+ resizeable,
13
+ style: {
14
+ ...style,
15
+ ...replacement.props.style
16
+ }
17
+ }), path);
18
+ return swapChild(model, child, newChild);
19
+ }
20
+ function swapChild(model, child, replacement, op) {
21
+ if (model === child) return replacement;
22
+ const { idx, finalStep } = nextStep(getProp(model, "path"), getProp(child, "path"));
23
+ const modelChildren = model.props.children;
24
+ const children = modelChildren.slice();
25
+ if (finalStep) if (op) {
26
+ if ("collapse" === op) children[idx] = collapse(model, children[idx]);
27
+ else if ("expand" === op) children[idx] = expand(children[idx]);
28
+ } else children[idx] = replacement;
29
+ else children[idx] = swapChild(children[idx], child, replacement, op);
30
+ return react.cloneElement(model, void 0, children);
31
+ }
32
+ function collapse(parent, child) {
33
+ const { style: parentStyle } = getProps(parent);
34
+ const { style: childStyle } = getProps(child);
35
+ const { width, height, flexBasis, flexShrink, flexGrow, ...rest } = childStyle;
36
+ const restoreStyle = {
37
+ width,
38
+ height,
39
+ flexBasis,
40
+ flexShrink,
41
+ flexGrow
42
+ };
43
+ const style = {
44
+ ...rest,
45
+ flexBasis: 0,
46
+ flexGrow: 0,
47
+ flexShrink: 0
48
+ };
49
+ const collapsed = "row" === parentStyle.flexDirection ? "vertical" : "column" === parentStyle.flexDirection ? "horizontal" : false;
50
+ if (collapsed) return react.cloneElement(child, {
51
+ collapsed,
52
+ restoreStyle,
53
+ style
54
+ });
55
+ return child;
56
+ }
57
+ function expand(child) {
58
+ const { style: childStyle, restoreStyle } = getProps(child);
59
+ const { flexBasis, flexShrink, flexGrow, ...rest } = childStyle;
60
+ const style = {
61
+ ...rest,
62
+ ...restoreStyle
63
+ };
64
+ return react.cloneElement(child, {
65
+ collapsed: false,
66
+ style,
67
+ restoreStyle: void 0
68
+ });
69
+ }
70
+ export { _replaceChild, replaceChild, swapChild };
@@ -0,0 +1,48 @@
1
+ import react from "react";
2
+ import { followPath, getProps } from "../utils/index.js";
3
+ import { swapChild } from "./replace-layout-element.js";
4
+ function resizeFlexChild(layoutRoot, { path, size }) {
5
+ const target = followPath(layoutRoot, path, true);
6
+ const { style } = getProps(target);
7
+ const newStyle = {
8
+ ...style,
9
+ width: size
10
+ };
11
+ const replacement = react.cloneElement(target, {
12
+ style: newStyle
13
+ });
14
+ return swapChild(layoutRoot, target, replacement);
15
+ }
16
+ function resizeFlexChildren(layoutRoot, { path, sizes }) {
17
+ const target = followPath(layoutRoot, path, true);
18
+ const { children, style } = getProps(target);
19
+ const dimension = "column" === style.flexDirection ? "height" : "width";
20
+ const replacementChildren = applySizesToChildren(children, sizes, dimension);
21
+ const replacement = react.cloneElement(target, void 0, replacementChildren);
22
+ return swapChild(layoutRoot, target, replacement);
23
+ }
24
+ function applySizesToChildren(children, sizes, dimension) {
25
+ return children.map((child, i)=>{
26
+ const { style: { [dimension]: size, flexBasis: actualFlexBasis } } = getProps(child);
27
+ const meta = sizes[i];
28
+ const { currentSize, flexBasis } = meta;
29
+ const hasCurrentSize = void 0 !== currentSize;
30
+ const newSize = hasCurrentSize ? meta.currentSize : flexBasis;
31
+ if (void 0 === newSize || size === newSize || actualFlexBasis === newSize) return child;
32
+ return react.cloneElement(child, {
33
+ style: applySizeToChild(child.props.style, dimension, newSize)
34
+ });
35
+ });
36
+ }
37
+ function applySizeToChild(style, dimension, newSize) {
38
+ const hasSize = "number" == typeof style[dimension];
39
+ const { flexShrink = 1, flexGrow = 1 } = style;
40
+ return {
41
+ ...style,
42
+ [dimension]: hasSize ? newSize : "auto",
43
+ flexBasis: hasSize ? "auto" : newSize,
44
+ flexShrink,
45
+ flexGrow
46
+ };
47
+ }
48
+ export { resizeFlexChild, resizeFlexChildren };
@@ -0,0 +1,134 @@
1
+ import { getLayoutComponent, uuid } from "@vuu-ui/vuu-utils";
2
+ import react from "react";
3
+ import { getProp, getProps, nextStep, resetPath, typeOf } from "../utils/index.js";
4
+ import { createFlexbox, createPlaceHolder, getFlexStyle, getIntrinsicSize, wrapIntrinsicSizeComponentWithFlexbox } from "./flexUtils.js";
5
+ import { applyLayoutProps } from "./layoutUtils.js";
6
+ const isHtmlElement = (component)=>{
7
+ const [firstLetter] = typeOf(component);
8
+ return firstLetter === firstLetter.toLowerCase();
9
+ };
10
+ function wrap(container, existingComponent, newComponent, pos, clientRect, dropRect) {
11
+ const { children: containerChildren, path: containerPath } = getProps(container);
12
+ const existingComponentPath = getProp(existingComponent, "path");
13
+ const { idx, finalStep } = nextStep(containerPath, existingComponentPath);
14
+ const children = finalStep ? updateChildren(container, containerChildren, existingComponent, newComponent, pos, clientRect, dropRect) : containerChildren.map((child, index)=>index === idx ? wrap(child, existingComponent, newComponent, pos, clientRect, dropRect) : child);
15
+ return react.cloneElement(container, void 0, children);
16
+ }
17
+ function updateChildren(container, containerChildren, existingComponent, newComponent, pos, clientRect, dropRect) {
18
+ const intrinsicSize = getIntrinsicSize(newComponent);
19
+ if (intrinsicSize?.width && intrinsicSize?.height) {
20
+ if (void 0 === clientRect || void 0 === dropRect) throw Error("wrap-layout-element, updateChildren clientRect and dropRect must both be available");
21
+ return wrapIntrinsicSizedComponent(containerChildren, existingComponent, newComponent, pos, clientRect, dropRect);
22
+ }
23
+ return wrapFlexComponent(container, containerChildren, existingComponent, newComponent, pos);
24
+ }
25
+ function wrapFlexComponent(container, containerChildren, existingComponent, newComponent, pos) {
26
+ const { version = 0 } = getProps(newComponent);
27
+ const { path: existingComponentPath, title } = getProps(existingComponent);
28
+ const { type, flexDirection, showTabs: showTabsProp } = getLayoutSpecForWrapper(pos);
29
+ const [style, existingComponentStyle, newComponentStyle] = getWrappedFlexStyles(type, existingComponent, newComponent, flexDirection, pos);
30
+ const targetFirst = isTargetFirst(pos);
31
+ const active = targetFirst ? 1 : 0;
32
+ const newComponentProps = {
33
+ resizeable: true,
34
+ style: newComponentStyle,
35
+ version: version + 1
36
+ };
37
+ const resizeProp = isHtmlElement(existingComponent) ? "data-resizeable" : "resizeable";
38
+ const existingComponentProps = {
39
+ [resizeProp]: true,
40
+ style: existingComponentStyle
41
+ };
42
+ const showTabs = "Stack" === type ? {
43
+ showTabs: showTabsProp
44
+ } : void 0;
45
+ const splitterSize = "Flexbox" === type ? {
46
+ splitterSize: ("Flexbox" === typeOf(container) && container.props.splitterSize) ?? void 0
47
+ } : void 0;
48
+ const id = uuid();
49
+ const wrapper = react.createElement(getLayoutComponent(type), {
50
+ active,
51
+ id,
52
+ key: id,
53
+ path: getProp(existingComponent, "path"),
54
+ flexFill: getProp(existingComponent, "flexFill"),
55
+ ...splitterSize,
56
+ ...showTabs,
57
+ style,
58
+ title,
59
+ resizeable: getProp(existingComponent, "resizeable")
60
+ }, targetFirst ? [
61
+ resetPath(existingComponent, `${existingComponentPath}.0`, existingComponentProps),
62
+ applyLayoutProps(react.cloneElement(newComponent, newComponentProps), `${existingComponentPath}.1`)
63
+ ] : [
64
+ applyLayoutProps(react.cloneElement(newComponent, newComponentProps), `${existingComponentPath}.0`),
65
+ resetPath(existingComponent, `${existingComponentPath}.1`, existingComponentProps)
66
+ ]);
67
+ return containerChildren.map((child)=>child === existingComponent ? wrapper : child);
68
+ }
69
+ function wrapIntrinsicSizedComponent(containerChildren, existingComponent, newComponent, pos, clientRect, dropRect) {
70
+ const { flexDirection } = getLayoutSpecForWrapper(pos);
71
+ const contraDirection = "column" === flexDirection ? "row" : "column";
72
+ const targetFirst = isTargetFirst(pos);
73
+ const [dropLeft, dropTop, dropRight, dropBottom] = dropRect;
74
+ const [startPlaceholder, endPlaceholder] = "column" === flexDirection ? [
75
+ dropTop - clientRect.top,
76
+ clientRect.bottom - dropBottom
77
+ ] : [
78
+ dropLeft - clientRect.left,
79
+ clientRect.right - dropRight
80
+ ];
81
+ const pathRoot = getProp(existingComponent, "path");
82
+ let pathIndex = 0;
83
+ const resizeProp = isHtmlElement(existingComponent) ? "data-resizeable" : "resizeable";
84
+ const wrappedChildren = [];
85
+ if (startPlaceholder) wrappedChildren.push(targetFirst ? resetPath(existingComponent, `${pathRoot}.${pathIndex++}`, {
86
+ [resizeProp]: true,
87
+ style: {
88
+ flexBasis: startPlaceholder,
89
+ flexGrow: 1,
90
+ flexShrink: 1
91
+ }
92
+ }) : createPlaceHolder(`${pathRoot}.${pathIndex++}`, startPlaceholder, {
93
+ flexGrow: 0,
94
+ flexShrink: 0
95
+ }));
96
+ wrappedChildren.push(wrapIntrinsicSizeComponentWithFlexbox(newComponent, contraDirection, `${pathRoot}.${pathIndex++}`, clientRect, dropRect));
97
+ if (endPlaceholder) wrappedChildren.push(targetFirst ? createPlaceHolder(`${pathRoot}.${pathIndex++}`, 0) : resetPath(existingComponent, `${pathRoot}.${pathIndex++}`, {
98
+ [resizeProp]: true,
99
+ style: {
100
+ flexBasis: 0,
101
+ flexGrow: 1,
102
+ flexShrink: 1
103
+ }
104
+ }));
105
+ const wrapper = createFlexbox(flexDirection, existingComponent.props, wrappedChildren, pathRoot);
106
+ return containerChildren.map((child)=>child === existingComponent ? wrapper : child);
107
+ }
108
+ function getWrappedFlexStyles(type, existingComponent, newComponent, flexDirection, pos) {
109
+ const style = {
110
+ ...existingComponent.props.style,
111
+ flexDirection
112
+ };
113
+ const dimension = "Flexbox" === type && "column" === flexDirection ? "height" : "width";
114
+ const newComponentStyle = getFlexStyle(newComponent, dimension, pos);
115
+ const existingComponentStyle = getFlexStyle(existingComponent, dimension);
116
+ return [
117
+ style,
118
+ existingComponentStyle,
119
+ newComponentStyle
120
+ ];
121
+ }
122
+ const isTargetFirst = (pos)=>pos.position.SouthOrEast ? true : pos?.tab?.positionRelativeToTab === "before" ? false : !!pos.position.Header;
123
+ function getLayoutSpecForWrapper(pos) {
124
+ if (pos.position.Header) return {
125
+ type: "Stack",
126
+ flexDirection: "column",
127
+ showTabs: true
128
+ };
129
+ return {
130
+ type: "Flexbox",
131
+ flexDirection: pos.position.EastOrWest ? "row" : "column"
132
+ };
133
+ }
134
+ export { wrap };
@@ -0,0 +1,76 @@
1
+ const css = `
2
+ .vuuView {
3
+ --vuuToolbarProxy-height: var(--salt-size-base);
4
+ border-color: var(--vuuView-borderColor, transparent);
5
+ border-width: var(--vuuView-borderWidth, 1px);
6
+ border-style: var(--vuuView-borderStyle, solid);
7
+ margin: var(--vuuView-margin, 0px);
8
+ outline: none;
9
+ flex-direction: column;
10
+ min-width: 50px;
11
+ min-height: 50px;
12
+ transition: flex-basis .3s ease-in-out;
13
+ display: flex;
14
+ position: relative;
15
+ overflow: hidden;
16
+
17
+ &.vuuHighlighted {
18
+ --vuuView-borderStyle: dashed;
19
+ --vuuView-borderColor: var(--salt-container-primary-borderColor);
20
+ }
21
+ }
22
+
23
+ .vuuSplitterResizing .vuuView {
24
+ transition: none;
25
+ }
26
+
27
+ .vuuView:has( > .vuuHeader) {
28
+ min-height: var(--vuuToolbarProxy-height);
29
+ }
30
+
31
+ .vuuView.focus-visible:after {
32
+ content: "";
33
+ border: 2px dotted #6495ed;
34
+ position: absolute;
35
+ inset: 0;
36
+ }
37
+
38
+ .vuuView.dragging {
39
+ box-shadow: 0 6px 12px #0000002d;
40
+ }
41
+
42
+ .vuuView-main {
43
+ flex-direction: var(--vuuView-flexDirection, column);
44
+ flex-wrap: var(--vuuView-flex-wrap, nowrap);
45
+ justify-content: var(--vuuView-justify, flex-start);
46
+ flex: 1;
47
+ display: flex;
48
+ position: relative;
49
+ overflow: hidden;
50
+ }
51
+
52
+ .vuuView-main > * {
53
+ flex-basis: auto;
54
+ flex-grow: var(--vuuView-flex-grow, 1);
55
+ flex-shrink: var(--vuuView-flex-shrink, 1);
56
+ }
57
+
58
+ .vuuView-collapsed {
59
+ flex: 0 0 0 !important;
60
+ }
61
+
62
+ .vuuView-collapsed + .Splitter {
63
+ display: none;
64
+ }
65
+
66
+ .vuuView-collapsed .Toolbar-vertical {
67
+ border-right: solid 1px var(--grey40);
68
+ }
69
+
70
+ .vuuView-collapsed .Toolbar-vertical .toolbar-title {
71
+ display: none;
72
+ }
73
+
74
+
75
+ `;
76
+ export default css;
@@ -0,0 +1,116 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { registerComponent, useId } from "@vuu-ui/vuu-utils";
3
+ import { useForkRef } from "@salt-ds/core";
4
+ import { useComponentCssInjection } from "@salt-ds/styles";
5
+ import { useWindow } from "@salt-ds/window";
6
+ import clsx from "clsx";
7
+ import react, { forwardRef, useCallback, useMemo, useRef, useState } from "react";
8
+ import { Header as Header_js_Header } from "../layout-header/Header.js";
9
+ import { useView } from "./useView.js";
10
+ import { useViewResize } from "./useViewResize.js";
11
+ import { ViewContext } from "../layout-view-actions/ViewContext.js";
12
+ import View_0 from "./View.css";
13
+ const classBase = "vuuView";
14
+ const getProps = (state, props)=>{
15
+ if (state && props) return {
16
+ ...state,
17
+ ...props
18
+ };
19
+ return state || props;
20
+ };
21
+ const View_View = /*#__PURE__*/ forwardRef(function(props, forwardedRef) {
22
+ const { Header = Header_js_Header, allowRename, children, className, collapsed, closeable, "data-path": dataPath, "data-resizeable": dataResizeable, dropTargets, expanded, flexFill, id: idProp, header, onCollapse, onExpand, orientation = "horizontal", path = dataPath, resize = "responsive", resizeable = dataResizeable, restoreStyle, tearOut, style = {}, title: titleProp, ...restProps } = props;
23
+ const targetWindow = useWindow();
24
+ useComponentCssInjection({
25
+ testId: "vuu-view",
26
+ css: View_0,
27
+ window: targetWindow
28
+ });
29
+ const id = useId(idProp);
30
+ const rootRef = useRef(null);
31
+ const mainRef = useRef(null);
32
+ const [componentProps, _setComponentProps] = useState();
33
+ const { contributions, dispatchViewAction, load, onConfigChange, onEditTitle, purge, restoredState, save, title } = useView({
34
+ id,
35
+ rootRef,
36
+ path,
37
+ dropTargets,
38
+ title: titleProp
39
+ });
40
+ useViewResize({
41
+ mainRef,
42
+ resize,
43
+ rootRef
44
+ });
45
+ const setComponentProps = useCallback((props)=>{
46
+ _setComponentProps(props);
47
+ }, []);
48
+ const getContent = ()=>{
49
+ if (/*#__PURE__*/ react.isValidElement(children) && (restoredState || componentProps)) return /*#__PURE__*/ react.cloneElement(children, getProps(restoredState, componentProps));
50
+ return children;
51
+ };
52
+ const viewContextValue = useMemo(()=>({
53
+ dispatch: dispatchViewAction,
54
+ id,
55
+ path,
56
+ title,
57
+ load,
58
+ onConfigChange,
59
+ purge,
60
+ save,
61
+ setComponentProps
62
+ }), [
63
+ dispatchViewAction,
64
+ id,
65
+ load,
66
+ onConfigChange,
67
+ path,
68
+ purge,
69
+ save,
70
+ setComponentProps,
71
+ title
72
+ ]);
73
+ const headerProps = "object" == typeof header ? header : {};
74
+ return /*#__PURE__*/ jsx("div", {
75
+ ...restProps,
76
+ className: clsx(classBase, className, {
77
+ [`${classBase}-collapsed`]: collapsed,
78
+ [`${classBase}-expanded`]: expanded,
79
+ [`${classBase}-resize-defer`]: "defer" === resize
80
+ }),
81
+ "data-resizeable": resizeable,
82
+ id: id,
83
+ ref: useForkRef(forwardedRef, rootRef),
84
+ style: style,
85
+ tabIndex: -1,
86
+ children: /*#__PURE__*/ jsxs(ViewContext.Provider, {
87
+ value: viewContextValue,
88
+ children: [
89
+ header ? /*#__PURE__*/ jsx(Header, {
90
+ ...headerProps,
91
+ allowRename: allowRename,
92
+ collapsed: collapsed,
93
+ contributions: contributions,
94
+ expanded: expanded,
95
+ closeable: closeable,
96
+ onCollapse: onCollapse,
97
+ onEditTitle: onEditTitle,
98
+ onExpand: onExpand,
99
+ orientation: orientation,
100
+ tearOut: tearOut,
101
+ title: title
102
+ }) : null,
103
+ /*#__PURE__*/ jsx("div", {
104
+ className: `${classBase}-main`,
105
+ ref: mainRef,
106
+ children: getContent()
107
+ })
108
+ ]
109
+ })
110
+ });
111
+ });
112
+ View_View.displayName = "View";
113
+ const MemoView = /*#__PURE__*/ react.memo(View_View);
114
+ MemoView.displayName = "View";
115
+ registerComponent("View", MemoView, "view");
116
+ export { MemoView as View };
@@ -0,0 +1,69 @@
1
+ import { useCallback, useMemo } from "react";
2
+ import { useLayoutProviderDispatch } from "../layout-provider/LayoutProvider.js";
3
+ import { usePersistentState } from "../use-persistent-state.js";
4
+ import { useViewActionDispatcher } from "../layout-view-actions/useViewActionDispatcher.js";
5
+ const useView = ({ id, rootRef, path, dropTargets, title: titleProp })=>{
6
+ const layoutDispatch = useLayoutProviderDispatch();
7
+ const { loadState, purgeState, saveState } = usePersistentState();
8
+ const [dispatchViewAction, contributions] = useViewActionDispatcher(id, rootRef, path, dropTargets);
9
+ const title = useMemo(()=>loadState("view-title") ?? titleProp, [
10
+ loadState,
11
+ titleProp
12
+ ]);
13
+ const onEditTitle = useCallback((title)=>{
14
+ if (path) layoutDispatch({
15
+ type: "set-title",
16
+ path,
17
+ title
18
+ });
19
+ }, [
20
+ layoutDispatch,
21
+ path
22
+ ]);
23
+ const restoredState = useMemo(()=>loadState(id), [
24
+ id,
25
+ loadState
26
+ ]);
27
+ const load = useCallback((key)=>loadState(id, key), [
28
+ id,
29
+ loadState
30
+ ]);
31
+ const purge = useCallback((key)=>{
32
+ purgeState(id, key);
33
+ layoutDispatch({
34
+ type: "save"
35
+ });
36
+ }, [
37
+ id,
38
+ layoutDispatch,
39
+ purgeState
40
+ ]);
41
+ const save = useCallback((state, key)=>{
42
+ saveState(id, key, state);
43
+ layoutDispatch({
44
+ type: "save"
45
+ });
46
+ }, [
47
+ id,
48
+ layoutDispatch,
49
+ saveState
50
+ ]);
51
+ const onConfigChange = useCallback(({ type: key, ...config })=>{
52
+ const { [key]: data } = config;
53
+ save(data, key);
54
+ }, [
55
+ save
56
+ ]);
57
+ return {
58
+ contributions,
59
+ dispatchViewAction,
60
+ load,
61
+ onConfigChange,
62
+ onEditTitle,
63
+ purge,
64
+ restoredState,
65
+ save,
66
+ title
67
+ };
68
+ };
69
+ export { useView };