feat: styles
This commit is contained in:
@@ -1,11 +1,55 @@
|
||||
import { useEffect, useRef } from "react";
|
||||
import { EditorView, keymap } from "@codemirror/view";
|
||||
import { EditorState } from "@codemirror/state";
|
||||
import { EditorView, keymap, lineNumbers, highlightActiveLine, Decoration, ViewPlugin } from "@codemirror/view";
|
||||
import { EditorState, RangeSetBuilder } from "@codemirror/state";
|
||||
import type { Extension } from "@codemirror/state";
|
||||
import type { DecorationSet } from "@codemirror/view";
|
||||
import { defaultKeymap, history, historyKeymap } from "@codemirror/commands";
|
||||
import { searchKeymap } from "@codemirror/search";
|
||||
import { oneDark } from "./oneDarkTheme";
|
||||
|
||||
function toRoman(n: number): string {
|
||||
const vals = [1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1];
|
||||
const syms = ["M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I"];
|
||||
let result = "";
|
||||
for (let i = 0; i < vals.length; i++) {
|
||||
while (n >= vals[i]) {
|
||||
result += syms[i];
|
||||
n -= vals[i];
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
const dotDeco = Decoration.mark({ class: "cm-dot-space" });
|
||||
|
||||
function buildSpaceDeco(view: EditorView): DecorationSet {
|
||||
const builder = new RangeSetBuilder<Decoration>();
|
||||
for (const { from, to } of view.visibleRanges) {
|
||||
const text = view.state.sliceDoc(from, to);
|
||||
for (let i = 0; i < text.length; i++) {
|
||||
if (text[i] === " ") {
|
||||
builder.add(from + i, from + i + 1, dotDeco);
|
||||
}
|
||||
}
|
||||
}
|
||||
return builder.finish();
|
||||
}
|
||||
|
||||
const subtleWhitespace = ViewPlugin.fromClass(
|
||||
class {
|
||||
decorations: DecorationSet;
|
||||
constructor(view: EditorView) {
|
||||
this.decorations = buildSpaceDeco(view);
|
||||
}
|
||||
update(update: { docChanged: boolean; viewportChanged: boolean; view: EditorView }) {
|
||||
if (update.docChanged || update.viewportChanged) {
|
||||
this.decorations = buildSpaceDeco(update.view);
|
||||
}
|
||||
}
|
||||
},
|
||||
{ decorations: (v) => v.decorations },
|
||||
);
|
||||
|
||||
interface Props {
|
||||
value: string;
|
||||
onChange: (value: string) => void;
|
||||
@@ -25,6 +69,9 @@ export default function EditorPane({ value, onChange, extensions = [] }: Props)
|
||||
doc: value,
|
||||
extensions: [
|
||||
history(),
|
||||
lineNumbers({ formatNumber: toRoman }),
|
||||
highlightActiveLine(),
|
||||
subtleWhitespace,
|
||||
keymap.of([...defaultKeymap, ...historyKeymap, ...searchKeymap]),
|
||||
oneDark,
|
||||
EditorView.updateListener.of((update) => {
|
||||
@@ -49,6 +96,20 @@ export default function EditorPane({ value, onChange, extensions = [] }: Props)
|
||||
borderLeftColor: "var(--primary)",
|
||||
borderLeftWidth: "0.5em",
|
||||
},
|
||||
".cm-dot-space": {
|
||||
color: "transparent",
|
||||
position: "relative",
|
||||
},
|
||||
".cm-dot-space:before": {
|
||||
content: '"\\22C5"',
|
||||
position: "absolute",
|
||||
left: "0",
|
||||
right: "0",
|
||||
textAlign: "center",
|
||||
color: "var(--muted-foreground)",
|
||||
opacity: "0.5",
|
||||
pointerEvents: "none",
|
||||
},
|
||||
}),
|
||||
...extensions,
|
||||
],
|
||||
|
||||
@@ -3,26 +3,27 @@ import { EditorView } from "@codemirror/view";
|
||||
export const oneDark = EditorView.theme(
|
||||
{
|
||||
"&": {
|
||||
backgroundColor: "#0d1117",
|
||||
color: "#c9d1d9",
|
||||
backgroundColor: "var(--background)",
|
||||
color: "var(--foreground)",
|
||||
},
|
||||
".cm-cursor, .cm-cursor-primary": {
|
||||
borderLeftColor: "var(--primary)",
|
||||
borderLeftWidth: "0.5em",
|
||||
},
|
||||
".cm-selectionBackground, &.cm-focused .cm-selectionBackground": {
|
||||
backgroundColor: "#264f78",
|
||||
backgroundColor: "color-mix(in oklch, var(--primary) 25%, transparent)",
|
||||
},
|
||||
".cm-activeLine": {
|
||||
backgroundColor: "#161b2266",
|
||||
backgroundColor: "color-mix(in oklch, var(--primary) 8%, transparent)",
|
||||
},
|
||||
".cm-gutters": {
|
||||
backgroundColor: "#0d1117",
|
||||
color: "#484f58",
|
||||
borderRight: "1px solid #21262d",
|
||||
backgroundColor: "var(--background)",
|
||||
color: "var(--muted-foreground)",
|
||||
borderRight: "1px solid var(--border)",
|
||||
},
|
||||
".cm-activeLineGutter": {
|
||||
backgroundColor: "#161b2266",
|
||||
backgroundColor: "color-mix(in oklch, var(--primary) 8%, transparent)",
|
||||
color: "var(--primary)",
|
||||
},
|
||||
},
|
||||
{ dark: true }
|
||||
|
||||
Reference in New Issue
Block a user