/** * Creates an element with optional attributes and children. * Avoids innerHTML to satisfy SEC-12. */ export function h( tag: string, attrs?: Record, ...children: Array ): 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(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); }