inferno-clone-vnode
Version:
provides helper function to clone Inferno's vNodes
66 lines (63 loc) • 2.12 kB
JavaScript
import { createComponentVNode, EMPTY_OBJ, createTextVNode, createFragment, normalizeProps, createVNode } from 'inferno';
/*
directClone is preferred over cloneVNode and used internally also.
This function makes Inferno backwards compatible.
And can be tree-shaked by modern bundlers
*/
/**
* Clones given virtual node by creating new instance of it
* @param {VNode} vNodeToClone virtual node to be cloned
* @param {Props=} props additional props for new virtual node
* @param {...*} childArgs new children for new virtual node
* @returns {VNode} new virtual node
*/
function cloneVNode(vNodeToClone, props, ...childArgs) {
const flags = vNodeToClone.flags;
let children = flags & 14 /* VNodeFlags.Component */ ? vNodeToClone.props?.children : vNodeToClone.children;
const childLen = childArgs.length;
let className = vNodeToClone.className;
let key = vNodeToClone.key;
let ref = vNodeToClone.ref;
if (props) {
if (props.className !== void 0) {
className = props.className;
}
if (props.ref !== void 0) {
ref = props.ref;
}
if (props.key !== void 0) {
key = props.key;
}
if (props.children !== void 0) {
children = props.children;
}
} else {
props = {};
}
if (childLen === 1) {
children = childArgs[0];
} else if (childLen > 1) {
children = [];
for (let i = 0; i < childLen; i++) {
children.push(childArgs[i]);
}
}
props.children = children;
if (flags & 14 /* VNodeFlags.Component */) {
return createComponentVNode(flags, vNodeToClone.type, !vNodeToClone.props && !props ? EMPTY_OBJ : {
...vNodeToClone.props,
...props
}, key, ref);
}
if (flags & 16 /* VNodeFlags.Text */) {
return createTextVNode(children);
}
if (flags & 8192 /* VNodeFlags.Fragment */) {
return createFragment(childLen === 1 ? [children] : children, 0 /* ChildFlags.UnknownChildren */, key);
}
return normalizeProps(createVNode(flags, vNodeToClone.type, className, null, 1 /* ChildFlags.HasInvalidChildren */, {
...vNodeToClone.props,
...props
}, key, ref));
}
export { cloneVNode };