UNPKG

vue-tweet

Version:

Embed tweets just by giving the ID of a Tweet

182 lines (181 loc) 6.85 kB
import { defineComponent as B, ref as _, onMounted as O, onUnmounted as U, watch as $, toRef as x, nextTick as F, createElementBlock as N, openBlock as P, Fragment as V, renderSlot as E, createCommentVNode as W, createElementVNode as j, mergeProps as z } from "vue"; const D = /* @__PURE__ */ B({ __name: "vue-tweet", props: { tweetId: { type: String, default: "" }, tweetUrl: { type: String, default: "" }, conversation: { type: String, default: "all", validator: (i) => ["all", "none"].includes(i) }, cards: { type: String, default: "visible", validator: (i) => ["visible", "hidden"].includes(i) }, width: { type: [String, Number], default: "auto", validator: (i) => typeof i == "string" ? i === "auto" : typeof i == "number" ? i >= 250 && i <= 550 : !1 }, align: { type: [String, void 0], default: void 0, validator: (i) => ["left", "right", "center", void 0].includes(i) }, theme: { type: String, default: "system", validator: (i) => ["light", "dark", "system"].includes(i) }, lang: { type: String, default: "en" }, dnt: { type: Boolean, default: !1 } }, emits: ["tweet-load-success", "tweet-load-error"], setup(i, { emit: T }) { const u = i, m = T, w = _(!0), s = _(!1), f = _(), g = _("light"), o = _(!1), h = _(!0); function I() { return u.theme === "system" ? g.value : u.theme; } function S() { typeof window < "u" && window.matchMedia && (g.value = window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light"); } let p = null, r = null; const e = { loaded: !1, loading: !1, element: null }; function k() { if (typeof window > "u") return; window.___$twitterScriptLoaded___ && (e.loaded = !0), window.___$twitterScriptLoading___ && (e.loading = !0); const t = document.getElementById("twitter-widgets-script"); t && (e.element = t, window.twttr && window.twttr.ready && (e.loaded = !0, e.loading = !1, window.___$twitterScriptLoaded___ === void 0 && (window.___$twitterScriptLoaded___ = !0), window.___$twitterScriptLoading___ === void 0 && (window.___$twitterScriptLoading___ = !1))); } O(() => { k(), S(), typeof window < "u" && window.matchMedia && (p = window.matchMedia("(prefers-color-scheme: dark)"), p.addEventListener("change", S)), h.value = !1, y(); }), U(() => { p && p.removeEventListener("change", S), r && (clearInterval(r), r = null), o.value = !1, h.value = !0; }), $(x(u), y, { deep: !0 }), $(g, () => { u.theme === "system" && !h.value && y(); }); function y() { if (!o.value) { if (r && (clearInterval(r), r = null), (window.___$twitterScriptLoaded___ || e.loaded) && window.twttr && window.twttr.ready) { v(); return; } if (window.twttr && window.twttr.ready) { v(); return; } if (window.___$twitterScriptLoading___ || e.loading) { r = setInterval(() => { (window.___$twitterScriptLoaded___ || e.loaded) && window.twttr && window.twttr.ready && (r && (clearInterval(r), r = null), v()); }, 100); return; } R("https://platform.twitter.com/widgets.js", v); } } function v() { if (!o.value) { if (o.value = !0, !window.twttr || !window.twttr.ready) { console.error("Twitter widget not available"), s.value = !0, w.value = !1, o.value = !1; return; } window.twttr.ready().then(({ widgets: t }) => { if (w.value = !0, s.value = !1, f.value) f.value.innerHTML = ""; else { console.error("tweetContainerRef is null"), o.value = !1; return; } const { tweetId: n, tweetOptions: c } = C(); t.createTweet(n, f.value, c).then(async (a) => { await F(), a ? m("tweet-load-success", a) : (s.value = !0, m("tweet-load-error", new Error("Failed to load tweet."))); }).finally(() => { w.value = !1, o.value = !1; }); }).catch((t) => { console.error("Error loading Twitter widget:", t), s.value = !0, o.value = !1; }).finally(() => { w.value = !1, o.value = !1; }); } } function C() { let { tweetId: t, tweetUrl: n, theme: c, ...a } = u; const d = I(), M = { ...a, theme: d }; let l = null; if (t && n) l = new Error("Cannot provide both tweet-id and tweet-url."); else if (t) /^\d+$/.test(t) || (l = new Error( "Invalid tweet-id, please provide a valid numerical tweet-id." )); else if (n) { const b = /^(https?:\/\/)?(www\.)?(twitter|x)\.com\/.*\/status(?:es)?\/([^/?]\d+)$/i, L = n.trim().match(b); L && L[4] ? t = L[4] : l = new Error("Invalid tweet-url."); } else l = new Error("Must provide either tweet-id or tweet-url."); if (l) throw s.value = !0, w.value = !1, m("tweet-load-error", l), l; return { tweetId: t, tweetOptions: M }; } function R(t, n) { const c = "twitter-widgets-script"; if (window.___$twitterScriptLoaded___ === void 0 && (window.___$twitterScriptLoaded___ = e.loaded), window.___$twitterScriptLoading___ === void 0 && (window.___$twitterScriptLoading___ = e.loading), window.___$twitterScriptLoaded___ || e.loaded) { n(); return; } const a = document.getElementById(c); if (a) { if (e.element = a, window.___$twitterScriptLoaded___ || e.loaded) { n(); return; } if (window.___$twitterScriptLoading___ || e.loading) return; } if (window.___$twitterScriptLoading___ || e.loading) return; window.___$twitterScriptLoading___ = !0, e.loading = !0; const d = document.createElement("script"); d.id = c, d.setAttribute("src", t), d.async = !0, d.addEventListener("load", () => { window.___$twitterScriptLoaded___ = !0, window.___$twitterScriptLoading___ = !1, e.loaded = !0, e.loading = !1, n(); }, !1), d.addEventListener("error", () => { window.___$twitterScriptLoading___ = !1, e.loading = !1, console.error("Failed to load Twitter widgets script"); }, !1), e.element = d, document.body.appendChild(d); } return (t, n) => (P(), N(V, null, [ s.value ? E(t.$slots, "error", { key: 0 }) : w.value ? E(t.$slots, "loading", { key: 1 }) : W("", !0), j("div", z({ ref_key: "tweetContainerRef", ref: f }, t.$attrs), null, 16) ], 64)); } }); export { D as VueTweet, D as default };