tiny-sva
Version:
First-class slot variant ergonomics without Panda CSS
35 lines (33 loc) • 1.31 kB
text/typescript
type ClassValue = string | undefined;
type VariantMap<S extends string> = Record<S, ClassValue>;
type DeepPartial<T> = {
[K in keyof T]?: DeepPartial<T[K]> | T[K];
};
interface SvaConfig<S extends string, V extends Record<string, any>> {
slots: readonly S[];
base?: Partial<VariantMap<S>>;
variants?: {
[K in keyof V]: {
[P in V[K]]: DeepPartial<VariantMap<S>>;
};
};
defaultVariants?: Partial<{
[K in keyof V]: V[K];
}>;
compoundVariants?: Array<Partial<{
[K in keyof V]: V[K];
}> & {
css: DeepPartial<VariantMap<S>>;
}>;
className?: string;
}
type VariantProps<C extends SvaConfig<any, any>> = {
[K in keyof NonNullable<C['variants']>]?: keyof NonNullable<NonNullable<C['variants']>[K]>;
};
type SlotClasses<S extends readonly string[]> = Record<S[number], string>;
type SvaReturn<S extends readonly string[], V extends Record<string, any>> = {
(props?: VariantProps<SvaConfig<S[number], V>>): SlotClasses<S>;
splitVariantProps<T extends object>(all: T): [VariantProps<SvaConfig<S[number], V>>, Omit<T, keyof VariantProps<any>>];
};
declare function sva<S extends readonly string[], V extends Record<string, any> = {}>(config: SvaConfig<S[number], V>): SvaReturn<S, V>;
export { type ClassValue, sva };