@berenjena/react-dev-panel 2.4.2 → 2.5.0
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 +43 -1
- package/dist/assets/index.css +1 -1
- package/dist/assets/index10.css +1 -1
- package/dist/assets/index11.css +1 -1
- package/dist/assets/index12.css +1 -1
- package/dist/assets/index13.css +1 -1
- package/dist/assets/index14.css +1 -1
- package/dist/assets/index15.css +1 -1
- package/dist/assets/index2.css +1 -1
- package/dist/assets/index3.css +1 -1
- package/dist/assets/index4.css +1 -1
- package/dist/assets/index5.css +1 -1
- package/dist/assets/index6.css +1 -1
- package/dist/assets/index7.css +1 -1
- package/dist/assets/index8.css +1 -1
- package/dist/assets/index9.css +1 -1
- package/dist/components/ControlErrorBoundary/index.d.ts +24 -0
- package/dist/components/ControlErrorBoundary/index.js +17 -0
- package/dist/components/ControlRenderer/controls/BooleanControl/index.js +10 -9
- package/dist/components/ControlRenderer/controls/ButtonControl/index.js +4 -3
- package/dist/components/ControlRenderer/controls/ButtonGroupControl/index.js +6 -5
- package/dist/components/ControlRenderer/controls/ColorControl/index.js +2 -1
- package/dist/components/ControlRenderer/controls/DateControl/index.js +8 -7
- package/dist/components/ControlRenderer/controls/DragAndDropControl/index.js +15 -14
- package/dist/components/ControlRenderer/controls/LocalStorageControl/index.js +111 -110
- package/dist/components/ControlRenderer/controls/MultiSelectControl/index.d.ts +2 -0
- package/dist/components/ControlRenderer/controls/MultiSelectControl/index.js +8 -5
- package/dist/components/ControlRenderer/controls/MultiSelectControl/types.d.ts +2 -0
- package/dist/components/ControlRenderer/controls/NumberControl/index.js +10 -9
- package/dist/components/ControlRenderer/controls/RangeControl/index.js +6 -5
- package/dist/components/ControlRenderer/controls/SelectControl/index.js +5 -4
- package/dist/components/ControlRenderer/controls/SeparatorControl/index.js +2 -1
- package/dist/components/ControlRenderer/controls/TextControl/index.js +7 -6
- package/dist/components/ControlRenderer/controls/index.js +1 -0
- package/dist/components/ControlRenderer/index.js +28 -26
- package/dist/components/DevPanel/index.js +12 -11
- package/dist/components/DevPanel/types.d.ts +17 -0
- package/dist/components/DevPanelPortal/index.js +5 -4
- package/dist/components/EmptyContent/index.js +2 -1
- package/dist/components/Icon/index.js +11 -10
- package/dist/components/Input/index.js +2 -1
- package/dist/components/Section/index.js +2 -1
- package/dist/components/Select/index.js +11 -10
- package/dist/components/Textarea/index.js +5 -4
- package/dist/components/index.js +3 -2
- package/dist/hooks/useDebounceCallback/index.js +1 -0
- package/dist/hooks/useDevPanel/consoleApi.d.ts +37 -0
- package/dist/hooks/useDevPanel/consoleApi.js +16 -0
- package/dist/hooks/useDevPanel/index.d.ts +5 -1
- package/dist/hooks/useDevPanel/index.js +50 -41
- package/dist/hooks/useDevPanel/mountDevPanelPortal.d.ts +18 -0
- package/dist/hooks/useDevPanel/mountDevPanelPortal.js +20 -0
- package/dist/hooks/useDragAndDrop/index.js +1 -0
- package/dist/hooks/useHotKey/index.js +4 -3
- package/dist/hooks/useHotkeys/index.js +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +4 -3
- package/dist/managers/DevPanelManager.js +1 -0
- package/dist/store/BaseStoreService.d.ts +2 -7
- package/dist/store/BaseStoreService.js +14 -7
- package/dist/store/ControlPersistenceService.d.ts +2 -0
- package/dist/store/ControlPersistenceService.js +34 -26
- package/dist/store/SectionsStore.js +3 -2
- package/dist/store/UIStore.d.ts +14 -0
- package/dist/store/UIStore.js +37 -22
- package/dist/utils/className/className.js +6 -5
- package/dist/utils/className/index.js +3 -2
- package/dist/utils/copyToClipboard/copyToClipboard.js +1 -0
- package/dist/utils/copyToClipboard/index.js +3 -2
- package/dist/utils/createHotkey/createHotkey.js +4 -3
- package/dist/utils/createHotkey/index.js +3 -2
- package/dist/utils/debounce/debounce.js +4 -3
- package/dist/utils/debounce/index.js +3 -2
- package/dist/utils/deepEqual/deepEqual.d.ts +19 -0
- package/dist/utils/deepEqual/deepEqual.js +22 -0
- package/dist/utils/formatHotkey/formatHotkey.js +1 -0
- package/dist/utils/formatHotkey/index.js +1 -0
- package/dist/utils/getConstrainedPosition/getConstrainedPosition.js +6 -5
- package/dist/utils/getConstrainedPosition/index.js +3 -2
- package/dist/utils/getCurrentElementPosition/getCurrentElementPosition.js +1 -0
- package/dist/utils/getCurrentElementPosition/index.js +3 -2
- package/dist/utils/getPositionAdjustment/getPositionAdjustment.js +6 -5
- package/dist/utils/getPositionAdjustment/index.js +3 -2
- package/dist/utils/getStringPreview/getStringPreview.js +3 -2
- package/dist/utils/getStringPreview/index.js +1 -0
- package/dist/utils/hasControlChanged/hasControlChanged.js +7 -5
- package/dist/utils/hasControlChanged/index.js +3 -2
- package/dist/utils/isMacOS/index.js +3 -2
- package/dist/utils/isMacOS/isMacOS.js +3 -2
- package/dist/utils/isValidPersistedValue/isValidPersistedValue.d.ts +13 -0
- package/dist/utils/isValidPersistedValue/isValidPersistedValue.js +22 -0
- package/dist/utils/prettifyJson/index.js +3 -2
- package/dist/utils/prettifyJson/prettifyJson.js +5 -4
- package/package.json +7 -3
- package/dist/assets/index16.css +0 -1
|
@@ -1,52 +1,61 @@
|
|
|
1
|
-
|
|
2
|
-
import {
|
|
3
|
-
import { DevPanelPortal as E } from "../../components/DevPanelPortal/index.js";
|
|
1
|
+
"use client";
|
|
2
|
+
import { useRef as d, useEffect as f } from "react";
|
|
4
3
|
import { DevPanelManager as P } from "../../managers/DevPanelManager.js";
|
|
5
|
-
import { controlPersistenceService as
|
|
6
|
-
import { useDevPanelSections as
|
|
7
|
-
import { hasControlsChanged as
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
4
|
+
import { controlPersistenceService as C } from "../../store/ControlPersistenceService.js";
|
|
5
|
+
import { useDevPanelSections as $, useDevPanelSectionActions as m } from "../../store/SectionsStore.js";
|
|
6
|
+
import { hasControlsChanged as E } from "../../utils/hasControlChanged/hasControlChanged.js";
|
|
7
|
+
import { isValidPersistedValue as V } from "../../utils/isValidPersistedValue/isValidPersistedValue.js";
|
|
8
|
+
import { mountDevPanelPortal as b } from "./mountDevPanelPortal.js";
|
|
9
|
+
function M(e, i, o) {
|
|
10
|
+
const v = $(), { registerSection: l, unregisterSection: a } = m(), p = d(void 0), c = d(null), h = d(/* @__PURE__ */ new Set()), s = o?.enabled ?? !0;
|
|
11
|
+
c.current || (c.current = P.getInstance()), f(() => {
|
|
12
|
+
s && Object.entries(i).forEach(([n, r]) => {
|
|
13
|
+
const t = `${e}-${n}`;
|
|
14
|
+
if (r.persist && !h.current.has(t)) {
|
|
15
|
+
const u = C.getPersistedValue(e, n);
|
|
16
|
+
u !== void 0 && "onChange" in r && typeof r.onChange == "function" && (V(r, u) ? r.onChange(u) : (console.warn(
|
|
17
|
+
`[DevPanel] Ignoring persisted value for "${e}.${n}": type does not match control "${r.type}". Dropping stored value.`
|
|
18
|
+
), C.removePersistedValue(e, n))), h.current.add(t);
|
|
16
19
|
}
|
|
17
20
|
});
|
|
18
|
-
}, [
|
|
19
|
-
const
|
|
20
|
-
|
|
21
|
-
const
|
|
22
|
-
Object.entries(
|
|
23
|
-
if (
|
|
24
|
-
const
|
|
25
|
-
|
|
26
|
-
...
|
|
27
|
-
onChange: (
|
|
28
|
-
|
|
21
|
+
}, [s, e, i]);
|
|
22
|
+
const g = d({});
|
|
23
|
+
f(() => {
|
|
24
|
+
const n = {};
|
|
25
|
+
Object.entries(i).forEach(([r, t]) => {
|
|
26
|
+
if (t.persist && "onChange" in t && typeof t.onChange == "function") {
|
|
27
|
+
const u = t.onChange;
|
|
28
|
+
n[r] = {
|
|
29
|
+
...t,
|
|
30
|
+
onChange: (S) => {
|
|
31
|
+
C.setPersistedValue(e, r, S);
|
|
32
|
+
try {
|
|
33
|
+
u(S);
|
|
34
|
+
} catch (D) {
|
|
35
|
+
console.error(`[DevPanel] Error in onChange for "${e}.${r}":`, D);
|
|
36
|
+
}
|
|
29
37
|
}
|
|
30
38
|
};
|
|
31
39
|
} else
|
|
32
|
-
|
|
33
|
-
}),
|
|
34
|
-
}, [
|
|
35
|
-
const
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
40
|
+
n[r] = t;
|
|
41
|
+
}), g.current = n;
|
|
42
|
+
}, [e, i]), f(() => {
|
|
43
|
+
const n = c.current, r = v[e] !== void 0;
|
|
44
|
+
if (!s) {
|
|
45
|
+
r && (a(e), n.removeSection(e), p.current = void 0);
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
E(g.current, p.current) || !r ? (l(e, g.current), p.current = g.current, n.addSection(e, o)) : o && n.updateProps(o);
|
|
49
|
+
}, [s, e, i, o, v, l, a]), f(() => {
|
|
50
|
+
const n = h.current;
|
|
39
51
|
return () => {
|
|
40
|
-
const
|
|
41
|
-
|
|
52
|
+
const r = c.current;
|
|
53
|
+
a(e), r.removeSection(e), n.clear();
|
|
42
54
|
};
|
|
43
|
-
}, [
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
const e = document.createElement("div");
|
|
47
|
-
e.id = "dev-panel-portal-container", e.style.display = "none", document.body.appendChild(e), S(e).render(v(E));
|
|
48
|
-
}, []);
|
|
55
|
+
}, [e, a]), f(() => {
|
|
56
|
+
s && b();
|
|
57
|
+
}, [s]);
|
|
49
58
|
}
|
|
50
59
|
export {
|
|
51
|
-
|
|
60
|
+
M as useDevPanel
|
|
52
61
|
};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mounts the DevPanelPortal into a dedicated, hidden container appended to
|
|
3
|
+
* `document.body`, creating a single React root for the whole app.
|
|
4
|
+
*
|
|
5
|
+
* Idempotent and safe to call from every `useDevPanel` call site:
|
|
6
|
+
* - No-op in non-browser environments (SSR) — guarded by `typeof document`.
|
|
7
|
+
* - No-op if already mounted in this runtime (the stored `root` acts as guard).
|
|
8
|
+
* - Self-heals across HMR/module reloads: a stale container left over from a
|
|
9
|
+
* previous module instance is removed before creating a fresh root, so the
|
|
10
|
+
* portal never duplicates and never leaks an orphaned container.
|
|
11
|
+
*/
|
|
12
|
+
export declare function mountDevPanelPortal(): void;
|
|
13
|
+
/**
|
|
14
|
+
* Tears down the DevPanelPortal root and removes its container from the DOM.
|
|
15
|
+
* Intended for HMR resets and tests; the portal re-mounts on the next
|
|
16
|
+
* `mountDevPanelPortal` call.
|
|
17
|
+
*/
|
|
18
|
+
export declare function unmountDevPanelPortal(): void;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { createElement as r } from "react";
|
|
3
|
+
import { createRoot as l } from "react-dom/client";
|
|
4
|
+
import { DevPanelPortal as i } from "../../components/DevPanelPortal/index.js";
|
|
5
|
+
import { registerDevPanelConsoleApi as m, unregisterDevPanelConsoleApi as u } from "./consoleApi.js";
|
|
6
|
+
const o = "dev-panel-portal-container";
|
|
7
|
+
let n = null, e = null;
|
|
8
|
+
function f() {
|
|
9
|
+
if (typeof document > "u" || n)
|
|
10
|
+
return;
|
|
11
|
+
const t = document.getElementById(o);
|
|
12
|
+
t && t.remove(), e = document.createElement("div"), e.id = o, e.style.display = "none", document.body.appendChild(e), n = l(e), n.render(r(i)), m();
|
|
13
|
+
}
|
|
14
|
+
function s() {
|
|
15
|
+
n?.unmount(), n = null, e?.remove(), e = null, u();
|
|
16
|
+
}
|
|
17
|
+
export {
|
|
18
|
+
f as mountDevPanelPortal,
|
|
19
|
+
s as unmountDevPanelPortal
|
|
20
|
+
};
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
"use client";
|
|
1
2
|
import { useRef as g, useState as p, useCallback as u, useEffect as f } from "react";
|
|
2
3
|
import { debounce as E } from "../../utils/debounce/debounce.js";
|
|
3
4
|
import { getConstrainedPosition as D } from "../../utils/getConstrainedPosition/getConstrainedPosition.js";
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
1
|
export { useDevPanel } from './hooks/useDevPanel';
|
|
2
|
+
export type { DevPanelConsoleApi } from './hooks/useDevPanel/consoleApi';
|
|
2
3
|
export type { DevPanelProps } from './components/DevPanel/types';
|
|
3
4
|
export type { ControlsGroup } from './components/ControlRenderer/controls/types';
|
package/dist/index.js
CHANGED
|
@@ -1,13 +1,8 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Abstract base class for state management services using the useSyncExternalStore pattern.
|
|
3
|
-
* Provides common functionality for subscription management, state updates, and persistence.
|
|
4
|
-
*
|
|
5
|
-
* @template TState - The type of the state object
|
|
6
|
-
* @template TPersistedState - The type of the persisted state object (usually a subset of TState)
|
|
7
|
-
*/
|
|
8
1
|
export declare abstract class BaseStoreService<TState, TPersistedState = TState> {
|
|
9
2
|
/** Set of listeners subscribed to state changes */
|
|
10
3
|
protected readonly listeners: Set<() => void>;
|
|
4
|
+
/** Whether a persistence failure has already been logged (avoids log spam). */
|
|
5
|
+
private persistenceWarned;
|
|
11
6
|
/** The localStorage key for persisting state */
|
|
12
7
|
protected readonly storageKey: string;
|
|
13
8
|
/** Whether this store should persist state to localStorage */
|
|
@@ -1,6 +1,10 @@
|
|
|
1
|
-
|
|
1
|
+
"use client";
|
|
2
|
+
import { deepEqual as r } from "../utils/deepEqual/deepEqual.js";
|
|
3
|
+
class n {
|
|
2
4
|
/** Set of listeners subscribed to state changes */
|
|
3
5
|
listeners = /* @__PURE__ */ new Set();
|
|
6
|
+
/** Whether a persistence failure has already been logged (avoids log spam). */
|
|
7
|
+
persistenceWarned = !1;
|
|
4
8
|
/** The localStorage key for persisting state */
|
|
5
9
|
storageKey;
|
|
6
10
|
/** Whether this store should persist state to localStorage */
|
|
@@ -24,12 +28,15 @@ class r {
|
|
|
24
28
|
* @protected
|
|
25
29
|
*/
|
|
26
30
|
saveState() {
|
|
27
|
-
if (this.shouldPersist)
|
|
31
|
+
if (!(!this.shouldPersist || typeof localStorage > "u"))
|
|
28
32
|
try {
|
|
29
33
|
const t = this.toPersistableState(this.state);
|
|
30
34
|
localStorage.setItem(this.storageKey, JSON.stringify(t));
|
|
31
|
-
} catch {
|
|
32
|
-
|
|
35
|
+
} catch (t) {
|
|
36
|
+
if (!this.persistenceWarned) {
|
|
37
|
+
const e = t instanceof DOMException && t.name === "QuotaExceededError" ? "localStorage quota exceeded" : "localStorage unavailable";
|
|
38
|
+
console.warn(`[DevPanel] Failed to save ${this.getServiceName()} state (${e}).`), this.persistenceWarned = !0;
|
|
39
|
+
}
|
|
33
40
|
}
|
|
34
41
|
}
|
|
35
42
|
/**
|
|
@@ -39,7 +46,7 @@ class r {
|
|
|
39
46
|
* @protected
|
|
40
47
|
*/
|
|
41
48
|
loadState() {
|
|
42
|
-
if (this.shouldPersist)
|
|
49
|
+
if (!(!this.shouldPersist || typeof localStorage > "u"))
|
|
43
50
|
try {
|
|
44
51
|
const t = localStorage.getItem(this.storageKey);
|
|
45
52
|
if (t) {
|
|
@@ -67,7 +74,7 @@ class r {
|
|
|
67
74
|
*/
|
|
68
75
|
setState(t) {
|
|
69
76
|
const e = t(this.state);
|
|
70
|
-
|
|
77
|
+
r(e, this.state) || (this.state = e, this.saveState(), this.notifySubscribers());
|
|
71
78
|
}
|
|
72
79
|
/**
|
|
73
80
|
* Returns the current state snapshot for useSyncExternalStore.
|
|
@@ -86,5 +93,5 @@ class r {
|
|
|
86
93
|
});
|
|
87
94
|
}
|
|
88
95
|
export {
|
|
89
|
-
|
|
96
|
+
n as BaseStoreService
|
|
90
97
|
};
|
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
*/
|
|
4
4
|
declare class ControlPersistenceService {
|
|
5
5
|
private readonly storageKey;
|
|
6
|
+
/** Whether a write failure has already been logged (avoids log spam). */
|
|
7
|
+
private writeWarned;
|
|
6
8
|
/**
|
|
7
9
|
* Gets persisted value for a control
|
|
8
10
|
* @param sectionName - Name of the section
|
|
@@ -1,5 +1,8 @@
|
|
|
1
|
+
"use client";
|
|
1
2
|
class a {
|
|
2
3
|
storageKey = "dev-panel-controls-persistence";
|
|
4
|
+
/** Whether a write failure has already been logged (avoids log spam). */
|
|
5
|
+
writeWarned = !1;
|
|
3
6
|
/**
|
|
4
7
|
* Gets persisted value for a control
|
|
5
8
|
* @param sectionName - Name of the section
|
|
@@ -7,12 +10,13 @@ class a {
|
|
|
7
10
|
* @returns Persisted value or undefined if not found
|
|
8
11
|
*/
|
|
9
12
|
getPersistedValue(e, s) {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
13
|
+
if (!(typeof localStorage > "u"))
|
|
14
|
+
try {
|
|
15
|
+
const r = localStorage.getItem(this.storageKey);
|
|
16
|
+
return r ? JSON.parse(r)[e]?.[s] : void 0;
|
|
17
|
+
} catch {
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
16
20
|
}
|
|
17
21
|
/**
|
|
18
22
|
* Sets persisted value for a control
|
|
@@ -20,12 +24,14 @@ class a {
|
|
|
20
24
|
* @param controlKey - Key of the control within the section
|
|
21
25
|
* @param value - Value to persist
|
|
22
26
|
*/
|
|
23
|
-
setPersistedValue(e, s,
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
27
|
+
setPersistedValue(e, s, r) {
|
|
28
|
+
if (!(typeof localStorage > "u"))
|
|
29
|
+
try {
|
|
30
|
+
const t = localStorage.getItem(this.storageKey), o = t ? JSON.parse(t) : {};
|
|
31
|
+
o[e] || (o[e] = {}), o[e][s] = r, localStorage.setItem(this.storageKey, JSON.stringify(o));
|
|
32
|
+
} catch (t) {
|
|
33
|
+
this.writeWarned || (console.warn(`[DevPanel] Failed to persist "${e}.${s}" (quota exceeded or value not serializable).`, t), this.writeWarned = !0);
|
|
34
|
+
}
|
|
29
35
|
}
|
|
30
36
|
/**
|
|
31
37
|
* Removes persisted value for a control
|
|
@@ -33,26 +39,28 @@ class a {
|
|
|
33
39
|
* @param controlKey - Key of the control within the section
|
|
34
40
|
*/
|
|
35
41
|
removePersistedValue(e, s) {
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
42
|
+
if (!(typeof localStorage > "u"))
|
|
43
|
+
try {
|
|
44
|
+
const r = localStorage.getItem(this.storageKey);
|
|
45
|
+
if (!r) return;
|
|
46
|
+
const t = JSON.parse(r);
|
|
47
|
+
t[e] && (delete t[e][s], Object.keys(t[e]).length === 0 && delete t[e], localStorage.setItem(this.storageKey, JSON.stringify(t)));
|
|
48
|
+
} catch {
|
|
49
|
+
}
|
|
43
50
|
}
|
|
44
51
|
/**
|
|
45
52
|
* Removes all persisted values for a section
|
|
46
53
|
* @param sectionName - Name of the section
|
|
47
54
|
*/
|
|
48
55
|
removeSection(e) {
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
+
if (!(typeof localStorage > "u"))
|
|
57
|
+
try {
|
|
58
|
+
const s = localStorage.getItem(this.storageKey);
|
|
59
|
+
if (!s) return;
|
|
60
|
+
const r = JSON.parse(s);
|
|
61
|
+
delete r[e], localStorage.setItem(this.storageKey, JSON.stringify(r));
|
|
62
|
+
} catch {
|
|
63
|
+
}
|
|
56
64
|
}
|
|
57
65
|
}
|
|
58
66
|
const l = new a();
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
+
"use client";
|
|
1
2
|
import { useSyncExternalStore as n } from "react";
|
|
2
3
|
import { BaseStoreService as c } from "./BaseStoreService.js";
|
|
3
4
|
const S = "dev-panel-sections-storage";
|
|
4
|
-
class
|
|
5
|
+
class l extends c {
|
|
5
6
|
/**
|
|
6
7
|
* Creates a new DevPanelSectionsService instance.
|
|
7
8
|
*/
|
|
@@ -96,7 +97,7 @@ class a extends c {
|
|
|
96
97
|
this.setState(() => ({}));
|
|
97
98
|
};
|
|
98
99
|
}
|
|
99
|
-
const r = new
|
|
100
|
+
const r = new l();
|
|
100
101
|
function p() {
|
|
101
102
|
return n(r.subscribe, r.getSnapshot);
|
|
102
103
|
}
|
package/dist/store/UIStore.d.ts
CHANGED
|
@@ -1,4 +1,18 @@
|
|
|
1
1
|
import { DevPanelUIState, Position } from '../components/DevPanel/types';
|
|
2
|
+
/**
|
|
3
|
+
* Imperatively shows the dev panel. Usable outside React (e.g. the console API).
|
|
4
|
+
* The panel still only appears on screen if at least one section is registered.
|
|
5
|
+
*/
|
|
6
|
+
export declare function showDevPanel(): void;
|
|
7
|
+
/**
|
|
8
|
+
* Imperatively hides the dev panel. Usable outside React (e.g. the console API).
|
|
9
|
+
*/
|
|
10
|
+
export declare function hideDevPanel(): void;
|
|
11
|
+
/**
|
|
12
|
+
* Imperatively toggles the dev panel visibility — mirrors the keyboard hotkey.
|
|
13
|
+
* Usable outside React (e.g. the console API).
|
|
14
|
+
*/
|
|
15
|
+
export declare function toggleDevPanel(): void;
|
|
2
16
|
/**
|
|
3
17
|
* React hook that provides access to the complete dev panel UI state and actions.
|
|
4
18
|
* Uses useSyncExternalStore for optimal performance and React 18 compatibility.
|
package/dist/store/UIStore.js
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
|
+
"use client";
|
|
1
2
|
import { useSyncExternalStore as r } from "react";
|
|
2
3
|
import { BaseStoreService as o } from "./BaseStoreService.js";
|
|
3
|
-
const u = "dev-panel-ui-storage",
|
|
4
|
+
const u = "dev-panel-ui-storage", l = { x: 20, y: 20 }, n = {
|
|
4
5
|
isVisible: !1,
|
|
5
6
|
isCollapsed: !1,
|
|
6
|
-
position:
|
|
7
|
+
position: l,
|
|
7
8
|
currentTheme: "auto"
|
|
8
9
|
};
|
|
9
|
-
class
|
|
10
|
+
class h extends o {
|
|
10
11
|
/**
|
|
11
12
|
* Creates a new DevPanelUIService instance and loads persisted state from localStorage.
|
|
12
13
|
*/
|
|
@@ -58,6 +59,8 @@ class a extends o {
|
|
|
58
59
|
* @private
|
|
59
60
|
*/
|
|
60
61
|
applyTheme(t) {
|
|
62
|
+
if (typeof document > "u")
|
|
63
|
+
return;
|
|
61
64
|
const s = document.documentElement;
|
|
62
65
|
t === "auto" || t === "" ? s.removeAttribute("data-dev-panel-theme") : s.setAttribute("data-dev-panel-theme", t);
|
|
63
66
|
}
|
|
@@ -113,8 +116,17 @@ class a extends o {
|
|
|
113
116
|
this.setState(() => ({ ...n })), this.applyTheme(n.currentTheme);
|
|
114
117
|
};
|
|
115
118
|
}
|
|
116
|
-
const e = new
|
|
117
|
-
function
|
|
119
|
+
const e = new h();
|
|
120
|
+
function T() {
|
|
121
|
+
e.setVisible(!0);
|
|
122
|
+
}
|
|
123
|
+
function p() {
|
|
124
|
+
e.setVisible(!1);
|
|
125
|
+
}
|
|
126
|
+
function b() {
|
|
127
|
+
e.setVisible(!e.getSnapshot().isVisible);
|
|
128
|
+
}
|
|
129
|
+
function a() {
|
|
118
130
|
return {
|
|
119
131
|
...r(e.subscribe, e.getSnapshot),
|
|
120
132
|
setVisible: e.setVisible,
|
|
@@ -126,19 +138,19 @@ function l() {
|
|
|
126
138
|
reset: e.reset
|
|
127
139
|
};
|
|
128
140
|
}
|
|
129
|
-
function
|
|
141
|
+
function d() {
|
|
130
142
|
return r(e.subscribe, () => e.getSnapshot().isVisible);
|
|
131
143
|
}
|
|
132
|
-
function
|
|
144
|
+
function S() {
|
|
133
145
|
return r(e.subscribe, () => e.getSnapshot().isCollapsed);
|
|
134
146
|
}
|
|
135
|
-
function
|
|
147
|
+
function f() {
|
|
136
148
|
return r(e.subscribe, () => e.getSnapshot().position);
|
|
137
149
|
}
|
|
138
|
-
function
|
|
150
|
+
function g() {
|
|
139
151
|
return r(e.subscribe, () => e.getSnapshot().currentTheme);
|
|
140
152
|
}
|
|
141
|
-
function
|
|
153
|
+
function P() {
|
|
142
154
|
return {
|
|
143
155
|
currentTheme: r(e.subscribe, () => e.getSnapshot().currentTheme),
|
|
144
156
|
setTheme: e.setTheme,
|
|
@@ -146,7 +158,7 @@ function d() {
|
|
|
146
158
|
getCurrentTheme: e.getCurrentTheme
|
|
147
159
|
};
|
|
148
160
|
}
|
|
149
|
-
function
|
|
161
|
+
function v() {
|
|
150
162
|
return {
|
|
151
163
|
setVisible: e.setVisible,
|
|
152
164
|
setCollapsed: e.setCollapsed,
|
|
@@ -157,22 +169,25 @@ function C() {
|
|
|
157
169
|
reset: e.reset
|
|
158
170
|
};
|
|
159
171
|
}
|
|
160
|
-
function
|
|
172
|
+
function C() {
|
|
161
173
|
return {
|
|
162
174
|
setTheme: e.setTheme,
|
|
163
175
|
resetTheme: e.resetTheme,
|
|
164
176
|
getCurrentTheme: e.getCurrentTheme
|
|
165
177
|
};
|
|
166
178
|
}
|
|
167
|
-
const
|
|
179
|
+
const V = a;
|
|
168
180
|
export {
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
b as
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
181
|
+
p as hideDevPanel,
|
|
182
|
+
T as showDevPanel,
|
|
183
|
+
b as toggleDevPanel,
|
|
184
|
+
g as useCurrentTheme,
|
|
185
|
+
S as useDevPanelCollapsed,
|
|
186
|
+
f as useDevPanelPosition,
|
|
187
|
+
V as useDevPanelStore,
|
|
188
|
+
P as useDevPanelTheme,
|
|
189
|
+
C as useDevPanelThemeActions,
|
|
190
|
+
a as useDevPanelUI,
|
|
191
|
+
v as useDevPanelUIActions,
|
|
192
|
+
d as useDevPanelVisible
|
|
178
193
|
};
|
|
@@ -1,15 +1,16 @@
|
|
|
1
|
-
|
|
1
|
+
"use client";
|
|
2
|
+
function c(...t) {
|
|
2
3
|
const s = [];
|
|
3
|
-
for (const e of
|
|
4
|
+
for (const e of t)
|
|
4
5
|
if (e) {
|
|
5
6
|
if (typeof e == "string")
|
|
6
7
|
s.push(e);
|
|
7
8
|
else if (typeof e == "object")
|
|
8
|
-
for (const [
|
|
9
|
-
n && s.push(
|
|
9
|
+
for (const [o, n] of Object.entries(e))
|
|
10
|
+
n && s.push(o);
|
|
10
11
|
}
|
|
11
12
|
return { className: s.join(" ") };
|
|
12
13
|
}
|
|
13
14
|
export {
|
|
14
|
-
|
|
15
|
+
c as className
|
|
15
16
|
};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
|
|
1
|
+
"use client";
|
|
2
|
+
function l(e, a, t = {}, c = {}) {
|
|
2
3
|
return {
|
|
3
4
|
key: e,
|
|
4
5
|
action: a,
|
|
@@ -6,9 +7,9 @@ function c(e, a, t = {}, y = {}) {
|
|
|
6
7
|
shiftKey: t.shift,
|
|
7
8
|
altKey: t.alt,
|
|
8
9
|
metaKey: t.meta,
|
|
9
|
-
...
|
|
10
|
+
...c
|
|
10
11
|
};
|
|
11
12
|
}
|
|
12
13
|
export {
|
|
13
|
-
|
|
14
|
+
l as createHotkey
|
|
14
15
|
};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Structural deep-equality check used to skip redundant store updates and
|
|
3
|
+
* re-registrations.
|
|
4
|
+
*
|
|
5
|
+
* Preferable to comparing two `JSON.stringify` outputs because it:
|
|
6
|
+
* - does not allocate two full string copies on every call;
|
|
7
|
+
* - is insensitive to object key order;
|
|
8
|
+
* - compares functions by reference (`Object.is`) instead of silently dropping
|
|
9
|
+
* them, so a control whose only change is a new `onChange` handler is still
|
|
10
|
+
* detected as changed.
|
|
11
|
+
*
|
|
12
|
+
* Note: like `JSON.stringify`, it does not guard against circular references;
|
|
13
|
+
* the states compared here (UI state, control descriptors) are never circular.
|
|
14
|
+
*
|
|
15
|
+
* @param a - First value
|
|
16
|
+
* @param b - Second value
|
|
17
|
+
* @returns `true` when the two values are structurally equal
|
|
18
|
+
*/
|
|
19
|
+
export declare function deepEqual(a: unknown, b: unknown): boolean;
|