ui-layout-manager-dev 0.0.21 → 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 +16 -2
- 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/sample_components/filetree/FileTree.jsx +23 -1
package/package.json
CHANGED
|
@@ -134,9 +134,23 @@ export const HandleBar = ({orientation, parent, sibling1, sibling2}) => {
|
|
|
134
134
|
if (newSibling1Size < MIN_PANEL_SIZE || newSibling2Size < MIN_PANEL_SIZE) {
|
|
135
135
|
return;
|
|
136
136
|
}
|
|
137
|
+
|
|
138
|
+
// If both siblings are type fill, then set sizes.
|
|
139
|
+
const sibling1Type = startInfo.sibling1LayoutConfig.initial.type;
|
|
140
|
+
const sibling2Type = startInfo.sibling2LayoutConfig.initial.type;
|
|
141
|
+
if (sibling1Type === "fill" && sibling2Type === "fill") {
|
|
142
|
+
controller.containerRefs[sibling1].style[startInfo.propKey] = newSibling1Size + "px";
|
|
143
|
+
controller.containerRefs[sibling2].style[startInfo.propKey] = newSibling2Size + "px";
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
137
146
|
|
|
138
|
-
|
|
139
|
-
|
|
147
|
+
// Don't update fill type siblings, if one of the siblings isn't fill type.
|
|
148
|
+
if (!(sibling1Type === "fill")) {
|
|
149
|
+
controller.containerRefs[sibling1].style[startInfo.propKey] = newSibling1Size + "px";
|
|
150
|
+
}
|
|
151
|
+
if (!(sibling2Type === "fill")) {
|
|
152
|
+
controller.containerRefs[sibling2].style[startInfo.propKey] = newSibling2Size + "px";
|
|
153
|
+
}
|
|
140
154
|
}
|
|
141
155
|
|
|
142
156
|
/**
|
|
@@ -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";
|
|
@@ -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 (
|