diff --git a/src/RootAppRouter.tsx b/src/RootAppRouter.tsx index bb64480816..968a703c8c 100644 --- a/src/RootAppRouter.tsx +++ b/src/RootAppRouter.tsx @@ -18,7 +18,7 @@ import BangRedirect from 'components/router/BangRedirect'; import { createRouterHistory } from 'components/router/routerHistory'; import { LayoutMode } from 'constants/layoutMode'; import browser from 'scripts/browser'; -import appTheme from 'themes/themes'; +import appTheme from 'themes'; import { ThemeStorageManager } from 'themes/themeStorageManager'; const layoutMode = browser.tv ? LayoutMode.Tv : localStorage.getItem(LAYOUT_SETTING_KEY); diff --git a/src/themes/_palette.scss b/src/themes/_base/_palette.scss similarity index 100% rename from src/themes/_palette.scss rename to src/themes/_base/_palette.scss diff --git a/src/themes/_base.scss b/src/themes/_base/_theme.scss similarity index 99% rename from src/themes/_base.scss rename to src/themes/_base/_theme.scss index a8c91a36b8..2e84323c26 100644 --- a/src/themes/_base.scss +++ b/src/themes/_base/_theme.scss @@ -1,4 +1,4 @@ -@use '../styles/mixins' as *; +@use '../../styles/mixins' as *; @use './palette' as palette; // Theme options diff --git a/src/themes/defaults.ts b/src/themes/_base/theme.ts similarity index 100% rename from src/themes/defaults.ts rename to src/themes/_base/theme.ts diff --git a/src/themes/appletv/index.ts b/src/themes/appletv/index.ts new file mode 100644 index 0000000000..695e1b7635 --- /dev/null +++ b/src/themes/appletv/index.ts @@ -0,0 +1,17 @@ +import { buildCustomColorScheme } from 'themes/utils'; + +/** The Apple TV inspired color scheme. */ +const theme = buildCustomColorScheme({ + palette: { + mode: 'light', + background: { + default: '#d5e9f2', + paper: '#fff' + }, + AppBar: { + defaultBg: '#bcbcbc' + } + } +}); + +export default theme; diff --git a/src/themes/blueradiance/index.ts b/src/themes/blueradiance/index.ts new file mode 100644 index 0000000000..31556d2863 --- /dev/null +++ b/src/themes/blueradiance/index.ts @@ -0,0 +1,15 @@ +import { buildCustomColorScheme } from 'themes/utils'; + +/** The "Blue Radiance" color scheme. */ +const theme = buildCustomColorScheme({ + palette: { + background: { + paper: '#011432' + }, + AppBar: { + defaultBg: '#011432' + } + } +}); + +export default theme; diff --git a/src/themes/dark/index.ts b/src/themes/dark/index.ts new file mode 100644 index 0000000000..b1f8e2ab3c --- /dev/null +++ b/src/themes/dark/index.ts @@ -0,0 +1,20 @@ +import type { ColorSystemOptions } from '@mui/material/styles'; +import merge from 'lodash-es/merge'; + +import { DEFAULT_COLOR_SCHEME } from '../_base/theme'; + +/** The default "Dark" color scheme. */ +const theme = merge( + {}, + DEFAULT_COLOR_SCHEME, + { + palette: { + SnackbarContent: { + bg: '#303030', + color: 'rgba(255, 255, 255, 0.87)' + } + } + } +); + +export default theme; diff --git a/src/themes/dark/theme.scss b/src/themes/dark/theme.scss index cc1ff9261a..02a593c3e2 100644 --- a/src/themes/dark/theme.scss +++ b/src/themes/dark/theme.scss @@ -1,5 +1,5 @@ /* Import the base theme */ -@use '../base'; +@use '../_base/theme'; /* Card background color variants */ .defaultCardBackground1 { diff --git a/src/themes/index.ts b/src/themes/index.ts new file mode 100644 index 0000000000..904162ddf2 --- /dev/null +++ b/src/themes/index.ts @@ -0,0 +1,30 @@ +import { createTheme } from '@mui/material/styles'; + +import { DEFAULT_THEME_OPTIONS } from './_base/theme'; +import appletv from './appletv'; +import blueradiance from './blueradiance'; +import dark from './dark'; +import light from './light'; +import purplehaze from './purplehaze'; +import wmc from './wmc'; + +/** The default theme containing all color scheme variants. */ +const DEFAULT_THEME = createTheme({ + cssVariables: { + cssVarPrefix: 'jf', + colorSchemeSelector: '[data-theme="%s"]', + disableCssColorScheme: true + }, + defaultColorScheme: 'dark', + ...DEFAULT_THEME_OPTIONS, + colorSchemes: { + appletv, + blueradiance, + dark, + light, + purplehaze, + wmc + } +}); + +export default DEFAULT_THEME; diff --git a/src/themes/light/index.ts b/src/themes/light/index.ts new file mode 100644 index 0000000000..4670cf15d9 --- /dev/null +++ b/src/themes/light/index.ts @@ -0,0 +1,40 @@ +import type { ColorSystemOptions } from '@mui/material/styles'; +import merge from 'lodash-es/merge'; + +import { DEFAULT_COLOR_SCHEME } from '../_base/theme'; + +/** The "Light" color scheme. */ +const theme = merge( + {}, + DEFAULT_COLOR_SCHEME, + { + palette: { + mode: 'light', + background: { + default: '#f2f2f2', + paper: '#e8e8e8' + }, + text: { + primary: '#000', + secondary: 'rgba(0, 0, 0, 0.87)' + }, + action: { + focus: '#bbb', + hover: '#ddd' + }, + Alert: { + infoFilledBg: '#fff3a5', + infoFilledColor: '#000' + }, + AppBar: { + defaultBg: '#e8e8e8' + }, + Button: { + inheritContainedBg: '#d8d8d8', + inheritContainedHoverBg: '#ccc' + } + } + } +); + +export default theme; diff --git a/src/themes/light/theme.scss b/src/themes/light/theme.scss index ab6e8dbdc1..e882e88b4d 100644 --- a/src/themes/light/theme.scss +++ b/src/themes/light/theme.scss @@ -1,8 +1,8 @@ @use '../../styles/mixins' as *; -@use '../palette' as palette; +@use '../_base/palette' as palette; /* Import the base theme with overrides */ -@use '../base' with ( +@use '../_base/theme' with ( // Theme options $dark: false, diff --git a/src/themes/purplehaze/index.ts b/src/themes/purplehaze/index.ts new file mode 100644 index 0000000000..0ab57ad097 --- /dev/null +++ b/src/themes/purplehaze/index.ts @@ -0,0 +1,21 @@ +import { buildCustomColorScheme } from 'themes/utils'; + +/** The "Purple Haze" color scheme. */ +const theme = buildCustomColorScheme({ + palette: { + background: { + paper: '#000420' + }, + primary: { + main: '#48c3c8' + }, + secondary: { + main: '#ff77f1' + }, + AppBar: { + defaultBg: '#000420' + } + } +}); + +export default theme; diff --git a/src/themes/styles.d.ts b/src/themes/styles.d.ts new file mode 100644 index 0000000000..38bcfcb8b8 --- /dev/null +++ b/src/themes/styles.d.ts @@ -0,0 +1,19 @@ +import '@mui/material/styles'; + +/** Extend MUI types to include our customizations. */ +declare module '@mui/material/styles' { + interface ColorSchemeOverrides { + appletv: true; + blueradiance: true; + purplehaze: true; + wmc: true; + } + + interface Palette { + starIcon: Palette['primary']; + } + + interface PaletteOptions { + starIcon?: PaletteOptions['primary']; + } +} diff --git a/src/themes/themes.ts b/src/themes/themes.ts deleted file mode 100644 index 54e8bed851..0000000000 --- a/src/themes/themes.ts +++ /dev/null @@ -1,159 +0,0 @@ -import { type ColorSystemOptions, createTheme, extendTheme } from '@mui/material/styles'; -import merge from 'lodash-es/merge'; - -import { DEFAULT_COLOR_SCHEME, DEFAULT_THEME_OPTIONS } from './defaults'; - -/** Extend MUI types to include our customizations. */ -declare module '@mui/material/styles' { - interface ColorSchemeOverrides { - appletv: true; - blueradiance: true; - purplehaze: true; - wmc: true; - } - - interface Palette { - starIcon: Palette['primary']; - } - - interface PaletteOptions { - starIcon?: PaletteOptions['primary']; - } -} - -/** The default built-in MUI theme. */ -const defaultMuiTheme = extendTheme({ - // @ts-expect-error The default theme does not include our custom color schemes - colorSchemes: { dark: true, light: true } -}); - -/** - * Default color schemes ('dark' or 'light') will automatically be merged with MUI's corresponding default color - * scheme. For custom schemes, we need to merge these manually. - */ -const buildCustomColorScheme = (options: ColorSystemOptions) => merge( - {}, - options.palette?.mode === 'light' ? defaultMuiTheme.colorSchemes.light : defaultMuiTheme.colorSchemes.dark, - DEFAULT_COLOR_SCHEME, - options -); - -/** The Apple TV inspired color scheme. */ -const appletv = buildCustomColorScheme({ - palette: { - mode: 'light', - background: { - default: '#d5e9f2', - paper: '#fff' - }, - AppBar: { - defaultBg: '#bcbcbc' - } - } -}); - -/** The "Blue Radiance" color scheme. */ -const blueradiance = buildCustomColorScheme({ - palette: { - background: { - paper: '#011432' - }, - AppBar: { - defaultBg: '#011432' - } - } -}); - -/** The default "Dark" color scheme. */ -const dark = merge({}, DEFAULT_COLOR_SCHEME, { - palette: { - SnackbarContent: { - bg: '#303030', - color: 'rgba(255, 255, 255, 0.87)' - } - } -}); - -/** The "Light" color scheme. */ -const light = merge({}, DEFAULT_COLOR_SCHEME, { - palette: { - mode: 'light', - background: { - default: '#f2f2f2', - paper: '#e8e8e8' - }, - text: { - primary: '#000', - secondary: 'rgba(0, 0, 0, 0.87)' - }, - action: { - focus: '#bbb', - hover: '#ddd' - }, - Alert: { - infoFilledBg: '#fff3a5', - infoFilledColor: '#000' - }, - AppBar: { - defaultBg: '#e8e8e8' - }, - Button: { - inheritContainedBg: '#d8d8d8', - inheritContainedHoverBg: '#ccc' - } - } -}); - -/** The "Purple Haze" color scheme. */ -const purplehaze = buildCustomColorScheme({ - palette: { - background: { - paper: '#000420' - }, - primary: { - main: '#48c3c8' - }, - secondary: { - main: '#ff77f1' - }, - AppBar: { - defaultBg: '#000420' - } - } -}); - -/** The Windows Media Center inspired color scheme. */ -const wmc = buildCustomColorScheme({ - palette: { - background: { - paper: '#0c2450' - }, - AppBar: { - defaultBg: '#0c2450' - } - } -}); - -/** All color scheme variants in the app. */ -export const COLOR_SCHEMES = { - appletv, - blueradiance, - dark, - light, - purplehaze, - wmc -}; - -/** The default theme containing all color scheme variants. */ -const DEFAULT_THEME = createTheme({ - cssVariables: { - cssVarPrefix: 'jf', - colorSchemeSelector: '[data-theme="%s"]', - disableCssColorScheme: true - }, - defaultColorScheme: 'dark', - ...DEFAULT_THEME_OPTIONS, - colorSchemes: COLOR_SCHEMES -}); - -export default DEFAULT_THEME; diff --git a/src/themes/utils.ts b/src/themes/utils.ts new file mode 100644 index 0000000000..33e58b1a0a --- /dev/null +++ b/src/themes/utils.ts @@ -0,0 +1,22 @@ +import { type ColorSystemOptions, extendTheme } from '@mui/material/styles'; +import merge from 'lodash-es/merge'; + +import { DEFAULT_COLOR_SCHEME } from './_base/theme'; + +/** The default built-in MUI theme. */ +const defaultMuiTheme = extendTheme({ + // @ts-expect-error The default theme does not include our custom color schemes + colorSchemes: { dark: true, light: true } +}); + +/** + * Default color schemes ('dark' or 'light') will automatically be merged with MUI's corresponding default color + * scheme. For custom schemes, we need to merge these manually. + */ +export const buildCustomColorScheme = (options: ColorSystemOptions) => + merge( + {}, + options.palette?.mode === 'light' ? defaultMuiTheme.colorSchemes.light : defaultMuiTheme.colorSchemes.dark, + DEFAULT_COLOR_SCHEME, + options + ); diff --git a/src/themes/wmc/index.ts b/src/themes/wmc/index.ts new file mode 100644 index 0000000000..feb0412dd2 --- /dev/null +++ b/src/themes/wmc/index.ts @@ -0,0 +1,15 @@ +import { buildCustomColorScheme } from 'themes/utils'; + +/** The Windows Media Center inspired color scheme. */ +const theme = buildCustomColorScheme({ + palette: { + background: { + paper: '#0c2450' + }, + AppBar: { + defaultBg: '#0c2450' + } + } +}); + +export default theme; diff --git a/src/utils/reactUtils.tsx b/src/utils/reactUtils.tsx index 80abdd512a..996ab33839 100644 --- a/src/utils/reactUtils.tsx +++ b/src/utils/reactUtils.tsx @@ -6,7 +6,7 @@ import { createRoot } from 'react-dom/client'; import { ApiProvider } from 'hooks/useApi'; import { UserSettingsProvider } from 'hooks/useUserSettings'; import { WebConfigProvider } from 'hooks/useWebConfig'; -import appTheme from 'themes/themes'; +import appTheme from 'themes'; import { queryClient } from 'utils/query/queryClient'; export const renderComponent =

(