From 3ea88314ebbc5b3324009f9b8edf575c6229651d Mon Sep 17 00:00:00 2001 From: 1ilit <1ilit@proton.me> Date: Wed, 18 Jun 2025 16:08:12 +0400 Subject: [PATCH] Refactor theming (#497) --- src/App.jsx | 42 +------------------- src/components/EditorCanvas/Canvas.jsx | 4 +- src/components/EditorCanvas/Relationship.jsx | 6 +-- src/components/EditorHeader/ControlPanel.jsx | 18 +-------- src/context/SettingsContext.jsx | 4 ++ src/hooks/index.js | 1 + src/hooks/useThemedPage.js | 13 ++++++ src/pages/BugReport.jsx | 12 ++++-- src/pages/Editor.jsx | 3 ++ 9 files changed, 36 insertions(+), 67 deletions(-) create mode 100644 src/hooks/useThemedPage.js diff --git a/src/App.jsx b/src/App.jsx index 0678c6a..fcb0981 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -5,7 +5,6 @@ import BugReport from "./pages/BugReport"; import Templates from "./pages/Templates"; import LandingPage from "./pages/LandingPage"; import SettingsContextProvider from "./context/SettingsContext"; -import { useSettings } from "./hooks"; import NotFound from "./pages/NotFound"; export default function App() { @@ -15,22 +14,8 @@ export default function App() { } /> - - - - } - /> - - - - } - /> + } /> + } /> } /> } /> @@ -39,29 +24,6 @@ export default function App() { ); } -function ThemedPage({ children }) { - const { setSettings } = useSettings(); - - useLayoutEffect(() => { - const theme = localStorage.getItem("theme"); - if (theme === "dark") { - setSettings((prev) => ({ ...prev, mode: "dark" })); - const body = document.body; - if (body.hasAttribute("theme-mode")) { - body.setAttribute("theme-mode", "dark"); - } - } else { - setSettings((prev) => ({ ...prev, mode: "light" })); - const body = document.body; - if (body.hasAttribute("theme-mode")) { - body.setAttribute("theme-mode", "light"); - } - } - }, [setSettings]); - - return children; -} - function RestoreScroll() { const location = useLocation(); useLayoutEffect(() => { diff --git a/src/components/EditorCanvas/Canvas.jsx b/src/components/EditorCanvas/Canvas.jsx index fb45870..c9e4d0e 100644 --- a/src/components/EditorCanvas/Canvas.jsx +++ b/src/components/EditorCanvas/Canvas.jsx @@ -708,15 +708,13 @@ export default function Canvas() { { passive: false }, ); - const theme = localStorage.getItem("theme"); - return (
{ - const body = document.body; - if (body.hasAttribute("theme-mode")) { - body.setAttribute("theme-mode", "light"); - } - localStorage.setItem("theme", "light"); - setSettings((prev) => ({ ...prev, mode: "light" })); - }, + function: () => setSettings((prev) => ({ ...prev, mode: "light" })), }, { name: t("dark"), - function: () => { - const body = document.body; - if (body.hasAttribute("theme-mode")) { - body.setAttribute("theme-mode", "dark"); - } - localStorage.setItem("theme", "dark"); - setSettings((prev) => ({ ...prev, mode: "dark" })); - }, + function: () => setSettings((prev) => ({ ...prev, mode: "dark" })), }, ], function: () => {}, diff --git a/src/context/SettingsContext.jsx b/src/context/SettingsContext.jsx index 9bd224a..0ad31bd 100644 --- a/src/context/SettingsContext.jsx +++ b/src/context/SettingsContext.jsx @@ -28,6 +28,10 @@ export default function SettingsContextProvider({ children }) { } }, []); + useEffect(() => { + document.body.setAttribute("theme-mode", settings.mode); + }, [settings.mode]); + useEffect(() => { localStorage.setItem("settings", JSON.stringify(settings)); }, [settings]); diff --git a/src/hooks/index.js b/src/hooks/index.js index e21eee1..d24b45c 100644 --- a/src/hooks/index.js +++ b/src/hooks/index.js @@ -12,3 +12,4 @@ export { default as useTransform } from "./useTransform"; export { default as useTypes } from "./useTypes"; export { default as useUndoRedo } from "./useUndoRedo"; export { default as useEnums } from "./useEnums"; +export { default as useThemedPage } from "./useThemedPage"; diff --git a/src/hooks/useThemedPage.js b/src/hooks/useThemedPage.js new file mode 100644 index 0000000..e92f8e5 --- /dev/null +++ b/src/hooks/useThemedPage.js @@ -0,0 +1,13 @@ +import { useLayoutEffect } from "react"; +import useSettings from "./useSettings"; + +/** + * Adds the `theme-mode` attribute to the body element for semi-ui dark theme + */ +export default function useThemedPage() { + const { settings } = useSettings(); + + useLayoutEffect(() => { + document.body.setAttribute("theme-mode", settings.mode); + }, [settings]); +} diff --git a/src/pages/BugReport.jsx b/src/pages/BugReport.jsx index 9d76dc5..20a6a56 100644 --- a/src/pages/BugReport.jsx +++ b/src/pages/BugReport.jsx @@ -12,6 +12,7 @@ import { CLEAR_EDITOR_COMMAND } from "lexical"; import { Link } from "react-router-dom"; import { socials } from "../data/socials"; import { send } from "../api/email"; +import { useSettings, useThemedPage } from "../hooks"; function Form({ theme }) { const [editor] = useLexicalComposerContext(); @@ -85,7 +86,7 @@ function Form({ theme }) { value={data.title} onChange={(v) => setData((prev) => ({ ...prev, title: v }))} /> - + { - setTheme(localStorage.getItem("theme")); document.title = "Report a bug | drawDB"; document.body.setAttribute("class", "theme"); - }, [setTheme]); + }, []); + + useThemedPage(); return ( <> diff --git a/src/pages/Editor.jsx b/src/pages/Editor.jsx index 000a50d..24b5afe 100644 --- a/src/pages/Editor.jsx +++ b/src/pages/Editor.jsx @@ -10,8 +10,11 @@ import TasksContextProvider from "../context/TasksContext"; import SaveStateContextProvider from "../context/SaveStateContext"; import EnumsContextProvider from "../context/EnumsContext"; import WorkSpace from "../components/Workspace"; +import { useThemedPage } from "../hooks"; export default function Editor() { + useThemedPage(); + return (