diff --git a/src/components/ThemeSelector.tsx b/src/components/ThemeSelector.tsx
index 0ea96ab..a9c8d37 100644
--- a/src/components/ThemeSelector.tsx
+++ b/src/components/ThemeSelector.tsx
@@ -1,6 +1,23 @@
import { useEffect, useState } from "react";
-type Theme = "dark" | "light";
+type Theme = "dark" | "light" | "automatic";
+
+const DiagonalSplitPreview = () => {
+ return (
+
+ );
+};
const ThemeOption = ({
value,
@@ -12,7 +29,7 @@ const ThemeOption = ({
}: {
value: Theme;
label: string;
- previewColor: string;
+ previewColor: string | "diagonalSplit";
theme: Theme;
setTheme: (theme: Theme) => void;
isLast?: boolean;
@@ -40,10 +57,16 @@ const ThemeOption = ({
>
{/* Preview Box */}
-
+
+ {previewColor === "diagonalSplit" ? (
+
+ ) : (
+
+ )}
+
{/* Label */}
{label}
@@ -68,19 +91,66 @@ const ThemeOption = ({
);
};
+function getSystemTheme(): "dark" | "light" {
+ if (typeof window === "undefined") return "dark";
+ return window.matchMedia("(prefers-color-scheme: dark)").matches
+ ? "dark"
+ : "light";
+}
+
+function getEffectiveTheme(theme: Theme): "dark" | "light" {
+ if (theme === "automatic") {
+ return getSystemTheme();
+ }
+ return theme;
+}
+
export function ThemeSelector() {
const [theme, setTheme] = useState
(() => {
const saved = localStorage.getItem("theme") as Theme | null;
- return saved || "dark";
+ // Default to "automatic" if no saved preference
+ return saved || "automatic";
});
useEffect(() => {
- document.documentElement.setAttribute("data-theme", theme);
+ const effectiveTheme = getEffectiveTheme(theme);
+ document.documentElement.setAttribute("data-theme", effectiveTheme);
localStorage.setItem("theme", theme);
}, [theme]);
+ // Listen to system theme changes when "automatic" is selected
+ useEffect(() => {
+ if (theme !== "automatic") return;
+
+ const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
+ const handleChange = () => {
+ if (theme === "automatic") {
+ const newSystemTheme = getSystemTheme();
+ document.documentElement.setAttribute("data-theme", newSystemTheme);
+ }
+ };
+
+ // Modern browsers
+ if (mediaQuery.addEventListener) {
+ mediaQuery.addEventListener("change", handleChange);
+ return () => mediaQuery.removeEventListener("change", handleChange);
+ }
+ // Fallback for older browsers
+ else if (mediaQuery.addListener) {
+ mediaQuery.addListener(handleChange);
+ return () => mediaQuery.removeListener(handleChange);
+ }
+ }, [theme]);
+
return (