1 | import { 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 | */
|
32 | export 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 | }
|