aboutsummaryrefslogtreecommitdiffstats
path: root/apps/browser-extension/src/utils/ThemeProvider.tsx
diff options
context:
space:
mode:
authorMohamedBassem <me@mbassem.com>2024-04-22 18:28:41 +0100
committerMohamedBassem <me@mbassem.com>2024-04-23 09:56:37 +0100
commit7ddcb5fe6b7de9df3e0424598d1836d51c3f80eb (patch)
tree8c1a52f560583a0bc69df48b9fe6bc5f9d39dec8 /apps/browser-extension/src/utils/ThemeProvider.tsx
parent5f599f29e1aed699d313b9f652934ecedef8f3ea (diff)
downloadkarakeep-7ddcb5fe6b7de9df3e0424598d1836d51c3f80eb.tar.zst
ui(extension): Use shadcn and better dark mode support
Diffstat (limited to 'apps/browser-extension/src/utils/ThemeProvider.tsx')
-rw-r--r--apps/browser-extension/src/utils/ThemeProvider.tsx73
1 files changed, 73 insertions, 0 deletions
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;
+};