diff --git a/package.json b/package.json
index 5739eb1..6ccd618 100644
--- a/package.json
+++ b/package.json
@@ -2,7 +2,7 @@
"name": "physicshub",
"homepage": "https://physicshub.github.io",
"private": true,
- "version": "2.2.1",
+ "version": "2.3.0",
"type": "module",
"scripts": {
"dev": "vite",
diff --git a/src/components/Theme.tsx b/src/components/Theme.tsx
index dce1420..a332c8d 100644
--- a/src/components/Theme.tsx
+++ b/src/components/Theme.tsx
@@ -1,8 +1,8 @@
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
-import { faSun, faMoon } from '@fortawesome/free-solid-svg-icons';
+import { faSun, faMoon, faCircleHalfStroke } from '@fortawesome/free-solid-svg-icons';
interface Props {
- mode: 'light' | 'dark';
+ mode: 'light' | 'dark' | 'system';
onToggle: () => void;
}
@@ -13,7 +13,11 @@ export function Theme({ mode, onToggle }: Props) {
onClick={onToggle}
aria-label="Toggle theme"
>
-
+
);
}
diff --git a/src/hooks/useTheme.tsx b/src/hooks/useTheme.tsx
index 5beeb04..7550829 100644
--- a/src/hooks/useTheme.tsx
+++ b/src/hooks/useTheme.tsx
@@ -1,14 +1,36 @@
import { useState, useEffect, useCallback } from 'react';
-export function useTheme(defaultMode: 'light' | 'dark' = 'dark') {
+export function useTheme(defaultMode: 'light' | 'dark' | 'system' = 'system') {
const [mode, setMode] = useState(defaultMode);
- useEffect(() => {
- document.body.dataset.theme = mode;
- }, [mode]);
+ const getSystemTheme = () => {
+ return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'
+ }
+
+ useEffect(() => {
+ let actualTheme = mode;
+ if(mode === 'system'){
+ actualTheme = getSystemTheme();
+ }
+ document.body.dataset.theme = actualTheme;
+ if(mode === 'system'){
+ const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
+
+ const handleChange = () => {
+ document.body.dataset.theme = getSystemTheme();
+ };
+
+ mediaQuery.addEventListener('change', handleChange);
+ return ()=> mediaQuery.removeEventListener('change', handleChange);
+ }
+}, [mode]);
const toggleMode = useCallback(
- () => setMode(prev => (prev === 'dark' ? 'light' : 'dark')),
+ () => setMode(prev => {
+ if(prev === 'dark') return 'light';
+ if(prev === 'light') return 'system';
+ return 'dark';
+ }),
[]
);