diff options
author | metamuffin <metamuffin@disroot.org> | 2023-10-01 11:27:59 +0200 |
---|---|---|
committer | metamuffin <metamuffin@disroot.org> | 2023-10-01 11:27:59 +0200 |
commit | 4c6a395de093dce24c688276a8b04a93093fd118 (patch) | |
tree | f5b345a4e0b8650577ce0734ee1b26d8c0433b1c /src/element.ts | |
download | jshelper-4c6a395de093dce24c688276a8b04a93093fd118.tar jshelper-4c6a395de093dce24c688276a8b04a93093fd118.tar.bz2 jshelper-4c6a395de093dce24c688276a8b04a93093fd118.tar.zst |
init
Diffstat (limited to 'src/element.ts')
-rw-r--r-- | src/element.ts | 60 |
1 files changed, 60 insertions, 0 deletions
diff --git a/src/element.ts b/src/element.ts new file mode 100644 index 0000000..9880748 --- /dev/null +++ b/src/element.ts @@ -0,0 +1,60 @@ +/* + This file is part of jshelper (https://codeberg.org/metamuffin/jshelper) + which is licensed under the GNU Affero General Public License (version 3); see /COPYING. + Copyright (C) 2023 metamuffin <metamuffin.org> +*/ +import { OVar } from "./observable.ts"; + +interface Opts<E> { + class?: string[] | string, + id?: string, + src?: string, + for?: string, + type?: string, + href?: string, + onclick?: (e: E) => void, + onchange?: (e: E) => void, +} + +function apply_opts<E extends HTMLElement>(e: E, o: Opts<E>): (() => unknown) | void { + if (o.id) e.id = o.id + if (o.for) (e as unknown as HTMLLabelElement).htmlFor = o.for + if (o.type && e instanceof HTMLInputElement) e.type = o.type + if (o.href && e instanceof HTMLAnchorElement) e.href = o.href; + if (o.onclick) e.addEventListener("click", () => o.onclick!(e)) + if (o.onchange) e.addEventListener("change", () => o.onchange!(e)) + if (typeof o?.class == "string") e.classList.add(o.class) + if (typeof o?.class == "object") e.classList.add(...o.class) +} + +type EEl<K extends keyof HTMLElementTagNameMap> = string | HTMLElement | Opts<HTMLElementTagNameMap[K]> | OVar<Opts<HTMLElementTagNameMap[K]>> | OVar<string> | OVar<HTMLElement> | OVar<HTMLUListElement> | undefined; + +export function e<K extends keyof HTMLElementTagNameMap>(name: K, ...children: EEl<K>[]): HTMLElementTagNameMap[K] { + const el = document.createElement(name) + for (const c of children) e_apply(el, c) + return el +} + +function e_apply<K extends keyof HTMLElementTagNameMap, C extends EEl<K>>(el: HTMLElementTagNameMap[K], c: C): () => unknown { + if (typeof c == "undefined") { + return () => { } + } + if (typeof c == "string") { + el.append(c) + return () => { + el.textContent = "" + } + } + else if (c instanceof HTMLElement) { + el.append(c) + return () => el.removeChild(c) + } + else if (c instanceof OVar) { + let undo_last: () => unknown; + return c.onchangeinit(val => { + if (undo_last) undo_last() + undo_last = e_apply(el, val) + }) + } + else return apply_opts(el, c) ?? (() => { }) +} |