feat: implement light and dark theme (#30)
This commit is contained in:
@@ -34,6 +34,7 @@ export interface EditorDocument {
|
||||
|
||||
export interface EditorSettings {
|
||||
fontSize?: string;
|
||||
gutterFontSize?: string;
|
||||
tabSize?: number;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,11 +1,8 @@
|
||||
import { defaultHighlightStyle, syntaxHighlighting } from '@codemirror/language';
|
||||
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';
|
||||
import { vscodeDarkTheme } from './themes/vscode-dark.js';
|
||||
|
||||
import './styles.css';
|
||||
|
||||
export const darkTheme = EditorView.theme({}, { dark: true });
|
||||
export const themeSelection = new Compartment();
|
||||
@@ -23,11 +20,9 @@ export function reconfigureTheme(theme: Theme) {
|
||||
|
||||
function getEditorTheme(settings: EditorSettings) {
|
||||
return EditorView.theme({
|
||||
...(settings.fontSize && {
|
||||
'&': {
|
||||
fontSize: settings.fontSize,
|
||||
},
|
||||
}),
|
||||
'&': {
|
||||
fontSize: settings.fontSize ?? '12px',
|
||||
},
|
||||
'&.cm-editor': {
|
||||
height: '100%',
|
||||
background: 'var(--cm-backgroundColor)',
|
||||
@@ -46,7 +41,7 @@ function getEditorTheme(settings: EditorSettings) {
|
||||
padding: '0 0 0 4px',
|
||||
},
|
||||
'&.cm-focused > .cm-scroller > .cm-selectionLayer .cm-selectionBackground': {
|
||||
backgroundColor: 'var(--cm-selection-backgroundColorFocused)',
|
||||
backgroundColor: 'var(--cm-selection-backgroundColorFocused) !important',
|
||||
opacity: 'var(--cm-selection-backgroundOpacityFocused, 0.3)',
|
||||
},
|
||||
'&:not(.cm-focused) > .cm-scroller > .cm-selectionLayer .cm-selectionBackground': {
|
||||
@@ -67,7 +62,7 @@ function getEditorTheme(settings: EditorSettings) {
|
||||
'.cm-gutter': {
|
||||
'&.cm-lineNumbers': {
|
||||
fontFamily: 'Roboto Mono, monospace',
|
||||
fontSize: '13px',
|
||||
fontSize: settings.gutterFontSize ?? settings.fontSize ?? '12px',
|
||||
minWidth: '40px',
|
||||
},
|
||||
'& .cm-activeLineGutter': {
|
||||
@@ -91,6 +86,13 @@ function getEditorTheme(settings: EditorSettings) {
|
||||
},
|
||||
'.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',
|
||||
@@ -100,10 +102,14 @@ function getEditorTheme(settings: EditorSettings) {
|
||||
'.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: '6px 8px',
|
||||
padding: '8px',
|
||||
},
|
||||
'.cm-search .cm-button': {
|
||||
background: 'var(--cm-search-button-backgroundColor)',
|
||||
@@ -130,6 +136,7 @@ function getEditorTheme(settings: EditorSettings) {
|
||||
top: '6px',
|
||||
right: '6px',
|
||||
padding: '0 6px',
|
||||
fontSize: '1rem',
|
||||
backgroundColor: 'var(--cm-search-closeButton-backgroundColor)',
|
||||
color: 'var(--cm-search-closeButton-textColor)',
|
||||
'&:hover': {
|
||||
@@ -141,6 +148,7 @@ function getEditorTheme(settings: EditorSettings) {
|
||||
'.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': {
|
||||
@@ -149,6 +157,7 @@ function getEditorTheme(settings: EditorSettings) {
|
||||
},
|
||||
'.cm-tooltip': {
|
||||
background: 'var(--cm-tooltip-backgroundColor)',
|
||||
border: '1px solid transparent',
|
||||
borderColor: 'var(--cm-tooltip-borderColor)',
|
||||
color: 'var(--cm-tooltip-textColor)',
|
||||
},
|
||||
@@ -156,13 +165,16 @@ function getEditorTheme(settings: EditorSettings) {
|
||||
background: 'var(--cm-tooltip-backgroundColorSelected)',
|
||||
color: 'var(--cm-tooltip-textColorSelected)',
|
||||
},
|
||||
'.cm-searchMatch': {
|
||||
backgroundColor: 'var(--cm-searchMatch-backgroundColor)',
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
function getLightTheme() {
|
||||
return syntaxHighlighting(defaultHighlightStyle);
|
||||
return vscodeLight;
|
||||
}
|
||||
|
||||
function getDarkTheme() {
|
||||
return syntaxHighlighting(vscodeDarkTheme);
|
||||
return vscodeDark;
|
||||
}
|
||||
|
||||
@@ -1,133 +0,0 @@
|
||||
:root {
|
||||
--cm-backgroundColor: var(--bolt-elements-editor-backgroundColor, var(--bolt-elements-app-backgroundColor));
|
||||
--cm-textColor: var(--bolt-elements-editor-textColor, var(--bolt-text-primary));
|
||||
|
||||
/* Gutter */
|
||||
|
||||
--cm-gutter-backgroundColor: var(--bolt-elements-editor-gutter-backgroundColor, var(--cm-backgroundColor));
|
||||
--cm-gutter-textColor: var(--bolt-elements-editor-gutter-textColor, var(--bolt-text-secondary));
|
||||
--cm-gutter-activeLineTextColor: var(--bolt-elements-editor-gutter-activeLineTextColor, var(--cm-gutter-textColor));
|
||||
|
||||
/* Fold Gutter */
|
||||
|
||||
--cm-foldGutter-textColor: var(--bolt-elements-editor-foldGutter-textColor, var(--cm-gutter-textColor));
|
||||
--cm-foldGutter-textColorHover: var(--bolt-elements-editor-foldGutter-textColorHover, var(--cm-gutter-textColor));
|
||||
|
||||
/* Active Line */
|
||||
|
||||
--cm-activeLineBackgroundColor: var(--bolt-elements-editor-activeLineBackgroundColor, rgb(224 231 235 / 30%));
|
||||
|
||||
/* Cursor */
|
||||
|
||||
--cm-cursor-width: 2px;
|
||||
--cm-cursor-backgroundColor: var(--bolt-elements-editor-cursorColor, var(--bolt-text-primary));
|
||||
|
||||
/* Matching Brackets */
|
||||
|
||||
--cm-matching-bracket: var(--bolt-elements-editor-matchingBracketBackgroundColor, rgb(50 140 130 / 0.3));
|
||||
|
||||
/* Selection */
|
||||
|
||||
--cm-selection-backgroundColorFocused: var(--bolt-elements-editor-selection-backgroundColor, #42b4ff);
|
||||
--cm-selection-backgroundOpacityFocused: var(--bolt-elements-editor-selection-backgroundOpacity, 0.3);
|
||||
--cm-selection-backgroundColorBlured: var(--bolt-elements-editor-selection-inactiveBackgroundColor, #c9e9ff);
|
||||
--cm-selection-backgroundOpacityBlured: var(--bolt-elements-editor-selection-inactiveBackgroundOpacity, 0.3);
|
||||
|
||||
/* Panels */
|
||||
|
||||
--cm-panels-borderColor: var(--bolt-elements-editor-panels-borderColor, var(--bolt-elements-app-borderColor));
|
||||
|
||||
/* Search */
|
||||
|
||||
--cm-search-backgroundColor: var(--bolt-elements-editor-search-backgroundColor, var(--cm-backgroundColor));
|
||||
--cm-search-textColor: var(--bolt-elements-editor-search-textColor, var(--bolt-elements-app-textColor));
|
||||
--cm-search-closeButton-backgroundColor: var(--bolt-elements-editor-search-closeButton-backgroundColor, transparent);
|
||||
|
||||
--cm-search-closeButton-backgroundColorHover: var(
|
||||
--bolt-elements-editor-search-closeButton-backgroundColorHover,
|
||||
var(--bolt-background-secondary)
|
||||
);
|
||||
|
||||
--cm-search-closeButton-textColor: var(
|
||||
--bolt-elements-editor-search-closeButton-textColor,
|
||||
var(--bolt-text-secondary)
|
||||
);
|
||||
|
||||
--cm-search-closeButton-textColorHover: var(
|
||||
--bolt-elements-editor-search-closeButton-textColorHover,
|
||||
var(--bolt-text-primary)
|
||||
);
|
||||
|
||||
--cm-search-button-backgroundColor: var(
|
||||
--bolt-elements-editor-search-button-backgroundColor,
|
||||
var(--bolt-background-secondary)
|
||||
);
|
||||
|
||||
--cm-search-button-backgroundColorHover: var(
|
||||
--bolt-elements-editor-search-button-backgroundColorHover,
|
||||
var(--bolt-background-active)
|
||||
);
|
||||
|
||||
--cm-search-button-textColor: var(--bolt-elements-editor-search-button-textColor, var(--bolt-text-secondary));
|
||||
--cm-search-button-textColorHover: var(--bolt-elements-editor-search-button-textColorHover, var(--bolt-text-primary));
|
||||
--cm-search-button-borderColor: var(--bolt-elements-editor-search-button-borderColor, transparent);
|
||||
|
||||
--cm-search-button-borderColorHover: var(
|
||||
--bolt-elements-editor-search-button-borderColorHover,
|
||||
var(--cm-search-button-borderColor)
|
||||
);
|
||||
|
||||
--cm-search-button-borderColorFocused: var(
|
||||
--bolt-elements-editor-search-button-borderColorFocused,
|
||||
var(--bolt-border-accent)
|
||||
);
|
||||
|
||||
--cm-search-input-backgroundColor: var(
|
||||
--bolt-elements-editor-search-input-backgroundColor,
|
||||
var(--bolt-background-primary)
|
||||
);
|
||||
|
||||
--cm-search-input-borderColor: var(
|
||||
--bolt-elements-editor-search-input-borderColor,
|
||||
var(--bolt-elements-app-borderColor)
|
||||
);
|
||||
|
||||
--cm-search-input-borderColorFocused: var(
|
||||
--bolt-elements-editor-search-input-borderColorFocused,
|
||||
var(--bolt-border-accent)
|
||||
);
|
||||
|
||||
/* Tooltip */
|
||||
|
||||
--cm-tooltip-backgroundColor: var(
|
||||
--bolt-elements-editor-tooltip-backgroundColor,
|
||||
var(--bolt-elements-app-backgroundColor)
|
||||
);
|
||||
|
||||
--cm-tooltip-textColor: var(--bolt-elements-editor-tooltip-textColor, var(--bolt-text-primary));
|
||||
|
||||
--cm-tooltip-backgroundColorSelected: var(
|
||||
--bolt-elements-editor-tooltip-backgroundColorSelected,
|
||||
var(--bolt-background-accent)
|
||||
);
|
||||
|
||||
--cm-tooltip-textColorSelected: var(
|
||||
--bolt-elements-editor-tooltip-textColorSelected,
|
||||
var(--bolt-text-primary-inverted)
|
||||
);
|
||||
|
||||
--cm-tooltip-borderColor: var(--bolt-elements-editor-tooltip-borderColor, var(--bolt-elements-app-borderColor));
|
||||
}
|
||||
|
||||
html[data-theme='light'] {
|
||||
--bolt-elements-editor-gutter-textColor: #237893;
|
||||
--bolt-elements-editor-gutter-activeLineTextColor: var(--bolt-text-primary);
|
||||
--bolt-elements-editor-foldGutter-textColorHover: var(--bolt-text-primary);
|
||||
}
|
||||
|
||||
html[data-theme='dark'] {
|
||||
--bolt-elements-editor-gutter-activeLineTextColor: var(--bolt-text-primary);
|
||||
--bolt-elements-editor-selection-backgroundOpacityBlured: 0.1;
|
||||
--bolt-elements-editor-activeLineBackgroundColor: rgb(50 53 63 / 50%);
|
||||
--bolt-elements-editor-foldGutter-textColorHover: var(--bolt-text-primary);
|
||||
}
|
||||
@@ -1,76 +0,0 @@
|
||||
import { HighlightStyle } from '@codemirror/language';
|
||||
import { tags } from '@lezer/highlight';
|
||||
|
||||
export const vscodeDarkTheme = HighlightStyle.define([
|
||||
{
|
||||
tag: [
|
||||
tags.keyword,
|
||||
tags.operatorKeyword,
|
||||
tags.modifier,
|
||||
tags.color,
|
||||
tags.constant(tags.name),
|
||||
tags.standard(tags.name),
|
||||
tags.standard(tags.tagName),
|
||||
tags.special(tags.brace),
|
||||
tags.atom,
|
||||
tags.bool,
|
||||
tags.special(tags.variableName),
|
||||
],
|
||||
color: '#569cd6',
|
||||
},
|
||||
{
|
||||
tag: [tags.controlKeyword, tags.moduleKeyword],
|
||||
color: '#c586c0',
|
||||
},
|
||||
{
|
||||
tag: [
|
||||
tags.name,
|
||||
tags.deleted,
|
||||
tags.character,
|
||||
tags.macroName,
|
||||
tags.propertyName,
|
||||
tags.variableName,
|
||||
tags.labelName,
|
||||
tags.definition(tags.name),
|
||||
],
|
||||
color: '#9cdcfe',
|
||||
},
|
||||
{ tag: tags.heading, fontWeight: 'bold', color: '#9cdcfe' },
|
||||
{
|
||||
tag: [
|
||||
tags.typeName,
|
||||
tags.className,
|
||||
tags.tagName,
|
||||
tags.number,
|
||||
tags.changed,
|
||||
tags.annotation,
|
||||
tags.self,
|
||||
tags.namespace,
|
||||
],
|
||||
color: '#4ec9b0',
|
||||
},
|
||||
{
|
||||
tag: [tags.function(tags.variableName), tags.function(tags.propertyName)],
|
||||
color: '#dcdcaa',
|
||||
},
|
||||
{ tag: [tags.number], color: '#b5cea8' },
|
||||
{
|
||||
tag: [tags.operator, tags.punctuation, tags.separator, tags.url, tags.escape, tags.regexp],
|
||||
color: '#d4d4d4',
|
||||
},
|
||||
{
|
||||
tag: [tags.regexp],
|
||||
color: '#d16969',
|
||||
},
|
||||
{
|
||||
tag: [tags.special(tags.string), tags.processingInstruction, tags.string, tags.inserted],
|
||||
color: '#ce9178',
|
||||
},
|
||||
{ tag: [tags.angleBracket], color: '#808080' },
|
||||
{ tag: tags.strong, fontWeight: 'bold' },
|
||||
{ tag: tags.emphasis, fontStyle: 'italic' },
|
||||
{ tag: tags.strikethrough, textDecoration: 'line-through' },
|
||||
{ tag: [tags.meta, tags.comment], color: '#6a9955' },
|
||||
{ tag: tags.link, color: '#6a9955', textDecoration: 'underline' },
|
||||
{ tag: tags.invalid, color: '#ff0000' },
|
||||
]);
|
||||
Reference in New Issue
Block a user