@preprio/toolkit 0.3.2 → 0.3.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.
package/dist/index.d.cts CHANGED
@@ -1,11 +1,11 @@
1
- import { P as PreprFeatures, R as ResolvedPreprFeatures, L as Locale, a as PreprSegment, b as PreprVariant, c as PreprToolbarProps, d as PreprPreviewOptions, e as PreprErrorCode, f as PreprHeaders } from './pixel-Dd72wuJp.cjs';
2
- export { g as PreprEnvironment, h as PreprEventType, i as PreprFeatureConfig, j as PreprHeaderName, k as PreprPixelConfig, l as PreprToolbarComponentProps, m as PreprToolbarOptions, n as loadTrackingPixel, s as setTrackingParam, t as trackEvent } from './pixel-Dd72wuJp.cjs';
1
+ import { P as PreprFeatures, R as ResolvedPreprFeatures, L as Locale, a as PreprSegment, b as PreprVariant, c as PreprToolbarProps, d as PreprPreviewOptions, e as PreprErrorCode, f as PreprHeaders } from './pixel-B6FtY-11.cjs';
2
+ export { g as PreprEnvironment, h as PreprEventType, i as PreprFeatureConfig, j as PreprHeaderName, k as PreprPixelConfig, l as PreprToolbarComponentProps, m as PreprToolbarOptions, n as loadTrackingPixel, s as setTrackingParam, t as trackEvent } from './pixel-B6FtY-11.cjs';
3
3
 
4
4
  /**
5
5
  * Package version; must match package.json. Lives in its own leaf module so
6
6
  * core can import it without cycling through the barrel.
7
7
  */
8
- declare const VERSION = "0.3.2";
8
+ declare const VERSION = "0.3.4";
9
9
 
10
10
  /**
11
11
  * Resolve a `PreprFeatures` bag to plain booleans, defaulting every omitted key
package/dist/index.d.ts CHANGED
@@ -1,11 +1,11 @@
1
- import { P as PreprFeatures, R as ResolvedPreprFeatures, L as Locale, a as PreprSegment, b as PreprVariant, c as PreprToolbarProps, d as PreprPreviewOptions, e as PreprErrorCode, f as PreprHeaders } from './pixel-Dd72wuJp.js';
2
- export { g as PreprEnvironment, h as PreprEventType, i as PreprFeatureConfig, j as PreprHeaderName, k as PreprPixelConfig, l as PreprToolbarComponentProps, m as PreprToolbarOptions, n as loadTrackingPixel, s as setTrackingParam, t as trackEvent } from './pixel-Dd72wuJp.js';
1
+ import { P as PreprFeatures, R as ResolvedPreprFeatures, L as Locale, a as PreprSegment, b as PreprVariant, c as PreprToolbarProps, d as PreprPreviewOptions, e as PreprErrorCode, f as PreprHeaders } from './pixel-B6FtY-11.js';
2
+ export { g as PreprEnvironment, h as PreprEventType, i as PreprFeatureConfig, j as PreprHeaderName, k as PreprPixelConfig, l as PreprToolbarComponentProps, m as PreprToolbarOptions, n as loadTrackingPixel, s as setTrackingParam, t as trackEvent } from './pixel-B6FtY-11.js';
3
3
 
4
4
  /**
5
5
  * Package version; must match package.json. Lives in its own leaf module so
6
6
  * core can import it without cycling through the barrel.
7
7
  */
8
- declare const VERSION = "0.3.2";
8
+ declare const VERSION = "0.3.4";
9
9
 
10
10
  /**
11
11
  * Resolve a `PreprFeatures` bag to plain booleans, defaulting every omitted key
package/dist/index.js CHANGED
@@ -17,10 +17,10 @@ import {
17
17
  setTrackingParam,
18
18
  stegaClean,
19
19
  trackEvent
20
- } from "./chunk-GIEOTQD4.js";
20
+ } from "./chunk-HXQ6JUZM.js";
21
21
 
22
22
  // src/version.ts
23
- var VERSION = "0.3.2";
23
+ var VERSION = "0.3.4";
24
24
 
25
25
  // src/core/server.ts
26
26
  var PreprError = class extends Error {
@@ -418,28 +418,45 @@ function tagEncodedElement(element, decoded) {
418
418
 
419
419
  // src/core/stega/auto-clean.ts
420
420
  var debug2 = createScopedLogger("stega:auto-clean");
421
- function createStegaAutoClean() {
421
+ function createStegaAutoClean(options) {
422
+ const stripText = options?.enabled ?? true;
422
423
  let observer = null;
423
424
  let processing = false;
424
425
  let cleaned = /* @__PURE__ */ new WeakMap();
426
+ let pendingHidden = /* @__PURE__ */ new Set();
427
+ let pendingDirty = /* @__PURE__ */ new Set();
425
428
  let debounceTimeout = null;
426
429
  function cleanTextNode(textNode) {
427
430
  if (isIgnoredTextNode(textNode)) return false;
428
431
  const textContent = textNode.textContent;
429
432
  const info = cleaned.get(textNode);
430
- if (info && textContent === info.cleaned) return false;
433
+ const settled = stripText ? info?.cleaned : info?.original;
434
+ if (info && textContent === settled) {
435
+ const shown = resolveEditTarget(textNode);
436
+ if (!shown) return false;
437
+ pendingHidden.delete(textNode);
438
+ if (shown.hasAttribute("data-prepr-encoded")) return false;
439
+ tagEncodedElement(shown, info.decoded);
440
+ return true;
441
+ }
431
442
  try {
432
443
  const { cleaned: stripped, encoded } = (0, import_stega2.vercelStegaSplit)(textContent);
433
444
  if (!encoded || stripped === textContent) return false;
434
445
  const decoded = decodeStega(textContent);
435
446
  if (!decoded?.href) return false;
436
- cleaned.set(textNode, { original: textContent, cleaned: stripped });
437
- textNode.textContent = stripped;
447
+ cleaned.set(textNode, {
448
+ original: textContent,
449
+ cleaned: stripped,
450
+ decoded
451
+ });
452
+ if (stripText) textNode.textContent = stripped;
438
453
  const target = resolveEditTarget(textNode);
439
454
  if (target) {
455
+ pendingHidden.delete(textNode);
440
456
  tagEncodedElement(target, decoded);
441
457
  return true;
442
458
  }
459
+ pendingHidden.add(textNode);
443
460
  } catch (error) {
444
461
  debug2.log("error cleaning text node", error);
445
462
  }
@@ -448,8 +465,10 @@ function createStegaAutoClean() {
448
465
  function scanAndClean() {
449
466
  processing = true;
450
467
  walkTextNodes(document.body, cleanTextNode);
451
- const title = (0, import_stega2.vercelStegaSplit)(document.title);
452
- if (title.encoded) document.title = title.cleaned;
468
+ if (stripText) {
469
+ const title = (0, import_stega2.vercelStegaSplit)(document.title);
470
+ if (title.encoded) document.title = title.cleaned;
471
+ }
453
472
  processing = false;
454
473
  }
455
474
  function collectAffected(mutations) {
@@ -474,15 +493,37 @@ function createStegaAutoClean() {
474
493
  });
475
494
  return affected;
476
495
  }
496
+ function retryPendingHidden() {
497
+ if (pendingHidden.size === 0) return;
498
+ processing = true;
499
+ [...pendingHidden].forEach((textNode) => {
500
+ if (!textNode.isConnected) {
501
+ pendingHidden.delete(textNode);
502
+ return;
503
+ }
504
+ cleanTextNode(textNode);
505
+ });
506
+ processing = false;
507
+ }
477
508
  function handleMutations(mutations) {
478
509
  if (processing) return;
479
510
  const affected = collectAffected(mutations);
480
- if (affected.size === 0) return;
511
+ if (affected.size === 0) {
512
+ retryPendingHidden();
513
+ return;
514
+ }
515
+ affected.forEach((textNode) => pendingDirty.add(textNode));
481
516
  if (debounceTimeout) clearTimeout(debounceTimeout);
482
517
  debounceTimeout = setTimeout(() => {
518
+ debounceTimeout = null;
483
519
  processing = true;
484
- affected.forEach((textNode) => cleanTextNode(textNode));
520
+ const batch = [...pendingDirty];
521
+ pendingDirty.clear();
522
+ batch.forEach((textNode) => {
523
+ if (textNode.isConnected) cleanTextNode(textNode);
524
+ });
485
525
  processing = false;
526
+ retryPendingHidden();
486
527
  }, 50);
487
528
  }
488
529
  function setupObserver() {
@@ -490,7 +531,11 @@ function createStegaAutoClean() {
490
531
  observer.observe(document.body, {
491
532
  childList: true,
492
533
  subtree: true,
493
- characterData: true
534
+ characterData: true,
535
+ // A dropdown opening only toggles a class or inline style; without these
536
+ // the nodes it reveals are never revisited and stay untagged.
537
+ attributes: true,
538
+ attributeFilter: ["class", "style", "hidden", "open", "aria-expanded"]
494
539
  });
495
540
  }
496
541
  function start() {
@@ -509,6 +554,8 @@ function createStegaAutoClean() {
509
554
  observer = null;
510
555
  }
511
556
  cleaned = /* @__PURE__ */ new WeakMap();
557
+ pendingHidden = /* @__PURE__ */ new Set();
558
+ pendingDirty = /* @__PURE__ */ new Set();
512
559
  debug2.log("stega auto-clean stopped");
513
560
  }
514
561
  return { start, stop };
@@ -577,8 +624,13 @@ var StegaElements = class {
577
624
  if (mutation.type === "characterData") {
578
625
  addedNodes.add(mutation.target);
579
626
  }
627
+ if (mutation.type === "attributes") {
628
+ addedNodes.add(mutation.target);
629
+ }
630
+ });
631
+ addedNodes.forEach((node) => {
632
+ if (node.isConnected) this.scanNode(node);
580
633
  });
581
- addedNodes.forEach((node) => this.scanNode(node));
582
634
  pending = [];
583
635
  this.elements = document.querySelectorAll("[data-prepr-encoded]");
584
636
  onUpdate?.();
@@ -591,7 +643,11 @@ var StegaElements = class {
591
643
  this.observer.observe(document.body, {
592
644
  childList: true,
593
645
  subtree: true,
594
- characterData: true
646
+ characterData: true,
647
+ // Reveal-on-class/style (dropdowns, accordions) changes no text and adds
648
+ // no nodes, but does change what is hoverable and needs a rescan.
649
+ attributes: true,
650
+ attributeFilter: ["class", "style", "hidden", "open", "aria-expanded"]
595
651
  });
596
652
  }
597
653
  /** Drops the active class but keeps the data attributes, unlike cleanup(). */
@@ -680,11 +736,13 @@ var StegaOverlay = class {
680
736
  const maxTop = window.scrollY + window.innerHeight - tooltip.clientHeight - 4;
681
737
  const minLeft = window.scrollX + 4;
682
738
  const maxLeft = window.scrollX + window.innerWidth - tooltip.clientWidth - 4;
683
- if (top < minTop) {
739
+ const below = top < minTop;
740
+ if (below) {
684
741
  top = rect.bottom + window.scrollY + 2;
685
742
  }
686
743
  top = Math.max(minTop, Math.min(top, maxTop));
687
744
  left = Math.max(minLeft, Math.min(left, maxLeft));
745
+ tooltip.dataset.preprPlacement = below ? "below" : "above";
688
746
  tooltip.style.top = `${top}px`;
689
747
  tooltip.style.left = `${left}px`;
690
748
  });
@@ -816,7 +874,7 @@ var StegaProximity = class {
816
874
  };
817
875
 
818
876
  // src/core/stega/stega.generated.ts
819
- var STEGA_STYLES = '[data-prepr-encoded]{position:relative}.prepr-overlay{pointer-events:none;z-index:10000;border:2px solid #4f46e5;border-radius:4px 0 4px 4px;transition:all .2s ease-in-out;position:absolute}.prepr-tooltip{color:#fff;white-space:nowrap;z-index:10001;text-align:center;pointer-events:auto;cursor:pointer;background-color:#4f46e5;border-radius:4px 4px 0 0;min-width:80px;padding:4px 8px;font-size:12px;line-height:1;transition:opacity .2s ease-in-out;position:absolute}.prepr-tooltip:hover{background-color:#4338ca}.prepr-proximity-highlight{z-index:1;position:relative}.prepr-proximity-highlight,.prepr-proximity-highlight *{overflow:visible!important}.prepr-proximity-highlight:before{content:"";pointer-events:none;background:radial-gradient(circle var(--gradient-size) at var(--cursor-x) var(--cursor-y), #4f46e526 0%, #2563eb00 70%);z-index:9999;border:2px solid #4f46e526;border-radius:4px;transition:all .2s;position:absolute;top:-2px;bottom:-2px;left:-4px;right:-4px;overflow:visible}';
877
+ var STEGA_STYLES = '[data-prepr-encoded]{position:relative}.prepr-overlay{pointer-events:none;z-index:10000;border:2px solid #4f46e5;border-radius:4px 0 4px 4px;transition:all .2s ease-in-out;position:absolute}.prepr-tooltip{color:#fff;white-space:nowrap;z-index:10001;text-align:center;pointer-events:auto;cursor:pointer;background-color:#4f46e5;border-radius:4px 4px 0 0;min-width:80px;padding:4px 8px;font-size:12px;line-height:1;transition:opacity .2s ease-in-out;position:absolute}.prepr-tooltip[data-prepr-placement=below]{border-radius:0 0 4px 4px}.prepr-tooltip:hover{background-color:#4338ca}.prepr-proximity-highlight{z-index:1;position:relative}.prepr-proximity-highlight,.prepr-proximity-highlight *{overflow:visible!important}.prepr-proximity-highlight:before{content:"";pointer-events:none;background:radial-gradient(circle var(--gradient-size) at var(--cursor-x) var(--cursor-y), #4f46e526 0%, #2563eb00 70%);z-index:9999;border:2px solid #4f46e526;border-radius:4px;transition:all .2s;position:absolute;top:-2px;bottom:-2px;left:-4px;right:-4px;overflow:visible}';
820
878
 
821
879
  // src/core/stega/styles.ts
822
880
  var STEGA_STYLE_MARKER = "data-prepr-stega";
@@ -1365,7 +1423,7 @@ var CLOSE_ICON_SVG = `<svg width="10" height="10" viewBox="0 0 10 10" fill="none
1365
1423
  </svg>`;
1366
1424
 
1367
1425
  // src/core/ui/toolbar.generated.ts
1368
- 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>span{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}}";
1426
+ 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>span{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[data-interactive=false]{cursor:default;opacity:1;color:#fff}.prepr-status-pill[data-interactive=true]: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}}";
1369
1427
 
1370
1428
  // ../../node_modules/.pnpm/preact@10.29.7/node_modules/preact/jsx-runtime/dist/jsxRuntime.mjs
1371
1429
  var f2 = 0;
@@ -1624,13 +1682,17 @@ function StatusPill({
1624
1682
  } else {
1625
1683
  segmentLabel = defaultSegmentName;
1626
1684
  }
1685
+ const dirty = features.segments && state.selectedSegment !== null || features.abTesting && state.selectedVariant === "B";
1686
+ const interactive = !state.previewMode || dirty;
1627
1687
  return /* @__PURE__ */ u2(
1628
1688
  "button",
1629
1689
  {
1630
1690
  type: "button",
1631
1691
  class: "prepr-status-pill",
1632
1692
  "data-prepr": "status-pill",
1693
+ "data-interactive": String(interactive),
1633
1694
  hidden: state.isIframe,
1695
+ disabled: !interactive,
1634
1696
  onClick: () => handlers.onStatusPill(),
1635
1697
  children: [
1636
1698
  /* @__PURE__ */ u2("span", { class: "prepr-status-viewing", "data-prepr": "status-viewing", children: t3("common.viewingAs") }),
@@ -1649,7 +1711,7 @@ function StatusPill({
1649
1711
  {
1650
1712
  class: "prepr-status-x",
1651
1713
  "data-prepr": "status-x",
1652
- hidden: !state.previewMode || !(features.segments && state.selectedSegment !== null || features.abTesting && state.selectedVariant === "B"),
1714
+ hidden: !state.previewMode || !dirty,
1653
1715
  children: /* @__PURE__ */ u2(RawSvg, { svg: XMARK_ICON_SVG })
1654
1716
  }
1655
1717
  )
@@ -2153,7 +2215,9 @@ function createPreprPreview(opts = {}) {
2153
2215
  }
2154
2216
  }
2155
2217
  });
2156
- const autoClean = createStegaAutoClean();
2218
+ const autoClean = createStegaAutoClean({
2219
+ enabled: options?.autoClean
2220
+ });
2157
2221
  autoClean.start();
2158
2222
  const handleChange = createChangeHandler({
2159
2223
  store,
@@ -2202,7 +2266,7 @@ function createPreprPreview(opts = {}) {
2202
2266
  var import_react = require("react");
2203
2267
 
2204
2268
  // src/core/pixel.ts
2205
- var PIXEL_SCRIPT_URL = "https://cdn.tracking.prepr.io/js/prepr-v2.min.js";
2269
+ var PIXEL_SCRIPT_URL = "https://cdn.tracking.prepr.io/js/prepr.min.js";
2206
2270
  var CACHE_BUST_INTERVAL_MS = 24 * 60 * 60 * 1e3;
2207
2271
  function loadTrackingPixel(trackingId, config) {
2208
2272
  if (typeof window === "undefined" || typeof document === "undefined") {
@@ -1,4 +1,4 @@
1
- import { k as PreprPixelConfig, l as PreprToolbarComponentProps } from '../pixel-Dd72wuJp.cjs';
1
+ import { k as PreprPixelConfig, l as PreprToolbarComponentProps } from '../pixel-B6FtY-11.cjs';
2
2
 
3
3
  interface PreprTrackingPixelProps {
4
4
  /** Prepr tracking/access token. */
@@ -1,4 +1,4 @@
1
- import { k as PreprPixelConfig, l as PreprToolbarComponentProps } from '../pixel-Dd72wuJp.js';
1
+ import { k as PreprPixelConfig, l as PreprToolbarComponentProps } from '../pixel-B6FtY-11.js';
2
2
 
3
3
  interface PreprTrackingPixelProps {
4
4
  /** Prepr tracking/access token. */
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  createPreprPreview,
4
4
  loadTrackingPixel
5
- } from "../chunk-GIEOTQD4.js";
5
+ } from "../chunk-HXQ6JUZM.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.3.2";
41
+ var VERSION = "0.3.4";
42
42
 
43
43
  // src/core/constants.ts
44
44
  var COOKIE_PREVIEW_MODE = "Prepr-Preview-Mode";
@@ -64,6 +64,20 @@ interface PreprPreviewOptions extends PreprToolbarOptions {
64
64
  * Intended for self-hosted editors; when set, the wildcard no longer applies.
65
65
  */
66
66
  allowedEditorOrigins?: string[];
67
+ /**
68
+ * Strip the invisible stega characters out of visible text at runtime.
69
+ * Default `true`.
70
+ *
71
+ * Preview content carries an encoded payload inside the text itself. Left in
72
+ * place it is invisible but real: it inflates `String.length`, breaks text
73
+ * measurement and truncation, and is announced by screen readers.
74
+ *
75
+ * Set `false` only when the site already strips the characters itself — for
76
+ * example by passing every field through `stegaClean` as it renders.
77
+ * Click-to-edit is unaffected either way: elements are still tagged from the
78
+ * payload, so the overlay keeps working.
79
+ */
80
+ autoClean?: boolean;
67
81
  }
68
82
  interface PreprToolbarProps {
69
83
  /**
@@ -64,6 +64,20 @@ interface PreprPreviewOptions extends PreprToolbarOptions {
64
64
  * Intended for self-hosted editors; when set, the wildcard no longer applies.
65
65
  */
66
66
  allowedEditorOrigins?: string[];
67
+ /**
68
+ * Strip the invisible stega characters out of visible text at runtime.
69
+ * Default `true`.
70
+ *
71
+ * Preview content carries an encoded payload inside the text itself. Left in
72
+ * place it is invisible but real: it inflates `String.length`, breaks text
73
+ * measurement and truncation, and is announced by screen readers.
74
+ *
75
+ * Set `false` only when the site already strips the characters itself — for
76
+ * example by passing every field through `stegaClean` as it renders.
77
+ * Click-to-edit is unaffected either way: elements are still tagged from the
78
+ * payload, so the overlay keeps working.
79
+ */
80
+ autoClean?: boolean;
67
81
  }
68
82
  interface PreprToolbarProps {
69
83
  /**
@@ -2,7 +2,7 @@
2
2
  import { NextResponse } from "next/server";
3
3
 
4
4
  // src/version.ts
5
- var VERSION = "0.3.2";
5
+ var VERSION = "0.3.4";
6
6
 
7
7
  // src/core/constants.ts
8
8
  var COOKIE_PREVIEW_MODE = "Prepr-Preview-Mode";
@@ -35,7 +35,7 @@ __export(nuxt_exports, {
35
35
  module.exports = __toCommonJS(nuxt_exports);
36
36
 
37
37
  // src/version.ts
38
- var VERSION = "0.3.2";
38
+ var VERSION = "0.3.4";
39
39
 
40
40
  // src/core/constants.ts
41
41
  var COOKIE_PREVIEW_MODE = "Prepr-Preview-Mode";
@@ -1,5 +1,5 @@
1
1
  // src/version.ts
2
- var VERSION = "0.3.2";
2
+ var VERSION = "0.3.4";
3
3
 
4
4
  // src/core/constants.ts
5
5
  var COOKIE_PREVIEW_MODE = "Prepr-Preview-Mode";
@@ -68,6 +68,20 @@ interface PreprPreviewOptions extends PreprToolbarOptions {
68
68
  * Intended for self-hosted editors; when set, the wildcard no longer applies.
69
69
  */
70
70
  allowedEditorOrigins?: string[];
71
+ /**
72
+ * Strip the invisible stega characters out of visible text at runtime.
73
+ * Default `true`.
74
+ *
75
+ * Preview content carries an encoded payload inside the text itself. Left in
76
+ * place it is invisible but real: it inflates `String.length`, breaks text
77
+ * measurement and truncation, and is announced by screen readers.
78
+ *
79
+ * Set `false` only when the site already strips the characters itself — for
80
+ * example by passing every field through `stegaClean` as it renders.
81
+ * Click-to-edit is unaffected either way: elements are still tagged from the
82
+ * payload, so the overlay keeps working.
83
+ */
84
+ autoClean?: boolean;
71
85
  }
72
86
  interface PreprToolbarProps {
73
87
  /**
@@ -68,6 +68,20 @@ interface PreprPreviewOptions extends PreprToolbarOptions {
68
68
  * Intended for self-hosted editors; when set, the wildcard no longer applies.
69
69
  */
70
70
  allowedEditorOrigins?: string[];
71
+ /**
72
+ * Strip the invisible stega characters out of visible text at runtime.
73
+ * Default `true`.
74
+ *
75
+ * Preview content carries an encoded payload inside the text itself. Left in
76
+ * place it is invisible but real: it inflates `String.length`, breaks text
77
+ * measurement and truncation, and is announced by screen readers.
78
+ *
79
+ * Set `false` only when the site already strips the characters itself — for
80
+ * example by passing every field through `stegaClean` as it renders.
81
+ * Click-to-edit is unaffected either way: elements are still tagged from the
82
+ * payload, so the overlay keeps working.
83
+ */
84
+ autoClean?: boolean;
71
85
  }
72
86
  interface PreprToolbarProps {
73
87
  /**