Skip to content

Commit

Permalink
feat!: add custom theme (#15)
Browse files Browse the repository at this point in the history
- Add theme.ts to create common theme structure for components.
- Add light and dark and dark mode themes.
- Add ThemeContext.tsx for theme management.
- Edit Layout.tsx to add ThemeProvider and CssBaseline.
- Add theme.test.tsx to test themes.
- Install roboto font.
  • Loading branch information
ishaan000 authored Nov 1, 2024
1 parent 195bc97 commit 808cb93
Show file tree
Hide file tree
Showing 6 changed files with 372 additions and 7 deletions.
7 changes: 7 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
"dependencies": {
"@emotion/cache": "^11.13.1",
"@emotion/styled": "^11.13.0",
"@fontsource/roboto": "^5.1.0",
"@mui/material": "^6.1.0",
"@mui/material-nextjs": "^6.0.0",
"@next/env": "^14.2.7",
Expand Down
23 changes: 16 additions & 7 deletions src/app/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,24 @@
import React, { ReactNode } from 'react';
import '@fontsource/roboto/300.css';
import '@fontsource/roboto/400.css';
import '@fontsource/roboto/500.css';
import '@fontsource/roboto/700.css';
import { AppRouterCacheProvider } from '@mui/material-nextjs/v13-appRouter';
import { CssBaseline } from '@mui/material';
import React from 'react';
import { ThemeProvider } from '../theme/ThemeContext';

interface RootLayoutProps {
children: ReactNode;
}

export default function RootLayout({ children }: RootLayoutProps) {
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html lang="en">
<body>
<AppRouterCacheProvider>{children}</AppRouterCacheProvider>
<ThemeProvider>
<CssBaseline />
<AppRouterCacheProvider>{children}</AppRouterCacheProvider>
</ThemeProvider>
</body>
</html>
);
Expand Down
47 changes: 47 additions & 0 deletions src/theme/ThemeContext.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
'use client';

import { ThemeProvider as MuiThemeProvider, Theme } from '@mui/material/styles';
import React, { createContext, useEffect, useMemo, useState } from 'react';
import { darkTheme, lightTheme } from './theme';

interface ThemeContextType {
toggleTheme: () => void;
isDarkMode: boolean;
}

export const ThemeContext = createContext<ThemeContextType>({
toggleTheme: () => {},
isDarkMode: false,
});

export const ThemeProvider: React.FC<{ children: React.ReactNode }> = ({
children,
}) => {
const [isDarkMode, setIsDarkMode] = useState<boolean>(false);

useEffect(() => {
const savedTheme = localStorage.getItem('theme');
if (savedTheme) {
setIsDarkMode(savedTheme === 'dark');
}
}, []);

const toggleTheme = () => {
setIsDarkMode((prev) => {
const newMode = !prev;
localStorage.setItem('theme', newMode ? 'dark' : 'light');
return newMode;
});
};

const theme: Theme = useMemo(
() => (isDarkMode ? darkTheme : lightTheme),
[isDarkMode]
);

return (
<ThemeContext.Provider value={{ toggleTheme, isDarkMode }}>
<MuiThemeProvider theme={theme}>{children}</MuiThemeProvider>
</ThemeContext.Provider>
);
};
114 changes: 114 additions & 0 deletions src/theme/theme.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
import { createTheme } from '@mui/material/styles';

const commonSettings = {
typography: {
fontFamily: 'Roboto, Arial, sans-serif, ',
body1: {
color: 'var(--common-white_states-main, #FFF)',
fontFamily: 'Roboto',
fontSize: '16px',
fontStyle: 'normal',
fontWeight: 400,
lineHeight: '24px',
letterSpacing: '0.15px',
},
body2: {
color: '#FFFFFF',
fontFamily: 'Roboto',
fontSize: '14px',
fontWeight: 400,
lineHeight: '20px',
letterSpacing: '0.15px',
},
h1: {
color: 'var(--common-white_states-main, #FFF)',
fontFamily: 'Roboto',
fontSize: '30px',
fontStyle: 'normal',
fontWeight: 500,
lineHeight: '24px',
letterSpacing: '0.15px',
},
h2: {
color: 'var(--common-white_states-main, #FFF)',
fontFamily: 'Roboto',
fontSize: '24px',
fontWeight: 500,
lineHeight: '32px',
letterSpacing: '0.1px',
},
h3: {
color: 'var(--common-white_states-main, #FFF)',
fontFamily: 'Roboto',
fontSize: '20px',
fontWeight: 500,
lineHeight: '28px',
letterSpacing: '0.1px',
},
subtitle1: {
color: '#D9D9D9',
fontFamily: 'Roboto',
fontSize: '16px',
fontWeight: 400,
lineHeight: '24px',
letterSpacing: '0.15px',
},
subtitle2: {
color: '#8F8C8C',
fontFamily: 'Roboto',
fontSize: '14px',
fontWeight: 400,
lineHeight: '20px',
letterSpacing: '0.1px',
},
caption: {
color: '#8F8C8C',
fontFamily: 'Roboto',
fontSize: '12px',
fontWeight: 400,
lineHeight: '16px',
letterSpacing: '0.4px',
},
overline: {
color: '#8F8C8C',
fontFamily: 'Roboto',
fontSize: '10px',
fontWeight: 400,
lineHeight: '16px',
letterSpacing: '1.5px',
textTransform: 'uppercase' as const,
},
},
};

export const lightTheme = createTheme({
...commonSettings,
palette: {
mode: 'light',
primary: { main: '#282828' },
secondary: { main: '#8F8C8C' },
background: { default: '#D9D9D9', paper: '#fff' },
text: {
primary: '#000000',
secondary: '#282828',
},
},
});

export const darkTheme = createTheme({
...commonSettings,
palette: {
mode: 'dark',
primary: { main: '#FFFFFF' },
secondary: { main: '#8F8C8C' },
background: {
default: '#000000',
paper: '#161616',
},
text: {
primary: '#FFFFFF',
secondary: '#D9D9D9',
},
divider: '#282828',
},
});
Loading

0 comments on commit 808cb93

Please sign in to comment.