sample-ui-component-library 0.0.61-dev → 0.0.62-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 +2 -2
- package/dist/esm/index.js.map +1 -1
- package/package.json +1 -1
- package/src/components/Editor/MonacoInstance/MonacoInstance.jsx +22 -14
- package/src/components/Editor/MonacoInstance/MonacoInstance.scss +4 -16
- package/src/components/Editor/MonacoInstance/OverlayRow/OverlayRow.jsx +36 -0
- package/src/components/Editor/MonacoInstance/OverlayRow/OverlayRow.scss +11 -0
- package/src/stories/data/FileBrowser/workspace_sample.json +332 -1
- package/src/components/Editor/MonacoInstance/MonacoInstance copy.jsx +0 -184
|
@@ -1,184 +0,0 @@
|
|
|
1
|
-
import React, { useCallback, useLayoutEffect, useEffect, useRef, useState } from 'react';
|
|
2
|
-
import PropTypes from 'prop-types';
|
|
3
|
-
|
|
4
|
-
import EDITOR_MODES from '../EDITOR_MODES';
|
|
5
|
-
|
|
6
|
-
import Editor from '@monaco-editor/react';
|
|
7
|
-
|
|
8
|
-
import "./MonacoInstance.scss"
|
|
9
|
-
|
|
10
|
-
import { useEditor } from "../Editor";
|
|
11
|
-
|
|
12
|
-
export const MonacoInstance = ({onSelectAbstraction, updateContent}) => {
|
|
13
|
-
const { state } = useEditor();
|
|
14
|
-
const [editorContent, setEditorContent] = useState("Loading content...");
|
|
15
|
-
const [showEditor, setShowEditor] = useState(false);
|
|
16
|
-
const activeTabRef = useRef(state.activeTab);
|
|
17
|
-
|
|
18
|
-
const editorRef = useRef(null);
|
|
19
|
-
const content = useRef();
|
|
20
|
-
const containerRef = useRef(null);
|
|
21
|
-
const frameRef = useRef(0);
|
|
22
|
-
|
|
23
|
-
const [overlayDivs, setOverlayDivs] = useState();
|
|
24
|
-
|
|
25
|
-
// When active tab changes, update the editor content and add overlays for the new active tab.
|
|
26
|
-
useLayoutEffect(() => {
|
|
27
|
-
if (state.activeTab) {
|
|
28
|
-
console.log(state.activeTab)
|
|
29
|
-
activeTabRef.current = state.activeTab;
|
|
30
|
-
setEditorContent(state.activeTab.updatedContent);
|
|
31
|
-
setShowEditor(true);
|
|
32
|
-
addOverlays();
|
|
33
|
-
} else {
|
|
34
|
-
setShowEditor(false);
|
|
35
|
-
}
|
|
36
|
-
}, [state.activeTab, editorRef]);
|
|
37
|
-
|
|
38
|
-
// When the editor content changes, update the content in the context for the active tab.
|
|
39
|
-
// Setup content change listener for the editor to update the content in the context
|
|
40
|
-
// and track dirty state of the tab.
|
|
41
|
-
useEffect(() => {
|
|
42
|
-
content.current = editorContent;
|
|
43
|
-
if (editorRef?.current && content.current !== undefined && content.current !== null) {
|
|
44
|
-
editorRef.current.setValue(content.current);
|
|
45
|
-
editorRef.current.getModel().onDidChangeContent((content) => {
|
|
46
|
-
updateContent(activeTabRef.current, editorRef.current.getValue());
|
|
47
|
-
});
|
|
48
|
-
}
|
|
49
|
-
}, [editorContent]);
|
|
50
|
-
|
|
51
|
-
/**
|
|
52
|
-
* Callback for when the Monaco Editor is mounted.
|
|
53
|
-
* @param {Object} editor
|
|
54
|
-
* @param {Object} monaco
|
|
55
|
-
*/
|
|
56
|
-
const handleEditorDidMount = useCallback((editor, monaco) => {
|
|
57
|
-
editorRef.current = editor;
|
|
58
|
-
if (content?.current) {
|
|
59
|
-
editorRef.current.setValue(content.current);
|
|
60
|
-
}
|
|
61
|
-
editorRef.current.layout();
|
|
62
|
-
addOverlays();
|
|
63
|
-
|
|
64
|
-
}, []);
|
|
65
|
-
|
|
66
|
-
// Add overlays to editor for the given line ranges.
|
|
67
|
-
const addOverlays = useCallback(() => {
|
|
68
|
-
if (!editorRef.current) return;
|
|
69
|
-
|
|
70
|
-
if (state.mode !== EDITOR_MODES.MAPPING || !state.mapping.get(state.activeTab?.name)) {
|
|
71
|
-
setOverlayDivs([]);
|
|
72
|
-
return;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
const ranges = state.mapping.get(state.activeTab?.name);
|
|
76
|
-
const lineCount = editorRef.current.getModel().getLineCount();
|
|
77
|
-
const lineHeight = editorRef.current.getOption(monaco.editor.EditorOption.lineHeight);
|
|
78
|
-
const divs = [];
|
|
79
|
-
|
|
80
|
-
ranges.forEach((entry) => {
|
|
81
|
-
const top = editorRef.current.getTopForLineNumber(entry.start_line) - editorRef.current.getScrollTop();
|
|
82
|
-
let bottom = editorRef.current.getTopForLineNumber(entry.end_line + 1) - editorRef.current.getScrollTop();
|
|
83
|
-
if (entry.end_line >= lineCount) {
|
|
84
|
-
bottom = bottom + lineHeight;
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
const style= {
|
|
88
|
-
top: top + "px",
|
|
89
|
-
height: (bottom - top) + "px"
|
|
90
|
-
}
|
|
91
|
-
if (state.mappedIds.includes(entry.uid)) {
|
|
92
|
-
style["backgroundColor"] = "rgba(255, 0, 0, 0.3)";
|
|
93
|
-
}
|
|
94
|
-
const overlayDiv = <div
|
|
95
|
-
className="line-block-overlay"
|
|
96
|
-
onClick={(e) => onSelectAbstraction(entry)}
|
|
97
|
-
style={style}>
|
|
98
|
-
</div>;
|
|
99
|
-
divs.push(overlayDiv);
|
|
100
|
-
|
|
101
|
-
});
|
|
102
|
-
setOverlayDivs(divs);
|
|
103
|
-
}, [editorRef?.current, state, onSelectAbstraction]);
|
|
104
|
-
|
|
105
|
-
// Scroll the editor and update overlays on wheel event.
|
|
106
|
-
const handleWheel = useCallback((e) => {
|
|
107
|
-
if (!editorRef.current) return;
|
|
108
|
-
const deltaY = e.deltaY;
|
|
109
|
-
const currentScrollTop = editorRef.current.getScrollTop();
|
|
110
|
-
editorRef.current.setScrollTop(currentScrollTop + deltaY);
|
|
111
|
-
addOverlays();
|
|
112
|
-
}, [state.activeTab, addOverlays]);
|
|
113
|
-
|
|
114
|
-
// Editor options for Monaco Editor.
|
|
115
|
-
const editorOptions = {
|
|
116
|
-
fontSize: "13px",
|
|
117
|
-
minimap: {
|
|
118
|
-
enabled: false
|
|
119
|
-
},
|
|
120
|
-
padding: {
|
|
121
|
-
top: 10
|
|
122
|
-
},
|
|
123
|
-
renderWhitespace: "none",
|
|
124
|
-
wordWrap: "on",
|
|
125
|
-
scrollBeyondLastLine: false,
|
|
126
|
-
automaticLayout: false
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
// Disable automatic layout and Manually layout the editor to avoid resize observer loops
|
|
130
|
-
useEffect(() => {
|
|
131
|
-
if (!containerRef.current) return;
|
|
132
|
-
|
|
133
|
-
const ro = new ResizeObserver(() => {
|
|
134
|
-
cancelAnimationFrame(frameRef.current);
|
|
135
|
-
frameRef.current = requestAnimationFrame(() => {
|
|
136
|
-
editorRef.current?.layout();
|
|
137
|
-
addOverlays();
|
|
138
|
-
});
|
|
139
|
-
});
|
|
140
|
-
|
|
141
|
-
ro.observe(containerRef.current);
|
|
142
|
-
|
|
143
|
-
return () => {
|
|
144
|
-
cancelAnimationFrame(frameRef.current);
|
|
145
|
-
ro.disconnect();
|
|
146
|
-
};
|
|
147
|
-
}, [state.activeTab, addOverlays]);
|
|
148
|
-
|
|
149
|
-
/**
|
|
150
|
-
* Render the editor if there is an active tab, otherwise render a placeholder message.
|
|
151
|
-
* @returns JSX
|
|
152
|
-
*/
|
|
153
|
-
const renderEditor = () => {
|
|
154
|
-
if (showEditor) {
|
|
155
|
-
return (
|
|
156
|
-
<Editor
|
|
157
|
-
defaultLanguage="python"
|
|
158
|
-
defaultValue={editorContent}
|
|
159
|
-
onMount={handleEditorDidMount}
|
|
160
|
-
theme="vs-dark"
|
|
161
|
-
options={editorOptions}
|
|
162
|
-
/>
|
|
163
|
-
);
|
|
164
|
-
} else {
|
|
165
|
-
return <div className="no-tab">Select file or drag and drop to view.</div>;
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
return (
|
|
170
|
-
<div className="editor-container" ref={containerRef}>
|
|
171
|
-
{renderEditor()}
|
|
172
|
-
{
|
|
173
|
-
state.mode === EDITOR_MODES.MAPPING &&
|
|
174
|
-
<div className="overlay-layer" onWheel={handleWheel}>
|
|
175
|
-
{overlayDivs}
|
|
176
|
-
</div>
|
|
177
|
-
}
|
|
178
|
-
</div>
|
|
179
|
-
)
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
MonacoInstance.propTypes = {
|
|
183
|
-
editorContent: PropTypes.string,
|
|
184
|
-
}
|