grafana-ui: export lazy-loaded version of react-monaco-editor (#39570)

* grafana-ui: refactor: move laziness to a lower level in code-editor

* grafana-ui: re-export react-monaco-editor

* rename export

Co-authored-by: Dominik Prokop <dominik.prokop@grafana.com>

* improved comment

* reverted name change

we already have an export with that name

Co-authored-by: Dominik Prokop <dominik.prokop@grafana.com>
This commit is contained in:
Gábor Farkas 2021-10-14 14:33:45 +02:00 committed by GitHub
parent 4565fcd0df
commit 19972600d7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 62 additions and 48 deletions

View File

@ -1,5 +1,5 @@
import { Meta, Story, Preview, Props } from '@storybook/addon-docs/blocks';
import { CodeEditor } from './CodeEditorLazy';
import { CodeEditor } from './CodeEditor';
<Meta title="MDX|CodeEditor" component={CodeEditor} />

View File

@ -3,7 +3,7 @@ import { Meta, Story } from '@storybook/react';
import { action } from '@storybook/addon-actions';
import { withCenteredStory } from '../../utils/storybook/withCenteredStory';
import mdx from './CodeEditor.mdx';
import { CodeEditor } from './CodeEditorLazy';
import { CodeEditor } from './CodeEditor';
export default {
title: 'CodeEditor',

View File

@ -1,6 +1,6 @@
import React from 'react';
import { css } from '@emotion/css';
import MonacoEditor, { loader as monacoEditorLoader } from '@monaco-editor/react';
import { ReactMonacoEditorLazy } from './ReactMonacoEditorLazy';
import type * as monacoType from 'monaco-editor/esm/vs/editor/editor.api';
import { selectors } from '@grafana/e2e-selectors';
import { GrafanaTheme2, monacoLanguageRegistry } from '@grafana/data';
@ -14,27 +14,12 @@ import defineThemes from './theme';
type Props = CodeEditorProps & Themeable2;
let initalized = false;
function initMonoco() {
if (initalized) {
return;
}
monacoEditorLoader.config({
paths: {
vs: (window.__grafana_public_path__ ?? 'public/') + 'lib/monaco/min/vs',
},
});
initalized = true;
}
class UnthemedCodeEditor extends React.PureComponent<Props> {
completionCancel?: monacoType.IDisposable;
monaco?: Monaco;
constructor(props: Props) {
super(props);
initMonoco();
}
componentWillUnmount() {
@ -154,7 +139,7 @@ class UnthemedCodeEditor extends React.PureComponent<Props> {
return (
<div className={styles.container} onBlur={this.onBlur} aria-label={selectors.components.CodeEditor.container}>
<MonacoEditor
<ReactMonacoEditorLazy
width={width}
height={height}
language={language}
@ -172,7 +157,7 @@ class UnthemedCodeEditor extends React.PureComponent<Props> {
}
}
export default withTheme2(UnthemedCodeEditor);
export const CodeEditor = withTheme2(UnthemedCodeEditor);
const getStyles = (theme: GrafanaTheme2) => {
return {

View File

@ -1,27 +0,0 @@
import React from 'react';
import { useAsyncDependency } from '../../utils/useAsyncDependency';
import { ErrorWithStack, LoadingPlaceholder } from '..';
import { CodeEditorProps } from './types';
export const CodeEditor: React.FC<CodeEditorProps> = (props) => {
const { loading, error, dependency } = useAsyncDependency(
import(/* webpackChunkName: "code-editor" */ './CodeEditor')
);
if (loading) {
return <LoadingPlaceholder text={''} />;
}
if (error) {
return (
<ErrorWithStack
title="Code editor failed to load"
error={error}
errorInfo={{ componentStack: error?.stack || '' }}
/>
);
}
const CodeEditor = dependency.default;
return <CodeEditor {...props} />;
};

View File

@ -0,0 +1,21 @@
import React from 'react';
import MonacoEditor, { loader as monacoEditorLoader, EditorProps as MonacoEditorProps } from '@monaco-editor/react';
let initalized = false;
function initMonaco() {
if (initalized) {
return;
}
monacoEditorLoader.config({
paths: {
vs: (window.__grafana_public_path__ ?? 'public/') + 'lib/monaco/min/vs',
},
});
initalized = true;
}
export const ReactMonacoEditor = (props: MonacoEditorProps) => {
initMonaco();
return <MonacoEditor {...props} />;
};

View File

@ -0,0 +1,32 @@
import React from 'react';
import { useAsyncDependency } from '../../utils/useAsyncDependency';
import { ErrorWithStack, LoadingPlaceholder } from '..';
// we only use import type so it will not be included in the bundle
import type { EditorProps } from '@monaco-editor/react';
/**
* @internal
* Experimental export
**/
export const ReactMonacoEditorLazy = (props: EditorProps) => {
const { loading, error, dependency } = useAsyncDependency(
import(/* webpackChunkName: "react-monaco-editor" */ './ReactMonacoEditor')
);
if (loading) {
return <LoadingPlaceholder text={''} />;
}
if (error) {
return (
<ErrorWithStack
title="React Monaco Editor failed to load"
error={error}
errorInfo={{ componentStack: error?.stack || '' }}
/>
);
}
const ReactMonacoEditor = dependency.ReactMonacoEditor;
return <ReactMonacoEditor {...props} />;
};

View File

@ -41,7 +41,10 @@ export { ConfirmModal, ConfirmModalProps } from './ConfirmModal/ConfirmModal';
export { QueryField } from './QueryField/QueryField';
// Code editor
export { CodeEditor } from './Monaco/CodeEditorLazy';
export { CodeEditor } from './Monaco/CodeEditor';
export { ReactMonacoEditorLazy as ReactMonacoEditor } from './Monaco/ReactMonacoEditorLazy';
export {
Monaco,
monacoTypes,