1import { indentWithTab } from "@codemirror/commands";
2import { json, jsonParseLinter } from "@codemirror/lang-json";
3import { linter } from "@codemirror/lint";
4import { Compartment } from "@codemirror/state";
5import { keymap } from "@codemirror/view";
6import { basicDark } from "@fsegurai/codemirror-theme-basic-dark";
7import { basicLight } from "@fsegurai/codemirror-theme-basic-light";
8import { basicSetup, EditorView } from "codemirror";
9import { onCleanup, onMount } from "solid-js";
10import { editorInstance } from "./create/state";
11
12const Editor = (props: { content: string }) => {
13 let editorDiv!: HTMLDivElement;
14 let themeColor = new Compartment();
15 let view: EditorView;
16
17 const themeEvent = () => {
18 view.dispatch({
19 effects: themeColor.reconfigure(
20 window.matchMedia("(prefers-color-scheme: dark)").matches ? basicDark : basicLight,
21 ),
22 });
23 };
24
25 onMount(() => {
26 const theme = EditorView.theme({
27 ".cm-content": {
28 fontFamily: "'Roboto Mono', monospace",
29 fontSize: "12px",
30 },
31 ".cm-scroller": {
32 overflow: "auto",
33 },
34 "&": {
35 height: "100%",
36 },
37 });
38
39 window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change", themeEvent);
40
41 view = new EditorView({
42 doc: props.content,
43 parent: editorDiv,
44 extensions: [
45 basicSetup,
46 theme,
47 json(),
48 keymap.of([indentWithTab]),
49 linter(jsonParseLinter()),
50 themeColor.of(document.documentElement.classList.contains("dark") ? basicDark : basicLight),
51 ],
52 });
53 editorInstance.view = view;
54 });
55
56 onCleanup(() =>
57 window.matchMedia("(prefers-color-scheme: dark)").removeEventListener("change", themeEvent),
58 );
59
60 return (
61 <div
62 ref={editorDiv}
63 id="editor"
64 class="h-full cursor-auto border-[0.5px] border-neutral-300 dark:border-neutral-700"
65 ></div>
66 );
67};
68
69export { Editor };