Skip to content

Commit a8deb43

Browse files
committed
feat: add util mergeProps
1 parent 24afddb commit a8deb43

File tree

2 files changed

+52
-0
lines changed

2 files changed

+52
-0
lines changed
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import type { ReactElement } from 'react';
2+
import { cloneElement } from 'react';
3+
4+
import type { ClassValue } from '@/types/other';
5+
6+
import { cn } from './utils';
7+
8+
export type AnyProps = Record<string, any>;
9+
10+
export function mergeProps(slotProps: AnyProps, childProps: AnyProps) {
11+
// all child props should override
12+
const overrideProps = { ...childProps };
13+
14+
// eslint-disable-next-line guard-for-in
15+
for (const propName in childProps) {
16+
const slotPropValue = slotProps[propName];
17+
const childPropValue = childProps[propName];
18+
19+
const isHandler = /^on[A-Z]/.test(propName);
20+
if (isHandler) {
21+
// if the handler exists on both, we compose them
22+
if (slotPropValue && childPropValue) {
23+
overrideProps[propName] = (...args: unknown[]) => {
24+
const result = childPropValue(...args);
25+
slotPropValue(...args);
26+
return result;
27+
};
28+
}
29+
// but if it exists only on the slot, we use only this one
30+
else if (slotPropValue) {
31+
overrideProps[propName] = slotPropValue;
32+
}
33+
}
34+
// if it's `style`, we merge them
35+
else if (propName === 'style') {
36+
overrideProps[propName] = { ...slotPropValue, ...childPropValue };
37+
} else if (propName === 'className') {
38+
overrideProps[propName] = [slotPropValue, childPropValue].filter(Boolean).join(' ');
39+
}
40+
}
41+
42+
return { ...slotProps, ...overrideProps };
43+
}
44+
45+
export function withClassName(element: ReactElement<any>, ...className: ClassValue[]) {
46+
return cloneElement(element, {
47+
...element.props,
48+
className: cn(className, element.props.className)
49+
});
50+
}

packages/ui/src/lib/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
export * from './compose-props';
2+
13
export * from './typed';
24

35
export * from './utils';

0 commit comments

Comments
 (0)