diff --git a/app/components/theme-switch.tsx b/app/components/theme-switch.tsx
index 03d51fb..9483b0c 100644
--- a/app/components/theme-switch.tsx
+++ b/app/components/theme-switch.tsx
@@ -2,91 +2,190 @@
import * as React from "react";
import { useTheme } from "next-themes";
import { ThemeProvider as NextThemesProvider } from "next-themes";
-import type { ThemeProviderProps } from "next-themes";
import { FaCircleHalfStroke } from "react-icons/fa6";
-const storageKey = 'theme-preference';
+// Key to store user preference in localStorage
+const storageKey = "theme-preference";
+
+// ThemeProvider component
+export function ThemeProvider({ children }: { children: React.ReactNode }) {
+ const [mounted, setMounted] = React.useState(false);
+
+ React.useEffect(() => {
+ // Ensures the component renders only after the theme is determined
+ setMounted(true);
+ }, []);
+
+ if (!mounted) {
+ // Hide content until theme is mounted to prevent mismatches
+ return
{children}
;
+ }
-export function ThemeProvider({ children, ...props }: ThemeProviderProps) {
return (
{children}
);
}
+// ThemeSwitch component
export const ThemeSwitch: React.FC = () => {
- const { setTheme } = useTheme();
- const [mounted, setMounted] = React.useState(false);
- const [currentTheme, setCurrentTheme] = React.useState<'light' | 'dark'>('light');
-
- const getColorPreference = (): 'light' | 'dark' => {
- if (typeof window !== 'undefined') {
- const storedPreference = localStorage.getItem(storageKey);
- if (storedPreference) {
- return storedPreference as 'light' | 'dark';
- }
- return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
- }
- return 'light';
- };
+ const { theme, setTheme, systemTheme } = useTheme();
+ const [currentTheme, setCurrentTheme] = React.useState<"light" | "dark">("light");
- const reflectPreference = (theme: 'light' | 'dark') => {
- document.documentElement.classList.remove('bg-light', 'bg-dark');
- document.documentElement.classList.add(`bg-${theme}`);
- setCurrentTheme(theme);
- setTheme(theme);
- };
+ // Reflects preference based on system or manual choice
+ const reflectPreference = React.useCallback((newTheme: "light" | "dark") => {
+ document.documentElement.classList.remove("bg-light", "bg-dark");
+ document.documentElement.classList.add(`bg-${newTheme}`);
+ setCurrentTheme(newTheme);
+ setTheme(newTheme);
+ }, [setTheme]);
+ // Determine initial theme preference
React.useEffect(() => {
- setMounted(true);
- const initTheme = getColorPreference();
- reflectPreference(initTheme);
+ const storedPreference = localStorage.getItem(storageKey) as "light" | "dark" | null;
+ const systemPreference = window.matchMedia("(prefers-color-scheme: dark)").matches
+ ? "dark"
+ : "light";
- const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
+ const initialTheme = storedPreference || systemPreference;
+ reflectPreference(initialTheme);
+
+ // Watch for system theme changes
+ const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
const handleChange = () => {
- const newTheme = mediaQuery.matches ? 'dark' : 'light';
- localStorage.setItem(storageKey, newTheme);
- reflectPreference(newTheme);
+ const newTheme = mediaQuery.matches ? "dark" : "light";
+ if (!storedPreference) reflectPreference(newTheme);
};
- mediaQuery.addEventListener('change', handleChange);
-
- return () => mediaQuery.removeEventListener('change', handleChange);
- }, [setTheme]);
+ mediaQuery.addEventListener("change", handleChange);
+ return () => mediaQuery.removeEventListener("change", handleChange);
+ }, [reflectPreference]);
+ // Toggle between themes
const toggleTheme = () => {
- const newTheme = currentTheme === 'light' ? 'dark' : 'light';
+ const newTheme = currentTheme === "light" ? "dark" : "light";
localStorage.setItem(storageKey, newTheme);
reflectPreference(newTheme);
};
- if (!mounted) {
- return (
-
- );
- }
-
return (
);
-};
\ No newline at end of file
+};
+
+// The theme toggle system using next-themes that:
+
+// Automatically detects and applies the system theme (light/dark) on the first load.
+// Dynamically updates the theme when the system theme changes.
+// Allows manual toggling of the theme by the user, with the preference saved to localStorage.
+// This includes both the ThemeProvider and ThemeSwitch components.
+
+// *REMOVE PROPS --> [LAYOUT.TSX]
+
+// -----------------------------------------------------------------------------------------------------------------BEFORE (HYDRATION ERROR) (ABOVE CODE - WITHOUT HYDRATION ERROR)
+// "use client";
+// import * as React from "react";
+// import { useTheme } from "next-themes";
+// import { ThemeProvider as NextThemesProvider } from "next-themes";
+// import type { ThemeProviderProps } from "next-themes";
+// import { FaCircleHalfStroke } from "react-icons/fa6";
+
+// const storageKey = 'theme-preference';
+
+// export function ThemeProvider({ children, ...props }: ThemeProviderProps) {
+// return (
+//
+// {children}
+//
+// );
+// }
+
+// export const ThemeSwitch: React.FC = () => {
+// const { setTheme } = useTheme();
+// const [mounted, setMounted] = React.useState(false);
+// const [currentTheme, setCurrentTheme] = React.useState<'light' | 'dark'>('light');
+
+// const getColorPreference = (): 'light' | 'dark' => {
+// if (typeof window !== 'undefined') {
+// const storedPreference = localStorage.getItem(storageKey);
+// if (storedPreference) {
+// return storedPreference as 'light' | 'dark';
+// }
+// return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
+// }
+// return 'light';
+// };
+
+// const reflectPreference = (theme: 'light' | 'dark') => {
+// document.documentElement.classList.remove('bg-light', 'bg-dark');
+// document.documentElement.classList.add(`bg-${theme}`);
+// setCurrentTheme(theme);
+// setTheme(theme);
+// };
+
+// React.useEffect(() => {
+// setMounted(true);
+// const initTheme = getColorPreference();
+// reflectPreference(initTheme);
+
+// const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
+// const handleChange = () => {
+// const newTheme = mediaQuery.matches ? 'dark' : 'light';
+// localStorage.setItem(storageKey, newTheme);
+// reflectPreference(newTheme);
+// };
+
+// mediaQuery.addEventListener('change', handleChange);
+
+// return () => mediaQuery.removeEventListener('change', handleChange);
+// }, [setTheme]);
+
+// const toggleTheme = () => {
+// const newTheme = currentTheme === 'light' ? 'dark' : 'light';
+// localStorage.setItem(storageKey, newTheme);
+// reflectPreference(newTheme);
+// };
+
+// if (!mounted) {
+// return (
+//
+// );
+// }
+
+// return (
+//
+// );
+// };
diff --git a/app/layout.tsx b/app/layout.tsx
index 43c2323..31a9035 100644
--- a/app/layout.tsx
+++ b/app/layout.tsx
@@ -75,12 +75,7 @@ export default function RootLayout({
/>
-
+
{children}
@@ -93,3 +88,11 @@ export default function RootLayout({
);
}
+
+// --------------------------------------BEFORE UPDATED THEME-SWITCH.TSX
+// [not using props]