@takazudo/zdtp 0.4.9 → 0.4.11

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/README.md CHANGED
@@ -510,6 +510,7 @@ default instance only.
510
510
  | `tabs` | `readonly TabConfig[]` | **Required.** Tab strip data — each entry is a tab with one or more `TierConfig` objects. The color tab (id `'color'`) additionally requires `colorExtras`. See §6. |
511
511
  | `colorPresets` | `Record<string, ColorScheme>` (optional) | Optional named scheme presets surfaced in the Color tab "Scheme..." dropdown. Defaults to `{}`. See §7.5. |
512
512
  | `applySink` | `ApplySink` (optional) | Optional sink that routes this instance's CSS-var writes off `:root`. See §5.4. Not JSON-serializable — do not include in Astro inline config. |
513
+ | `autoRememberOnOpen` | `boolean` (optional) | Whether opening the panel (any of the auto-remember call sites — see §10.1) writes the `:autoload` flag with `'auto'` provenance. Defaults to `true`. Set `false` for a public site that wants a panel-open button visible to every visitor without arming owner-mode for whoever clicks it. `enableAutoload()`'s explicit `'1'` write is unaffected either way. See §10.1's Auto-remember footgun. |
513
514
 
514
515
  ### 5.4 `applySink` — optional write target
515
516
 
@@ -555,16 +556,27 @@ const handle = configurePanel({
555
556
  });
556
557
  ```
557
558
 
558
- ### 5.3 Mount strategy & auto-mount
559
+ ### 5.5 Mount strategy & auto-mount
559
560
 
560
561
  The Astro entry point (`<DesignTokenPanelHost>`) handles mounting for you. Internally:
561
562
 
562
563
  - The console API (`showDesignPanel` etc.) is **always installed eagerly**, even when the panel module has not loaded — calling them is what triggers the lazy import for cold-start users.
563
- - The panel module is **dynamically imported on first need**: when the user calls a console helper, OR when first-paint detects any of four gate signals in `localStorage` — `${storagePrefix}:visible` set to `1`, persisted overrides (checked as `${storagePrefix}-state-v4`, falling back to `-state-v3` / `-state-v2` for pre-migration sessions — see §9), the owner-autoload flag (`${storagePrefix}:autoload` set to `1`), or the element-path inspector enabled.
564
- - This gating keeps the panel out of the initial JS bundle for first-time visitors while still re-applying overrides on hard reload for users who have tweaked things. **General visitors** (none of the four signals set) pay zero bundle cost.
564
+ - The panel module is **dynamically imported on first need**: when the user calls a console helper, OR when first-paint detects any of these gate signals in `localStorage` — `${storagePrefix}:visible` set to `1` or its `${storagePrefix}-open` mirror set to `1`, persisted overrides (a content check across the `${storagePrefix}-state` family — `-state` (v1) through every `-state-vN` — rather than a presence check on a specific version key; see §9), the owner-autoload flag (`${storagePrefix}:autoload` set to `'1'` or `'auto'`), or the element-path inspector enabled.
565
+ - This gating keeps the panel out of the initial JS bundle for first-time visitors while still re-applying overrides on hard reload for users who have tweaked things. **General visitors** (none of these signals set) pay zero bundle cost.
565
566
 
566
567
  For a Vite-only / non-Astro host, mount it yourself by importing the adapter module after `configurePanel(...)`. See §11.5.
567
568
 
569
+ ### 5.6 First-open geometry
570
+
571
+ The first time an instance opens with no persisted position, the panel picks its position and size together as one coherent rectangle, not as two independently-computed values:
572
+
573
+ - **Size first, position from that size.** The default size follows the historical `min(1200, 0.8·vw) × min(800, 0.8·vh)` rule, clamped to a minimum floor and the viewport. The default position then centers _that same clamped rectangle_. Position and size can no longer disagree about the panel's width — they used to be computed separately, which could center a wider phantom panel than the one actually rendered and spawn it partly off-screen on a narrow viewport.
574
+ - **Always contained in the viewport.** The centered position is run through a containment clamp before use, so the whole panel — not just a grabbable strip of it — sits inside `[0, innerWidth]` × `[0, innerHeight]`. This holds at every viewport width, including phone widths, and it holds for a *persisted* size too: an instance that has a saved size but no saved position (the user resized the panel without ever dragging it) is centered and contained against that saved size, not against the default one.
575
+ - **Instance-aware: concurrent panels cascade apart.** Each additional concurrently-mounted instance offsets its own fresh-open position by 24px on both axes. The offset comes from mount order with lowest-free-slot reuse — the first free ordinal is claimed on mount and given back on unmount, so opening a third panel after closing the first reuses ordinal 0 rather than always growing. Two instances opened at once therefore don't spawn stacked exactly on top of each other.
576
+ - **A persisted position always wins.** The cascade offset applies only to the fallback used when an instance has no saved position yet. A panel the user has dragged (and which got saved) reopens exactly where it was left, regardless of how many sibling instances happen to be mounted.
577
+ - **Containment beats distinctness.** These two guarantees are not both promised unconditionally — on a viewport with no spare room, the 24px cascade shrinks toward whatever slack is left, down to a 0px offset, rather than pushing a panel outside the viewport. Two instances' first-open positions may then coincide. Each axis degrades independently: at a 320px viewport width the horizontal offset collapses to 0 once the minimum-width floor eats all the spare width, while the vertical offset may still cascade its full 24px if vertical slack remains.
578
+ - **A different, stricter rule than the drag-recovery clamp.** Once a panel has been dragged, its position is governed by a separate, deliberately permissive clamp: it only guarantees a small grip of the panel's header stays on-screen so the user can drag it back, and otherwise allows the panel to hang off any edge. That drag clamp is unchanged and keeps applying after a drag; the full-containment guarantee above is specific to the first-open fallback position and does not carry over once the user has moved the panel.
579
+
568
580
  ---
569
581
 
570
582
  ## 6. Tab / tier model schema
@@ -951,9 +963,9 @@ Behaviour notes:
951
963
  | `state-v2` | `${storagePrefix}-state-v2` | Legacy pre-v3 format. Migrated into `state-v3` (and from there into `state-v4`) on first load, then deleted. |
952
964
  | `state-v1` | `${storagePrefix}-state` | Legacy pre-v2 flat-state format (Color-only). Migrated into `state-v3` (and from there into `state-v4`) on first load, then deleted. |
953
965
  | `open` | `${storagePrefix}-open` | Mirror of the panel's `open` boolean (synchronous mount-time read — preserves user intent across reloads, fixes #1549). |
954
- | `position` | `${storagePrefix}-position` | Drag position `{ top, right }` so the panel reappears where the user left it. |
966
+ | `position` | `${storagePrefix}-position` | Drag position `{ top, left }` so the panel reappears where the user left it. |
955
967
  | `visible` | `${storagePrefix}:visible` | Adapter-level visibility-intent flag, owned by the lazy-load gate. |
956
- | `autoload` | `${storagePrefix}:autoload` | Owner-mode autoload flag. When `'1'`, the panel bundle fetches eagerly on every page load and mounts CLOSED so the Alt+click element-path inspector is armed without opening the panel UI. Set by `enableAutoload()` and cleared by `disableAutoload()`. See §10.1. |
968
+ | `autoload` | `${storagePrefix}:autoload` | Owner-mode autoload flag. Holds `'1'` (explicit — set by `enableAutoload()`) or `'auto'` (auto-remembered — set by opening the panel). Either value arms the panel bundle to fetch eagerly on every page load and mount CLOSED so the Alt+click element-path inspector is armed without opening the panel UI. Cleared by `disableAutoload()`. See §10.1. |
957
969
 
958
970
  For example, with `storagePrefix: 'myapp-design-token-panel'`:
959
971
 
@@ -1042,7 +1054,7 @@ zdtp.toggle(); // toggle open/closed
1042
1054
  - Non-Astro hosts get it as soon as `@takazudo/zdtp`'s package-root module has loaded (it installs the alias at module init).
1043
1055
  - Astro hosts get it as soon as the host-adapter `<script>` has run — **before** the panel bundle itself has loaded. The first `zdtp.*` call lazy-imports the bundle, exactly like `window[consoleNamespace].*`.
1044
1056
  - **Never clobbers a host-defined `window.zdtp`.** If your page already has its own `window.zdtp` for something unrelated, the package leaves it alone and logs a `console.warn` instead of overwriting it — including the edge case of choosing `consoleNamespace: 'zdtp'` yourself.
1045
- - **Auto-remember applies too** — `zdtp.show()` arms the `:autoload` flag exactly like `showDesignPanel()` (§10.1's Auto-remember footgun note applies here as well).
1057
+ - **Auto-remember applies too** — `zdtp.show()` arms the `:autoload` flag with `'auto'` provenance exactly like `showDesignPanel()` (§10.1's Auto-remember footgun note applies here as well).
1046
1058
 
1047
1059
  See `PORTABLE-CONTRACT.md` §6.5 for the full install-site and no-clobber/no-double-install contract.
1048
1060
 
@@ -1078,11 +1090,15 @@ Both the Astro host-adapter (`window[consoleNamespace].*`) and the package-root
1078
1090
 
1079
1091
  #### The `${storagePrefix}:autoload` flag
1080
1092
 
1081
- Stored in `localStorage` as `'1'` when armed, removed or `'0'` otherwise. The host-adapter's lazy-load gate reads this flag on every page load — when it is `'1'`, the panel bundle loads eagerly (the same as when the panel was previously visible or overrides are persisted). **General visitors** who have never called `enableAutoload()` have no flag and pay zero bundle cost.
1093
+ Stored in `localStorage` as `'1'` (explicit — set by `enableAutoload()`) or `'auto'` (auto-remembered — set by opening the panel; see "Auto-remember on open" below), removed or `'0'` otherwise. The host-adapter's lazy-load gate honours **either** value — when the flag is `'1'` or `'auto'`, the panel bundle loads eagerly (the same as when the panel was previously visible, via either the `:visible` flag or its `-open` mirror, or overrides are persisted, checked as a content check across the `${storagePrefix}-state` family rather than a presence check on a specific version key — see §9). **General visitors** who have never opened the panel or called `enableAutoload()` have no flag and pay zero bundle cost.
1094
+
1095
+ **Downstream-host recipe.** A host that writes its own lazy-load probe (e.g. to decide whether to eagerly fetch something else alongside the panel) can read the flag directly and test `=== '1'` to match only the explicit-owner population, excluding visitors who merely opened the panel once.
1096
+
1097
+ **Legacy caveat.** Browsers that auto-remembered *before* this provenance split shipped already hold `'1'` — the split value was never stored for them, so there is nothing to reclassify. An `=== '1'` probe therefore sheds the auto-remembered population only for opens made from this version onward; it does not retroactively shed the pre-existing legacy population still holding `'1'`.
1082
1098
 
1083
1099
  #### Auto-remember on open
1084
1100
 
1085
- Opening the panel by any means — `showDesignPanel()`, `toggleDesignPanel()`, or clicking the panel's own header close button to re-open it — **automatically sets the `:autoload` flag**. This means once you open the panel you will be in owner-mode on subsequent page loads without calling `enableAutoload()` explicitly.
1101
+ Opening the panel by any means — `showDesignPanel()`, `toggleDesignPanel()`, or clicking the panel's own header close button to re-open it — **automatically sets the `:autoload` flag to `'auto'`** (auto-remembered provenance, distinct from the `'1'` that `enableAutoload()` writes). This means once you open the panel you will be in owner-mode on subsequent page loads without calling `enableAutoload()` explicitly. An existing explicit `'1'` is never downgraded — an owner who armed autoload deliberately keeps that provenance even after opening the panel again.
1086
1102
 
1087
1103
  #### Element-path coupling
1088
1104
 
@@ -1090,12 +1106,14 @@ Opening the panel by any means — `showDesignPanel()`, `toggleDesignPanel()`, o
1090
1106
 
1091
1107
  #### Auto-remember footgun
1092
1108
 
1093
- Because **any open trigger sets `:autoload`**, a visible "open panel" button, keyboard shortcut, or similar affordance on your site becomes a de-facto owner-mode opt-in for anyone who clicks it. On an owner-only public site:
1109
+ Because **any open trigger sets `:autoload`** (to `'auto'`), a visible "open panel" button, keyboard shortcut, or similar affordance on your site becomes a de-facto owner-mode opt-in for anyone who clicks it. On an owner-only public site:
1094
1110
 
1095
1111
  - Gate or omit such triggers (hide them behind a login check, remove them from the production build, etc.).
1096
1112
  - Rely on the console `enableAutoload()` call as the owner's explicit opt-in.
1097
1113
  - See the [Load the panel only for you](/docs/recipes/owner-autoload) recipe for a safe worked example.
1098
1114
 
1115
+ **If your site wants a visible panel button for every visitor** (not just the owner) — hiding the trigger isn't an option — set `autoRememberOnOpen: false` on `PanelConfig` (§5.3). Opening the panel then never persists owner-mode for anyone; `enableAutoload()` remains available as the explicit, owner-only opt-in regardless of this setting.
1116
+
1099
1117
  ---
1100
1118
 
1101
1119
  ## 11. Tailwind not required
@@ -14,10 +14,10 @@
14
14
  * namespace is a configured field — different consumers can pick
15
15
  * distinct values to prove the contract is host-agnostic.
16
16
  * 4. Gate the panel module's dynamic import on the same probes the legacy
17
- * host script used: an existing `wasVisible()` flag or any persisted v2
18
- * overrides. When neither is set, the panel module stays out of the
19
- * initial bundle and only loads when the user calls a `window.<ns>.*`
20
- * helper from the console.
17
+ * host script used: an existing `wasVisible()` flag or any non-empty
18
+ * persisted state envelope. When none is set, the panel module stays out
19
+ * of the initial bundle and only loads when the user calls a
20
+ * `window.<ns>.*` helper from the console.
21
21
  *
22
22
  * Idempotency
23
23
  * -----------
@@ -1,16 +1,16 @@
1
- import { c as h, g as u, a as g, b as y, d as P, e as b, f as _, i as A } from "../panel-config-BNLlUc_r.js";
2
- import { g as d, Z as k } from "../tweak-state-Dti6XMoQ.js";
3
- import { s as I, l as E, a as T, b as c, c as C, d as S } from "../autoload-state-CFmRjtD-.js";
4
- const r = "tokenpanel-config";
5
- function v() {
1
+ import { c as y, g as m, a as w, b, i as P } from "../panel-config-7Xg59uKj.js";
2
+ import { g, Z as k } from "../tweak-state-DRKV1uYj.js";
3
+ import { s as A, l as D, a as E, i as c, r as f, c as _, b as I, d } from "../autoload-state-CTDDBxI8.js";
4
+ const u = "tokenpanel-config";
5
+ function S() {
6
6
  if (typeof document > "u")
7
7
  throw new Error(
8
8
  "[design-token-panel] host-adapter loaded without a document; expected to run in a browser context."
9
9
  );
10
- const e = document.getElementById(r);
10
+ const e = document.getElementById(u);
11
11
  if (!e)
12
12
  throw new Error(
13
- `[design-token-panel] Inline config script #${r} not found. Ensure <DesignTokenPanelHost config={...} /> is rendered on this page before the host script runs.`
13
+ `[design-token-panel] Inline config script #${u} not found. Ensure <DesignTokenPanelHost config={...} /> is rendered on this page before the host script runs.`
14
14
  );
15
15
  const o = e.textContent ?? "";
16
16
  let n;
@@ -18,38 +18,56 @@ function v() {
18
18
  n = JSON.parse(o);
19
19
  } catch (a) {
20
20
  throw new Error(
21
- `[design-token-panel] Failed to parse inline config from #${r}: ${a.message}`
21
+ `[design-token-panel] Failed to parse inline config from #${u}: ${a.message}`
22
22
  );
23
23
  }
24
- return _(n), n;
24
+ return b(n), n;
25
25
  }
26
- function D(e) {
26
+ function T(e) {
27
27
  return e.__zudoDesignTokenPanelAdapter || (e.__zudoDesignTokenPanelAdapter = {}), e.__zudoDesignTokenPanelAdapter;
28
28
  }
29
- function V(e, o) {
30
- const n = D(e);
29
+ function v(e, o) {
30
+ const n = T(e);
31
31
  let a = n[o];
32
32
  return a || (a = { bound: !1, modulePromise: null }, n[o] = a), a;
33
33
  }
34
- function K(e) {
34
+ function p(e) {
35
35
  try {
36
36
  return window.localStorage.getItem(e) === "1";
37
37
  } catch {
38
38
  return !1;
39
39
  }
40
40
  }
41
- function M(e, o, n) {
41
+ function C(e) {
42
+ return e.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
43
+ }
44
+ function O(e) {
45
+ if (e === null || e === "") return !1;
46
+ let o;
47
+ try {
48
+ o = JSON.parse(e);
49
+ } catch {
50
+ return !0;
51
+ }
52
+ return o === null ? !1 : Array.isArray(o) ? o.length > 0 : typeof o == "object" ? Object.keys(o).length > 0 : !0;
53
+ }
54
+ function x(e) {
42
55
  try {
43
- const a = window.localStorage;
44
- return a.getItem(n) !== null || a.getItem(o) !== null || a.getItem(e) !== null;
56
+ const o = new RegExp(`^${C(e.storagePrefix)}-state(-v\\d+)?$`), n = window.localStorage;
57
+ for (let a = 0; a < n.length; a++) {
58
+ const t = n.key(a);
59
+ if (t !== null && o.test(t) && O(n.getItem(t)))
60
+ return !0;
61
+ }
62
+ return !1;
45
63
  } catch {
46
64
  return !1;
47
65
  }
48
66
  }
49
- async function i(e) {
67
+ async function s(e) {
50
68
  return e.modulePromise === null && (e.modulePromise = import("@takazudo/zdtp").then((o) => {
51
69
  try {
52
- const n = u(), a = o.__panelConfigForTest();
70
+ const n = m(), a = o.__panelConfigForTest();
53
71
  n !== a && console.warn(
54
72
  "[design-token-panel] Singleton-sharing check failed: the host adapter and the panel module observed different PanelConfig singletons. This indicates the package's `config/panel-config` module is no longer code-split into a single shared chunk. The panel may behave correctly today, but storage keys / namespaces / branding could diverge between the two surfaces in future bundles."
55
73
  );
@@ -61,55 +79,68 @@ async function i(e) {
61
79
  return o;
62
80
  })), e.modulePromise;
63
81
  }
64
- function O(e, o, n, a, t) {
65
- const l = e[o] ?? {};
66
- l.showDesignPanel = async () => {
67
- c(t, !0), await i(n), a.open();
68
- }, l.hideDesignPanel = async () => {
69
- await i(n), a.close();
70
- }, l.toggleDesignPanel = async () => {
71
- await i(n), a.toggle();
72
- let s = !1;
82
+ function R(e, o, n, a, t) {
83
+ const i = e[o] ?? {};
84
+ i.showDesignPanel = async () => {
85
+ const r = d();
86
+ await s(n), c(r) && (f(t), a.open());
87
+ }, i.hideDesignPanel = async () => {
88
+ const r = d();
89
+ await s(n), c(r) && a.close();
90
+ }, i.toggleDesignPanel = async () => {
91
+ const r = d();
92
+ if (await s(n), !c(r)) return;
93
+ a.toggle();
94
+ let l = !1;
73
95
  try {
74
- s = window.localStorage.getItem(d(t)) === "1";
96
+ l = window.localStorage.getItem(g(t)) === "1";
75
97
  } catch {
76
98
  }
77
- s && c(t, !0);
78
- }, l.enableAutoload = async () => {
79
- (await i(n)).enableAutoload(t);
80
- }, l.disableAutoload = async () => {
99
+ l && f(t);
100
+ }, i.enableAutoload = async () => {
101
+ const r = d(), l = await s(n);
102
+ c(r) && l.enableAutoload(t);
103
+ }, i.disableAutoload = async () => {
104
+ const r = d();
81
105
  if (n.modulePromise !== null) {
82
- (await i(n)).disableAutoload(t);
106
+ const l = await s(n);
107
+ if (!c(r)) return;
108
+ l.disableAutoload(t);
83
109
  return;
84
110
  }
85
- C(t), S(!1, t);
111
+ _(t), I(!1, t);
86
112
  try {
87
- window.localStorage.setItem(g(t), "0");
113
+ window.localStorage.setItem(w(t), "0");
88
114
  } catch {
89
115
  }
90
116
  try {
91
- window.localStorage.removeItem(d(t));
117
+ window.localStorage.removeItem(g(t));
92
118
  } catch {
93
119
  }
94
- }, e[o] = l;
120
+ }, e[o] = i;
95
121
  }
96
- function x(e, o) {
97
- A({
122
+ function N(e, o) {
123
+ P({
98
124
  show: async () => {
99
- await i(e), o.open();
125
+ const n = d();
126
+ await s(e), c(n) && o.open();
100
127
  },
101
128
  hide: async () => {
102
- await i(e), o.close();
129
+ const n = d();
130
+ await s(e), c(n) && o.close();
103
131
  },
104
132
  toggle: async () => {
105
- await i(e), o.toggle();
133
+ const n = d();
134
+ await s(e), c(n) && o.toggle();
106
135
  }
107
136
  });
108
137
  }
109
138
  (function() {
110
- const o = v(), n = o.legacyIdRenameMap ? o : { ...o, legacyIdRenameMap: { ...k } }, a = h(n), t = u(), l = window, s = V(l, t.storagePrefix);
111
- if (O(l, t.consoleNamespace, s, a, t), x(s, a), s.bound) return;
112
- s.bound = !0;
113
- const p = g(t), f = y(t), m = P(t), w = b(t);
114
- (K(p) || M(f, m, w) || I(t) || E(t) || t.domTweaker !== void 0 && T(t)) && i(s);
139
+ const o = S(), n = o.legacyIdRenameMap ? o : { ...o, legacyIdRenameMap: { ...k } }, a = y(n), t = m(), i = window, r = v(i, t.storagePrefix);
140
+ if (R(i, t.consoleNamespace, r, a, t), N(r, a), r.bound) return;
141
+ r.bound = !0;
142
+ const l = w(t);
143
+ (p(l) || p(g(t)) || x(t) || A(t) || D(t) || t.domTweaker !== void 0 && E(t)) && s(r).catch((h) => {
144
+ console.error("[design-token-panel] Eager panel-module load failed.", h);
145
+ });
115
146
  })();
@@ -1,4 +1,4 @@
1
- import { s as t } from "../panel-config-BNLlUc_r.js";
1
+ import { s as t } from "../panel-config-7Xg59uKj.js";
2
2
  import { c as d } from "../color-schemes-CgzOBqGO.js";
3
3
  import { F as r, G as m, a as g, S as z } from "../manifest-DCReQE0k.js";
4
4
  const e = {
@@ -0,0 +1,88 @@
1
+ import { g as n, j as o } from "./panel-config-7Xg59uKj.js";
2
+ function c() {
3
+ return typeof document < "u" && document !== null && typeof document.getElementById == "function";
4
+ }
5
+ function f() {
6
+ return typeof document > "u" || document === null ? null : document;
7
+ }
8
+ function i(e) {
9
+ return e !== null && c() && document === e;
10
+ }
11
+ function r(e = n()) {
12
+ return `${e.storagePrefix}-elpath-enabled`;
13
+ }
14
+ function s(e = n()) {
15
+ try {
16
+ return localStorage.getItem(r(e)) === "1";
17
+ } catch {
18
+ return !1;
19
+ }
20
+ }
21
+ function m(e, t = n()) {
22
+ try {
23
+ localStorage.setItem(r(t), e ? "1" : "0");
24
+ } catch {
25
+ }
26
+ }
27
+ function u(e = n()) {
28
+ return `${e.storagePrefix}-domtweaker-enabled`;
29
+ }
30
+ function g(e = n()) {
31
+ try {
32
+ return localStorage.getItem(u(e)) === "1";
33
+ } catch {
34
+ return !1;
35
+ }
36
+ }
37
+ function w(e, t = n()) {
38
+ try {
39
+ localStorage.setItem(u(t), e ? "1" : "0");
40
+ } catch {
41
+ }
42
+ }
43
+ const a = "1", l = "auto";
44
+ function y(e) {
45
+ if (typeof window > "u") return !1;
46
+ try {
47
+ const t = window.localStorage.getItem(o(e));
48
+ return t === a || t === l;
49
+ } catch {
50
+ return !1;
51
+ }
52
+ }
53
+ function E(e, t) {
54
+ if (!(typeof window > "u"))
55
+ try {
56
+ window.localStorage.setItem(o(e), t ? a : "0");
57
+ } catch {
58
+ }
59
+ }
60
+ function b(e) {
61
+ if (!(typeof window > "u") && e.autoRememberOnOpen !== !1)
62
+ try {
63
+ const t = o(e);
64
+ if (window.localStorage.getItem(t) === a) return;
65
+ window.localStorage.setItem(t, l);
66
+ } catch {
67
+ }
68
+ }
69
+ function h(e) {
70
+ if (!(typeof window > "u"))
71
+ try {
72
+ window.localStorage.removeItem(o(e));
73
+ } catch {
74
+ }
75
+ }
76
+ export {
77
+ g as a,
78
+ m as b,
79
+ h as c,
80
+ f as d,
81
+ c as e,
82
+ w as f,
83
+ E as g,
84
+ i,
85
+ s as l,
86
+ b as r,
87
+ y as s
88
+ };
@@ -205,6 +205,21 @@ export interface PanelConfig {
205
205
  * callers that depend on it.
206
206
  */
207
207
  legacyIdRenameMap?: Record<string, string | null>;
208
+ /**
209
+ * Whether opening the panel (via any of the five auto-remember call sites
210
+ * documented in `state/autoload-state.ts`) writes `${storagePrefix}:autoload`
211
+ * with `'auto'` provenance.
212
+ *
213
+ * Defaults to `true` (unchanged historical behaviour). README §10.1 names
214
+ * the auto-remember footgun this field addresses: because any visible
215
+ * "open panel" trigger arms owner-mode autoload for whoever clicks it, a
216
+ * PUBLIC DOCS SITE that wants a panel button visible to every visitor
217
+ * (not just its owner) cannot use the documented mitigation of hiding the
218
+ * trigger. Set `false` on such a host so opening the panel never persists
219
+ * owner-mode; `enableAutoload()` remains available as the explicit
220
+ * owner-only opt-in regardless of this setting.
221
+ */
222
+ autoRememberOnOpen?: boolean;
208
223
  }
209
224
  /**
210
225
  * Handle returned by `configurePanel`. Identifies one configured panel