Improve CodeEditor wrapper (#114500)

This commit is contained in:
Anton Dosov 2021-10-15 12:47:18 +02:00 committed by GitHub
parent 033dfb3c22
commit 21760d4832
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 87 additions and 55 deletions

View file

@ -104,7 +104,7 @@ pageLoadAssetSize:
dataViews: 41532
expressions: 140958
fieldFormats: 65209
kibanaReact: 99422
kibanaReact: 84422
share: 71239
uiActions: 35121
dataEnhanced: 24980

View file

@ -594,9 +594,13 @@ exports[`Source Viewer component renders json code editor 1`] = `
fallback={<Fallback />}
>
<Fallback>
<EuiDelayRender
delay={500}
/>
<div
style={Object {}}
>
<EuiDelayRender
delay={500}
/>
</div>
</Fallback>
</Suspense>
</EuiErrorBoundary>

View file

@ -14,6 +14,7 @@ import { monaco } from '@kbn/monaco';
import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n/react';
import classNames from 'classnames';
import './register_languages';
import {
DARK_THEME,

View file

@ -0,0 +1,39 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
import React from 'react';
import darkTheme from '@elastic/eui/dist/eui_theme_dark.json';
import lightTheme from '@elastic/eui/dist/eui_theme_light.json';
import { EuiFormControlLayout } from '@elastic/eui';
import { CodeEditor, Props } from './code_editor';
/**
* Renders a Monaco code editor in the same style as other EUI form fields.
*/
export const CodeEditorField: React.FunctionComponent<Props> = (props) => {
const { width, height, options, fullWidth, useDarkTheme } = props;
const theme = useDarkTheme ? darkTheme : lightTheme;
const style = {
width,
height,
backgroundColor: options?.readOnly
? theme.euiFormBackgroundReadOnlyColor
: theme.euiFormBackgroundColor,
};
return (
<EuiFormControlLayout
append={<div hidden />}
style={style}
readOnly={options?.readOnly}
fullWidth={fullWidth}
>
<CodeEditor {...props} transparentBackground />
</EuiFormControlLayout>
);
};

View file

@ -7,28 +7,31 @@
*/
import React from 'react';
import {
EuiDelayRender,
EuiErrorBoundary,
EuiLoadingContent,
EuiFormControlLayout,
} from '@elastic/eui';
import darkTheme from '@elastic/eui/dist/eui_theme_dark.json';
import lightTheme from '@elastic/eui/dist/eui_theme_light.json';
import { useUiSetting } from '../ui_settings';
import { Props } from './code_editor';
import './register_languages';
import { EuiDelayRender, EuiErrorBoundary, EuiLoadingContent } from '@elastic/eui';
export * from './languages';
import { useUiSetting } from '../ui_settings';
import type { Props } from './code_editor';
export * from './languages/constants';
const LazyBaseEditor = React.lazy(() => import('./code_editor'));
const Fallback = () => (
<EuiDelayRender>
<EuiLoadingContent lines={3} />
</EuiDelayRender>
const LazyCodeEditorField = React.lazy(() =>
import('./code_editor_field').then((m) => ({ default: m.CodeEditorField }))
);
const Fallback: React.FunctionComponent<{ height: Props['height'] }> = ({ height }) => {
return (
<>
{/* when height is known, set minHeight to avoid layout shift */}
<div style={height ? { minHeight: height } : {}}>
<EuiDelayRender>
<EuiLoadingContent lines={3} />
</EuiDelayRender>
</div>
</>
);
};
export type CodeEditorProps = Props;
/**
@ -40,7 +43,7 @@ export const CodeEditor: React.FunctionComponent<Props> = (props) => {
const darkMode = useUiSetting<boolean>('theme:darkMode');
return (
<EuiErrorBoundary>
<React.Suspense fallback={<Fallback />}>
<React.Suspense fallback={<Fallback height={props.height} />}>
<LazyBaseEditor {...props} useDarkTheme={darkMode} />
</React.Suspense>
</EuiErrorBoundary>
@ -51,38 +54,11 @@ export const CodeEditor: React.FunctionComponent<Props> = (props) => {
* Renders a Monaco code editor in the same style as other EUI form fields.
*/
export const CodeEditorField: React.FunctionComponent<Props> = (props) => {
const { width, height, options, fullWidth } = props;
const darkMode = useUiSetting<boolean>('theme:darkMode');
const theme = darkMode ? darkTheme : lightTheme;
const style = {
width,
height,
backgroundColor: options?.readOnly
? theme.euiFormBackgroundReadOnlyColor
: theme.euiFormBackgroundColor,
};
return (
<EuiErrorBoundary>
<React.Suspense
fallback={
<EuiFormControlLayout
append={<div hidden />}
style={{ ...style, padding: theme.paddingSizes.m }}
readOnly={options?.readOnly}
>
<Fallback />
</EuiFormControlLayout>
}
>
<EuiFormControlLayout
append={<div hidden />}
style={style}
readOnly={options?.readOnly}
fullWidth={fullWidth}
>
<LazyBaseEditor {...props} useDarkTheme={darkMode} transparentBackground />
</EuiFormControlLayout>
<React.Suspense fallback={<Fallback height={props.height} />}>
<LazyCodeEditorField {...props} useDarkTheme={darkMode} />
</React.Suspense>
</EuiErrorBoundary>
);

View file

@ -0,0 +1,12 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
export { LANG as CssLang } from './css/constants';
export { LANG as MarkdownLang } from './markdown/constants';
export { LANG as YamlLang } from './yaml/constants';
export { LANG as HandlebarsLang } from './handlebars/constants';

View file

@ -66,7 +66,7 @@ export const UrlTemplateEditor: React.FC<UrlTemplateEditorProps> = ({
return;
}
const { dispose } = monaco.languages.registerCompletionItemProvider(HandlebarsLang.ID, {
const { dispose } = monaco.languages.registerCompletionItemProvider(HandlebarsLang, {
triggerCharacters: ['{', '/', '?', '&', '='],
provideCompletionItems(model, position, context, token) {
const { lineNumber } = position;
@ -124,7 +124,7 @@ export const UrlTemplateEditor: React.FC<UrlTemplateEditorProps> = ({
return (
<div className={'urlTemplateEditor__container'} onKeyDown={handleKeyDown}>
<Editor
languageId={HandlebarsLang.ID}
languageId={HandlebarsLang}
height={height}
value={value}
onChange={onChange}

View file

@ -116,7 +116,7 @@ export class MarkdownEditor extends Component {
<div className="tvbMarkdownEditor__editor">
<CodeEditor
editorDidMount={this.handleOnLoad}
languageId={MarkdownLang.ID}
languageId={MarkdownLang}
options={{
fontSize: '14px',
wordWrap: 'on',

View file

@ -262,7 +262,7 @@ export class MarkdownPanelConfig extends Component<
<EuiSpacer size="s" />
<CodeEditor
height="500px"
languageId={CssLang.ID}
languageId={CssLang}
options={{ fontSize: 14 }}
value={model.markdown_css ?? ''}
onChange={this.handleCSSChange}