ui-layout-manager-dev 0.0.19 → 0.0.20
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/Worker/LayoutWorker.js +38 -1
- package/dist/esm/index.js +3 -3
- package/dist/esm/index.js.map +1 -1
- package/package.json +3 -3
- package/src/components/LayoutManager/Components/Container/Container.jsx +1 -1
- package/src/components/LayoutManager/Components/HandleBar/HandleBar.jsx +6 -16
- package/src/components/LayoutManager/Components/LazyLoader/LazyLoader.js +74 -9
- package/src/components/LayoutManager/Components/LazyLoader/LazyLoader.scss +38 -1
- package/src/components/LayoutManager/Components/LazyLoader/MenuBar/MenuBar.js +40 -0
- package/src/components/LayoutManager/Components/LazyLoader/MenuBar/MenuBar.scss +22 -0
- package/src/components/LayoutManager/Components/LazyLoader/Tabs/Tabs.js +51 -0
- package/src/components/LayoutManager/Components/LazyLoader/Tabs/Tabs.scss +34 -0
- package/src/components/LayoutManager/Components/RootContainer/DragController.js +79 -0
- package/src/components/LayoutManager/Components/RootContainer/RootContainer.jsx +21 -21
- package/src/components/LayoutManager/Components/RootContainer/RootContainer.scss +1 -0
- package/src/components/LayoutManager/Controller/LAYOUT_WORKER_PROTOCOL.js +2 -1
- package/src/components/LayoutManager/Controller/LayoutController.js +14 -0
- package/src/components/LayoutManager/Controller/LayoutEventController.js +55 -0
- package/src/components/LayoutManager/Controller/Worker/HandleRulesEnforcer.js +4 -0
- package/src/components/LayoutManager/Controller/Worker/LayoutEditor.js +29 -0
- package/src/components/LayoutManager/Controller/Worker/LayoutWorker.js +3 -0
- package/src/components/LayoutManager/LayoutManager.jsx +5 -5
- package/src/components/LayoutManager/Providers/LayoutEventProvider.js +55 -0
- package/src/components/LayoutManager/index.js +1 -2
- package/src/stories/LayoutManager.stories.js +17 -0
- package/src/stories/layouts/vsCode/workbench.json +22 -5
- package/src/stories/layouts/vsCode/workbench2.json +176 -0
- package/src/stories/layouts/vsCode/workbench3.json +176 -0
- package/src/stories/sample_components/fileeditor/FileEditor.jsx +45 -21
- package/src/stories/sample_components/fileeditor/helper.js +22 -0
- package/src/stories/sample_components/filetree/FileTree.jsx +11 -5
- package/src/components/LayoutManager/Providers/DragProvider.js +0 -87
|
@@ -3,45 +3,69 @@ import { useRef, useLayoutEffect, useEffect } from "react";
|
|
|
3
3
|
import { Editor } from 'sample-ui-component-library';
|
|
4
4
|
import fileTree from "./workspace_sample.json";
|
|
5
5
|
|
|
6
|
-
import {
|
|
6
|
+
import { flattenTree } from "./helper";
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
tree.flatMap(node => [
|
|
10
|
-
{ ...node, level },
|
|
11
|
-
...(node.children ? flattenTree(node.children, level + 1) : [])
|
|
12
|
-
]);
|
|
8
|
+
import { useLayoutEventSubscription } from "../../../components/LayoutManager/Providers/LayoutEventProvider";
|
|
13
9
|
|
|
14
10
|
|
|
15
11
|
const FileEditor = () => {
|
|
16
12
|
const editorRef = useRef(null);
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
13
|
+
const parentIdRef = useRef(null);
|
|
14
|
+
|
|
15
|
+
useLayoutEventSubscription("file:selected", (event) => {
|
|
16
|
+
editorRef.current.addTab(event.payload);
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
useLayoutEventSubscription("drag:drop", (event) => {
|
|
20
|
+
const drop = event.payload;
|
|
21
21
|
if (!drop?.overId) {
|
|
22
22
|
return;
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
const activeType = drop.activeData.type;
|
|
26
26
|
const overType = drop.overData.type;
|
|
27
|
+
const activeParent = drop.activeData.parentId;
|
|
28
|
+
const overParent = drop.overData.parentId;
|
|
29
|
+
|
|
30
|
+
// Only drop files, not folders.
|
|
31
|
+
if (drop.activeData.node.type !== "file") {
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// TODO: This is a temporary solution while I switch to event based arch.
|
|
27
36
|
if (activeType === "EditorTab" && overType === "EditorTabGutter") {
|
|
28
|
-
|
|
29
|
-
|
|
37
|
+
if (activeParent === overParent) {
|
|
38
|
+
// Moving within same editor
|
|
39
|
+
if (overParent === parentIdRef.current) {
|
|
40
|
+
editorRef.current.moveTab(drop.activeData.node.uid, drop.overData.index);
|
|
41
|
+
}
|
|
42
|
+
} else {
|
|
43
|
+
// Moving between editors, need to remove the tab that was moved
|
|
44
|
+
if (overParent === parentIdRef.current) {
|
|
45
|
+
editorRef.current.addTab(drop.activeData.node, drop.overData.index);
|
|
46
|
+
} else if (activeParent === parentIdRef.current) {
|
|
47
|
+
editorRef.current.closeTab(drop.activeData.node.uid);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
} else if (activeType === "FileTreeNode" && overType === "EditorTabGutter" && overParent === parentIdRef.current) {
|
|
51
|
+
// Moving from fileTree to editor
|
|
30
52
|
editorRef.current.addTab(drop.activeData.node, drop.overData.index);
|
|
31
53
|
}
|
|
32
|
-
}
|
|
54
|
+
});
|
|
33
55
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
56
|
+
useEffect(() => {
|
|
57
|
+
parentIdRef.current = crypto.randomUUID();
|
|
58
|
+
editorRef.current.setTabGroupId(parentIdRef.current);
|
|
59
|
+
|
|
60
|
+
// This is only for demo purposes, I am randomly loading 2 files.
|
|
61
|
+
const files = flattenTree(fileTree.tree).filter((node) => node.type === "file");
|
|
62
|
+
for (let i = 0; i < 4; i++) {
|
|
63
|
+
editorRef.current.addTab(files[Math.floor(Math.random() * 2) + 1]);
|
|
64
|
+
}
|
|
41
65
|
}, []);
|
|
42
66
|
|
|
43
67
|
return (
|
|
44
|
-
<Editor
|
|
68
|
+
<Editor ref={editorRef} />
|
|
45
69
|
);
|
|
46
70
|
};
|
|
47
71
|
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Given a file tree, it flattens the tree into a list of nodes with the level of each node in the tree.
|
|
3
|
+
*
|
|
4
|
+
* @param {Array} tree - The file tree to flatten.
|
|
5
|
+
* @param {number} level - The current level of the tree (used for indentation).
|
|
6
|
+
* @return {Array} - The flattened tree with level information.
|
|
7
|
+
*/
|
|
8
|
+
export const flattenTree = (tree, level = 0) => {
|
|
9
|
+
if (!level) {
|
|
10
|
+
level = 0;
|
|
11
|
+
}
|
|
12
|
+
let rows = [];
|
|
13
|
+
for (let i = 0; i < tree.length; i++) {
|
|
14
|
+
const node = tree[i];
|
|
15
|
+
node.level = level;
|
|
16
|
+
rows.push(node);
|
|
17
|
+
if (node?.children) {
|
|
18
|
+
rows = rows.concat(flattenTree(node.children, level + 1));
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
return rows;
|
|
22
|
+
}
|
|
@@ -3,19 +3,25 @@ import { useRef, useLayoutEffect } from "react";
|
|
|
3
3
|
import { FileBrowser } from 'sample-ui-component-library';
|
|
4
4
|
import tree from "./workspace_sample.json"
|
|
5
5
|
|
|
6
|
+
import { useLayoutEventPublisher } from "../../../components/LayoutManager/Providers/LayoutEventProvider";
|
|
7
|
+
|
|
6
8
|
const FileTree = () => {
|
|
7
9
|
const fileBrowserRef = useRef(null);
|
|
10
|
+
const publish = useLayoutEventPublisher();
|
|
8
11
|
|
|
9
12
|
useLayoutEffect(() => {
|
|
10
13
|
fileBrowserRef.current.addFileTree(tree.tree);
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
}, 3000);
|
|
14
|
+
// setTimeout(() => {
|
|
15
|
+
// fileBrowserRef.current.selectNode("dir-f6459410-1634-4dbc-8d76-35896822158d");
|
|
16
|
+
// }, 3000);
|
|
15
17
|
}, []);
|
|
16
18
|
|
|
17
19
|
const onSelectFile = (node) => {
|
|
18
|
-
|
|
20
|
+
publish({
|
|
21
|
+
type: "file:selected",
|
|
22
|
+
payload: node,
|
|
23
|
+
source: "file-tree",
|
|
24
|
+
})
|
|
19
25
|
}
|
|
20
26
|
|
|
21
27
|
return (
|
|
@@ -1,87 +0,0 @@
|
|
|
1
|
-
import React, { createContext, useState, useCallback, useMemo } from "react";
|
|
2
|
-
|
|
3
|
-
const DragContext = createContext(null);
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Exposes the drag state through a hook. The state is updated
|
|
8
|
-
* by linking the drage events to dnd kit. The consuming appplication
|
|
9
|
-
* uses the hook and access the latest state. This will enable the
|
|
10
|
-
* consumer to react to drag start and over to preview interactions.
|
|
11
|
-
*
|
|
12
|
-
* TODO:
|
|
13
|
-
* In the initial implementation, the child components will use the
|
|
14
|
-
* useDrag hook and react to the state change on drop. However,
|
|
15
|
-
* eventually, I will modify it so that I only trigger the drop
|
|
16
|
-
* on the component in which it was dropped. For now, all the components
|
|
17
|
-
* will check to see if the drop was for them and ignore it if it isn't.
|
|
18
|
-
*/
|
|
19
|
-
export const DragProvider = ({ children }) => {
|
|
20
|
-
|
|
21
|
-
const [dragState, setDragState] = useState({
|
|
22
|
-
activeId: null,
|
|
23
|
-
activeData: null,
|
|
24
|
-
overId: null,
|
|
25
|
-
overData: null,
|
|
26
|
-
isDragging: false
|
|
27
|
-
});
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
const [drop, setDrop] = useState(null);
|
|
31
|
-
|
|
32
|
-
const handleDragStart = useCallback((event) => {
|
|
33
|
-
setDragState({
|
|
34
|
-
activeId: event.active?.id ?? null,
|
|
35
|
-
activeData: event.active?.data?.current ?? null,
|
|
36
|
-
overId: null,
|
|
37
|
-
overData: null,
|
|
38
|
-
isDragging: true
|
|
39
|
-
});
|
|
40
|
-
}, []);
|
|
41
|
-
|
|
42
|
-
const handleDragOver = useCallback((event) => {
|
|
43
|
-
setDragState((prev) => ({
|
|
44
|
-
...prev,
|
|
45
|
-
overId: event.over?.id ?? null,
|
|
46
|
-
overData: event.over?.data?.current ?? null,
|
|
47
|
-
}));
|
|
48
|
-
}, []);
|
|
49
|
-
|
|
50
|
-
const clearDrag = useCallback((event) => {
|
|
51
|
-
setDrop({
|
|
52
|
-
activeId: event.active?.id ?? null,
|
|
53
|
-
activeData: event.active?.data?.current ?? null,
|
|
54
|
-
overId: event.over?.id ?? null,
|
|
55
|
-
overData: event.over?.data?.current ?? null,
|
|
56
|
-
});
|
|
57
|
-
setDragState({
|
|
58
|
-
activeId: null,
|
|
59
|
-
activeData: null,
|
|
60
|
-
overId: null,
|
|
61
|
-
overData: null,
|
|
62
|
-
isDragging: false,
|
|
63
|
-
});
|
|
64
|
-
}, []);
|
|
65
|
-
|
|
66
|
-
const value = useMemo(() => ({
|
|
67
|
-
dragState,
|
|
68
|
-
drop,
|
|
69
|
-
handleDragStart,
|
|
70
|
-
handleDragOver,
|
|
71
|
-
clearDrag,
|
|
72
|
-
}), [dragState, drop, handleDragStart, handleDragOver, clearDrag]);
|
|
73
|
-
|
|
74
|
-
return (
|
|
75
|
-
<DragContext.Provider value={value}>
|
|
76
|
-
{children}
|
|
77
|
-
</DragContext.Provider>
|
|
78
|
-
);
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
export const useDragState = () => {
|
|
82
|
-
const ctx = React.useContext(DragContext);
|
|
83
|
-
if (!ctx) {
|
|
84
|
-
throw new Error("useDragState must be used inside DragProvider");
|
|
85
|
-
}
|
|
86
|
-
return ctx;
|
|
87
|
-
}
|