@preprio/toolkit 0.1.0-beta.1 → 0.1.0-beta.4

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.
@@ -48,16 +48,34 @@ function getCookie(name) {
48
48
  }
49
49
  function setCookie(name, value, options = {}) {
50
50
  if (typeof document === "undefined") return;
51
- const { maxAge, path = "/" } = options;
51
+ const { maxAge, path = "/", sameSite, secure } = options;
52
52
  let cookie = `${name}=${encodeURIComponent(value)};path=${path}`;
53
53
  if (typeof maxAge === "number") {
54
54
  cookie += `;max-age=${maxAge}`;
55
55
  }
56
+ if (sameSite) {
57
+ cookie += `;samesite=${sameSite}`;
58
+ }
59
+ if (secure) {
60
+ cookie += ";secure";
61
+ }
56
62
  document.cookie = cookie;
57
63
  }
58
- function removeCookie(name, path = "/") {
64
+ function removeCookie(name, path = "/", options = {}) {
59
65
  if (typeof document === "undefined") return;
60
- document.cookie = `${name}=;path=${path};expires=Thu, 01 Jan 1970 00:00:00 GMT`;
66
+ const { sameSite, secure } = options;
67
+ let cookie = `${name}=;path=${path};expires=Thu, 01 Jan 1970 00:00:00 GMT`;
68
+ if (sameSite) {
69
+ cookie += `;samesite=${sameSite}`;
70
+ }
71
+ if (secure) {
72
+ cookie += ";secure";
73
+ }
74
+ document.cookie = cookie;
75
+ }
76
+ function crossSiteCookieOptions() {
77
+ if (typeof window === "undefined" || !window.isSecureContext) return {};
78
+ return { sameSite: "None", secure: true };
61
79
  }
62
80
 
63
81
  // src/core/locales/en.json
@@ -76,6 +94,7 @@ var en_default = {
76
94
  segment: "Segment",
77
95
  ABVariant: "A/B variant",
78
96
  chooseSegment: "Choose segment",
97
+ searchSegments: "Search segments",
79
98
  none: "No segments",
80
99
  allOtherUsers: "All other users",
81
100
  offDescription: "View the site as a real user (use cookies)",
@@ -104,6 +123,7 @@ var nl_default = {
104
123
  segment: "Segment",
105
124
  ABVariant: "A/B-variant",
106
125
  chooseSegment: "Kies segment",
126
+ searchSegments: "Zoek segmenten",
107
127
  none: "Geen segmenten",
108
128
  allOtherUsers: "Alle andere gebruikers",
109
129
  offDescription: "Bekijk de site als een echte gebruiker (gebruik cookies)",
@@ -908,7 +928,13 @@ function createToolbarStore(initial = {}) {
908
928
  }
909
929
 
910
930
  // src/core/toolbar-change-handler.ts
911
- var COOKIE_OPTS = { maxAge: ONE_YEAR_SECONDS, path: "/" };
931
+ function cookieOpts() {
932
+ return {
933
+ maxAge: ONE_YEAR_SECONDS,
934
+ path: "/",
935
+ ...crossSiteCookieOptions()
936
+ };
937
+ }
912
938
  function createChangeHandler(deps) {
913
939
  const { store, stega, syncAutoClean } = deps;
914
940
  function updateParam(name, value) {
@@ -925,9 +951,9 @@ function createChangeHandler(deps) {
925
951
  return function handleChange(before, after) {
926
952
  if (before.selectedSegment !== after.selectedSegment) {
927
953
  if (after.selectedSegment === null) {
928
- removeCookie(COOKIE_SEGMENT);
954
+ removeCookie(COOKIE_SEGMENT, "/", crossSiteCookieOptions());
929
955
  } else {
930
- setCookie(COOKIE_SEGMENT, after.selectedSegment, COOKIE_OPTS);
956
+ setCookie(COOKIE_SEGMENT, after.selectedSegment, cookieOpts());
931
957
  }
932
958
  updateParam(PARAM_SEGMENT, after.selectedSegment);
933
959
  sendPreprEvent("segment_changed", {
@@ -936,9 +962,9 @@ function createChangeHandler(deps) {
936
962
  }
937
963
  if (before.selectedVariant !== after.selectedVariant) {
938
964
  if (after.selectedVariant === null) {
939
- removeCookie(COOKIE_VARIANT);
965
+ removeCookie(COOKIE_VARIANT, "/", crossSiteCookieOptions());
940
966
  } else {
941
- setCookie(COOKIE_VARIANT, after.selectedVariant, COOKIE_OPTS);
967
+ setCookie(COOKIE_VARIANT, after.selectedVariant, cookieOpts());
942
968
  }
943
969
  updateParam(PARAM_VARIANT, after.selectedVariant);
944
970
  sendPreprEvent("variant_changed", {
@@ -964,14 +990,23 @@ function createChangeHandler(deps) {
964
990
  if (Object.keys(coupled).length > 0) {
965
991
  store.set(coupled);
966
992
  }
967
- setCookie(COOKIE_PREVIEW_MODE, String(after.previewMode), COOKIE_OPTS);
968
- setCookie(COOKIE_TOOLBAR_OPEN, "false", COOKIE_OPTS);
993
+ setCookie(COOKIE_PREVIEW_MODE, String(after.previewMode), cookieOpts());
994
+ setCookie(COOKIE_TOOLBAR_OPEN, "false", cookieOpts());
969
995
  sendPreprEvent("preview_mode_toggled", { previewMode: after.previewMode });
970
996
  syncAutoClean(after.previewMode);
971
- deps.reload();
997
+ const [path, existing] = splitPath(deps.currentPath());
998
+ const params = new URLSearchParams(existing);
999
+ if (params.has(PARAM_SEGMENT) || params.has(PARAM_VARIANT)) {
1000
+ params.delete(PARAM_SEGMENT);
1001
+ params.delete(PARAM_VARIANT);
1002
+ const query = params.toString();
1003
+ deps.navigate(query ? `${path}?${query}` : path);
1004
+ } else {
1005
+ deps.reload();
1006
+ }
972
1007
  }
973
1008
  if (before.toolbarOpen !== after.toolbarOpen) {
974
- setCookie(COOKIE_TOOLBAR_OPEN, String(after.toolbarOpen), COOKIE_OPTS);
1009
+ setCookie(COOKIE_TOOLBAR_OPEN, String(after.toolbarOpen), cookieOpts());
975
1010
  }
976
1011
  };
977
1012
  }
@@ -1263,7 +1298,7 @@ var CLOSE_ICON_SVG = `<svg width="10" height="10" viewBox="0 0 10 10" fill="none
1263
1298
  </svg>`;
1264
1299
 
1265
1300
  // src/core/ui/toolbar.generated.ts
1266
- var TOOLBAR_CSS = ":host{--prepr-primary:#4338ca;--prepr-bg:#eef2ff;--prepr-text:#1f2937;--prepr-radius:8px;--prepr-shadow:0px 0px 40px 0px #1f29373d;--prepr-z-index:10000;--prepr-primary-50:#eef2ff;--prepr-primary-100:#e0e7ff;--prepr-primary-800:#3730a3;--prepr-indigo-600:#4f46e5;--prepr-indigo-50:#eef2ff;--prepr-indigo-700:#4338ca;--prepr-secondary-400:#fb923c;--prepr-secondary-500:#f97316;--prepr-gray-100:#f3f4f6;--prepr-gray-200:#e5e7eb;--prepr-gray-300:#d1d5db;--prepr-gray-400:#9ca3af;--prepr-gray-500:#6b7280;--prepr-gray-700:#374151;--prepr-gray-800:#1f2937;--prepr-gray-900:#111827;--prepr-shadow-sm:0px 0px 12px 0px #c3c3c3cc;color:var(--prepr-text);box-sizing:border-box;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica,Arial,sans-serif;font-size:14px;line-height:1.5}:host *,:host :before,:host :after,*,:before,:after{box-sizing:border-box}button{font-family:inherit;font-size:inherit;margin:0}.prepr-regular-text{font-size:.875rem;font-weight:500;line-height:1.5}.prepr-backdrop{z-index:calc(var(--prepr-z-index) - 1);opacity:0;pointer-events:none;background:#0000001a;transition:opacity .2s ease-in-out;position:fixed;top:0;bottom:0;left:0;right:0}.prepr-backdrop[data-open=true]{opacity:1;pointer-events:auto;animation:.2s ease-in-out prepr-fade-in}.prepr-container{z-index:var(--prepr-z-index);justify-content:flex-end;align-items:center;display:flex;position:fixed;top:calc(50% - 64px);right:0}.prepr-toggle-holder{padding:.5rem}.prepr-toggle{cursor:pointer;background:var(--prepr-primary);color:#fff;border:none;border-radius:9999px;justify-content:center;align-items:center;width:2.25rem;height:2.25rem;display:flex}.prepr-toggle svg{color:#fff}.prepr-panel{z-index:var(--prepr-z-index);opacity:0;pointer-events:none;justify-content:flex-end;padding:.75rem;transition:opacity .2s ease-in-out;display:flex;position:fixed;top:50%;right:0;transform:translateY(-50%)}.prepr-panel[data-open=true]{opacity:1;pointer-events:auto;animation:.2s ease-in-out prepr-fade-in}.prepr-content{box-shadow:var(--prepr-shadow);border-radius:var(--prepr-radius);background:var(--prepr-bg);flex-direction:column;gap:2.5rem;width:100%;padding:1.5rem;display:flex}@media (min-width:640px){.prepr-panel{margin-right:4rem;padding:0}.prepr-content{width:502px;padding:2.5rem}}.prepr-header{justify-content:space-between;align-items:center;gap:.5rem;display:flex}.prepr-header-left{align-items:flex-start;gap:.75rem;display:flex}.prepr-badge{background:var(--prepr-primary-100);height:1.5rem;color:var(--prepr-primary);border-radius:4px;align-items:center;padding:.25rem .75rem;font-size:.875rem;display:flex}.prepr-header-close{cursor:pointer;background:var(--prepr-primary-100);width:2rem;height:2rem;color:var(--prepr-gray-700);border:none;border-radius:6px;justify-content:center;align-items:center;display:flex}.prepr-section{flex-direction:column;gap:.5rem;display:flex}.prepr-section-label{color:var(--prepr-gray-400);font-size:.875rem}.prepr-row{flex-wrap:wrap;justify-content:space-between;align-items:center;gap:.5rem 1.5rem;display:flex}.prepr-row-title{color:var(--prepr-gray-800);margin:0;font-size:1rem;font-weight:600}.prepr-radiogroup{border-radius:var(--prepr-radius);border:1px solid var(--prepr-gray-300);background:#fff;align-items:center;gap:.25rem;height:2.5rem;padding:.25rem;display:flex}.prepr-radiogroup[data-disabled=true]{cursor:not-allowed;opacity:.5}.prepr-radiogroup[data-disabled=true] .prepr-radio{pointer-events:none}.prepr-radio{cursor:pointer;white-space:nowrap;text-align:center;height:2rem;color:var(--prepr-gray-900);background:0 0;border:none;border-radius:6px;justify-content:center;align-items:center;padding:.5rem 1.125rem;font-size:.875rem;font-weight:500;transition:all .2s ease-in-out;display:flex}.prepr-radio[data-checked=true]{background:var(--prepr-indigo-600);color:#fff;box-shadow:var(--prepr-shadow-sm)}.prepr-radio[data-checked=true][data-off=true]{background:var(--prepr-gray-800);color:#fff}.prepr-radio-variant{width:82px}.prepr-listbox{position:relative}.prepr-segment-button{border-radius:var(--prepr-radius);border:1px solid var(--prepr-gray-300);width:240px;height:2.5rem;color:var(--prepr-gray-500);cursor:pointer;background:#fff;flex-shrink:0;align-items:center;gap:.5rem;padding:0 .5rem;font-size:.875rem;font-weight:500;display:flex;overflow:hidden}@media (min-width:768px){.prepr-segment-button{padding:0 1rem}}.prepr-segment-button:disabled{cursor:not-allowed;background:var(--prepr-gray-200);color:var(--prepr-gray-400)}.prepr-segment-button[aria-expanded=true]{border-bottom-color:#fff;border-bottom-right-radius:0;border-bottom-left-radius:0}.prepr-segment-label{white-space:nowrap;text-overflow:ellipsis;text-align:left;width:100%;margin-right:auto;overflow:hidden}.prepr-segment-caret{color:var(--prepr-gray-800);display:flex}.prepr-options{z-index:calc(var(--prepr-z-index) + 1);border-left:1px solid var(--prepr-gray-300);border-right:1px solid var(--prepr-gray-300);border-bottom:1px solid var(--prepr-gray-300);-ms-overflow-style:none;scrollbar-width:none;background:#fff;border-radius:0 0 6px 6px;width:240px;max-height:300px;margin:0;padding:0;list-style:none;position:absolute;top:100%;left:0;overflow-y:auto;box-shadow:0 20px 25px -5px #0000001a,0 8px 10px -6px #0000001a}.prepr-options::-webkit-scrollbar{display:none}.prepr-options[hidden]{display:none}.prepr-option{cursor:pointer;width:100%;color:var(--prepr-gray-900);background:#fff;align-items:center;padding:.5rem 1rem;font-size:.875rem;font-weight:500;display:flex}.prepr-option:hover{background:var(--prepr-gray-100)}.prepr-option[aria-selected=true]{background:var(--prepr-indigo-50);color:var(--prepr-indigo-700)}.prepr-option-label{white-space:nowrap;text-overflow:ellipsis;text-align:left;width:100%;margin-right:auto;overflow:hidden}.prepr-reset{background:var(--prepr-secondary-400);color:#fff;cursor:pointer;border:none;border-radius:6px;justify-content:center;align-items:center;gap:.5rem;width:100%;height:2.5rem;padding:.5rem .75rem;font-size:.875rem;font-weight:500;display:flex}.prepr-reset:hover:not(:disabled){background:var(--prepr-secondary-500)}.prepr-reset:disabled{background:var(--prepr-gray-400);color:var(--prepr-gray-500);cursor:not-allowed}@media (min-width:768px){.prepr-reset{width:108px}}.prepr-indicators{z-index:var(--prepr-z-index);gap:.75rem;display:flex;position:fixed;bottom:1.5rem;right:1.5rem}.prepr-status-pill{background:var(--prepr-primary);color:#fff;cursor:pointer;border:none;border-radius:9999px;align-items:center;gap:.5rem;padding:.5rem 1rem;font-size:.75rem;font-weight:500;transition:background-color .15s;display:flex;box-shadow:0 10px 15px -3px #0000001a,0 4px 6px -4px #0000001a}.prepr-status-pill:hover{background:var(--prepr-primary-800)}.prepr-status-pill[hidden]{display:none}.prepr-status-viewing{color:#fff9;font-size:10px}.prepr-status-segment{text-overflow:ellipsis;white-space:nowrap;max-width:120px;display:inline-block;overflow:hidden}.prepr-status-variant{text-overflow:ellipsis;white-space:nowrap;background:#fff3;border-radius:4px;max-width:80px;padding:0 .5rem;display:inline-block;overflow:hidden}.prepr-status-x{color:#fff;width:.75rem;height:.75rem}.prepr-close-edit-pill{background:var(--prepr-primary-50);color:var(--prepr-gray-800);cursor:pointer;border:none;border-radius:9999px;align-items:center;gap:.5rem;padding:.5rem 1rem;font-size:.75rem;font-weight:500;transition:background-color .15s;display:flex;box-shadow:0 10px 15px -3px #0000001a,0 4px 6px -4px #0000001a}.prepr-close-edit-pill:hover{background:var(--prepr-primary-100)}.prepr-close-edit-pill[hidden]{display:none}.prepr-close-edit-x{width:1rem;height:1rem;color:var(--prepr-gray-500);transition:color .15s}.prepr-close-edit-pill:hover .prepr-close-edit-x{color:var(--prepr-gray-700)}.prepr-tip{z-index:calc(var(--prepr-z-index) + 2);overflow-wrap:break-word;background:var(--prepr-gray-900);color:#fff;pointer-events:none;border-radius:6px;width:auto;max-width:min(420px,100vw - 16px);padding:.5rem .75rem;font-size:.75rem;font-weight:500;position:fixed;box-shadow:0 20px 25px -5px #0000001a,0 8px 10px -6px #0000001a}.prepr-tip-arrow{border-left:6px solid #0000;border-right:6px solid #0000;border-top:6px solid var(--prepr-gray-900);width:0;height:0;position:absolute;top:100%;transform:translate(-50%)}[hidden]{display:none!important}@keyframes prepr-fade-in{0%{opacity:0}to{opacity:1}}";
1301
+ var TOOLBAR_CSS = ":host{--prepr-primary:#4338ca;--prepr-bg:#eef2ff;--prepr-text:#1f2937;--prepr-radius:8px;--prepr-shadow:0px 0px 40px 0px #1f29373d;--prepr-z-index:10000;--prepr-primary-50:#eef2ff;--prepr-primary-100:#e0e7ff;--prepr-primary-800:#3730a3;--prepr-indigo-600:#4f46e5;--prepr-indigo-50:#eef2ff;--prepr-indigo-700:#4338ca;--prepr-secondary-400:#fb923c;--prepr-secondary-500:#f97316;--prepr-gray-100:#f3f4f6;--prepr-gray-200:#e5e7eb;--prepr-gray-300:#d1d5db;--prepr-gray-400:#9ca3af;--prepr-gray-500:#6b7280;--prepr-gray-700:#374151;--prepr-gray-800:#1f2937;--prepr-gray-900:#111827;--prepr-shadow-sm:0px 0px 12px 0px #c3c3c3cc;color:var(--prepr-text);box-sizing:border-box;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica,Arial,sans-serif;font-size:14px;line-height:1.5}:host *,:host :before,:host :after,*,:before,:after{box-sizing:border-box}button{font-family:inherit;font-size:inherit;margin:0}.prepr-regular-text{font-size:.875rem;font-weight:500;line-height:1.5}.prepr-backdrop{z-index:calc(var(--prepr-z-index) - 1);opacity:0;pointer-events:none;background:#0000001a;transition:opacity .2s ease-in-out;position:fixed;top:0;bottom:0;left:0;right:0}.prepr-backdrop[data-open=true]{opacity:1;pointer-events:auto;animation:.2s ease-in-out prepr-fade-in}.prepr-container{z-index:var(--prepr-z-index);justify-content:flex-end;align-items:center;display:flex;position:fixed;top:calc(50% - 64px);right:0}.prepr-toggle-holder{padding:.5rem}.prepr-toggle{cursor:pointer;background:var(--prepr-primary);color:#fff;border:none;border-radius:9999px;justify-content:center;align-items:center;width:2.25rem;height:2.25rem;display:flex}.prepr-toggle svg{color:#fff}.prepr-panel{z-index:var(--prepr-z-index);opacity:0;pointer-events:none;justify-content:flex-end;padding:.75rem;transition:opacity .2s ease-in-out;display:flex;position:fixed;top:50%;right:0;transform:translateY(-50%)}.prepr-panel[data-open=true]{opacity:1;pointer-events:auto;animation:.2s ease-in-out prepr-fade-in}.prepr-content{box-shadow:var(--prepr-shadow);border-radius:var(--prepr-radius);background:var(--prepr-bg);flex-direction:column;gap:2.5rem;width:100%;padding:1.5rem;display:flex}@media (min-width:640px){.prepr-panel{margin-right:4rem;padding:0}.prepr-content{width:502px;padding:2.5rem}}.prepr-header{justify-content:space-between;align-items:center;gap:.5rem;display:flex}.prepr-header-left{align-items:flex-start;gap:.75rem;display:flex}.prepr-badge{background:var(--prepr-primary-100);height:1.5rem;color:var(--prepr-primary);border-radius:4px;align-items:center;padding:.25rem .75rem;font-size:.875rem;display:flex}.prepr-header-close{cursor:pointer;background:var(--prepr-primary-100);width:2rem;height:2rem;color:var(--prepr-gray-700);border:none;border-radius:6px;justify-content:center;align-items:center;display:flex}.prepr-section{flex-direction:column;gap:.5rem;display:flex}.prepr-section-label{color:var(--prepr-gray-400);font-size:.875rem}.prepr-row{flex-wrap:wrap;justify-content:space-between;align-items:center;gap:.5rem 1.5rem;display:flex}.prepr-row-title{color:var(--prepr-gray-800);margin:0;font-size:1rem;font-weight:600}.prepr-radiogroup{border-radius:var(--prepr-radius);border:1px solid var(--prepr-gray-300);background:#fff;align-items:center;gap:.25rem;height:2.5rem;padding:.25rem;display:flex}.prepr-radiogroup[data-disabled=true]{cursor:not-allowed;opacity:.5}.prepr-radiogroup[data-disabled=true] .prepr-radio{pointer-events:none}.prepr-radio{cursor:pointer;white-space:nowrap;text-align:center;height:2rem;color:var(--prepr-gray-900);background:0 0;border:none;border-radius:6px;justify-content:center;align-items:center;padding:.5rem 1.125rem;font-size:.875rem;font-weight:500;transition:all .2s ease-in-out;display:flex}.prepr-radio[data-checked=true]{background:var(--prepr-indigo-600);color:#fff;box-shadow:var(--prepr-shadow-sm)}.prepr-radio[data-checked=true][data-off=true]{background:var(--prepr-gray-800);color:#fff}.prepr-radio-variant{width:82px}.prepr-listbox{position:relative}.prepr-segment-button{border-radius:var(--prepr-radius);border:1px solid var(--prepr-gray-300);width:240px;height:2.5rem;color:var(--prepr-gray-500);cursor:pointer;background:#fff;flex-shrink:0;align-items:center;gap:.5rem;padding:0 .5rem;font-size:.875rem;font-weight:500;display:flex;overflow:hidden}@media (min-width:768px){.prepr-segment-button{padding:0 1rem}}.prepr-segment-button:disabled{cursor:not-allowed;background:var(--prepr-gray-200);color:var(--prepr-gray-400)}.prepr-segment-button[aria-expanded=true]{border-bottom-color:#fff;border-bottom-right-radius:0;border-bottom-left-radius:0}.prepr-segment-label{white-space:nowrap;text-overflow:ellipsis;text-align:left;width:100%;margin-right:auto;overflow:hidden}.prepr-segment-caret{color:var(--prepr-gray-800);display:flex}.prepr-options{z-index:calc(var(--prepr-z-index) + 1);border-left:1px solid var(--prepr-gray-300);border-right:1px solid var(--prepr-gray-300);border-bottom:1px solid var(--prepr-gray-300);-ms-overflow-style:none;scrollbar-width:none;background:#fff;border-radius:0 0 6px 6px;width:240px;max-height:300px;margin:0;padding:0;list-style:none;position:absolute;top:100%;left:0;overflow-y:auto;box-shadow:0 20px 25px -5px #0000001a,0 8px 10px -6px #0000001a}.prepr-options::-webkit-scrollbar{display:none}.prepr-options[hidden]{display:none}.prepr-option-search{background:#fff;padding:.5rem;position:-webkit-sticky;position:sticky;top:0}.prepr-segment-search{border:1px solid var(--prepr-gray-300);border-radius:var(--prepr-radius);width:100%;height:2rem;font:inherit;color:var(--prepr-gray-900);box-sizing:border-box;background:#fff;padding:0 .5rem;font-size:.875rem}.prepr-segment-search::placeholder{color:var(--prepr-gray-400)}.prepr-segment-search:focus{border-color:var(--prepr-gray-400);outline:none}.prepr-option{cursor:pointer;width:100%;color:var(--prepr-gray-900);background:#fff;align-items:center;padding:.5rem 1rem;font-size:.875rem;font-weight:500;display:flex}.prepr-option:hover{background:var(--prepr-gray-100)}.prepr-option[aria-selected=true]{background:var(--prepr-indigo-50);color:var(--prepr-indigo-700)}.prepr-option-label{white-space:nowrap;text-overflow:ellipsis;text-align:left;width:100%;margin-right:auto;overflow:hidden}.prepr-reset{background:var(--prepr-secondary-400);color:#fff;cursor:pointer;border:none;border-radius:6px;justify-content:center;align-items:center;gap:.5rem;width:100%;height:2.5rem;padding:.5rem .75rem;font-size:.875rem;font-weight:500;display:flex}.prepr-reset:hover:not(:disabled){background:var(--prepr-secondary-500)}.prepr-reset:disabled{background:var(--prepr-gray-400);color:var(--prepr-gray-500);cursor:not-allowed}@media (min-width:768px){.prepr-reset{width:108px}}.prepr-indicators{z-index:var(--prepr-z-index);gap:.75rem;display:flex;position:fixed;bottom:1.5rem;right:1.5rem}.prepr-status-pill{background:var(--prepr-primary);color:#fff;cursor:pointer;border:none;border-radius:9999px;align-items:center;gap:.5rem;padding:.5rem 1rem;font-size:.75rem;font-weight:500;transition:background-color .15s;display:flex;box-shadow:0 10px 15px -3px #0000001a,0 4px 6px -4px #0000001a}.prepr-status-pill:hover{background:var(--prepr-primary-800)}.prepr-status-pill[hidden]{display:none}.prepr-status-viewing{color:#fff9;font-size:10px}.prepr-status-segment{text-overflow:ellipsis;white-space:nowrap;max-width:120px;display:inline-block;overflow:hidden}.prepr-status-variant{text-overflow:ellipsis;white-space:nowrap;background:#fff3;border-radius:4px;max-width:80px;padding:0 .5rem;display:inline-block;overflow:hidden}.prepr-status-x{color:#fff;width:.75rem;height:.75rem}.prepr-close-edit-pill{background:var(--prepr-primary-50);color:var(--prepr-gray-800);cursor:pointer;border:none;border-radius:9999px;align-items:center;gap:.5rem;padding:.5rem 1rem;font-size:.75rem;font-weight:500;transition:background-color .15s;display:flex;box-shadow:0 10px 15px -3px #0000001a,0 4px 6px -4px #0000001a}.prepr-close-edit-pill:hover{background:var(--prepr-primary-100)}.prepr-close-edit-pill[hidden]{display:none}.prepr-close-edit-x{width:1rem;height:1rem;color:var(--prepr-gray-500);transition:color .15s}.prepr-close-edit-pill:hover .prepr-close-edit-x{color:var(--prepr-gray-700)}.prepr-tip{z-index:calc(var(--prepr-z-index) + 2);overflow-wrap:break-word;background:var(--prepr-gray-900);color:#fff;pointer-events:none;border-radius:6px;width:auto;max-width:min(420px,100vw - 16px);padding:.5rem .75rem;font-size:.75rem;font-weight:500;position:fixed;box-shadow:0 20px 25px -5px #0000001a,0 8px 10px -6px #0000001a}.prepr-tip-arrow{border-left:6px solid #0000;border-right:6px solid #0000;border-top:6px solid var(--prepr-gray-900);width:0;height:0;position:absolute;top:100%;transform:translate(-50%)}[hidden]{display:none!important}@keyframes prepr-fade-in{0%{opacity:0}to{opacity:1}}";
1267
1302
 
1268
1303
  // ../../node_modules/.pnpm/preact@10.29.7/node_modules/preact/jsx-runtime/dist/jsxRuntime.mjs
1269
1304
  var f2 = 0;
@@ -1352,10 +1387,13 @@ function SegmentListbox({
1352
1387
  state,
1353
1388
  t: t3,
1354
1389
  listboxOpen,
1390
+ segmentFilter,
1355
1391
  handlers
1356
1392
  }) {
1357
1393
  const segments = state.segments;
1358
1394
  const hasSegments = segments.length > 0;
1395
+ const filter = segmentFilter.trim().toLowerCase();
1396
+ const visibleSegments = filter ? segments.filter((s2) => s2.name.toLowerCase().includes(filter)) : segments;
1359
1397
  let label;
1360
1398
  if (!hasSegments) {
1361
1399
  label = t3("adaptiveContent.none");
@@ -1392,15 +1430,30 @@ function SegmentListbox({
1392
1430
  role: "listbox",
1393
1431
  hidden: !listboxOpen,
1394
1432
  onKeyDown: (e2) => handlers.onOptionsKeydown(e2),
1395
- children: segments.map((seg) => /* @__PURE__ */ u2(
1396
- SegmentOption,
1397
- {
1398
- seg,
1399
- selected: seg._id === state.selectedSegment,
1400
- onChoose: handlers.onChooseSegment
1401
- },
1402
- seg._id
1403
- ))
1433
+ children: [
1434
+ /* @__PURE__ */ u2("li", { class: "prepr-option-search", role: "none", children: /* @__PURE__ */ u2(
1435
+ "input",
1436
+ {
1437
+ type: "text",
1438
+ class: "prepr-segment-search",
1439
+ "data-prepr": "segment-search",
1440
+ placeholder: t3("adaptiveContent.searchSegments"),
1441
+ value: segmentFilter,
1442
+ onInput: (e2) => handlers.onSegmentFilterInput(
1443
+ e2.currentTarget.value
1444
+ )
1445
+ }
1446
+ ) }),
1447
+ visibleSegments.map((seg) => /* @__PURE__ */ u2(
1448
+ SegmentOption,
1449
+ {
1450
+ seg,
1451
+ selected: seg._id === state.selectedSegment,
1452
+ onChoose: handlers.onChooseSegment
1453
+ },
1454
+ seg._id
1455
+ ))
1456
+ ]
1404
1457
  }
1405
1458
  )
1406
1459
  ] });
@@ -1525,7 +1578,7 @@ function StatusPill({
1525
1578
  {
1526
1579
  class: "prepr-status-x",
1527
1580
  "data-prepr": "status-x",
1528
- hidden: state.selectedSegment === null,
1581
+ hidden: !state.previewMode || state.selectedSegment === null,
1529
1582
  children: /* @__PURE__ */ u2(RawSvg, { svg: XMARK_ICON_SVG })
1530
1583
  }
1531
1584
  )
@@ -1554,7 +1607,13 @@ function CloseEditPill({
1554
1607
  }
1555
1608
  );
1556
1609
  }
1557
- function Panel({ state, t: t3, listboxOpen, handlers }) {
1610
+ function Panel({
1611
+ state,
1612
+ t: t3,
1613
+ listboxOpen,
1614
+ segmentFilter,
1615
+ handlers
1616
+ }) {
1558
1617
  const hasPersonalization = state.selectedSegment !== null || state.selectedVariant !== null;
1559
1618
  return /* @__PURE__ */ u2(S, { children: [
1560
1619
  /* @__PURE__ */ u2(
@@ -1611,6 +1670,7 @@ function Panel({ state, t: t3, listboxOpen, handlers }) {
1611
1670
  state,
1612
1671
  t: t3,
1613
1672
  listboxOpen,
1673
+ segmentFilter,
1614
1674
  handlers
1615
1675
  }
1616
1676
  )
@@ -1668,6 +1728,7 @@ var PreprToolbarElement = class extends HTMLElementBase {
1668
1728
  this.t = (key) => key;
1669
1729
  this.unsubscribe = null;
1670
1730
  this.listboxOpen = false;
1731
+ this.segmentFilter = "";
1671
1732
  this.handlers = {
1672
1733
  onToggle: () => this.set({ toolbarOpen: !this.state.toolbarOpen }),
1673
1734
  onClose: () => this.set({ toolbarOpen: false }),
@@ -1698,6 +1759,10 @@ var PreprToolbarElement = class extends HTMLElementBase {
1698
1759
  onSegmentButtonKeydown: (e2) => this.onListboxKeydown(e2),
1699
1760
  onOptionsKeydown: (e2) => this.onListboxKeydown(e2),
1700
1761
  onChooseSegment: (id) => this.chooseSegment(id),
1762
+ onSegmentFilterInput: (value) => {
1763
+ this.segmentFilter = value;
1764
+ this.renderPanel(this.state);
1765
+ },
1701
1766
  onPreviewTooltipEnter: (el) => this.showTooltip(el),
1702
1767
  onPreviewTooltipLeave: () => this.hideTooltip()
1703
1768
  };
@@ -1746,6 +1811,7 @@ var PreprToolbarElement = class extends HTMLElementBase {
1746
1811
  state,
1747
1812
  t: this.t,
1748
1813
  listboxOpen: this.listboxOpen,
1814
+ segmentFilter: this.segmentFilter,
1749
1815
  handlers: this.handlers
1750
1816
  }),
1751
1817
  root
@@ -1811,6 +1877,8 @@ var PreprToolbarElement = class extends HTMLElementBase {
1811
1877
  onListboxKeydown(event) {
1812
1878
  const e2 = event;
1813
1879
  const options = this.optionEls();
1880
+ const inSearch = e2.target?.getAttribute?.("data-prepr") === "segment-search";
1881
+ if (inSearch && e2.key === " ") return;
1814
1882
  if (options.length === 0 && e2.key !== "Escape") return;
1815
1883
  switch (e2.key) {
1816
1884
  case "Enter":
@@ -1872,6 +1940,7 @@ var PreprToolbarElement = class extends HTMLElementBase {
1872
1940
  const button = this.segmentButton();
1873
1941
  if (button?.disabled) return;
1874
1942
  this.listboxOpen = open;
1943
+ this.segmentFilter = "";
1875
1944
  this.renderPanel(this.state);
1876
1945
  if (open) {
1877
1946
  const options = this.optionEls();
@@ -1882,11 +1951,17 @@ var PreprToolbarElement = class extends HTMLElementBase {
1882
1951
  options.forEach(
1883
1952
  (el, i2) => el.setAttribute("data-active", String(i2 === activeIndex))
1884
1953
  );
1885
- options[activeIndex]?.focus();
1954
+ this.searchInput()?.focus();
1886
1955
  }
1887
1956
  }
1957
+ searchInput() {
1958
+ return this.shadowRoot?.querySelector(
1959
+ '[data-prepr="segment-search"]'
1960
+ ) ?? null;
1961
+ }
1888
1962
  chooseSegment(id) {
1889
1963
  this.listboxOpen = false;
1964
+ this.segmentFilter = "";
1890
1965
  this.set({ selectedSegment: id });
1891
1966
  this.renderPanel(this.state);
1892
1967
  this.segmentButton()?.focus();
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  createPreprToolbar,
4
4
  loadTrackingPixel
5
- } from "../chunk-H7HVQSSF.js";
5
+ } from "../chunk-3FOY6KL4.js";
6
6
 
7
7
  // src/nextjs/components.ts
8
8
  import { usePathname, useRouter } from "next/navigation";
@@ -38,7 +38,7 @@ module.exports = __toCommonJS(nextjs_exports);
38
38
  var import_server = require("next/server");
39
39
 
40
40
  // src/version.ts
41
- var VERSION = "0.1.0-beta.1";
41
+ var VERSION = "0.1.0-beta.4";
42
42
 
43
43
  // src/core/constants.ts
44
44
  var COOKIE_PREVIEW_MODE = "Prepr-Preview-Mode";
@@ -77,7 +77,11 @@ function processPreprRequest(request, opts) {
77
77
  const requestHeaders = new Headers(request.headers);
78
78
  const responseCookies = [];
79
79
  const requestCookies = parseCookies(request);
80
- const searchParams = new URL(request.url).searchParams;
80
+ const url = new URL(request.url);
81
+ const searchParams = url.searchParams;
82
+ const forwardedProto = request.headers.get("x-forwarded-proto")?.split(",")[0]?.trim();
83
+ const isSecure = forwardedProto ? forwardedProto === "https" : url.protocol === "https:";
84
+ const crossSite = isSecure ? { sameSite: "None", secure: true } : {};
81
85
  for (const key of UTM_PARAMS) {
82
86
  const value = searchParams.get(key);
83
87
  if (value !== null) {
@@ -126,6 +130,15 @@ function processPreprRequest(request, opts) {
126
130
  }
127
131
  requestHeaders.set("Prepr-Preview-Bar", "true");
128
132
  const isLivePreview = searchParams.get(PARAM_HIDE_BAR) === "true";
133
+ if (!isLivePreview && !requestCookies.has(COOKIE_PREVIEW_MODE)) {
134
+ responseCookies.push({
135
+ name: COOKIE_PREVIEW_MODE,
136
+ value: "true",
137
+ maxAge: ONE_YEAR_SECONDS,
138
+ path: "/",
139
+ ...crossSite
140
+ });
141
+ }
129
142
  if (!isLivePreview) {
130
143
  const segmentCookie = requestCookies.get(COOKIE_SEGMENT);
131
144
  if (segmentCookie) {
@@ -144,7 +157,8 @@ function processPreprRequest(request, opts) {
144
157
  name: COOKIE_VARIANT,
145
158
  value: previewAb,
146
159
  maxAge: ONE_YEAR_SECONDS,
147
- path: "/"
160
+ path: "/",
161
+ ...crossSite
148
162
  });
149
163
  }
150
164
  }
@@ -156,7 +170,8 @@ function processPreprRequest(request, opts) {
156
170
  name: COOKIE_SEGMENT,
157
171
  value: previewSegment,
158
172
  maxAge: ONE_YEAR_SECONDS,
159
- path: "/"
173
+ path: "/",
174
+ ...crossSite
160
175
  });
161
176
  }
162
177
  }
@@ -183,7 +198,10 @@ function createPreprMiddleware(request, responseOrOptions, maybeOptions) {
183
198
  for (const cookie of responseCookies) {
184
199
  response.cookies.set(cookie.name, cookie.value, {
185
200
  maxAge: cookie.maxAge,
186
- path: cookie.path
201
+ path: cookie.path,
202
+ // Lower-cased: Next's cookie API expects 'none' | 'lax' | 'strict'.
203
+ ...cookie.sameSite ? { sameSite: cookie.sameSite.toLowerCase() } : {},
204
+ ...cookie.secure ? { secure: true } : {}
187
205
  });
188
206
  }
189
207
  return response;
@@ -2,7 +2,7 @@
2
2
  import { NextResponse } from "next/server";
3
3
 
4
4
  // src/version.ts
5
- var VERSION = "0.1.0-beta.1";
5
+ var VERSION = "0.1.0-beta.4";
6
6
 
7
7
  // src/core/constants.ts
8
8
  var COOKIE_PREVIEW_MODE = "Prepr-Preview-Mode";
@@ -41,7 +41,11 @@ function processPreprRequest(request, opts) {
41
41
  const requestHeaders = new Headers(request.headers);
42
42
  const responseCookies = [];
43
43
  const requestCookies = parseCookies(request);
44
- const searchParams = new URL(request.url).searchParams;
44
+ const url = new URL(request.url);
45
+ const searchParams = url.searchParams;
46
+ const forwardedProto = request.headers.get("x-forwarded-proto")?.split(",")[0]?.trim();
47
+ const isSecure = forwardedProto ? forwardedProto === "https" : url.protocol === "https:";
48
+ const crossSite = isSecure ? { sameSite: "None", secure: true } : {};
45
49
  for (const key of UTM_PARAMS) {
46
50
  const value = searchParams.get(key);
47
51
  if (value !== null) {
@@ -90,6 +94,15 @@ function processPreprRequest(request, opts) {
90
94
  }
91
95
  requestHeaders.set("Prepr-Preview-Bar", "true");
92
96
  const isLivePreview = searchParams.get(PARAM_HIDE_BAR) === "true";
97
+ if (!isLivePreview && !requestCookies.has(COOKIE_PREVIEW_MODE)) {
98
+ responseCookies.push({
99
+ name: COOKIE_PREVIEW_MODE,
100
+ value: "true",
101
+ maxAge: ONE_YEAR_SECONDS,
102
+ path: "/",
103
+ ...crossSite
104
+ });
105
+ }
93
106
  if (!isLivePreview) {
94
107
  const segmentCookie = requestCookies.get(COOKIE_SEGMENT);
95
108
  if (segmentCookie) {
@@ -108,7 +121,8 @@ function processPreprRequest(request, opts) {
108
121
  name: COOKIE_VARIANT,
109
122
  value: previewAb,
110
123
  maxAge: ONE_YEAR_SECONDS,
111
- path: "/"
124
+ path: "/",
125
+ ...crossSite
112
126
  });
113
127
  }
114
128
  }
@@ -120,7 +134,8 @@ function processPreprRequest(request, opts) {
120
134
  name: COOKIE_SEGMENT,
121
135
  value: previewSegment,
122
136
  maxAge: ONE_YEAR_SECONDS,
123
- path: "/"
137
+ path: "/",
138
+ ...crossSite
124
139
  });
125
140
  }
126
141
  }
@@ -147,7 +162,10 @@ function createPreprMiddleware(request, responseOrOptions, maybeOptions) {
147
162
  for (const cookie of responseCookies) {
148
163
  response.cookies.set(cookie.name, cookie.value, {
149
164
  maxAge: cookie.maxAge,
150
- path: cookie.path
165
+ path: cookie.path,
166
+ // Lower-cased: Next's cookie API expects 'none' | 'lax' | 'strict'.
167
+ ...cookie.sameSite ? { sameSite: cookie.sameSite.toLowerCase() } : {},
168
+ ...cookie.secure ? { secure: true } : {}
151
169
  });
152
170
  }
153
171
  return response;