Skip to content

Commit a52a80d

Browse files
committed
feat(CodeEditor): use custom PatternFly monaco theme
1 parent 2452955 commit a52a80d

File tree

2 files changed

+66
-2
lines changed

2 files changed

+66
-2
lines changed

packages/react-code-editor/src/components/CodeEditor/CodeEditor.tsx

+11-2
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import {
1313
import { Popover, PopoverProps } from '@patternfly/react-core/dist/esm/components/Popover';
1414
import { TooltipPosition } from '@patternfly/react-core/dist/esm/components/Tooltip';
1515
import { getResizeObserver } from '@patternfly/react-core/dist/esm/helpers/resizeObserver';
16-
import Editor, { EditorProps, Monaco } from '@monaco-editor/react';
16+
import Editor, { BeforeMount, EditorProps, Monaco } from '@monaco-editor/react';
1717
import type { editor } from 'monaco-editor';
1818
import CopyIcon from '@patternfly/react-icons/dist/esm/icons/copy-icon';
1919
import UploadIcon from '@patternfly/react-icons/dist/esm/icons/upload-icon';
@@ -23,6 +23,7 @@ import HelpIcon from '@patternfly/react-icons/dist/esm/icons/help-icon';
2323
import Dropzone, { FileRejection } from 'react-dropzone';
2424
import { CodeEditorContext } from './CodeEditorUtils';
2525
import { CodeEditorControl } from './CodeEditorControl';
26+
import { defineThemes } from './CodeEditorTheme';
2627

2728
export type ChangeHandler = (value: string, event: editor.IModelContentChangedEvent) => void;
2829
export type EditorDidMount = (editor: editor.IStandaloneCodeEditor, monaco: Monaco) => void;
@@ -366,13 +367,19 @@ export const CodeEditor = ({
366367
};
367368
}, []);
368369

370+
const editorBeforeMount: BeforeMount = (monaco) => {
371+
defineThemes(monaco.editor);
372+
editorProps?.beforeMount?.(monaco);
373+
};
374+
369375
const editorDidMount: EditorDidMount = (editor, monaco) => {
370376
// eslint-disable-next-line no-bitwise
371377
editor.addCommand(monaco.KeyMod.Shift | monaco.KeyCode.Tab, () => wrapperRef.current.focus());
372378
Array.from(document.getElementsByClassName('monaco-editor')).forEach((editorElement) =>
373379
editorElement.removeAttribute('role')
374380
);
375381
onEditorDidMount(editor, monaco);
382+
editorProps?.onMount?.(editor, monaco);
376383
editorRef.current = editor;
377384
if (height === 'sizeToFit') {
378385
setHeightToFitContent();
@@ -428,6 +435,7 @@ export const CodeEditor = ({
428435
};
429436

430437
const editorOptions: editor.IStandaloneEditorConstructionOptions = {
438+
fontFamily: 'var(--pf-t--global--font--family--mono)',
431439
scrollBeyondLastLine: height !== 'sizeToFit',
432440
readOnly: isReadOnly,
433441
cursorStyle: 'line',
@@ -570,8 +578,9 @@ export const CodeEditor = ({
570578
overrideServices={overrideServices}
571579
onChange={onModelChange}
572580
onMount={editorDidMount}
581+
beforeMount={editorBeforeMount}
573582
loading={loading}
574-
theme={isDarkTheme ? 'vs-dark' : 'vs-light'}
583+
theme={isDarkTheme ? 'pf-v6-theme-dark' : 'pf-v6-theme-light'}
575584
{...editorProps}
576585
/>
577586
</div>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
import green70 from '@patternfly/react-tokens/dist/esm/t_color_green_70';
2+
import yellow70 from '@patternfly/react-tokens/dist/esm/t_color_yellow_70';
3+
import blue70 from '@patternfly/react-tokens/dist/esm/t_color_blue_70';
4+
import purple70 from '@patternfly/react-tokens/dist/esm/t_color_purple_70';
5+
import green30 from '@patternfly/react-tokens/dist/esm/t_color_green_30';
6+
import blue30 from '@patternfly/react-tokens/dist/esm/t_color_blue_30';
7+
import yellow30 from '@patternfly/react-tokens/dist/esm/t_color_yellow_30';
8+
import purple30 from '@patternfly/react-tokens/dist/esm/t_color_purple_30';
9+
import white from '@patternfly/react-tokens/dist/esm/t_color_white';
10+
import gray20 from '@patternfly/react-tokens/dist/esm/t_color_gray_20';
11+
import gray60 from '@patternfly/react-tokens/dist/esm/t_color_gray_60';
12+
import gray90 from '@patternfly/react-tokens/dist/esm/t_color_gray_90';
13+
import black from '@patternfly/react-tokens/dist/esm/t_color_black';
14+
import type { editor as monacoEditor } from 'monaco-editor/esm/vs/editor/editor.api';
15+
16+
/**
17+
* Define the themes `pf-v6-theme-light` and
18+
* `pf-v6-theme-dark` for an instance of Monaco editor.
19+
*
20+
* Note that base tokens must be used as Monaco will throw a runtime
21+
* error for CSS variables.
22+
*/
23+
export const defineThemes = (editor: typeof monacoEditor) => {
24+
editor.defineTheme('pf-v6-theme-light', {
25+
base: 'vs',
26+
inherit: true,
27+
colors: {
28+
'editor.background': white.value,
29+
'editorLineNumber.activeForeground': black.value,
30+
'editorLineNumber.foreground': gray60.value
31+
},
32+
rules: [
33+
{ token: 'number', foreground: green70.value },
34+
{ token: 'type', foreground: yellow70.value },
35+
{ token: 'string', foreground: blue70.value },
36+
{ token: 'keyword', foreground: purple70.value }
37+
]
38+
});
39+
40+
editor.defineTheme('pf-v6-theme-dark', {
41+
base: 'vs-dark',
42+
inherit: true,
43+
colors: {
44+
'editor.background': gray90.value,
45+
'editorLineNumber.activeForeground': white.value,
46+
'editorLineNumber.foreground': gray20.value
47+
},
48+
rules: [
49+
{ token: 'number', foreground: green30.value },
50+
{ token: 'type', foreground: blue30.value },
51+
{ token: 'string', foreground: yellow30.value },
52+
{ token: 'keyword', foreground: purple30.value }
53+
]
54+
});
55+
};

0 commit comments

Comments
 (0)