107 lines
3.3 KiB
Plaintext
107 lines
3.3 KiB
Plaintext
import { StringToBoolean, ClassProp, ClassValue, OmitUndefined } from 'tailwind-variants';
|
|
import { JSXElementConstructor, ForwardRefExoticComponent, PropsWithoutRef, RefAttributes, ReactElement } from 'react';
|
|
|
|
type SlotsClassValue<S> = {
|
|
[K in keyof S]?: ClassValue;
|
|
};
|
|
|
|
type Variants<S> = {
|
|
[K: string]: {[P: string]: S extends undefined ? ClassValue : SlotsClassValue<S>};
|
|
};
|
|
|
|
type ComponentProps<C> = C extends JSXElementConstructor<infer P> ? P : never;
|
|
|
|
type ComponentSlots<CP> = CP extends {classNames?: infer S} ? S : undefined;
|
|
|
|
type ValidateSubtype<T, U> = OmitUndefined<T> extends U ? "true" : "false";
|
|
|
|
type GetSuggestedValues<S> = S extends undefined ? ClassValue : SlotsClassValue<S>;
|
|
|
|
type SuggestedVariants<CP, S> = {
|
|
[K in keyof CP]?: ValidateSubtype<CP[K], string> extends "true"
|
|
? {[K2 in CP[K]]?: GetSuggestedValues<S>}
|
|
: ValidateSubtype<CP[K], boolean> extends "true"
|
|
? {
|
|
true?: GetSuggestedValues<S>;
|
|
false?: GetSuggestedValues<S>;
|
|
}
|
|
: never;
|
|
};
|
|
|
|
type ComposeVariants<CP, S> = SuggestedVariants<CP, S> | Variants<S>;
|
|
|
|
type VariantValue<V, SV> = {
|
|
[K in keyof V | keyof SV]?:
|
|
| (K extends keyof V ? StringToBoolean<keyof V[K]> : never)
|
|
| (K extends keyof V ? StringToBoolean<keyof V[K]>[] : never)
|
|
| (K extends keyof SV
|
|
? ValidateSubtype<SV[K], object> extends "true"
|
|
? keyof OmitUndefined<SV[K]>
|
|
: never
|
|
: never);
|
|
};
|
|
|
|
type DefaultVariants<V, SV> = VariantValue<V, SV>;
|
|
|
|
type CompoundVariants<V, SV> = Array<VariantValue<V, SV> & ClassProp<ClassValue>>;
|
|
|
|
type Options = {
|
|
/**
|
|
* Whether to merge the class names with `tailwind-merge` library.
|
|
* It avoids to have duplicate tailwind classes. (Recommended)
|
|
* @see https://github.com/dcastil/tailwind-merge/blob/v1.8.1/README.md
|
|
* @default true
|
|
*/
|
|
twMerge?: boolean;
|
|
/**
|
|
* The config object for `tailwind-merge` library.
|
|
* @see https://github.com/dcastil/tailwind-merge/blob/v1.8.1/docs/configuration.md
|
|
*/
|
|
twMergeConfig?: any;
|
|
};
|
|
|
|
type ExtendVariantProps = {
|
|
variants?: Record<string, Record<string, string>>;
|
|
defaultVariants?: Record<string, string>;
|
|
compoundVariants?: Array<Record<string, boolean | string | Record<string, string>>>;
|
|
};
|
|
|
|
type ExtendVariantWithSlotsProps = {
|
|
variants?: Record<string, Record<string, string | Record<string, string>>>;
|
|
defaultVariants?: Record<string, string>;
|
|
compoundVariants?: Array<Record<string, boolean | string | Record<string, string>>>;
|
|
};
|
|
|
|
type ExtendVariants = {
|
|
<
|
|
C extends JSXElementConstructor<any>,
|
|
CP extends ComponentProps<C>,
|
|
S extends ComponentSlots<CP>,
|
|
V extends ComposeVariants<CP, S>,
|
|
SV extends SuggestedVariants<CP, S>,
|
|
DV extends DefaultVariants<V, SV>,
|
|
CV extends CompoundVariants<V, SV>,
|
|
>(
|
|
BaseComponent: C,
|
|
styles: {
|
|
variants?: V;
|
|
defaultVariants?: DV;
|
|
compoundVariants?: CV;
|
|
slots?: S;
|
|
},
|
|
opts?: Options,
|
|
): ForwardRefExoticComponent<
|
|
PropsWithoutRef<{
|
|
[key in keyof CP | keyof V]?:
|
|
| (key extends keyof CP ? CP[key] : never)
|
|
| (key extends keyof V ? StringToBoolean<keyof V[key]> : never);
|
|
}> &
|
|
RefAttributes<ReactElement>
|
|
>;
|
|
};
|
|
|
|
// main function
|
|
declare const extendVariants: ExtendVariants;
|
|
|
|
export { ExtendVariantProps, ExtendVariantWithSlotsProps, ExtendVariants, extendVariants };
|