2026-03-31 23:03:52 +07:00

70 lines
2.3 KiB
TypeScript

/**
* Creates an element with optional attributes and children.
* Avoids innerHTML to satisfy SEC-12.
*/
export function h(
tag: string,
attrs?: Record<string, string>,
...children: Array<HTMLElement | string>
): HTMLElement {
const el = document.createElement(tag);
if (attrs) {
for (const [key, val] of Object.entries(attrs)) {
el.setAttribute(key, val);
}
}
for (const child of children) {
if (typeof child === "string") {
el.appendChild(document.createTextNode(child));
} else {
el.appendChild(child);
}
}
return el;
}
/** Clears the body and appends an element, returning it typed as T. */
export function mount<T extends HTMLElement>(el: T): T {
document.body.textContent = "";
document.body.appendChild(el);
return el;
}
/** Creates and mounts a petty-collapsible with a details/summary structure. */
export function createCollapsible(): HTMLElement {
const el = document.createElement("petty-collapsible");
const d = document.createElement("details");
d.appendChild(h("summary", {}, "Toggle"));
d.appendChild(h("div", { "data-part": "content" }, "Content"));
el.appendChild(d);
return mount(el);
}
/** Creates and mounts a petty-alert with text content. */
export function createAlert(text = "msg"): HTMLElement {
const el = document.createElement("petty-alert");
el.appendChild(document.createTextNode(text));
return mount(el);
}
/** Creates and mounts a petty-progress with fill and label parts. */
export function createProgress(): HTMLElement {
const el = document.createElement("petty-progress");
el.appendChild(h("div", { "data-part": "fill" }));
el.appendChild(h("span", { "data-part": "label" }));
return mount(el);
}
/** Creates and mounts a petty-pagination with prev/next and numbered items. */
export function createPagination(total = "50", pageSize = "10"): HTMLElement {
const el = document.createElement("petty-pagination");
el.setAttribute("total", total);
el.setAttribute("page-size", pageSize);
el.appendChild(h("petty-pagination-item", { type: "prev" }, "Prev"));
el.appendChild(h("petty-pagination-item", { value: "1" }, "1"));
el.appendChild(h("petty-pagination-item", { value: "2" }, "2"));
el.appendChild(h("petty-pagination-item", { value: "3" }, "3"));
el.appendChild(h("petty-pagination-item", { type: "next" }, "Next"));
return mount(el);
}