ui-layout-manager-dev 0.0.24-dev → 0.0.26-dev
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/dist/cjs/index.js +1 -1
- package/dist/cjs/index.js.map +1 -1
- package/dist/esm/index.js +1 -1
- package/dist/esm/index.js.map +1 -1
- package/package.json +1 -1
- package/src/components/LayoutManager/Components/RootContainer/RootContainer.jsx +1 -1
- package/src/components/LayoutManager/LayoutManager.jsx +5 -9
- package/src/components/LayoutManager/Providers/ModalProvider.js +2 -1
- package/src/index.js +2 -1
- package/src/stories/LayoutManager.stories.js +7 -3
- package/src/stories/sample_components/filetree/FileTree.jsx +5 -5
- package/src/stories/sample_components/stack/Stack.jsx +5 -3
- package/dist/esm/LayoutWorker.js +0 -494
package/package.json
CHANGED
|
@@ -147,7 +147,7 @@ export const RootContainer = () => {
|
|
|
147
147
|
onDragEnd={dragController.onDragEnd}
|
|
148
148
|
onDragCancel={dragController.onDragCancel}>
|
|
149
149
|
|
|
150
|
-
<div
|
|
150
|
+
<div className="root-container">
|
|
151
151
|
<div ref={rootRef} className="relative-container">
|
|
152
152
|
{childElements}
|
|
153
153
|
</div>
|
|
@@ -3,7 +3,6 @@ import PropTypes from 'prop-types';
|
|
|
3
3
|
import { RootContainer } from "./Components/RootContainer/RootContainer";
|
|
4
4
|
import ComponentRegistryContext from "./Providers/ComponentRegistryContext";
|
|
5
5
|
import { LayoutControllerProvider } from "./Providers/LayoutProvider";
|
|
6
|
-
import { LayoutEventProvider } from "./Providers/LayoutEventProvider";
|
|
7
6
|
import { ModalProvider } from "./Providers/ModalProvider";
|
|
8
7
|
|
|
9
8
|
import "./LayoutManager.scss";
|
|
@@ -17,17 +16,14 @@ import "./LayoutManager.scss";
|
|
|
17
16
|
* @return {React.ReactElement}
|
|
18
17
|
*/
|
|
19
18
|
export const LayoutManager = ({ldf, registry}) => {
|
|
20
|
-
|
|
21
19
|
|
|
22
20
|
return (
|
|
23
21
|
<LayoutControllerProvider layout={ldf}>
|
|
24
|
-
<
|
|
25
|
-
<
|
|
26
|
-
<
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
</ComponentRegistryContext.Provider>
|
|
30
|
-
</LayoutEventProvider>
|
|
22
|
+
<ComponentRegistryContext.Provider value={registry}>
|
|
23
|
+
<ModalProvider>
|
|
24
|
+
<RootContainer/>
|
|
25
|
+
</ModalProvider>
|
|
26
|
+
</ComponentRegistryContext.Provider>
|
|
31
27
|
</LayoutControllerProvider>
|
|
32
28
|
);
|
|
33
29
|
}
|
|
@@ -30,6 +30,7 @@ export function ModalProvider({ children }) {
|
|
|
30
30
|
setModal({
|
|
31
31
|
id: id,
|
|
32
32
|
title: args.title,
|
|
33
|
+
args: args.args,
|
|
33
34
|
render: args.render,
|
|
34
35
|
close: close,
|
|
35
36
|
});
|
|
@@ -56,7 +57,7 @@ export function ModalProvider({ children }) {
|
|
|
56
57
|
<XLg className="close-button" onClick={modal.close} />
|
|
57
58
|
</div>
|
|
58
59
|
<div className="modal-body">
|
|
59
|
-
{modal.render({ close: modal.close })}
|
|
60
|
+
{modal.render({ close: modal.close , args: modal.args })}
|
|
60
61
|
</div>
|
|
61
62
|
</div>
|
|
62
63
|
</div>
|
package/src/index.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export * from "./components/LayoutManager";
|
|
2
2
|
export { useLayoutEventPublisher } from "./components/LayoutManager/Providers/LayoutEventProvider";
|
|
3
3
|
export { useLayoutEventSubscription } from "./components/LayoutManager/Providers/LayoutEventProvider";
|
|
4
|
-
export { useModalManager } from "./components/LayoutManager/Providers/ModalProvider";
|
|
4
|
+
export { useModalManager } from "./components/LayoutManager/Providers/ModalProvider";
|
|
5
|
+
export { LayoutEventProvider } from "./components/LayoutManager/Providers/LayoutEventProvider";
|
|
@@ -7,6 +7,8 @@ import workbenchJSON from "./layouts/vsCode/workbench.json";
|
|
|
7
7
|
import workbench2JSON from "./layouts/vsCode/workbench2.json";
|
|
8
8
|
import workbench3JSON from "./layouts/vsCode/workbench3.json";
|
|
9
9
|
|
|
10
|
+
import { LayoutEventProvider } from "../components/LayoutManager/Providers/LayoutEventProvider";
|
|
11
|
+
|
|
10
12
|
import "./LayoutManager.stories.scss";
|
|
11
13
|
|
|
12
14
|
export default {
|
|
@@ -50,9 +52,11 @@ const Template = (args) => {
|
|
|
50
52
|
}, [updateArgs, registry]);
|
|
51
53
|
|
|
52
54
|
return (
|
|
53
|
-
<
|
|
54
|
-
<
|
|
55
|
-
|
|
55
|
+
<LayoutEventProvider>
|
|
56
|
+
<div className="rootContainer">
|
|
57
|
+
<LayoutManager {...args}/>
|
|
58
|
+
</div>
|
|
59
|
+
</LayoutEventProvider>
|
|
56
60
|
)
|
|
57
61
|
}
|
|
58
62
|
|
|
@@ -31,11 +31,11 @@ const FileTree = () => {
|
|
|
31
31
|
if (node.name === "readme") {
|
|
32
32
|
const {id, close} = openModal({
|
|
33
33
|
title:"Readme",
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
34
|
+
args: {
|
|
35
|
+
sample: "sample arg"
|
|
36
|
+
},
|
|
37
|
+
render: ({ close, args }) => {
|
|
38
|
+
return <Stack close={close} args={args} />
|
|
39
39
|
}
|
|
40
40
|
});
|
|
41
41
|
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { StackList } from 'sample-ui-component-library';
|
|
2
2
|
|
|
3
|
-
const Stack = () => {
|
|
3
|
+
const Stack = ({close, args}) => {
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
console.log(args);
|
|
6
|
+
|
|
7
|
+
const args2 = [
|
|
6
8
|
{functionName:"visit_arg", fileName: "helper.py", lineNumber: 3},
|
|
7
9
|
{functionName:"__init__", fileName: "helper.py", lineNumber: 65},
|
|
8
10
|
{functionName:"injectLogTypesA", fileName: "LogInjector.py", lineNumber: 3, selected: true},
|
|
@@ -14,7 +16,7 @@ const Stack = () => {
|
|
|
14
16
|
]
|
|
15
17
|
|
|
16
18
|
return (
|
|
17
|
-
<StackList traces={
|
|
19
|
+
<StackList traces={args2} />
|
|
18
20
|
);
|
|
19
21
|
};
|
|
20
22
|
|
package/dist/esm/LayoutWorker.js
DELETED
|
@@ -1,494 +0,0 @@
|
|
|
1
|
-
let LAYOUT_WORKER_PROTOCOL = {
|
|
2
|
-
INITIALIZE: 1,
|
|
3
|
-
INITIALIZE_FLEXBOX: 2,
|
|
4
|
-
APPLY_SIZES: 3,
|
|
5
|
-
ERROR: 4,
|
|
6
|
-
TRANSFORMATIONS: 5,
|
|
7
|
-
MOVE_HANDLE_BAR: 6
|
|
8
|
-
};
|
|
9
|
-
LAYOUT_WORKER_PROTOCOL = Object.freeze(LAYOUT_WORKER_PROTOCOL);
|
|
10
|
-
|
|
11
|
-
var LAYOUT_WORKER_PROTOCOL$1 = LAYOUT_WORKER_PROTOCOL;
|
|
12
|
-
|
|
13
|
-
let TRANSFORMATION_TYPES = {
|
|
14
|
-
UPDATE_SIZE: 1
|
|
15
|
-
};
|
|
16
|
-
TRANSFORMATION_TYPES = Object.freeze(TRANSFORMATION_TYPES);
|
|
17
|
-
|
|
18
|
-
var TRANSFORMATION_TYPES$1 = TRANSFORMATION_TYPES;
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* This class generates transformations based on the
|
|
22
|
-
* parents layout configuration. For example, it collapses
|
|
23
|
-
* a container if the parent size reaches a threshold
|
|
24
|
-
* or expands it if the is above a threshold.
|
|
25
|
-
*/
|
|
26
|
-
class ParentRuleEnforcer {
|
|
27
|
-
/**
|
|
28
|
-
* Initialize the rule enforcer.
|
|
29
|
-
* @param {Object} sizes
|
|
30
|
-
* @param {Object} parent
|
|
31
|
-
* @param {Object} child
|
|
32
|
-
*/
|
|
33
|
-
constructor (sizes, parent, child) {
|
|
34
|
-
this.sizes = sizes;
|
|
35
|
-
this.parent = parent;
|
|
36
|
-
this.child = child;
|
|
37
|
-
this.type = null;
|
|
38
|
-
this.args = {};
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
/**
|
|
42
|
-
* Get props given node orientation.
|
|
43
|
-
* @param {Object} node
|
|
44
|
-
*/
|
|
45
|
-
getProps(node) {
|
|
46
|
-
// Identify the dynamic property based on orientation.
|
|
47
|
-
if (node.orientation === "horizontal") {
|
|
48
|
-
return {"dynamic": "width", "fixed": "height"};
|
|
49
|
-
} else if (node.orientation === "vertical") {
|
|
50
|
-
return {"dynamic": "height", "fixed": "width"};
|
|
51
|
-
} else {
|
|
52
|
-
throw new Error(`Unknown orientation "${node.orientation}" in LDF configuration`);
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
/**
|
|
57
|
-
* Evaluate the rules based on parent and child sizes and
|
|
58
|
-
* the specified layout configuration.
|
|
59
|
-
*/
|
|
60
|
-
evaluate() {
|
|
61
|
-
if (this.child.hasOwnProperty("collapse") && this.child["collapse"]["relative"] === "parent") {
|
|
62
|
-
this.evaluateCollapseByParent();
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
/**
|
|
67
|
-
* Evaluate the collapse by parent property.
|
|
68
|
-
*/
|
|
69
|
-
evaluateCollapseByParent() {
|
|
70
|
-
const props = this.getProps(this.parent);
|
|
71
|
-
const parentSize = this.sizes[this.parent.id];
|
|
72
|
-
|
|
73
|
-
let args = {};
|
|
74
|
-
if (parentSize[props["dynamic"]] <= this.child.collapse.value && this.child.collapse.condition === "lessThan") {
|
|
75
|
-
// Collapse below threshold
|
|
76
|
-
if (!this.child.hidden) {
|
|
77
|
-
this.type = TRANSFORMATION_TYPES$1.UPDATE_SIZE;
|
|
78
|
-
args = {style: {"display":"none"}};
|
|
79
|
-
const prop = "min-" + props["dynamic"];
|
|
80
|
-
args.style[prop] = 0;
|
|
81
|
-
this.child.hidden = true;
|
|
82
|
-
}
|
|
83
|
-
} else {
|
|
84
|
-
// Expand above threshold
|
|
85
|
-
if (this.child.hidden) {
|
|
86
|
-
this.type = TRANSFORMATION_TYPES$1.UPDATE_SIZE;
|
|
87
|
-
args = {style: {"display":"flex"}};
|
|
88
|
-
if ("min" in this.child.size) {
|
|
89
|
-
const prop = "min-" + props["dynamic"];
|
|
90
|
-
args.style[prop] = this.child.size.min.value + this.child.size.min.unit;
|
|
91
|
-
}
|
|
92
|
-
this.child.hidden = false;
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
Object.assign(this.args, args);
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
/**
|
|
100
|
-
* This class generates transformations based on the handle
|
|
101
|
-
* bars movements. It sets up thresholds at which it collapses
|
|
102
|
-
* and expands the containers. This isn't the width of the container,
|
|
103
|
-
* it is the position of the handle bar in the parent container. So
|
|
104
|
-
* even if a container has a min width of 200px, when the handle bar
|
|
105
|
-
* reaches 50px from the left, it will collapse it.
|
|
106
|
-
*
|
|
107
|
-
* This will be expanded in the future to have different collapsed states.
|
|
108
|
-
* So rather than fully collapsing the container, it sets up a
|
|
109
|
-
* minimum size, this willl be useful for accordians and other containers.
|
|
110
|
-
*/
|
|
111
|
-
class HandleRulesEnforcer {
|
|
112
|
-
/**
|
|
113
|
-
* Initialize the child rule enforcer.
|
|
114
|
-
* @param {Object} parent
|
|
115
|
-
* @param {Object} sibling1
|
|
116
|
-
* @param {Object} sibling2
|
|
117
|
-
* @param {Object} handleMetadata
|
|
118
|
-
*/
|
|
119
|
-
constructor (parent, sibling1, sibling2, handleMetadata) {
|
|
120
|
-
this.parent = parent;
|
|
121
|
-
this.type = null;
|
|
122
|
-
this.args = {};
|
|
123
|
-
this.sibling1 = sibling1;
|
|
124
|
-
this.sibling2 = sibling2;
|
|
125
|
-
this.handleMetadata = handleMetadata;
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
/**
|
|
129
|
-
* Get props given node orientation.
|
|
130
|
-
* @param {Object} node
|
|
131
|
-
*/
|
|
132
|
-
getProps(node) {
|
|
133
|
-
// Identify the dynamic property based on orientation.
|
|
134
|
-
if (node.orientation === "horizontal") {
|
|
135
|
-
return {"dynamic": "width", "fixed": "height"};
|
|
136
|
-
} else if (node.orientation === "vertical") {
|
|
137
|
-
return {"dynamic": "height", "fixed": "width"};
|
|
138
|
-
} else {
|
|
139
|
-
throw new Error(`Unknown orientation "${node.orientation}" in LDF configuration`);
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
/**
|
|
144
|
-
* Evaluate the rules based on childs
|
|
145
|
-
*/
|
|
146
|
-
evaluate() {
|
|
147
|
-
this.activeSibling = null;
|
|
148
|
-
const props = this.getProps(this.parent);
|
|
149
|
-
if (props.dynamic === "width") {
|
|
150
|
-
this.processVerticalContainers();
|
|
151
|
-
} else if (props.dynamic === "height") {
|
|
152
|
-
this.processHorizontalContainers();
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
/**
|
|
157
|
-
* Process the vertical containers.
|
|
158
|
-
*/
|
|
159
|
-
processVerticalContainers () {
|
|
160
|
-
const totalWidth = this.handleMetadata.sizes[this.parent.id].width;
|
|
161
|
-
this.type = TRANSFORMATION_TYPES$1.UPDATE_SIZE;
|
|
162
|
-
|
|
163
|
-
// Currently only collapse the edge containers
|
|
164
|
-
// TODO: In the future add logic for middle containers (accordian style)
|
|
165
|
-
if (!this.checkIfEdgeContainer()) {
|
|
166
|
-
return;
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
if (this.handleMetadata.handle.x < 100) {
|
|
170
|
-
this.args = {style: {"display":"none", "min-width":0}};
|
|
171
|
-
this.sibling1.hidden = true;
|
|
172
|
-
this.activeSibling = this.sibling1.id;
|
|
173
|
-
} else if (this.handleMetadata.handle.x > 100 && this.sibling1.hidden) {
|
|
174
|
-
this.args = {style: {"display":"flex"}};
|
|
175
|
-
const sibling = this.getSiblingProps(this.sibling1.id);
|
|
176
|
-
if ("min" in sibling.size) {
|
|
177
|
-
this.args.style["min-width"] = sibling.size.min.value + sibling.size.min.unit;
|
|
178
|
-
}
|
|
179
|
-
this.sibling1.hidden = false;
|
|
180
|
-
this.activeSibling = this.sibling1.id;
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
if (this.handleMetadata.handle.x > totalWidth - 100) {
|
|
185
|
-
this.args = {style: {"display":"none", "min-width":0}};
|
|
186
|
-
this.sibling2.hidden = true;
|
|
187
|
-
this.activeSibling = this.sibling2.id;
|
|
188
|
-
} else if (this.handleMetadata.handle.x < totalWidth - 100 && this.sibling2.hidden) {
|
|
189
|
-
this.args = {style: {"display":"flex"}};
|
|
190
|
-
const sibling = this.getSiblingProps(this.sibling2.id);
|
|
191
|
-
if ("min" in sibling.size) {
|
|
192
|
-
this.args.style["min-width"] = sibling.size.min.value + sibling.size.min.unit;
|
|
193
|
-
}
|
|
194
|
-
this.sibling2.hidden = false;
|
|
195
|
-
this.activeSibling = this.sibling2.id;
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
/**
|
|
201
|
-
* Process the vertical containers.
|
|
202
|
-
*/
|
|
203
|
-
processHorizontalContainers () {
|
|
204
|
-
const totalHeight = this.handleMetadata.sizes[this.parent.id].height;
|
|
205
|
-
this.type = TRANSFORMATION_TYPES$1.UPDATE_SIZE;
|
|
206
|
-
|
|
207
|
-
// Currently only collapse the edge containers
|
|
208
|
-
// TODO: In the future add logic for middle containers (accordian style)
|
|
209
|
-
if (!this.checkIfEdgeContainer()) {
|
|
210
|
-
return;
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
if (this.handleMetadata.handle.y < 100) {
|
|
214
|
-
this.args = {style: {"display":"none", "min-height":0}};
|
|
215
|
-
this.sibling1.hidden = true;
|
|
216
|
-
this.activeSibling = this.sibling1.id;
|
|
217
|
-
} else if (this.handleMetadata.handle.y > 100 && this.sibling1.hidden) {
|
|
218
|
-
this.args = {style: {"display":"flex"}};
|
|
219
|
-
const sibling = this.getSiblingProps(this.sibling1.id);
|
|
220
|
-
if ("min" in sibling.size) {
|
|
221
|
-
this.args.style["min-height"] = sibling.size.min.value + sibling.size.min.unit;
|
|
222
|
-
}
|
|
223
|
-
this.sibling1.hidden = false;
|
|
224
|
-
this.activeSibling = this.sibling1.id;
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
if (this.handleMetadata.handle.y > totalHeight - 100) {
|
|
229
|
-
this.args = {style: {"display":"none", "min-height":0}};
|
|
230
|
-
this.sibling2.hidden = true;
|
|
231
|
-
this.activeSibling = this.sibling2.id;
|
|
232
|
-
} else if (this.handleMetadata.handle.y < totalHeight - 100 && this.sibling2.hidden) {
|
|
233
|
-
this.args = {style: {"display":"flex"}};
|
|
234
|
-
const sibling = this.getSiblingProps(this.sibling2.id);
|
|
235
|
-
if ("min" in sibling.size) {
|
|
236
|
-
this.args.style["min-height"] = sibling.size.min.value + sibling.size.min.unit;
|
|
237
|
-
}
|
|
238
|
-
this.sibling2.hidden = false;
|
|
239
|
-
this.activeSibling = this.sibling2.id;
|
|
240
|
-
}
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
/**
|
|
244
|
-
* Given the sibling ID, it returns the child properties from the parent.
|
|
245
|
-
* This includes the min-size and max-size. This is done because the actual
|
|
246
|
-
* min and max sizes are saved in the children of the parent, not in the actual
|
|
247
|
-
* container itself in the LDF file.
|
|
248
|
-
* @param {String} siblingId
|
|
249
|
-
*/
|
|
250
|
-
getSiblingProps (siblingId) {
|
|
251
|
-
for (let i = 0; i < this.parent.children.length; i++) {
|
|
252
|
-
const child = this.parent.children[i];
|
|
253
|
-
if (child.containerId === siblingId) {
|
|
254
|
-
return child;
|
|
255
|
-
}
|
|
256
|
-
}
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
/**
|
|
261
|
-
* Check if the handle bar is attached to the edge of the parent container.
|
|
262
|
-
* i.e. Is sibling1 on the very left or is sibling2 on the very right.
|
|
263
|
-
*/
|
|
264
|
-
checkIfEdgeContainer () {
|
|
265
|
-
const firstSibling = this.parent.children[0];
|
|
266
|
-
const lastSibling = this.parent.children[this.parent.children.length -1];
|
|
267
|
-
|
|
268
|
-
if (firstSibling.containerId === this.sibling1.id) {
|
|
269
|
-
return true;
|
|
270
|
-
} else if (lastSibling.containerId === this.sibling2.id) {
|
|
271
|
-
return true;
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
return false;
|
|
275
|
-
}
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
class LayoutEditor {
|
|
279
|
-
|
|
280
|
-
/**
|
|
281
|
-
* Initializes the editor with the given ldf file.
|
|
282
|
-
* @param {Object} ldf
|
|
283
|
-
*/
|
|
284
|
-
constructor (ldf) {
|
|
285
|
-
this.ldf = ldf;
|
|
286
|
-
console.log("Created modifier with ", this.ldf);
|
|
287
|
-
this.transformations = [];
|
|
288
|
-
}
|
|
289
|
-
|
|
290
|
-
/**
|
|
291
|
-
* Initializes flexbox layout by processing LDF file.
|
|
292
|
-
*/
|
|
293
|
-
initializeFlexBox() {
|
|
294
|
-
this.initializeNode(this.ldf.containers[this.ldf.layoutRoot]);
|
|
295
|
-
postMessage({
|
|
296
|
-
type: LAYOUT_WORKER_PROTOCOL$1.INITIALIZE_FLEXBOX,
|
|
297
|
-
data: this.transformations
|
|
298
|
-
});
|
|
299
|
-
this.transformations = [];
|
|
300
|
-
}
|
|
301
|
-
|
|
302
|
-
/**
|
|
303
|
-
* Get props given node orientation.
|
|
304
|
-
* @param {Object} node
|
|
305
|
-
*/
|
|
306
|
-
getProps(node) {
|
|
307
|
-
// Identify the dynamic property based on orientation.
|
|
308
|
-
if (node.orientation === "horizontal") {
|
|
309
|
-
return {"dynamic": "width", "fixed": "height"};
|
|
310
|
-
} else if (node.orientation === "vertical") {
|
|
311
|
-
return {"dynamic": "height", "fixed": "width"};
|
|
312
|
-
} else {
|
|
313
|
-
throw new Error(`Unknown orientation "${node.orientation}" in LDF configuration`);
|
|
314
|
-
}
|
|
315
|
-
}
|
|
316
|
-
|
|
317
|
-
/**
|
|
318
|
-
* Processes the node and applies the initial flex box styles. It recursively
|
|
319
|
-
* calls the initialization function on the nodes children until the entire
|
|
320
|
-
* layout is initialized.
|
|
321
|
-
*
|
|
322
|
-
* After initialization, the layout is recalculated when the handle bar moves
|
|
323
|
-
* or when the window is resized. In the future, I will add programatic control
|
|
324
|
-
* to modify the layout. This means that the API will ask to divide a container
|
|
325
|
-
* in two or to delete container.
|
|
326
|
-
*
|
|
327
|
-
* TODO: Implement the programmatic control of layout containers (see above).
|
|
328
|
-
*
|
|
329
|
-
* @param {Object} node Node to process.
|
|
330
|
-
*/
|
|
331
|
-
initializeNode (node) {
|
|
332
|
-
const isSplit = node.type ? node.type === "split": false;
|
|
333
|
-
|
|
334
|
-
// If node is not split, then it has no children and is a leaf node, so we return.
|
|
335
|
-
if (!isSplit) {
|
|
336
|
-
return;
|
|
337
|
-
}
|
|
338
|
-
|
|
339
|
-
const props = this.getProps(node);
|
|
340
|
-
|
|
341
|
-
for (const child of node.children) {
|
|
342
|
-
if (child.type === "container") {
|
|
343
|
-
let childStyle = {};
|
|
344
|
-
switch(child.size.initial.type) {
|
|
345
|
-
case "fixed":
|
|
346
|
-
childStyle[props["dynamic"]] = child.size.initial.value + "px" ;
|
|
347
|
-
childStyle["flex"] = "0 0 auto";
|
|
348
|
-
break;
|
|
349
|
-
case "fill":
|
|
350
|
-
childStyle["flexGrow"] = 1;
|
|
351
|
-
break;
|
|
352
|
-
default:
|
|
353
|
-
throw new Error(`Unknown size type "${child.size.initial.type}" in LDF configuration`);
|
|
354
|
-
}
|
|
355
|
-
|
|
356
|
-
if ("min" in child.size) {
|
|
357
|
-
childStyle["min-" + props["dynamic"]] = child.size.min.value + "px" ;
|
|
358
|
-
}
|
|
359
|
-
|
|
360
|
-
if ("max" in child.size) {
|
|
361
|
-
childStyle["max-" + props["dynamic"]] = child.size.max.value + "px" ;
|
|
362
|
-
}
|
|
363
|
-
|
|
364
|
-
const childContainer = this.ldf.containers[child.containerId];
|
|
365
|
-
childContainer.collapsed = false;
|
|
366
|
-
this.transformations.push(
|
|
367
|
-
{
|
|
368
|
-
id: childContainer.id,
|
|
369
|
-
type: TRANSFORMATION_TYPES$1.UPDATE_SIZE,
|
|
370
|
-
args: {style: childStyle}
|
|
371
|
-
}
|
|
372
|
-
);
|
|
373
|
-
this.initializeNode(childContainer);
|
|
374
|
-
}
|
|
375
|
-
}
|
|
376
|
-
}
|
|
377
|
-
|
|
378
|
-
/**
|
|
379
|
-
* Use the given sizes to perform layout calculations and generate
|
|
380
|
-
* transformations.
|
|
381
|
-
* @param {Object} sizes
|
|
382
|
-
*/
|
|
383
|
-
applySizes(sizes) {
|
|
384
|
-
this.sizes = sizes;
|
|
385
|
-
this.applyLayoutToNode(this.ldf.layoutRoot);
|
|
386
|
-
postMessage({
|
|
387
|
-
type: LAYOUT_WORKER_PROTOCOL$1.TRANSFORMATIONS,
|
|
388
|
-
data: this.transformations
|
|
389
|
-
});
|
|
390
|
-
this.transformations = [];
|
|
391
|
-
}
|
|
392
|
-
|
|
393
|
-
/**
|
|
394
|
-
* This function moves the handlebar.
|
|
395
|
-
* @param {Object} metadata
|
|
396
|
-
*/
|
|
397
|
-
moveHandleBar(metadata) {
|
|
398
|
-
const parent = this.ldf.containers[metadata.parent];
|
|
399
|
-
const sibling1 = this.ldf.containers[metadata.sibling1];
|
|
400
|
-
const sibling2 = this.ldf.containers[metadata.sibling2];
|
|
401
|
-
const enforcer = new HandleRulesEnforcer(parent, sibling1, sibling2, metadata);
|
|
402
|
-
enforcer.evaluate();
|
|
403
|
-
|
|
404
|
-
if (enforcer.activeSibling !== null) {
|
|
405
|
-
this.transformations.push(
|
|
406
|
-
{
|
|
407
|
-
id: enforcer.activeSibling,
|
|
408
|
-
type: TRANSFORMATION_TYPES$1.UPDATE_SIZE,
|
|
409
|
-
args: enforcer.args
|
|
410
|
-
}
|
|
411
|
-
);
|
|
412
|
-
postMessage({
|
|
413
|
-
type: LAYOUT_WORKER_PROTOCOL$1.TRANSFORMATIONS,
|
|
414
|
-
data: this.transformations
|
|
415
|
-
});
|
|
416
|
-
this.transformations = [];
|
|
417
|
-
}
|
|
418
|
-
}
|
|
419
|
-
|
|
420
|
-
/**
|
|
421
|
-
* Applys the layout logic to the node with the given container id.
|
|
422
|
-
* @param {String} containerId
|
|
423
|
-
* @returns
|
|
424
|
-
*/
|
|
425
|
-
applyLayoutToNode(containerId) {
|
|
426
|
-
const parent = this.ldf.containers[containerId];
|
|
427
|
-
|
|
428
|
-
// If node is not split, then it has no children and is a leaf node, so we return.
|
|
429
|
-
if ((!parent.type ? parent.type === "split": false) || (!("children" in parent))) {
|
|
430
|
-
return;
|
|
431
|
-
}
|
|
432
|
-
|
|
433
|
-
if (!this.sizes[containerId]) {
|
|
434
|
-
console.warn(`Parent size not found for node ${parent.id}. Skipping collapse checks.`);
|
|
435
|
-
return;
|
|
436
|
-
}
|
|
437
|
-
|
|
438
|
-
for (const child of parent.children) {
|
|
439
|
-
if (child.type === "container") {
|
|
440
|
-
const enforcer = new ParentRuleEnforcer(this.sizes, parent, child);
|
|
441
|
-
enforcer.evaluate();
|
|
442
|
-
if (enforcer.type) {
|
|
443
|
-
this.transformations.push(
|
|
444
|
-
{
|
|
445
|
-
id: this.ldf.containers[child.containerId].id,
|
|
446
|
-
type: enforcer.type,
|
|
447
|
-
args: enforcer.args,
|
|
448
|
-
}
|
|
449
|
-
);
|
|
450
|
-
}
|
|
451
|
-
this.applyLayoutToNode(child.containerId);
|
|
452
|
-
}
|
|
453
|
-
}
|
|
454
|
-
}
|
|
455
|
-
}
|
|
456
|
-
|
|
457
|
-
/**
|
|
458
|
-
* This function receives messages from the main thread and executes
|
|
459
|
-
* the layout manipulation logic.
|
|
460
|
-
* @param {Object} e
|
|
461
|
-
*/
|
|
462
|
-
let editor;
|
|
463
|
-
self.onmessage = function (e) {
|
|
464
|
-
|
|
465
|
-
try {
|
|
466
|
-
const args = e.data.args;
|
|
467
|
-
switch (e.data.code) {
|
|
468
|
-
case LAYOUT_WORKER_PROTOCOL$1.INITIALIZE:
|
|
469
|
-
/** @type {LayoutEditor} */
|
|
470
|
-
editor = new LayoutEditor(args.ldf);
|
|
471
|
-
break;
|
|
472
|
-
case LAYOUT_WORKER_PROTOCOL$1.INITIALIZE_FLEXBOX:
|
|
473
|
-
editor.initializeFlexBox();
|
|
474
|
-
break;
|
|
475
|
-
case LAYOUT_WORKER_PROTOCOL$1.APPLY_SIZES:
|
|
476
|
-
editor.applySizes(args.sizes);
|
|
477
|
-
break;
|
|
478
|
-
case LAYOUT_WORKER_PROTOCOL$1.MOVE_HANDLE_BAR:
|
|
479
|
-
editor.moveHandleBar(args.metadata);
|
|
480
|
-
break;
|
|
481
|
-
default:
|
|
482
|
-
break;
|
|
483
|
-
}
|
|
484
|
-
|
|
485
|
-
} catch (e) {
|
|
486
|
-
postMessage({
|
|
487
|
-
type: LAYOUT_WORKER_PROTOCOL$1.ERROR,
|
|
488
|
-
error: {
|
|
489
|
-
message: e.message,
|
|
490
|
-
stack: e.stack
|
|
491
|
-
}
|
|
492
|
-
});
|
|
493
|
-
}
|
|
494
|
-
};
|