Material-ui-system is an awesome library, but when using with @emotion/styled
there might be a few annoying warnings, complaining that you're passing an invalid property to a DOM node. Here's a quick function to prevent that:
import memoize from '@emotion/memoize'; | |
import isPropValid from '@emotion/is-prop-valid'; | |
/** | |
* These props will not be forwarded to the wrapped element by @emotion/styled. | |
*/ | |
// prettier-ignore | |
const props: string[] = [ | |
// @material-ui/system/borders | |
'border', 'borderBottom', 'borderColor', 'borderLeft', 'borderRadius', | |
'borderRight', 'borderTop', | |
// @material-ui/system/shadows | |
'boxShadow', | |
// @material-ui/system/spacing | |
'm', 'mx', 'my', 'margin', | |
'mb', 'marginBottom', | |
'ml', 'marginLeft', | |
'mr', 'marginRight', | |
'mt', 'marginTop', | |
'p', 'px', 'py', 'padding', | |
'pb', 'paddingBottom', | |
'pl', 'paddingLeft', | |
'pr', 'paddingRight', | |
'pt', 'paddingTop', | |
// @material-ui/system/display | |
'displayPrint', 'display', | |
// @material-ui/system/flexbox | |
'alignContent', 'alignItems', 'alignSelf', 'flex', 'flexDirection', | |
'flexGrow', 'flexShrink', 'flexWrap', 'justifyContent', 'order', | |
// @material-ui/system/palette | |
'bgColor', 'color', | |
// @material-ui/system/positions | |
'bottom', 'left', 'position', 'right', 'top', 'zIndex', | |
// @material-ui/system/sizing | |
'height', 'maxHeight', 'maxWidth', 'minHeight', 'minWidth', 'width', 'boxSizing', | |
// @material-ui/system/typography | |
'fontFamily', 'fontSize', 'fontWeight', 'textAlign', | |
]; | |
const regex = new RegExp(`^(${props.join('|')})$`); | |
type Fn<T> = (key: string) => T; | |
/** | |
* The return function will only filter out the props listed above. This is the | |
* one we want to use if we are wrapping a Material-UI component. | |
*/ | |
export const createShouldForwardProp = (): Fn<boolean> => | |
memoize((prop) => !regex.test(prop)); | |
export default createShouldForwardProp(); | |
/** | |
* The created function will filter out the props listed above and any prop | |
* that is not a valid DOM prop. So this is the function we want to use if | |
* we are wrapping existing DOM components. | |
*/ | |
const createShouldForwardDomProp = (): Fn<boolean> => | |
memoize((prop) => isPropValid(prop) && !regex.test(prop)); | |
export const shouldForwardDomProp: Fn<boolean> = createShouldForwardDomProp(); |
And an example overriding an existing Material-UI component:
import styled from '@emotion/styled'; | |
import { | |
Typography as MaterialTypography, | |
TypographyProps as MaterialTypographyProps, | |
} from '@material-ui/core'; | |
import { | |
spacing, | |
SpacingProps, | |
sizing, | |
SizingProps, | |
typography, | |
TypographyProps as MaterialSystemTypographyProps, | |
} from '@material-ui/system'; | |
import shouldForwardProp from './shouldForwardProp'; | |
type TypographyProps = MaterialTypographyProps & | |
SpacingProps & | |
SizingProps & | |
MaterialSystemTypographyProps; | |
export const Typography = styled(MaterialTypography, { | |
shouldForwardProp, | |
})<TypographyProps>` | |
${sizing} | |
${spacing} | |
${typography} | |
`; |
Top comments (0)