UNPKG

preact

Version:

Fast 3kb React-compatible Virtual DOM library.

103 lines (92 loc) 3.03 kB
import options from './options'; /** * Create an virtual node (used for JSX) * @param {import('./internal').VNode["type"]} type The node name or Component * constructor for this virtual node * @param {object | null | undefined} [props] The properties of the virtual node * @param {Array<import('.').ComponentChildren>} [children] The children of the virtual node * @returns {import('./internal').VNode} */ export function createElement(type, props, children) { let normalizedProps = {}, i; for (i in props) { if (i !== 'key' && i !== 'ref') normalizedProps[i] = props[i]; } if (arguments.length > 3) { children = [children]; // https://github.com/preactjs/preact/issues/1916 for (i = 3; i < arguments.length; i++) { children.push(arguments[i]); } } if (children != null) { normalizedProps.children = children; } // If a Component VNode, check for and apply defaultProps // Note: type may be undefined in development, must never error here. if (typeof type == 'function' && type.defaultProps != null) { for (i in type.defaultProps) { if (normalizedProps[i] === undefined) { normalizedProps[i] = type.defaultProps[i]; } } } return createVNode( type, normalizedProps, props && props.key, props && props.ref, null ); } /** * Create a VNode (used internally by Preact) * @param {import('./internal').VNode["type"]} type The node name or Component * Constructor for this virtual node * @param {object | string | number | null} props The properties of this virtual node. * If this virtual node represents a text node, this is the text of the node (string or number). * @param {string | number | null} key The key for this virtual node, used when * diffing it against its children * @param {import('./internal').VNode["ref"]} ref The ref property that will * receive a reference to its created child * @returns {import('./internal').VNode} */ export function createVNode(type, props, key, ref, original) { // V8 seems to be better at detecting type shapes if the object is allocated from the same call site // Do not inline into createElement and coerceToVNode! const vnode = { type, props, key, ref, _children: null, _parent: null, _depth: 0, _dom: null, // _nextDom must be initialized to undefined b/c it will eventually // be set to dom.nextSibling which can return `null` and it is important // to be able to distinguish between an uninitialized _nextDom and // a _nextDom that has been set to `null` _nextDom: undefined, _component: null, constructor: undefined, _original: original }; if (original == null) vnode._original = vnode; if (options.vnode) options.vnode(vnode); return vnode; } export function createRef() { return {}; } export function Fragment(props) { return props.children; } /** * Check if a the argument is a valid Preact VNode. * @param {*} vnode * @returns {vnode is import('./internal').VNode} */ export const isValidElement = vnode => vnode != null && vnode.constructor === undefined;