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; };