@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/CHANGELOG.md +40 -0
- package/PORTABLE-CONTRACT.md +1309 -0
- package/README.md +27 -9
- package/dist/astro/host-adapter.d.ts +4 -4
- package/dist/astro/host-adapter.js +78 -47
- package/dist/astro/index.js +1 -1
- package/dist/autoload-state-CTDDBxI8.js +88 -0
- package/dist/config/panel-config.d.ts +15 -0
- package/dist/{index-t74PT2zd.js → index-BeYH-tJD.js} +2052 -2012
- package/dist/{index-CGev6ZiI.js → index-C8GR1TU-.js} +2 -2
- package/dist/index.d.ts +14 -0
- package/dist/index.js +30 -28
- package/dist/{panel-config-BNLlUc_r.js → panel-config-7Xg59uKj.js} +18 -14
- package/dist/panel.d.ts +8 -1
- package/dist/state/autoload-state.d.ts +91 -21
- package/dist/state/tweak-state.d.ts +73 -5
- package/dist/testing.js +7 -7
- package/dist/{tweak-state-Dti6XMoQ.js → tweak-state-DRKV1uYj.js} +407 -385
- package/dist/utils/document-liveness.d.ts +53 -0
- package/package.json +2 -1
- package/dist/autoload-state-CFmRjtD-.js +0 -64
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx as y, jsxs as K, Fragment as kt } from "preact/jsx-runtime";
|
|
2
2
|
import { useEffect as P, useState as Y, useRef as O, useMemo as J, useCallback as X } from "preact/hooks";
|
|
3
|
-
import { b as ft, p as wt, u as ht, a as Ne, A as bt, Z as gt } from "./index-
|
|
4
|
-
import { g as vt, m as j } from "./panel-config-
|
|
3
|
+
import { b as ft, p as wt, u as ht, a as Ne, A as bt, Z as gt } from "./index-BeYH-tJD.js";
|
|
4
|
+
import { g as vt, m as j } from "./panel-config-7Xg59uKj.js";
|
|
5
5
|
const xt = (e, o) => {
|
|
6
6
|
const t = new Array(e.length + o.length);
|
|
7
7
|
for (let r = 0; r < e.length; r++)
|
package/dist/index.d.ts
CHANGED
|
@@ -35,6 +35,20 @@
|
|
|
35
35
|
*/
|
|
36
36
|
import './styles/panel.css';
|
|
37
37
|
import { type PanelConfig } from './config/panel-config';
|
|
38
|
+
/**
|
|
39
|
+
* Test-only: snapshot of the mounted-shell slot registry (prefix -> ordinal).
|
|
40
|
+
* A copy, so a test cannot mutate the live registry through it.
|
|
41
|
+
*
|
|
42
|
+
* Prefixed `__` to make it clear this is internal/test surface, not a
|
|
43
|
+
* documented public API.
|
|
44
|
+
*/
|
|
45
|
+
export declare function __mountedSpawnSlotsForTests(): ReadonlyMap<string, number>;
|
|
46
|
+
/**
|
|
47
|
+
* Test-only: drop every registered slot. Unlike the bindings reset this has
|
|
48
|
+
* no listeners to drain — the registry holds plain numbers — so clearing the
|
|
49
|
+
* map is the whole teardown.
|
|
50
|
+
*/
|
|
51
|
+
export declare function __resetSpawnSlotsForTests(): void;
|
|
38
52
|
export { configurePanel, setPanelColorPresets } from './config/panel-config';
|
|
39
53
|
export type { PanelConfig, PanelInstanceHandle, ApplySink } from './config/panel-config';
|
|
40
54
|
/**
|
package/dist/index.js
CHANGED
|
@@ -1,37 +1,39 @@
|
|
|
1
1
|
import "preact/jsx-runtime";
|
|
2
2
|
import "preact";
|
|
3
|
-
import { S as
|
|
4
|
-
import { Z as
|
|
5
|
-
import { c as
|
|
6
|
-
import "./autoload-state-
|
|
3
|
+
import { S as t, c as i, d as n, _ as l, e as d, f as _, g as p, h as g, i as m, j as P, k as u, l as A, m as C, n as S, o as T, q as c, r as f, s as K, t as M, v, w as E, x as F, y as h, z as w } from "./index-BeYH-tJD.js";
|
|
4
|
+
import { Z as y, U as D, v as k, u as H, X as L } from "./tweak-state-DRKV1uYj.js";
|
|
5
|
+
import { c as O, s as V } from "./panel-config-7Xg59uKj.js";
|
|
6
|
+
import "./autoload-state-CTDDBxI8.js";
|
|
7
7
|
export {
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
t as SCHEMA_V1,
|
|
9
|
+
i as SCHEMA_V2,
|
|
10
10
|
n as SCHEMA_V3,
|
|
11
|
-
|
|
12
|
-
l as
|
|
13
|
-
d as
|
|
14
|
-
_ as
|
|
15
|
-
|
|
16
|
-
g as
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
P as
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
11
|
+
y as ZDTP_LEGACY_TYPOGRAPHY_RENAME_MAP,
|
|
12
|
+
l as __mountedSpawnSlotsForTests,
|
|
13
|
+
d as __panelConfigForTest,
|
|
14
|
+
_ as __reapplyFromStorageForTests,
|
|
15
|
+
p as __resetInstanceBindingsForTests,
|
|
16
|
+
g as __resetSpawnSlotsForTests,
|
|
17
|
+
O as configurePanel,
|
|
18
|
+
m as disableAutoload,
|
|
19
|
+
D as emptyOverrides,
|
|
20
|
+
P as enableAutoload,
|
|
21
|
+
k as getClusterDefaultMode,
|
|
22
|
+
u as hideDesignTokenPanel,
|
|
23
|
+
A as isColorKind,
|
|
24
|
+
C as isContentKind,
|
|
25
|
+
S as isCursorKind,
|
|
26
|
+
T as isLengthKind,
|
|
25
27
|
c as isMaskImageKind,
|
|
26
28
|
f as isNumberKind,
|
|
27
29
|
K as isSelectKind,
|
|
28
30
|
M as isTextKind,
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
31
|
+
v as reapplyPersistedOverrides,
|
|
32
|
+
H as resolvePerModeLiteral,
|
|
33
|
+
L as resolveSemanticPreviewColor,
|
|
34
|
+
E as setLifecycleAdapter,
|
|
35
|
+
V as setPanelColorPresets,
|
|
36
|
+
F as shouldAutoload,
|
|
37
|
+
h as showDesignTokenPanel,
|
|
38
|
+
w as toggleDesignPanel
|
|
37
39
|
};
|
|
@@ -336,10 +336,10 @@ const _ = {
|
|
|
336
336
|
// No bundled apply endpoint / routing — hosts wire their own.
|
|
337
337
|
applyEndpoint: void 0,
|
|
338
338
|
applyRouting: void 0
|
|
339
|
-
},
|
|
339
|
+
}, O = /* @__PURE__ */ Symbol.for("@takazudo/zdtp:singleton");
|
|
340
340
|
function m() {
|
|
341
341
|
const e = globalThis;
|
|
342
|
-
let t = e[
|
|
342
|
+
let t = e[O];
|
|
343
343
|
return t || (t = {
|
|
344
344
|
instances: /* @__PURE__ */ new Map(),
|
|
345
345
|
defaultPrefix: null,
|
|
@@ -347,7 +347,7 @@ function m() {
|
|
|
347
347
|
pendingPostConfigureHooks: [],
|
|
348
348
|
lifecycleHooks: {},
|
|
349
349
|
colorSchemeOwners: /* @__PURE__ */ new Set()
|
|
350
|
-
}, e[
|
|
350
|
+
}, e[O] = t), t;
|
|
351
351
|
}
|
|
352
352
|
function F(e) {
|
|
353
353
|
return {
|
|
@@ -499,19 +499,19 @@ function Ce(e, t) {
|
|
|
499
499
|
function Pe(e) {
|
|
500
500
|
return `${e.exportFilenameBase}.json`;
|
|
501
501
|
}
|
|
502
|
-
const
|
|
502
|
+
const R = /* @__PURE__ */ Symbol.for("@takazudo/zdtp:global-alias-marker");
|
|
503
503
|
function Ee(e) {
|
|
504
504
|
if (typeof window > "u") return;
|
|
505
505
|
const t = window, n = t.zdtp;
|
|
506
506
|
if (n !== void 0) {
|
|
507
|
-
if ((typeof n == "object" || typeof n == "function") && n !== null && n[
|
|
507
|
+
if ((typeof n == "object" || typeof n == "function") && n !== null && n[R] === !0) return;
|
|
508
508
|
console.warn(
|
|
509
509
|
"[design-token-panel] window.zdtp already exists and was not installed by this package. Skipping the zdtp.show() / zdtp.hide() / zdtp.toggle() global alias to avoid clobbering it. Use window[consoleNamespace].* or the configurePanel(cfg) handle instead."
|
|
510
510
|
);
|
|
511
511
|
return;
|
|
512
512
|
}
|
|
513
513
|
const i = { ...e };
|
|
514
|
-
i[
|
|
514
|
+
i[R] = !0, t.zdtp = i;
|
|
515
515
|
}
|
|
516
516
|
function ve(e) {
|
|
517
517
|
if (e === null || typeof e != "object" || Array.isArray(e))
|
|
@@ -565,6 +565,10 @@ function ve(e) {
|
|
|
565
565
|
);
|
|
566
566
|
}
|
|
567
567
|
}
|
|
568
|
+
if (t.autoRememberOnOpen !== void 0 && typeof t.autoRememberOnOpen != "boolean")
|
|
569
|
+
throw new Error(
|
|
570
|
+
`[design-token-panel] PanelConfig.autoRememberOnOpen must be a boolean when set (got ${typeof t.autoRememberOnOpen})`
|
|
571
|
+
);
|
|
568
572
|
if (t.legacyIdRenameMap !== void 0) {
|
|
569
573
|
if (t.legacyIdRenameMap === null || typeof t.legacyIdRenameMap != "object" || Array.isArray(t.legacyIdRenameMap))
|
|
570
574
|
throw new Error("[design-token-panel] PanelConfig.legacyIdRenameMap must be a plain object");
|
|
@@ -926,17 +930,17 @@ export {
|
|
|
926
930
|
be as K,
|
|
927
931
|
oe as _,
|
|
928
932
|
he as a,
|
|
929
|
-
|
|
933
|
+
ve as b,
|
|
930
934
|
ee as c,
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
935
|
+
ue as d,
|
|
936
|
+
pe as e,
|
|
937
|
+
de as f,
|
|
934
938
|
D as g,
|
|
935
|
-
|
|
939
|
+
fe as h,
|
|
936
940
|
Ee as i,
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
941
|
+
we as j,
|
|
942
|
+
ge as k,
|
|
943
|
+
ce as l,
|
|
940
944
|
Ce as m,
|
|
941
945
|
se as n,
|
|
942
946
|
le as o,
|
package/dist/panel.d.ts
CHANGED
|
@@ -10,9 +10,16 @@ import { type PanelConfig } from './config/panel-config';
|
|
|
10
10
|
* distinct sync events, and render distinct manifests, never cross-talking.
|
|
11
11
|
* Omitted (e.g. a direct test render) → the active/default instance, preserving
|
|
12
12
|
* the historical single-panel behaviour.
|
|
13
|
+
*
|
|
14
|
+
* `spawnOrdinal` is this shell's slot in the mounted-shell registry (#584),
|
|
15
|
+
* handed down by the adapter at `render(...)` time. It cascades the FIRST-OPEN
|
|
16
|
+
* position of concurrently mounted instances apart (#585) so a second panel
|
|
17
|
+
* stops landing exactly on top of the first; a persisted position ignores it.
|
|
18
|
+
* Omitted → 0, i.e. no offset.
|
|
13
19
|
*/
|
|
14
20
|
interface DesignTokenTweakPanelProps {
|
|
15
21
|
instanceConfig?: PanelConfig;
|
|
22
|
+
spawnOrdinal?: number;
|
|
16
23
|
}
|
|
17
|
-
export default function DesignTokenTweakPanel({ instanceConfig: instanceConfigProp, }?: DesignTokenTweakPanelProps): import("preact").JSX.Element;
|
|
24
|
+
export default function DesignTokenTweakPanel({ instanceConfig: instanceConfigProp, spawnOrdinal, }?: DesignTokenTweakPanelProps): import("preact").JSX.Element;
|
|
18
25
|
export type { TweakState } from './state/tweak-state';
|
|
@@ -3,31 +3,66 @@
|
|
|
3
3
|
*
|
|
4
4
|
* ## Flag semantics
|
|
5
5
|
*
|
|
6
|
-
* `${storagePrefix}:autoload`
|
|
7
|
-
* when not) is the owner-mode flag. It means:
|
|
6
|
+
* `${storagePrefix}:autoload` is the owner-mode flag. It means:
|
|
8
7
|
* "This browser visited the site as the site owner — autoload the
|
|
9
8
|
* design-token panel on every subsequent page visit."
|
|
10
9
|
*
|
|
10
|
+
* The stored value carries the flag's **provenance** — how the browser came to
|
|
11
|
+
* be in owner mode:
|
|
12
|
+
*
|
|
13
|
+
* - `'1'` — **explicit**: the owner deliberately armed owner mode. Written only
|
|
14
|
+
* by `enableAutoload()` (via `setAutoload(cfg, true)`).
|
|
15
|
+
* - `'auto'` — **auto-remembered**: something merely opened the panel once.
|
|
16
|
+
* Written by `rememberAutoload()` from the five auto-remember sites —
|
|
17
|
+
* `showInstance` / `toggleInstance` / the header-button + window-event
|
|
18
|
+
* handler in `index.tsx`, and `showDesignPanel` / the toggle handler in
|
|
19
|
+
* `astro/host-adapter.ts`.
|
|
20
|
+
* - `'0'`, absent, or any other value — **not in owner mode**. Written by
|
|
21
|
+
* `setAutoload(cfg, false)`; `clearAutoload()` removes the key outright.
|
|
22
|
+
*
|
|
23
|
+
* The split exists so a **downstream host** can discriminate the two
|
|
24
|
+
* populations — e.g. keep an `=== '1'` probe and stop eagerly fetching the
|
|
25
|
+
* panel bundle for a visitor who clicked a panel button once months ago.
|
|
26
|
+
*
|
|
27
|
+
* **zdtp's own gates honour BOTH values.** `shouldAutoload()` is `true` for
|
|
28
|
+
* `'1'` and `'auto'` alike, so an owner who reached owner mode by opening the
|
|
29
|
+
* panel still gets the auto-reload this module documents. Making zdtp's own
|
|
30
|
+
* gate ignore `'auto'` would be a silent behaviour regression for every
|
|
31
|
+
* existing user — the discrimination lives in the *stored value*, not in
|
|
32
|
+
* zdtp's behaviour.
|
|
33
|
+
*
|
|
34
|
+
* Auto-remember never **downgrades** an existing `'1'`: an owner who armed
|
|
35
|
+
* explicitly and then opens the panel keeps the explicit provenance.
|
|
36
|
+
*
|
|
37
|
+
* ### Legacy values are forward-looking only
|
|
38
|
+
*
|
|
39
|
+
* Browsers that auto-remembered BEFORE the provenance value existed already
|
|
40
|
+
* hold `'1'`, and no migration can recover a provenance that was never stored.
|
|
41
|
+
* They therefore read as explicit owners forever. A downstream host must not
|
|
42
|
+
* expect an `=== '1'` probe to immediately shed its whole legacy population —
|
|
43
|
+
* the discrimination only applies to writes made from this version onward.
|
|
44
|
+
*
|
|
11
45
|
* ## General-visitor vs owner behavior
|
|
12
46
|
*
|
|
13
|
-
* - **General visitor** (flag absent or
|
|
14
|
-
* eagerly fetched. Gate #1 (`shouldAutoload`) returns
|
|
15
|
-
* request fires on page load. The panel remains entirely
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
* the
|
|
19
|
-
*
|
|
47
|
+
* - **General visitor** (flag absent, `'0'`, or any unrecognised value): the
|
|
48
|
+
* panel bundle is NOT eagerly fetched. Gate #1 (`shouldAutoload`) returns
|
|
49
|
+
* false, so no bundle request fires on page load. The panel remains entirely
|
|
50
|
+
* invisible.
|
|
51
|
+
* - **Owner** (flag `'1'` or `'auto'`): Gate #1 fires, the host-adapter fetches
|
|
52
|
+
* the bundle eagerly, and Gate #2 (`reapplyFromStorage` in `index.tsx`)
|
|
53
|
+
* mounts the Preact shell CLOSED so the element-path inspector is available
|
|
54
|
+
* even while the panel UI is hidden.
|
|
20
55
|
*
|
|
21
56
|
* ## enableAutoload() / disableAutoload() contract (implemented by S2 #419)
|
|
22
57
|
*
|
|
23
58
|
* `enableAutoload()` (console API, wired by S2):
|
|
24
|
-
* 1. Sets `:autoload = '1'
|
|
59
|
+
* 1. Sets `:autoload = '1'` (explicit provenance).
|
|
25
60
|
* 2. Sets `-elpath-enabled = '1'` once (arms the alt+click inspector).
|
|
26
61
|
* 3. Loads the panel bundle (if not already loaded).
|
|
27
62
|
* 4. Mounts the Preact shell CLOSED via `hideInstance`.
|
|
28
63
|
*
|
|
29
64
|
* `disableAutoload()` (console API, wired by S2):
|
|
30
|
-
* 1. Clears `:autoload
|
|
65
|
+
* 1. Clears `:autoload` (removes the key, whichever value it held).
|
|
31
66
|
* 2. Clears `:visible`.
|
|
32
67
|
* 3. Clears `-elpath-enabled`.
|
|
33
68
|
* 4. Clears the open-state key (`getOpenKey(cfg)` from `state/tweak-state`).
|
|
@@ -36,9 +71,17 @@
|
|
|
36
71
|
* ## Auto-remember
|
|
37
72
|
*
|
|
38
73
|
* Any action that shows the panel (console `showDesignPanel()`, the header-
|
|
39
|
-
* button open event, or the `showInstance` path in `index.tsx`) MUST also
|
|
40
|
-
*
|
|
41
|
-
*
|
|
74
|
+
* button open event, or the `showInstance` path in `index.tsx`) MUST also call
|
|
75
|
+
* `rememberAutoload(cfg)`, which writes `:autoload = 'auto'`. Once the panel
|
|
76
|
+
* has been opened the flag is set so subsequent page loads reload it
|
|
77
|
+
* automatically. (Wired by S2 / S3.)
|
|
78
|
+
*
|
|
79
|
+
* A host can opt out of this entirely by setting `PanelConfig.autoRememberOnOpen
|
|
80
|
+
* = false` — `rememberAutoload` then becomes a no-op, so opening the panel
|
|
81
|
+
* never persists owner-mode. This exists for a public docs site that wants a
|
|
82
|
+
* visible panel button for every visitor without arming owner-mode for
|
|
83
|
+
* whoever clicks it. `enableAutoload()` (which writes `'1'` via `setAutoload`,
|
|
84
|
+
* not this function) is unaffected either way.
|
|
42
85
|
*
|
|
43
86
|
* ## Element-path coupling
|
|
44
87
|
*
|
|
@@ -64,26 +107,53 @@
|
|
|
64
107
|
* are persisted yet.
|
|
65
108
|
*/
|
|
66
109
|
import type { PanelConfig } from '../config/panel-config';
|
|
110
|
+
/** Stored `:autoload` value meaning "the owner armed owner mode deliberately". */
|
|
111
|
+
export declare const AUTOLOAD_EXPLICIT = "1";
|
|
112
|
+
/** Stored `:autoload` value meaning "owner mode was inferred from a panel open". */
|
|
113
|
+
export declare const AUTOLOAD_AUTO_REMEMBERED = "auto";
|
|
67
114
|
/**
|
|
68
|
-
* Return `true` iff this browser has the owner-autoload flag set
|
|
115
|
+
* Return `true` iff this browser has the owner-autoload flag set, regardless of
|
|
116
|
+
* how it got there.
|
|
69
117
|
*
|
|
70
118
|
* SSR-safe (returns `false` when `window` is not available) and quota-
|
|
71
119
|
* tolerant (returns `false` on any storage error). Reads exactly
|
|
72
|
-
* `${cfg.storagePrefix}:autoload` and matches
|
|
73
|
-
*
|
|
120
|
+
* `${cfg.storagePrefix}:autoload` and matches `'1'` (explicit) or `'auto'`
|
|
121
|
+
* (auto-remembered); any other stored value — including `'0'` and an absent
|
|
122
|
+
* key — is `false`.
|
|
74
123
|
*/
|
|
75
124
|
export declare function shouldAutoload(cfg: PanelConfig): boolean;
|
|
76
125
|
/**
|
|
77
|
-
* Write the owner-autoload flag. Pass `true` to arm
|
|
78
|
-
* to disarm (`'0'`). SSR-safe and quota-tolerant —
|
|
79
|
-
* silently so this never throws in restricted storage
|
|
126
|
+
* Write the owner-autoload flag with EXPLICIT provenance. Pass `true` to arm
|
|
127
|
+
* autoload (`'1'`), `false` to disarm (`'0'`). SSR-safe and quota-tolerant —
|
|
128
|
+
* errors are swallowed silently so this never throws in restricted storage
|
|
129
|
+
* contexts.
|
|
130
|
+
*
|
|
131
|
+
* Reserved for the deliberate `enableAutoload()` path; auto-remember call sites
|
|
132
|
+
* use `rememberAutoload` so the two populations stay distinguishable in storage.
|
|
80
133
|
*
|
|
81
134
|
* Prefer `clearAutoload` when you want to fully remove the key (e.g. on
|
|
82
135
|
* `disableAutoload`) rather than leave a `'0'` sentinel.
|
|
83
136
|
*/
|
|
84
137
|
export declare function setAutoload(cfg: PanelConfig, on: boolean): void;
|
|
85
138
|
/**
|
|
86
|
-
*
|
|
139
|
+
* Arm the owner-autoload flag with AUTO-REMEMBERED provenance (`'auto'`).
|
|
140
|
+
*
|
|
141
|
+
* Called from every auto-remember site — any action that merely opens the panel.
|
|
142
|
+
* An existing explicit `'1'` is left untouched: an owner who armed owner mode
|
|
143
|
+
* deliberately must not demote themselves by opening the panel.
|
|
144
|
+
*
|
|
145
|
+
* No-op when `cfg.autoRememberOnOpen === false` — see that field's doc for the
|
|
146
|
+
* public-site use case. The gate lives HERE (not at each call site) so a
|
|
147
|
+
* future auto-remember site inherits it automatically instead of needing its
|
|
148
|
+
* own opt-out check. `enableAutoload()` calls `setAutoload`, not this
|
|
149
|
+
* function, so it is never subject to this gate.
|
|
150
|
+
*
|
|
151
|
+
* SSR-safe and quota-tolerant.
|
|
152
|
+
*/
|
|
153
|
+
export declare function rememberAutoload(cfg: PanelConfig): void;
|
|
154
|
+
/**
|
|
155
|
+
* Remove the owner-autoload flag from storage entirely, whichever provenance
|
|
156
|
+
* value it held.
|
|
87
157
|
*
|
|
88
158
|
* Called by `disableAutoload()` (S2) as part of the full owner-mode teardown.
|
|
89
159
|
* SSR-safe and quota-tolerant.
|
|
@@ -104,16 +104,36 @@ export declare const DEFAULT_POSITION: PanelPosition;
|
|
|
104
104
|
/**
|
|
105
105
|
* Compute a viewport-centered default panel position for first-open behaviour.
|
|
106
106
|
*
|
|
107
|
-
*
|
|
108
|
-
*
|
|
109
|
-
*
|
|
107
|
+
* Delegates to `defaultGeometry()` so the position is centered against the
|
|
108
|
+
* panel's *actual* clamped default size rather than an independently derived
|
|
109
|
+
* one — see that function for why the two must not be computed separately.
|
|
110
|
+
*
|
|
111
|
+
* `spawnOrdinal` cascades concurrently-mounted instances apart; ordinal 0 (the
|
|
112
|
+
* default, and the only ordinal a single-panel host ever sees) is exactly the
|
|
113
|
+
* centered position. `size`, when given, is the rectangle to center — pass the
|
|
114
|
+
* size the panel will actually render at rather than letting the default size
|
|
115
|
+
* be assumed.
|
|
110
116
|
*
|
|
111
117
|
* Falls back to the static `DEFAULT_POSITION` when `window` is undefined
|
|
112
118
|
* (e.g. SSR / node test setup without jsdom). Real browsers + jsdom-backed
|
|
113
119
|
* tests get the centered position.
|
|
114
120
|
*/
|
|
115
|
-
export declare function defaultPosition(): PanelPosition;
|
|
116
|
-
|
|
121
|
+
export declare function defaultPosition(spawnOrdinal?: number, size?: PanelSize): PanelPosition;
|
|
122
|
+
/**
|
|
123
|
+
* Read this instance's persisted position, falling back to the cascaded
|
|
124
|
+
* first-open default.
|
|
125
|
+
*
|
|
126
|
+
* `spawnOrdinal` is applied ONLY to the fallback. A stored position is an
|
|
127
|
+
* explicit user preference — a panel the user dragged somewhere reopens
|
|
128
|
+
* exactly there, never nudged by however many siblings happen to be mounted.
|
|
129
|
+
*
|
|
130
|
+
* `size` is the size the caller will actually render at (i.e. `loadSize()`'s
|
|
131
|
+
* result). Pass it so the fallback is centered and contained against THAT
|
|
132
|
+
* rectangle: an instance with a persisted size but no persisted position
|
|
133
|
+
* would otherwise be centered as if it were the default width and spawn
|
|
134
|
+
* partly off-screen.
|
|
135
|
+
*/
|
|
136
|
+
export declare function loadPosition(cfg?: PanelConfig, spawnOrdinal?: number, size?: PanelSize): PanelPosition;
|
|
117
137
|
export declare function savePosition(pos: PanelPosition, cfg?: PanelConfig): void;
|
|
118
138
|
/** Keep at least VISIBLE_MIN px of the panel on-screen so the user can grab it back. */
|
|
119
139
|
export declare const VISIBLE_MIN = 60;
|
|
@@ -141,6 +161,8 @@ export declare const DEFAULT_SIZE: PanelSize;
|
|
|
141
161
|
* result respects the MIN_PANEL_* floor and the viewport cap. The floor only
|
|
142
162
|
* bites on phone-width viewports (e.g. 375px → 0.8*375 = 300, raised to the
|
|
143
163
|
* 320 min); on normal viewports the clamp is a no-op.
|
|
164
|
+
*
|
|
165
|
+
* Delegates to `defaultGeometry()` — the single place the rule lives.
|
|
144
166
|
*/
|
|
145
167
|
export declare function defaultSize(): PanelSize;
|
|
146
168
|
/**
|
|
@@ -149,6 +171,52 @@ export declare function defaultSize(): PanelSize;
|
|
|
149
171
|
* from rendering off-screen when reopened on a 1080p laptop.
|
|
150
172
|
*/
|
|
151
173
|
export declare function clampSize(width: number, height: number): PanelSize;
|
|
174
|
+
/** Per-ordinal cascade step, in px, applied to both axes on a fresh spawn. */
|
|
175
|
+
export declare const SPAWN_CASCADE_STEP = 24;
|
|
176
|
+
/** Position + size of a panel, as one coherent rectangle. */
|
|
177
|
+
export interface PanelGeometry extends PanelPosition, PanelSize {
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Compute the coherent first-open geometry: the clamped default size, plus a
|
|
181
|
+
* position that centers *that* rectangle in the viewport.
|
|
182
|
+
*
|
|
183
|
+
* Position and size used to be derived independently — `defaultPosition()`
|
|
184
|
+
* centered a phantom `min(1200, 0.8 * vw)` panel while `defaultSize()` raised
|
|
185
|
+
* that same value to the `MIN_PANEL_WIDTH` floor. On a 320px viewport the two
|
|
186
|
+
* disagreed by 32px (left 32 + width 320 = 352) and the panel spawned partly
|
|
187
|
+
* off-screen; `clampPosition()` did not catch it because it is a permissive
|
|
188
|
+
* drag-recovery clamp that only guarantees `VISIBLE_MIN` px stays grabbable.
|
|
189
|
+
* Computing the size first and centering against it keeps them in lockstep,
|
|
190
|
+
* and is the reason `defaultPosition()` / `defaultSize()` are thin wrappers
|
|
191
|
+
* rather than independent implementations.
|
|
192
|
+
*
|
|
193
|
+
* `spawnOrdinal` (from the mount layer's slot registry) cascades a second and
|
|
194
|
+
* third concurrently-mounted instance away from the first — see
|
|
195
|
+
* `SPAWN_CASCADE_STEP` and `clampSpawnPosition`. Ordinal 0 takes no offset, so
|
|
196
|
+
* a single-panel host is byte-identical to the pre-cascade behaviour.
|
|
197
|
+
*
|
|
198
|
+
* The ordinal travels mount layer -> geometry, never the reverse: this module
|
|
199
|
+
* must not import `index.tsx` (epic #582, decision 4).
|
|
200
|
+
*
|
|
201
|
+
* Falls back to the static SSR constants when `window` is undefined.
|
|
202
|
+
*/
|
|
203
|
+
export declare function defaultGeometry(spawnOrdinal?: number, sizeOverride?: PanelSize): PanelGeometry;
|
|
204
|
+
/**
|
|
205
|
+
* Clamp a FRESH-SPAWN position so the whole panel sits inside the viewport:
|
|
206
|
+
* `left ∈ [0, max(0, innerWidth - panelWidth)]`, `top` likewise.
|
|
207
|
+
*
|
|
208
|
+
* Deliberately NOT `clampPosition()`. That one is the drag-recovery clamp and
|
|
209
|
+
* is permissive on purpose — it lets a panel the user dragged hang off the
|
|
210
|
+
* edge so long as `VISIBLE_MIN` px stay grabbable. Spawn containment is a
|
|
211
|
+
* stricter, separate rule (epic #582, decision 2), so it gets its own clamp
|
|
212
|
+
* rather than tightening a clamp other behaviour depends on.
|
|
213
|
+
*
|
|
214
|
+
* Containment beats distinctness: on a viewport with no spare room the upper
|
|
215
|
+
* bound collapses to 0 and the cascade degrades — reduced first, dropped
|
|
216
|
+
* entirely when there is nothing left. Two instances may then coincide. That
|
|
217
|
+
* is the documented trade-off; a panel spawned off-screen is worse.
|
|
218
|
+
*/
|
|
219
|
+
export declare function clampSpawnPosition(top: number, left: number, panelWidth: number, panelHeight: number): PanelPosition;
|
|
152
220
|
export declare function loadSize(cfg?: PanelConfig): PanelSize;
|
|
153
221
|
export declare function saveSize(size: PanelSize, cfg?: PanelConfig): void;
|
|
154
222
|
/**
|
package/dist/testing.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { _ as r, c as _,
|
|
2
|
-
import { a as
|
|
1
|
+
import { _ as r, c as _, d as i, e as n, f as g, h as R, a as p } from "./panel-config-7Xg59uKj.js";
|
|
2
|
+
import { a as l, b as y, l as O } from "./tweak-state-DRKV1uYj.js";
|
|
3
3
|
import { F as K, G as E, a as S, S as u } from "./manifest-DCReQE0k.js";
|
|
4
|
-
async function s(
|
|
5
|
-
await
|
|
4
|
+
async function s(e, a) {
|
|
5
|
+
await e.fill(a), await e.dispatchEvent("input");
|
|
6
6
|
}
|
|
7
7
|
export {
|
|
8
8
|
K as FONT_GROUP_ORDER,
|
|
@@ -11,9 +11,9 @@ export {
|
|
|
11
11
|
u as SIZE_GROUP_ORDER,
|
|
12
12
|
r as __resetPanelConfigForTests,
|
|
13
13
|
_ as configurePanel,
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
14
|
+
l as getStorageKeyV1,
|
|
15
|
+
y as getStorageKeyV2,
|
|
16
|
+
O as loadPersistedState,
|
|
17
17
|
s as setPanelInputValue,
|
|
18
18
|
i as storageKey_open,
|
|
19
19
|
n as storageKey_position,
|