aboutsummaryrefslogtreecommitdiff
path: root/src/element.ts
diff options
context:
space:
mode:
authormetamuffin <metamuffin@disroot.org>2023-10-01 11:27:59 +0200
committermetamuffin <metamuffin@disroot.org>2023-10-01 11:27:59 +0200
commit4c6a395de093dce24c688276a8b04a93093fd118 (patch)
treef5b345a4e0b8650577ce0734ee1b26d8c0433b1c /src/element.ts
downloadjshelper-4c6a395de093dce24c688276a8b04a93093fd118.tar
jshelper-4c6a395de093dce24c688276a8b04a93093fd118.tar.bz2
jshelper-4c6a395de093dce24c688276a8b04a93093fd118.tar.zst
init
Diffstat (limited to 'src/element.ts')
-rw-r--r--src/element.ts60
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) ?? (() => { })
+}