/
index.ts
65 lines (63 loc) · 2.08 KB
/
index.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
const convertToTextNodeIfStr = (node: string | object): any =>
typeof node === 'string' ? document.createTextNode(node) : node;
const createElement = function(
tag: string,
props: object,
...children: Array<any>
): HTMLElement | Array<any> {
const ele: HTMLElement = document.createElement(tag);
if (!tag) {
return children;
}
if (props) {
Object.entries(props).forEach(function([propKey, propValue]: Array<any>) {
propKey = propKey.toLowerCase();
if ('ref' === propKey) {
if ('function' !== typeof propValue) {
throw new TypeError('value of property \'ref\' must be a function');
}
propValue.call(undefined, ele);
return;
}
if ('classname' === propKey) {
propKey = 'class';
}
if ('class' === propKey) {
propValue.split(' ').forEach((cls: string) => ele.classList.add(cls));
} else if ('style' === propKey) {
if (typeof propValue !== 'object') {
throw new TypeError('style attribute should be an object');
}
Object.keys(propValue).forEach((k: any) => (ele.style[k] = propValue[k]));
} else if ('dangerouslysetinnerhtml' === propKey) {
let htmlStr: string;
if(typeof propValue === 'function') {
htmlStr = propValue.call();
} else {
htmlStr = propValue;
}
ele.innerHTML = htmlStr;
} else if (propKey in ele) {
if (propKey.slice(0, 2) === 'on') {
ele.addEventListener(propKey.slice(2), propValue);
return;
}
ele.setAttribute(propKey, propValue);
} else if ('data-' === propKey.slice(0, 5)) {
ele.setAttribute(propKey, propValue);
}
});
}
if (children) {
if (children.length === 1 && Array.isArray(children[0])) {
children.pop().forEach(function(child: string | object) {
children.push(convertToTextNodeIfStr(child));
});
}
children.forEach(function(child: string | object) {
ele.appendChild(convertToTextNodeIfStr(child));
});
}
return ele;
};
export default { createElement };