editor theme selector

This commit is contained in:
kachbit 2023-11-19 14:30:10 -08:00
parent 168d4b035b
commit 6f5c0cb063
4 changed files with 44 additions and 8 deletions

View File

@ -34,6 +34,7 @@ function App() {
const [settings, setSettings] = useState<Settings>({
openAiApiKey: null,
isImageGenerationEnabled: true,
editorTheme: "cobalt"
});
const downloadCode = () => {
@ -231,7 +232,7 @@ function App() {
<Preview code={generatedCode} device="mobile" />
</TabsContent>
<TabsContent value="code">
<CodeMirror code={generatedCode} />
<CodeMirror code={generatedCode} editorTheme={settings.editorTheme} />
</TabsContent>
</Tabs>
</div>

View File

@ -2,6 +2,8 @@ import { useRef, useEffect } from "react";
import { EditorState } from "@codemirror/state";
import { EditorView, keymap, lineNumbers } from "@codemirror/view";
import { espresso } from "thememirror";
import { cobalt } from "thememirror";
import {
defaultKeymap,
history,
@ -14,14 +16,19 @@ import { html } from "@codemirror/lang-html";
interface Props {
code: string;
editorTheme: string;
}
function CodeMirror({ code }: Props) {
function CodeMirror({ code, editorTheme }: Props) {
const ref = useRef<HTMLDivElement>(null);
const view = useRef<EditorView | null>(null);
// Initialize the editor when the component mounts
useEffect(() => {
let selectedTheme = cobalt;
if (editorTheme === "espresso") {
selectedTheme = espresso;
}
view.current = new EditorView({
state: EditorState.create({
doc: code,
@ -36,7 +43,7 @@ function CodeMirror({ code }: Props) {
lineNumbers(),
bracketMatching(),
html(),
espresso,
selectedTheme,
EditorView.lineWrapping,
],
}),
@ -49,9 +56,8 @@ function CodeMirror({ code }: Props) {
view.current = null;
}
};
}, []);
}, [code, editorTheme]);
// Update the contents of the editor when the code changes
useEffect(() => {
if (view.current && view.current.state.doc.toString() !== code) {
view.current.dispatch({
@ -60,6 +66,9 @@ function CodeMirror({ code }: Props) {
}
}, [code]);
return <div className="overflow-x-scroll overflow-y-scroll mx-2 border-[4px] border-black rounded-[20px]" ref={ref} />;
return (
<div className="overflow-x-scroll overflow-y-scroll mx-2 border-[4px] border-black rounded-[20px]" ref={ref} />
);
}
export default CodeMirror;
export default CodeMirror;

View File

@ -1,3 +1,4 @@
import React from "react";
import {
Dialog,
DialogClose,
@ -12,6 +13,7 @@ import { Settings } from "../types";
import { Switch } from "./ui/switch";
import { Label } from "./ui/label";
import { Input } from "./ui/input";
import { Select } from "./ui/select";
interface Props {
settings: Settings;
@ -19,6 +21,13 @@ interface Props {
}
function SettingsDialog({ settings, setSettings }: Props) {
const handleThemeChange = (theme: string) => {
setSettings((s) => ({
...s,
editorTheme: theme,
}));
};
return (
<Dialog>
<DialogTrigger>
@ -65,7 +74,23 @@ function SettingsDialog({ settings, setSettings }: Props) {
}))
}
/>
<Label htmlFor="editor-theme">
<div>Editor Theme</div>
</Label>
<div>
<Select // Use the custom Select component here
id="editor-theme"
value={settings.editorTheme}
onChange={(e: React.ChangeEvent<HTMLSelectElement>) =>
handleThemeChange(e.target.value)
}
>
<option value="cobalt">Cobalt</option>
<option value="espresso">Espresso</option>
</Select>
</div>
</div>
<DialogFooter>
<DialogClose>Save</DialogClose>
</DialogFooter>

View File

@ -1,4 +1,5 @@
export interface Settings {
openAiApiKey: string | null;
isImageGenerationEnabled: boolean;
editorTheme: string;
}