// @flow import type { ElementType, StatelessFunctionalComponent, AbstractComponent } from 'react' import isPropValid from '@emotion/is-prop-valid' export type Interpolations = Array export type StyledElementType = | string | AbstractComponent<{ ...Props, className: string }, mixed> export type StyledOptions = { label?: string, shouldForwardProp?: string => boolean, target?: string } export type StyledComponent = StatelessFunctionalComponent & { defaultProps: any, toString: () => string, withComponent: ( nextTag: StyledElementType, nextOptions?: StyledOptions ) => StyledComponent } export type PrivateStyledComponent = StyledComponent & { __emotion_real: StyledComponent, __emotion_base: any, __emotion_styles: any, __emotion_forwardProp: any } const testOmitPropsOnStringTag = isPropValid const testOmitPropsOnComponent = (key: string) => key !== 'theme' export const getDefaultShouldForwardProp = (tag: ElementType) => typeof tag === 'string' && // 96 is one less than the char code // for "a" so this is checking that // it's a lowercase character tag.charCodeAt(0) > 96 ? testOmitPropsOnStringTag : testOmitPropsOnComponent export const composeShouldForwardProps = ( tag: PrivateStyledComponent, options: StyledOptions | void, isReal: boolean ) => { let shouldForwardProp if (options) { const optionsShouldForwardProp = options.shouldForwardProp shouldForwardProp = tag.__emotion_forwardProp && optionsShouldForwardProp ? (propName: string) => tag.__emotion_forwardProp(propName) && optionsShouldForwardProp(propName) : optionsShouldForwardProp } if (typeof shouldForwardProp !== 'function' && isReal) { shouldForwardProp = tag.__emotion_forwardProp } return shouldForwardProp } export type CreateStyledComponent = ( ...args: Interpolations ) => StyledComponent export type CreateStyled = { ( tag: StyledElementType, options?: StyledOptions ): (...args: Interpolations) => StyledComponent, [key: string]: CreateStyledComponent, bind: () => CreateStyled }