diff --git a/packages/grafana-ui/src/components/Monaco/CodeEditor.tsx b/packages/grafana-ui/src/components/Monaco/CodeEditor.tsx index ac205345b50..e8ee8ccf047 100644 --- a/packages/grafana-ui/src/components/Monaco/CodeEditor.tsx +++ b/packages/grafana-ui/src/components/Monaco/CodeEditor.tsx @@ -1,15 +1,17 @@ import React from 'react'; - +import { withTheme2 } from '../../themes'; +import { Themeable2 } from '../../types'; import { selectors } from '@grafana/e2e-selectors'; -import { withTheme } from '../../themes'; -import { Themeable } from '../../types'; +import { GrafanaTheme2 } from '@grafana/data'; import { Monaco, MonacoEditor as MonacoEditorType, CodeEditorProps, MonacoOptions } from './types'; import { registerSuggestions } from './suggestions'; import MonacoEditor, { loader as monacoEditorLoader } from '@monaco-editor/react'; import type * as monacoType from 'monaco-editor/esm/vs/editor/editor.api'; +import defineThemes from './theme'; +import { css } from '@emotion/css'; -type Props = CodeEditorProps & Themeable; +type Props = CodeEditorProps & Themeable2; let initalized = false; function initMonoco() { @@ -71,7 +73,8 @@ class UnthemedCodeEditor extends React.PureComponent { handleBeforeMount = (monaco: Monaco) => { this.monaco = monaco; - const { language, getSuggestions } = this.props; + const { language, theme, getSuggestions } = this.props; + defineThemes(monaco, theme); if (getSuggestions) { this.completionCancel = registerSuggestions(monaco, language, getSuggestions); @@ -99,6 +102,8 @@ class UnthemedCodeEditor extends React.PureComponent { const value = this.props.value ?? ''; const longText = value.length > 100; + const styles = getStyles(theme); + const options: MonacoOptions = { wordWrap: 'off', tabSize: 2, @@ -112,26 +117,29 @@ class UnthemedCodeEditor extends React.PureComponent { readOnly, lineNumbersMinChars: 4, - lineDecorationsWidth: 0, + lineDecorationsWidth: 1 * theme.spacing.gridSize, overviewRulerBorder: false, automaticLayout: true, + padding: { + top: 0.5 * theme.spacing.gridSize, + bottom: 0.5 * theme.spacing.gridSize, + }, }; if (!showLineNumbers) { options.glyphMargin = false; options.folding = false; options.lineNumbers = 'off'; - options.lineDecorationsWidth = 5; // left margin when not showing line numbers options.lineNumbersMinChars = 0; } return ( -
+
{ } } -export default withTheme(UnthemedCodeEditor); +export default withTheme2(UnthemedCodeEditor); + +const getStyles = (theme: GrafanaTheme2) => { + return { + container: css` + border-radius: ${theme.shape.borderRadius()}; + border: 1px solid ${theme.components.input.borderColor}; + `, + }; +}; diff --git a/packages/grafana-ui/src/components/Monaco/theme.ts b/packages/grafana-ui/src/components/Monaco/theme.ts new file mode 100644 index 00000000000..d2d828c352c --- /dev/null +++ b/packages/grafana-ui/src/components/Monaco/theme.ts @@ -0,0 +1,24 @@ +import { GrafanaTheme2 } from '@grafana/data'; +import { Monaco } from './types'; + +export default function defineThemes(monaco: Monaco, theme: GrafanaTheme2) { + // color tokens are defined here https://github.com/microsoft/vscode/blob/main/src/vs/platform/theme/common/colorRegistry.ts#L174 + const colors = { + 'editor.background': theme.components.input.background, + 'minimap.background': theme.colors.background.secondary, + }; + + monaco.editor.defineTheme('grafana-dark', { + base: 'vs-dark', + inherit: true, + colors: colors, + rules: [], + }); + + monaco.editor.defineTheme('grafana-light', { + base: 'vs', + inherit: true, + colors: colors, + rules: [], + }); +}