devrun Theme

This commit is contained in:
2026-02-06 18:20:41 +01:00
parent 00deda5df1
commit 5e412f1cd9
5 changed files with 243 additions and 10 deletions
@@ -0,0 +1,105 @@
import { EditorView } from "@codemirror/view";
import { Extension } from "@codemirror/state";
import {
HighlightStyle,
TagStyle,
syntaxHighlighting,
} from "@codemirror/language";
interface Options {
/**
* Theme variant. Determines which styles CodeMirror will apply by default.
*/
variant: Variant;
/**
* Settings to customize the look of the editor, like background, gutter, selection and others.
*/
settings: Settings;
/**
* Syntax highlighting styles.
*/
styles: TagStyle[];
}
type Variant = "light" | "dark";
interface Settings {
/**
* Editor background.
*/
background: string;
/**
* Default text color.
*/
foreground: string;
/**
* Caret color.
*/
caret: string;
/**
* Selection background.
*/
selection: string;
/**
* Background of highlighted lines.
*/
lineHighlight: string;
/**
* Gutter background.
*/
gutterBackground: string;
/**
* Text color inside gutter.
*/
gutterForeground: string;
}
const createTheme = ({ variant, settings, styles }: Options): Extension => {
const theme = EditorView.theme(
{
// eslint-disable-next-line @typescript-eslint/naming-convention
"&": {
backgroundColor: settings.background,
color: settings.foreground,
},
".cm-content": {
caretColor: settings.caret,
},
".cm-cursor, .cm-dropCursor": {
borderLeftColor: settings.caret,
},
"&.cm-focused .cm-selectionBackgroundm .cm-selectionBackground, .cm-content ::selection":
{
backgroundColor: settings.selection,
},
".cm-activeLine": {
backgroundColor: settings.lineHighlight,
},
".cm-gutters": {
backgroundColor: settings.gutterBackground,
color: settings.gutterForeground,
},
".cm-activeLineGutter": {
backgroundColor: settings.lineHighlight,
},
},
{
dark: variant === "dark",
},
);
const highlightStyle = HighlightStyle.define(styles);
const extension = [theme, syntaxHighlighting(highlightStyle)];
return extension;
};
export default createTheme;
+81
View File
@@ -0,0 +1,81 @@
import { tags as t } from "@lezer/highlight";
import createTheme from "./create-theme";
// Original theme: thememirror (dracula)
export const devRun = createTheme({
variant: "dark",
settings: {
background: "var(--card)", // stays app-integrated
foreground: "#e6e6eb",
caret: "var(--primary)",
selection: "rgba(120, 120, 150, 0.25)",
gutterBackground: "var(--card)",
gutterForeground: "rgb(120, 122, 128)",
lineHighlight: "rgba(255, 255, 255, 0.03)",
},
styles: [
// Comments — low priority, low contrast
{
tag: t.comment,
color: "#5f6a8a",
fontStyle: "italic",
},
// Strings & literals — data, not logic
{
tag: [t.string, t.special(t.brace)],
color: "#f4e58c",
},
// Numbers / booleans — benchmarks & truth
{
tag: [t.number, t.bool, t.null],
color: "#c792ea",
fontWeight: "500",
},
// Keywords & operators — decisions & flow
{
tag: [t.keyword, t.operator],
color: "#ff5fa2",
fontWeight: "600",
},
// Types & definitions — structure
{
tag: [t.definitionKeyword, t.typeName],
color: "#6be6ff",
},
// Type definitions — neutral, readable
{
tag: t.definition(t.typeName),
color: "#e6e6eb",
},
// Functions, classes, props — execution paths
{
tag: [
t.className,
t.definition(t.propertyName),
t.function(t.variableName),
t.attributeName,
],
color: "#4dff9f",
fontWeight: "500",
},
// Variables — slightly muted, context-aware
{
tag: t.variableName,
color: "#cfd3dc",
},
// Invalid / errors — instant attention
{
tag: t.invalid,
color: "#ff5555",
fontWeight: "700",
},
],
});
+22 -5
View File
@@ -1,14 +1,13 @@
"use client";
import CodeMirror, { EditorState } from "@uiw/react-codemirror";
import { vscodeDark } from "@uiw/codemirror-theme-vscode";
import { Card, CardContent } from "@/components/ui/card";
import RunTimer, { RunInfo } from "./components/RunTimer";
import RunChat, { ChatMessage } from "./components/RunChat";
import { useState } from "react";
import { FileTree } from "./components/FileTree";
import { File } from "lucide-react";
import { devRun } from "./components/theme/theme";
import { javascript } from "@codemirror/lang-javascript";
export default function Run() {
const runInfo: RunInfo = {
@@ -58,8 +57,26 @@ export default function Run() {
<CodeMirror
readOnly
className="h-full w-full"
value="yo"
value={`// Import the necessary React library features
import { createRoot } from 'react-dom/client';
// Define a functional component named "App"
// Component names must start with a capital letter
function App() {
// Components return JSX markup
return (
<h1>Hello, world!</h1>
);
}
// Target a DOM element in your HTML (e.g., <div id="root"></div>)
const domNode = document.getElementById('root');
// Create a root and render your component into the DOM
const root = createRoot(domNode);
root.render(<App />); `}
extensions={[
javascript(),
EditorState.transactionFilter.of((tr) => {
if (tr.selection && tr.isUserEvent("select")) {
return [];
@@ -67,7 +84,7 @@ export default function Run() {
return tr;
}),
]}
theme={vscodeDark}
theme={devRun}
onCreateEditor={(view) => {
view.focus();
view.dispatch({