UNPKG

@reddigital/quickstart

Version:
116 lines (114 loc) 3.22 kB
// src/web_component/utils.ts var resetInputs = ({ element }) => { return new Promise((resolve) => { if (window.performance?.navigation?.type === performance.navigation.TYPE_RELOAD || window.performance?.navigation?.type === performance.navigation.TYPE_BACK_FORWARD) { element.querySelectorAll("input").forEach((el) => { switch (el.type) { case "checkbox": case "radio": el.checked = el.defaultChecked; break; case "file": el.value = ""; break; default: el.value = el.defaultValue; } }); element.querySelectorAll("textarea").forEach((el) => { el.value = el.defaultValue; }); element.querySelectorAll("select").forEach((select) => { if (select.multiple) { Array.from(select.options).forEach((opt) => { opt.selected = opt.defaultSelected; }); } else { const defaultIndex = Array.from(select.options).findIndex((opt) => opt.defaultSelected); select.selectedIndex = defaultIndex > -1 ? defaultIndex : -1; } }); } resolve(); }); }; var visible = ({ element }) => { return new Promise((resolve) => { const observer = new IntersectionObserver((entries) => { for (const entry of entries) { if (entry.isIntersecting) { observer.disconnect(); resolve(true); } } }); observer.observe(element); }); }; var media = ({ query, onMatch, onUnmatch }) => { const handleChange = (event) => { if (event.matches) { onMatch?.(); } else { onUnmatch?.(); } }; const mediaQuery = window.matchMedia(query); if (mediaQuery.matches) { onMatch?.(); } else { onUnmatch?.(); } mediaQuery.addEventListener("change", handleChange); return () => { mediaQuery.removeEventListener("change", handleChange); }; }; var safeJsonParse = (json) => { try { return JSON.parse(json); } catch (error) { console.warn("Invalid JSON in data-props attribute:", error); return {}; } }; // src/web_component/init.ts function init({ resolve, hydrate }) { class Quickstart extends HTMLElement { cleanupMediaListener; async connectedCallback() { await resetInputs({ element: this }); if (this.hasAttribute("client:lazy")) { await visible({ element: this }); } if (this.hasAttribute("client:media")) { const query = this.getAttribute("client:media") ?? ""; this.cleanupMediaListener = media({ query, onMatch: async () => await this.hydrate(), onUnmatch: () => this.innerHTML = "" }); } else { await this.hydrate(); } } disconnectedCallback() { this.cleanupMediaListener?.(); } async hydrate() { const src = this.getAttribute("src") ?? ""; const propsData = this.getAttribute("data-props"); const props = propsData ? safeJsonParse(propsData) : {}; const Component = await resolve(src); hydrate(Component, { target: this, props }); } } customElements.define("quick-start", Quickstart); } export { init };