javascript - Exportando un tema personalizado desde una biblioteca de UI usando Material-UI
Estoy creando una biblioteca de interfaz de usuario personalizada para el trabajo que utiliza Material-UI. La biblioteca de UI tiene un tema personalizado donde agregué al objeto palette colores personalizados de la empresa. El tema vive en la biblioteca de UI, y para los elementos que viven allí, puedo usar los colores personalizados en makeStyles, pero cuando intento usar el tema exportado en la base de código principal, los colores personalizados generan errores en makeStyles.
Creo que el problema es que no estoy exportando el módulo personalizado del tema. No estoy seguro de cómo exportar e importar esto correctamente en la base de código principal. Actualmente, solo estoy exportando el archivo del tema e importándolo en la base de código principal.
Código Principal:
import { theme } from 'customUILibrary';
...
<MuiThemeProvider theme={theme}>
...
</MuiThemeProvider>
BibliotecaUIPersonalizada:
index.ts:
export { theme } from 'theme/theme';
tema/tema.ts
import {
createTheme,
responsiveFontSizes,
} from '@material-ui/core/styles';
import './extendPalette';
export const theme = responsiveFontSizes(createTheme({
palette: {
gradients: {
primary: 'linear-gradient(270deg, #35C7E1 -10.76%, #1A92BD 121.8%)',
secondary: 'linear-gradient(270deg, #194E94 0%, #317CA6 100%)',
},
},
}));
extenderPaleta.ts
declare module '@material-ui/core/styles/createPalette' {
export interface PaletteOptions {
gradients: {
primary: string
secondary: string,
},
}
export interface Palette {
gradients: {
primary: string
secondary: string,
},
}
}
Los atributos de tema personalizados funcionan muy bien dentro de la Biblioteca de IU con los elementos de IU, pero cuando se importan al código principal, los atributos personalizados no se reconocen y, de hecho, causan errores.
Respuesta #1
Se pueden compartir las ampliaciones de tipos entre múltiples proyectos en un monorepo poniendo los tipos en un archivo .d.ts en algún lugar de tu espacio de trabajo y luego incluyéndolo en el tsconfig.json de cualquier proyecto que necesite estos tipos.
El truco es que necesitarás importar cualquier interfaz que estés ampliando en ese archivo, o de lo contrario sobrescribirás en lugar de fusionar las declaraciones de tipos.
Aquí hay un ejemplo de la configuración de mi proyecto si ayuda:
<workspaceRoot>/types/mui-types.d.ts
interface CustomShadowOptions {
z1: string;
z4: string;
z8: string;
z12: string;
z16: string;
z20: string;
z24: string;
//
primary: string;
secondary: string;
info: string;
success: string;
warning: string;
error: string;
//
card: string;
dialog: string;
dropdown: string;
}
import { Theme, ThemeOptions } from '@mui/material/styles';
declare module '@mui/material/styles' {
interface Theme {
customShadows: CustomShadowOptions;
}
interface ThemeOptions {
customShadows?: CustomShadowOptions;
}
}
import {
TypeBackground,
SimplePaletteColorOptions,
PaletteColor,
} from '@mui/material/styles/createPalette';
declare module '@mui/material/styles/createPalette' {
interface TypeBackground {
neutral: string;
}
interface SimplePaletteColorOptions {
lighter: string;
darker: string;
}
interface PaletteColor {
lighter: string;
darker: string;
}
}
import { TypographyVariants } from '@mui/material/styles';
declare module '@mui/material/styles' {
interface TypographyVariants {
fontWeightSemiBold: React.CSSProperties['fontWeight'];
}
}
import { ButtonPropsVariantOverrides } from '@mui/material/Button';
declare module '@mui/material/Button' {
interface ButtonPropsVariantOverrides {
soft: true;
}
}
import { ButtonGroupPropsVariantOverrides } from '@mui/material/ButtonGroup';
declare module '@mui/material/ButtonGroup' {
interface ButtonGroupPropsVariantOverrides {
soft: true;
}
}
Por ejemplo, para una aplicación hipotética con una configuración base compartida.
<workspaceRoot>/apps/home/tsconfig.json
{
"extends": "../../tsconfig.base.json",
"files": ["../../types/mui-types.d.ts"]
}
Respuesta #2
Como se sugiere aquí, puedes hacer algo así:
declare module "@mui/material/styles" {
interface Palette {
custom: {
pink: string;
};
}
interface PaletteOptions {
custom: {
pink: string;
};
}
}
Entonces puedes establecer tu valor en el tema de manera segura:
const theme = createTheme({
palette: {
custom: {
pink: "pink"
}
}
});
y úsalo en estilos:
<Button sx={{ color: "custom.pink" }}>Content</Button>
Ver mi ejemplo en codesandbox
