UNPKG

1.68 kBJavaScriptView Raw
1import { createVNode } from './vnode'
2/**
3 * @typedef {Object.<string, any>} Props
4 */
5/**
6 * @typedef {Object} VNode;
7 * @property {string | Function} VNode.type;
8 * @property {Props} VNode.props;
9 * @property {any[]} VNode.children;
10 * @property {string | number | null} VNode.key;
11 */
12/**
13 * Hyperscript function. Enables definition of HTML/SVG using functions.
14 * @param {string | Function} type A tag name or function.
15 * @param {Object} [props] An Object literal of key-value pairs.
16 * @param {any[]} children An array of strings or other arrays.
17 * @return {VNode} VNode An object literal of type, props and children.
18 *
19 * @example Virtual node with string as content:
20 * const title = h('h1', {class: 'main-title'}, 'This is the Titel!')
21 * @example Virtual node with children:
22 * const list = h(
23 * 'ul',
24 * {class: 'list'},
25 * [
26 * h('li', {}, 'One'),
27 * h('li', {}, 'Two'),
28 * h('li', {}, 'Three')
29 * ]
30 * )
31 */
32export function h(type, props, ...children) {
33 const nodes = []
34 const childNodes = []
35 let length = children.length
36 props = props || {}
37 let key = props.key || null
38
39 // Remove key from props if present:
40 delete props.key
41
42 while (length-- > 0) nodes.push(children[length])
43
44 while (nodes.length) {
45 const node = nodes.pop()
46 if (node && node.pop) {
47 for (length = node.length; length--; ) {
48 nodes.push(node[length])
49 }
50 } else if (node != null && node !== true && node !== false) {
51 childNodes.push(node)
52 }
53 }
54
55 children = childNodes
56
57 if (typeof type === 'function') {
58 return type(props || {}, childNodes)
59 } else {
60 return createVNode(type, props, children, key)
61 }
62}