ui-layout-manager-dev 0.0.18 → 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.
Files changed (34) hide show
  1. package/dist/cjs/index.js +3 -3
  2. package/dist/cjs/index.js.map +1 -1
  3. package/dist/esm/Worker/LayoutWorker.js +38 -1
  4. package/dist/esm/index.js +3 -3
  5. package/dist/esm/index.js.map +1 -1
  6. package/package.json +3 -3
  7. package/src/components/LayoutManager/Components/Container/Container.jsx +1 -1
  8. package/src/components/LayoutManager/Components/HandleBar/HandleBar.jsx +6 -16
  9. package/src/components/LayoutManager/Components/LazyLoader/LazyLoader.js +74 -9
  10. package/src/components/LayoutManager/Components/LazyLoader/LazyLoader.scss +38 -1
  11. package/src/components/LayoutManager/Components/LazyLoader/MenuBar/MenuBar.js +40 -0
  12. package/src/components/LayoutManager/Components/LazyLoader/MenuBar/MenuBar.scss +22 -0
  13. package/src/components/LayoutManager/Components/LazyLoader/Tabs/Tabs.js +51 -0
  14. package/src/components/LayoutManager/Components/LazyLoader/Tabs/Tabs.scss +34 -0
  15. package/src/components/LayoutManager/Components/RootContainer/DragController.js +79 -0
  16. package/src/components/LayoutManager/Components/RootContainer/RootContainer.jsx +21 -21
  17. package/src/components/LayoutManager/Components/RootContainer/RootContainer.scss +1 -0
  18. package/src/components/LayoutManager/Controller/LAYOUT_WORKER_PROTOCOL.js +2 -1
  19. package/src/components/LayoutManager/Controller/LayoutController.js +14 -0
  20. package/src/components/LayoutManager/Controller/LayoutEventController.js +55 -0
  21. package/src/components/LayoutManager/Controller/Worker/HandleRulesEnforcer.js +4 -0
  22. package/src/components/LayoutManager/Controller/Worker/LayoutEditor.js +29 -0
  23. package/src/components/LayoutManager/Controller/Worker/LayoutWorker.js +3 -0
  24. package/src/components/LayoutManager/LayoutManager.jsx +5 -5
  25. package/src/components/LayoutManager/Providers/LayoutEventProvider.js +55 -0
  26. package/src/components/LayoutManager/index.js +1 -2
  27. package/src/stories/LayoutManager.stories.js +17 -0
  28. package/src/stories/layouts/vsCode/workbench.json +22 -5
  29. package/src/stories/layouts/vsCode/workbench2.json +176 -0
  30. package/src/stories/layouts/vsCode/workbench3.json +176 -0
  31. package/src/stories/sample_components/fileeditor/FileEditor.jsx +45 -21
  32. package/src/stories/sample_components/fileeditor/helper.js +22 -0
  33. package/src/stories/sample_components/filetree/FileTree.jsx +11 -5
  34. 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 { useDragState } from "../../../components/LayoutManager/Providers/DragProvider";
6
+ import { flattenTree } from "./helper";
7
7
 
8
- const flattenTree = (tree, level = 0) =>
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
- const { drop } = useDragState();
19
-
20
- useEffect(() => {
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
- editorRef.current.moveTab(drop.activeData.node.uid, drop.overData.index);
29
- } else if (activeType === "FileTreeNode" && overType === "EditorTabGutter") {
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
- }, [drop]);
54
+ });
33
55
 
34
- useLayoutEffect(() => {
35
- editorRef.current.setTabGroupId("tab-group-1");
36
- flattenTree(fileTree.tree).forEach((node) => {
37
- if (node.type === "file") {
38
- editorRef.current.addTab(node);
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 ref={editorRef} />
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
- setTimeout(() => {
13
- fileBrowserRef.current.selectNode("dir-f6459410-1634-4dbc-8d76-35896822158d");
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
- console.log("Selected Node:", node);
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
- }