UNPKG

@uiw/react-monacoeditor

Version:
136 lines 4.33 kB
import _extends from "@babel/runtime/helpers/extends"; import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/objectWithoutPropertiesLoose"; import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator"; var _excluded = ["width", "height", "value", "theme", "language", "autoComplete", "options", "editorDidMount", "onChange", "defaultValue"]; /* eslint-disable react-hooks/exhaustive-deps */ import React, { useImperativeHandle, useEffect, useRef, useState, useCallback } from 'react'; import * as monaco from 'monaco-editor'; import { editor, languages } from 'monaco-editor'; // @ts-ignore import codicon from 'monaco-editor/min/vs/base/browser/ui/codicons/codicon/codicon.ttf'; import { jsx as _jsx } from "react/jsx-runtime"; function noop() {} export function loadFont(_x, _x2) { return _loadFont.apply(this, arguments); } function _loadFont() { _loadFont = _asyncToGenerator(function* (fontFamily, url) { var font = new FontFace(fontFamily, "local(" + fontFamily + "), url(" + url + ")"); // wait for font to be loaded yield font.load(); // add font to document document.fonts.add(font); }); return _loadFont.apply(this, arguments); } function MonacoEditor(props, ref) { var { width = '100%', height = '100%', value = '', theme = '', language = 'javascript', autoComplete, options = {}, editorDidMount = noop, onChange = noop, defaultValue = '' } = props, other = _objectWithoutPropertiesLoose(props, _excluded); options.language = language || options.language; options.theme = theme || options.theme; var [val, setVal] = useState(defaultValue); var container = useRef(); var $editor = useRef(); useImperativeHandle(ref, () => ({ container: container.current || null, editor: $editor.current, monaco })); useEffect(() => setVal(value), [value]); useEffect(() => { if ($editor.current) { $editor.current.setValue(val); } }, [val]); useEffect(() => { if (options.theme) { editor.setTheme(options.theme); } }, [options.theme]); useEffect(() => { var CPDisposable; if ($editor.current && autoComplete) { if ($editor.current.getModel() && $editor.current.getPosition()) { CPDisposable = languages.registerCompletionItemProvider(language, { provideCompletionItems: (model, position) => { return { suggestions: autoComplete(model, position) }; } }); } } return () => { CPDisposable && CPDisposable.dispose(); }; }, [language, autoComplete]); useEffect(() => { if ($editor.current) { var model = $editor.current.getModel(); if (model) { editor.setModelLanguage(model, props.language || ''); } } }, [language]); useEffect(() => { if ($editor.current) { var optionsRaw = $editor.current.getRawOptions(); Object.keys(optionsRaw).forEach(keyname => { var propsOpt = options[keyname]; if (optionsRaw[keyname] !== propsOpt && propsOpt !== undefined) { $editor.current.updateOptions({ [keyname]: propsOpt }); } }); } }, [options]); var refElement = useCallback(node => { if (node !== null) { container.current = node; $editor.current = editor.create(node, _extends({ value: val, language }, options)); if (options.theme) { editor.setTheme(options.theme); } // After initializing monaco editor editorDidMount($editor.current, monaco); $editor.current.onDidChangeModelContent(event => { var valueCurrent = $editor.current.getValue(); // Always refer to the latest value onChange(valueCurrent, event); }); loadFont('codicon', codicon).catch(e => { if (e) { throw new Error('Failed to load font codicon!!'); } }); } else { if ($editor.current) { $editor.current.dispose(); $editor.current = undefined; } } }, []); return /*#__PURE__*/_jsx("div", _extends({}, other, { ref: refElement, style: _extends({}, other.style, { width, height }) })); } export default /*#__PURE__*/React.forwardRef(MonacoEditor);