sample-ui-component-library 0.0.7-dev → 0.0.9-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 +6 -6
- 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 +3 -1
- package/src/components/Editor/Editor.jsx +77 -42
- package/src/components/Editor/Editor.scss +1 -0
- package/src/components/Editor/EditorContext.js +2 -0
- package/src/components/Editor/EditorReducer.js +97 -0
- package/src/components/Editor/MonacoInstance/MonacoInstance.jsx +62 -40
- package/src/components/Editor/MonacoInstance/MonacoInstance.scss +8 -0
- package/src/components/Editor/Tabs/Gutter/Gutter.jsx +35 -0
- package/src/components/Editor/Tabs/Gutter/Gutter.scss +5 -0
- package/src/components/Editor/Tabs/Tab/Tab.jsx +89 -0
- package/src/components/Editor/Tabs/Tab/Tab.scss +28 -0
- package/src/components/Editor/Tabs/Tabs.jsx +47 -0
- package/src/components/Editor/Tabs/Tabs.scss +15 -0
- package/src/components/FileBrowser/FileBrowser.jsx +56 -119
- package/src/components/FileBrowser/FileBrowser.scss +0 -33
- package/src/components/FileBrowser/FileBrowserContext.js +2 -0
- package/src/components/FileBrowser/FileBrowserReducer.js +47 -0
- package/src/components/FileBrowser/Tree/Tree.jsx +55 -0
- package/src/components/FileBrowser/Tree/Tree.scss +33 -0
- package/src/components/FileBrowser/TreeNode/TreeNode.jsx +102 -0
- package/src/components/FileBrowser/TreeNode/TreeNode.scss +33 -0
- package/src/components/FileBrowser/helper.js +1 -0
- package/src/stories/Editor.stories.js +34 -50
- package/src/stories/FileBrowser.stories.js +21 -36
- package/src/stories/data/FileBrowser/workspace_sample.json +1 -0
- package/src/components/Editor/EditorTabs/EditorTabs.jsx +0 -93
- package/src/components/Editor/EditorTabs/EditorTabs.scss +0 -33
- package/src/stories/data/FileBrowser/Tree1.json +0 -57
- package/src/stories/data/FileBrowser/Tree2.json +0 -60
|
@@ -1,19 +1,16 @@
|
|
|
1
|
-
import { useEffect } from "react";
|
|
1
|
+
import { useEffect, useLayoutEffect, useRef, useState } 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
5
|
import {
|
|
6
6
|
DndContext,
|
|
7
7
|
DragOverlay,
|
|
8
|
-
useDraggable,
|
|
9
|
-
useDroppable,
|
|
10
8
|
PointerSensor,
|
|
11
9
|
useSensor,
|
|
12
10
|
useSensors
|
|
13
11
|
} from "@dnd-kit/core";
|
|
14
12
|
|
|
15
|
-
import
|
|
16
|
-
import FileTree2 from "./data/FileBrowser/Tree2.json"
|
|
13
|
+
import WorkspaceSampleTree from "./data/FileBrowser/workspace_sample.json"
|
|
17
14
|
|
|
18
15
|
import "./FileBrowserStories.scss"
|
|
19
16
|
|
|
@@ -23,26 +20,6 @@ export default {
|
|
|
23
20
|
argTypes: {}
|
|
24
21
|
};
|
|
25
22
|
|
|
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
23
|
/**
|
|
47
24
|
* Offset for the drag overlay.
|
|
48
25
|
* @returns
|
|
@@ -58,6 +35,9 @@ const offsetOverlay = ({ transform }) => {
|
|
|
58
35
|
|
|
59
36
|
const Template = (args) => {
|
|
60
37
|
const [, updateArgs] = useArgs();
|
|
38
|
+
const fileBrowserRef = useRef();
|
|
39
|
+
|
|
40
|
+
const [dragPreviewLabel, setDragPreviewLabel] = useState(<></>);
|
|
61
41
|
|
|
62
42
|
const onNodeSelect = (selectedFile) => {
|
|
63
43
|
action('Selected Node:')(selectedFile);
|
|
@@ -67,6 +47,15 @@ const Template = (args) => {
|
|
|
67
47
|
updateArgs({onNodeSelect : onNodeSelect});
|
|
68
48
|
}, []);
|
|
69
49
|
|
|
50
|
+
|
|
51
|
+
useLayoutEffect(() => {
|
|
52
|
+
fileBrowserRef.current.addFileTree(args.tree);
|
|
53
|
+
|
|
54
|
+
setTimeout(() => {
|
|
55
|
+
fileBrowserRef.current.selectNode("dir-f6459410-1634-4dbc-8d76-35896822158d");
|
|
56
|
+
}, 3000);
|
|
57
|
+
}, []);
|
|
58
|
+
|
|
70
59
|
/**
|
|
71
60
|
* Callback for when drag ends.
|
|
72
61
|
*/
|
|
@@ -90,6 +79,8 @@ const Template = (args) => {
|
|
|
90
79
|
*/
|
|
91
80
|
const onDragStart = (event) => {
|
|
92
81
|
console.log("Drag Started");
|
|
82
|
+
const dragPreview = fileBrowserRef.current.getPreviewElement(event.active.data.current.node.uid);
|
|
83
|
+
setDragPreviewLabel(dragPreview);
|
|
93
84
|
}
|
|
94
85
|
|
|
95
86
|
const sensors = useSensors(
|
|
@@ -104,24 +95,18 @@ const Template = (args) => {
|
|
|
104
95
|
<DndContext sensors={sensors} onDragStart={onDragStart} onDragEnd={handleDragEnd}>
|
|
105
96
|
<div className="viewerStoryWrapper">
|
|
106
97
|
<div className="file-browser">
|
|
107
|
-
<FileBrowser {...args} />
|
|
98
|
+
<FileBrowser ref={fileBrowserRef} {...args} />
|
|
108
99
|
</div>
|
|
109
100
|
</div>
|
|
110
101
|
<DragOverlay modifiers={[offsetOverlay]} dropAnimation={null}>
|
|
111
|
-
|
|
102
|
+
{dragPreviewLabel}
|
|
112
103
|
</DragOverlay>
|
|
113
104
|
</DndContext>
|
|
114
105
|
)
|
|
115
106
|
}
|
|
116
107
|
|
|
117
|
-
export const
|
|
118
|
-
|
|
119
|
-
Default.args = {
|
|
120
|
-
tree: FileTree1.tree
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
export const Tree2 = Template.bind({});
|
|
108
|
+
export const SampleTree = Template.bind({});
|
|
124
109
|
|
|
125
|
-
|
|
126
|
-
tree:
|
|
110
|
+
SampleTree.args = {
|
|
111
|
+
tree: WorkspaceSampleTree.tree
|
|
127
112
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"tree":[{"name":"library_manager_single_threaded","type":"folder","uid":"dir-ba56de84-31dd-4ccf-ae98-a98b0581f803","children":[{"name":"library_manager.py","type":"file","uid":"dir-3d7aaf8e-6224-4eb7-8301-936447fef430","content":"import sys\n\ndef place_book_on_shelf(book_shelf, name, genre):\n '''\n This function places the given book on the shelf \n in a slot determined by the first letter of its name.\n \n :param book_shelf: Bookshelf to place the book on.\n :param name: Name of the book.\n :param genre: Genre of the book.\n '''\n print(f\"Accepted book: {name} (Genre: {genre})\")\n \n firstLetter = name[0].upper()\n\n if (firstLetter not in book_shelf):\n book_shelf[firstLetter] = []\n else:\n print(\"Slot for book already exists.\")\n\n book_shelf[firstLetter].append(name)\n\n return book_shelf\n\ndef accept_book():\n '''\n Accepts a book and genre from the user and returns it.\n '''\n print(\"\\nEnter book details:\")\n \n name = input(\"Book name: \")\n\n genre = input(\"Genre: \")\n\n return {\"name\":name, \"genre\":genre}\n\n\ndef library_manager():\n '''\n Runs the library manager to accept books until the user decides to stop.\n '''\n book_shelf = {}\n\n while True:\n book_details = accept_book()\n book_shelf = place_book_on_shelf(\n book_shelf, \n book_details[\"name\"], \n book_details[\"genre\"]\n )\n\n more = input(\"Add another book? (y): \").lower()\n \n if more != \"y\":\n break\n\n print(\"Exiting library manager, goodbye.\")\n\nif __name__ == \"__main__\":\n sys.exit(library_manager())\n "},{"name":"readme","type":"file","uid":"dir-5aa507ee-e43d-4d77-b49a-b6e0b1da36f5","content":"This is version 1 of the library manager and it contains a simple implementation that accepts a book name and genre before placing it on the shelf. It places it on the shelf using the first letter of the book name. It continues to accept books until the user decides to stop.\n\nThis version of the library manager will also use instrumentation to identify abstractions by line to overcome the limitations of existing techniques."}]},{"name":"text_translator","type":"folder","uid":"dir-cbb97582-e3da-403e-aa7f-a524a5a7cff7","children":[{"name":"FrenchTranslator.py","type":"file","uid":"dir-516008b2-e80c-4a3a-bb00-d651885ac15d","content":"import threading\nimport queue\nfrom deep_translator import GoogleTranslator # type: ignore\n\nclass FrenchTranslator(threading.Thread):\n def __init__(self, id, queue, packerQueue):\n super().__init__(daemon=True)\n self.queue = queue\n self.id = id\n self.packerQueue = packerQueue\n self.start()\n\n def run(self):\n while True:\n try:\n job = self.queue.get(timeout=10)\n except queue.Empty:\n continue\n\n translatedMsg = GoogleTranslator(source=\"auto\", target=\"french\").translate(job[\"value\"][\"data\"])\n self.packerQueue.put({\n \"uid\": job[\"uid\"],\n \"value\": {\n \"language\": \"french\",\n \"original\": job[\"value\"][\"data\"],\n \"translated\": translatedMsg\n }\n })"},{"name":"Packer.py","type":"file","uid":"dir-e5085241-ff4f-434d-85ab-7f50e673ea4d","content":"import threading\nimport queue\nfrom TransactionDB import TransactionDB\n\nclass PackerThread(threading.Thread):\n def __init__(self, queue):\n super().__init__(daemon=True)\n self.queue = queue\n self.items = {}\n self.start()\n\n def run(self):\n self.db = TransactionDB()\n while True:\n try:\n translatedJobPart = self.queue.get(timeout=10)\n except queue.Empty:\n continue\n\n self.db.addTranslation(translatedJobPart)\n\n if self.db.isDone(translatedJobPart[\"uid\"]):\n self.db.setDone(translatedJobPart[\"uid\"])"},{"name":"SpanishTranslator.py","type":"file","uid":"dir-b2a78dfd-aa94-4068-a5f7-24c396d88825","content":"import threading\nimport queue\nfrom deep_translator import GoogleTranslator # type: ignore\n\nclass SpanishTranslator(threading.Thread):\n def __init__(self, id, queue, packerQueue):\n super().__init__(daemon=True)\n self.queue = queue\n self.id = id\n self.packerQueue = packerQueue\n self.start()\n\n def run(self):\n while True:\n try:\n job = self.queue.get(timeout=10)\n except queue.Empty:\n continue\n\n translatedMsg = GoogleTranslator(source=\"auto\", target=\"spanish\").translate(job[\"value\"][\"data\"])\n self.packerQueue.put({\n \"uid\": job[\"uid\"],\n \"value\": {\n \"language\": \"spanish\",\n \"original\": job[\"value\"][\"data\"],\n \"translated\": translatedMsg\n }\n })"},{"name":"TamilTranslator.py","type":"file","uid":"dir-594ff411-b916-4a88-9077-3d5b8ff7f871","content":"import threading\nimport queue\nfrom deep_translator import GoogleTranslator # type: ignore\n\nclass TamilTranslator(threading.Thread):\n def __init__(self, id, queue, packerQueue):\n super().__init__(daemon=True)\n self.queue = queue\n self.id = id\n self.packerQueue = packerQueue\n self.start()\n\n def run(self):\n while True:\n try:\n job = self.queue.get(timeout=10)\n except queue.Empty:\n continue\n\n translatedMsg = GoogleTranslator(source=\"auto\", target=\"tamil\").translate(job[\"value\"][\"data\"])\n self.packerQueue.put({\n \"uid\": job[\"uid\"],\n \"value\": {\n \"language\": \"tamil\",\n \"original\": job[\"value\"][\"data\"],\n \"translated\": translatedMsg\n }\n })"},{"name":"readme","type":"file","uid":"dir-f6459410-1634-4dbc-8d76-35896822158d","content":"This folder contains a text translator that uses three workers to translate the text and uses a packer to add the results to a cabinet."}]}]}
|
|
@@ -1,93 +0,0 @@
|
|
|
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 = {};
|
|
@@ -1,33 +0,0 @@
|
|
|
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
|
-
}
|
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"tree": [
|
|
3
|
-
{
|
|
4
|
-
"id": 1,
|
|
5
|
-
"name": "root",
|
|
6
|
-
"type": "folder",
|
|
7
|
-
"children": [
|
|
8
|
-
{
|
|
9
|
-
"id": 2,
|
|
10
|
-
"name": "TraceViewer",
|
|
11
|
-
"type": "folder",
|
|
12
|
-
"children": [
|
|
13
|
-
{
|
|
14
|
-
"id": 3,
|
|
15
|
-
"name": "file1.js",
|
|
16
|
-
"type": "file"
|
|
17
|
-
},
|
|
18
|
-
{
|
|
19
|
-
"id": 4,
|
|
20
|
-
"name": "fileTree.json",
|
|
21
|
-
"type": "file"
|
|
22
|
-
}
|
|
23
|
-
]
|
|
24
|
-
},
|
|
25
|
-
{
|
|
26
|
-
"id": 5,
|
|
27
|
-
"name": "LogInjector",
|
|
28
|
-
"type": "folder",
|
|
29
|
-
"children": [
|
|
30
|
-
{
|
|
31
|
-
"id": 6,
|
|
32
|
-
"name": "injector.py",
|
|
33
|
-
"type": "file"
|
|
34
|
-
}
|
|
35
|
-
]
|
|
36
|
-
}
|
|
37
|
-
]
|
|
38
|
-
},
|
|
39
|
-
{
|
|
40
|
-
"id": 7,
|
|
41
|
-
"name": "sample.py",
|
|
42
|
-
"type": "file"
|
|
43
|
-
},
|
|
44
|
-
{
|
|
45
|
-
"id": 8,
|
|
46
|
-
"name": "DesignViewer",
|
|
47
|
-
"type": "folder",
|
|
48
|
-
"children": [
|
|
49
|
-
{
|
|
50
|
-
"id": 9,
|
|
51
|
-
"name": "test.js",
|
|
52
|
-
"type": "file"
|
|
53
|
-
}
|
|
54
|
-
]
|
|
55
|
-
}
|
|
56
|
-
]
|
|
57
|
-
}
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"tree": [
|
|
3
|
-
{
|
|
4
|
-
"id": 1,
|
|
5
|
-
"name": "TraceViewer",
|
|
6
|
-
"type": "folder",
|
|
7
|
-
"children": [
|
|
8
|
-
{
|
|
9
|
-
"id": 2,
|
|
10
|
-
"name": "FileBrowser.stories.js",
|
|
11
|
-
"type": "file"
|
|
12
|
-
},
|
|
13
|
-
{
|
|
14
|
-
"id": 3,
|
|
15
|
-
"name": "FileBrowserStories.scss",
|
|
16
|
-
"type": "file"
|
|
17
|
-
},
|
|
18
|
-
{
|
|
19
|
-
"id": 4,
|
|
20
|
-
"name": "FlowDiagram.stories.js",
|
|
21
|
-
"type": "file"
|
|
22
|
-
},
|
|
23
|
-
{
|
|
24
|
-
"id": 5,
|
|
25
|
-
"name": "FlowDiagram.scss",
|
|
26
|
-
"type": "file"
|
|
27
|
-
}
|
|
28
|
-
]
|
|
29
|
-
},
|
|
30
|
-
{
|
|
31
|
-
"id": 6,
|
|
32
|
-
"name": "Data",
|
|
33
|
-
"type": "folder",
|
|
34
|
-
"children": [
|
|
35
|
-
{
|
|
36
|
-
"id": 7,
|
|
37
|
-
"name": "fileTree.json",
|
|
38
|
-
"type": "file"
|
|
39
|
-
},
|
|
40
|
-
{
|
|
41
|
-
"id": 8,
|
|
42
|
-
"name": "FileBrowser",
|
|
43
|
-
"type": "folder",
|
|
44
|
-
"children": [
|
|
45
|
-
{
|
|
46
|
-
"id": 9,
|
|
47
|
-
"name": "fileTree.json",
|
|
48
|
-
"type": "file"
|
|
49
|
-
},
|
|
50
|
-
{
|
|
51
|
-
"id": 10,
|
|
52
|
-
"name": "Tree2.json",
|
|
53
|
-
"type": "file"
|
|
54
|
-
}
|
|
55
|
-
]
|
|
56
|
-
}
|
|
57
|
-
]
|
|
58
|
-
}
|
|
59
|
-
]
|
|
60
|
-
}
|