UNPKG

@ipaat/vue3-tailwind3-cookie-comply

Version:

A Vue 3 compatible component to handle cookie consent styled with Tailwind CSS 3.

417 lines (416 loc) 16.6 kB
import { ref as T, onMounted as I, openBlock as o, createElementBlock as f, normalizeClass as b, createElementVNode as t, computed as h, unref as m, renderSlot as d, createBlock as R, Teleport as j, toDisplayString as s, createVNode as g, withCtx as i, createTextVNode as v, Transition as M, withDirectives as _, vShow as N, Fragment as z, renderList as E, createCommentVNode as A } from "vue"; const J = ["for"], U = ["id", "checked", "disabled", "value"], Y = /* @__PURE__ */ t("div", { class: "w-11 h-6 bg-gray-200 rounded-full peer peer-focus:ring-4 peer-focus:ring-blue-300 dark:peer-focus:ring-blue-800 dark:bg-gray-700 peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-0.5 after:left-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-5 after:w-5 after:transition-all dark:border-gray-600 peer-checked:bg-blue-600" }, null, -1), F = { __name: "CookieToggle", props: { value: { type: String, required: !0 }, isRequired: { type: Boolean, default: !1 } }, emits: ["update:checkbox"], setup(e, { emit: n }) { const c = e, r = T(!1); I(() => { c.isRequired && (r.value = !0, n("update:checkbox", { value: c.value, isEnabled: !0 })); }); const l = (u) => { r.value = !r.value, n("update:checkbox", { value: u, isEnabled: r.value }); }; return (u, k) => (o(), f("label", { class: b([{ "cursor-pointer": !e.isRequired, "cursor-not-allowed": e.isRequired }, "inline-flex relative items-center"]), for: "toggle_" + e.value }, [ t("input", { id: "toggle_" + e.value, checked: e.isRequired, disabled: e.isRequired, value: e.value, class: "sr-only peer", type: "checkbox", onInput: k[0] || (k[0] = (B) => l(B.target.value)) }, null, 40, U), Y ], 10, J)); } }, y = { __name: "CookieButton", props: { color: { type: String, default: "primary", validator: (e) => ["primary", "secondary", "danger", "danger-o", "success"].includes(e) }, paddingClasses: { type: [String, Array], default: () => ["py-2.5", "px-5"] } }, setup(e) { const n = e, c = h(() => { switch (n.color) { case "secondary": return "border text-gray-900 bg-white border-gray-200 hover:bg-gray-100 hover:text-blue-700 focus:ring-gray-200 dark:focus:ring-gray-700 dark:bg-gray-800 dark:text-gray-400 dark:border-gray-600 dark:hover:text-white dark:hover:bg-gray-700"; case "danger": return "text-white bg-red-700 hover:bg-red-800 focus:ring-red-300 dark:bg-red-600 dark:hover:bg-red-700 dark:focus:ring-red-900"; case "danger-o": return "text-red-700 hover:text-white border border-red-700 hover:bg-red-800 focus:ring-red-300 dark:border-red-500 dark:text-red-500 dark:hover:text-white dark:hover:bg-red-600 dark:focus:ring-red-900"; case "success": return "text-white bg-green-700 hover:bg-green-800 focus:ring-green-300 dark:bg-green-600 dark:hover:bg-green-700 dark:focus:ring-green-800"; case "primary": return "text-white bg-blue-700 hover:bg-blue-800 focus:ring-blue-300 dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-800"; default: return "text-white bg-blue-700 hover:bg-blue-800 focus:ring-blue-300 dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-800"; } }); return (r, l) => (o(), f("button", { class: b([[m(c), e.paddingClasses], "text-sm font-medium focus:outline-none rounded-lg focus:z-10 focus:ring-4 transition duration-150 ease-in-out"]), type: "button" }, [ d(r.$slots, "default") ], 2)); } }, G = { class: "font-semibold" }, H = { class: "ml-auto flex flex-col sm:flex-row space-y-3 sm:space-y-0 sm:space-x-3" }, K = { class: "fixed inset-0 overflow-y-auto px-4 py-6 sm:px-0 z-[1000] flex items-center" }, Q = { class: "fixed inset-0 transform transition-all" }, X = /* @__PURE__ */ t("div", { class: "absolute inset-0 bg-gray-500 opacity-90 dark:bg-gray-900 dark:opacity-80" }, null, -1), Z = [ X ], ee = { class: "relative bg-white dark:bg-gray-800 rounded-lg" }, te = { class: "p-6 bg-gray-50 dark:bg-gray-700 rounded-t-lg" }, ae = { class: "text-xl font-medium text-gray-900 dark:text-white" }, re = /* @__PURE__ */ t("svg", { class: "h-[12px] w-[12px]", viewPort: "0 0 12 12", xmlns: "http://www.w3.org/2000/svg" }, [ /* @__PURE__ */ t("line", { stroke: "currentColor", "stroke-width": "2", x1: "1", x2: "11", y1: "11", y2: "1" }), /* @__PURE__ */ t("line", { stroke: "currentColor", "stroke-width": "2", x1: "1", x2: "11", y1: "1", y2: "11" }) ], -1), le = { class: "px-6 overflow-y-auto py-6" }, se = { class: "text-semibold text-gray-800 dark:text-gray-200" }, oe = { class: "text-sm text-gray-600 dark:text-gray-400" }, ne = { class: "space-y-2 mt-6" }, ce = { class: "text-gray-800 dark:text-gray-200" }, ie = { key: 0, class: "border-t border-gray-100 dark:border-gray-700 my-6" }, de = { class: "p-6 bg-gray-50 dark:bg-gray-700 rounded-b-lg" }, ue = { class: "flex items-center justify-end space-x-3" }, ge = { __name: "VueCookieComply", props: { bannerTitle: { type: String, default: "Cookie settings" }, bannerDescription: { type: String, default: "We use cookies and similar technologies to help personalize content and offer a better experience. You can opt to customize them by clicking the preferences button." }, preferencesBtnLabel: { type: String, default: "Preferences" }, acceptAllBtnLabel: { type: String, default: "Accept All" }, declineAllBtnLabel: { type: String, default: "Decline All" }, savePreferencesBtnLabel: { type: String, default: "Save" }, modalTitle: { type: String, default: "Your cookie settings" }, preferences: { type: Array, default: () => [] }, target: { type: String, default: "body" }, bannerBackgroundColor: { type: [String, Array], default: () => ["bg-gray-200", "dark:bg-gray-800"] }, bannerTextColor: { type: [String, Array], default: () => ["text-gray-800", "dark:text-gray-200"] }, bannerDescriptionTextColor: { type: [String, Array], default: () => ["text-gray-600", "dark:text-gray-400"] }, modalMaxWidth: { type: String, default: "xl" }, bannerMaxWidth: { type: String, default: "5xl" } }, emits: [ "on-accept-all", "on-decline-all", "on-save-preferences" ], setup(e, { emit: n }) { const c = e, r = T(!0), l = T(!1), u = T([]), k = h(() => ({ xs: "sm:max-w-xs", sm: "sm:max-w-sm", md: "sm:max-w-md", lg: "sm:max-w-lg", xl: "sm:max-w-xl", "2xl": "sm:max-w-2xl", "3xl": "sm:max-w-3xl", "4xl": "sm:max-w-4xl", "5xl": "sm:max-w-5xl", "6xl": "sm:max-w-6xl", "7xl": "sm:max-w-7xl" })[c.modalMaxWidth]), B = h(() => ({ xs: "sm:max-w-xs", sm: "sm:max-w-sm", md: "sm:max-w-md", lg: "sm:max-w-lg", xl: "sm:max-w-xl", "2xl": "sm:max-w-2xl", "3xl": "sm:max-w-3xl", "4xl": "sm:max-w-4xl", "5xl": "sm:max-w-5xl", "6xl": "sm:max-w-6xl", "7xl": "sm:max-w-7xl" })[c.bannerMaxWidth]), q = h(() => c.preferences.map( (a) => a.items.map((x) => x.isRequired ? x.value : null) ).flat().filter((a) => a)), V = h(() => c.preferences.map((a) => a.items.map((x) => x.value)).flat().filter((a) => a)), p = h(() => q.value.length === c.preferences.length); I(() => { localStorage.getItem("cookie-comply") && (r.value = !1); }); const w = () => { r.value = !1, l.value = !1, localStorage.setItem("cookie-comply", JSON.stringify(V.value)), n("on-accept-all", V.value); }, W = () => { r.value = !1, l.value = !1, localStorage.setItem("cookie-comply", JSON.stringify(q.value)), n("on-decline-all", q.value); }, O = () => { r.value = !1, l.value = !1, localStorage.setItem("cookie-comply", JSON.stringify(u.value)), n("on-save-preferences", u.value); }, P = () => { l.value = !0; }, $ = () => { l.value = !1; }, D = ({ value: a, isEnabled: x }) => { x ? u.value.push(a) : u.value.splice(u.value.indexOf(a), 1); }; return (a, x) => (o(), R(j, { to: e.target }, [ r.value ? (o(), f("aside", { key: 0, class: b([[e.bannerBackgroundColor, m(B)], "fixed px-6 py-4 bottom-0 left-0 right-0 sm:bottom-6 sm:left-16 sm:right-16 sm:rounded-md mx-auto"]) }, [ t("div", { class: b([[e.bannerTextColor], "flex items-center justify-between space-x-6"]) }, [ t("div", null, [ d(a.$slots, "banner-text", { description: e.bannerDescription, title: e.bannerTitle }, () => [ t("h3", G, s(e.bannerTitle), 1), t("p", { class: b([[e.bannerDescriptionTextColor], "text-sm"]) }, s(e.bannerDescription), 3) ]) ]), t("div", H, [ d(a.$slots, "banner-actions", { onAccept: w, onPreferences: P }, () => [ g(y, { class: "whitespace-nowrap", color: "secondary", onClick: P }, { default: i(() => [ v(s(e.preferencesBtnLabel), 1) ]), _: 1 }), g(y, { class: "whitespace-nowrap", color: "success", onClick: w }, { default: i(() => [ v(s(e.acceptAllBtnLabel), 1) ]), _: 1 }) ]) ]) ], 2), g(M, { "leave-active-class": "duration-200" }, { default: i(() => [ _(t("div", K, [ g(M, { "enter-active-class": "ease-out duration-300", "enter-from-class": "opacity-0", "enter-to-class": "opacity-100", "leave-active-class": "ease-in duration-200", "leave-from-class": "opacity-100", "leave-to-class": "opacity-0" }, { default: i(() => [ _(t("div", Q, Z, 512), [ [N, l.value] ]) ]), _: 1 }), g(M, { "enter-active-class": "ease-out duration-300", "enter-from-class": "opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95", "enter-to-class": "opacity-100 translate-y-0 sm:scale-100", "leave-active-class": "ease-in duration-200", "leave-from-class": "opacity-100 translate-y-0 sm:scale-100", "leave-to-class": "opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95" }, { default: i(() => [ _(t("div", { class: b([m(k), "mb-6 shadow-xl transform transition-all sm:w-full sm:mx-auto"]) }, [ t("div", ee, [ d(a.$slots, "modal-header", { modalTitle: e.modalTitle, onClose: $ }, () => [ t("header", te, [ d(a.$slots, "modal-title", {}, () => [ t("h3", ae, s(e.modalTitle), 1) ]), d(a.$slots, "modal-close-button", { onClose: $ }, () => [ g(y, { class: "absolute top-6 right-6", color: "danger-o", "padding-classes": "p-1.5", onClick: $ }, { default: i(() => [ re ]), _: 1 }) ]) ]) ]), d(a.$slots, "modal-body", { preferences: e.preferences, onToggle: D }, () => [ t("main", le, [ (o(!0), f(z, null, E(e.preferences, (C, L) => (o(), f("div", { key: L }, [ d(a.$slots, "modal-preference-item", { index: L, preference: C, onToggle: D }, () => [ t("h5", se, s(C.title), 1), t("p", oe, s(C.description), 1), t("div", ne, [ (o(!0), f(z, null, E(C.items, (S) => (o(), f("div", { key: S.value, class: "flex justify-between items-center" }, [ t("h6", ce, s(S.label), 1), g(F, { "is-required": S.isRequired, value: S.value, "onUpdate:checkbox": D }, null, 8, ["is-required", "value"]) ]))), 128)) ]), L !== e.preferences.length - 1 ? (o(), f("hr", ie)) : A("", !0) ]) ]))), 128)) ]) ]), d(a.$slots, "modal-footer", { hasOnlyRequired: m(p), onAccept: w, onDecline: W, onSave: O }, () => [ t("footer", de, [ t("div", ue, [ t("div", { class: b([{ "mr-auto": !m(p), "ml-auto": m(p) }, "space-x-3"]) }, [ m(p) ? A("", !0) : (o(), R(y, { key: 0, class: "whitespace-nowrap", color: "danger", onClick: W }, { default: i(() => [ v(s(e.declineAllBtnLabel), 1) ]), _: 1 })), g(y, { class: "whitespace-nowrap", color: "success", onClick: w }, { default: i(() => [ v(s(e.acceptAllBtnLabel), 1) ]), _: 1 }) ], 2), m(p) ? A("", !0) : (o(), R(y, { key: 0, class: "whitespace-nowrap", onClick: O }, { default: i(() => [ v(s(e.savePreferencesBtnLabel), 1) ]), _: 1 })) ]) ]) ]) ]) ], 2), [ [N, l.value] ]) ]), _: 3 }) ], 512), [ [N, l.value] ]) ]), _: 3 }) ], 2)) : A("", !0) ], 8, ["to"])); } }, fe = /* @__PURE__ */ (() => { const e = ge; return e.install = (n) => { n.component("VueCookieComply", e); }, e; })(); export { fe as default };