Files
v10/dist/dev/utils/merge-props.js

84 lines
2.2 KiB
JavaScript

"use client";
//#region src/utils/merge-props.ts
/**
* Check if a key is an event handler key (on* with capital letter).
*/
function isEventHandlerKey(key) {
return key.charCodeAt(0) === 111 && key.charCodeAt(1) === 110 && key.charCodeAt(2) >= 65 && key.charCodeAt(2) <= 90;
}
/**
* Check if a key/value pair is an event handler (includes undefined values).
*/
function isEventHandler(key, value) {
return isEventHandlerKey(key) && (typeof value === "function" || typeof value === "undefined");
}
/**
* Merge two event handlers - external runs first, ours runs second.
*/
function mergeEventHandlers(ours, theirs) {
if (!theirs) return ours;
if (!ours) return theirs;
return (event) => {
theirs(event);
ours(event);
};
}
/**
* Merge two className values - concatenate strings.
*/
function mergeClassNames(ours, theirs) {
if (theirs && ours) return `${theirs} ${ours}`;
return theirs || ours;
}
/**
* Merge two style objects - theirs overwrites conflicts.
*/
function mergeStyles(ours, theirs) {
if (!theirs) return ours;
if (!ours) return theirs;
return {
...ours,
...theirs
};
}
/**
* Merge a single props object into accumulated result.
*/
function mergeOne(merged, props) {
if (!props) return merged;
for (const key in props) {
const value = props[key];
if (key === "className") merged.className = mergeClassNames(merged.className, value);
else if (key === "style") merged.style = mergeStyles(merged.style, value);
else if (isEventHandler(key, value)) merged[key] = mergeEventHandlers(merged[key], value);
else merged[key] = value;
}
return merged;
}
/**
* Merge multiple props objects.
*
* - Event handlers (on*): chained - external first, ours second
* - className: concatenated
* - style: merged objects (external wins conflicts)
* - other: last one wins
*
* @public
* @example
* ```ts
* const merged = mergeProps(
* { onClick: ourHandler, className: 'base' },
* { onClick: theirHandler, className: 'custom' }
* );
* // { onClick: chainedHandler, className: 'custom base' }
* ```
*/
function mergeProps(...propSets) {
let merged = {};
for (const props of propSets) merged = mergeOne(merged, props);
return merged;
}
//#endregion
export { mergeProps };
//# sourceMappingURL=merge-props.js.map