chore: App theme added

This commit is contained in:
2025-07-12 21:59:36 +03:30
parent a87120d163
commit f14bd00ed8
8 changed files with 771 additions and 28 deletions

717
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -11,6 +11,9 @@
"preview": "vite preview"
},
"dependencies": {
"@emotion/react": "^11.14.0",
"@emotion/styled": "^11.14.1",
"@mui/material": "^7.2.0",
"i18next": "^25.3.0",
"i18next-http-backend": "^3.0.2",
"react": "^19.1.0",

View File

@@ -1,7 +1,11 @@
import './App.css';
function App() {
return <div>PlaceHolder</div>;
return (
<div>
<h1>Hello World</h1>
</div>
);
}
export default App;

View File

@@ -0,0 +1,12 @@
import type { AppTheme } from '@/types/theme';
import { createContext } from 'react';
export interface AppThemeContextModel {
mode: AppTheme;
changeTheme: (theme: AppTheme) => void;
}
// The context is used by the LangaugeProvider
export const AppThemeContext = createContext<AppThemeContextModel>({
mode: 'default',
changeTheme: () => {},
});

21
src/hooks/useAppTheme.ts Normal file
View File

@@ -0,0 +1,21 @@
import {
AppThemeContext,
type AppThemeContextModel,
} from '@/contexts/AppThemeContext';
import { useTheme, type Theme } from '@mui/material';
import { useContext } from 'react';
export interface AppThemeHookModel extends AppThemeContextModel {
theme: Theme;
}
export const useAppTheme = (): AppThemeHookModel => {
const appThemeContext = useContext(AppThemeContext);
const muiTheme = useTheme();
return {
mode: appThemeContext.mode,
changeTheme: appThemeContext.changeTheme,
theme: muiTheme,
};
};

View File

@@ -4,11 +4,15 @@ import './index.css';
import './lib/i18n';
import App from './App';
import { LanguageProvider } from './providers/LanguageProvider';
import { createTheme, ThemeProvider } from '@mui/material';
import { AppThemeProvider } from './providers/ThemeProvider';
createRoot(document.getElementById('root')!).render(
<StrictMode>
<LanguageProvider>
<App />
<AppThemeProvider>
<App />
</AppThemeProvider>
</LanguageProvider>
</StrictMode>,
);

View File

@@ -0,0 +1,33 @@
import { useLayoutEffect, type JSX, type PropsWithChildren } from 'react';
import { useLocalStorage } from '@/hooks/useLocalStorage';
import type { AppTheme } from '@/types/theme';
import { AppThemeContext } from '@/contexts/AppThemeContext';
import { createTheme, ThemeProvider } from '@mui/material';
import { useLangauge } from '@/hooks/useLanguage';
export const AppThemeProvider = (props: PropsWithChildren): JSX.Element => {
const { language } = useLangauge();
const [currentThemeMode, setCurrentTheme] = useLocalStorage<AppTheme>(
'theme',
'default',
);
const muiTheme = createTheme({
direction: language === 'fa' ? 'rtl' : 'ltr',
});
useLayoutEffect(() => {
document.body.setAttribute('theme', currentThemeMode);
}, [currentThemeMode]);
return (
<AppThemeContext.Provider
value={{
mode: currentThemeMode,
changeTheme: setCurrentTheme,
}}
>
<ThemeProvider theme={muiTheme}>{props.children}</ThemeProvider>
</AppThemeContext.Provider>
);
};

1
src/types/theme.ts Normal file
View File

@@ -0,0 +1 @@
export type AppTheme = 'default' | 'dark';