feat(theme): apply Material 3 component system
This commit is contained in:
42
src/features/theme/services/MaterialYouThemeOptions.test.ts
Normal file
42
src/features/theme/services/MaterialYouThemeOptions.test.ts
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) Contributors to the Suwayomi project
|
||||||
|
*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import assert from 'node:assert/strict';
|
||||||
|
import { describe, it } from 'node:test';
|
||||||
|
import { createMaterialYouScheme } from '@/features/theme/services/MaterialYouPalette.ts';
|
||||||
|
import {
|
||||||
|
createMaterialYouThemeOptions,
|
||||||
|
MATERIAL_YOU_MOTION,
|
||||||
|
} from '@/features/theme/services/MaterialYouThemeOptions.ts';
|
||||||
|
|
||||||
|
describe('createMaterialYouThemeOptions', () => {
|
||||||
|
const options = createMaterialYouThemeOptions(createMaterialYouScheme('#5B74EF', 'dark')) as any;
|
||||||
|
|
||||||
|
it('uses Material 3 geometry and readable button labels', () => {
|
||||||
|
assert.equal(options.shape.borderRadius, 20);
|
||||||
|
assert.equal(options.components.MuiCard.styleOverrides.root.borderRadius, 20);
|
||||||
|
assert.equal(options.components.MuiDialog.styleOverrides.paper.borderRadius, 28);
|
||||||
|
assert.equal(options.components.MuiButton.styleOverrides.root.borderRadius, 999);
|
||||||
|
assert.equal(options.components.MuiButton.styleOverrides.root.textTransform, 'none');
|
||||||
|
assert.equal(options.components.MuiChip.styleOverrides.root.borderRadius, 999);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('uses tonal surfaces instead of elevated app chrome', () => {
|
||||||
|
assert.equal(options.components.MuiAppBar.defaultProps.elevation, 0);
|
||||||
|
assert.equal(options.components.MuiDrawer.styleOverrides.paper.boxShadow, 'none');
|
||||||
|
assert.equal(options.palette.background.default, '#11131A');
|
||||||
|
assert.equal(options.palette.background.paper, '#191B23');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('provides focus and reduced-motion tokens', () => {
|
||||||
|
assert.equal(options.focusRing, '0 0 0 3px rgba(183, 194, 255, 0.72)');
|
||||||
|
assert.equal(MATERIAL_YOU_MOTION.standard, '180ms cubic-bezier(0.2, 0, 0, 1)');
|
||||||
|
assert.match(options.components.MuiCssBaseline.styleOverrides, /prefers-reduced-motion/);
|
||||||
|
assert.match(options.components.MuiCssBaseline.styleOverrides, /focus-visible/);
|
||||||
|
});
|
||||||
|
});
|
||||||
151
src/features/theme/services/MaterialYouThemeOptions.ts
Normal file
151
src/features/theme/services/MaterialYouThemeOptions.ts
Normal file
@@ -0,0 +1,151 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) Contributors to the Suwayomi project
|
||||||
|
*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import type { MaterialYouScheme } from '@/features/theme/services/MaterialYouPalette.ts';
|
||||||
|
|
||||||
|
export const MATERIAL_YOU_MOTION = {
|
||||||
|
standard: '180ms cubic-bezier(0.2, 0, 0, 1)',
|
||||||
|
emphasized: '320ms cubic-bezier(0.2, 0, 0, 1)',
|
||||||
|
} as const;
|
||||||
|
|
||||||
|
const FOCUS_RING = '0 0 0 3px rgba(183, 194, 255, 0.72)';
|
||||||
|
|
||||||
|
export const createMaterialYouThemeOptions = (scheme: MaterialYouScheme) => ({
|
||||||
|
focusRing: FOCUS_RING,
|
||||||
|
shape: {
|
||||||
|
borderRadius: 20,
|
||||||
|
},
|
||||||
|
palette: {
|
||||||
|
primary: {
|
||||||
|
main: scheme.primary,
|
||||||
|
contrastText: scheme.onPrimary,
|
||||||
|
},
|
||||||
|
secondary: {
|
||||||
|
main: scheme.secondary,
|
||||||
|
contrastText: scheme.onSecondary,
|
||||||
|
},
|
||||||
|
background: {
|
||||||
|
default: scheme.surface,
|
||||||
|
paper: scheme.surfaceContainer,
|
||||||
|
},
|
||||||
|
text: {
|
||||||
|
primary: scheme.onSurface,
|
||||||
|
secondary: scheme.onSurfaceVariant,
|
||||||
|
},
|
||||||
|
divider: scheme.outlineVariant,
|
||||||
|
},
|
||||||
|
typography: {
|
||||||
|
fontFamily:
|
||||||
|
'Roboto, "Noto Sans SC", "Microsoft YaHei UI", "Microsoft YaHei", system-ui, -apple-system, sans-serif',
|
||||||
|
h1: { fontWeight: 500, letterSpacing: '-0.02em' },
|
||||||
|
h2: { fontWeight: 500, letterSpacing: '-0.015em' },
|
||||||
|
h3: { fontWeight: 500 },
|
||||||
|
h4: { fontWeight: 500 },
|
||||||
|
h5: { fontWeight: 500 },
|
||||||
|
h6: { fontWeight: 600 },
|
||||||
|
button: { fontWeight: 600, letterSpacing: '0.01em' },
|
||||||
|
},
|
||||||
|
components: {
|
||||||
|
MuiCssBaseline: {
|
||||||
|
styleOverrides: `
|
||||||
|
:root { color-scheme: light dark; }
|
||||||
|
body { background: ${scheme.surface}; }
|
||||||
|
* { scrollbar-color: ${scheme.outlineVariant} transparent; }
|
||||||
|
:where(a, button, input, textarea, select, [tabindex]):focus-visible {
|
||||||
|
outline: none;
|
||||||
|
box-shadow: ${FOCUS_RING};
|
||||||
|
}
|
||||||
|
@media (prefers-reduced-motion: reduce) {
|
||||||
|
*, *::before, *::after {
|
||||||
|
animation-duration: 0.01ms !important;
|
||||||
|
animation-iteration-count: 1 !important;
|
||||||
|
scroll-behavior: auto !important;
|
||||||
|
transition-duration: 0.01ms !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
MuiButton: {
|
||||||
|
defaultProps: { disableElevation: true },
|
||||||
|
styleOverrides: {
|
||||||
|
root: {
|
||||||
|
minHeight: 40,
|
||||||
|
borderRadius: 999,
|
||||||
|
paddingInline: 24,
|
||||||
|
textTransform: 'none',
|
||||||
|
transition: `background-color ${MATERIAL_YOU_MOTION.standard}, transform ${MATERIAL_YOU_MOTION.standard}`,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
MuiIconButton: {
|
||||||
|
styleOverrides: {
|
||||||
|
root: {
|
||||||
|
minWidth: 44,
|
||||||
|
minHeight: 44,
|
||||||
|
transition: `background-color ${MATERIAL_YOU_MOTION.standard}, color ${MATERIAL_YOU_MOTION.standard}`,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
MuiCard: {
|
||||||
|
defaultProps: { elevation: 0 },
|
||||||
|
styleOverrides: {
|
||||||
|
root: {
|
||||||
|
borderRadius: 20,
|
||||||
|
backgroundImage: 'none',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
MuiPaper: {
|
||||||
|
styleOverrides: {
|
||||||
|
root: { backgroundImage: 'none' },
|
||||||
|
rounded: { borderRadius: 20 },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
MuiDialog: {
|
||||||
|
styleOverrides: {
|
||||||
|
paper: { borderRadius: 28, backgroundColor: scheme.surfaceContainerHigh },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
MuiChip: {
|
||||||
|
styleOverrides: {
|
||||||
|
root: { minHeight: 32, borderRadius: 999 },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
MuiOutlinedInput: {
|
||||||
|
styleOverrides: {
|
||||||
|
root: { borderRadius: 16 },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
MuiAppBar: {
|
||||||
|
defaultProps: { elevation: 0, color: 'transparent' as const },
|
||||||
|
styleOverrides: {
|
||||||
|
root: { backgroundColor: scheme.surface, backgroundImage: 'none', color: scheme.onSurface },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
MuiDrawer: {
|
||||||
|
styleOverrides: {
|
||||||
|
paper: {
|
||||||
|
border: 0,
|
||||||
|
boxShadow: 'none',
|
||||||
|
backgroundColor: scheme.surfaceContainer,
|
||||||
|
backgroundImage: 'none',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
MuiTooltip: {
|
||||||
|
styleOverrides: {
|
||||||
|
tooltip: { borderRadius: 8, fontSize: '0.75rem' },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
MuiSkeleton: {
|
||||||
|
styleOverrides: {
|
||||||
|
root: { borderRadius: 12, backgroundColor: scheme.surfaceVariant },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
@@ -6,104 +6,23 @@
|
|||||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import type { Direction, PaletteBackgroundChannel, Theme, TypeBackground } from '@mui/material/styles';
|
import type { Direction, Theme } from '@mui/material/styles';
|
||||||
import { createTheme as createMuiTheme, responsiveFontSizes, useTheme } from '@mui/material/styles';
|
import { createTheme as createMuiTheme, responsiveFontSizes, useTheme } from '@mui/material/styles';
|
||||||
import { useCallback } from 'react';
|
import { useCallback } from 'react';
|
||||||
// oxlint-disable-next-line no-restricted-imports
|
// oxlint-disable-next-line no-restricted-imports
|
||||||
import { deepmerge } from '@mui/utils';
|
import { deepmerge } from '@mui/utils';
|
||||||
import { complement, hsl, parseToHsl } from 'polished';
|
|
||||||
import type { HslaColor, HslColor } from 'polished/lib/types/color';
|
|
||||||
import type { AppTheme } from '@/features/theme/services/AppThemes.ts';
|
import type { AppTheme } from '@/features/theme/services/AppThemes.ts';
|
||||||
import { defaultPromiseErrorHandler } from '@/lib/DefaultPromiseErrorHandler.ts';
|
import { defaultPromiseErrorHandler } from '@/lib/DefaultPromiseErrorHandler.ts';
|
||||||
import { applyStyles } from '@/base/utils/ApplyStyles.ts';
|
import { applyStyles } from '@/base/utils/ApplyStyles.ts';
|
||||||
import type { TAppThemeContext } from '@/features/theme/AppTheme.types.ts';
|
import type { TAppThemeContext } from '@/features/theme/AppTheme.types.ts';
|
||||||
import { ThemeMode } from '@/features/theme/AppTheme.types.ts';
|
import { ThemeMode } from '@/features/theme/AppTheme.types.ts';
|
||||||
import { ThemeFontLoader } from '@/features/theme/services/ThemeFontLoader.ts';
|
import { ThemeFontLoader } from '@/features/theme/services/ThemeFontLoader.ts';
|
||||||
import { coerceIn } from '@/lib/HelperFunctions.ts';
|
|
||||||
import { MediaQuery } from '@/base/utils/MediaQuery.tsx';
|
import { MediaQuery } from '@/base/utils/MediaQuery.tsx';
|
||||||
|
import { createMaterialYouScheme, MATERIAL_YOU_STABLE_SEED } from '@/features/theme/services/MaterialYouPalette.ts';
|
||||||
|
import { createMaterialYouThemeOptions } from '@/features/theme/services/MaterialYouThemeOptions.ts';
|
||||||
|
|
||||||
const SCROLLBAR_SIZE = 14;
|
const SCROLLBAR_SIZE = 14;
|
||||||
|
|
||||||
const isNeutralColor = (color: HslColor | HslaColor): boolean => {
|
|
||||||
const isDesaturated = color.saturation < 0.08;
|
|
||||||
const isNearBlack = color.lightness < 0.03;
|
|
||||||
const isNearWhite = color.lightness > 0.97;
|
|
||||||
|
|
||||||
return isDesaturated || isNearBlack || isNearWhite;
|
|
||||||
};
|
|
||||||
|
|
||||||
const createBackgroundColors = (color: string, lightnessPaper: number, lightnessDefault: number): TypeBackground => {
|
|
||||||
const colorHsl = parseToHsl(color);
|
|
||||||
|
|
||||||
const saturationBoost = isNeutralColor(colorHsl) ? 0 : 0.15;
|
|
||||||
const saturation = coerceIn(colorHsl.saturation + saturationBoost, 0, 1);
|
|
||||||
|
|
||||||
return {
|
|
||||||
paper: hsl(colorHsl.hue, saturation, lightnessPaper),
|
|
||||||
default: hsl(colorHsl.hue, saturation, lightnessDefault),
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
const getBackgroundColor = (
|
|
||||||
type: 'light' | 'dark',
|
|
||||||
appTheme: AppTheme['muiTheme'],
|
|
||||||
theme: Theme,
|
|
||||||
setPureBlackMode: boolean = false,
|
|
||||||
): (Partial<TypeBackground> & Partial<PaletteBackgroundChannel>) | undefined => {
|
|
||||||
if (setPureBlackMode) {
|
|
||||||
return {
|
|
||||||
paper: '#000',
|
|
||||||
default: '#000',
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type === 'light' && !!theme.colorSchemes.light) {
|
|
||||||
if (typeof appTheme.colorSchemes?.light === 'object' && appTheme.colorSchemes.light.palette?.background) {
|
|
||||||
return appTheme.colorSchemes.light.palette.background;
|
|
||||||
}
|
|
||||||
|
|
||||||
return createBackgroundColors(theme.colorSchemes.light.palette.primary.dark, 0.87, 0.93);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type === 'dark' && !!theme.colorSchemes.dark) {
|
|
||||||
if (typeof appTheme.colorSchemes?.dark === 'object' && appTheme.colorSchemes.dark.palette?.background) {
|
|
||||||
return appTheme.colorSchemes.dark.palette.background;
|
|
||||||
}
|
|
||||||
|
|
||||||
return createBackgroundColors(theme.colorSchemes.dark.palette.primary.dark, 0.06, 0.03);
|
|
||||||
}
|
|
||||||
|
|
||||||
return undefined;
|
|
||||||
};
|
|
||||||
|
|
||||||
const createAppThemeWithDynamicColors = (
|
|
||||||
primaryColorDark: string | null | undefined,
|
|
||||||
primaryColorLight: string | null | undefined,
|
|
||||||
appTheme: AppTheme['muiTheme'],
|
|
||||||
): AppTheme['muiTheme'] => {
|
|
||||||
if (!primaryColorDark || !primaryColorLight) {
|
|
||||||
return appTheme;
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
...appTheme,
|
|
||||||
colorSchemes: {
|
|
||||||
light: {
|
|
||||||
palette: {
|
|
||||||
primary: { main: primaryColorLight },
|
|
||||||
secondary: { main: complement(primaryColorLight) },
|
|
||||||
},
|
|
||||||
},
|
|
||||||
dark: {
|
|
||||||
palette: {
|
|
||||||
primary: { main: primaryColorDark },
|
|
||||||
secondary: { main: complement(primaryColorDark) },
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
} satisfies AppTheme['muiTheme'];
|
|
||||||
};
|
|
||||||
|
|
||||||
const getVibrantColorForTheme = (
|
const getVibrantColorForTheme = (
|
||||||
palette: TAppThemeContext['dynamicColor'] | null,
|
palette: TAppThemeContext['dynamicColor'] | null,
|
||||||
mode: Exclude<ThemeMode, ThemeMode.SYSTEM>,
|
mode: Exclude<ThemeMode, ThemeMode.SYSTEM>,
|
||||||
@@ -115,57 +34,45 @@ const getVibrantColorForTheme = (
|
|||||||
return mode === ThemeMode.LIGHT ? palette.DarkVibrant.hex : palette.LightVibrant.hex;
|
return mode === ThemeMode.LIGHT ? palette.DarkVibrant.hex : palette.LightVibrant.hex;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const getThemeSeed = (
|
||||||
|
appTheme: AppTheme['muiTheme'],
|
||||||
|
mode: Exclude<ThemeMode, ThemeMode.SYSTEM>,
|
||||||
|
): string => {
|
||||||
|
const colorScheme = appTheme.colorSchemes?.[mode];
|
||||||
|
if (typeof colorScheme !== 'object') {
|
||||||
|
return MATERIAL_YOU_STABLE_SEED;
|
||||||
|
}
|
||||||
|
|
||||||
|
const primary = colorScheme.palette?.primary;
|
||||||
|
return typeof primary === 'object' && primary !== null && 'main' in primary && typeof primary.main === 'string'
|
||||||
|
? primary.main
|
||||||
|
: MATERIAL_YOU_STABLE_SEED;
|
||||||
|
};
|
||||||
|
|
||||||
export const createAppColorTheme = (
|
export const createAppColorTheme = (
|
||||||
appTheme: AppTheme['muiTheme'],
|
appTheme: AppTheme['muiTheme'],
|
||||||
dynamicColor: TAppThemeContext['dynamicColor'],
|
dynamicColor: TAppThemeContext['dynamicColor'],
|
||||||
setPureBlackMode: boolean,
|
setPureBlackMode: boolean,
|
||||||
mode: Exclude<ThemeMode, ThemeMode.SYSTEM>,
|
mode: Exclude<ThemeMode, ThemeMode.SYSTEM>,
|
||||||
): AppTheme['muiTheme'] => {
|
): AppTheme['muiTheme'] => {
|
||||||
const appThemeWithDominantPrimaryColor = createAppThemeWithDynamicColors(
|
const lightSeed = getVibrantColorForTheme(dynamicColor, ThemeMode.LIGHT) ?? getThemeSeed(appTheme, ThemeMode.LIGHT);
|
||||||
dynamicColor?.average.hex,
|
const darkSeed = getVibrantColorForTheme(dynamicColor, ThemeMode.DARK) ?? getThemeSeed(appTheme, ThemeMode.DARK);
|
||||||
dynamicColor?.average.hex,
|
const lightOptions = createMaterialYouThemeOptions(createMaterialYouScheme(lightSeed, ThemeMode.LIGHT));
|
||||||
appTheme,
|
const darkOptions = createMaterialYouThemeOptions(
|
||||||
|
createMaterialYouScheme(darkSeed, ThemeMode.DARK, setPureBlackMode),
|
||||||
);
|
);
|
||||||
const themePrimaryColorForBackground = createMuiTheme({
|
const activeOptions = mode === ThemeMode.DARK ? darkOptions : lightOptions;
|
||||||
...appThemeWithDominantPrimaryColor,
|
|
||||||
defaultColorScheme: mode,
|
|
||||||
});
|
|
||||||
|
|
||||||
const themeBackgroundColor = deepmerge(appThemeWithDominantPrimaryColor, {
|
return deepmerge(appTheme, {
|
||||||
defaultColorScheme: mode,
|
defaultColorScheme: mode,
|
||||||
|
shape: activeOptions.shape,
|
||||||
|
typography: deepmerge(activeOptions.typography, appTheme.typography ?? {}),
|
||||||
|
components: deepmerge(activeOptions.components, appTheme.components ?? {}),
|
||||||
colorSchemes: {
|
colorSchemes: {
|
||||||
light: themePrimaryColorForBackground.colorSchemes?.light
|
light: { palette: lightOptions.palette },
|
||||||
? {
|
dark: { palette: darkOptions.palette },
|
||||||
palette: {
|
|
||||||
background: getBackgroundColor(
|
|
||||||
'light',
|
|
||||||
appThemeWithDominantPrimaryColor,
|
|
||||||
themePrimaryColorForBackground,
|
|
||||||
),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
: undefined,
|
|
||||||
dark: themePrimaryColorForBackground.colorSchemes?.dark
|
|
||||||
? {
|
|
||||||
palette: {
|
|
||||||
background: getBackgroundColor(
|
|
||||||
'dark',
|
|
||||||
appThemeWithDominantPrimaryColor,
|
|
||||||
themePrimaryColorForBackground,
|
|
||||||
setPureBlackMode,
|
|
||||||
),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
: undefined,
|
|
||||||
},
|
},
|
||||||
});
|
}) as AppTheme['muiTheme'];
|
||||||
|
|
||||||
const appThemeWithVibrantPrimaryColor = createAppThemeWithDynamicColors(
|
|
||||||
getVibrantColorForTheme(dynamicColor, ThemeMode.DARK),
|
|
||||||
getVibrantColorForTheme(dynamicColor, ThemeMode.LIGHT),
|
|
||||||
themeBackgroundColor,
|
|
||||||
);
|
|
||||||
return deepmerge(themeBackgroundColor, appThemeWithVibrantPrimaryColor);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const createTheme = (
|
export const createTheme = (
|
||||||
@@ -195,26 +102,26 @@ export const createTheme = (
|
|||||||
direction,
|
direction,
|
||||||
typography: {
|
typography: {
|
||||||
fontSize: 13,
|
fontSize: 13,
|
||||||
...appTheme.muiTheme.typography,
|
...appColorTheme.typography,
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
...appTheme.muiTheme.components,
|
...appColorTheme.components,
|
||||||
MuiUseMediaQuery: {
|
MuiUseMediaQuery: {
|
||||||
defaultProps: {
|
defaultProps: {
|
||||||
noSsr: true,
|
noSsr: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
MuiCssBaseline: {
|
MuiCssBaseline: {
|
||||||
...appTheme.muiTheme.components?.MuiCssBaseline,
|
...appColorTheme.components?.MuiCssBaseline,
|
||||||
styleOverrides:
|
styleOverrides:
|
||||||
typeof appTheme.muiTheme.components?.MuiCssBaseline?.styleOverrides === 'object'
|
typeof appColorTheme.components?.MuiCssBaseline?.styleOverrides === 'object'
|
||||||
? {
|
? {
|
||||||
...appTheme.muiTheme.components?.MuiCssBaseline?.styleOverrides,
|
...appColorTheme.components?.MuiCssBaseline?.styleOverrides,
|
||||||
'*::-webkit-scrollbar': applyStyles(doesDeviceSupportHover, {
|
'*::-webkit-scrollbar': applyStyles(doesDeviceSupportHover, {
|
||||||
width: `${SCROLLBAR_SIZE}px`,
|
width: `${SCROLLBAR_SIZE}px`,
|
||||||
height: `${SCROLLBAR_SIZE}px`,
|
height: `${SCROLLBAR_SIZE}px`,
|
||||||
// @ts-ignore - '*::-webkit-scrollbar' is a valid key
|
// @ts-ignore - '*::-webkit-scrollbar' is a valid key
|
||||||
...appTheme.muiTheme.components?.MuiCssBaseline?.styleOverrides?.[
|
...appColorTheme.components?.MuiCssBaseline?.styleOverrides?.[
|
||||||
'*::-webkit-scrollbar'
|
'*::-webkit-scrollbar'
|
||||||
],
|
],
|
||||||
}),
|
}),
|
||||||
@@ -224,14 +131,14 @@ export const createTheme = (
|
|||||||
borderRadius: '9999px',
|
borderRadius: '9999px',
|
||||||
backgroundColor: `${themeForColors.palette.primary[isDarkMode ? 'dark' : 'light']}`,
|
backgroundColor: `${themeForColors.palette.primary[isDarkMode ? 'dark' : 'light']}`,
|
||||||
// @ts-ignore - '*::-webkit-scrollbar-thumb' is a valid key
|
// @ts-ignore - '*::-webkit-scrollbar-thumb' is a valid key
|
||||||
...appTheme.muiTheme.components?.MuiCssBaseline?.styleOverrides?.[
|
...appColorTheme.components?.MuiCssBaseline?.styleOverrides?.[
|
||||||
'*::-webkit-scrollbar-thumb'
|
'*::-webkit-scrollbar-thumb'
|
||||||
],
|
],
|
||||||
}),
|
}),
|
||||||
'*::-webkit-scrollbar-thumb:hover': applyStyles(doesDeviceSupportHover, {
|
'*::-webkit-scrollbar-thumb:hover': applyStyles(doesDeviceSupportHover, {
|
||||||
borderWidth: '2px',
|
borderWidth: '2px',
|
||||||
// @ts-ignore - '*::-webkit-scrollbar-thumb:hover' is a valid key
|
// @ts-ignore - '*::-webkit-scrollbar-thumb:hover' is a valid key
|
||||||
...appTheme.muiTheme.components?.MuiCssBaseline?.styleOverrides?.[
|
...appColorTheme.components?.MuiCssBaseline?.styleOverrides?.[
|
||||||
'*::-webkit-scrollbar-thumb:hover'
|
'*::-webkit-scrollbar-thumb:hover'
|
||||||
],
|
],
|
||||||
}),
|
}),
|
||||||
@@ -252,7 +159,7 @@ export const createTheme = (
|
|||||||
border-width: 2px;
|
border-width: 2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
${appTheme.muiTheme.components?.MuiCssBaseline?.styleOverrides ?? ''}
|
${appColorTheme.components?.MuiCssBaseline?.styleOverrides ?? ''}
|
||||||
}
|
}
|
||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user