import { ElementType, ReactElement } from 'react'; /** * Creates a Prop Types from a VariantRecord. * Function variants get the type inferred by the first argument type */ declare type EvaluateProps = { [Prop in keyof Variants]: Variants[Prop] extends Record ? keyof Variants[Prop] : Variants[Prop] extends (...args: any) => any ? Parameters[0] : never; }; declare type EvaluateRecordProps = { [Prop in keyof Variants]: Variants[Prop] extends Record ? keyof Variants[Prop] : Variants[Prop] extends (arg: any) => any ? any : never; }; /** * Gets the keys that 2 types have in common * GetIntersectionKeys<{ x, y, z }, { h, x, z }> = 'x' | 'z' */ declare type GetIntersectionKeys = { [k in keyof T]: K extends k ? K : never; }[keyof T]; /** * Create Optional Props type. * CreateOptionalProps<{ x: string, y: number}, 'x'> = { x?: string } */ declare type CreateOptionalProps = Partial>>; declare type EvaluatePropsWithDefaultVariants = Omit, keyof DefaultVariants> & CreateOptionalProps, DefaultVariants>; /** * Variants can receive records or functions. This is the function type of it. * It would be incredible if we could pass the types to it, but it would need to auto-infer * the variants as it's been written. */ declare type ClassNameFunction = (value: any, props: any, variants: any) => string; export declare type VariantsRecord = Record | ClassNameFunction>; export declare type CompoundVariants = Partial<{ [k in Keys]: keyof Variants[k]; }> & { defaultTo?: Partial<{ [k in Keys]: keyof Variants[k]; }>; class?: string; }; /** * Configuration to create a Component with variants */ export interface ComponentConfig { className?: string; variants?: Variants; transient?: (keyof Variants)[]; defaultVariants?: DefaultVariants; compoundVariants?: Array>; defaultProps?: Partial>>; } /** * Get Default Values types. * It could be better, infering which values it could receive, like using * = Partial> * But, that breaks `styled`, as it makes all props optional. */ declare type GetDefaultVariants = Partial>; /** * Styled Component. Supports the As prop, which changes the prop types based on the component * it's rendering. */ export interface Component { (props: StyledProps): ReactElement; displayName?: string | undefined; } /** * Extract Props from a Component */ declare type InferAnyComponentProps = T extends ElementType ? Props : T; declare type ToIntrinsicElementIfPossible = As extends keyof JSX.IntrinsicElements ? JSX.IntrinsicElements[As] : As; /** * Extract Props from a W.Component */ export declare type Infer = T extends Component ? StyledProps : InferAnyComponentProps; declare type GetPropsWithoutVariantsKeys = Omit>, keyof Variants | 'as'>; /** * Evaluates props based on Variants. Variants that have a Default value become optional. * It also merges with the Component's Props, replacing the ones that are variants. * Ex.: * const Component = styled( * ({ color, checked, x }: { color: string, checked: string, x: string }) => null, { * variants: { * color: { * gray: 'foo', * red: 'bar', * }, * checked: (value: boolean) => value ? 'x' : 'y' * }, * defaultVariants: { * color: 'gray' * } * }) * * // ✅ * // ❌ missing `x` prop * // ❌ `x` prop should be string * // ❌ `checked` prop should be boolean * // ❌ missing `checked` prop * // ✅ */ export declare type StyledProps = { as?: As; } & GetPropsWithoutVariantsKeys & EvaluatePropsWithDefaultVariants; /** * Styled Function should infer the Component, the Variants object and the Default * Variants values so the created component has the right props. */ interface StyledFunction { = {}>(component: DefaultAs, config: ComponentConfig): Component; } /** * Styled should be callable by: * styled('a', { className: 'text-sm', variants: { ... } }) * styled(Component, { className: '...', variants: { ... } }) * styled.a('text-sm', { variants: { ... } }) * styled.a('text-sm') */ export declare type Styled = StyledFunction & { [DefaultAs in keyof JSX.IntrinsicElements]: StyledTagFunction; }; export declare type StyledTagFunction = = {}>(cx: string, config?: Omit, 'className'>) => Component; /** * Configuration to create a Component with variants */ export interface ClassNameFactorConfig { className?: string; variants: Variants; defaultVariants?: DefaultVariants; compoundVariants?: Array>; } export declare type ClassNameFactor = { >>(config: ClassNameFactorConfig): (props: EvaluatePropsWithDefaultVariants) => string; }; export {};