9ff4c0dbd5
* Setup project-wide prettier * Remove old workspace file * Remove old debugging directives * New top-level .prettierignore * Updated Prettier config settings * Contrubuting guide: Fix for some bad code blocks * Added more ignores * Improved the format script command * printWidth set to 100 * Formatted entire repo (pnpm run format)
99 lines
2.3 KiB
TypeScript
99 lines
2.3 KiB
TypeScript
import { json as jsonLang } from "@codemirror/lang-json";
|
|
import type { ViewUpdate } from "@codemirror/view";
|
|
import type { ReactCodeMirrorProps, UseCodeMirror } from "@uiw/react-codemirror";
|
|
import { useCodeMirror } from "@uiw/react-codemirror";
|
|
import { useRef, useEffect } from "react";
|
|
import { getEditorSetup } from "./codeMirrorSetup";
|
|
import { darkTheme } from "./codeMirrorTheme";
|
|
import { cn } from "~/utils/cn";
|
|
|
|
export interface JSONEditorProps extends Omit<ReactCodeMirrorProps, "onBlur"> {
|
|
defaultValue?: string;
|
|
language?: "json";
|
|
readOnly?: boolean;
|
|
onChange?: (value: string) => void;
|
|
onUpdate?: (update: ViewUpdate) => void;
|
|
onBlur?: (code: string) => void;
|
|
}
|
|
|
|
const languages = {
|
|
json: jsonLang,
|
|
};
|
|
|
|
type JSONEditorDefaultProps = Partial<JSONEditorProps>;
|
|
|
|
const defaultProps: JSONEditorDefaultProps = {
|
|
language: "json",
|
|
readOnly: true,
|
|
basicSetup: false,
|
|
};
|
|
|
|
export function JSONEditor(opts: JSONEditorProps) {
|
|
const {
|
|
defaultValue = "",
|
|
language,
|
|
readOnly,
|
|
onChange,
|
|
onUpdate,
|
|
onBlur,
|
|
basicSetup,
|
|
autoFocus,
|
|
} = {
|
|
...defaultProps,
|
|
...opts,
|
|
};
|
|
|
|
const extensions = getEditorSetup();
|
|
|
|
if (!language) throw new Error("language is required");
|
|
const languageExtension = languages[language];
|
|
|
|
extensions.push(languageExtension());
|
|
|
|
const editor = useRef<HTMLDivElement>(null);
|
|
const settings: Omit<UseCodeMirror, "onBlur"> = {
|
|
...opts,
|
|
container: editor.current,
|
|
extensions,
|
|
editable: !readOnly,
|
|
contentEditable: !readOnly,
|
|
value: defaultValue,
|
|
autoFocus,
|
|
theme: darkTheme(),
|
|
indentWithTab: false,
|
|
basicSetup,
|
|
onChange,
|
|
onUpdate,
|
|
};
|
|
const { setContainer, state } = useCodeMirror(settings);
|
|
|
|
useEffect(() => {
|
|
if (editor.current) {
|
|
setContainer(editor.current);
|
|
}
|
|
}, [setContainer]);
|
|
|
|
//if the defaultValue changes update the editor
|
|
useEffect(() => {
|
|
if (state !== undefined) {
|
|
state.update({
|
|
changes: { from: 0, to: state.doc.length, insert: defaultValue },
|
|
});
|
|
}
|
|
}, [defaultValue, state]);
|
|
|
|
return (
|
|
<div
|
|
className={cn(
|
|
"overflow-y-auto scrollbar-thin scrollbar-track-transparent scrollbar-thumb-slate-700",
|
|
opts.className
|
|
)}
|
|
ref={editor}
|
|
onBlur={() => {
|
|
if (!onBlur) return;
|
|
onBlur(editor.current?.textContent ?? "");
|
|
}}
|
|
/>
|
|
);
|
|
}
|