@uninspired/cookie-banner 0.0.11 → 0.0.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,4 @@
1
- import require$$0, { useMemo, useState, useEffect, useCallback, createContext, useContext } from "react";
1
+ import require$$0, { useState, useEffect, useMemo, useCallback, createContext, useContext } from "react";
2
2
  import { Item, Trigger, Content, Root as Root$3 } from "@radix-ui/react-accordion";
3
3
  import { ChevronDown, ChevronUp } from "lucide-react";
4
4
  import { Root as Root$1, Content as Content$1, Title, Description, Close } from "@radix-ui/react-dialog";
@@ -962,25 +962,25 @@ const Text = ({
962
962
  )
963
963
  );
964
964
  };
965
- const root$2 = "_root_2wcp0_53";
966
- const open$1 = "_open_2wcp0_66";
967
- const noTarget = "_noTarget_2wcp0_72";
968
- const collapsible = "_collapsible_2wcp0_81";
969
- const header$1 = "_header_2wcp0_84";
970
- const heading = "_heading_2wcp0_91";
971
- const chevron$1 = "_chevron_2wcp0_97";
972
- const settings = "_settings_2wcp0_108";
973
- const footer = "_footer_2wcp0_122";
974
- const legal = "_legal_2wcp0_129";
975
- const actions$1 = "_actions_2wcp0_132";
965
+ const root$2 = "_root_12udu_53";
966
+ const noTarget = "_noTarget_12udu_65";
967
+ const collapsible = "_collapsible_12udu_74";
968
+ const header$1 = "_header_12udu_77";
969
+ const heading = "_heading_12udu_84";
970
+ const chevron$1 = "_chevron_12udu_90";
971
+ const open$1 = "_open_12udu_95";
972
+ const settings = "_settings_12udu_101";
973
+ const footer = "_footer_12udu_115";
974
+ const legal = "_legal_12udu_122";
975
+ const actions$1 = "_actions_12udu_125";
976
976
  const classes$2 = {
977
977
  root: root$2,
978
- open: open$1,
979
978
  noTarget,
980
979
  collapsible,
981
980
  header: header$1,
982
981
  heading,
983
982
  chevron: chevron$1,
983
+ open: open$1,
984
984
  settings,
985
985
  footer,
986
986
  legal,
@@ -1949,6 +1949,7 @@ function optional(innerType) {
1949
1949
  });
1950
1950
  }
1951
1951
  const remoteScriptDefinitionSchema = /* @__PURE__ */ object({
1952
+ id: /* @__PURE__ */ string(),
1952
1953
  variant: /* @__PURE__ */ literal("remote"),
1953
1954
  type: /* @__PURE__ */ optional(/* @__PURE__ */ string()),
1954
1955
  src: /* @__PURE__ */ string(),
@@ -1958,6 +1959,7 @@ const remoteScriptDefinitionSchema = /* @__PURE__ */ object({
1958
1959
  integrity: /* @__PURE__ */ optional(/* @__PURE__ */ string())
1959
1960
  });
1960
1961
  const inlineScriptDefinitionSchema = /* @__PURE__ */ object({
1962
+ id: /* @__PURE__ */ string(),
1961
1963
  variant: /* @__PURE__ */ literal("inline"),
1962
1964
  type: /* @__PURE__ */ optional(/* @__PURE__ */ string()),
1963
1965
  async: /* @__PURE__ */ optional(/* @__PURE__ */ boolean()),
@@ -1982,14 +1984,59 @@ const Switch = ({ label: label2, id, ...rest }) => {
1982
1984
  ] });
1983
1985
  };
1984
1986
  const selectionSchema = /* @__PURE__ */ record(/* @__PURE__ */ string(), /* @__PURE__ */ boolean());
1987
+ class Cookies {
1988
+ #domain;
1989
+ #prefix;
1990
+ #sameSite;
1991
+ #secure;
1992
+ constructor(options) {
1993
+ this.#domain = options.domain;
1994
+ this.#prefix = options.prefix ?? "us-cookie-banner-";
1995
+ this.#sameSite = options.sameSite ?? "lax";
1996
+ this.#secure = options.secure ?? true;
1997
+ }
1998
+ #serialize = (data) => {
1999
+ return btoa(String.fromCharCode(...new TextEncoder().encode(data)));
2000
+ };
2001
+ #deserialize = (data) => {
2002
+ return new TextDecoder().decode(
2003
+ Uint8Array.from(atob(data), (c) => c.charCodeAt(0))
2004
+ );
2005
+ };
2006
+ set = (key, value, ttl = 365) => {
2007
+ const expires = new Date(Date.now() + ttl * 24 * 60 * 60 * 1e3);
2008
+ const cookie = `${this.#prefix}${key}=${this.#serialize(value)}; expires=${expires}; path=/; domain=${this.#domain}; SameSite=${this.#sameSite}; ${this.#secure ? "secure" : ""}`;
2009
+ document.cookie = cookie;
2010
+ };
2011
+ get = (key) => {
2012
+ const match = document.cookie.match(
2013
+ new RegExp(`(?:^|; )${this.#prefix}${key}=([^;]*)`)
2014
+ );
2015
+ if (!match) return null;
2016
+ const [_, serializedValue] = match;
2017
+ if (!serializedValue) return null;
2018
+ return this.#deserialize(serializedValue);
2019
+ };
2020
+ remove = (key) => {
2021
+ this.set(key, "", -1);
2022
+ };
2023
+ }
2024
+ const SELECTION_KEY = "selection";
1985
2025
  const SelectionContext = createContext(null);
1986
2026
  const SelectionProvider = ({
1987
2027
  children,
1988
2028
  items,
1989
- localStorageKey
2029
+ cookie
1990
2030
  }) => {
1991
- function getLsSelection(localStorageKey2) {
1992
- const storedSelection = localStorage.getItem(localStorageKey2);
2031
+ const { domain, prefix, sameSite, secure } = cookie;
2032
+ const [cookies, setCookies] = useState(
2033
+ new Cookies({ domain, prefix, sameSite, secure })
2034
+ );
2035
+ useEffect(() => {
2036
+ setCookies(new Cookies({ domain, prefix, sameSite, secure }));
2037
+ }, [domain, prefix, sameSite, secure]);
2038
+ function getCookieSelection() {
2039
+ const storedSelection = cookies.get(SELECTION_KEY);
1993
2040
  if (!storedSelection) return null;
1994
2041
  const { success, data } = selectionSchema.safeParse(
1995
2042
  JSON.parse(storedSelection)
@@ -2004,10 +2051,10 @@ const SelectionProvider = ({
2004
2051
  [items]
2005
2052
  );
2006
2053
  const [selection, setSelection] = useState(
2007
- getLsSelection(localStorageKey) ?? defaultSelection
2054
+ getCookieSelection() ?? defaultSelection
2008
2055
  );
2009
2056
  const [savedSelection, setSavedSelection] = useState(
2010
- getLsSelection(localStorageKey)
2057
+ getCookieSelection()
2011
2058
  );
2012
2059
  function toggleSelection(key, value) {
2013
2060
  const newSelection = selection ? { ...selection, [key]: value } : { [key]: value };
@@ -2022,47 +2069,51 @@ const SelectionProvider = ({
2022
2069
  (item) => selectedValues.includes(item.value)
2023
2070
  );
2024
2071
  for (const item of items) {
2025
- const elem = document.head.querySelector(`#${item.value}`);
2026
- if (!elem) continue;
2027
- elem.remove();
2072
+ if (!item.scripts) continue;
2073
+ for (const script of item.scripts) {
2074
+ const elem = document.head.querySelector(`#${item.value}-${script.id}`);
2075
+ if (!elem) continue;
2076
+ elem.remove();
2077
+ }
2028
2078
  }
2029
2079
  for (const item of mountedItems) {
2030
- const elem = document.createElement("script");
2031
- elem.id = item.value;
2032
- if (!item.script) {
2080
+ if (!item.scripts) {
2033
2081
  if (!item.required)
2034
2082
  console.warn("CookieBanner: Missing script for", item.value);
2035
2083
  continue;
2036
2084
  }
2037
- const { success, data: script } = scriptDefinitionSchema.safeParse(
2038
- item.script
2039
- );
2040
- if (!success) {
2041
- console.error(
2042
- "CookieBanner: Invalid script definition for",
2043
- item.value
2044
- );
2045
- continue;
2085
+ for (const script of item.scripts) {
2086
+ if (!script) continue;
2087
+ const elem = document.createElement("script");
2088
+ elem.id = `${item.value}-${script.id}`;
2089
+ const { success, data } = scriptDefinitionSchema.safeParse(script);
2090
+ if (!success) {
2091
+ console.error(
2092
+ "CookieBanner: Invalid script definition for",
2093
+ item.value
2094
+ );
2095
+ continue;
2096
+ }
2097
+ elem.type = data.type ?? "text/javascript";
2098
+ elem.async = data.async ?? false;
2099
+ elem.defer = data.defer ?? false;
2100
+ switch (data.variant) {
2101
+ case "inline":
2102
+ elem.textContent = data.content;
2103
+ break;
2104
+ case "remote":
2105
+ elem.src = data.src;
2106
+ elem.crossOrigin = data.crossorigin ?? null;
2107
+ elem.integrity = data.integrity ?? "";
2108
+ break;
2109
+ }
2110
+ document.head.appendChild(elem);
2046
2111
  }
2047
- elem.type = script.type ?? "text/javascript";
2048
- elem.async = script.async ?? false;
2049
- elem.defer = script.defer ?? false;
2050
- switch (script.variant) {
2051
- case "inline":
2052
- elem.textContent = script.content;
2053
- break;
2054
- case "remote":
2055
- elem.src = script.src;
2056
- elem.crossOrigin = script.crossorigin ?? null;
2057
- elem.integrity = script.integrity ?? "";
2058
- break;
2059
- }
2060
- document.head.appendChild(elem);
2061
2112
  }
2062
2113
  }, [savedSelection, items]);
2063
2114
  function saveSelection(newSelection) {
2064
2115
  setSavedSelection(newSelection);
2065
- localStorage.setItem(localStorageKey, JSON.stringify(newSelection));
2116
+ cookies.set(SELECTION_KEY, JSON.stringify(newSelection));
2066
2117
  }
2067
2118
  const onDeclineAll = useCallback(() => {
2068
2119
  const newSelection = Object.fromEntries(
@@ -2244,21 +2295,17 @@ const BannerContent = ({
2244
2295
  }
2245
2296
  ) });
2246
2297
  };
2247
- const Banner = ({
2248
- localStorageKey = "cb-selection",
2249
- items,
2250
- ...rest
2251
- }) => {
2298
+ const Banner = ({ cookie, items, ...rest }) => {
2252
2299
  const selectionItems = useMemo(
2253
2300
  () => items.filter((item) => !item.required).map((item) => ({
2254
2301
  value: item.value,
2255
- script: item.script,
2302
+ scripts: item.scripts,
2256
2303
  defaultSelected: item.defaultSelected,
2257
2304
  required: item.required
2258
2305
  })),
2259
2306
  [items]
2260
2307
  );
2261
- return /* @__PURE__ */ jsxRuntimeExports.jsx(SelectionProvider, { items: selectionItems, localStorageKey, children: /* @__PURE__ */ jsxRuntimeExports.jsx(BannerContent, { items, ...rest }) });
2308
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(SelectionProvider, { items: selectionItems, cookie, children: /* @__PURE__ */ jsxRuntimeExports.jsx(BannerContent, { items, cookie, ...rest }) });
2262
2309
  };
2263
2310
  export {
2264
2311
  Banner
@@ -102,7 +102,7 @@
102
102
  }
103
103
  }
104
104
  }
105
- @keyframes _contentShow_2wcp0_1 {
105
+ @keyframes _contentShow_12udu_1 {
106
106
  from {
107
107
  opacity: 0;
108
108
  transform: translateX(-100px);
@@ -113,7 +113,7 @@
113
113
  }
114
114
  }
115
115
 
116
- @keyframes _contentHide_2wcp0_1 {
116
+ @keyframes _contentHide_12udu_1 {
117
117
  from {
118
118
  opacity: 1;
119
119
  transform: translateX(0px);
@@ -124,7 +124,7 @@
124
124
  }
125
125
  }
126
126
 
127
- @keyframes _slideDown_2wcp0_1 {
127
+ @keyframes _slideDown_12udu_1 {
128
128
  0% {
129
129
  max-height: var(--cb-size-settings-max-height);
130
130
  overflow: auto;
@@ -139,7 +139,7 @@
139
139
  }
140
140
  }
141
141
 
142
- @keyframes _slideUp_2wcp0_1 {
142
+ @keyframes _slideUp_12udu_1 {
143
143
  0% {
144
144
  max-height: 0;
145
145
  overflow: hidden;
@@ -154,9 +154,8 @@
154
154
  }
155
155
  }
156
156
 
157
- ._root_2wcp0_53 {
158
- display: none;
159
- visibility: hidden;
157
+ ._root_12udu_53 {
158
+ display: flex;
160
159
  flex-direction: column;
161
160
  gap: var(--cb-space-md);
162
161
  padding: var(--cb-space-md);
@@ -165,15 +164,9 @@
165
164
  border-radius: var(--cb-radius-md);
166
165
  overflow: hidden;
167
166
  will-change: opacity, transform;
168
- animation: _contentHide_2wcp0_1 150ms cubic-bezier(0.16, 1, 0.3, 1);
169
-
170
- &._open_2wcp0_66 {
171
- visibility: visible;
172
- display: flex;
173
- animation: _contentShow_2wcp0_1 150ms cubic-bezier(0.16, 1, 0.3, 1);
174
- }
167
+ animation: _contentShow_12udu_1 150ms cubic-bezier(0.16, 1, 0.3, 1);
175
168
 
176
- &._noTarget_2wcp0_72 {
169
+ &._noTarget_12udu_65 {
177
170
  position: fixed;
178
171
  bottom: var(--cb-space-md);
179
172
  left: var(--cb-space-md);
@@ -182,58 +175,58 @@
182
175
  max-width: var(--cb-size-banner-max-width);
183
176
  }
184
177
 
185
- ._collapsible_2wcp0_81 {
178
+ ._collapsible_12udu_74 {
186
179
  display: contents;
187
180
 
188
- ._header_2wcp0_84 {
181
+ ._header_12udu_77 {
189
182
  display: flex;
190
183
  flex-direction: row;
191
184
  align-items: flex-start;
192
185
  justify-content: space-between;
193
186
  gap: var(--cb-space-md);
194
187
 
195
- ._heading_2wcp0_91 {
188
+ ._heading_12udu_84 {
196
189
  display: flex;
197
190
  flex-direction: column;
198
191
  align-items: flex-start;
199
192
  }
200
193
 
201
- ._chevron_2wcp0_97 {
194
+ ._chevron_12udu_90 {
202
195
  transform: rotate(0deg);
203
196
  will-change: transform;
204
197
  transition: transform 150ms ease-out;
205
198
 
206
- &._open_2wcp0_66 {
199
+ &._open_12udu_95 {
207
200
  transform: rotate(180deg);
208
201
  }
209
202
  }
210
203
  }
211
204
 
212
- ._settings_2wcp0_108 {
205
+ ._settings_12udu_101 {
213
206
  display: flex;
214
207
  flex-direction: column;
215
208
  background-color: var(--cb-color-background-muted);
216
209
  border-radius: var(--cb-radius-md);
217
210
  overflow: hidden;
218
211
  will-change: max-height, overflow;
219
- animation: _slideDown_2wcp0_1 250ms ease-out;
212
+ animation: _slideDown_12udu_1 250ms ease-out;
220
213
 
221
214
  &[data-state="open"] {
222
- animation: _slideUp_2wcp0_1 250ms ease-out;
215
+ animation: _slideUp_12udu_1 250ms ease-out;
223
216
  }
224
217
  }
225
218
 
226
- ._footer_2wcp0_122 {
219
+ ._footer_12udu_115 {
227
220
  display: flex;
228
221
  flex-direction: row;
229
222
  align-items: center;
230
223
  justify-content: space-between;
231
224
  gap: var(--cb-space-md);
232
225
 
233
- ._legal_2wcp0_129 {
226
+ ._legal_12udu_122 {
234
227
  }
235
228
 
236
- ._actions_2wcp0_132 {
229
+ ._actions_12udu_125 {
237
230
  display: flex;
238
231
  flex-direction: row;
239
232
  align-items: center;