I'm porting to typescript this awesome project
https://github.com/codingmonk-yt/chat-app
it's a boilerplate starter for a modern chat webapp
built with material ui, where it customize extensively the default material theme
i'm not very familiar with react and material ui, truth be told, so i don't understand what am i doing wrong, i have a typescript issue when i try to migrate a styled component with its typescript version
ERROR :
Property 'theme' is missing in type '{ children: Element[]; sx: { bgcolor?: string | undefined; border?: solid 2px ${string}
| undefined; boxShadow?: inset 0 4px 8px 0 ${string}
| undefined; }; }' but required in type '{ theme: CustomTheme; }'.ts(2741)
the error suggests that the component can't see that BoxStyle is wrapped around a themeProvider with my custom theme, but i don't understand why
(i omitted to paste SettingsDrawer component since for now it's nothing more than a container for SettingColorPresets)
Thank you in advance for any pointers
i'm pasting here all the relevant code, please let me know if you need any more information
/*********************************/
//App.tsx:
/*********************************/
function App() {
return (
<ThemeProvider>
<ThemeSettings>
{" "}
<Routes />{" "}
</ThemeSettings>
</ThemeProvider>
);
}
/*********************************/
//theme.d.ts:
/*********************************/
declare module '@mui/material/styles' {
interface CustomTheme extends Theme {
customShadows: CustomShadows;
palette: CustomPalette;
}
// allow configuration using `createTheme`
interface CustomThemeOptions extends ThemeOptions {
customShadows: CustomShadows;
palette: CustomPalette;
}
export function createTheme(options?: CustomThemeOptions): CustomTheme;
}
/*********************************/
//ThemeProvider.tsx:
/*********************************/
import {
createTheme,
ThemeProvider as MUIThemeProvider,
StyledEngineProvider,
CustomThemeOptions,
ThemeOptions,
CustomTheme,
} from "@mui/material/styles";
export default function ThemeProvider({ children }: { children: ReactNode }) {
const { themeMode, themeDirection } = useSettings();
const isLight = themeMode === "light";
const themeOptions = useMemo(
() => ({
palette: isLight ? palette.light : palette.dark,
typography,
breakpoints,
shape: { borderRadius: 8 },
direction: themeDirection,
shadows: isLight ? shadows.light : shadows.dark,
customShadows: isLight ? customShadows.light : customShadows.dark,
} as CustomThemeOptions),
[isLight, themeDirection]
);
const theme = createTheme(themeOptions);
// if i inspect theme in vscode it shows that is instance of CustomTheme, as it should be...
theme.components = componentsOverride(theme);
return (
<StyledEngineProvider injectFirst>
<MUIThemeProvider theme={theme}>
<CssBaseline />
{children}
</MUIThemeProvider>
</StyledEngineProvider>
);
}
/*********************************/
//ThemeSettings.tsx:
/*********************************/
export default function ThemeSettings({ children }: { children: ReactNode }) {
return (
<ThemeColorPresets>
<ThemeContrast>
<ThemeLocalization>
<ThemeRtlLayout>
{children}
<SettingsDrawer />
</ThemeRtlLayout>
</ThemeLocalization>
</ThemeContrast>
</ThemeColorPresets>
);
}
/*********************************/
//ThemeColorPresets.tsx:
/*********************************/
import PropTypes from "prop-types";
import { ReactNode, useMemo } from "react";
// @mui
import {
alpha,
ThemeProvider,
createTheme,
useTheme,
CustomTheme,
} from "@mui/material/styles";
// hooks
import useSettings from "../../hooks/useSettings";
//
import componentsOverride from "../../theme/overrides";
// ----------------------------------------------------------------------
ThemeColorPresets.propTypes = {
children: PropTypes.node,
};
export default function ThemeColorPresets({
children,
}: {
children: ReactNode;
}) {
const defaultTheme = useTheme<CustomTheme>();
const { setColor } = useSettings();
const themeOptions = useMemo(
() => ({
...defaultTheme,
palette: {
...defaultTheme.palette,
primary: setColor,
},
customShadows: {
...defaultTheme.customShadows,
primary: `0 8px 16px 0 ${alpha(setColor.main, 0.24)}`,
},
}),
[setColor, defaultTheme]
);
const theme = createTheme(themeOptions);
// if i inspect theme in vscode it shows that is instance of CustomTheme, as it should be...
theme.components = componentsOverride(theme);
return <ThemeProvider theme={theme}>{children}</ThemeProvider>;
}
Finally, the part with the error:
/*********************************/
//SettingsColorPresets.tsx (CALLED FROM INSIDE <SettingsDrawer />, from ThemeSettings.tsx:
/*********************************/
const BoxStyle = styled(CardActionArea)(({ theme }: { theme: CustomTheme }) => ({
height: 48,
display: "flex",
alignItems: "center",
justifyContent: "center",
color: theme.palette.text.disabled,
border: `solid 1px ${(theme).palette.grey[500_12]}`,
borderRadius: Number(theme.shape.borderRadius) * 1.25,
}));
export default function SettingColorPresets() {
const { themeColorPresets, onChangeColor, colorOption } = useSettings();
return (
<RadioGroup
name="themeColorPresets"
value={themeColorPresets}
onChange={onChangeColor}
>
<Grid dir="ltr" container spacing={1.5}>
{colorOption.map((color: ColorOption) => {
const colorName = color.name;
const colorValue = color.value;
const isSelected = themeColorPresets === colorName;
return (
<Grid key={colorName} item xs={4}>
<BoxStyle <--- ERROR HERE
sx={{
...(isSelected && {
bgcolor: alpha(colorValue, 0.08),
border: `solid 2px ${colorValue}`,
boxShadow: `inset 0 4px 8px 0 ${alpha(colorValue, 0.24)}`,
}),
}}
>
.....