@berenjena/react-dev-panel 1.0.0 → 1.0.3
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/LICENSE +21 -0
- package/README.md +444 -1
- package/dist/assets/ButtonControl.css +1 -1
- package/dist/assets/ControlRenderer.css +1 -0
- package/dist/assets/DevPanel.css +1 -1
- package/dist/assets/EmptyContent.css +1 -1
- package/dist/assets/Input.css +1 -1
- package/dist/assets/RangeControl.css +1 -0
- package/dist/assets/Section.css +1 -1
- package/dist/assets/SeparatorControl.css +1 -0
- package/dist/assets/index.css +1 -1
- package/dist/assets/index2.css +1 -0
- package/dist/components/ControlRenderer/ControlRenderer.js +30 -6
- package/dist/components/ControlRenderer/controls/BooleanControl/BooleanControl.js +9 -10
- package/dist/components/ControlRenderer/controls/ButtonControl/ButtonControl.js +3 -3
- package/dist/components/ControlRenderer/controls/DateControl/DateControl.d.ts +29 -0
- package/dist/components/ControlRenderer/controls/DateControl/DateControl.js +31 -0
- package/dist/components/ControlRenderer/controls/DateControl/index.d.ts +1 -0
- package/dist/components/ControlRenderer/controls/DateControl/index.js +4 -0
- package/dist/components/ControlRenderer/controls/DateControl/types.d.ts +12 -0
- package/dist/components/ControlRenderer/controls/NumberControl/NumberControl.js +8 -8
- package/dist/components/ControlRenderer/controls/RangeControl/RangeControl.d.ts +30 -0
- package/dist/components/ControlRenderer/controls/RangeControl/RangeControl.js +40 -0
- package/dist/components/ControlRenderer/controls/RangeControl/index.d.ts +1 -0
- package/dist/components/ControlRenderer/controls/RangeControl/index.js +4 -0
- package/dist/components/ControlRenderer/controls/RangeControl/types.d.ts +13 -0
- package/dist/components/ControlRenderer/controls/SelectControl/SelectControl.js +6 -9
- package/dist/components/ControlRenderer/controls/SeparatorControl/SeparatorControl.d.ts +30 -0
- package/dist/components/ControlRenderer/controls/SeparatorControl/SeparatorControl.js +14 -0
- package/dist/components/ControlRenderer/controls/SeparatorControl/index.d.ts +1 -0
- package/dist/components/ControlRenderer/controls/SeparatorControl/index.js +4 -0
- package/dist/components/ControlRenderer/controls/SeparatorControl/types.d.ts +10 -0
- package/dist/components/ControlRenderer/controls/TextControl/TextControl.js +7 -7
- package/dist/components/ControlRenderer/controls/index.d.ts +3 -1
- package/dist/components/ControlRenderer/controls/index.js +13 -38
- package/dist/components/ControlRenderer/controls/types.d.ts +6 -0
- package/dist/components/ControlRenderer/index.js +1 -1
- package/dist/components/DevPanel/DevPanel.js +43 -41
- package/dist/components/DevPanel/types.d.ts +7 -4
- package/dist/components/EmptyContent/EmptyContent.js +2 -2
- package/dist/components/Input/Input.js +3 -3
- package/dist/components/Logger/index.d.ts +20 -0
- package/dist/components/Logger/index.js +85 -0
- package/dist/components/Section/Section.js +17 -16
- package/dist/components/index.d.ts +1 -0
- package/dist/components/index.js +6 -5
- package/dist/hooks/useDevPanel/useDevPanel.js +10 -10
- package/dist/hooks/useDragAndDrop/useDragAndDrop.d.ts +1 -1
- package/dist/hooks/useHotkeys/types.d.ts +14 -0
- package/dist/hooks/useHotkeys/useHotkey.d.ts +1 -2
- package/dist/hooks/useHotkeys/useHotkeys.d.ts +1 -2
- package/dist/index.d.ts +2 -0
- package/dist/index.js +9 -8
- package/dist/store/store.d.ts +106 -0
- package/dist/store/store.js +239 -0
- package/dist/utils/createHotkey/createHotkey.d.ts +1 -1
- package/dist/utils/formatHotkey/formatHotkey.d.ts +1 -1
- package/dist/utils/getConstrainedPosition/getConstrainedPosition.d.ts +1 -1
- package/dist/utils/getCurrentElementPosition/getCurrentElementPosition.d.ts +1 -1
- package/dist/utils/getPositionAdjustment/getPositionAdjustment.d.ts +2 -2
- package/dist/utils/hasControlChanged/hasControlChanged.js +5 -5
- package/dist/utils/index.d.ts +0 -1
- package/dist/utils/index.js +16 -23
- package/package.json +27 -21
- package/dist/assets/SelectControl.css +0 -1
- package/dist/components/logger.d.ts +0 -5
- package/dist/components/logger.js +0 -7
- package/dist/types.d.ts +0 -18
- package/dist/utils/store/store.d.ts +0 -40
- package/dist/utils/store/store.js +0 -103
- package/dist/vite-env.d.ts +0 -1
- /package/dist/{utils/store → store}/index.d.ts +0 -0
- /package/dist/{utils/store → store}/index.js +0 -0
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { jsxs as r, jsx as e } from "react/jsx-runtime";
|
|
2
|
+
import { useState as l, useRef as D, useEffect as h } from "react";
|
|
3
|
+
import { className as I } from "../../utils/className/className.js";
|
|
4
|
+
import '../../assets/index2.css';const O = "_logger_t8a3p_1", L = "_dark_t8a3p_17", S = "_collapsed_t8a3p_22", J = "_header_t8a3p_27", $ = "_title_t8a3p_49", A = "_controls_t8a3p_62", z = "_toggleButton_t8a3p_68", H = "_closeButton_t8a3p_104", M = "_content_t8a3p_129", R = "_jsonDisplay_t8a3p_139", T = "_empty_t8a3p_152", U = "_badge_t8a3p_162", V = "_updated_t8a3p_175", t = {
|
|
5
|
+
logger: O,
|
|
6
|
+
dark: L,
|
|
7
|
+
collapsed: S,
|
|
8
|
+
header: J,
|
|
9
|
+
title: $,
|
|
10
|
+
controls: A,
|
|
11
|
+
toggleButton: z,
|
|
12
|
+
closeButton: H,
|
|
13
|
+
content: M,
|
|
14
|
+
jsonDisplay: R,
|
|
15
|
+
empty: T,
|
|
16
|
+
badge: U,
|
|
17
|
+
updated: V
|
|
18
|
+
};
|
|
19
|
+
function F({ items: s, title: m = "Logger", theme: c = "auto", defaultCollapsed: f = !0, defaultVisible: y = !0, onClose: p }) {
|
|
20
|
+
const [a, v] = l(f), [N, b] = l(y), [C, d] = l(!1), [k, g] = l(!1), [u, w] = l(0), i = D("");
|
|
21
|
+
function _() {
|
|
22
|
+
v(!a);
|
|
23
|
+
}
|
|
24
|
+
function B() {
|
|
25
|
+
b(!1), p?.();
|
|
26
|
+
}
|
|
27
|
+
function x(o) {
|
|
28
|
+
try {
|
|
29
|
+
return JSON.stringify(o, null, 2);
|
|
30
|
+
} catch (n) {
|
|
31
|
+
return `Error formatting JSON: ${n}`;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
if (h(() => {
|
|
35
|
+
if (c === "auto") {
|
|
36
|
+
const o = window.matchMedia("(prefers-color-scheme: dark)");
|
|
37
|
+
d(o.matches);
|
|
38
|
+
const n = (E) => d(E.matches);
|
|
39
|
+
return o.addEventListener("change", n), () => o.removeEventListener("change", n);
|
|
40
|
+
} else
|
|
41
|
+
d(c === "dark");
|
|
42
|
+
}, [c]), h(() => {
|
|
43
|
+
const o = JSON.stringify(s), n = Object.keys(s).length;
|
|
44
|
+
i.current && i.current !== o && (g(!0), setTimeout(() => g(!1), 600)), w(n), i.current = o;
|
|
45
|
+
}, [s]), !N) return null;
|
|
46
|
+
const j = !s || Object.keys(s).length === 0;
|
|
47
|
+
return /* @__PURE__ */ r("div", { className: `${t.logger} ${C ? t.dark : ""} ${a ? t.collapsed : ""}`, children: [
|
|
48
|
+
/* @__PURE__ */ r("div", { className: t.header, onClick: _, children: [
|
|
49
|
+
/* @__PURE__ */ r("h3", { className: t.title, children: [
|
|
50
|
+
m,
|
|
51
|
+
u > 0 && /* @__PURE__ */ e("span", { ...I(t.badge, { [t.updated]: k }), children: u })
|
|
52
|
+
] }),
|
|
53
|
+
/* @__PURE__ */ r("div", { className: t.controls, children: [
|
|
54
|
+
/* @__PURE__ */ e(
|
|
55
|
+
"button",
|
|
56
|
+
{
|
|
57
|
+
className: t.toggleButton,
|
|
58
|
+
onClick: _,
|
|
59
|
+
type: "button",
|
|
60
|
+
"aria-label": a ? "Expand logger" : "Collapse logger",
|
|
61
|
+
title: a ? "Expand" : "Collapse",
|
|
62
|
+
children: /* @__PURE__ */ e("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", className: a ? t.collapsed : void 0, children: /* @__PURE__ */ e("path", { d: "M16.843 10.211A.75.75 0 0 0 16.251 9H7.75a.75.75 0 0 0-.591 1.212l4.258 5.498a.746.746 0 0 0 1.183-.001l4.243-5.498z" }) })
|
|
63
|
+
}
|
|
64
|
+
),
|
|
65
|
+
p && /* @__PURE__ */ e(
|
|
66
|
+
"button",
|
|
67
|
+
{
|
|
68
|
+
className: t.closeButton,
|
|
69
|
+
type: "button",
|
|
70
|
+
"aria-label": "Close logger",
|
|
71
|
+
title: "Close",
|
|
72
|
+
onClick: (o) => {
|
|
73
|
+
o.stopPropagation(), B();
|
|
74
|
+
},
|
|
75
|
+
children: /* @__PURE__ */ e("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", children: /* @__PURE__ */ e("path", { d: "m12 10.93 5.719-5.72a.749.749 0 1 1 1.062 1.062l-5.72 5.719 5.719 5.719a.75.75 0 1 1-1.061 1.062L12 13.053l-5.719 5.719A.75.75 0 0 1 5.22 17.71l5.719-5.719-5.72-5.719A.752.752 0 0 1 6.281 5.21z" }) })
|
|
76
|
+
}
|
|
77
|
+
)
|
|
78
|
+
] })
|
|
79
|
+
] }),
|
|
80
|
+
!a && /* @__PURE__ */ e("div", { className: t.content, children: j ? /* @__PURE__ */ e("div", { className: t.empty, children: "No data to display" }) : /* @__PURE__ */ e("pre", { className: t.jsonDisplay, children: /* @__PURE__ */ e("code", { children: x(s) }) }) })
|
|
81
|
+
] });
|
|
82
|
+
}
|
|
83
|
+
export {
|
|
84
|
+
F as Logger
|
|
85
|
+
};
|
|
@@ -1,23 +1,24 @@
|
|
|
1
|
-
import { jsxs as
|
|
2
|
-
import { ControlRenderer as
|
|
3
|
-
import { useDevPanelActions as r } from "../../
|
|
4
|
-
import '../../assets/Section.css';const d = "
|
|
1
|
+
import { jsxs as o, jsx as e } from "react/jsx-runtime";
|
|
2
|
+
import { ControlRenderer as i } from "../ControlRenderer/ControlRenderer.js";
|
|
3
|
+
import { useDevPanelActions as r } from "../../store/store.js";
|
|
4
|
+
import '../../assets/Section.css';const d = "_section_1vgul_1", g = "_header_1vgul_8", _ = "_title_1vgul_15", p = "_toggle_1vgul_20", m = "_collapsed_1vgul_29", v = "_content_1vgul_35", l = {
|
|
5
5
|
section: d,
|
|
6
|
-
header:
|
|
7
|
-
title:
|
|
8
|
-
toggle:
|
|
9
|
-
|
|
6
|
+
header: g,
|
|
7
|
+
title: _,
|
|
8
|
+
toggle: p,
|
|
9
|
+
collapsed: m,
|
|
10
|
+
content: v
|
|
10
11
|
};
|
|
11
|
-
function
|
|
12
|
-
const
|
|
13
|
-
return /* @__PURE__ */
|
|
14
|
-
/* @__PURE__ */
|
|
15
|
-
/* @__PURE__ */
|
|
16
|
-
/* @__PURE__ */
|
|
12
|
+
function x({ sectionName: n, section: t }) {
|
|
13
|
+
const c = r();
|
|
14
|
+
return /* @__PURE__ */ o("div", { className: l.section, children: [
|
|
15
|
+
/* @__PURE__ */ o("div", { className: l.header, onClick: () => c.toggleSectionCollapse(n), children: [
|
|
16
|
+
/* @__PURE__ */ e("span", { className: l.title, children: t.name }),
|
|
17
|
+
/* @__PURE__ */ e("span", { className: l.toggle, children: /* @__PURE__ */ e("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", className: t.isCollapsed ? l.collapsed : void 0, children: /* @__PURE__ */ e("path", { d: "M10.211 7.155A.75.75 0 0 0 9 7.747v8.501a.75.75 0 0 0 1.212.591l5.498-4.258a.746.746 0 0 0-.001-1.183l-5.498-4.243z" }) }) })
|
|
17
18
|
] }),
|
|
18
|
-
!t.isCollapsed && /* @__PURE__ */
|
|
19
|
+
!t.isCollapsed && /* @__PURE__ */ e("div", { className: l.content, children: Object.entries(t.controls).map(([s, a]) => /* @__PURE__ */ e(i, { name: s, control: a }, s)) })
|
|
19
20
|
] });
|
|
20
21
|
}
|
|
21
22
|
export {
|
|
22
|
-
|
|
23
|
+
x as Section
|
|
23
24
|
};
|
package/dist/components/index.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { DevPanel as
|
|
1
|
+
import { controls as e } from "./ControlRenderer/controls/index.js";
|
|
2
|
+
import { DevPanel as n } from "./DevPanel/DevPanel.js";
|
|
3
|
+
import { ControlRenderer as l } from "./ControlRenderer/ControlRenderer.js";
|
|
3
4
|
export {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
l as ControlRenderer,
|
|
6
|
+
n as DevPanel,
|
|
7
|
+
e as controls
|
|
7
8
|
};
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import { useRef as
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
function C(e,
|
|
5
|
-
const
|
|
1
|
+
import { useRef as f, useEffect as s } from "react";
|
|
2
|
+
import { useDevPanelStore as p } from "../../store/store.js";
|
|
3
|
+
import { hasControlsChanged as v } from "../../utils/hasControlChanged/hasControlChanged.js";
|
|
4
|
+
function C(e, r) {
|
|
5
|
+
const { sections: t, registerSection: o, unregisterSection: i } = p(), n = f(void 0);
|
|
6
6
|
s(() => {
|
|
7
|
-
const
|
|
8
|
-
(
|
|
9
|
-
}, [
|
|
10
|
-
|
|
11
|
-
}, [
|
|
7
|
+
const u = t[e] !== void 0;
|
|
8
|
+
(v(r, n.current) || !u) && (o(e, r), n.current = r);
|
|
9
|
+
}, [e, r, t, o]), s(() => () => {
|
|
10
|
+
i(e);
|
|
11
|
+
}, [e, i]);
|
|
12
12
|
}
|
|
13
13
|
export {
|
|
14
14
|
C as useDevPanel
|
|
@@ -4,3 +4,17 @@ export interface UseHotkeysOptions {
|
|
|
4
4
|
preventDefault?: boolean;
|
|
5
5
|
stopPropagation?: boolean;
|
|
6
6
|
}
|
|
7
|
+
|
|
8
|
+
export interface HotkeyConfig {
|
|
9
|
+
key: string;
|
|
10
|
+
description?: string;
|
|
11
|
+
ctrlKey?: boolean;
|
|
12
|
+
shiftKey?: boolean;
|
|
13
|
+
altKey?: boolean;
|
|
14
|
+
metaKey?: boolean;
|
|
15
|
+
preventDefault?: boolean;
|
|
16
|
+
stopPropagation?: boolean;
|
|
17
|
+
enabled?: boolean;
|
|
18
|
+
target?: HTMLElement | Window | Document;
|
|
19
|
+
action: (event: KeyboardEvent) => void;
|
|
20
|
+
}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import { HotkeyConfig } from '
|
|
2
|
-
import { UseHotkeysOptions } from './types';
|
|
1
|
+
import { HotkeyConfig, UseHotkeysOptions } from './types';
|
|
3
2
|
/**
|
|
4
3
|
* Hook for handling keyboard shortcuts (hotkeys) with support for modifier keys
|
|
5
4
|
* and multiple key combinations.
|
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { DevPanel as
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
l as
|
|
7
|
-
n as
|
|
8
|
-
|
|
1
|
+
import { controls as r } from "./components/ControlRenderer/controls/index.js";
|
|
2
|
+
import { DevPanel as n } from "./components/DevPanel/DevPanel.js";
|
|
3
|
+
import { ControlRenderer as l } from "./components/ControlRenderer/ControlRenderer.js";
|
|
4
|
+
import { useDevPanel as p } from "./hooks/useDevPanel/useDevPanel.js";
|
|
5
|
+
import './assets/index.css';export {
|
|
6
|
+
l as ControlRenderer,
|
|
7
|
+
n as DevPanel,
|
|
8
|
+
r as controls,
|
|
9
|
+
p as useDevPanel
|
|
9
10
|
};
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { ControlsGroup } from '../components/ControlRenderer/controls/types';
|
|
2
|
+
import { DevPanelState, Position } from '../components/DevPanel/types';
|
|
3
|
+
/**
|
|
4
|
+
* React hook that provides access to the complete dev panel state and actions.
|
|
5
|
+
* Uses useSyncExternalStore for optimal performance and React 18 compatibility.
|
|
6
|
+
*
|
|
7
|
+
* @returns Object containing the current state and all available actions
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```typescript
|
|
11
|
+
* const {
|
|
12
|
+
* isVisible,
|
|
13
|
+
* sections,
|
|
14
|
+
* setVisible,
|
|
15
|
+
* registerSection
|
|
16
|
+
* } = useDevPanelStore();
|
|
17
|
+
* ```
|
|
18
|
+
*/
|
|
19
|
+
export declare function useDevPanelStore(): DevPanelState & {
|
|
20
|
+
setVisible: (visible: boolean) => void;
|
|
21
|
+
setCollapsed: (collapsed: boolean) => void;
|
|
22
|
+
setPosition: (position: Position) => void;
|
|
23
|
+
registerSection: (name: string, controls: ControlsGroup) => void;
|
|
24
|
+
unregisterSection: (name: string) => void;
|
|
25
|
+
toggleSectionCollapse: (name: string) => void;
|
|
26
|
+
reset: () => void;
|
|
27
|
+
};
|
|
28
|
+
/**
|
|
29
|
+
* React hook that subscribes only to the visibility state of the dev panel.
|
|
30
|
+
* Optimized for components that only need to know if the panel is visible.
|
|
31
|
+
*
|
|
32
|
+
* @returns Boolean indicating whether the dev panel is visible
|
|
33
|
+
*
|
|
34
|
+
* @example
|
|
35
|
+
* ```typescript
|
|
36
|
+
* const isVisible = useDevPanelVisible();
|
|
37
|
+
* ```
|
|
38
|
+
*/
|
|
39
|
+
export declare function useDevPanelVisible(): boolean;
|
|
40
|
+
/**
|
|
41
|
+
* React hook that subscribes only to the collapsed state of the dev panel.
|
|
42
|
+
* Optimized for components that only need to know if the panel is collapsed.
|
|
43
|
+
*
|
|
44
|
+
* @returns Boolean indicating whether the dev panel is collapsed
|
|
45
|
+
*
|
|
46
|
+
* @example
|
|
47
|
+
* ```typescript
|
|
48
|
+
* const isCollapsed = useDevPanelCollapsed();
|
|
49
|
+
* ```
|
|
50
|
+
*/
|
|
51
|
+
export declare function useDevPanelCollapsed(): boolean;
|
|
52
|
+
/**
|
|
53
|
+
* React hook that subscribes only to the position state of the dev panel.
|
|
54
|
+
* Optimized for components that only need to track panel position.
|
|
55
|
+
*
|
|
56
|
+
* @returns Position object with x and y coordinates
|
|
57
|
+
*
|
|
58
|
+
* @example
|
|
59
|
+
* ```typescript
|
|
60
|
+
* const position = useDevPanelPosition();
|
|
61
|
+
* console.log(`Panel is at ${position.x}, ${position.y}`);
|
|
62
|
+
* ```
|
|
63
|
+
*/
|
|
64
|
+
export declare function useDevPanelPosition(): Position;
|
|
65
|
+
/**
|
|
66
|
+
* React hook that subscribes only to the sections state of the dev panel.
|
|
67
|
+
* Optimized for components that only need to access panel sections.
|
|
68
|
+
*
|
|
69
|
+
* @returns Record of section names to section objects
|
|
70
|
+
*
|
|
71
|
+
* @example
|
|
72
|
+
* ```typescript
|
|
73
|
+
* const sections = useDevPanelSections();
|
|
74
|
+
* const sectionNames = Object.keys(sections);
|
|
75
|
+
* ```
|
|
76
|
+
*/
|
|
77
|
+
export declare function useDevPanelSections(): Record<string, import('../components/DevPanel/types').DevPanelSection>;
|
|
78
|
+
/**
|
|
79
|
+
* React hook that provides access to all dev panel actions without subscribing to state.
|
|
80
|
+
* Ideal for components that only need to trigger actions without rendering on state changes.
|
|
81
|
+
*
|
|
82
|
+
* @returns Object containing all available actions
|
|
83
|
+
*
|
|
84
|
+
* @example
|
|
85
|
+
* ```typescript
|
|
86
|
+
* const { setVisible, registerSection, reset } = useDevPanelActions();
|
|
87
|
+
*
|
|
88
|
+
* // Toggle panel visibility
|
|
89
|
+
* setVisible(true);
|
|
90
|
+
*
|
|
91
|
+
* // Add a new section
|
|
92
|
+
* registerSection('mySection', myControls);
|
|
93
|
+
*
|
|
94
|
+
* // Reset everything
|
|
95
|
+
* reset();
|
|
96
|
+
* ```
|
|
97
|
+
*/
|
|
98
|
+
export declare function useDevPanelActions(): {
|
|
99
|
+
setVisible: (visible: boolean) => void;
|
|
100
|
+
setCollapsed: (collapsed: boolean) => void;
|
|
101
|
+
setPosition: (position: Position) => void;
|
|
102
|
+
registerSection: (name: string, controls: ControlsGroup) => void;
|
|
103
|
+
unregisterSection: (name: string) => void;
|
|
104
|
+
toggleSectionCollapse: (name: string) => void;
|
|
105
|
+
reset: () => void;
|
|
106
|
+
};
|
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
import { useSyncExternalStore as o } from "react";
|
|
2
|
+
const n = "dev-panel-storage", a = { x: 20, y: 20 };
|
|
3
|
+
class d {
|
|
4
|
+
/** The current state of the dev panel */
|
|
5
|
+
state = {
|
|
6
|
+
isVisible: !1,
|
|
7
|
+
isCollapsed: !1,
|
|
8
|
+
sections: {},
|
|
9
|
+
position: a
|
|
10
|
+
};
|
|
11
|
+
/** Set of listeners subscribed to state changes */
|
|
12
|
+
listeners = /* @__PURE__ */ new Set();
|
|
13
|
+
/**
|
|
14
|
+
* Creates a new DevPanelService instance and loads persisted state from localStorage.
|
|
15
|
+
*/
|
|
16
|
+
constructor() {
|
|
17
|
+
this.loadState();
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Saves the current state to localStorage.
|
|
21
|
+
* Only persists visibility, collapse state, position, and section collapse states.
|
|
22
|
+
* Sections themselves are not persisted as they are dynamic and recreated on mount.
|
|
23
|
+
*
|
|
24
|
+
* @private
|
|
25
|
+
*/
|
|
26
|
+
saveState() {
|
|
27
|
+
try {
|
|
28
|
+
const e = {
|
|
29
|
+
isVisible: this.state.isVisible,
|
|
30
|
+
isCollapsed: this.state.isCollapsed,
|
|
31
|
+
position: this.state.position,
|
|
32
|
+
sectionCollapseState: Object.fromEntries(
|
|
33
|
+
Object.entries(this.state.sections).map(([t, i]) => [t, i.isCollapsed ?? !1])
|
|
34
|
+
)
|
|
35
|
+
};
|
|
36
|
+
localStorage.setItem(n, JSON.stringify(e));
|
|
37
|
+
} catch {
|
|
38
|
+
console.warn("Failed to save state to localStorage");
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Loads previously persisted state from localStorage.
|
|
43
|
+
* If no state exists or loading fails, uses default values.
|
|
44
|
+
*
|
|
45
|
+
* @private
|
|
46
|
+
*/
|
|
47
|
+
loadState() {
|
|
48
|
+
try {
|
|
49
|
+
const e = localStorage.getItem(n);
|
|
50
|
+
if (e) {
|
|
51
|
+
const t = JSON.parse(e);
|
|
52
|
+
this.state = {
|
|
53
|
+
...this.state,
|
|
54
|
+
isVisible: t.isVisible ?? !1,
|
|
55
|
+
isCollapsed: t.isCollapsed ?? !1,
|
|
56
|
+
position: t.position ?? a
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
} catch {
|
|
60
|
+
console.warn("Failed to load persisted state from localStorage");
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Notifies all subscribed listeners about state changes.
|
|
65
|
+
*
|
|
66
|
+
* @private
|
|
67
|
+
*/
|
|
68
|
+
notifySubscribers() {
|
|
69
|
+
this.listeners.forEach((e) => e());
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Updates the state using an updater function, persists the new state,
|
|
73
|
+
* and notifies all subscribers.
|
|
74
|
+
*
|
|
75
|
+
* @param updater - Function that receives current state and returns new state
|
|
76
|
+
* @private
|
|
77
|
+
*/
|
|
78
|
+
setState(e) {
|
|
79
|
+
this.state = e(this.state), this.saveState(), this.notifySubscribers();
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Returns the current state snapshot for useSyncExternalStore.
|
|
83
|
+
*
|
|
84
|
+
* @returns The current dev panel state
|
|
85
|
+
*/
|
|
86
|
+
getSnapshot = () => this.state;
|
|
87
|
+
/**
|
|
88
|
+
* Subscribes a listener to state changes for useSyncExternalStore.
|
|
89
|
+
*
|
|
90
|
+
* @param listener - Function to call when state changes
|
|
91
|
+
* @returns Unsubscribe function
|
|
92
|
+
*/
|
|
93
|
+
subscribe = (e) => (this.listeners.add(e), () => {
|
|
94
|
+
this.listeners.delete(e);
|
|
95
|
+
});
|
|
96
|
+
/**
|
|
97
|
+
* Sets the visibility state of the dev panel.
|
|
98
|
+
*
|
|
99
|
+
* @param visible - Whether the panel should be visible
|
|
100
|
+
*/
|
|
101
|
+
setVisible = (e) => {
|
|
102
|
+
this.setState((t) => ({ ...t, isVisible: e }));
|
|
103
|
+
};
|
|
104
|
+
/**
|
|
105
|
+
* Sets the collapsed state of the dev panel.
|
|
106
|
+
*
|
|
107
|
+
* @param collapsed - Whether the panel should be collapsed
|
|
108
|
+
*/
|
|
109
|
+
setCollapsed = (e) => {
|
|
110
|
+
this.setState((t) => ({ ...t, isCollapsed: e }));
|
|
111
|
+
};
|
|
112
|
+
/**
|
|
113
|
+
* Updates the position of the dev panel.
|
|
114
|
+
*
|
|
115
|
+
* @param position - New position coordinates {x, y}
|
|
116
|
+
*/
|
|
117
|
+
setPosition = (e) => {
|
|
118
|
+
this.setState((t) => ({ ...t, position: e }));
|
|
119
|
+
};
|
|
120
|
+
/**
|
|
121
|
+
* Registers a new section with the dev panel.
|
|
122
|
+
* If a section with the same name already exists, it preserves the existing collapse state.
|
|
123
|
+
* Otherwise, it attempts to restore the collapse state from localStorage.
|
|
124
|
+
*
|
|
125
|
+
* @param name - Unique name for the section
|
|
126
|
+
* @param controls - Array of control configurations for the section
|
|
127
|
+
*/
|
|
128
|
+
registerSection = (e, t) => {
|
|
129
|
+
this.setState((i) => {
|
|
130
|
+
const l = i.sections[e];
|
|
131
|
+
let r = !1;
|
|
132
|
+
try {
|
|
133
|
+
const c = localStorage.getItem(n);
|
|
134
|
+
c && (r = JSON.parse(c).sectionCollapseState?.[e] ?? !1);
|
|
135
|
+
} catch {
|
|
136
|
+
console.warn("Failed to read section collapse state from localStorage");
|
|
137
|
+
}
|
|
138
|
+
const p = l?.isCollapsed ?? r;
|
|
139
|
+
return {
|
|
140
|
+
...i,
|
|
141
|
+
sections: {
|
|
142
|
+
...i.sections,
|
|
143
|
+
[e]: {
|
|
144
|
+
name: e,
|
|
145
|
+
controls: t,
|
|
146
|
+
isCollapsed: p
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
};
|
|
150
|
+
});
|
|
151
|
+
};
|
|
152
|
+
/**
|
|
153
|
+
* Removes a section from the dev panel.
|
|
154
|
+
*
|
|
155
|
+
* @param name - Name of the section to remove
|
|
156
|
+
*/
|
|
157
|
+
unregisterSection = (e) => {
|
|
158
|
+
this.setState((t) => {
|
|
159
|
+
const { [e]: i, ...l } = t.sections;
|
|
160
|
+
return { ...t, sections: l };
|
|
161
|
+
});
|
|
162
|
+
};
|
|
163
|
+
/**
|
|
164
|
+
* Toggles the collapsed state of a specific section.
|
|
165
|
+
*
|
|
166
|
+
* @param name - Name of the section to toggle
|
|
167
|
+
*/
|
|
168
|
+
toggleSectionCollapse = (e) => {
|
|
169
|
+
this.setState((t) => {
|
|
170
|
+
const i = t.sections[e];
|
|
171
|
+
return i ? {
|
|
172
|
+
...t,
|
|
173
|
+
sections: {
|
|
174
|
+
...t.sections,
|
|
175
|
+
[e]: {
|
|
176
|
+
...i,
|
|
177
|
+
isCollapsed: !i.isCollapsed
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
} : t;
|
|
181
|
+
});
|
|
182
|
+
};
|
|
183
|
+
/**
|
|
184
|
+
* Resets the dev panel to its default state.
|
|
185
|
+
* Clears all sections, resets position, and sets visibility and collapse to false.
|
|
186
|
+
*/
|
|
187
|
+
reset = () => {
|
|
188
|
+
this.setState(() => ({
|
|
189
|
+
isVisible: !1,
|
|
190
|
+
isCollapsed: !1,
|
|
191
|
+
sections: {},
|
|
192
|
+
position: a
|
|
193
|
+
}));
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
const s = new d();
|
|
197
|
+
function b() {
|
|
198
|
+
return {
|
|
199
|
+
...o(s.subscribe, s.getSnapshot),
|
|
200
|
+
setVisible: s.setVisible,
|
|
201
|
+
setCollapsed: s.setCollapsed,
|
|
202
|
+
setPosition: s.setPosition,
|
|
203
|
+
registerSection: s.registerSection,
|
|
204
|
+
unregisterSection: s.unregisterSection,
|
|
205
|
+
toggleSectionCollapse: s.toggleSectionCollapse,
|
|
206
|
+
reset: s.reset
|
|
207
|
+
};
|
|
208
|
+
}
|
|
209
|
+
function h() {
|
|
210
|
+
return o(s.subscribe, () => s.getSnapshot().isVisible);
|
|
211
|
+
}
|
|
212
|
+
function f() {
|
|
213
|
+
return o(s.subscribe, () => s.getSnapshot().isCollapsed);
|
|
214
|
+
}
|
|
215
|
+
function C() {
|
|
216
|
+
return o(s.subscribe, () => s.getSnapshot().position);
|
|
217
|
+
}
|
|
218
|
+
function v() {
|
|
219
|
+
return o(s.subscribe, () => s.getSnapshot().sections);
|
|
220
|
+
}
|
|
221
|
+
function P() {
|
|
222
|
+
return {
|
|
223
|
+
setVisible: s.setVisible,
|
|
224
|
+
setCollapsed: s.setCollapsed,
|
|
225
|
+
setPosition: s.setPosition,
|
|
226
|
+
registerSection: s.registerSection,
|
|
227
|
+
unregisterSection: s.unregisterSection,
|
|
228
|
+
toggleSectionCollapse: s.toggleSectionCollapse,
|
|
229
|
+
reset: s.reset
|
|
230
|
+
};
|
|
231
|
+
}
|
|
232
|
+
export {
|
|
233
|
+
P as useDevPanelActions,
|
|
234
|
+
f as useDevPanelCollapsed,
|
|
235
|
+
C as useDevPanelPosition,
|
|
236
|
+
v as useDevPanelSections,
|
|
237
|
+
b as useDevPanelStore,
|
|
238
|
+
h as useDevPanelVisible
|
|
239
|
+
};
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* @returns Object containing the current position, constrained position, and whether adjustment is needed
|
|
5
5
|
*/
|
|
6
6
|
export declare function getPositionAdjustment(element: HTMLElement): {
|
|
7
|
-
currentPosition: import('../../types').Position;
|
|
8
|
-
constrainedPosition: import('../../types').Position;
|
|
7
|
+
currentPosition: import('../../components/DevPanel/types').Position;
|
|
8
|
+
constrainedPosition: import('../../components/DevPanel/types').Position;
|
|
9
9
|
needsAdjustment: boolean;
|
|
10
10
|
};
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
function
|
|
1
|
+
function a(n, r) {
|
|
2
2
|
if (!r) return !0;
|
|
3
|
-
const i = Object.keys(n),
|
|
4
|
-
if (i.length !==
|
|
3
|
+
const i = Object.keys(n), s = Object.keys(r);
|
|
4
|
+
if (i.length !== s.length) return !0;
|
|
5
5
|
for (const u of i) {
|
|
6
6
|
const t = n[u], e = r[u];
|
|
7
|
-
if (!e || t.type !== e.type || t.label !== e.label || t.disabled !== e.disabled || "value" in t && "value" in e && t.value !== e.value || t.type === "number" && e.type === "number" && (t.min !== e.min || t.max !== e.max || t.step !== e.step) || t.type === "select" && e.type === "select" && JSON.stringify(t.options) !== JSON.stringify(e.options) || t.type === "text" && e.type === "text" && t.placeholder !== e.placeholder)
|
|
7
|
+
if (!e || t.type !== e.type || t.label !== e.label || t.disabled !== e.disabled || "value" in t && "value" in e && t.value !== e.value || t.type === "number" && e.type === "number" && (t.min !== e.min || t.max !== e.max || t.step !== e.step) || t.type === "range" && e.type === "range" && (t.min !== e.min || t.max !== e.max || t.step !== e.step) || t.type === "date" && e.type === "date" && (t.min !== e.min || t.max !== e.max) || t.type === "select" && e.type === "select" && JSON.stringify(t.options) !== JSON.stringify(e.options) || t.type === "text" && e.type === "text" && t.placeholder !== e.placeholder)
|
|
8
8
|
return !0;
|
|
9
9
|
}
|
|
10
10
|
return !1;
|
|
11
11
|
}
|
|
12
12
|
export {
|
|
13
|
-
|
|
13
|
+
a as hasControlsChanged
|
|
14
14
|
};
|
package/dist/utils/index.d.ts
CHANGED