From 7ddcb5fe6b7de9df3e0424598d1836d51c3f80eb Mon Sep 17 00:00:00 2001
From: MohamedBassem <me@mbassem.com>
Date: Mon, 22 Apr 2024 18:28:41 +0100
Subject: ui(extension): Use shadcn and better dark mode support

---
 apps/browser-extension/src/utils/ThemeProvider.tsx | 73 ++++++++++++++++++++++
 1 file changed, 73 insertions(+)
 create mode 100644 apps/browser-extension/src/utils/ThemeProvider.tsx

(limited to 'apps/browser-extension/src/utils/ThemeProvider.tsx')

diff --git a/apps/browser-extension/src/utils/ThemeProvider.tsx b/apps/browser-extension/src/utils/ThemeProvider.tsx
new file mode 100644
index 00000000..79a0b32f
--- /dev/null
+++ b/apps/browser-extension/src/utils/ThemeProvider.tsx
@@ -0,0 +1,73 @@
+import { createContext, useContext, useEffect, useState } from "react";
+
+type Theme = "dark" | "light" | "system";
+
+interface ThemeProviderProps {
+  children: React.ReactNode;
+  defaultTheme?: Theme;
+  storageKey?: string;
+}
+
+interface ThemeProviderState {
+  theme: Theme;
+  setTheme: (theme: Theme) => void;
+}
+
+const initialState: ThemeProviderState = {
+  theme: "system",
+  setTheme: () => null,
+};
+
+const ThemeProviderContext = createContext<ThemeProviderState>(initialState);
+
+export function ThemeProvider({
+  children,
+  defaultTheme = "system",
+  storageKey = "vite-ui-theme",
+  ...props
+}: ThemeProviderProps) {
+  const [theme, setTheme] = useState<Theme>(
+    () => (localStorage.getItem(storageKey) as Theme) || defaultTheme,
+  );
+
+  useEffect(() => {
+    const root = window.document.documentElement;
+
+    root.classList.remove("light", "dark");
+
+    if (theme === "system") {
+      const systemTheme = window.matchMedia("(prefers-color-scheme: dark)")
+        .matches
+        ? "dark"
+        : "light";
+
+      root.classList.add(systemTheme);
+      return;
+    }
+
+    root.classList.add(theme);
+  }, [theme]);
+
+  const value = {
+    theme,
+    setTheme: (theme: Theme) => {
+      localStorage.setItem(storageKey, theme);
+      setTheme(theme);
+    },
+  };
+
+  return (
+    <ThemeProviderContext.Provider {...props} value={value}>
+      {children}
+    </ThemeProviderContext.Provider>
+  );
+}
+
+export const useTheme = () => {
+  const context = useContext(ThemeProviderContext);
+
+  if (context === undefined)
+    throw new Error("useTheme must be used within a ThemeProvider");
+
+  return context;
+};
-- 
cgit v1.2.3-70-g09d2

