@emotion/native
Version:
Style and render React Native components using emotion
206 lines (185 loc) • 6.11 kB
TypeScript
// Definitions by: Pat Sissons <https://github.com/patsissons>
// TypeScript Version: 3.4
import { Theme } from '@emotion/react'
import * as RN from 'react-native'
type ReactNative = typeof RN
export type ReactNativeStyle = RN.ViewStyle | RN.TextStyle | RN.ImageStyle
export type ReactNativeStyleType<Props> = Props extends {
style?: RN.StyleProp<infer StyleType>
}
? StyleType extends ReactNativeStyle
? StyleType
: ReactNativeStyle
: ReactNativeStyle
export type InterpolationPrimitive<
StyleType extends ReactNativeStyle = ReactNativeStyle
> =
| null
| undefined
| boolean
| number
| string
| ObjectInterpolation<StyleType>
export type ObjectInterpolation<
StyleType extends ReactNativeStyle = ReactNativeStyle
> = StyleType
export interface ArrayCSSInterpolation<
StyleType extends ReactNativeStyle = ReactNativeStyle
> extends Array<CSSInterpolation<StyleType>> {}
export type CSSInterpolation<
StyleType extends ReactNativeStyle = ReactNativeStyle
> = InterpolationPrimitive<StyleType> | ArrayCSSInterpolation<StyleType>
export interface ArrayInterpolation<
MergedProps,
StyleType extends ReactNativeStyle = ReactNativeStyle
> extends Array<Interpolation<MergedProps, StyleType>> {}
export interface FunctionInterpolation<
MergedProps,
StyleType extends ReactNativeStyle = ReactNativeStyle
> {
(mergedProps: MergedProps): Interpolation<MergedProps, StyleType>
}
export type Interpolation<
MergedProps = unknown,
StyleType extends ReactNativeStyle = ReactNativeStyle
> =
| InterpolationPrimitive<StyleType>
| ArrayInterpolation<MergedProps, StyleType>
| FunctionInterpolation<MergedProps, StyleType>
/** Same as StyledOptions but shouldForwardProp must be a type guard */
export interface FilteringStyledOptions<
Props = Record<string, any>,
ForwardedProps extends keyof Props & string = keyof Props & string
> {
shouldForwardProp?: (propName: string) => propName is ForwardedProps
}
export interface StyledOptions<Props = Record<string, any>> {
shouldForwardProp?: (propName: string) => boolean
}
/**
* @typeparam ComponentProps Props which will be included when withComponent is called
* @typeparam SpecificComponentProps Props which will *not* be included when withComponent is called
*/
export interface StyledComponent<
ComponentProps extends {},
SpecificComponentProps extends {} = {},
JSXProps extends {} = {}
> extends React.FC<ComponentProps & SpecificComponentProps & JSXProps> {
withComponent<C extends React.ComponentClass<React.ComponentProps<C>>>(
component: C
): StyledComponent<
ComponentProps & React.ComponentProps<C>,
{},
{ ref?: React.Ref<InstanceType<C>> }
>
withComponent<C extends React.ComponentType<React.ComponentProps<C>>>(
component: C
): StyledComponent<ComponentProps & React.ComponentProps<C>>
}
/**
* @typeparam ComponentProps Props which will be included when withComponent is called
* @typeparam SpecificComponentProps Props which will *not* be included when withComponent is called
*/
export interface CreateStyledComponent<
ComponentProps extends {},
SpecificComponentProps extends {} = {},
JSXProps extends {} = {},
StyleType extends ReactNativeStyle = ReactNativeStyle
> {
/**
* @typeparam AdditionalProps Additional props to add to your styled component
*/
<AdditionalProps extends {} = {}>(
...styles: ArrayInterpolation<
ComponentProps &
SpecificComponentProps &
AdditionalProps & { theme: Theme },
StyleType
>
): StyledComponent<
ComponentProps & AdditionalProps,
SpecificComponentProps,
JSXProps
>
/**
* @typeparam AdditionalProps Additional props to add to your styled component
*/
<AdditionalProps extends {} = {}>(
template: TemplateStringsArray,
...styles: ArrayInterpolation<
ComponentProps &
SpecificComponentProps &
AdditionalProps & { theme: Theme },
StyleType
>
): StyledComponent<
ComponentProps & AdditionalProps,
SpecificComponentProps,
JSXProps
>
}
/**
* @desc
* This function accepts a React component.
*
* @example styled(MyComponent)({ width: 100 })
* @example styled(MyComponent)(myComponentProps => ({ width: myComponentProps.width })
* @example styled(View)({ width: 100 })
* @example styled(View)<Props>(props => ({ width: props.width })
*/
export interface CreateStyled {
<
C extends React.ComponentClass<React.ComponentProps<C>>,
ForwardedProps extends keyof React.ComponentProps<C> &
string = keyof React.ComponentProps<C> & string
>(
component: C,
options: FilteringStyledOptions<React.ComponentProps<C>, ForwardedProps>
): CreateStyledComponent<
Pick<React.ComponentProps<C>, ForwardedProps> & {
theme?: Theme
as?: React.ElementType
},
{},
{ ref?: React.Ref<InstanceType<C>> },
ReactNativeStyleType<React.ComponentProps<C>>
>
<C extends React.ComponentClass<React.ComponentProps<C>>>(
component: C,
options?: StyledOptions<React.ComponentProps<C>>
): CreateStyledComponent<
React.ComponentProps<C> & {
theme?: Theme
as?: React.ElementType
},
{},
{ ref?: React.Ref<InstanceType<C>> },
ReactNativeStyleType<React.ComponentProps<C>>
>
<
C extends React.ComponentType<React.ComponentProps<C>>,
ForwardedProps extends keyof React.ComponentProps<C> &
string = keyof React.ComponentProps<C> & string
>(
component: C,
options: FilteringStyledOptions<React.ComponentProps<C>, ForwardedProps>
): CreateStyledComponent<
Pick<React.ComponentProps<C>, ForwardedProps> & {
theme?: Theme
as?: React.ElementType
},
{},
{},
ReactNativeStyleType<React.ComponentProps<C>>
>
<C extends React.ComponentType<React.ComponentProps<C>>>(
component: C,
options?: StyledOptions<React.ComponentProps<C>>
): CreateStyledComponent<
React.ComponentProps<C> & { theme?: Theme; as?: React.ElementType },
{},
{},
ReactNativeStyleType<React.ComponentProps<C>>
>
}
export const styled: CreateStyled