Skip to content

Commit 142bd61

Browse files
committed
refactor: a little micro-optimization
1 parent a19b8de commit 142bd61

File tree

2 files changed

+49
-17
lines changed

2 files changed

+49
-17
lines changed

src/index.ts

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -485,8 +485,12 @@ export function defineConfig(options?: VariantFactoryOptions) {
485485
C extends VariantsConfig<V>,
486486
V extends VariantsSchema = NonNullable<C['variants']>
487487
>(config: Exact<Simplify<C>, VariantsConfig<V>>): VariantsResolverFn<C, V> {
488-
const { base, variants: configVariants, compoundVariants, defaultVariants } =
489-
config;
488+
const {
489+
base,
490+
variants: configVariants,
491+
compoundVariants,
492+
defaultVariants,
493+
} = config;
490494

491495
if (!configVariants) {
492496
return (props?: { className?: ClassNameValue }) =>
@@ -522,7 +526,7 @@ export function defineConfig(options?: VariantFactoryOptions) {
522526

523527
for (const cv of compoundVariants ?? []) {
524528
const cvVariants = cv.variants;
525-
const matches = Object.keys(cvVariants).every((name) => {
529+
const matches = Object.keys(cvVariants).every(name => {
526530
const selected = getSelectedVariant(name);
527531
const cvSelector = cvVariants[name];
528532
return Array.isArray(cvSelector)
@@ -667,8 +671,9 @@ export function defineConfig(options?: VariantFactoryOptions) {
667671
const component = ((props: BaseProps) => {
668672
return createElement(elementType, resolveProps(props as any));
669673
}) as VariantComponentType<T, C, V>;
670-
(component as { displayName?: string }).displayName =
671-
`Variant(${getDisplayName()})`;
674+
(
675+
component as { displayName?: string }
676+
).displayName = `Variant(${getDisplayName()})`;
672677
return component;
673678
}
674679

@@ -694,8 +699,9 @@ export function defineConfig(options?: VariantFactoryOptions) {
694699
return createElement(elementType, { ...resolvedProps, ref: mergedRef });
695700
}) as VariantComponentType<T, C, V>;
696701

697-
(component as { displayName?: string }).displayName =
698-
`Variant(${getDisplayName()})`;
702+
(
703+
component as { displayName?: string }
704+
).displayName = `Variant(${getDisplayName()})`;
699705

700706
return component;
701707
}

src/utils.ts

Lines changed: 36 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,10 @@ export function mergeProps<T extends HTMLAttributes<any>>(
110110
base: T,
111111
overrides: T
112112
): T {
113+
if (!overrides || Object.keys(overrides).length === 0) {
114+
return base;
115+
}
116+
113117
const props = { ...base };
114118

115119
for (const key in overrides) {
@@ -156,22 +160,44 @@ export function mergeProps<T extends HTMLAttributes<any>>(
156160
return props;
157161
}
158162

163+
/**
164+
* Creates a merged ref callback from multiple refs.
165+
* Use this in event handlers or conditional branches where hooks cannot be used.
166+
*
167+
* @param refs - Array of refs to merge
168+
* @returns A callback ref that sets all provided refs, or undefined if no valid refs
169+
*
170+
* @example
171+
* const merged = mergeRefs(ref1, ref2);
172+
* // Use in cloneElement or other non-hook contexts
173+
*/
174+
export function mergeRefs<T = any>(
175+
...refs: Array<Ref<T> | undefined | null>
176+
): Ref<T> | undefined {
177+
const validRefs = refs.filter((ref): ref is Ref<T> => Boolean(ref));
178+
179+
if (validRefs.length === 0) return;
180+
if (validRefs.length === 1) return validRefs[0];
181+
182+
return (value: T | null) => {
183+
for (const ref of validRefs) {
184+
setRef(ref, value);
185+
}
186+
};
187+
}
188+
159189
/**
160190
* Merges React Refs into a single memoized function ref so you can pass it to
161-
* an element.
191+
* an element. This is a hook version that memoizes the merged ref.
192+
*
162193
* @example
163194
* const Component = forwardRef((props, ref) => {
164195
* const internalRef = useRef();
165196
* return <div {...props} ref={useMergeRefs(internalRef, ref)} />;
166197
* });
167198
*/
168-
export function useMergeRefs(...refs: Array<Ref<any> | undefined>) {
169-
return useMemo(() => {
170-
if (!refs.some(Boolean)) return;
171-
return (value: unknown) => {
172-
for (const ref of refs) {
173-
setRef(ref, value);
174-
}
175-
};
176-
}, refs);
199+
export function useMergeRefs<T = any>(
200+
...refs: Array<Ref<T> | undefined | null>
201+
): Ref<T> | undefined {
202+
return useMemo(() => mergeRefs(...refs), refs);
177203
}

0 commit comments

Comments
 (0)