Files
defgov/packages/ui-web-headless/utils/mergeProps.ts
2026-05-11 05:30:03 +08:00

104 lines
2.4 KiB
TypeScript

function innerClassMergeFn(...classes: string[]): string {
return classes
.map((str) => str.trim())
.filter(Boolean)
.join(" ")
.trim();
}
// 重载1
export function mergeProps(
...propsN: Record<string, any>[]
): Record<string, any>;
// 重载2
export function mergeProps(
options: { classMergeFn: Function },
...propsN: Record<string, any>[]
): Record<string, any>;
// 实现
export function mergeProps(
arg1: { classMergeFn: Function } | Record<string, any>,
...rest: Record<string, any>[]
) {
let options: { classMergeFn: Function } = {
classMergeFn: innerClassMergeFn,
};
let propsN: Record<string, any>[];
if (
arg1 &&
typeof arg1 === "object" &&
!Array.isArray(arg1) &&
"classMergeFn" in arg1 &&
typeof (arg1 as any).classMergeFn === "function"
) {
options = arg1 as { classMergeFn: Function };
propsN = rest;
} else {
propsN = [arg1 as Record<string, any>, ...rest];
}
// --------------------------------
const result: any = {};
const eventHandlerMap = new Map<string, Function[]>();
const refs: any[] = [];
propsN.forEach((props) => {
if (!props) return;
if (props.className) {
result.className = options.classMergeFn(
result.className || "",
props.className,
);
}
if (props.style) {
result.style = { ...(result.style || {}), ...props.style };
}
if (props.ref) {
refs.push(props.ref);
}
Object.keys(props).forEach((key) => {
if (key.startsWith("on") && typeof props[key] === "function") {
if (!eventHandlerMap.has(key)) {
eventHandlerMap.set(key, []);
}
eventHandlerMap.get(key)!.push(props[key]);
} else if (key !== "ref" && key !== "className" && key !== "style") {
// 其他普通属性,后面的覆盖前面的
result[key] = props[key];
}
});
});
// 合并 Refs
if (refs.length > 0) {
if (refs.length === 1) {
result.ref = refs[0];
} else {
result.ref = (node: any) => {
refs.forEach((ref) => {
if (typeof ref === "function") {
ref(node);
} else if (ref) {
ref.current = node;
}
});
};
}
}
// 合并事件处理器
eventHandlerMap.forEach((handlers, key) => {
result[key] = (...args: any[]) => {
handlers.forEach((handler) => handler(...args));
};
});
return result;
}