UNPKG

2.23 kBJavaScriptView Raw
1// @flow
2import type {
3 ElementType,
4 StatelessFunctionalComponent,
5 AbstractComponent
6} from 'react'
7import isPropValid from '@emotion/is-prop-valid'
8
9export type Interpolations = Array<any>
10
11export type StyledElementType<Props> =
12 | string
13 | AbstractComponent<{ ...Props, className: string }, mixed>
14
15export type StyledOptions = {
16 label?: string,
17 shouldForwardProp?: string => boolean,
18 target?: string
19}
20
21export type StyledComponent<Props> = StatelessFunctionalComponent<Props> & {
22 defaultProps: any,
23 toString: () => string,
24 withComponent: (
25 nextTag: StyledElementType<Props>,
26 nextOptions?: StyledOptions
27 ) => StyledComponent<Props>
28}
29
30export type PrivateStyledComponent<Props> = StyledComponent<Props> & {
31 __emotion_real: StyledComponent<Props>,
32 __emotion_base: any,
33 __emotion_styles: any,
34 __emotion_forwardProp: any
35}
36
37const testOmitPropsOnStringTag = isPropValid
38const testOmitPropsOnComponent = (key: string) => key !== 'theme'
39
40export const getDefaultShouldForwardProp = (tag: ElementType) =>
41 typeof tag === 'string' &&
42 // 96 is one less than the char code
43 // for "a" so this is checking that
44 // it's a lowercase character
45 tag.charCodeAt(0) > 96
46 ? testOmitPropsOnStringTag
47 : testOmitPropsOnComponent
48
49export const composeShouldForwardProps = (
50 tag: PrivateStyledComponent<any>,
51 options: StyledOptions | void,
52 isReal: boolean
53) => {
54 let shouldForwardProp
55 if (options) {
56 const optionsShouldForwardProp = options.shouldForwardProp
57 shouldForwardProp =
58 tag.__emotion_forwardProp && optionsShouldForwardProp
59 ? (propName: string) =>
60 tag.__emotion_forwardProp(propName) &&
61 optionsShouldForwardProp(propName)
62 : optionsShouldForwardProp
63 }
64
65 if (typeof shouldForwardProp !== 'function' && isReal) {
66 shouldForwardProp = tag.__emotion_forwardProp
67 }
68
69 return shouldForwardProp
70}
71
72export type CreateStyledComponent = <Props>(
73 ...args: Interpolations
74) => StyledComponent<Props>
75
76export type CreateStyled = {
77 <Props>(
78 tag: StyledElementType<Props>,
79 options?: StyledOptions
80 ): (...args: Interpolations) => StyledComponent<Props>,
81 [key: string]: CreateStyledComponent,
82 bind: () => CreateStyled
83}