sample-ui-component-library 0.0.9-dev → 0.0.11-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/Editor/Editor.jsx +2 -2
- package/src/components/Editor/EditorReducer.js +16 -7
- package/src/components/Editor/Tabs/Tab/Tab.jsx +6 -3
- package/src/components/FileBrowser/FileBrowser.jsx +7 -1
- package/src/components/FileBrowser/FileBrowserReducer.js +5 -2
- package/src/components/FileBrowser/TreeNode/TreeNode.jsx +3 -2
- package/src/components/FileBrowser/helper.js +0 -12
- package/src/stories/Editor.stories.js +59 -16
- package/src/stories/FileBrowser.stories.js +38 -9
package/package.json
CHANGED
|
@@ -37,8 +37,8 @@ export const Editor = forwardRef(({ }, ref) => {
|
|
|
37
37
|
dispatch({ type: "MOVE_TAB", payload: { tabId, newIndex } });
|
|
38
38
|
}, []);
|
|
39
39
|
|
|
40
|
-
const addTab = useCallback((tab) => {
|
|
41
|
-
dispatch({ type: "ADD_TAB", payload: tab });
|
|
40
|
+
const addTab = useCallback((tab, index) => {
|
|
41
|
+
dispatch({ type: "ADD_TAB", payload: { tab, index } });
|
|
42
42
|
}, []);
|
|
43
43
|
|
|
44
44
|
const setTabGroupId = useCallback((id) => {
|
|
@@ -8,20 +8,29 @@ export const editorReducer = (state, action) => {
|
|
|
8
8
|
switch (action.type) {
|
|
9
9
|
|
|
10
10
|
case "ADD_TAB": {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
11
|
+
const { tab, index } = action.payload;
|
|
12
|
+
|
|
13
|
+
const tabInfo = state.tabs.find(obj => obj.uid === tab.uid);
|
|
14
|
+
if (tabInfo) {
|
|
15
|
+
console.warn(`Tab with id ${tabInfo.uid} already exists`);
|
|
15
16
|
return {
|
|
16
17
|
...state,
|
|
17
|
-
activeTab:
|
|
18
|
+
activeTab: tabInfo
|
|
18
19
|
};
|
|
19
20
|
}
|
|
20
21
|
|
|
22
|
+
// Insert tab at specific location if it was provided.
|
|
23
|
+
let tabs = [...state.tabs];
|
|
24
|
+
if (index !== undefined && index < state.tabs.length) {
|
|
25
|
+
tabs.splice(index, 0, tab);
|
|
26
|
+
} else {
|
|
27
|
+
tabs.push(tab);
|
|
28
|
+
}
|
|
29
|
+
|
|
21
30
|
return {
|
|
22
31
|
...state,
|
|
23
|
-
tabs:
|
|
24
|
-
activeTab:
|
|
32
|
+
tabs: tabs,
|
|
33
|
+
activeTab: tab
|
|
25
34
|
};
|
|
26
35
|
}
|
|
27
36
|
|
|
@@ -30,7 +30,8 @@ export const Tab = ({ id, parentId, node }) => {
|
|
|
30
30
|
data: {
|
|
31
31
|
type: "EditorTab",
|
|
32
32
|
parentId: parentId,
|
|
33
|
-
node: node
|
|
33
|
+
node: node,
|
|
34
|
+
preview: <TabPreview node={node} />
|
|
34
35
|
},
|
|
35
36
|
});
|
|
36
37
|
|
|
@@ -80,10 +81,12 @@ Tab.propTypes = {
|
|
|
80
81
|
}
|
|
81
82
|
|
|
82
83
|
|
|
83
|
-
export const TabPreview = ({
|
|
84
|
+
export const TabPreview = ({node}) => {
|
|
84
85
|
return (
|
|
85
86
|
<div className="tab" style={{ backgroundColor: ACTIVE_TAB_BG_COLOR, color: ACTIVE_TAB_FG_COLOR, opacity:0.5 }}>
|
|
86
|
-
<FileEarmark className="icon" />
|
|
87
|
+
<FileEarmark className="icon" />
|
|
88
|
+
<span className="tab-name">{node.name}</span>
|
|
89
|
+
<XLg className="close-icon"/>
|
|
87
90
|
</div>
|
|
88
91
|
);
|
|
89
92
|
}
|
|
@@ -5,6 +5,7 @@ import {
|
|
|
5
5
|
useCallback,
|
|
6
6
|
useContext,
|
|
7
7
|
useImperativeHandle,
|
|
8
|
+
useEffect,
|
|
8
9
|
} from "react";
|
|
9
10
|
import "./FileBrowser.scss";
|
|
10
11
|
|
|
@@ -20,13 +21,18 @@ import { fileBrowserReducer, initialState } from "./FileBrowserReducer";
|
|
|
20
21
|
*
|
|
21
22
|
* @return {JSX}
|
|
22
23
|
*/
|
|
23
|
-
export const FileBrowser = forwardRef(({
|
|
24
|
+
export const FileBrowser = forwardRef(({onSelectFile}, ref) => {
|
|
24
25
|
const [state, dispatch] = useReducer(fileBrowserReducer, initialState);
|
|
25
26
|
|
|
26
27
|
const addFileTree = useCallback((tree) => {
|
|
27
28
|
dispatch({ type: "ADD_FILE_TREE", payload: tree });
|
|
28
29
|
}, []);
|
|
29
30
|
|
|
31
|
+
useEffect(() => {
|
|
32
|
+
if (state.selectedNode && state.selectedNode.type === "file") {
|
|
33
|
+
onSelectFile(state.selectedNode);
|
|
34
|
+
}
|
|
35
|
+
}, [state.selectedNode]);
|
|
30
36
|
|
|
31
37
|
const selectNode = useCallback((node) => {
|
|
32
38
|
dispatch({ type: "SELECT_NODE", payload: node });
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import {
|
|
2
2
|
setDefaultCollapsed,
|
|
3
3
|
collapseTree,
|
|
4
|
-
selectNode,
|
|
5
4
|
flattenTree,
|
|
6
5
|
} from "./helper";
|
|
7
6
|
|
|
8
7
|
export const initialState = {
|
|
9
8
|
tree: {},
|
|
10
9
|
flattenedTree: {},
|
|
10
|
+
selectedNode: null,
|
|
11
11
|
collapsedTree: [],
|
|
12
12
|
};
|
|
13
13
|
|
|
@@ -28,8 +28,10 @@ export const fileBrowserReducer = (state, action) => {
|
|
|
28
28
|
|
|
29
29
|
case "SELECT_NODE": {
|
|
30
30
|
const tree = [...state.flattenedTree];
|
|
31
|
+
let selectedNode;
|
|
31
32
|
tree.forEach((n) => {
|
|
32
33
|
if (n.uid === action.payload) {
|
|
34
|
+
selectedNode = n;
|
|
33
35
|
n.selected = true;
|
|
34
36
|
n.collapsed = !n.collapsed;
|
|
35
37
|
} else {
|
|
@@ -40,7 +42,8 @@ export const fileBrowserReducer = (state, action) => {
|
|
|
40
42
|
return {
|
|
41
43
|
...state,
|
|
42
44
|
flattenedTree: tree,
|
|
43
|
-
collapsedTree: collapsedTree
|
|
45
|
+
collapsedTree: collapsedTree,
|
|
46
|
+
selectedNode: selectedNode
|
|
44
47
|
}
|
|
45
48
|
}
|
|
46
49
|
}
|
|
@@ -23,7 +23,8 @@ export const TreeNode = ({ id, node }) => {
|
|
|
23
23
|
id,
|
|
24
24
|
data: {
|
|
25
25
|
type: "FileTreeNode",
|
|
26
|
-
node: node
|
|
26
|
+
node: node,
|
|
27
|
+
preview: <TreeNodePreview node={node}/ >
|
|
27
28
|
}
|
|
28
29
|
}
|
|
29
30
|
);
|
|
@@ -95,7 +96,7 @@ export const TreeNode = ({ id, node }) => {
|
|
|
95
96
|
|
|
96
97
|
export const TreeNodePreview = ({node}) => {
|
|
97
98
|
return (
|
|
98
|
-
<div className="file-node-row">
|
|
99
|
+
<div className="file-node-row" >
|
|
99
100
|
<span className="file-name">{node.name}</span>
|
|
100
101
|
</div>
|
|
101
102
|
);
|
|
@@ -8,7 +8,6 @@ export const setDefaultCollapsed = (tree) => {
|
|
|
8
8
|
return tree;
|
|
9
9
|
}
|
|
10
10
|
|
|
11
|
-
|
|
12
11
|
/**
|
|
13
12
|
* Given a file tree, it flattens the tree into a list of nodes with the level of each node in the tree.
|
|
14
13
|
*
|
|
@@ -58,14 +57,3 @@ export const collapseTree = (tree) => {
|
|
|
58
57
|
}
|
|
59
58
|
return rows;
|
|
60
59
|
}
|
|
61
|
-
|
|
62
|
-
/**
|
|
63
|
-
* Selects the given node and deselects all other nodes in the tree.
|
|
64
|
-
*/
|
|
65
|
-
export const selectNode = (tree, node) => {
|
|
66
|
-
tree.forEach((n) => {
|
|
67
|
-
n.selected = false;
|
|
68
|
-
});
|
|
69
|
-
node.selected = true;
|
|
70
|
-
node.collapsed = !node.collapsed;
|
|
71
|
-
}
|
|
@@ -51,31 +51,65 @@ const Template = (args) => {
|
|
|
51
51
|
editorRef.current.addTab(node);
|
|
52
52
|
}
|
|
53
53
|
});
|
|
54
|
-
}, []);
|
|
55
54
|
|
|
56
|
-
const onDragStart = (event) => {
|
|
57
|
-
console.log("");
|
|
58
|
-
console.log("Drag Started");
|
|
59
|
-
const dragPreview = editorRef.current.getPreviewElement(event.active.data.current.node.uid);
|
|
60
|
-
setDragPreviewLabel(dragPreview);
|
|
61
|
-
}
|
|
62
55
|
|
|
56
|
+
const node = {
|
|
57
|
+
"name": "SAMPLE",
|
|
58
|
+
"type": "file",
|
|
59
|
+
"uid": "dissr-f6459410-1634-4dbc-8d76-35896822158d",
|
|
60
|
+
"content": "1234"
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
editorRef.current.addTab(node,2);
|
|
64
|
+
}, []);
|
|
65
|
+
|
|
66
|
+
const [dragging, setDragging] = useState(false);
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Callback for when drag ends.
|
|
70
|
+
*/
|
|
63
71
|
const handleDragEnd = (event) =>{
|
|
64
72
|
const { active, over } = event;
|
|
73
|
+
console.log("Drag Ended");
|
|
74
|
+
const rect = event.activatorEvent;
|
|
75
|
+
|
|
76
|
+
console.log(active, over);
|
|
65
77
|
|
|
66
78
|
if (over) {
|
|
67
|
-
console.log("Dragged item:", active);
|
|
68
|
-
console.log("Dropped on:", over);
|
|
79
|
+
console.log("Dragged item:", active.id);
|
|
80
|
+
console.log("Dropped on:", over.id);
|
|
69
81
|
} else {
|
|
70
82
|
console.log("Dropped outside any droppable");
|
|
71
|
-
return;
|
|
72
83
|
}
|
|
84
|
+
setDragging(false);
|
|
85
|
+
}
|
|
73
86
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
87
|
+
/**
|
|
88
|
+
* Callback for when drag is started.
|
|
89
|
+
*/
|
|
90
|
+
const onDragStart = (event) => {
|
|
91
|
+
console.log("Drag Started");
|
|
92
|
+
console.log(event.active.data);
|
|
93
|
+
setDragPreviewLabel(event.active.data.current.preview);
|
|
94
|
+
setDragging(true);
|
|
77
95
|
}
|
|
78
96
|
|
|
97
|
+
// Manually track the drag position.
|
|
98
|
+
const [pos, setPos] = useState({ x: 0, y: 0 });
|
|
99
|
+
useEffect(() => {
|
|
100
|
+
if (!dragging) return;
|
|
101
|
+
|
|
102
|
+
const handleMove = (e) => {
|
|
103
|
+
setPos({ x: e.clientX, y: e.clientY });
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
window.addEventListener("pointermove", handleMove);
|
|
107
|
+
|
|
108
|
+
return () => {
|
|
109
|
+
window.removeEventListener("pointermove", handleMove);
|
|
110
|
+
};
|
|
111
|
+
}, [dragging]);
|
|
112
|
+
|
|
79
113
|
const sensors = useSensors(
|
|
80
114
|
useSensor(PointerSensor, {
|
|
81
115
|
activationConstraint: {
|
|
@@ -89,9 +123,18 @@ const Template = (args) => {
|
|
|
89
123
|
<div className="editorStoryWrapper">
|
|
90
124
|
<Editor ref={editorRef}{...args} />
|
|
91
125
|
</div>
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
126
|
+
{dragging && (
|
|
127
|
+
<div
|
|
128
|
+
style={{
|
|
129
|
+
position: "fixed",
|
|
130
|
+
left: pos.x,
|
|
131
|
+
top: pos.y,
|
|
132
|
+
pointerEvents: "none",
|
|
133
|
+
zIndex: 9999,
|
|
134
|
+
}}>
|
|
135
|
+
{dragPreviewLabel}
|
|
136
|
+
</div>
|
|
137
|
+
)}
|
|
95
138
|
</DndContext>
|
|
96
139
|
)
|
|
97
140
|
}
|
|
@@ -39,23 +39,24 @@ const Template = (args) => {
|
|
|
39
39
|
|
|
40
40
|
const [dragPreviewLabel, setDragPreviewLabel] = useState(<></>);
|
|
41
41
|
|
|
42
|
-
const
|
|
42
|
+
const onSelectFile = (selectedFile) => {
|
|
43
43
|
action('Selected Node:')(selectedFile);
|
|
44
44
|
}
|
|
45
45
|
|
|
46
46
|
useEffect(() => {
|
|
47
|
-
updateArgs({
|
|
47
|
+
updateArgs({onSelectFile : onSelectFile});
|
|
48
48
|
}, []);
|
|
49
49
|
|
|
50
|
-
|
|
51
50
|
useLayoutEffect(() => {
|
|
52
51
|
fileBrowserRef.current.addFileTree(args.tree);
|
|
53
|
-
|
|
54
52
|
setTimeout(() => {
|
|
55
53
|
fileBrowserRef.current.selectNode("dir-f6459410-1634-4dbc-8d76-35896822158d");
|
|
56
54
|
}, 3000);
|
|
57
55
|
}, []);
|
|
58
56
|
|
|
57
|
+
|
|
58
|
+
const [dragging, setDragging] = useState(false);
|
|
59
|
+
|
|
59
60
|
/**
|
|
60
61
|
* Callback for when drag ends.
|
|
61
62
|
*/
|
|
@@ -64,7 +65,7 @@ const Template = (args) => {
|
|
|
64
65
|
console.log("Drag Ended");
|
|
65
66
|
const rect = event.activatorEvent;
|
|
66
67
|
|
|
67
|
-
console.log(over
|
|
68
|
+
console.log(active, over);
|
|
68
69
|
|
|
69
70
|
if (over) {
|
|
70
71
|
console.log("Dragged item:", active.id);
|
|
@@ -72,6 +73,7 @@ const Template = (args) => {
|
|
|
72
73
|
} else {
|
|
73
74
|
console.log("Dropped outside any droppable");
|
|
74
75
|
}
|
|
76
|
+
setDragging(false);
|
|
75
77
|
}
|
|
76
78
|
|
|
77
79
|
/**
|
|
@@ -79,10 +81,28 @@ const Template = (args) => {
|
|
|
79
81
|
*/
|
|
80
82
|
const onDragStart = (event) => {
|
|
81
83
|
console.log("Drag Started");
|
|
84
|
+
console.log(event.active.data);
|
|
82
85
|
const dragPreview = fileBrowserRef.current.getPreviewElement(event.active.data.current.node.uid);
|
|
83
|
-
setDragPreviewLabel(
|
|
86
|
+
setDragPreviewLabel(event.active.data.current.preview);
|
|
87
|
+
setDragging(true);
|
|
84
88
|
}
|
|
85
89
|
|
|
90
|
+
// Manually track the drag position.
|
|
91
|
+
const [pos, setPos] = useState({ x: 0, y: 0 });
|
|
92
|
+
useEffect(() => {
|
|
93
|
+
if (!dragging) return;
|
|
94
|
+
|
|
95
|
+
const handleMove = (e) => {
|
|
96
|
+
setPos({ x: e.clientX, y: e.clientY });
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
window.addEventListener("pointermove", handleMove);
|
|
100
|
+
|
|
101
|
+
return () => {
|
|
102
|
+
window.removeEventListener("pointermove", handleMove);
|
|
103
|
+
};
|
|
104
|
+
}, [dragging]);
|
|
105
|
+
|
|
86
106
|
const sensors = useSensors(
|
|
87
107
|
useSensor(PointerSensor, {
|
|
88
108
|
activationConstraint: {
|
|
@@ -98,9 +118,18 @@ const Template = (args) => {
|
|
|
98
118
|
<FileBrowser ref={fileBrowserRef} {...args} />
|
|
99
119
|
</div>
|
|
100
120
|
</div>
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
121
|
+
{dragging && (
|
|
122
|
+
<div
|
|
123
|
+
style={{
|
|
124
|
+
position: "fixed",
|
|
125
|
+
left: pos.x,
|
|
126
|
+
top: pos.y,
|
|
127
|
+
pointerEvents: "none",
|
|
128
|
+
zIndex: 9999,
|
|
129
|
+
}}>
|
|
130
|
+
{dragPreviewLabel}
|
|
131
|
+
</div>
|
|
132
|
+
)}
|
|
104
133
|
</DndContext>
|
|
105
134
|
)
|
|
106
135
|
}
|