From c45fc71f4ff41e8f0950fff9549ee6458472afc3 Mon Sep 17 00:00:00 2001 From: Innei Date: Wed, 12 Apr 2023 23:08:27 +0800 Subject: [PATCH] feat: support monaco theme toggle Signed-off-by: Innei --- src/components/common/Monaco/index.tsx | 7 + src/components/common/Monaco/theme/dark.json | 244 ++++++++++++++++++ src/components/common/Monaco/theme/light.json | 98 +++++++ src/components/common/Monaco/use-theme.ts | 32 +++ .../dashboard/[subdomain]/settings/css.tsx | 6 +- 5 files changed, 385 insertions(+), 2 deletions(-) create mode 100644 src/components/common/Monaco/index.tsx create mode 100644 src/components/common/Monaco/theme/dark.json create mode 100644 src/components/common/Monaco/theme/light.json create mode 100644 src/components/common/Monaco/use-theme.ts diff --git a/src/components/common/Monaco/index.tsx b/src/components/common/Monaco/index.tsx new file mode 100644 index 00000000..f6f02bea --- /dev/null +++ b/src/components/common/Monaco/index.tsx @@ -0,0 +1,7 @@ +import Editor, { EditorProps } from "@monaco-editor/react" +import { useMonacoTheme } from "./use-theme" + +export function MonacoEditor(props: EditorProps) { + useMonacoTheme() + return +} diff --git a/src/components/common/Monaco/theme/dark.json b/src/components/common/Monaco/theme/dark.json new file mode 100644 index 00000000..56285ba6 --- /dev/null +++ b/src/components/common/Monaco/theme/dark.json @@ -0,0 +1,244 @@ +{ + "base": "vs-dark", + "inherit": true, + "rules": [ + { + "background": "000000", + "token": "" + }, + { + "foreground": "969896", + "token": "comment" + }, + { + "foreground": "eeeeee", + "token": "keyword.operator.class" + }, + { + "foreground": "eeeeee", + "token": "constant.other" + }, + { + "foreground": "eeeeee", + "token": "source.php.embedded.line" + }, + { + "foreground": "d54e53", + "token": "variable" + }, + { + "foreground": "d54e53", + "token": "support.other.variable" + }, + { + "foreground": "d54e53", + "token": "string.other.link" + }, + { + "foreground": "d54e53", + "token": "string.regexp" + }, + { + "foreground": "d54e53", + "token": "entity.name.tag" + }, + { + "foreground": "d54e53", + "token": "entity.other.attribute-name" + }, + { + "foreground": "d54e53", + "token": "meta.tag" + }, + { + "foreground": "d54e53", + "token": "declaration.tag" + }, + { + "foreground": "d54e53", + "token": "markup.deleted.git_gutter" + }, + { + "foreground": "e78c45", + "token": "constant.numeric" + }, + { + "foreground": "e78c45", + "token": "constant.language" + }, + { + "foreground": "e78c45", + "token": "support.constant" + }, + { + "foreground": "e78c45", + "token": "constant.character" + }, + { + "foreground": "e78c45", + "token": "variable.parameter" + }, + { + "foreground": "e78c45", + "token": "punctuation.section.embedded" + }, + { + "foreground": "e78c45", + "token": "keyword.other.unit" + }, + { + "foreground": "e7c547", + "token": "entity.name.class" + }, + { + "foreground": "e7c547", + "token": "entity.name.type.class" + }, + { + "foreground": "e7c547", + "token": "support.type" + }, + { + "foreground": "e7c547", + "token": "support.class" + }, + { + "foreground": "b9ca4a", + "token": "string" + }, + { + "foreground": "b9ca4a", + "token": "constant.other.symbol" + }, + { + "foreground": "b9ca4a", + "token": "entity.other.inherited-class" + }, + { + "foreground": "b9ca4a", + "token": "markup.heading" + }, + { + "foreground": "b9ca4a", + "token": "markup.inserted.git_gutter" + }, + { + "foreground": "70c0b1", + "token": "keyword.operator" + }, + { + "foreground": "70c0b1", + "token": "constant.other.color" + }, + { + "foreground": "7aa6da", + "token": "entity.name.function" + }, + { + "foreground": "7aa6da", + "token": "meta.function-call" + }, + { + "foreground": "7aa6da", + "token": "support.function" + }, + { + "foreground": "7aa6da", + "token": "keyword.other.special-method" + }, + { + "foreground": "7aa6da", + "token": "meta.block-level" + }, + { + "foreground": "7aa6da", + "token": "markup.changed.git_gutter" + }, + { + "foreground": "c397d8", + "token": "keyword" + }, + { + "foreground": "c397d8", + "token": "storage" + }, + { + "foreground": "c397d8", + "token": "storage.type" + }, + { + "foreground": "c397d8", + "token": "entity.name.tag.css" + }, + { + "foreground": "ced2cf", + "background": "df5f5f", + "token": "invalid" + }, + { + "foreground": "ced2cf", + "background": "82a3bf", + "token": "meta.separator" + }, + { + "foreground": "ced2cf", + "background": "b798bf", + "token": "invalid.deprecated" + }, + { + "foreground": "ffffff", + "token": "markup.inserted.diff" + }, + { + "foreground": "ffffff", + "token": "markup.deleted.diff" + }, + { + "foreground": "ffffff", + "token": "meta.diff.header.to-file" + }, + { + "foreground": "ffffff", + "token": "meta.diff.header.from-file" + }, + { + "foreground": "718c00", + "token": "markup.inserted.diff" + }, + { + "foreground": "718c00", + "token": "meta.diff.header.to-file" + }, + { + "foreground": "c82829", + "token": "markup.deleted.diff" + }, + { + "foreground": "c82829", + "token": "meta.diff.header.from-file" + }, + { + "foreground": "ffffff", + "background": "4271ae", + "token": "meta.diff.header.from-file" + }, + { + "foreground": "ffffff", + "background": "4271ae", + "token": "meta.diff.header.to-file" + }, + { + "foreground": "3e999f", + "fontStyle": "italic", + "token": "meta.diff.range" + } + ], + "colors": { + "editor.foreground": "#DEDEDE", + "editor.background": "#00000000", + "editor.selectionBackground": "#424242", + "editor.lineHighlightBackground": "#2A2A2A", + "editorCursor.foreground": "#9F9F9F", + "editorWhitespace.foreground": "#343434" + } +} diff --git a/src/components/common/Monaco/theme/light.json b/src/components/common/Monaco/theme/light.json new file mode 100644 index 00000000..779b419c --- /dev/null +++ b/src/components/common/Monaco/theme/light.json @@ -0,0 +1,98 @@ +{ + "base": "vs", + "inherit": true, + "rules": [ + { + "background": "FFFFFF", + "token": "" + }, + { + "foreground": "008e00", + "token": "comment" + }, + { + "foreground": "7d4726", + "token": "meta.preprocessor" + }, + { + "foreground": "7d4726", + "token": "keyword.control.import" + }, + { + "foreground": "df0002", + "token": "string" + }, + { + "foreground": "3a00dc", + "token": "constant.numeric" + }, + { + "foreground": "c800a4", + "token": "constant.language" + }, + { + "foreground": "275a5e", + "token": "constant.character" + }, + { + "foreground": "275a5e", + "token": "constant.other" + }, + { + "foreground": "c800a4", + "token": "variable.language" + }, + { + "foreground": "c800a4", + "token": "variable.other" + }, + { + "foreground": "c800a4", + "token": "keyword" + }, + { + "foreground": "c900a4", + "token": "storage" + }, + { + "foreground": "438288", + "token": "entity.name.class" + }, + { + "foreground": "790ead", + "token": "entity.name.tag" + }, + { + "foreground": "450084", + "token": "entity.other.attribute-name" + }, + { + "foreground": "450084", + "token": "support.function" + }, + { + "foreground": "450084", + "token": "support.constant" + }, + { + "foreground": "790ead", + "token": "support.type" + }, + { + "foreground": "790ead", + "token": "support.class" + }, + { + "foreground": "790ead", + "token": "support.other.variable" + } + ], + "colors": { + "editor.foreground": "#000000", + "editor.background": "#FFFFFF00", + "editor.selectionBackground": "#B5D5FF", + "editor.lineHighlightBackground": "#00000012", + "editorCursor.foreground": "#000000", + "editorWhitespace.foreground": "#BFBFBF" + } +} diff --git a/src/components/common/Monaco/use-theme.ts b/src/components/common/Monaco/use-theme.ts new file mode 100644 index 00000000..db5fd906 --- /dev/null +++ b/src/components/common/Monaco/use-theme.ts @@ -0,0 +1,32 @@ +import { useMonaco } from "@monaco-editor/react" +import { useEffect } from "react" +import { useMediaStore } from "~/hooks/useDarkMode" +import Dark from "./theme/dark.json" +import Light from "./theme/light.json" + +const set = new Set() +const useDefineTheme = (theme: string, json: any) => { + const monaco = useMonaco() + useEffect(() => { + if (set.has(theme)) { + return + } + + if (monaco) { + monaco.editor.defineTheme(theme, json) + + set.add(theme) + } + }, [monaco, theme]) +} + +export const useMonacoTheme = () => { + useDefineTheme("light", Light) + useDefineTheme("dark", Dark) + const isDark = useMediaStore((state) => state.isDark) + const monaco = useMonaco() + + useEffect(() => { + monaco?.editor.setTheme(isDark ? "dark" : "light") + }, [monaco, isDark]) +} diff --git a/src/pages/dashboard/[subdomain]/settings/css.tsx b/src/pages/dashboard/[subdomain]/settings/css.tsx index 462cb4ed..01e316a9 100644 --- a/src/pages/dashboard/[subdomain]/settings/css.tsx +++ b/src/pages/dashboard/[subdomain]/settings/css.tsx @@ -5,13 +5,14 @@ import { DashboardLayout } from "~/components/dashboard/DashboardLayout" import { SettingsLayout } from "~/components/dashboard/SettingsLayout" import { Button } from "~/components/ui/Button" import { useGetSite, useUpdateSite } from "~/queries/site" -import Editor from "@monaco-editor/react" + import { FieldLabel } from "~/components/ui/FieldLabel" import type { ReactElement } from "react" import { useTranslation } from "next-i18next" import { getServerSideProps as getLayoutServerSideProps } from "~/components/dashboard/DashboardLayout.server" import { GetServerSideProps } from "next" import { serverSidePropsHandler } from "~/lib/server-side-props" +import { MonacoEditor } from "~/components/common/Monaco" export const getServerSideProps: GetServerSideProps = serverSidePropsHandler( async (ctx) => { @@ -106,13 +107,14 @@ export default function SettingsCSSPage() {

- setCss(value || "")} options={{ fontSize: 14, + minimap: { enabled: false }, }} />