| import { Compartment, type Extension } from '@codemirror/state'; | |
| import { EditorView } from '@codemirror/view'; | |
| import { vscodeDark, vscodeLight } from '@uiw/codemirror-theme-vscode'; | |
| import type { Theme } from '~/types/theme.js'; | |
| import type { EditorSettings } from './CodeMirrorEditor.js'; | |
| export const darkTheme = EditorView.theme({}, { dark: true }); | |
| export const themeSelection = new Compartment(); | |
| export function getTheme(theme: Theme, settings: EditorSettings = {}): Extension { | |
| return [ | |
| getEditorTheme(settings), | |
| theme === 'dark' ? themeSelection.of([getDarkTheme()]) : themeSelection.of([getLightTheme()]), | |
| ]; | |
| } | |
| export function reconfigureTheme(theme: Theme) { | |
| return themeSelection.reconfigure(theme === 'dark' ? getDarkTheme() : getLightTheme()); | |
| } | |
| function getEditorTheme(settings: EditorSettings) { | |
| return EditorView.theme({ | |
| '&': { | |
| fontSize: settings.fontSize ?? '12px', | |
| }, | |
| '&.cm-editor': { | |
| height: '100%', | |
| background: 'var(--cm-backgroundColor)', | |
| color: 'var(--cm-textColor)', | |
| }, | |
| '.cm-cursor': { | |
| borderLeft: 'var(--cm-cursor-width) solid var(--cm-cursor-backgroundColor)', | |
| }, | |
| '.cm-scroller': { | |
| lineHeight: '1.5', | |
| '&:focus-visible': { | |
| outline: 'none', | |
| }, | |
| }, | |
| '.cm-line': { | |
| padding: '0 0 0 4px', | |
| }, | |
| '&.cm-focused > .cm-scroller > .cm-selectionLayer .cm-selectionBackground': { | |
| backgroundColor: 'var(--cm-selection-backgroundColorFocused) !important', | |
| opacity: 'var(--cm-selection-backgroundOpacityFocused, 0.3)', | |
| }, | |
| '&:not(.cm-focused) > .cm-scroller > .cm-selectionLayer .cm-selectionBackground': { | |
| backgroundColor: 'var(--cm-selection-backgroundColorBlured)', | |
| opacity: 'var(--cm-selection-backgroundOpacityBlured, 0.3)', | |
| }, | |
| '&.cm-focused > .cm-scroller .cm-matchingBracket': { | |
| backgroundColor: 'var(--cm-matching-bracket)', | |
| }, | |
| '.cm-activeLine': { | |
| background: 'var(--cm-activeLineBackgroundColor)', | |
| }, | |
| '.cm-gutters': { | |
| background: 'var(--cm-gutter-backgroundColor)', | |
| borderRight: 0, | |
| color: 'var(--cm-gutter-textColor)', | |
| }, | |
| '.cm-gutter': { | |
| '&.cm-lineNumbers': { | |
| fontFamily: 'Roboto Mono, monospace', | |
| fontSize: settings.gutterFontSize ?? settings.fontSize ?? '12px', | |
| minWidth: '40px', | |
| }, | |
| '& .cm-activeLineGutter': { | |
| background: 'transparent', | |
| color: 'var(--cm-gutter-activeLineTextColor)', | |
| }, | |
| '&.cm-foldGutter .cm-gutterElement > .fold-icon': { | |
| cursor: 'pointer', | |
| color: 'var(--cm-foldGutter-textColor)', | |
| transform: 'translateY(2px)', | |
| '&:hover': { | |
| color: 'var(--cm-foldGutter-textColorHover)', | |
| }, | |
| }, | |
| }, | |
| '.cm-foldGutter .cm-gutterElement': { | |
| padding: '0 4px', | |
| }, | |
| '.cm-tooltip-autocomplete > ul > li': { | |
| minHeight: '18px', | |
| }, | |
| '.cm-panel.cm-search label': { | |
| marginLeft: '2px', | |
| fontSize: '12px', | |
| }, | |
| '.cm-panel.cm-search .cm-button': { | |
| fontSize: '12px', | |
| }, | |
| '.cm-panel.cm-search .cm-textfield': { | |
| fontSize: '12px', | |
| }, | |
| '.cm-panel.cm-search input[type=checkbox]': { | |
| position: 'relative', | |
| transform: 'translateY(2px)', | |
| marginRight: '4px', | |
| }, | |
| '.cm-panels': { | |
| borderColor: 'var(--cm-panels-borderColor)', | |
| }, | |
| '.cm-panels-bottom': { | |
| borderTop: '1px solid var(--cm-panels-borderColor)', | |
| backgroundColor: 'transparent', | |
| }, | |
| '.cm-panel.cm-search': { | |
| background: 'var(--cm-search-backgroundColor)', | |
| color: 'var(--cm-search-textColor)', | |
| padding: '8px', | |
| }, | |
| '.cm-search .cm-button': { | |
| background: 'var(--cm-search-button-backgroundColor)', | |
| borderColor: 'var(--cm-search-button-borderColor)', | |
| color: 'var(--cm-search-button-textColor)', | |
| borderRadius: '4px', | |
| '&:hover': { | |
| color: 'var(--cm-search-button-textColorHover)', | |
| }, | |
| '&:focus-visible': { | |
| outline: 'none', | |
| borderColor: 'var(--cm-search-button-borderColorFocused)', | |
| }, | |
| '&:hover:not(:focus-visible)': { | |
| background: 'var(--cm-search-button-backgroundColorHover)', | |
| borderColor: 'var(--cm-search-button-borderColorHover)', | |
| }, | |
| '&:hover:focus-visible': { | |
| background: 'var(--cm-search-button-backgroundColorHover)', | |
| borderColor: 'var(--cm-search-button-borderColorFocused)', | |
| }, | |
| }, | |
| '.cm-panel.cm-search [name=close]': { | |
| top: '6px', | |
| right: '6px', | |
| padding: '0 6px', | |
| fontSize: '1rem', | |
| backgroundColor: 'var(--cm-search-closeButton-backgroundColor)', | |
| color: 'var(--cm-search-closeButton-textColor)', | |
| '&:hover': { | |
| 'border-radius': '6px', | |
| color: 'var(--cm-search-closeButton-textColorHover)', | |
| backgroundColor: 'var(--cm-search-closeButton-backgroundColorHover)', | |
| }, | |
| }, | |
| '.cm-search input': { | |
| background: 'var(--cm-search-input-backgroundColor)', | |
| borderColor: 'var(--cm-search-input-borderColor)', | |
| color: 'var(--cm-search-input-textColor)', | |
| outline: 'none', | |
| borderRadius: '4px', | |
| '&:focus-visible': { | |
| borderColor: 'var(--cm-search-input-borderColorFocused)', | |
| }, | |
| }, | |
| '.cm-tooltip': { | |
| background: 'var(--cm-tooltip-backgroundColor)', | |
| border: '1px solid transparent', | |
| borderColor: 'var(--cm-tooltip-borderColor)', | |
| color: 'var(--cm-tooltip-textColor)', | |
| }, | |
| '.cm-tooltip.cm-tooltip-autocomplete ul li[aria-selected]': { | |
| background: 'var(--cm-tooltip-backgroundColorSelected)', | |
| color: 'var(--cm-tooltip-textColorSelected)', | |
| }, | |
| '.cm-searchMatch': { | |
| backgroundColor: 'var(--cm-searchMatch-backgroundColor)', | |
| }, | |
| '.cm-tooltip.cm-readonly-tooltip': { | |
| padding: '4px', | |
| whiteSpace: 'nowrap', | |
| backgroundColor: 'var(--bolt-elements-bg-depth-2)', | |
| borderColor: 'var(--bolt-elements-borderColorActive)', | |
| '& .cm-tooltip-arrow:before': { | |
| borderTopColor: 'var(--bolt-elements-borderColorActive)', | |
| }, | |
| '& .cm-tooltip-arrow:after': { | |
| borderTopColor: 'transparent', | |
| }, | |
| }, | |
| }); | |
| } | |
| function getLightTheme() { | |
| return vscodeLight; | |
| } | |
| function getDarkTheme() { | |
| return vscodeDark; | |
| } | |