UNPKG

9.43 kBTypeScriptView Raw
1import type * as CSS from 'csstype';
2import React from 'react';
3import ComponentStyle from './models/ComponentStyle';
4import { DefaultTheme } from './models/ThemeProvider';
5import createWarnTooManyClasses from './utils/createWarnTooManyClasses';
6import type { SupportedHTMLElements } from './utils/domElements';
7export { CSS, DefaultTheme, SupportedHTMLElements };
8interface ExoticComponentWithDisplayName<P extends object = {}> extends React.ExoticComponent<P> {
9 defaultProps?: Partial<P> | undefined;
10 displayName?: string | undefined;
11}
12/**
13 * Use this type to disambiguate between a styled-component instance
14 * and a StyleFunction or any other type of function.
15 */
16export type StyledComponentBrand = {
17 readonly _sc: symbol;
18};
19export type BaseObject = {};
20export type OmitNever<T> = {
21 [K in keyof T as T[K] extends never ? never : K]: T[K];
22};
23export type FastOmit<T extends object, U extends string | number | symbol> = {
24 [K in keyof T as K extends U ? never : K]: T[K];
25};
26export type Runtime = 'web' | 'native';
27export type AnyComponent<P extends object = any> = ExoticComponentWithDisplayName<P> | React.ComponentType<P>;
28export type KnownTarget = SupportedHTMLElements | AnyComponent;
29export type WebTarget = string | KnownTarget;
30export type NativeTarget = AnyComponent;
31export type StyledTarget<R extends Runtime> = R extends 'web' ? WebTarget : NativeTarget;
32export interface StyledOptions<R extends Runtime, Props extends object> {
33 attrs?: Attrs<Props>[] | undefined;
34 componentId?: (R extends 'web' ? string : never) | undefined;
35 displayName?: string | undefined;
36 parentComponentId?: (R extends 'web' ? string : never) | undefined;
37 shouldForwardProp?: ShouldForwardProp<R> | undefined;
38}
39export type Dict<T = any> = {
40 [key: string]: T;
41};
42/**
43 * This type is intended for when data attributes are composed via
44 * the `.attrs` API:
45 *
46 * ```tsx
47 * styled.div.attrs<DataAttributes>({ 'data-testid': 'foo' })``
48 * ```
49 *
50 * Would love to figure out how to support this natively without having to
51 * manually compose the type, but haven't figured out a way to do so yet that
52 * doesn't cause specificity loss (see `test/types.tsx` if you attempt to embed
53 * `DataAttributes` directly in the `Attrs<>` type.)
54 */
55export type DataAttributes = {
56 [key: `data-${string}`]: any;
57};
58export type ExecutionProps = {
59 /**
60 * Dynamically adjust the rendered component or HTML tag, e.g.
61 * ```
62 * const StyledButton = styled.button``
63 *
64 * <StyledButton as="a" href="/foo">
65 * I'm an anchor now
66 * </StyledButton>
67 * ```
68 */
69 as?: KnownTarget | undefined;
70 forwardedAs?: KnownTarget | undefined;
71 theme?: DefaultTheme | undefined;
72};
73/**
74 * ExecutionProps but with `theme` required.
75 */
76export interface ExecutionContext extends ExecutionProps {
77 theme: DefaultTheme;
78}
79export interface StyleFunction<Props extends object> {
80 (executionContext: ExecutionContext & Props): Interpolation<Props>;
81}
82export type Interpolation<Props extends object> = StyleFunction<Props> | StyledObject<Props> | TemplateStringsArray | string | number | false | undefined | null | Keyframes | StyledComponentBrand | RuleSet<Props> | Interpolation<Props>[];
83export type Attrs<Props extends object = BaseObject> = (ExecutionProps & Partial<Props>) | ((props: ExecutionContext & Props) => ExecutionProps & Partial<Props>);
84export type RuleSet<Props extends object = BaseObject> = Interpolation<Props>[];
85export type Styles<Props extends object> = TemplateStringsArray | StyledObject<Props> | StyleFunction<Props>;
86export type NameGenerator = (hash: number) => string;
87export interface StyleSheet {
88 create: Function;
89}
90export interface Keyframes {
91 id: string;
92 name: string;
93 rules: string;
94}
95export interface Flattener<Props extends object> {
96 (chunks: Interpolation<Props>[], executionContext: object | null | undefined, styleSheet: StyleSheet | null | undefined): Interpolation<Props>[];
97}
98export interface Stringifier {
99 (css: string, selector?: string | undefined, prefix?: string | undefined, componentId?: string | undefined): string[];
100 hash: string;
101}
102export interface ShouldForwardProp<R extends Runtime> {
103 (prop: string, elementToBeCreated: StyledTarget<R>): boolean;
104}
105export interface CommonStatics<R extends Runtime, Props extends object> {
106 attrs: Attrs<Props>[];
107 target: StyledTarget<R>;
108 shouldForwardProp?: ShouldForwardProp<R> | undefined;
109}
110export interface IStyledStatics<R extends Runtime, OuterProps extends object> extends CommonStatics<R, OuterProps> {
111 componentStyle: R extends 'web' ? ComponentStyle : never;
112 foldedComponentIds: R extends 'web' ? string : never;
113 inlineStyle: R extends 'native' ? InstanceType<IInlineStyleConstructor<OuterProps>> : never;
114 target: StyledTarget<R>;
115 styledComponentId: R extends 'web' ? string : never;
116 warnTooManyClasses?: (R extends 'web' ? ReturnType<typeof createWarnTooManyClasses> : never) | undefined;
117}
118/**
119 * Used by PolymorphicComponent to define prop override cascading order.
120 */
121export type PolymorphicComponentProps<R extends Runtime, BaseProps extends object, AsTarget extends StyledTarget<R> | void, ForwardedAsTarget extends StyledTarget<R> | void, AsTargetProps extends object = AsTarget extends KnownTarget ? React.ComponentPropsWithRef<AsTarget> : {}, ForwardedAsTargetProps extends object = ForwardedAsTarget extends KnownTarget ? React.ComponentPropsWithRef<ForwardedAsTarget> : {}> = NoInfer<FastOmit<Substitute<BaseProps, Substitute<ForwardedAsTargetProps, AsTargetProps>>, keyof ExecutionProps>> & FastOmit<ExecutionProps, 'as' | 'forwardedAs'> & {
122 as?: AsTarget;
123 forwardedAs?: ForwardedAsTarget;
124};
125/**
126 * This type forms the signature for a forwardRef-enabled component
127 * that accepts the "as" prop to dynamically change the underlying
128 * rendered JSX. The interface will automatically attempt to extract
129 * props from the given rendering target to get proper typing for
130 * any specialized props in the target component.
131 */
132export interface PolymorphicComponent<R extends Runtime, BaseProps extends object> extends React.ForwardRefExoticComponent<BaseProps> {
133 <AsTarget extends StyledTarget<R> | void = void, ForwardedAsTarget extends StyledTarget<R> | void = void>(props: PolymorphicComponentProps<R, BaseProps, AsTarget, ForwardedAsTarget>): React.JSX.Element;
134}
135export interface IStyledComponentBase<R extends Runtime, Props extends object = BaseObject> extends PolymorphicComponent<R, Props>, IStyledStatics<R, Props>, StyledComponentBrand {
136 defaultProps?: (ExecutionProps & Partial<Props>) | undefined;
137 toString: () => string;
138}
139export type IStyledComponent<R extends Runtime, Props extends object = BaseObject> = IStyledComponentBase<R, Props> &
140/**
141 * TypeScript doesn't allow using a styled component as a key inside object
142 * styles because "A computed property name must be of type 'string', 'number',
143 * 'symbol', or 'any'.". The toString() method only exists in the web runtime.
144 * This hack intersects the `IStyledComponent` type with the built-in `string`
145 * type to keep TSC happy.
146 *
147 * @example
148 * const H1 = styled.h1({
149 * fontSize: '2rem'
150 * });
151 *
152 * const Header = styled.header({
153 * [H1]: {
154 * marginBottom: '1rem'
155 * }
156 * })
157 */
158(R extends 'web' ? string : {});
159export interface IStyledComponentFactory<R extends Runtime, Target extends StyledTarget<R>, OuterProps extends object, OuterStatics extends object = BaseObject> {
160 <Props extends object = BaseObject, Statics extends object = BaseObject>(target: Target, options: StyledOptions<R, OuterProps & Props>, rules: RuleSet<OuterProps & Props>): IStyledComponent<R, Substitute<OuterProps, Props>> & OuterStatics & Statics;
161}
162export interface IInlineStyleConstructor<Props extends object> {
163 new (rules: RuleSet<Props>): IInlineStyle<Props>;
164}
165export interface IInlineStyle<Props extends object> {
166 rules: RuleSet<Props>;
167 generateStyleObject(executionContext: ExecutionContext & Props): object;
168}
169export type CSSProperties = CSS.Properties<number | (string & {})>;
170export type CSSPseudos = {
171 [K in CSS.Pseudos]?: CSSObject;
172};
173export type CSSKeyframes = object & {
174 [key: string]: CSSObject;
175};
176export type CSSObject<Props extends object = BaseObject> = StyledObject<Props>;
177export interface StyledObject<Props extends object = BaseObject> extends CSSProperties, CSSPseudos {
178 [key: string]: StyledObject<Props> | string | number | StyleFunction<Props> | RuleSet<any> | undefined;
179}
180/**
181 * The `css` prop is not declared by default in the types as it would cause `css` to be present
182 * on the types of anything that uses styled-components indirectly, even if they do not use the
183 * babel plugin.
184 *
185 * To enable support for the `css` prop in TypeScript, create a `styled-components.d.ts` file in
186 * your project source with the following contents:
187 *
188 * ```ts
189 * import type { CSSProp } from "styled-components";
190 *
191 * declare module "react" {
192 * interface Attributes {
193 * css?: CSSProp;
194 * }
195 * }
196 * ```
197 *
198 * In order to get accurate typings for `props.theme` in `css` interpolations, see
199 * {@link DefaultTheme}.
200 */
201export type CSSProp = Interpolation<any>;
202export type NoInfer<T> = [T][T extends any ? 0 : never];
203export type Substitute<A extends object, B extends object> = FastOmit<A, keyof B> & B;
204export type InsertionTarget = HTMLElement | ShadowRoot;