UNPKG

vue-web-component-wrapper

Version:

A Vue 3 plugin that provides a web component wrapper with styles, seamlessly integrating with Vuex, Vue Router, Vue I18n, and supporting Tailwind CSS and Sass styles.

374 lines (373 loc) 12.3 kB
var F = Object.defineProperty; var G = (e, n, t) => n in e ? F(e, n, { enumerable: !0, configurable: !0, writable: !0, value: t }) : e[n] = t; var m = (e, n, t) => G(e, typeof n != "symbol" ? n + "" : n, t); import { defineComponent as W, nextTick as X, render as D, createVNode as I, h as R } from "vue"; /** * @vue/shared v3.5.13 * (c) 2018-present Yuxi (Evan) You and Vue contributors * @license MIT **/ process.env.NODE_ENV !== "production" && Object.freeze({}); process.env.NODE_ENV !== "production" && Object.freeze([]); const Z = Object.assign, $ = Array.isArray, J = (e) => typeof e == "string", B = (e) => { const n = /* @__PURE__ */ Object.create(null); return (t) => n[t] || (n[t] = e(t)); }, Q = /-(\w)/g, S = B( (e) => e.replace(Q, (n, t) => t ? t.toUpperCase() : "") ), Y = /\B([A-Z])/g, N = B( (e) => e.replace(Y, "-$1").toLowerCase() ), C = (e) => { const n = J(e) ? Number(e) : NaN; return isNaN(n) ? e : n; }; /*!#__NO_SIDE_EFFECTS__*/ // @__NO_SIDE_EFFECTS__ function ee(e, n, t) { const s = W(e); class o extends T { constructor(i) { super(s, i, n, t); } } return m(o, "def", s), o; } const te = typeof HTMLElement < "u" ? HTMLElement : class { }; class T extends te { constructor(t, s = {}, o = { shadowRoot: !0 }, r) { super(); /** * @internal */ m(this, "_instance", null); m(this, "_connected", !1); m(this, "_resolved", !1); m(this, "_numberProps", null); m(this, "_styles"); m(this, "_slots", {}); m(this, "_ob", null); this._def = t, this._props = s, this._config = o, this._root && r ? r(this._createVNode(), this._root) : (this._config.shadowRoot !== !1 && this.attachShadow({ mode: "open" }), this._def.__asyncLoader || this._resolveProps(this._def)); } get _root() { return this._config.shadowRoot ? this.shadowRoot : this; } connectedCallback() { this._connected = !0, this._instance || (this._resolved ? this._update() : this._resolveDef()); } disconnectedCallback() { this._connected = !1, X(() => { this._connected || (this._ob && (this._ob.disconnect(), this._ob = null), D(null, this._root), this._instance = null); }); } /** * resolve inner component definition (handle possible async component) */ _resolveDef() { this._resolved = !0; for (let o = 0; o < this.attributes.length; o++) this._setAttr(this.attributes[o].name); this._ob = new MutationObserver((o) => { for (const r of o) this._setAttr(r.attributeName); }), this._ob.observe(this, { attributes: !0 }); const t = (o, r = !1) => { var y; const { props: i } = o, _ = this._collectNestedStyles(o); let E; if (i && !$(i)) for (const d in i) { const c = i[d]; (c === Number || c && c.type === Number) && (d in this._props && (this._props[d] = C(this._props[d])), (E || (E = /* @__PURE__ */ Object.create(null)))[S(d)] = !0); } if (this._numberProps = E, r && this._resolveProps(o), !this._config.shadowRoot) { this._slots = {}; const d = (c) => Array.from(c).map((l) => { var h; if (l.nodeType === Node.ELEMENT_NODE) { const u = l, b = Object.fromEntries( Array.from(u.attributes).map((O) => [O.name, O.value]) ); return R( u.tagName.toLowerCase(), b, d(u.childNodes) ); } else if (l.nodeType === Node.TEXT_NODE) return ((h = l.textContent) == null ? void 0 : h.trim()) || null; return null; }).filter((l) => l != null); for (const c of Array.from(this.childNodes)) { const l = c.nodeType === Node.ELEMENT_NODE && c.getAttribute("slot") || "default"; if (this._slots[l] || (this._slots[l] = []), c.nodeType === Node.ELEMENT_NODE) { const h = c, u = Object.fromEntries( Array.from(h.attributes).map((b) => [b.name, b.value]) ); this._slots[l].push( R( h.tagName.toLowerCase(), u, d(h.childNodes) ) ); } else if (c.nodeType === Node.TEXT_NODE) { const h = (y = c.textContent) == null ? void 0 : y.trim(); h && this._slots[l].push(h); } } this.replaceChildren(); } this._applyStyles(_), this._update(); }, s = this._def.__asyncLoader; s ? s().then((o) => t(o, !0)) : t(this._def); } _resolveProps(t) { const { props: s } = t, o = $(s) ? s : Object.keys(s || {}); for (const r of Object.keys(this)) r[0] !== "_" && o.includes(r) && this._setProp(r, this[r], !0, !1); for (const r of o.map(S)) Object.defineProperty(this, r, { get() { return this._getProp(r); }, set(i) { this._setProp(r, i); } }); } _setAttr(t) { let s = this.hasAttribute(t) ? this.getAttribute(t) : void 0; const o = S(t); this._numberProps && this._numberProps[o] && (s = C(s)), this._setProp(o, s, !1); } /** * @internal */ _getProp(t) { return this._props[t]; } /** * @internal */ _setProp(t, s, o = !0, r = !0) { s !== this._props[t] && (this._props[t] = s, r && this._instance && this._update(), o && (s === !0 ? this.setAttribute(N(t), "") : typeof s == "string" || typeof s == "number" ? this.setAttribute(N(t), s + "") : s || this.removeAttribute(N(t)))); } _update() { D(this._createVNode(), this._root); } _createVNode() { const t = I(this._def, Z({}, this._props), this._slots); return this._instance || (t.ce = (s) => { this._instance = s, s.isCE = !0; const o = (i, _) => { this.dispatchEvent( new CustomEvent(i, { detail: _ }) ); }; s.emit = (i, ..._) => { o(i, _), N(i) !== i && o(N(i), _); }; let r = this; for (; r = r && (r.parentNode || r.host); ) if (r instanceof T) { s.parent = r._instance, s.provides = r._instance.provides; break; } }), t; } _applyStyles(t) { t && t.forEach((s) => { const o = document.createElement("style"); o.textContent = s, this._config.nonce && o.setAttribute("nonce", this._config.nonce), this._root.prepend(o); }); } _collectNestedStyles(t) { let s = t.styles ?? []; return t.components && Object.values(t.components).forEach((o) => { s = s.concat(this._collectNestedStyles(o)); }), s; } } const H = (e) => { for (; (e == null ? void 0 : e.nodeType) !== 1; ) { if (!e.parentElement) throw new Error( "No parent element found, the rootComponent must be wrapped in a HTML element (e.g. <template><div> app content </div></template>)" ); e = e.parentElement; } return e; }; function se(e) { return "on" + e.charAt(0).toUpperCase() + e.slice(1); } function oe(e) { return typeof e == "string" ? e.replace(/:root/g, ":host") : Array.isArray(e) ? e.map((n) => n.replace(/:root/g, ":host")) : e; } const re = ({ rootComponent: e, plugins: n, cssFrameworkStyles: t, VueDefineCustomElement: s, h: o, createApp: r, getCurrentInstance: i, elementName: _, disableRemoveStylesOnUnmount: E, disableShadowDOM: y, replaceRootWithHostInCssFramework: d, asyncInitialization: c, loaderAttribute: l, hideSlotContentUntilMounted: h, nonce: u }) => { const b = y ? ee : s, O = d ? oe(t) : t, M = b({ styles: [O], nonce: u, props: { ...e.props, modelValue: { type: [String, Number, Boolean, Array, Object] } // v-model support }, emits: e == null ? void 0 : e.emits, setup(K, { slots: U }) { var L; const P = [...(e == null ? void 0 : e.emits) || [], "update:modelValue"], f = r(); if (f.component("app-root", e), e.provide) { const a = typeof e.provide == "function" ? e.provide() : e.provide; Object.keys(a).forEach((p) => { f.provide(p, a[p]); }); } f.mixin({ mounted() { var g, A, j, V; if (((A = (g = this.$) == null ? void 0 : g.type) == null ? void 0 : A.name) === "vue-custom-element-root-component") return; const a = (v) => { v != null && v.length && (this.__style = document.createElement("style"), this.__style.innerText = v.join().replace(/\n/g, ""), u && this.__style.setAttribute("nonce", u), H(this.$el).append(this.__style)); }; if (a((j = this.$) == null ? void 0 : j.type.styles), this.$options.components) for (const v of Object.values(this.$options.components)) a(v.styles); const p = ((V = this.$el.getRootNode()) == null ? void 0 : V.host) || H(this.$el); p && (h && p.querySelectorAll("[hidden]").forEach((q) => { q.removeAttribute("hidden"); }), p.querySelectorAll(`[${l}]`).forEach((x) => { x.remove(); })); }, unmounted() { var a; E || (a = this.__style) == null || a.remove(); } }), f.use(n); const w = i(); if (Object.assign(w.appContext, f._context), Object.assign(w.provides, f._context.provides), process.env.NODE_ENV === "development" && window.__VUE_DEVTOOLS_GLOBAL_HOOK__) { const a = document.querySelector(_); f._container = a, f._instance = w; const p = { Comment: Symbol("v-cmt"), Fragment: Symbol("v-fgt"), Static: Symbol("v-stc"), Text: Symbol("v-txt") }; window.__VUE_DEVTOOLS_GLOBAL_HOOK__.emit("app:init", f, f.version, p), window.__VUE_DEVTOOLS_GLOBAL_HOOK__.Vue = f; } const z = P == null ? void 0 : P.reduce((a, p) => { const g = se(p); return a[g] = (A) => { w.emit(p, A); }, a; }, {}), k = (L = e == null ? void 0 : e.namedSlots) == null ? void 0 : L.reduce((a, p) => (a[p] = () => o("slot", { name: p }), a), {}); return () => o( e, { ...K, ...z }, { default: () => o("slot"), ...k, ...U } ); } }, { shadowRoot: !y, nonce: u }); return c().then(() => M); }, ce = ({ elementName: e, rootComponent: n, plugins: t, cssFrameworkStyles: s, VueDefineCustomElement: o, h: r, createApp: i, getCurrentInstance: _, disableRemoveStylesOnUnmount: E = !1, disableShadowDOM: y = !1, replaceRootWithHostInCssFramework: d = !1, asyncInitialization: c = () => Promise.resolve(), loaderAttribute: l = "data-web-component-loader", hideSlotContentUntilMounted: h = !1, nonce: u // Used for Content Security Policy (CSP) compliance - will be applied to inline styles }) => { if (!n) { console.warn("No root component provided. Please provide a root component to create a web component."); return; } if (!e) { console.warn("No element name provided. Please provide an element name to create a web component."); return; } if (!o) { console.warn( "No VueDefineCustomElement provided. Please provide a VueDefineCustomElement to create a web component." ); return; } if (!r) { console.warn("No h provided. Please provide an h to create a web component."); return; } if (!i) { console.warn("No createApp provided. Please provide a createApp to create a web component."); return; } if (!_) { console.warn("No getCurrentInstance provided. Please provide a getCurrentInstance to create a web component."); return; } re({ rootComponent: n, plugins: t, cssFrameworkStyles: s, VueDefineCustomElement: o, h: r, createApp: i, getCurrentInstance: _, elementName: e, disableRemoveStylesOnUnmount: E, disableShadowDOM: y, replaceRootWithHostInCssFramework: d, asyncInitialization: c, loaderAttribute: l, hideSlotContentUntilMounted: h, nonce: u }).then((b) => { customElements.define( e, b ); }); }; export { ce as createWebComponent, ce as default, re as defineCustomElement, ee as defineCustomElementSFC };