UNPKG

@openpolicy/react

Version:

React components and hooks for OpenPolicy

920 lines (911 loc) 29.6 kB
import { createContext, useCallback, useContext, useEffect, useMemo, useRef, useState, useSyncExternalStore } from "react"; import { Fragment, jsx, jsxs } from "react/jsx-runtime"; //#region ../core/dist/index.js function acceptAll(config) { const consent = { essential: true }; for (const [key, value] of Object.entries(config.cookies)) { if (key === "essential") continue; consent[key] = Boolean(value); } return consent; } function rejectAll(config) { const consent = { essential: true }; if (config) for (const key of Object.keys(config.cookies)) { if (key === "essential") continue; consent[key] = false; } return consent; } const heading = (value, levelOrContext, context) => { const level = typeof levelOrContext === "number" ? levelOrContext : void 0; const ctx = typeof levelOrContext === "object" ? levelOrContext : context; return { type: "heading", ...level !== void 0 && { level }, value, ...ctx && { context: ctx } }; }; const text = (value, context) => ({ type: "text", value, ...context && { context } }); const bold = (value, context) => ({ type: "bold", value, ...context && { context } }); const link = (href, value, context) => ({ type: "link", href, value, ...context && { context } }); const p = (children, context) => ({ type: "paragraph", children: children.map((c) => typeof c === "string" ? text(c) : c), ...context && { context } }); const li = (children, context) => ({ type: "listItem", children: children.map((c) => typeof c === "string" ? text(c) : c), ...context && { context } }); const ul = (items, context) => ({ type: "list", items, ...context && { context } }); const section = (id, content, context) => ({ type: "section", id, content, ...context && { context } }); function buildIntroduction$1(config) { return section("cookie-introduction", [heading("Cookie Policy"), p([`This Cookie Policy explains how ${config.company.name} ("we", "us", or "our") uses cookies and similar tracking technologies on our services. Effective Date: ${config.effectiveDate}.`])]); } function buildWhatAreCookies() { return section("cookie-what-are-cookies", [ heading("What Are Cookies?"), p(["Cookies are small text files placed on your device by websites you visit. They are widely used to make websites work more efficiently and to provide information to site owners."]), p(["Cookies can be \"session cookies\" (deleted when you close your browser) or \"persistent cookies\" (remain on your device until they expire or you delete them)."]) ]); } function buildTypes(config) { const types = []; if (config.cookies.essential) types.push({ label: "Essential Cookies", description: "Required for the basic functioning of our services. These cannot be disabled." }); if (config.cookies.analytics) types.push({ label: "Analytics Cookies", description: "Help us understand how visitors interact with our services so we can improve them." }); if (config.cookies.functional) types.push({ label: "Functional Cookies", description: "Enable enhanced functionality and personalisation, such as remembering your preferences." }); if (config.cookies.marketing) types.push({ label: "Marketing Cookies", description: "Used to deliver advertisements more relevant to you and your interests." }); if (types.length === 0) return section("cookie-types", [heading("Types of Cookies We Use"), p(["We do not currently use any cookies."])]); return section("cookie-types", [heading("Types of Cookies We Use"), ul(types.map((t) => li([ bold(t.label), " — ", t.description ])))]); } function buildTrackingTechnologies(config) { if (!config.trackingTechnologies || config.trackingTechnologies.length === 0) return null; return section("cookie-tracking-technologies", [ heading("Other Tracking Technologies"), p(["In addition to cookies, we may use the following tracking technologies:"]), ul(config.trackingTechnologies.map((t) => li([t]))) ]); } function buildThirdParties$1(config) { if (!config.thirdParties || config.thirdParties.length === 0) return null; return section("cookie-third-parties", [ heading("Third-Party Cookies"), p(["The following third parties may set cookies through our services:"]), ul(config.thirdParties.map((t) => li([ bold(t.name), " — ", t.purpose, ...t.policyUrl ? [ " (", link(t.policyUrl, "Privacy Policy"), ")" ] : [] ]))) ]); } function buildConsent(config) { if (!config.consentMechanism) return null; const { hasBanner, hasPreferencePanel, canWithdraw } = config.consentMechanism; const items = []; if (hasBanner) items.push("We display a cookie consent banner when you first visit our services."); if (hasPreferencePanel) items.push("You can manage your cookie preferences at any time via our preference panel."); if (canWithdraw) items.push("You may withdraw your consent at any time; however, this will not affect the lawfulness of processing based on consent before its withdrawal."); if (items.length === 0) return null; return section("cookie-consent", [heading("Your Consent"), ul(items.map((i) => li([i])))]); } function buildManaging() { return section("cookie-managing", [ heading("Managing Cookies"), p(["Most web browsers allow you to control cookies through their settings. You can:"]), ul([ li(["Delete cookies already stored on your device"]), li(["Block cookies from being set on your device"]), li(["Set your browser to notify you when a cookie is being set"]) ]), p(["Please note that restricting cookies may impact the functionality of our services. Consult your browser's help documentation for instructions on managing cookies."]) ]); } function buildJurisdictionEu(config) { if (!config.jurisdictions.includes("eu")) return null; return section("cookie-jurisdiction-eu", [ heading("European Users (GDPR)", { reason: "Required under ePrivacy Directive and GDPR" }), p(["If you are located in the European Economic Area, we rely on your consent as our legal basis for setting non-essential cookies. You have the right to withdraw consent at any time."]), p(["Essential cookies are set on the basis of our legitimate interests to provide you with a functioning service."]) ]); } function buildContact$1(config) { return section("cookie-contact", [ heading("Contact Us"), p(["If you have questions about this Cookie Policy, please contact us:"]), ul([ li([bold("Legal Name: "), config.company.legalName]), li([bold("Address: "), config.company.address]), li([bold("Email: "), config.company.contact]) ]) ]); } const SECTION_BUILDERS$1 = [ buildIntroduction$1, () => buildWhatAreCookies(), buildTypes, buildTrackingTechnologies, buildThirdParties$1, buildConsent, () => buildManaging(), buildJurisdictionEu, buildContact$1 ]; function compileCookieDocument(config) { return SECTION_BUILDERS$1.map((builder) => builder(config)).filter((s) => s !== null); } const LEGAL_BASIS_LABELS = { consent: "Consent (Article 6(1)(a))", contract: "Performance of a contract (Article 6(1)(b))", legal_obligation: "Compliance with a legal obligation (Article 6(1)(c))", vital_interests: "Protection of vital interests (Article 6(1)(d))", public_task: "Performance of a public task (Article 6(1)(e))", legitimate_interests: "Legitimate interests (Article 6(1)(f))" }; const RIGHTS_LABELS = { access: "Right to access your personal data", rectification: "Right to correct inaccurate data", erasure: "Right to request deletion of your data", portability: "Right to receive your data in a portable format", restriction: "Right to restrict how we process your data", objection: "Right to object to processing", opt_out_sale: "Right to opt out of the sale of your personal information", non_discrimination: "Right to non-discriminatory treatment for exercising your rights" }; function buildIntroduction(config) { return section("introduction", [ heading("Introduction"), p([`This Privacy Policy describes how ${config.company.name} ("we", "us", or "our") collects, uses, and shares information about you when you use our services. Effective Date: ${config.effectiveDate}.`]), p([`If you have questions about this policy, please contact us at ${config.company.contact}.`]) ]); } function buildChildrenPrivacy(config) { if (!config.children) return null; const { underAge, noticeUrl } = config.children; return section("children-privacy", [ heading("Children's Privacy", { reason: "Required by COPPA" }), p([`Our services are not directed to children under the age of ${underAge}. We do not knowingly collect personal information from children under ${underAge}. If you believe we have collected information from a child, please contact us immediately.`]), ...noticeUrl ? [p([ "For more information, see our ", link(noticeUrl, "Children's Privacy Notice"), "." ])] : [] ]); } function buildDataCollected(config) { const items = Object.entries(config.dataCollected).map(([category, fields]) => li([bold(category), ul(fields.map((f) => li([f])))])); return section("data-collected", [ heading("Information We Collect"), p(["We collect the following categories of information:"]), ul(items) ]); } function buildLegalBasis(config) { if (!config.jurisdictions.includes("eu")) return null; const labelled = (Array.isArray(config.legalBasis) ? config.legalBasis : [config.legalBasis]).map((b) => LEGAL_BASIS_LABELS[b] ?? b); return section("legal-basis", [heading("Legal Basis for Processing", { reason: "Required by GDPR Article 13" }), p([labelled.join(" and ")])]); } function buildDataRetention(config) { const items = Object.entries(config.retention).map(([category, period]) => li([ bold(category), ": ", period ])); return section("data-retention", [ heading("Data Retention"), p(["We retain your data for the following periods:"]), ul(items) ]); } function buildCookies(config) { const enabled = []; if (config.cookies.essential) enabled.push("Essential cookies — required for the service to function"); if (config.cookies.analytics) enabled.push("Analytics cookies — help us understand how the service is used"); if (config.cookies.marketing) enabled.push("Marketing cookies — used to deliver relevant advertisements"); if (enabled.length === 0) return section("cookies", [heading("Cookies and Tracking"), p(["We do not use cookies or similar tracking technologies."])]); return section("cookies", [ heading("Cookies and Tracking"), p(["We use the following types of cookies and tracking technologies:"]), ul(enabled.map((e) => li([e]))) ]); } function buildThirdParties(config) { if (config.thirdParties.length === 0) return section("third-parties", [heading("Third-Party Services"), p(["We do not share your personal information with third parties except as required by law."])]); return section("third-parties", [ heading("Third-Party Services"), p(["We share data with the following third-party services:"]), ul(config.thirdParties.map((t) => li([ t.policyUrl ? link(t.policyUrl, t.name) : bold(t.name), " — ", t.purpose ]))) ]); } function buildUserRights(config) { if (config.userRights.length === 0) return null; const items = config.userRights.map((right) => { return li([RIGHTS_LABELS[right] ?? right]); }); return section("user-rights", [ heading("Your Rights"), p(["You have the following rights regarding your personal data:"]), ul(items) ]); } function buildGdprSupplement(config) { if (!config.jurisdictions.includes("eu")) return null; return section("gdpr-supplement", [ heading("GDPR Supplemental Disclosures", { reason: "Required by GDPR Article 13" }), p(["This section applies to individuals in the European Economic Area (EEA) under the General Data Protection Regulation (GDPR)."]), p([ "Data Controller: ", bold(config.company.legalName), `, ${config.company.address}` ]), p(["In addition to the rights listed above, you have the right to lodge a complaint with your local data protection authority if you believe we have not handled your data in accordance with applicable law."]), p(["If we transfer your personal data outside the EEA, we ensure adequate safeguards are in place in accordance with GDPR requirements."]) ]); } function buildCcpaSupplement(config) { if (!config.jurisdictions.includes("ca")) return null; return section("ccpa-supplement", [ heading("California Privacy Rights (CCPA)", { reason: "Required by CCPA" }), p(["If you are a California resident, you have the following additional rights:"]), ul([ li(["Right to Know — You may request disclosure of the personal information we collect, use, and share about you."]), li(["Right to Delete — You may request deletion of personal information we have collected about you."]), li(["Right to Opt-Out — You may opt out of the sale of your personal information."]), li(["Right to Non-Discrimination — We will not discriminate against you for exercising your CCPA rights."]) ]) ]); } function buildContact(config) { return section("contact", [ heading("Contact Us"), p(["Contact us:"]), ul([ li([ bold("Legal Name:"), " ", config.company.legalName ]), li([ bold("Address:"), " ", config.company.address ]), li([ bold("Email:"), " ", config.company.contact ]) ]) ]); } const SECTION_BUILDERS = [ buildIntroduction, buildChildrenPrivacy, buildDataCollected, buildLegalBasis, buildDataRetention, buildCookies, buildThirdParties, buildUserRights, buildGdprSupplement, buildCcpaSupplement, buildContact ]; function compilePrivacyDocument(config) { return SECTION_BUILDERS.map((builder) => builder(config)).filter((s) => s !== null); } function compile(input) { if (input.type === "privacy") { const { type: _, ...config } = input; return { type: "document", policyType: "privacy", sections: compilePrivacyDocument(config) }; } const { type: _, ...config } = input; return { type: "document", policyType: "cookie", sections: compileCookieDocument(config) }; } function isOpenPolicyConfig(value) { if (value === null || typeof value !== "object") return false; const obj = value; return "company" in obj && "effectiveDate" in obj && !("type" in obj); } const RIGHTS_BY_JURISDICTION = { eu: [ "access", "rectification", "erasure", "portability", "restriction", "objection" ], ca: [ "access", "erasure", "opt_out_sale", "non_discrimination" ] }; const CANONICAL_ORDER = [ "access", "rectification", "erasure", "portability", "restriction", "objection", "opt_out_sale", "non_discrimination" ]; function deriveUserRights(jurisdictions) { const set = /* @__PURE__ */ new Set(); for (const j of jurisdictions) for (const right of RIGHTS_BY_JURISDICTION[j] ?? []) set.add(right); return CANONICAL_ORDER.filter((right) => set.has(right)); } const PRIVACY_FIELDS = [ "dataCollected", "legalBasis", "retention", "children" ]; function hasAnyPrivacyField(config) { return PRIVACY_FIELDS.some((field) => config[field] !== void 0); } function hasCookieField(config) { return config.cookies !== void 0; } function shouldEmit(category, config) { if (config.policies) return config.policies.includes(category); return category === "privacy" ? hasAnyPrivacyField(config) : hasCookieField(config); } const EMPTY_COOKIES = { essential: true }; function expandOpenPolicyConfig(config) { const inputs = []; if (shouldEmit("privacy", config)) inputs.push({ type: "privacy", company: config.company, effectiveDate: config.effectiveDate, jurisdictions: config.jurisdictions, dataCollected: config.dataCollected ?? {}, legalBasis: config.legalBasis ?? [], retention: config.retention ?? {}, cookies: config.cookies ?? EMPTY_COOKIES, thirdParties: config.thirdParties ?? [], userRights: deriveUserRights(config.jurisdictions), children: config.children }); if (shouldEmit("cookie", config)) inputs.push({ type: "cookie", company: config.company, effectiveDate: config.effectiveDate, jurisdictions: config.jurisdictions, cookies: config.cookies ?? EMPTY_COOKIES, thirdParties: config.thirdParties ?? [], trackingTechnologies: config.trackingTechnologies, consentMechanism: config.consentMechanism }); return inputs; } //#endregion //#region src/hooks/useShouldShowCookieBanner.ts function useShouldShowCookieBanner(status, shouldShow) { const [visible, setVisible] = useState(false); const shouldShowRef = useRef(shouldShow); useEffect(() => { if (status !== "undecided") { setVisible(false); return; } let cancelled = false; (shouldShowRef.current ?? (() => Promise.resolve(true)))().then((show) => { if (!cancelled) setVisible(show); }); return () => { cancelled = true; }; }, [status]); if (status !== "undecided") return false; return visible; } //#endregion //#region src/styles.ts const defaultStyles = ` .op-policy { --op-font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; --op-font-size-body: 1rem; --op-font-size-heading: 1.125rem; --op-font-weight-heading: 600; --op-line-height: 1.7; --op-body-color: #374151; --op-heading-color: #111827; --op-link-color: #2563eb; --op-link-color-hover: #1d4ed8; --op-section-gap: 2rem; --op-border-color: #e5e7eb; --op-border-radius: 0.375rem; font-family: var(--op-font-family); font-size: var(--op-font-size-body); color: var(--op-body-color); line-height: var(--op-line-height); max-width: 65ch; } .op-section { margin-bottom: var(--op-section-gap); padding-bottom: var(--op-section-gap); border-bottom: 1px solid var(--op-border-color); } .op-section:last-child { border-bottom: none; margin-bottom: 0; padding-bottom: 0; } .op-heading { font-size: var(--op-font-size-heading); font-weight: var(--op-font-weight-heading); color: var(--op-heading-color); line-height: 1.3; margin: 0 0 0.75rem; } .op-paragraph { margin: 0 0 0.75rem; } .op-paragraph:last-child { margin-bottom: 0; } .op-list { margin: 0 0 0.75rem; padding-left: 1.5rem; list-style-type: disc; } .op-list:last-child { margin-bottom: 0; } .op-list .op-list { margin-top: 0.375rem; margin-bottom: 0; list-style-type: circle; } .op-list-item { margin-bottom: 0.375rem; } .op-list-item:last-child { margin-bottom: 0; } .op-bold { font-weight: 600; color: var(--op-heading-color); } .op-link { color: var(--op-link-color); text-decoration: underline; text-underline-offset: 2px; transition: color 0.15s ease; } .op-link:hover { color: var(--op-link-color-hover); } `; //#endregion //#region src/context.tsx const LS_KEY = "op_consent"; function getConsentFromStorage() { try { const raw = localStorage.getItem(LS_KEY); if (!raw) return null; return JSON.parse(raw); } catch { return null; } } function setConsentToStorage(consent) { const value = { ...consent, essential: true }; localStorage.setItem(LS_KEY, JSON.stringify(value)); } function clearConsentFromStorage() { localStorage.removeItem(LS_KEY); } function resolveCookieConfig(raw) { if (!raw) return void 0; if (isOpenPolicyConfig(raw)) { const cookie = expandOpenPolicyConfig(raw).find((p) => p.type === "cookie"); if (!cookie) return void 0; const { type: _type, ...rest } = cookie; return rest; } return raw; } const CATEGORY_LABELS = { essential: "Essential", analytics: "Analytics", functional: "Functional", marketing: "Marketing" }; function acceptAllForConfig(config) { const consent = acceptAll(config); setConsentToStorage(consent); return consent; } function rejectAllForConfig(config) { const consent = rejectAll(config); setConsentToStorage(consent); return consent; } function updateConsent(partial) { const next = { ...getConsentFromStorage() ?? { essential: true }, ...partial, essential: true }; setConsentToStorage(next); return next; } function evalHas(consent, expr) { if (!consent) return false; if (typeof expr === "string") return Boolean(consent[expr]); if ("and" in expr) return expr.and.every((child) => evalHas(consent, child)); if ("or" in expr) return expr.or.some((child) => evalHas(consent, child)); if ("not" in expr) return !evalHas(consent, expr.not); return false; } const listeners = /* @__PURE__ */ new Set(); function subscribe(listener) { listeners.add(listener); return () => listeners.delete(listener); } function notifyListeners() { for (const l of listeners) l(); } let cachedRaw = ""; let cachedValue = null; function getSnapshotCached() { const rawStr = localStorage.getItem(LS_KEY) ?? ""; if (rawStr === cachedRaw) return cachedValue; cachedRaw = rawStr; cachedValue = getConsentFromStorage(); return cachedValue; } function getServerSnapshot() { return null; } const OpenPolicyContext = createContext({ config: null, cookieConfig: null, route: "closed", setRoute: () => {}, status: "undecided", consent: null, accept: () => {}, reject: () => {}, update: () => {}, reset: () => {}, has: () => false, categories: [], toggle: () => {}, save: () => {}, rejectAll: () => {} }); function OpenPolicyProvider({ config, shouldShow, children }) { const cookieConfig = useMemo(() => resolveCookieConfig(config) ?? null, [config]); const consent = useSyncExternalStore(subscribe, getSnapshotCached, getServerSnapshot); const status = consent ? "completed" : "undecided"; useEffect(() => { const body = document.body; if (status) body.dataset.status = status; if (cookieConfig) for (const key of Object.keys(cookieConfig.cookies)) { const value = consent ? consent[key] ?? false : false; body.setAttribute(`data-consent-${key}`, String(Boolean(value))); } return () => { if (body.dataset.status === status) delete body.dataset.status; if (cookieConfig) for (const key of Object.keys(cookieConfig.cookies)) body.removeAttribute(`data-consent-${key}`); }; }, [ consent, cookieConfig, status ]); const has = useCallback((expr) => evalHas(consent, expr), [consent]); const visible = useShouldShowCookieBanner(status, shouldShow); const [route, setRoute] = useState("closed"); const [draft, setDraft] = useState({}); useEffect(() => { if (visible && route === "closed") setRoute("cookie"); else if (!visible && route !== "closed") setRoute("closed"); }, [visible, route]); const rawAccept = useCallback(() => { if (!cookieConfig) return; acceptAllForConfig(cookieConfig); notifyListeners(); }, [cookieConfig]); const rawReject = useCallback(() => { rejectAllForConfig(cookieConfig ?? void 0); notifyListeners(); }, [cookieConfig]); const update = useCallback((partial) => { updateConsent(partial); notifyListeners(); }, []); const reset = useCallback(() => { clearConsentFromStorage(); notifyListeners(); }, []); const accept = () => { rawAccept(); setRoute("closed"); }; const reject = () => { rawReject(); setRoute("closed"); }; const categories = cookieConfig ? Object.keys(cookieConfig.cookies).filter((key) => cookieConfig.cookies[key]).map((key) => ({ key, label: CATEGORY_LABELS[String(key)] ?? String(key), enabled: key === "essential" ? true : draft[key] ?? consent?.[key] ?? false, locked: key === "essential" })) : []; const toggle = (key) => { if (key === "essential") return; setDraft((prev) => ({ ...prev, [key]: !(prev[key] ?? consent?.[key] ?? false) })); }; const save = (onSave) => { const next = { ...consent ?? {}, ...draft, essential: true }; update(next); setDraft({}); onSave?.(next); setRoute("closed"); }; const rejectAllCategories = () => { if (!cookieConfig) return; const next = { essential: true }; for (const key of Object.keys(cookieConfig.cookies)) if (key !== "essential") next[key] = false; update(next); setDraft({}); setRoute("closed"); }; return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("style", { href: "@openpolicy/react", precedence: "default", children: defaultStyles }), /* @__PURE__ */ jsx(OpenPolicyContext.Provider, { value: { config, cookieConfig, route, setRoute, status, consent, accept, reject, update, reset, has, categories, toggle, save, rejectAll: rejectAllCategories }, children })] }); } //#endregion //#region src/hooks/useCookies.ts function useCookies() { const { route, setRoute, status, consent, accept, rejectAll, categories, toggle, save, reset, has } = useContext(OpenPolicyContext); return { status, consent, categories, route, has, acceptAll: accept, acceptNecessary: rejectAll, toggle, save, reset, setRoute }; } //#endregion //#region src/components/ConsentGate.tsx function ConsentGate({ requires, fallback = null, children }) { const { has } = useCookies(); return has(requires) ? children : fallback; } //#endregion //#region src/components/defaults.tsx function DefaultHeading({ node }) { return /* @__PURE__ */ jsx(`h${node.level ?? 2}`, { "data-op-heading": true, className: "op-heading", children: node.value }); } function DefaultText({ node }) { return /* @__PURE__ */ jsx(Fragment, { children: node.value }); } function DefaultBold({ node }) { return /* @__PURE__ */ jsx("strong", { className: "op-bold", children: node.value }); } function DefaultItalic({ node }) { return /* @__PURE__ */ jsx("em", { className: "op-italic", children: node.value }); } function DefaultLink({ node }) { return /* @__PURE__ */ jsx("a", { href: node.href, className: "op-link", children: node.value }); } function DefaultSection({ section, children }) { return /* @__PURE__ */ jsx("section", { "data-op-section": true, className: "op-section", id: section.id, ...section.context?.reason && { "data-op-reason": section.context.reason }, children }); } function DefaultParagraph({ node: _node, children }) { return /* @__PURE__ */ jsx("p", { "data-op-paragraph": true, className: "op-paragraph", children }); } function DefaultList({ node, children }) { return /* @__PURE__ */ jsx(node.ordered ? "ol" : "ul", { "data-op-list": true, className: "op-list", children }); } function renderNode(node, components, key) { switch (node.type) { case "document": return /* @__PURE__ */ jsx(Fragment, { children: node.sections.map((s, i) => renderNode(s, components, i)) }); case "section": return /* @__PURE__ */ jsx(components.Section ?? DefaultSection, { section: node, children: node.content.map((n, i) => renderNode(n, components, i)) }, key); case "heading": return /* @__PURE__ */ jsx(components.Heading ?? DefaultHeading, { node }, key); case "paragraph": { const children = node.children.map((n, i) => renderNode(n, components, i)); if (components.Paragraph) return /* @__PURE__ */ jsx(components.Paragraph, { node, children }, key); return /* @__PURE__ */ jsx("p", { "data-op-paragraph": true, className: "op-paragraph", children }, key); } case "list": { const children = node.items.map((item, i) => renderNode(item, components, i)); if (components.List) return /* @__PURE__ */ jsx(components.List, { node, children }, key); return /* @__PURE__ */ jsx(node.ordered ? "ol" : "ul", { "data-op-list": true, className: "op-list", children }, key); } case "listItem": return /* @__PURE__ */ jsx("li", { "data-op-list-item": true, className: "op-list-item", children: node.children.map((n, i) => renderNode(n, components, i)) }, key); case "text": return /* @__PURE__ */ jsx(components.Text ?? DefaultText, { node }, key); case "bold": return /* @__PURE__ */ jsx(components.Bold ?? DefaultBold, { node }, key); case "italic": return /* @__PURE__ */ jsx(components.Italic ?? DefaultItalic, { node }, key); case "link": return /* @__PURE__ */ jsx(components.Link ?? DefaultLink, { node }, key); } } //#endregion //#region src/render.tsx function renderDocument(doc, components = {}) { return renderNode(doc, components); } //#endregion //#region src/components/CookiePolicy.tsx function CookiePolicy({ config: configProp, components, style }) { const { config: contextConfig } = useContext(OpenPolicyContext); const config = configProp ?? contextConfig ?? void 0; if (!config) return null; const input = isOpenPolicyConfig(config) ? expandOpenPolicyConfig(config).find((i) => i.type === "cookie") : { type: "cookie", ...config }; if (!input) return null; const doc = compile(input); return /* @__PURE__ */ jsx("div", { "data-op-policy": true, className: "op-policy", style, children: renderDocument(doc, components) }); } //#endregion //#region src/components/PrivacyPolicy.tsx function PrivacyPolicy({ config: configProp, components, style }) { const { config: contextConfig } = useContext(OpenPolicyContext); const config = configProp ?? contextConfig ?? void 0; if (!config) return null; const input = isOpenPolicyConfig(config) ? expandOpenPolicyConfig(config).find((i) => i.type === "privacy") : { type: "privacy", ...config }; if (!input) return null; const doc = compile(input); return /* @__PURE__ */ jsx("div", { "data-op-policy": true, className: "op-policy", style, children: renderDocument(doc, components) }); } //#endregion export { ConsentGate, CookiePolicy, DefaultBold, DefaultHeading, DefaultLink, DefaultList, DefaultParagraph, DefaultSection, DefaultText, OpenPolicyProvider as OpenPolicy, PrivacyPolicy, defaultStyles, renderDocument, renderNode, useCookies, useShouldShowCookieBanner }; //# sourceMappingURL=index.js.map