sample-ui-component-library 0.0.6-beta → 0.0.7-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 +7 -7
- package/dist/cjs/index.js.map +1 -1
- package/dist/esm/index.js +7 -7
- package/dist/esm/index.js.map +1 -1
- package/package.json +2 -1
- package/rollup.config.mjs +1 -1
- package/src/components/Editor/Editor.jsx +59 -0
- package/src/components/Editor/Editor.scss +17 -0
- package/src/components/Editor/EditorTabs/EditorTabs.jsx +93 -0
- package/src/components/Editor/EditorTabs/EditorTabs.scss +33 -0
- package/src/components/Editor/MonacoInstance/MonacoInstance.jsx +66 -0
- package/src/components/Editor/MonacoInstance/MonacoInstance.scss +0 -0
- package/src/components/Editor/index.js +1 -0
- package/src/components/FileBrowser/FileBrowser.jsx +13 -4
- package/src/components/FileBrowser/FileBrowser.scss +0 -1
- package/src/index.js +2 -1
- package/src/stories/Editor.stories.js +117 -0
- package/src/stories/EditorStories.scss +7 -0
- package/src/stories/FileBrowser.stories.js +83 -4
- package/src/stories/FileBrowserStories.scss +1 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sample-ui-component-library",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.7-dev",
|
|
4
4
|
"description": "A library which contains sample UI elements that can be used for populating layouts.",
|
|
5
5
|
"main": "dist/cjs/index.js",
|
|
6
6
|
"module": "dist/esm/index.js",
|
|
@@ -58,6 +58,7 @@
|
|
|
58
58
|
"style-loader": "^4.0.0"
|
|
59
59
|
},
|
|
60
60
|
"peerDependencies": {
|
|
61
|
+
"@dnd-kit/core": "^6.3.1",
|
|
61
62
|
"react": "^18.2.0",
|
|
62
63
|
"react-dom": "^18.2.0"
|
|
63
64
|
},
|
package/rollup.config.mjs
CHANGED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import "./Editor.scss";
|
|
2
|
+
import PropTypes from 'prop-types';
|
|
3
|
+
|
|
4
|
+
import { MonacoInstance } from "./MonacoInstance/MonacoInstance";
|
|
5
|
+
import { EditorTabs } from "./EditorTabs/EditorTabs";
|
|
6
|
+
import { useEffect, useState } from "react";
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Renders the editor component with support for tabs.
|
|
10
|
+
*
|
|
11
|
+
* @return {JSX}
|
|
12
|
+
*/
|
|
13
|
+
export const Editor = ({systemTree, onFileSelect}) => {
|
|
14
|
+
|
|
15
|
+
const [editorContent, setEditorContent] = useState("asdf");
|
|
16
|
+
|
|
17
|
+
const [activeTab, setActiveTab] = useState();
|
|
18
|
+
const [tabs, setTabs] = useState([
|
|
19
|
+
{ id: "tab1", label: "Tab 1" },
|
|
20
|
+
{ id: "tab2", label: "Tab 2" },
|
|
21
|
+
{ id: "tab3", label: "Tab 3" },
|
|
22
|
+
]);
|
|
23
|
+
|
|
24
|
+
useEffect(() => {
|
|
25
|
+
if (activeTab) {
|
|
26
|
+
setEditorContent(activeTab.label);
|
|
27
|
+
}
|
|
28
|
+
}, [activeTab]);
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
useEffect(() => {
|
|
32
|
+
if (tabs) {
|
|
33
|
+
if ((activeTab && activeTab > tabs.length) || activeTab == null) {
|
|
34
|
+
setActiveTab(tabs[tabs.length - 1]);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}, [tabs]);
|
|
38
|
+
|
|
39
|
+
const onTabClick = (event) => {
|
|
40
|
+
const tab = tabs.find(obj => obj.id === event.target.id);
|
|
41
|
+
setActiveTab(tab);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
return (
|
|
45
|
+
<div className="editorContainer">
|
|
46
|
+
<div className="tabContainer">
|
|
47
|
+
<EditorTabs activeTab={activeTab} tabs={tabs} selectTab={onTabClick} />
|
|
48
|
+
</div>
|
|
49
|
+
<div className="monacoContainer">
|
|
50
|
+
<MonacoInstance editorContent={editorContent}/>
|
|
51
|
+
</div>
|
|
52
|
+
</div>
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
Editor.propTypes = {
|
|
57
|
+
systemTree: PropTypes.object,
|
|
58
|
+
onFileSelect: PropTypes.func
|
|
59
|
+
}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import "./EditorTabs.scss";
|
|
2
|
+
import PropTypes from "prop-types";
|
|
3
|
+
|
|
4
|
+
import { useEffect, useState } from "react";
|
|
5
|
+
import { FileEarmark } from "react-bootstrap-icons";
|
|
6
|
+
import {
|
|
7
|
+
useDraggable,
|
|
8
|
+
useDroppable,
|
|
9
|
+
} from "@dnd-kit/core";
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Tab Component
|
|
13
|
+
* @param {String} id
|
|
14
|
+
* @param {String} label
|
|
15
|
+
* @returns
|
|
16
|
+
*/
|
|
17
|
+
function Tab({id, label, onSelectTab, activeTab}) {
|
|
18
|
+
const { attributes, listeners, setNodeRef, transform } = useDraggable({id});
|
|
19
|
+
|
|
20
|
+
const [tabStyle, setTabStyle] = useState();
|
|
21
|
+
|
|
22
|
+
useEffect(() => {
|
|
23
|
+
const bc = (activeTab && activeTab.id === id) ? "#1e1e1e": "#2d2d2d";
|
|
24
|
+
const fc = (activeTab && activeTab.id === id) ? "#FFFFFF": "#969690";
|
|
25
|
+
setTabStyle( {"backgroundColor": bc, "color": fc})
|
|
26
|
+
}, [activeTab]);
|
|
27
|
+
|
|
28
|
+
return (
|
|
29
|
+
<div ref={setNodeRef} style={tabStyle} id={id} onClick={onSelectTab} className="tab" {...listeners} {...attributes}>
|
|
30
|
+
<FileEarmark className="icon" style={{ pointerEvents: "none" }}/>{label}
|
|
31
|
+
</div>
|
|
32
|
+
);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Tab Gutter Component
|
|
37
|
+
* @param {String} id
|
|
38
|
+
* @returns
|
|
39
|
+
*/
|
|
40
|
+
function Gutter({id}) {
|
|
41
|
+
const { setNodeRef, isOver } = useDroppable({id});
|
|
42
|
+
return (
|
|
43
|
+
<div
|
|
44
|
+
className="gutter"
|
|
45
|
+
ref={setNodeRef}
|
|
46
|
+
style={{background: isOver ? "white" : "#222425"}}
|
|
47
|
+
></div>
|
|
48
|
+
);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Tabs component.
|
|
53
|
+
* @param {Object} activeTab
|
|
54
|
+
* @param {Array} tabs
|
|
55
|
+
* @returns
|
|
56
|
+
*/
|
|
57
|
+
export const EditorTabs = ({activeTab, tabs, selectTab}) => {
|
|
58
|
+
|
|
59
|
+
const [tabsList, setTabsList] = useState();
|
|
60
|
+
|
|
61
|
+
useEffect(() => {
|
|
62
|
+
if (tabs) {
|
|
63
|
+
drawTabs();
|
|
64
|
+
}
|
|
65
|
+
}, [tabs]);
|
|
66
|
+
|
|
67
|
+
useEffect(() => {
|
|
68
|
+
if (activeTab) {
|
|
69
|
+
drawTabs();
|
|
70
|
+
}
|
|
71
|
+
}, [activeTab]);
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
const drawTabs = () => {
|
|
75
|
+
const list = [];
|
|
76
|
+
tabs.forEach((tab, index) => {
|
|
77
|
+
list.push(<Gutter id={"position-" + index} />);
|
|
78
|
+
list.push(
|
|
79
|
+
<Tab activeTab={activeTab} onSelectTab={selectTab} key={tab.id} {...tab} />
|
|
80
|
+
);
|
|
81
|
+
})
|
|
82
|
+
list.push(<Gutter id={"position-" + tabs.length} />);
|
|
83
|
+
setTabsList(list);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
return (
|
|
87
|
+
<div style={{ display: "flex", background: "#222425" }}>
|
|
88
|
+
{tabsList}
|
|
89
|
+
</div>
|
|
90
|
+
);
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
EditorTabs.propTypes = {};
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
.tabs {
|
|
2
|
+
position:relative;
|
|
3
|
+
display: flex;
|
|
4
|
+
flex-direction: row;
|
|
5
|
+
background-color: #1e1e1e;
|
|
6
|
+
height: 40px;
|
|
7
|
+
width: 100%;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
.tab {
|
|
11
|
+
padding: 0px 20px;
|
|
12
|
+
background-color: #2d2d2d;
|
|
13
|
+
color: #969690;
|
|
14
|
+
cursor: pointer;
|
|
15
|
+
height: 40px;
|
|
16
|
+
display:flex;
|
|
17
|
+
align-items: center;
|
|
18
|
+
font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
|
|
19
|
+
font-size:14px;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
.tab > .icon {
|
|
23
|
+
padding-right: 7px;
|
|
24
|
+
display:flex;
|
|
25
|
+
align-items: center;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
.gutter {
|
|
29
|
+
display:flex;
|
|
30
|
+
background-color: #2d2d2d;
|
|
31
|
+
height: 40px;
|
|
32
|
+
width: 2px;
|
|
33
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import React, { useEffect, useRef, useState } from 'react';
|
|
2
|
+
import PropTypes from 'prop-types';
|
|
3
|
+
|
|
4
|
+
import Editor from '@monaco-editor/react';
|
|
5
|
+
|
|
6
|
+
import "./MonacoInstance.scss"
|
|
7
|
+
|
|
8
|
+
function Gutter({ id }) {
|
|
9
|
+
const { setNodeRef, isOver } = useDroppable({
|
|
10
|
+
id,
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
return (
|
|
14
|
+
<div
|
|
15
|
+
ref={setNodeRef}
|
|
16
|
+
style={{
|
|
17
|
+
height: 40,
|
|
18
|
+
width: 1,
|
|
19
|
+
background: isOver ? "white" : "#4da3ff33",
|
|
20
|
+
display: "flex",
|
|
21
|
+
alignItems: "center",
|
|
22
|
+
justifyContent: "center"
|
|
23
|
+
}}
|
|
24
|
+
></div>
|
|
25
|
+
);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export const MonacoInstance = ({editorContent}) => {
|
|
29
|
+
const editorRef = useRef(null);
|
|
30
|
+
|
|
31
|
+
const content = useRef();
|
|
32
|
+
|
|
33
|
+
const handleEditorDidMount = (editor, monaco) => {
|
|
34
|
+
editorRef.current = editor;
|
|
35
|
+
if(content?.current) {
|
|
36
|
+
editorRef.current.setValue(content.current);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
useEffect(() => {
|
|
41
|
+
content.current = editorContent;
|
|
42
|
+
if (editorRef?.current && content.current) {
|
|
43
|
+
editorRef.current.setValue(content.current);
|
|
44
|
+
}
|
|
45
|
+
}, [editorContent]);
|
|
46
|
+
|
|
47
|
+
return (
|
|
48
|
+
<Editor
|
|
49
|
+
defaultLanguage="python"
|
|
50
|
+
defaultValue=""
|
|
51
|
+
onMount={handleEditorDidMount}
|
|
52
|
+
theme="vs-dark"
|
|
53
|
+
options={{
|
|
54
|
+
scrollBeyondLastLine:false,
|
|
55
|
+
fontSize:"12px",
|
|
56
|
+
minimap: {
|
|
57
|
+
enabled: false
|
|
58
|
+
}
|
|
59
|
+
}}
|
|
60
|
+
/>
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
MonacoInstance.propTypes = {
|
|
65
|
+
editorContent: PropTypes.string,
|
|
66
|
+
}
|
|
File without changes
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./Editor.jsx"
|
|
@@ -5,6 +5,12 @@ import { setDefaultCollapsed, collapseTree, selectNode, flattenTree } from "./he
|
|
|
5
5
|
|
|
6
6
|
import { FileCode, ChevronRight, ChevronDown, Braces, FiletypeScss, FiletypeJs, FiletypePy} from "react-bootstrap-icons";
|
|
7
7
|
import PropTypes from 'prop-types';
|
|
8
|
+
import {
|
|
9
|
+
DndContext,
|
|
10
|
+
DragOverlay,
|
|
11
|
+
useDraggable,
|
|
12
|
+
useDroppable,
|
|
13
|
+
} from "@dnd-kit/core";
|
|
8
14
|
|
|
9
15
|
const INDENT_WIDTH = 20;
|
|
10
16
|
const SELECTED_FILE_COLOR = "#00426b";
|
|
@@ -27,7 +33,8 @@ function useEvent(fn) {
|
|
|
27
33
|
/**
|
|
28
34
|
* Renders a single node in the file tree.
|
|
29
35
|
*/
|
|
30
|
-
const TreeNode = ({node, onRowClick}) => {
|
|
36
|
+
const TreeNode = ({id, node, onRowClick}) => {
|
|
37
|
+
const { attributes, listeners, setNodeRef, transform } = useDraggable({id});
|
|
31
38
|
/**
|
|
32
39
|
* Gets the appropriate icon for the node based on its type and collapsed state.
|
|
33
40
|
* @returns <JSX>
|
|
@@ -44,9 +51,11 @@ const TreeNode = ({node, onRowClick}) => {
|
|
|
44
51
|
* Sets the background color of the row if the node is selected.
|
|
45
52
|
*/
|
|
46
53
|
const getRowStyle = () => {
|
|
54
|
+
const style = {};
|
|
47
55
|
if (node.selected) {
|
|
48
|
-
|
|
56
|
+
style["backgroundColor"] = SELECTED_FILE_COLOR;
|
|
49
57
|
}
|
|
58
|
+
return style;
|
|
50
59
|
}
|
|
51
60
|
|
|
52
61
|
|
|
@@ -72,7 +81,7 @@ const TreeNode = ({node, onRowClick}) => {
|
|
|
72
81
|
}
|
|
73
82
|
|
|
74
83
|
return (
|
|
75
|
-
<div className="file-node-row" style={getRowStyle()} onClick={() => onRowClick(node)}>
|
|
84
|
+
<div className="file-node-row" ref={setNodeRef} {...listeners} {...attributes} style={getRowStyle()} onClick={() => onRowClick(node)}>
|
|
76
85
|
<div className="indent" style={{ width: node.level * INDENT_WIDTH + "px"}} />
|
|
77
86
|
{
|
|
78
87
|
node.type === "folder" ?
|
|
@@ -115,7 +124,7 @@ export const FileBrowser = ({tree, onNodeSelect}) => {
|
|
|
115
124
|
const nodes = collapseTree(treeRef.current);
|
|
116
125
|
const rows = [];
|
|
117
126
|
nodes.forEach((node) => {
|
|
118
|
-
rows.push(<TreeNode key={node.id} node={node} onRowClick={handleFileClick}/>);
|
|
127
|
+
rows.push(<TreeNode key={node.id} node={node} id={node.name} onRowClick={handleFileClick}/>);
|
|
119
128
|
});
|
|
120
129
|
setNodes(rows);
|
|
121
130
|
}
|
package/src/index.js
CHANGED
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { useEffect } from "react";
|
|
2
|
+
import { Editor } from "../components/Editor";
|
|
3
|
+
import { useArgs } from "@storybook/preview-api";
|
|
4
|
+
import { action } from "@storybook/addon-actions";
|
|
5
|
+
import {
|
|
6
|
+
DndContext,
|
|
7
|
+
DragOverlay,
|
|
8
|
+
useDraggable,
|
|
9
|
+
useDroppable,
|
|
10
|
+
PointerSensor,
|
|
11
|
+
useSensor,
|
|
12
|
+
useSensors
|
|
13
|
+
} from "@dnd-kit/core";
|
|
14
|
+
|
|
15
|
+
import fileTrees from "./data/filetree.json";
|
|
16
|
+
|
|
17
|
+
import "./EditorStories.scss"
|
|
18
|
+
|
|
19
|
+
export default {
|
|
20
|
+
title: 'Editor',
|
|
21
|
+
component: Editor,
|
|
22
|
+
argTypes: {}
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Preview for the div being dragged.
|
|
27
|
+
* @returns
|
|
28
|
+
*/
|
|
29
|
+
function DragPreview({ label }) {
|
|
30
|
+
return (
|
|
31
|
+
<div
|
|
32
|
+
style={{
|
|
33
|
+
padding: "6px 12px",
|
|
34
|
+
background: "#2d2d2d",
|
|
35
|
+
color: "white",
|
|
36
|
+
boxShadow: "0 4px 12px rgba(0,0,0,0.3)",
|
|
37
|
+
opacity:0.3
|
|
38
|
+
}}
|
|
39
|
+
>
|
|
40
|
+
{label}
|
|
41
|
+
</div>
|
|
42
|
+
);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Offset for the drag overlay.
|
|
47
|
+
* @returns
|
|
48
|
+
*/
|
|
49
|
+
const offsetOverlay = ({ transform }) => {
|
|
50
|
+
return {
|
|
51
|
+
...transform,
|
|
52
|
+
x: transform.x + 20,
|
|
53
|
+
y: transform.y + 20
|
|
54
|
+
};
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
const Template = (args) => {
|
|
58
|
+
const [, updateArgs] = useArgs();
|
|
59
|
+
|
|
60
|
+
const onFileSelect = (selectedFile) => {
|
|
61
|
+
action('Selected Stack Position:')(selectedFile);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
useEffect(() => {
|
|
65
|
+
updateArgs({onFileSelect : onFileSelect});
|
|
66
|
+
}, []);
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Callback for when drag ends.
|
|
70
|
+
*/
|
|
71
|
+
const handleDragEnd = (event) =>{
|
|
72
|
+
const { active, over } = event;
|
|
73
|
+
console.log("Drag Ended");
|
|
74
|
+
const rect = event.activatorEvent;
|
|
75
|
+
|
|
76
|
+
console.log(over );
|
|
77
|
+
|
|
78
|
+
if (over) {
|
|
79
|
+
console.log("Dragged item:", active.id);
|
|
80
|
+
console.log("Dropped on:", over.id);
|
|
81
|
+
} else {
|
|
82
|
+
console.log("Dropped outside any droppable");
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Callback for when drag is started.
|
|
88
|
+
*/
|
|
89
|
+
const onDragStart = (event) => {
|
|
90
|
+
console.log("Drag Started");
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
const sensors = useSensors(
|
|
94
|
+
useSensor(PointerSensor, {
|
|
95
|
+
activationConstraint: {
|
|
96
|
+
distance: 8
|
|
97
|
+
}
|
|
98
|
+
})
|
|
99
|
+
);
|
|
100
|
+
|
|
101
|
+
return (
|
|
102
|
+
<DndContext sensors={sensors} onDragStart={onDragStart} onDragEnd={handleDragEnd}>
|
|
103
|
+
<div className="editorStoryWrapper">
|
|
104
|
+
<Editor {...args} />
|
|
105
|
+
</div>
|
|
106
|
+
<DragOverlay modifiers={[offsetOverlay]} dropAnimation={null}>
|
|
107
|
+
<DragPreview label={"preview"}/>
|
|
108
|
+
</DragOverlay>
|
|
109
|
+
</DndContext>
|
|
110
|
+
)
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
export const Default = Template.bind({});
|
|
114
|
+
|
|
115
|
+
Default.args = {
|
|
116
|
+
systemTree: fileTrees.fileTrees
|
|
117
|
+
}
|
|
@@ -2,6 +2,15 @@ import { useEffect } from "react";
|
|
|
2
2
|
import { FileBrowser } from "../components/FileBrowser";
|
|
3
3
|
import { useArgs } from "@storybook/preview-api";
|
|
4
4
|
import { action } from "@storybook/addon-actions";
|
|
5
|
+
import {
|
|
6
|
+
DndContext,
|
|
7
|
+
DragOverlay,
|
|
8
|
+
useDraggable,
|
|
9
|
+
useDroppable,
|
|
10
|
+
PointerSensor,
|
|
11
|
+
useSensor,
|
|
12
|
+
useSensors
|
|
13
|
+
} from "@dnd-kit/core";
|
|
5
14
|
|
|
6
15
|
import FileTree1 from "./data/FileBrowser/Tree1.json"
|
|
7
16
|
import FileTree2 from "./data/FileBrowser/Tree2.json"
|
|
@@ -14,6 +23,38 @@ export default {
|
|
|
14
23
|
argTypes: {}
|
|
15
24
|
};
|
|
16
25
|
|
|
26
|
+
/**
|
|
27
|
+
* Preview for the div being dragged.
|
|
28
|
+
* @returns
|
|
29
|
+
*/
|
|
30
|
+
function DragPreview({ label }) {
|
|
31
|
+
return (
|
|
32
|
+
<div
|
|
33
|
+
style={{
|
|
34
|
+
padding: "6px 12px",
|
|
35
|
+
background: "#2d2d2d",
|
|
36
|
+
color: "white",
|
|
37
|
+
boxShadow: "0 4px 12px rgba(0,0,0,0.3)",
|
|
38
|
+
opacity:0.3
|
|
39
|
+
}}
|
|
40
|
+
>
|
|
41
|
+
{label}
|
|
42
|
+
</div>
|
|
43
|
+
);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Offset for the drag overlay.
|
|
48
|
+
* @returns
|
|
49
|
+
*/
|
|
50
|
+
const offsetOverlay = ({ transform }) => {
|
|
51
|
+
return {
|
|
52
|
+
...transform,
|
|
53
|
+
x: transform.x + 20,
|
|
54
|
+
y: transform.y + 20
|
|
55
|
+
};
|
|
56
|
+
};
|
|
57
|
+
|
|
17
58
|
|
|
18
59
|
const Template = (args) => {
|
|
19
60
|
const [, updateArgs] = useArgs();
|
|
@@ -26,12 +67,50 @@ const Template = (args) => {
|
|
|
26
67
|
updateArgs({onNodeSelect : onNodeSelect});
|
|
27
68
|
}, []);
|
|
28
69
|
|
|
70
|
+
/**
|
|
71
|
+
* Callback for when drag ends.
|
|
72
|
+
*/
|
|
73
|
+
const handleDragEnd = (event) =>{
|
|
74
|
+
const { active, over } = event;
|
|
75
|
+
console.log("Drag Ended");
|
|
76
|
+
const rect = event.activatorEvent;
|
|
77
|
+
|
|
78
|
+
console.log(over );
|
|
79
|
+
|
|
80
|
+
if (over) {
|
|
81
|
+
console.log("Dragged item:", active.id);
|
|
82
|
+
console.log("Dropped on:", over.id);
|
|
83
|
+
} else {
|
|
84
|
+
console.log("Dropped outside any droppable");
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Callback for when drag is started.
|
|
90
|
+
*/
|
|
91
|
+
const onDragStart = (event) => {
|
|
92
|
+
console.log("Drag Started");
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
const sensors = useSensors(
|
|
96
|
+
useSensor(PointerSensor, {
|
|
97
|
+
activationConstraint: {
|
|
98
|
+
distance: 8
|
|
99
|
+
}
|
|
100
|
+
})
|
|
101
|
+
);
|
|
102
|
+
|
|
29
103
|
return (
|
|
30
|
-
<
|
|
31
|
-
<div className="
|
|
32
|
-
<
|
|
104
|
+
<DndContext sensors={sensors} onDragStart={onDragStart} onDragEnd={handleDragEnd}>
|
|
105
|
+
<div className="viewerStoryWrapper">
|
|
106
|
+
<div className="file-browser">
|
|
107
|
+
<FileBrowser {...args} />
|
|
108
|
+
</div>
|
|
33
109
|
</div>
|
|
34
|
-
|
|
110
|
+
<DragOverlay modifiers={[offsetOverlay]} dropAnimation={null}>
|
|
111
|
+
<DragPreview label={"preview"}/>
|
|
112
|
+
</DragOverlay>
|
|
113
|
+
</DndContext>
|
|
35
114
|
)
|
|
36
115
|
}
|
|
37
116
|
|