styled.tsx 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. /* HACK(BYK): This file is a slightly modified backport of
  2. *
  3. * !!! DELETE ME WHEN UPGRADING TO EMOTION@11 !!!
  4. *
  5. * https://github.com/emotion-js/emotion/pull/1501 and
  6. * https://github.com/emotion-js/emotion/pull/1664 to
  7. * fix our TypeScript compile times and memory usage as
  8. * emotion@10 is known to generate too many new types due
  9. * to improper use of generics.
  10. *
  11. * This is especially pronounced with TS 3.7+
  12. * See https://github.com/microsoft/TypeScript/issues/24435
  13. * See https://github.com/microsoft/TypeScript/issues/34920
  14. */
  15. import * as React from 'react';
  16. import styled from '@original-emotion/styled';
  17. // TODO(BYK): Figure out why ESLint cannot resolve this
  18. // probably need to include `.d.ts` extension
  19. // in some resolver config.
  20. // eslint-disable-next-line import/no-unresolved
  21. import * as CSS from 'csstype';
  22. import {Theme} from './utils/theme';
  23. /**
  24. * @desc Utility type for getting props type of React component.
  25. */
  26. export type PropsOf<
  27. C extends keyof JSX.IntrinsicElements | React.JSXElementConstructor<any>
  28. > = JSX.LibraryManagedAttributes<C, React.ComponentProps<C>>;
  29. export interface SerializedStyles {
  30. name: string;
  31. styles: string;
  32. map?: string;
  33. next?: SerializedStyles;
  34. }
  35. export interface StyledOptions {
  36. label?: string;
  37. shouldForwardProp?(propName: string): boolean;
  38. target?: string;
  39. }
  40. export interface CSSObject
  41. extends CSSPropertiesWithMultiValues,
  42. CSSPseudosForCSSObject,
  43. CSSOthersObjectForCSSObject {}
  44. export interface ComponentSelector {
  45. __emotion_styles: any;
  46. }
  47. export type Keyframes = {
  48. name: string;
  49. styles: string;
  50. anim: number;
  51. toString: () => string;
  52. } & string;
  53. export type CSSProperties = CSS.PropertiesFallback<number | string>;
  54. export type CSSPropertiesWithMultiValues = {
  55. [K in keyof CSSProperties]: CSSProperties[K] | Array<Extract<CSSProperties[K], string>>;
  56. };
  57. /**
  58. * @desc Following type exists for autocompletion of key.
  59. */
  60. export type CSSPseudos<MP> = {[K in CSS.Pseudos]?: ObjectInterpolation<MP>};
  61. export interface CSSOthersObject<MP> {
  62. [propertiesName: string]: Interpolation<MP>;
  63. }
  64. export type CSSPseudosForCSSObject = {[K in CSS.Pseudos]?: CSSObject};
  65. export interface ArrayCSSInterpolation extends Array<CSSInterpolation> {}
  66. export type CSSInterpolation =
  67. | null
  68. | undefined
  69. | boolean
  70. | number
  71. | string
  72. | ComponentSelector
  73. | Keyframes
  74. | SerializedStyles
  75. | CSSObject
  76. | ArrayCSSInterpolation;
  77. export interface CSSOthersObjectForCSSObject {
  78. [propertiesName: string]: CSSInterpolation;
  79. }
  80. export interface ArrayInterpolation<MP> extends Array<Interpolation<MP>> {}
  81. export interface ObjectInterpolation<MP>
  82. extends CSSPropertiesWithMultiValues,
  83. CSSPseudos<MP>,
  84. CSSOthersObject<MP> {}
  85. export interface FunctionInterpolation<MergedProps> {
  86. (mergedProps: MergedProps): Interpolation<MergedProps>;
  87. }
  88. export type Interpolation<MergedProps = undefined> =
  89. | null
  90. | undefined
  91. | boolean
  92. | number
  93. | string
  94. | ComponentSelector
  95. | Keyframes
  96. | SerializedStyles
  97. | ArrayInterpolation<MergedProps>
  98. | ObjectInterpolation<MergedProps>
  99. | FunctionInterpolation<MergedProps>;
  100. /**
  101. * @typeparam ComponentProps Props which will be included when withComponent is called
  102. * @typeparam SpecificComponentProps Props which will *not* be included when withComponent is called
  103. */
  104. export interface StyledComponent<
  105. ComponentProps extends {},
  106. SpecificComponentProps extends {} = {}
  107. > extends React.FC<ComponentProps & SpecificComponentProps>,
  108. ComponentSelector {
  109. withComponent<C extends React.ComponentType<React.ComponentProps<C>>>(
  110. component: C
  111. ): StyledComponent<ComponentProps & PropsOf<C>>;
  112. withComponent<Tag extends keyof JSX.IntrinsicElements>(
  113. tag: Tag
  114. ): StyledComponent<ComponentProps, JSX.IntrinsicElements[Tag]>;
  115. }
  116. /**
  117. * @typeparam ComponentProps Props which will be included when withComponent is called
  118. * @typeparam SpecificComponentProps Props which will *not* be included when withComponent is called
  119. * @typeparam StyleProps Params passed to styles but not exposed as React props. These are normally library provided props
  120. */
  121. export interface CreateStyledComponent<
  122. ComponentProps extends {},
  123. SpecificComponentProps extends {} = {},
  124. StyleProps extends {} = {}
  125. > {
  126. /**
  127. * @typeparam AdditionalProps Additional props to add to your styled component
  128. */
  129. <AdditionalProps extends {} = {}>(
  130. ...styles: Array<
  131. Interpolation<
  132. ComponentProps &
  133. SpecificComponentProps &
  134. StyleProps &
  135. AdditionalProps & {theme: Theme}
  136. >
  137. >
  138. ): StyledComponent<ComponentProps & AdditionalProps, SpecificComponentProps>;
  139. (
  140. template: TemplateStringsArray,
  141. ...styles: Array<Interpolation<ComponentProps & SpecificComponentProps & StyleProps>>
  142. ): StyledComponent<ComponentProps, SpecificComponentProps>;
  143. /**
  144. * @typeparam AdditionalProps Additional props to add to your styled component
  145. */
  146. <AdditionalProps extends {}>(
  147. template: TemplateStringsArray,
  148. ...styles: Array<
  149. Interpolation<
  150. ComponentProps &
  151. SpecificComponentProps &
  152. StyleProps &
  153. AdditionalProps & {theme: Theme}
  154. >
  155. >
  156. ): StyledComponent<ComponentProps & AdditionalProps, SpecificComponentProps>;
  157. }
  158. /**
  159. * @desc
  160. * This function accepts a React component or tag ('div', 'a' etc).
  161. *
  162. * @example styled(MyComponent)({ width: 100 })
  163. * @example styled(MyComponent)(myComponentProps => ({ width: myComponentProps.width })
  164. * @example styled('div')({ width: 100 })
  165. * @example styled('div')<Props>(props => ({ width: props.width })
  166. */
  167. export interface CreateStyled {
  168. // This `any` below, should be `React.ComponentProps` but https://github.com/getsentry/sentry/pull/15383 prevents it
  169. <C extends React.ComponentType<any>>(
  170. component: C,
  171. options?: StyledOptions
  172. ): CreateStyledComponent<PropsOf<C> & {theme?: Theme}, {}, {theme: Theme}>;
  173. <Tag extends keyof JSX.IntrinsicElements>(
  174. tag: Tag,
  175. options?: StyledOptions
  176. ): CreateStyledComponent<{theme?: Theme}, JSX.IntrinsicElements[Tag], {theme: Theme}>;
  177. }
  178. export default styled as CreateStyled;