mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
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:
parent
4565fcd0df
commit
19972600d7
@ -1,5 +1,5 @@
|
|||||||
import { Meta, Story, Preview, Props } from '@storybook/addon-docs/blocks';
|
import { Meta, Story, Preview, Props } from '@storybook/addon-docs/blocks';
|
||||||
import { CodeEditor } from './CodeEditorLazy';
|
import { CodeEditor } from './CodeEditor';
|
||||||
|
|
||||||
<Meta title="MDX|CodeEditor" component={CodeEditor} />
|
<Meta title="MDX|CodeEditor" component={CodeEditor} />
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@ import { Meta, Story } from '@storybook/react';
|
|||||||
import { action } from '@storybook/addon-actions';
|
import { action } from '@storybook/addon-actions';
|
||||||
import { withCenteredStory } from '../../utils/storybook/withCenteredStory';
|
import { withCenteredStory } from '../../utils/storybook/withCenteredStory';
|
||||||
import mdx from './CodeEditor.mdx';
|
import mdx from './CodeEditor.mdx';
|
||||||
import { CodeEditor } from './CodeEditorLazy';
|
import { CodeEditor } from './CodeEditor';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
title: 'CodeEditor',
|
title: 'CodeEditor',
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { css } from '@emotion/css';
|
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 type * as monacoType from 'monaco-editor/esm/vs/editor/editor.api';
|
||||||
import { selectors } from '@grafana/e2e-selectors';
|
import { selectors } from '@grafana/e2e-selectors';
|
||||||
import { GrafanaTheme2, monacoLanguageRegistry } from '@grafana/data';
|
import { GrafanaTheme2, monacoLanguageRegistry } from '@grafana/data';
|
||||||
@ -14,27 +14,12 @@ import defineThemes from './theme';
|
|||||||
|
|
||||||
type Props = CodeEditorProps & Themeable2;
|
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> {
|
class UnthemedCodeEditor extends React.PureComponent<Props> {
|
||||||
completionCancel?: monacoType.IDisposable;
|
completionCancel?: monacoType.IDisposable;
|
||||||
monaco?: Monaco;
|
monaco?: Monaco;
|
||||||
|
|
||||||
constructor(props: Props) {
|
constructor(props: Props) {
|
||||||
super(props);
|
super(props);
|
||||||
initMonoco();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
componentWillUnmount() {
|
componentWillUnmount() {
|
||||||
@ -154,7 +139,7 @@ class UnthemedCodeEditor extends React.PureComponent<Props> {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.container} onBlur={this.onBlur} aria-label={selectors.components.CodeEditor.container}>
|
<div className={styles.container} onBlur={this.onBlur} aria-label={selectors.components.CodeEditor.container}>
|
||||||
<MonacoEditor
|
<ReactMonacoEditorLazy
|
||||||
width={width}
|
width={width}
|
||||||
height={height}
|
height={height}
|
||||||
language={language}
|
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) => {
|
const getStyles = (theme: GrafanaTheme2) => {
|
||||||
return {
|
return {
|
||||||
|
@ -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} />;
|
|
||||||
};
|
|
@ -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} />;
|
||||||
|
};
|
@ -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} />;
|
||||||
|
};
|
@ -41,7 +41,10 @@ export { ConfirmModal, ConfirmModalProps } from './ConfirmModal/ConfirmModal';
|
|||||||
export { QueryField } from './QueryField/QueryField';
|
export { QueryField } from './QueryField/QueryField';
|
||||||
|
|
||||||
// Code editor
|
// Code editor
|
||||||
export { CodeEditor } from './Monaco/CodeEditorLazy';
|
export { CodeEditor } from './Monaco/CodeEditor';
|
||||||
|
|
||||||
|
export { ReactMonacoEditorLazy as ReactMonacoEditor } from './Monaco/ReactMonacoEditorLazy';
|
||||||
|
|
||||||
export {
|
export {
|
||||||
Monaco,
|
Monaco,
|
||||||
monacoTypes,
|
monacoTypes,
|
||||||
|
Loading…
Reference in New Issue
Block a user