cva-extended
Version:
Class Variance Authority 🧬 - Extended
116 lines (115 loc) • 5.06 kB
TypeScript
export type ClassValue = ClassArray | ClassDictionary | string | number | bigint | null | boolean | undefined;
export type ClassDictionary = Record<string, any>;
export type ClassArray = ClassValue[];
type OmitUndefined<T> = T extends undefined ? never : T;
type StringToBoolean<T> = T extends "true" | "false" ? boolean : T;
type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends (k: infer I) => void ? I : never;
type AnyFunction = (...args: any[]) => any;
type RequiredKeys<O extends object, K extends keyof O> = Omit<O, K> & Required<Pick<O, K>>;
type RequiredKeysOf<T extends object> = Exclude<{
[Key in keyof T]: T extends Record<Key, T[Key]> ? Key : never;
}[keyof T], undefined>;
/**
* A private variant is a variant that is not meant to be used by the consumer, and is not exposed via `VariantProps`.
* Any variant that starts with a `$` is considered a private variant.
*/
type PrivateVariant<TVariantName extends string = string> = `$${TVariantName}`;
export type VariantProps<Component extends AnyFunction> = Omit<InternalVariantProps<Component>, PrivateVariant>;
type InternalVariantProps<Component extends (...args: any) => any> = Omit<OmitUndefined<Parameters<Component>[0]>, "class" | "className">;
type AnyCVABuilderFunction = AnyFunction & {
variants: never | Record<string, readonly VariantValue[]>;
};
export interface Compose {
<T extends AnyCVABuilderFunction[]>(...components: [...T]): OptionalizeParameter<(props: UnionToIntersection<{
[K in keyof T]: InternalVariantProps<T[K]>;
}[number]> & CVAClassProp) => string> & {
variants: UnionToIntersection<Exclude<T[number]["variants"], never>>;
};
}
export interface CX {
(...inputs: ClassValue[]): string;
}
export type CXOptions = Parameters<CX>;
export type CXReturn = ReturnType<CX>;
type CVAConfigBase = {
base?: ClassValue;
};
type CVAVariantShape = Record<string, Record<string, ClassValue>>;
type CVAVariantSchema<V extends CVAVariantShape> = {
[Variant in keyof V]?: StringToBoolean<keyof V[Variant]> | undefined;
};
type CVAClassProp = {
class?: ClassValue;
className?: never;
} | {
class?: never;
className?: ClassValue;
};
type CVAVariantSchemaProps<V extends CVAVariantSchema<any>, D> = Omit<RequiredKeys<V, Exclude<keyof V, keyof D>>, PrivateVariant>;
export interface CVA {
<_ extends "cva's generic parameters are restricted to internal use only.", TVariants, TDefaultVariants>(config: TVariants extends CVAVariantShape ? CVAConfigBase & {
variants?: TVariants;
compoundVariants?: (TVariants extends CVAVariantShape ? (CVAVariantSchema<TVariants> | {
[Variant in keyof TVariants]?: StringToBoolean<keyof TVariants[Variant]> | readonly StringToBoolean<keyof TVariants[Variant]>[] | undefined;
}) & CVAClassProp : CVAClassProp)[];
/**
* The default values that will be used when a variant is not provided.
* To mark a property as optional without specifying a value, use `undefined`.
*
* @example
* ```ts
* const box = cva({
* variants: {
* border: {
* true: '...'
* }
* },
* defaultVariants: {
* border: undefined
* }
* })
* ```
*/
defaultVariants?: CVAVariantSchema<TVariants> & TDefaultVariants;
} : CVAConfigBase & {
variants?: never;
compoundVariants?: never;
defaultVariants?: never;
}): OptionalizeParameter<(props: CVAClassProp & (TVariants extends CVAVariantShape ? CVAVariantSchemaProps<CVAVariantSchema<TVariants>, TDefaultVariants> : {})) => string> & {
variants: TVariants extends CVAVariantShape ? {
[K in Exclude<keyof TVariants, PrivateVariant>]: ReadonlyArray<StringToBoolean<Extract<keyof TVariants[K], VariantValue>>>;
} : never;
};
}
/**
* A function that accepts one parameter `T` and returns another parameter `R`.
*/
type UnaryFunction<in T, R> = (arg: T) => R;
/**
* Takes in an unary function and returns the same function, with the first parameter being optional, if the original function's first parameter is an
* object with all of its keys being optional.
*/
type OptionalizeParameter<F extends UnaryFunction<any, any>> = RequiredKeysOf<Parameters<F>[0]> extends [] ? (arg?: Parameters<F>[0]) => ReturnType<F> : F;
type VariantValue = string | number | boolean;
export interface DefineConfigOptions {
hooks?: {
/**
* @deprecated please use `onComplete`
*/
"cx:done"?: (className: string) => string;
/**
* Returns the completed string of concatenated classes/classNames.
*/
onComplete?: (className: string) => string;
};
}
export interface DefineConfig {
(options?: DefineConfigOptions): {
compose: Compose;
cx: CX;
cva: CVA;
};
}
export declare const defineConfig: DefineConfig;
export declare const compose: Compose, cva: CVA, cx: CX;
export {};