import type * as CSS from 'csstype';
import React from 'react';
import ComponentStyle from './models/ComponentStyle';
import { DefaultTheme } from './models/ThemeProvider';
import createWarnTooManyClasses from './utils/createWarnTooManyClasses';
import type { SupportedHTMLElements } from './utils/domElements';
export { CSS, DefaultTheme, SupportedHTMLElements };
interface ExoticComponentWithDisplayName
extends React.ExoticComponent
{
defaultProps?: Partial
| undefined;
displayName?: string | undefined;
}
/**
* Use this type to disambiguate between a styled-component instance
* and a StyleFunction or any other type of function.
*/
export type StyledComponentBrand = {
readonly _sc: symbol;
};
export type BaseObject = {};
export type OmitNever = {
[K in keyof T as T[K] extends never ? never : K]: T[K];
};
export type FastOmit = {
[K in keyof T as K extends U ? never : K]: T[K];
};
export type Runtime = 'web' | 'native';
export type AnyComponent = ExoticComponentWithDisplayName
| React.ComponentType
;
export type KnownTarget = SupportedHTMLElements | AnyComponent;
export type WebTarget = string | KnownTarget;
export type NativeTarget = AnyComponent;
export type StyledTarget = R extends 'web' ? WebTarget : NativeTarget;
export interface StyledOptions {
attrs?: Attrs[] | undefined;
componentId?: (R extends 'web' ? string : never) | undefined;
displayName?: string | undefined;
parentComponentId?: (R extends 'web' ? string : never) | undefined;
shouldForwardProp?: ShouldForwardProp | undefined;
}
export type Dict = {
[key: string]: T;
};
/**
* This type is intended for when data attributes are composed via
* the `.attrs` API:
*
* ```tsx
* styled.div.attrs({ 'data-testid': 'foo' })``
* ```
*
* Would love to figure out how to support this natively without having to
* manually compose the type, but haven't figured out a way to do so yet that
* doesn't cause specificity loss (see `test/types.tsx` if you attempt to embed
* `DataAttributes` directly in the `Attrs<>` type.)
*/
export type DataAttributes = {
[key: `data-${string}`]: any;
};
export type ExecutionProps = {
/**
* Dynamically adjust the rendered component or HTML tag, e.g.
* ```
* const StyledButton = styled.button``
*
*
* I'm an anchor now
*
* ```
*/
as?: KnownTarget | undefined;
forwardedAs?: KnownTarget | undefined;
theme?: DefaultTheme | undefined;
};
/**
* ExecutionProps but with `theme` required.
*/
export interface ExecutionContext extends ExecutionProps {
theme: DefaultTheme;
}
export interface StyleFunction {
(executionContext: ExecutionContext & Props): Interpolation;
}
export type Interpolation = StyleFunction | StyledObject | TemplateStringsArray | string | number | false | undefined | null | Keyframes | StyledComponentBrand | RuleSet | Interpolation[];
export type Attrs = (ExecutionProps & Partial) | ((props: ExecutionContext & Props) => ExecutionProps & Partial);
export type RuleSet = Interpolation[];
export type Styles = TemplateStringsArray | StyledObject | StyleFunction;
export type NameGenerator = (hash: number) => string;
export interface StyleSheet {
create: Function;
}
export interface Keyframes {
id: string;
name: string;
rules: string;
}
export interface Flattener {
(chunks: Interpolation[], executionContext: object | null | undefined, styleSheet: StyleSheet | null | undefined): Interpolation[];
}
export interface Stringifier {
(css: string, selector?: string | undefined, prefix?: string | undefined, componentId?: string | undefined): string[];
hash: string;
}
export interface ShouldForwardProp {
(prop: string, elementToBeCreated: StyledTarget): boolean;
}
export interface CommonStatics {
attrs: Attrs[];
target: StyledTarget;
shouldForwardProp?: ShouldForwardProp | undefined;
}
export interface IStyledStatics extends CommonStatics {
componentStyle: R extends 'web' ? ComponentStyle : never;
foldedComponentIds: R extends 'web' ? string : never;
inlineStyle: R extends 'native' ? InstanceType> : never;
target: StyledTarget;
styledComponentId: R extends 'web' ? string : never;
warnTooManyClasses?: (R extends 'web' ? ReturnType : never) | undefined;
}
/**
* Used by PolymorphicComponent to define prop override cascading order.
*/
export type PolymorphicComponentProps | void, ForwardedAsTarget extends StyledTarget | void, AsTargetProps extends object = AsTarget extends KnownTarget ? React.ComponentPropsWithRef : {}, ForwardedAsTargetProps extends object = ForwardedAsTarget extends KnownTarget ? React.ComponentPropsWithRef : {}> = NoInfer>, keyof ExecutionProps>> & FastOmit & {
as?: AsTarget;
forwardedAs?: ForwardedAsTarget;
};
/**
* This type forms the signature for a forwardRef-enabled component
* that accepts the "as" prop to dynamically change the underlying
* rendered JSX. The interface will automatically attempt to extract
* props from the given rendering target to get proper typing for
* any specialized props in the target component.
*/
export interface PolymorphicComponent extends React.ForwardRefExoticComponent {
| void = void, ForwardedAsTarget extends StyledTarget | void = void>(props: PolymorphicComponentProps): JSX.Element;
}
export interface IStyledComponentBase extends PolymorphicComponent, IStyledStatics, StyledComponentBrand {
defaultProps?: (ExecutionProps & Partial) | undefined;
toString: () => string;
}
export type IStyledComponent = IStyledComponentBase &
/**
* TypeScript doesn't allow using a styled component as a key inside object
* styles because "A computed property name must be of type 'string', 'number',
* 'symbol', or 'any'.". The toString() method only exists in the web runtime.
* This hack intersects the `IStyledComponent` type with the built-in `string`
* type to keep TSC happy.
*
* @example
* const H1 = styled.h1({
* fontSize: '2rem'
* });
*
* const Header = styled.header({
* [H1]: {
* marginBottom: '1rem'
* }
* })
*/
(R extends 'web' ? string : {});
export interface IStyledComponentFactory, OuterProps extends object, OuterStatics extends object = BaseObject> {
(target: Target, options: StyledOptions, rules: RuleSet): IStyledComponent> & OuterStatics & Statics;
}
export interface IInlineStyleConstructor {
new (rules: RuleSet): IInlineStyle;
}
export interface IInlineStyle {
rules: RuleSet;
generateStyleObject(executionContext: ExecutionContext & Props): object;
}
export type CSSProperties = CSS.Properties;
export type CSSPseudos = {
[K in CSS.Pseudos]?: CSSObject;
};
export type CSSKeyframes = object & {
[key: string]: CSSObject;
};
export type CSSObject = StyledObject;
export interface StyledObject extends CSSProperties, CSSPseudos {
[key: string]: StyledObject | string | number | StyleFunction | RuleSet | undefined;
}
/**
* The `css` prop is not declared by default in the types as it would cause `css` to be present
* on the types of anything that uses styled-components indirectly, even if they do not use the
* babel plugin.
*
* To enable support for the `css` prop in TypeScript, create a `styled-components.d.ts` file in
* your project source with the following contents:
*
* ```ts
* import type { CSSProp } from "styled-components";
*
* declare module "react" {
* interface Attributes {
* css?: CSSProp;
* }
* }
* ```
*
* In order to get accurate typings for `props.theme` in `css` interpolations, see
* {@link DefaultTheme}.
*/
export type CSSProp = Interpolation;
export type NoInfer = [T][T extends any ? 0 : never];
export type Substitute = FastOmit & B;