Last active
May 15, 2022 14:44
-
-
Save ItsJonQ/5a9fff8296e16d52a874de2bc26f19d1 to your computer and use it in GitHub Desktop.
Create emotion styled - Creating a custom styled component using Emotion to compile and consolidate CSS.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React from 'react'; | |
import createEmotion from '@emotion/css/create-instance'; | |
import isPropValid from '@emotion/is-prop-valid'; | |
export const { | |
flush, | |
hydrate, | |
cx, | |
merge, | |
getRegisteredStyles, | |
injectGlobal, | |
keyframes, | |
css, | |
sheet, | |
cache, | |
} = createEmotion({ key: 'css' }); | |
const shouldForwardProp = (prop) => isPropValid(prop); | |
const getFilteredProps = (props) => { | |
const filteredProps = {}; | |
for (const key in props) { | |
if (shouldForwardProp(key)) { | |
filteredProps[key] = props[key]; | |
} | |
} | |
return filteredProps; | |
}; | |
export const styled = (Component) => (styles) => { | |
// Compiling initial styledm component styles | |
const compiledStyles = css(styles); | |
const StyledComponent = React.forwardRef((props, ref) => { | |
const { as, className, css: __css, ...rest } = props; | |
const isBaseHTMLElement = | |
typeof Component === 'string' || typeof as === 'string'; | |
// Rendering as | |
const BaseComponent = as ? as : Component; | |
// Compiling custom css prop styles | |
const customStyles = __css ? css(__css) : ''; | |
// Compiling all classNames | |
const classes = cx(compiledStyles, className, customStyles); | |
// Filter non HTML props for base elements (e.g. `div`). | |
const finalProps = isBaseHTMLElement ? getFilteredProps(rest) : rest; | |
return <BaseComponent {...finalProps} className={classes} />; | |
}); | |
// Setting the display name | |
let displayName = 'Component'; | |
if (typeof Component === 'string') { | |
displayName = Component; | |
} | |
if (Component.displayName) { | |
displayName = Component.displayName; | |
} | |
StyledComponent.displayName = `Styled(${displayName})`; | |
return StyledComponent; | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment