From 34330d9d1fadedb1445449f8c706d85065d24837 Mon Sep 17 00:00:00 2001 From: Dariusz Niemczyk Date: Wed, 29 Jan 2025 21:02:29 +0100 Subject: [PATCH] feat: cleanup theme effects --- src/components/nav.tsx | 48 +++++++++++++++++++++++++++--------------- 1 file changed, 31 insertions(+), 17 deletions(-) diff --git a/src/components/nav.tsx b/src/components/nav.tsx index 1808893..f261e99 100644 --- a/src/components/nav.tsx +++ b/src/components/nav.tsx @@ -1,9 +1,9 @@ "use client" import { Button } from "@/components/ui/button" -import type { translations } from "@/i18n/translations" +import { Sections, type translations } from "@/i18n/translations" import { cn } from "@/lib/utils" import { MoonIcon, SunIcon } from "lucide-react" -import { useEffect, useState } from "react" +import { useCallback, useEffect, useState } from "react" import { MobileNav } from "./mobile-nav" const linksOrder: Array = [ @@ -16,29 +16,43 @@ const linksOrder: Array = [ "contact", ] -export function Nav({ - t, -}: { - t: typeof translations.pl -}) { +function useTheme(): [theme: "light" | "dark", setTheme: (theme: "light" | "dark") => void] { + /* eslint-disable react-hooks/rules-of-hooks */ + if (typeof window === "undefined") return ["dark", () => { }] const [theme, setTheme] = useState<"light" | "dark">("dark") - const [activeSection, setActiveSection] = useState("about") + + const root = window.document.documentElement + + const changeTheme = useCallback((theme: "light" | "dark") => { + root.classList.remove("light", "dark") + root.classList.add(theme) + }, [root]) useEffect(() => { // Determine the user's preferred color scheme const preferredTheme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light" setTheme(preferredTheme) - const root = window.document.documentElement - root.classList.remove("light", "dark") - root.classList.add(preferredTheme) - }, []) + changeTheme(preferredTheme) + }, [changeTheme]) + + const updateTheme = useCallback((theme: "light" | "dark") => { + setTheme(theme) + changeTheme(theme) + }, [changeTheme, setTheme]) + + return [theme, updateTheme] + /* eslint-enable react-hooks/rules-of-hooks */ +} + +export function Nav({ + t, +}: { + t: typeof translations.pl +}) { + const [theme, setTheme] = useTheme() + const [activeSection, setActiveSection] = useState("about") - useEffect(() => { - const root = window.document.documentElement - root.classList.remove("light", "dark") - root.classList.add(theme) - }, [theme]) useEffect(() => { const options = {