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
|
interface Opts<E> {
class?: string[] | string,
id?: string,
src?: string,
rel?: string,
title?: string,
for?: string,
type?: string,
href?: string,
method?: string,
placeholder?: string,
onclick?: (e: Event) => void,
onchange?: (e: Event) => void,
}
function apply_opts<E extends HTMLElement>(e: E, o: Opts<E>) {
if (o.id) e.id = o.id
if (o.onclick) e.onclick = ev => o.onclick!(ev)
if (o.onchange) e.onchange = ev => o.onchange!(ev)
// TODO can we do this properly?
if (o.for) (e as unknown as HTMLLabelElement).htmlFor = o.for
if (o.type && (e instanceof HTMLInputElement || e instanceof HTMLLinkElement)) e.type = o.type
if (o.placeholder && (e instanceof HTMLInputElement)) e.placeholder = o.placeholder
if (o.href && (e instanceof HTMLAnchorElement || e instanceof HTMLLinkElement)) e.href = o.href
if (o.rel && (e instanceof HTMLAnchorElement || e instanceof HTMLLinkElement)) e.rel = o.rel
if (o.title && (e instanceof HTMLAnchorElement || e instanceof HTMLLinkElement)) e.title = o.title
if (o.method && (e instanceof HTMLFormElement)) e.method = o.method
if (typeof o?.class == "string") e.classList.add(o.class)
if (typeof o?.class == "object") e.classList.add(...o.class)
}
export function e<K extends keyof HTMLElementTagNameMap>(name: K, opts: Opts<HTMLElementTagNameMap[K]>, ...children: (HTMLElement | string)[]): HTMLElementTagNameMap[K] {
const el = document.createElement(name)
apply_opts(el, opts)
for (const c of children) {
if (typeof c == "string") el.textContent += c
else el.append(c)
}
return el
}
|