mm
This commit is contained in:
103
packages/ui-web-headless/utils/mergeProps.ts
Normal file
103
packages/ui-web-headless/utils/mergeProps.ts
Normal file
@@ -0,0 +1,103 @@
|
||||
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;
|
||||
}
|
||||
Reference in New Issue
Block a user