UNPKG

use-monaco

Version:

[![npm](https://img.shields.io/npm/v/use-monaco)](https://npm.im/use-monaco)

130 lines 5.45 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.useRefWithEffect = exports.useMonaco = exports.useMonacoContext = exports.MonacoProvider = void 0; const tslib_1 = require("tslib"); const react_1 = tslib_1.__importDefault(require("react")); const monaco_1 = require("../monaco"); const ayu_light_1 = tslib_1.__importDefault(require("../themes/monaco/ayu-light")); const create_hook_context_1 = require("create-hook-context"); const plugins_1 = require("../plugins"); const [MonacoProvider, _, __, MonacoContext] = create_hook_context_1.createContext((config) => exports.useMonaco(config), undefined, 'Monaco'); exports.MonacoProvider = MonacoProvider; function useMonacoContext() { return react_1.default.useContext(MonacoContext); } exports.useMonacoContext = useMonacoContext; let startedLoading = false; const useMonaco = ({ themes, onThemeChange = () => { }, onLoad, defaultEditorOptions = { automaticLayout: true, minimap: { enabled: false, }, }, theme = 'ayu-light', plugins = [], languages = ['javascript', 'typescript', 'html', 'css', 'json'], ...loaderOptions } = {}) => { const contextMonaco = useMonacoContext(); const [monaco, setMonaco] = react_1.default.useState(contextMonaco === undefined ? null : contextMonaco.monaco); const [monacoRef, useMonacoEffect] = useRefWithEffect(monaco); monacoRef.current = contextMonaco?.monaco || monaco; react_1.default.useEffect(() => { let onLoadDisposable; async function initializeMonaco(monaco, plugins, languages) { let pluginDisposables = await monaco.plugin.install(...plugins .map((plug) => typeof plug === 'string' || (Array.isArray(plug) && plug.length === 2) ? plugins_1.pluginMap[Array.isArray(plug) ? plug[0] : plug] ? plugins_1.pluginMap[Array.isArray(plug) ? plug[0] : plug](Array.isArray(plug) ? plug[1] : {}) : undefined : plug) .filter(Boolean), ...languages .map((plug) => typeof plug === 'string' ? monaco_1.basicLanguagePlugins[plug] ? monaco_1.basicLanguagePlugins[plug] : undefined : plug) .filter(Boolean)); monaco.editor.defineTheme('ayu-light', ayu_light_1.default); setMonaco(monaco); let disposables = onLoad ? await onLoad(monaco) : null; onLoadDisposable = monaco_1.asDisposable([pluginDisposables, disposables].filter(Boolean)); window.monaco = monaco; } // only loading once if (contextMonaco === undefined && startedLoading) { return; // console.warn( // `Detected trying to load monaco from multiple hooks. If you want to use monaco with multiple editors or from multiple components, its better to use a MonacoProvider that wraps your components and initializes monaco.` // ); } if (!monacoRef.current && window.monaco) { initializeMonaco(window.monaco, plugins, languages); return () => { onLoadDisposable?.dispose?.(); }; } if (contextMonaco === undefined && !monacoRef.current) { startedLoading = true; const cancelable = monaco_1.loadMonaco(loaderOptions ?? {}); cancelable .then(async (monaco) => { await initializeMonaco(monaco, plugins, languages); return monaco; }) .catch((error) => console.error('An error occurred during initialization of Monaco:', error)); return () => { onLoadDisposable?.dispose?.(); cancelable.cancel?.(); }; } }, []); useMonacoEffect((monaco) => { if (themes) { monaco.editor.defineThemes(themes); return () => { }; } }, [themes]); useMonacoEffect((monaco) => { if (onThemeChange) { const disposable = monaco.editor.onDidChangeTheme((theme) => { onThemeChange(theme, monaco); }); return () => { disposable?.dispose?.(); }; } }, [onThemeChange]); useMonacoEffect((monaco) => { if (typeof theme === 'function') { const returnedTheme = theme(); if (returnedTheme.then) { returnedTheme.then((result) => { monaco.editor.setTheme(result); }); } else { monaco.editor.setTheme(returnedTheme); } } else if (theme) { monaco.editor.setTheme(theme); } }, [theme]); return { monaco: monacoRef.current, useMonacoEffect, defaultEditorOptions, isLoading: Boolean(monacoRef.current), }; }; exports.useMonaco = useMonaco; function useRefWithEffect(initialValue) { const ref = react_1.default.useRef(initialValue); const useRefEffect = (effect, deps) => { react_1.default.useEffect(() => { if (ref.current) { return effect(ref.current); } }, [ref.current, ...deps]); }; return [ref, useRefEffect]; } exports.useRefWithEffect = useRefWithEffect; //# sourceMappingURL=useMonaco.js.map