ente/web/packages/shared/themes/components.ts
2024-07-20 20:13:14 +05:30

225 lines
5.5 KiB
TypeScript

import type { Shadow, ThemeColorsOptions } from "@mui/material";
import type { Components } from "@mui/material/styles/components";
import type { TypographyOptions } from "@mui/material/styles/createTypography";
export const getComponents = (
colors: ThemeColorsOptions,
typography: TypographyOptions,
): Components => ({
MuiCssBaseline: {
styleOverrides: {
body: {
fontFamily: typography.fontFamily,
letterSpacing: "-0.011em",
},
strong: { fontWeight: 700 },
},
},
MuiTypography: {
defaultProps: {
variant: "body",
variantMapping: {
large: "p",
body: "p",
small: "p",
mini: "p",
tiny: "p",
},
},
},
MuiDrawer: {
styleOverrides: {
root: {
".MuiBackdrop-root": {
backgroundColor: colors.backdrop?.faint,
},
},
},
},
MuiDialog: {
styleOverrides: {
root: {
".MuiBackdrop-root": {
backgroundColor: colors.backdrop?.faint,
},
"& .MuiDialog-paper": {
filter: getDropShadowStyle(colors.shadows?.float),
},
"& .MuiDialogTitle-root": {
padding: "16px",
},
"& .MuiDialogContent-root": {
padding: "16px",
overflowY: "overlay",
},
"& .MuiDialogActions-root": {
padding: "16px",
},
".MuiDialogTitle-root + .MuiDialogContent-root": {
paddingTop: "16px",
},
},
},
},
MuiPaper: {
styleOverrides: { root: { backgroundImage: "none" } },
},
MuiLink: {
defaultProps: {
color: colors.accent?.A500,
underline: "none",
},
styleOverrides: {
root: {
"&:hover": {
underline: "always",
color: colors.accent?.A500,
},
},
},
},
MuiButton: {
defaultProps: {
variant: "contained",
},
styleOverrides: {
root: {
padding: "12px 16px",
borderRadius: "4px",
textTransform: "none",
fontWeight: "bold",
fontSize: typography.body?.fontSize,
lineHeight: typography.body?.lineHeight,
},
startIcon: {
marginRight: "12px",
"&& >svg": {
fontSize: "20px",
},
},
endIcon: {
marginLeft: "12px",
"&& >svg": {
fontSize: "20px",
},
},
sizeLarge: {
width: "100%",
},
},
},
MuiInputBase: {
styleOverrides: {
formControl: {
borderRadius: "8px",
"::before": {
borderBottom: "none !important",
},
},
},
},
MuiFilledInput: {
styleOverrides: {
input: {
"&:autofill": {
boxShadow: "#c7fd4f",
},
},
},
},
MuiTextField: {
defaultProps: {
variant: "filled",
margin: "dense",
},
styleOverrides: {
root: {
"& .MuiInputAdornment-root": {
marginRight: "8px",
},
},
},
},
MuiSvgIcon: {
styleOverrides: {
root: ({ ownerState }) => ({
...getIconColor(ownerState, colors),
}),
},
},
MuiIconButton: {
styleOverrides: {
root: ({ ownerState }) => ({
...getIconColor(ownerState, colors),
padding: "12px",
}),
},
},
MuiSnackbar: {
styleOverrides: {
root: {
borderRadius: "8px",
},
},
},
MuiModal: {
styleOverrides: {
root: {
'&:has(> div[style*="opacity: 0"])': {
pointerEvents: "none",
},
},
},
},
MuiMenuItem: {
styleOverrides: {
// don't reduce opacity of disabled items
root: {
"&.Mui-disabled": {
opacity: 1,
},
},
},
},
});
const getDropShadowStyle = (shadows: Shadow[] | undefined) => {
return (shadows ?? [])
.map(
(shadow) =>
`drop-shadow(${shadow.x}px ${shadow.y}px ${shadow.blur}px ${shadow.color})`,
)
.join(" ");
};
interface IconColorableOwnerState {
color?: string;
disabled?: boolean;
}
function getIconColor(
ownerState: IconColorableOwnerState,
colors: ThemeColorsOptions,
) {
switch (ownerState.color) {
case "primary":
return {
color: colors.stroke?.base,
};
case "secondary":
return {
color: colors.stroke?.muted,
};
}
if (ownerState.disabled) {
return {
color: colors.stroke?.faint,
};
}
return {};
}