@openpolicy/react
Version:
React components and hooks for OpenPolicy
920 lines (911 loc) • 29.6 kB
JavaScript
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