ui-layout-manager-dev 0.0.22 → 0.0.23-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 +3 -3
- package/dist/cjs/index.js.map +1 -1
- package/dist/esm/index.js +3 -3
- package/dist/esm/index.js.map +1 -1
- package/package.json +1 -1
- package/src/components/LayoutManager/Components/HandleBar/HandleBar.jsx +1 -1
- package/src/components/LayoutManager/Components/LazyLoader/Tabs/Tabs.js +2 -2
- package/src/components/LayoutManager/LayoutManager.jsx +10 -7
- package/src/components/LayoutManager/LayoutManager.scss +53 -0
- package/src/components/LayoutManager/Providers/ModalProvider.js +96 -0
- package/src/index.js +2 -1
- package/src/stories/layouts/vsCode/workbench.json +13 -155
- package/src/stories/sample_components/filetree/FileTree.jsx +23 -1
package/package.json
CHANGED
|
@@ -144,7 +144,7 @@ export const HandleBar = ({orientation, parent, sibling1, sibling2}) => {
|
|
|
144
144
|
return;
|
|
145
145
|
}
|
|
146
146
|
|
|
147
|
-
//
|
|
147
|
+
// Don't update fill type siblings, if one of the siblings isn't fill type.
|
|
148
148
|
if (!(sibling1Type === "fill")) {
|
|
149
149
|
controller.containerRefs[sibling1].style[startInfo.propKey] = newSibling1Size + "px";
|
|
150
150
|
}
|
|
@@ -4,6 +4,7 @@ import { RootContainer } from "./Components/RootContainer/RootContainer";
|
|
|
4
4
|
import ComponentRegistryContext from "./Providers/ComponentRegistryContext";
|
|
5
5
|
import { LayoutControllerProvider } from "./Providers/LayoutProvider";
|
|
6
6
|
import { LayoutEventProvider } from "./Providers/LayoutEventProvider";
|
|
7
|
+
import { ModalProvider } from "./Providers/ModalProvider";
|
|
7
8
|
|
|
8
9
|
import "./LayoutManager.scss";
|
|
9
10
|
|
|
@@ -19,13 +20,15 @@ export const LayoutManager = ({ldf, registry}) => {
|
|
|
19
20
|
|
|
20
21
|
|
|
21
22
|
return (
|
|
22
|
-
<
|
|
23
|
-
<
|
|
24
|
-
<
|
|
25
|
-
<
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
23
|
+
<ModalProvider>
|
|
24
|
+
<LayoutControllerProvider layout={ldf}>
|
|
25
|
+
<LayoutEventProvider>
|
|
26
|
+
<ComponentRegistryContext.Provider value={registry}>
|
|
27
|
+
<RootContainer/>
|
|
28
|
+
</ComponentRegistryContext.Provider>
|
|
29
|
+
</LayoutEventProvider>
|
|
30
|
+
</LayoutControllerProvider>
|
|
31
|
+
</ModalProvider>
|
|
29
32
|
);
|
|
30
33
|
}
|
|
31
34
|
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
.modal-backdrop {
|
|
2
|
+
position: fixed;
|
|
3
|
+
top: 0;
|
|
4
|
+
left: 0;
|
|
5
|
+
width: 100%;
|
|
6
|
+
height: 100%;
|
|
7
|
+
background-color: rgba(0, 0, 0, 0.5);
|
|
8
|
+
display: flex;
|
|
9
|
+
justify-content: center;
|
|
10
|
+
align-items: center;
|
|
11
|
+
z-index: 1000;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
.modal-content {
|
|
15
|
+
background-color: #333333;
|
|
16
|
+
border-radius: 5px;
|
|
17
|
+
display: flex;
|
|
18
|
+
flex-direction: column;
|
|
19
|
+
max-width: 500px;
|
|
20
|
+
max-height: 500px;
|
|
21
|
+
scrollbar-gutter: stable;
|
|
22
|
+
scrollbar-color: #47474766 #252526;
|
|
23
|
+
scrollbar-width: thin;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
.modal-header {
|
|
27
|
+
display:flex;
|
|
28
|
+
justify-content: space-between;
|
|
29
|
+
height:25px;
|
|
30
|
+
border-bottom: solid 1px rgb(85, 85, 85);
|
|
31
|
+
padding: 10px 20px;
|
|
32
|
+
align-items: center;
|
|
33
|
+
font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
.modal-header > .title {
|
|
37
|
+
color:rgb(180, 180, 180);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
.modal-header > .close-button {
|
|
41
|
+
cursor: pointer;
|
|
42
|
+
color:rgb(180, 180, 180);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
.modal-header > .close-button:hover {
|
|
46
|
+
color:white;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
.modal-body {
|
|
50
|
+
flex: 1;
|
|
51
|
+
overflow: auto;
|
|
52
|
+
padding:10px;
|
|
53
|
+
}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
// @ts-nocheck
|
|
2
|
+
import React, {
|
|
3
|
+
createContext,
|
|
4
|
+
useCallback,
|
|
5
|
+
useContext,
|
|
6
|
+
useMemo,
|
|
7
|
+
useState,
|
|
8
|
+
} from "react";
|
|
9
|
+
|
|
10
|
+
import { createPortal } from "react-dom";
|
|
11
|
+
|
|
12
|
+
import {XLg} from "react-bootstrap-icons";
|
|
13
|
+
|
|
14
|
+
const ModalContext = createContext(null);
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Modal provider component to manage modals in the application
|
|
18
|
+
* @returns {JSX} The modal provider component
|
|
19
|
+
*/
|
|
20
|
+
export function ModalProvider({ children }) {
|
|
21
|
+
const [modal, setModal] = useState(null);
|
|
22
|
+
|
|
23
|
+
// Open a modal with the given content and title. Returns a function to close the modal.
|
|
24
|
+
const openModal = useCallback(( args ) => {
|
|
25
|
+
const close = () => {
|
|
26
|
+
setModal(null);
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
const id = `modal-${Date.now()}`;
|
|
30
|
+
setModal({
|
|
31
|
+
id: id,
|
|
32
|
+
title: args.title,
|
|
33
|
+
render: args.render,
|
|
34
|
+
close: close,
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
return { id, close };
|
|
38
|
+
}, []);
|
|
39
|
+
|
|
40
|
+
// Close the currently open modal
|
|
41
|
+
const closeModal = useCallback(() => {
|
|
42
|
+
setModal(null);
|
|
43
|
+
}, []);
|
|
44
|
+
|
|
45
|
+
// Render the modal portal
|
|
46
|
+
// TODO: Add support for different sizes
|
|
47
|
+
const getPortal = () => {
|
|
48
|
+
return createPortal(
|
|
49
|
+
<>
|
|
50
|
+
{modal && (
|
|
51
|
+
<React.Fragment key={modal.id}>
|
|
52
|
+
<div className="modal-backdrop" onClick={modal.close}>
|
|
53
|
+
<div className="modal-content" onClick={(e) => e.stopPropagation()}>
|
|
54
|
+
<div className="modal-header">
|
|
55
|
+
<span className="title">{modal.title}</span>
|
|
56
|
+
<XLg className="close-button" onClick={modal.close} />
|
|
57
|
+
</div>
|
|
58
|
+
<div className="modal-body">
|
|
59
|
+
{modal.render({ close: modal.close })}
|
|
60
|
+
</div>
|
|
61
|
+
</div>
|
|
62
|
+
</div>
|
|
63
|
+
</React.Fragment>
|
|
64
|
+
)}
|
|
65
|
+
</>,
|
|
66
|
+
document.body,
|
|
67
|
+
);
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
const api = useMemo(
|
|
71
|
+
() => ({
|
|
72
|
+
openModal,
|
|
73
|
+
closeModal,
|
|
74
|
+
}),
|
|
75
|
+
[openModal, closeModal],
|
|
76
|
+
);
|
|
77
|
+
|
|
78
|
+
return (
|
|
79
|
+
<ModalContext.Provider value={api}>
|
|
80
|
+
{children}
|
|
81
|
+
{getPortal()}
|
|
82
|
+
</ModalContext.Provider>
|
|
83
|
+
);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Modal manager hook to access the modal API
|
|
88
|
+
* @return {Object} The modal manager API
|
|
89
|
+
*/
|
|
90
|
+
export function useModalManager() {
|
|
91
|
+
const value = useContext(ModalContext);
|
|
92
|
+
if (!value) {
|
|
93
|
+
throw new Error("useModalManager must be used inside ModalProvider");
|
|
94
|
+
}
|
|
95
|
+
return value;
|
|
96
|
+
}
|
package/src/index.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
1
|
export * from "./components/LayoutManager";
|
|
2
2
|
export { useLayoutEventPublisher } from "./components/LayoutManager/Providers/LayoutEventProvider";
|
|
3
|
-
export { useLayoutEventSubscription } from "./components/LayoutManager/Providers/LayoutEventProvider";
|
|
3
|
+
export { useLayoutEventSubscription } from "./components/LayoutManager/Providers/LayoutEventProvider";
|
|
4
|
+
export { useModalManager } from "./components/LayoutManager/Providers/ModalProvider";
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
{
|
|
11
11
|
"containerId": "header",
|
|
12
12
|
"type": "container",
|
|
13
|
-
"size": { "initial": { "value":
|
|
13
|
+
"size": { "initial": { "value": 25, "unit": "px", "type": "fixed" }}
|
|
14
14
|
},
|
|
15
15
|
{
|
|
16
16
|
"containerId": "mainBody",
|
|
@@ -38,9 +38,8 @@
|
|
|
38
38
|
{
|
|
39
39
|
"containerId": "sidebar",
|
|
40
40
|
"type": "container",
|
|
41
|
-
"size": { "initial": { "value":
|
|
42
|
-
"collapse": { "value": 400, "condition": "lessThan", "relative": "parent" }
|
|
43
|
-
"showHandlebar": true
|
|
41
|
+
"size": { "initial": { "value": 50, "unit": "px", "type": "fixed" }},
|
|
42
|
+
"collapse": { "value": 400, "condition": "lessThan", "relative": "parent" }
|
|
44
43
|
},
|
|
45
44
|
{
|
|
46
45
|
"containerId": "contentContainer",
|
|
@@ -80,13 +79,13 @@
|
|
|
80
79
|
"id": "terminal",
|
|
81
80
|
"tabsBar": {
|
|
82
81
|
"tabs": [
|
|
83
|
-
{
|
|
84
|
-
"name": "Terminal",
|
|
85
|
-
"component": "PtyTerminal"
|
|
86
|
-
},
|
|
87
82
|
{
|
|
88
83
|
"name": "Flow",
|
|
89
84
|
"component": "Flow"
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
"name": "FileTree",
|
|
88
|
+
"component": "FileTree"
|
|
90
89
|
}
|
|
91
90
|
],
|
|
92
91
|
"showClose": true,
|
|
@@ -104,9 +103,9 @@
|
|
|
104
103
|
"containerId": "menuContainer",
|
|
105
104
|
"type": "container",
|
|
106
105
|
"size": {
|
|
107
|
-
"initial": { "value":
|
|
108
|
-
"min": { "value":
|
|
109
|
-
"max": { "value":
|
|
106
|
+
"initial": { "value": 250, "unit": "px", "type": "fixed" },
|
|
107
|
+
"min": { "value": 200, "unit": "px"},
|
|
108
|
+
"max": { "value": 400, "unit": "px"}
|
|
110
109
|
},
|
|
111
110
|
"collapse": { "value": 700, "condition": "lessThan", "relative": "parent" }
|
|
112
111
|
},
|
|
@@ -119,31 +118,6 @@
|
|
|
119
118
|
"containerId": "editorContainer",
|
|
120
119
|
"type": "container",
|
|
121
120
|
"size": { "initial": { "type": "fill" }}
|
|
122
|
-
},
|
|
123
|
-
{
|
|
124
|
-
"type": "handleBar",
|
|
125
|
-
"sibling1": "editorContainer",
|
|
126
|
-
"sibling2": "designLayoutContainer"
|
|
127
|
-
},
|
|
128
|
-
{
|
|
129
|
-
"containerId": "designLayoutContainer",
|
|
130
|
-
"type": "container",
|
|
131
|
-
"size": { "initial": { "type": "fill" }}
|
|
132
|
-
},
|
|
133
|
-
{
|
|
134
|
-
"type": "handleBar",
|
|
135
|
-
"sibling1": "designLayoutContainer",
|
|
136
|
-
"sibling2": "rightMenuContainer"
|
|
137
|
-
},
|
|
138
|
-
{
|
|
139
|
-
"containerId": "rightMenuContainer",
|
|
140
|
-
"type": "container",
|
|
141
|
-
"size": {
|
|
142
|
-
"initial": { "value": 270, "unit": "px", "type": "fixed" },
|
|
143
|
-
"min": { "value": 170, "unit": "px"},
|
|
144
|
-
"max": { "value": 320, "unit": "px"}
|
|
145
|
-
},
|
|
146
|
-
"collapse": { "value": 700, "condition": "lessThan", "relative": "parent" }
|
|
147
121
|
}
|
|
148
122
|
]
|
|
149
123
|
},
|
|
@@ -164,139 +138,23 @@
|
|
|
164
138
|
{
|
|
165
139
|
"containerId": "fileTabsContainer",
|
|
166
140
|
"type": "container",
|
|
167
|
-
"size": {
|
|
168
|
-
"initial": { "value": 350, "unit": "px", "type": "fixed" },
|
|
169
|
-
"min": { "value": 51, "unit": "px"}
|
|
170
|
-
},
|
|
171
|
-
"collapse": { "value": 400, "condition": "lessThan", "relative": "parent" }
|
|
172
|
-
},
|
|
173
|
-
{
|
|
174
|
-
"type": "handleBar",
|
|
175
|
-
"sibling1": "fileTabsContainer",
|
|
176
|
-
"sibling2": "leftMenuContainer2"
|
|
177
|
-
},
|
|
178
|
-
{
|
|
179
|
-
"containerId": "leftMenuContainer2",
|
|
180
|
-
"type": "container",
|
|
181
|
-
"size": { "initial": { "type": "fill" }}
|
|
182
|
-
}
|
|
183
|
-
]
|
|
184
|
-
},
|
|
185
|
-
"rightMenuContainer": {
|
|
186
|
-
"id": "rightMenuContainer",
|
|
187
|
-
"background": "#252526",
|
|
188
|
-
"type": "split",
|
|
189
|
-
"orientation": "vertical",
|
|
190
|
-
"children": [
|
|
191
|
-
{
|
|
192
|
-
"containerId": "rightMenuContainer1",
|
|
193
|
-
"type": "container",
|
|
194
|
-
"size": {
|
|
195
|
-
"initial": { "value": 200, "unit": "px", "type": "fixed" },
|
|
196
|
-
"min": { "value": 51, "unit": "px"}
|
|
197
|
-
},
|
|
198
|
-
"collapse": { "value": 400, "condition": "lessThan", "relative": "parent" }
|
|
199
|
-
},
|
|
200
|
-
{
|
|
201
|
-
"type": "handleBar",
|
|
202
|
-
"sibling1": "rightMenuContainer1",
|
|
203
|
-
"sibling2": "rightMenuContainer3"
|
|
204
|
-
},
|
|
205
|
-
{
|
|
206
|
-
"containerId": "rightMenuContainer2",
|
|
207
|
-
"type": "container",
|
|
208
141
|
"size": { "initial": { "type": "fill" }}
|
|
209
|
-
},
|
|
210
|
-
{
|
|
211
|
-
"type": "handleBar",
|
|
212
|
-
"sibling1": "rightMenuContainer2",
|
|
213
|
-
"sibling2": "rightMenuContainer3"
|
|
214
|
-
},
|
|
215
|
-
{
|
|
216
|
-
"containerId": "rightMenuContainer3",
|
|
217
|
-
"type": "container",
|
|
218
|
-
"size": {
|
|
219
|
-
"initial": { "value": 200, "unit": "px", "type": "fixed" },
|
|
220
|
-
"min": { "value": 51, "unit": "px"}
|
|
221
|
-
},
|
|
222
|
-
"collapse": { "value": 500, "condition": "lessThan", "relative": "parent" }
|
|
223
142
|
}
|
|
224
143
|
]
|
|
225
144
|
},
|
|
226
145
|
"fileTabsContainer": {
|
|
227
146
|
"id": "fileTabsContainer",
|
|
228
|
-
"component": "
|
|
147
|
+
"component": "FileTree",
|
|
229
148
|
"menuBar": {
|
|
230
149
|
"showClose": true,
|
|
231
150
|
"closeContainerId": "menuContainer",
|
|
232
|
-
"title": "
|
|
151
|
+
"title": "EXPLORER"
|
|
233
152
|
},
|
|
234
153
|
"background": "#1e1e1e"
|
|
235
154
|
},
|
|
236
155
|
"editorContainer": {
|
|
237
156
|
"id": "editorContainer",
|
|
238
|
-
"component": "
|
|
239
|
-
"background": "#1e1e1e"
|
|
240
|
-
},
|
|
241
|
-
"FlowContainer": {
|
|
242
|
-
"id": "FlowContainer",
|
|
243
|
-
"component": "Flow",
|
|
244
|
-
"background": "#1e1e1e"
|
|
245
|
-
},
|
|
246
|
-
"designLayoutContainer": {
|
|
247
|
-
"id": "designLayoutContainer",
|
|
248
|
-
"type": "split",
|
|
249
|
-
"orientation": "horizontal",
|
|
250
|
-
"children": [
|
|
251
|
-
{
|
|
252
|
-
"containerId": "toolbarContainer",
|
|
253
|
-
"type": "container",
|
|
254
|
-
"size": { "initial": { "value": 40, "unit": "px", "type": "fixed" }},
|
|
255
|
-
"collapse": { "value": 100, "condition": "lessThan", "relative": "parent" }
|
|
256
|
-
},
|
|
257
|
-
{
|
|
258
|
-
"containerId": "FlowContainer",
|
|
259
|
-
"type": "container",
|
|
260
|
-
"size": { "initial": { "type": "fill" }}
|
|
261
|
-
}
|
|
262
|
-
],
|
|
263
|
-
"background": "#1e1e1e"
|
|
264
|
-
},
|
|
265
|
-
"leftMenuContainer2": {
|
|
266
|
-
"id": "leftMenuContainer2",
|
|
267
|
-
"menuBar": {
|
|
268
|
-
"showClose": false,
|
|
269
|
-
"title": "File Browser3"
|
|
270
|
-
},
|
|
271
|
-
"background": "#1e1e1e"
|
|
272
|
-
},
|
|
273
|
-
"rightMenuContainer1": {
|
|
274
|
-
"id": "rightMenuContainer1",
|
|
275
|
-
"menuBar": {
|
|
276
|
-
"showClose": false,
|
|
277
|
-
"title": "Behaviors"
|
|
278
|
-
},
|
|
279
|
-
"background": "#1e1e1e"
|
|
280
|
-
},
|
|
281
|
-
"rightMenuContainer2": {
|
|
282
|
-
"id": "rightMenuContainer2",
|
|
283
|
-
"menuBar": {
|
|
284
|
-
"showClose": false,
|
|
285
|
-
"title": "Participants"
|
|
286
|
-
},
|
|
287
|
-
"background": "#1e1e1e"
|
|
288
|
-
},
|
|
289
|
-
"rightMenuContainer3": {
|
|
290
|
-
"id": "rightMenuContainer3",
|
|
291
|
-
"menuBar": {
|
|
292
|
-
"showClose": false,
|
|
293
|
-
"title": "Invariants"
|
|
294
|
-
},
|
|
295
|
-
"background": "#1e1e1e"
|
|
296
|
-
},
|
|
297
|
-
"toolbarContainer": {
|
|
298
|
-
"id": "toolbarContainer",
|
|
299
|
-
"component": "ToolBar",
|
|
157
|
+
"component": "FileEditor",
|
|
300
158
|
"background": "#1e1e1e"
|
|
301
159
|
}
|
|
302
160
|
}
|
|
@@ -4,10 +4,13 @@ import { FileBrowser } from 'sample-ui-component-library';
|
|
|
4
4
|
import tree from "./workspace_sample.json"
|
|
5
5
|
|
|
6
6
|
import { useLayoutEventPublisher } from "../../../components/LayoutManager/Providers/LayoutEventProvider";
|
|
7
|
+
import { useModalManager } from "../../../components/LayoutManager/Providers/ModalProvider";
|
|
8
|
+
import Stack from "../stack/Stack";
|
|
7
9
|
|
|
8
10
|
const FileTree = () => {
|
|
9
11
|
const fileBrowserRef = useRef(null);
|
|
10
12
|
const publish = useLayoutEventPublisher();
|
|
13
|
+
const { openModal } = useModalManager();
|
|
11
14
|
|
|
12
15
|
useLayoutEffect(() => {
|
|
13
16
|
fileBrowserRef.current.addFileTree(tree.tree);
|
|
@@ -21,7 +24,26 @@ const FileTree = () => {
|
|
|
21
24
|
type: "file:selected",
|
|
22
25
|
payload: node,
|
|
23
26
|
source: "file-tree",
|
|
24
|
-
})
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
// For demo purposes, if the readme file is selected, open a modal.
|
|
31
|
+
if (node.name === "readme") {
|
|
32
|
+
const {id, close} = openModal({
|
|
33
|
+
title:"Readme",
|
|
34
|
+
render: ({ close }) => {
|
|
35
|
+
return <>
|
|
36
|
+
<Stack />
|
|
37
|
+
<Stack />
|
|
38
|
+
</>;
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
// For demo purposes, automatically close the modal after 10 seconds.
|
|
43
|
+
// setTimeout(() => {
|
|
44
|
+
// close();
|
|
45
|
+
// }, 10000);
|
|
46
|
+
}
|
|
25
47
|
}
|
|
26
48
|
|
|
27
49
|
return (
|