|
1 | 1 | import '@codingame/monaco-vscode-python-default-extension'; |
2 | 2 | import '@codingame/monaco-vscode-theme-defaults-default-extension'; |
3 | | -import { useEffect, useMemo, useRef } from 'react'; |
| 3 | +import { useEffect, useRef, useState } from 'react'; |
4 | 4 | import * as monaco from 'monaco-editor/esm/vs/editor/editor.api'; |
5 | 5 | import { initialize } from 'vscode/services'; |
6 | 6 | import getLanguagesServiceOverride from '@codingame/monaco-vscode-languages-service-override'; |
@@ -131,25 +131,37 @@ type MonacoEditorProps = { |
131 | 131 |
|
132 | 132 | const MonacoEditor = ({ |
133 | 133 | name, |
134 | | - width = '100vw', |
135 | | - height = '100vh', |
136 | 134 | language = 'python', |
137 | 135 | value, |
138 | 136 | className, |
139 | 137 | }: MonacoEditorProps) => { |
140 | 138 | const { t } = useTranslation(); |
141 | 139 | const containerRef = useRef<HTMLDivElement | null>(null); |
| 140 | + const editorRef = useRef<HTMLDivElement | null>(null); |
142 | 141 | const editor = useRef<monaco.editor.IStandaloneCodeEditor | null>(null); |
| 142 | + const [childWidth, setChildWidth] = useState(0); |
| 143 | + const [childHeight, setChildHeight] = useState(0); |
143 | 144 |
|
144 | | - const fixedWidth = width; |
145 | | - const fixedHeight = height; |
146 | | - const style = useMemo( |
147 | | - () => ({ |
148 | | - width: fixedWidth, |
149 | | - height: fixedHeight, |
150 | | - }), |
151 | | - [fixedWidth, fixedHeight], |
152 | | - ); |
| 145 | + useEffect(() => { |
| 146 | + if (containerRef.current) { |
| 147 | + const resizeObserver = new ResizeObserver((entries) => { |
| 148 | + // we only expect one element to be observed |
| 149 | + if (!entries || entries.length === 0) { |
| 150 | + return; |
| 151 | + } |
| 152 | + const {clientWidth, clientHeight} = entries[0].target as HTMLDivElement; |
| 153 | + setChildWidth(clientWidth); |
| 154 | + setChildHeight(clientHeight); |
| 155 | + if (editor.current) { |
| 156 | + editor.current.layout({ width: clientWidth, height: clientHeight }); |
| 157 | + } |
| 158 | + }); |
| 159 | + resizeObserver.observe(containerRef.current); |
| 160 | + return () => { |
| 161 | + resizeObserver.disconnect(); |
| 162 | + }; |
| 163 | + } |
| 164 | + }, []); |
153 | 165 |
|
154 | 166 | useEffect(() => { |
155 | 167 | /** |
@@ -181,7 +193,7 @@ const MonacoEditor = ({ |
181 | 193 | console.log('Editor Content', content); |
182 | 194 | const loadContent = JSON.parse(content); |
183 | 195 | if (loadContent.name !== name) return; |
184 | | - if (containerRef.current && editor.current) { |
| 196 | + if (editorRef.current && editor.current) { |
185 | 197 | const model = monaco.editor.createModel(loadContent.content, languageId); |
186 | 198 | editor.current.setModel(model); |
187 | 199 | } |
@@ -219,14 +231,14 @@ const MonacoEditor = ({ |
219 | 231 | EditorMgr.getInstance().setSubscription(name); |
220 | 232 | } |
221 | 233 |
|
222 | | - if (containerRef.current) { |
| 234 | + if (editorRef.current && childWidth > 0 && childHeight > 0) { |
223 | 235 | if (editor.current === null) { |
224 | 236 | updateUserConfiguration(`{ |
225 | 237 | "editor.fontSize": ${Constants.DEFAULT_FONTSIZE}, |
226 | 238 | "workbench.colorTheme": "${AppMgr.getInstance().getTheme() === Themes.DARK ? 'Default Dark Modern' : 'vs'}" |
227 | 239 | }`); |
228 | 240 |
|
229 | | - editor.current = monaco.editor.create(containerRef.current, { |
| 241 | + editor.current = monaco.editor.create(editorRef.current, { |
230 | 242 | value: value, |
231 | 243 | language: language, |
232 | 244 | }); |
@@ -277,9 +289,15 @@ const MonacoEditor = ({ |
277 | 289 | } |
278 | 290 | } |
279 | 291 | } |
280 | | - }, [name, language, value, t]); |
| 292 | + }, [name, language, value, t, childWidth, childHeight]); |
281 | 293 |
|
282 | | - return <div ref={containerRef} style={style} className={className} />; |
| 294 | + return ( |
| 295 | + <> |
| 296 | + <div ref={containerRef} className='w-full h-full'> |
| 297 | + <div ref={editorRef} style={{ width: childWidth, height: childHeight }} className={className} /> |
| 298 | + </div> |
| 299 | + </> |
| 300 | + ); |
283 | 301 | }; |
284 | 302 |
|
285 | 303 | export default MonacoEditor; |
0 commit comments