From 1001090e4cfbc2c6c6b4ea3a9a9c976bb2b8f913 Mon Sep 17 00:00:00 2001 From: p-sw Date: Sat, 25 May 2024 21:31:24 +0900 Subject: [PATCH] fix: apply overload for vcn to remove preset in prop when preset is not defined --- packages/react/shared.tsx | 82 +++++++++++++++++++++++++++------------ 1 file changed, 57 insertions(+), 25 deletions(-) diff --git a/packages/react/shared.tsx b/packages/react/shared.tsx index 494c302..9eeaf70 100644 --- a/packages/react/shared.tsx +++ b/packages/react/shared.tsx @@ -78,8 +78,8 @@ type VariantKV = { * } * ``` */ -type PresetType = { - [PresetName in N]: Partial> & { className?: string }; +type PresetType = { + [PresetName: string]: Partial> & { className?: string }; }; /** @@ -89,24 +89,15 @@ type PresetType = { * @returns function (variantProps) -> class name, * @returns function (anyProps) -> [variantProps, otherProps] */ -export function vcn< - V extends VariantType, - N extends string /* Preset names */, ->({ - base, - variants, - defaults, - presets, -}: { +export function vcn(param: { base?: string | undefined; - variants: V /* VariantType */; + variants: V; defaults: VariantKV; - presets?: PresetType; + presets?: undefined; }): [ ( variantProps: Partial> & { className?: string; - preset?: N; } ) => string, >( @@ -114,14 +105,49 @@ export function vcn< ) => [ Partial> & { className?: string; - preset?: N; + }, + Omit> | "className">, + ], +]; +export function vcn>(param: { + base?: string | undefined; + variants: V /* VariantType */; + defaults: VariantKV; + presets: P; +}): [ + ( + variantProps: Partial> & { + className?: string; + preset?: keyof P; + } + ) => string, + >( + anyProps: AnyPropBeforeResolve + ) => [ + Partial> & { + className?: string; + preset?: keyof P; }, Omit< AnyPropBeforeResolve, keyof Partial> | "preset" | "className" >, ], -] { +]; +export function vcn< + V extends VariantType, + P extends PresetType | undefined, +>({ + base, + variants, + defaults, + presets, +}: { + base?: string | undefined; + variants: V; + defaults: VariantKV; + presets?: P; +}) { return [ /** * Takes any props (including className), and returns the class name. @@ -130,9 +156,13 @@ export function vcn< * @param variantProps - The variant props including className. * @returns The class name. */ - ({ className, preset, ...variantProps }) => { - const currentPreset: PresetType[N] | null = - presets && preset ? presets[preset] ?? null : null; + ({ + className, + preset, + ...variantProps + }: { className?: string; preset?: keyof P } & Partial>) => { + const currentPreset: P[keyof P] | null = + presets && preset ? (presets as NonNullable

)[preset] ?? null : null; const presetVariantKeys: (keyof V)[] = Object.keys(currentPreset ?? {}); return twMerge( base, @@ -142,13 +172,13 @@ export function vcn< ([variantKey, defaultValue]) => variants[variantKey][ (variantProps as unknown as Partial>)[variantKey] ?? - (currentPreset !== null && - presetVariantKeys.includes(variantKey) - ? currentPreset[variantKey] ?? defaultValue + (!!currentPreset && presetVariantKeys.includes(variantKey) + ? (currentPreset as Partial>)[variantKey] ?? + defaultValue : defaultValue) ] ), - currentPreset?.className, // preset's classname comes after user's variant props? huh.. + (currentPreset as Partial> | null)?.className, // preset's classname comes after user's variant props? huh.. className ); }, @@ -160,7 +190,9 @@ export function vcn< * @param anyProps - Any props that have passed to the component. * @returns [variantProps, otherProps] */ - (anyProps) => { + >( + anyProps: AnyPropBeforeResolve + ) => { const variantKeys = Object.keys(variants) as (keyof V)[]; return Object.entries(anyProps).reduce( @@ -178,7 +210,7 @@ export function vcn< ) as [ Partial> & { className?: string; - preset?: N; + preset?: keyof P; }, Omit< typeof anyProps,