atproto explorer pdsls.dev
atproto tool
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"; 10 11export let editorView: EditorView; 12 13const Editor = (props: { content: string }) => { 14 let editorDiv!: HTMLDivElement; 15 let themeColor = new Compartment(); 16 17 const themeEvent = () => { 18 editorView.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 maxHeight: "20rem", 34 }, 35 }); 36 37 window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change", themeEvent); 38 39 editorView = new EditorView({ 40 doc: props.content, 41 parent: editorDiv, 42 extensions: [ 43 basicSetup, 44 theme, 45 json(), 46 keymap.of([indentWithTab]), 47 linter(jsonParseLinter()), 48 themeColor.of(document.documentElement.classList.contains("dark") ? basicDark : basicLight), 49 ], 50 }); 51 }); 52 53 onCleanup(() => 54 window.matchMedia("(prefers-color-scheme: dark)").removeEventListener("change", themeEvent), 55 ); 56 57 return ( 58 <div 59 ref={editorDiv} 60 id="editor" 61 class="dark:shadow-dark-700 cursor-auto border-[0.5px] border-neutral-300 shadow-xs dark:border-neutral-700" 62 ></div> 63 ); 64}; 65 66export { Editor };