@berenjena/react-dev-panel 1.0.1 → 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.
Files changed (71) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +444 -1
  3. package/dist/assets/ButtonControl.css +1 -1
  4. package/dist/assets/ControlRenderer.css +1 -0
  5. package/dist/assets/DevPanel.css +1 -1
  6. package/dist/assets/EmptyContent.css +1 -1
  7. package/dist/assets/Input.css +1 -1
  8. package/dist/assets/RangeControl.css +1 -0
  9. package/dist/assets/Section.css +1 -1
  10. package/dist/assets/SeparatorControl.css +1 -0
  11. package/dist/assets/index.css +1 -1
  12. package/dist/assets/index2.css +1 -0
  13. package/dist/components/ControlRenderer/ControlRenderer.js +30 -6
  14. package/dist/components/ControlRenderer/controls/BooleanControl/BooleanControl.js +9 -10
  15. package/dist/components/ControlRenderer/controls/ButtonControl/ButtonControl.js +3 -3
  16. package/dist/components/ControlRenderer/controls/DateControl/DateControl.d.ts +29 -0
  17. package/dist/components/ControlRenderer/controls/DateControl/DateControl.js +31 -0
  18. package/dist/components/ControlRenderer/controls/DateControl/index.d.ts +1 -0
  19. package/dist/components/ControlRenderer/controls/DateControl/index.js +4 -0
  20. package/dist/components/ControlRenderer/controls/DateControl/types.d.ts +12 -0
  21. package/dist/components/ControlRenderer/controls/RangeControl/RangeControl.d.ts +30 -0
  22. package/dist/components/ControlRenderer/controls/RangeControl/RangeControl.js +40 -0
  23. package/dist/components/ControlRenderer/controls/RangeControl/index.d.ts +1 -0
  24. package/dist/components/ControlRenderer/controls/RangeControl/index.js +4 -0
  25. package/dist/components/ControlRenderer/controls/RangeControl/types.d.ts +13 -0
  26. package/dist/components/ControlRenderer/controls/SelectControl/SelectControl.js +6 -9
  27. package/dist/components/ControlRenderer/controls/SeparatorControl/SeparatorControl.d.ts +30 -0
  28. package/dist/components/ControlRenderer/controls/SeparatorControl/SeparatorControl.js +14 -0
  29. package/dist/components/ControlRenderer/controls/SeparatorControl/index.d.ts +1 -0
  30. package/dist/components/ControlRenderer/controls/SeparatorControl/index.js +4 -0
  31. package/dist/components/ControlRenderer/controls/SeparatorControl/types.d.ts +10 -0
  32. package/dist/components/ControlRenderer/controls/index.d.ts +3 -1
  33. package/dist/components/ControlRenderer/controls/index.js +13 -39
  34. package/dist/components/ControlRenderer/controls/types.d.ts +6 -0
  35. package/dist/components/ControlRenderer/index.js +1 -1
  36. package/dist/components/DevPanel/DevPanel.js +38 -37
  37. package/dist/components/DevPanel/types.d.ts +7 -4
  38. package/dist/components/EmptyContent/EmptyContent.js +2 -2
  39. package/dist/components/Input/Input.js +3 -3
  40. package/dist/components/Logger/index.d.ts +20 -0
  41. package/dist/components/Logger/index.js +85 -0
  42. package/dist/components/Section/Section.js +17 -16
  43. package/dist/components/index.d.ts +1 -0
  44. package/dist/components/index.js +6 -5
  45. package/dist/hooks/useDevPanel/useDevPanel.js +10 -10
  46. package/dist/hooks/useDragAndDrop/useDragAndDrop.d.ts +1 -1
  47. package/dist/hooks/useHotkeys/types.d.ts +14 -0
  48. package/dist/hooks/useHotkeys/useHotkey.d.ts +1 -2
  49. package/dist/hooks/useHotkeys/useHotkeys.d.ts +1 -2
  50. package/dist/index.d.ts +2 -0
  51. package/dist/index.js +9 -8
  52. package/dist/store/store.d.ts +106 -0
  53. package/dist/store/store.js +239 -0
  54. package/dist/utils/createHotkey/createHotkey.d.ts +1 -1
  55. package/dist/utils/formatHotkey/formatHotkey.d.ts +1 -1
  56. package/dist/utils/getConstrainedPosition/getConstrainedPosition.d.ts +1 -1
  57. package/dist/utils/getCurrentElementPosition/getCurrentElementPosition.d.ts +1 -1
  58. package/dist/utils/getPositionAdjustment/getPositionAdjustment.d.ts +2 -2
  59. package/dist/utils/hasControlChanged/hasControlChanged.js +5 -5
  60. package/dist/utils/index.d.ts +0 -1
  61. package/dist/utils/index.js +16 -23
  62. package/package.json +27 -21
  63. package/dist/assets/SelectControl.css +0 -1
  64. package/dist/components/logger.d.ts +0 -5
  65. package/dist/components/logger.js +0 -7
  66. package/dist/types.d.ts +0 -18
  67. package/dist/utils/store/store.d.ts +0 -40
  68. package/dist/utils/store/store.js +0 -103
  69. package/dist/vite-env.d.ts +0 -1
  70. /package/dist/{utils/store → store}/index.d.ts +0 -0
  71. /package/dist/{utils/store → store}/index.js +0 -0
@@ -0,0 +1,31 @@
1
+ import { jsx as m } from "react/jsx-runtime";
2
+ import { useState as o, useEffect as r } from "react";
3
+ import { Input as f } from "../../../Input/Input.js";
4
+ function h({ control: e }) {
5
+ const n = e.event || "onBlur", [l, t] = o(e.value);
6
+ r(() => {
7
+ t(e.value);
8
+ }, [e.value]);
9
+ const s = (u) => {
10
+ const a = u.target.value;
11
+ t(a), n === "onChange" && e.onChange(a);
12
+ }, i = (u) => {
13
+ const a = u.target.value;
14
+ n === "onBlur" && e.onChange(a);
15
+ };
16
+ return /* @__PURE__ */ m(
17
+ f,
18
+ {
19
+ type: "date",
20
+ value: l,
21
+ min: e.min,
22
+ max: e.max,
23
+ disabled: e.disabled,
24
+ onChange: s,
25
+ ...n === "onBlur" && { onBlur: i }
26
+ }
27
+ );
28
+ }
29
+ export {
30
+ h as DateControl
31
+ };
@@ -0,0 +1 @@
1
+ export * from './DateControl';
@@ -0,0 +1,4 @@
1
+ import { DateControl as t } from "./DateControl.js";
2
+ export {
3
+ t as DateControl
4
+ };
@@ -0,0 +1,12 @@
1
+ import { BaseInputControl } from '../types';
2
+ export interface DateControl extends BaseInputControl {
3
+ type: "date";
4
+ value: string; // ISO date string (YYYY-MM-DD)
5
+ min?: string; // ISO date string
6
+ max?: string; // ISO date string
7
+ onChange: (value: string) => void;
8
+ }
9
+
10
+ export interface DateControlProps {
11
+ control: DateControl;
12
+ }
@@ -0,0 +1,30 @@
1
+ import { RangeControlProps } from './types';
2
+ /**
3
+ * Component that renders a range/slider control with configurable event handling
4
+ * @param control - The control to render
5
+ * @param control.event - When to trigger onChange: "onChange" (real-time) or "onBlur" (on focus loss). Defaults to "onChange"
6
+ * @returns The range control component
7
+ *
8
+ * @example
9
+ * ```typescript
10
+ * // Real-time updates (default)
11
+ * <RangeControl control={{
12
+ * type: 'range',
13
+ * value: 50,
14
+ * min: 0,
15
+ * max: 100,
16
+ * step: 1,
17
+ * event: 'onChange',
18
+ * onChange: (value) => setValue(value)
19
+ * }} />
20
+ *
21
+ * // Updates only when losing focus
22
+ * <RangeControl control={{
23
+ * type: 'range',
24
+ * value: 50,
25
+ * event: 'onBlur',
26
+ * onChange: (value) => setValue(value)
27
+ * }} />
28
+ * ```
29
+ */
30
+ export declare function RangeControl({ control }: RangeControlProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,40 @@
1
+ import { jsxs as g, jsx as r } from "react/jsx-runtime";
2
+ import { useState as o, useEffect as m } from "react";
3
+ import '../../../../assets/RangeControl.css';const v = "_container_1ewrb_1", h = "_range_1ewrb_9", d = "_value_1ewrb_116", t = {
4
+ container: v,
5
+ range: h,
6
+ value: d
7
+ };
8
+ function b({ control: e }) {
9
+ const n = e.event || "onChange", [u, l] = o(e.value);
10
+ m(() => {
11
+ l(e.value);
12
+ }, [e.value]);
13
+ const i = (s) => {
14
+ const a = Number(s.target.value);
15
+ l(a), n === "onChange" && e.onChange(a);
16
+ }, c = (s) => {
17
+ const a = Number(s.target.value);
18
+ n === "onBlur" && e.onChange(a);
19
+ };
20
+ return /* @__PURE__ */ g("div", { className: t.container, children: [
21
+ /* @__PURE__ */ r(
22
+ "input",
23
+ {
24
+ type: "range",
25
+ value: u,
26
+ min: e.min,
27
+ max: e.max,
28
+ step: e.step,
29
+ disabled: e.disabled,
30
+ onChange: i,
31
+ ...n === "onBlur" && { onBlur: c },
32
+ className: t.range
33
+ }
34
+ ),
35
+ /* @__PURE__ */ r("span", { className: t.value, children: u })
36
+ ] });
37
+ }
38
+ export {
39
+ b as RangeControl
40
+ };
@@ -0,0 +1 @@
1
+ export * from './RangeControl';
@@ -0,0 +1,4 @@
1
+ import { RangeControl as e } from "./RangeControl.js";
2
+ export {
3
+ e as RangeControl
4
+ };
@@ -0,0 +1,13 @@
1
+ import { BaseInputControl } from '../types';
2
+ export interface RangeControl extends BaseInputControl {
3
+ type: "range";
4
+ value: number;
5
+ min?: number;
6
+ max?: number;
7
+ step?: number;
8
+ onChange: (value: number) => void;
9
+ }
10
+
11
+ export interface RangeControlProps {
12
+ control: RangeControl;
13
+ }
@@ -1,14 +1,11 @@
1
- import { jsx as s } from "react/jsx-runtime";
1
+ import { jsx as t } from "react/jsx-runtime";
2
2
  import { Select as n } from "../../../Select/Select.js";
3
- import '../../../../assets/SelectControl.css';const r = "_select_1w3k9_1", c = {
4
- select: r
5
- };
6
- function o({ control: t }) {
7
- return /* @__PURE__ */ s(n, { value: t.value, disabled: t.disabled, onChange: (e) => t.onChange(e.target.value), className: c.select, children: t.options.map((e) => {
8
- const l = typeof e == "string" ? e : e.value, a = typeof e == "string" ? e : e.label;
9
- return /* @__PURE__ */ s("option", { value: l, children: a }, l);
3
+ function s({ control: a }) {
4
+ return /* @__PURE__ */ t(n, { value: a.value, disabled: a.disabled, onChange: (e) => a.onChange(e.target.value), children: a.options.map((e) => {
5
+ const l = typeof e == "string" ? e : e.value, r = typeof e == "string" ? e : e.label;
6
+ return /* @__PURE__ */ t("option", { value: l, children: r }, l);
10
7
  }) });
11
8
  }
12
9
  export {
13
- o as SelectControl
10
+ s as SelectControl
14
11
  };
@@ -0,0 +1,30 @@
1
+ import { SeparatorControlProps } from './types';
2
+ /**
3
+ * Component that renders a visual separator to organize control groups
4
+ * @param control - The control to render
5
+ * @param control.style - The style of separator: "line" (default), "space", or "label"
6
+ * @param control.label - Optional label text (only shown when style is "label")
7
+ * @returns The separator control component
8
+ *
9
+ * @example
10
+ * ```typescript
11
+ * // Simple line separator
12
+ * <SeparatorControl control={{
13
+ * type: 'separator'
14
+ * }} />
15
+ *
16
+ * // Separator with label
17
+ * <SeparatorControl control={{
18
+ * type: 'separator',
19
+ * style: 'label',
20
+ * label: 'Advanced Settings'
21
+ * }} />
22
+ *
23
+ * // Space separator
24
+ * <SeparatorControl control={{
25
+ * type: 'separator',
26
+ * style: 'space'
27
+ * }} />
28
+ * ```
29
+ */
30
+ export declare function SeparatorControl({ control }: SeparatorControlProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,14 @@
1
+ import { jsx as e } from "react/jsx-runtime";
2
+ import '../../../../assets/SeparatorControl.css';const s = "_line_12cvo_1", c = "_space_12cvo_9", t = "_labelContainer_12cvo_14", i = "_label_12cvo_14", l = {
3
+ line: s,
4
+ space: c,
5
+ labelContainer: t,
6
+ label: i
7
+ };
8
+ function r({ control: a }) {
9
+ const n = a.style || "line";
10
+ return n === "space" ? /* @__PURE__ */ e("div", { className: l.space }) : n === "label" && a.label ? /* @__PURE__ */ e("div", { className: l.labelContainer, children: /* @__PURE__ */ e("span", { className: l.label, children: a.label }) }) : /* @__PURE__ */ e("div", { className: l.line });
11
+ }
12
+ export {
13
+ r as SeparatorControl
14
+ };
@@ -0,0 +1 @@
1
+ export * from './SeparatorControl';
@@ -0,0 +1,4 @@
1
+ import { SeparatorControl as t } from "./SeparatorControl.js";
2
+ export {
3
+ t as SeparatorControl
4
+ };
@@ -0,0 +1,10 @@
1
+ import { BaseControl } from '../types';
2
+ export interface SeparatorControl extends BaseControl {
3
+ type: "separator";
4
+ style?: "line" | "space" | "label";
5
+ // Note: SeparatorControl doesn't need onChange or value as it's purely visual
6
+ }
7
+
8
+ export interface SeparatorControlProps {
9
+ control: SeparatorControl;
10
+ }
@@ -6,9 +6,11 @@ export declare const controls: Readonly<{
6
6
  boolean: import('react').LazyExoticComponent<typeof import('./BooleanControl').BooleanControl>;
7
7
  button: import('react').LazyExoticComponent<typeof import('./ButtonControl').ButtonControl>;
8
8
  color: import('react').LazyExoticComponent<typeof import('./ColorControl').ColorControl>;
9
+ date: import('react').LazyExoticComponent<typeof import('./DateControl').DateControl>;
9
10
  number: import('react').LazyExoticComponent<typeof import('./NumberControl').NumberControl>;
11
+ range: import('react').LazyExoticComponent<typeof import('./RangeControl').RangeControl>;
10
12
  select: import('react').LazyExoticComponent<typeof import('./SelectControl').SelectControl>;
13
+ separator: import('react').LazyExoticComponent<typeof import('./SeparatorControl').SeparatorControl>;
11
14
  text: import('react').LazyExoticComponent<typeof import('./TextControl').TextControl>;
12
15
  buttonGroup: import('react').LazyExoticComponent<typeof import('./ButtonGroupControl').ButtonGroupControl>;
13
16
  }>;
14
- export { ControlRenderer } from '..';
@@ -1,42 +1,16 @@
1
- import { Suspense as d, lazy as r } from "react";
2
- import { jsxs as i, jsx as o } from "react/jsx-runtime";
3
- import { className as s } from "../../../utils/className/className.js";
4
- import "../../../utils/store/store.js";
5
- import '../../../assets/index.css';const p = "_controlRendererContainer_eix3y_1", u = "_controlContainer_eix3y_5", m = "_fullWidth_eix3y_13", C = "_controlWrapper_eix3y_16", f = "_label_eix3y_20", _ = "_description_eix3y_28", h = "_loading_eix3y_29", t = {
6
- controlRendererContainer: p,
7
- controlContainer: u,
8
- fullWidth: m,
9
- controlWrapper: C,
10
- label: f,
11
- description: _,
12
- loading: h
13
- }, b = ["button", "buttonGroup"];
14
- function g({ name: e, control: n }) {
15
- const a = n?.label || e;
16
- function c() {
17
- if (!n || !n.type)
18
- return /* @__PURE__ */ o("div", { className: t.error, children: "Control type is not defined" });
19
- const l = y[n.type];
20
- return l ? /* @__PURE__ */ o(d, { fallback: /* @__PURE__ */ o("div", { className: t.loading, children: "Loading control..." }), children: /* @__PURE__ */ o(l, { control: n }) }) : /* @__PURE__ */ o("div", { children: "Unknown control type" });
21
- }
22
- return /* @__PURE__ */ i("div", { className: t.controlRendererContainer, children: [
23
- /* @__PURE__ */ i("div", { ...s(t.controlContainer, { [t.fullWidth]: b.includes(n.type) }), children: [
24
- n?.type !== "button" && /* @__PURE__ */ o("label", { className: t.label, children: a }),
25
- /* @__PURE__ */ o("div", { className: t.controlWrapper, children: c() })
26
- ] }),
27
- n?.description && /* @__PURE__ */ o("span", { className: t.description, children: n.description })
28
- ] });
29
- }
30
- const y = Object.freeze({
31
- boolean: r(() => import("./BooleanControl/index.js").then((e) => ({ default: e.BooleanControl }))),
32
- button: r(() => import("./ButtonControl/index.js").then((e) => ({ default: e.ButtonControl }))),
33
- color: r(() => import("./ColorControl/index.js").then((e) => ({ default: e.ColorControl }))),
34
- number: r(() => import("./NumberControl/index.js").then((e) => ({ default: e.NumberControl }))),
35
- select: r(() => import("./SelectControl/index.js").then((e) => ({ default: e.SelectControl }))),
36
- text: r(() => import("./TextControl/index.js").then((e) => ({ default: e.TextControl }))),
37
- buttonGroup: r(() => import("./ButtonGroupControl/index.js").then((e) => ({ default: e.ButtonGroupControl })))
1
+ import { lazy as o } from "react";
2
+ const r = Object.freeze({
3
+ boolean: o(() => import("./BooleanControl/index.js").then((t) => ({ default: t.BooleanControl }))),
4
+ button: o(() => import("./ButtonControl/index.js").then((t) => ({ default: t.ButtonControl }))),
5
+ color: o(() => import("./ColorControl/index.js").then((t) => ({ default: t.ColorControl }))),
6
+ date: o(() => import("./DateControl/index.js").then((t) => ({ default: t.DateControl }))),
7
+ number: o(() => import("./NumberControl/index.js").then((t) => ({ default: t.NumberControl }))),
8
+ range: o(() => import("./RangeControl/index.js").then((t) => ({ default: t.RangeControl }))),
9
+ select: o(() => import("./SelectControl/index.js").then((t) => ({ default: t.SelectControl }))),
10
+ separator: o(() => import("./SeparatorControl/index.js").then((t) => ({ default: t.SeparatorControl }))),
11
+ text: o(() => import("./TextControl/index.js").then((t) => ({ default: t.TextControl }))),
12
+ buttonGroup: o(() => import("./ButtonGroupControl/index.js").then((t) => ({ default: t.ButtonGroupControl })))
38
13
  });
39
14
  export {
40
- g as ControlRenderer,
41
- y as controls
15
+ r as controls
42
16
  };
@@ -2,8 +2,11 @@ import { BooleanControl } from './BooleanControl/types';
2
2
  import { ButtonControl } from './ButtonControl/types';
3
3
  import { ButtonGroupControl } from './ButtonGroupControl/types';
4
4
  import { ColorControl } from './ColorControl/types';
5
+ import { DateControl } from './DateControl/types';
5
6
  import { NumberControl } from './NumberControl/types';
7
+ import { RangeControl } from './RangeControl/types';
6
8
  import { SelectControl } from './SelectControl/types';
9
+ import { SeparatorControl } from './SeparatorControl/types';
7
10
  import { TextControl } from './TextControl/types';
8
11
  export interface BaseControl {
9
12
  label?: string;
@@ -23,6 +26,9 @@ export type Controls = {
23
26
  text: TextControl;
24
27
  button: ButtonControl;
25
28
  number: NumberControl;
29
+ range: RangeControl;
30
+ date: DateControl;
31
+ separator: SeparatorControl;
26
32
  buttonGroup: ButtonGroupControl;
27
33
  };
28
34
 
@@ -1,4 +1,4 @@
1
- import { ControlRenderer as o } from "./controls/index.js";
1
+ import { ControlRenderer as o } from "./ControlRenderer.js";
2
2
  export {
3
3
  o as ControlRenderer
4
4
  };
@@ -1,66 +1,67 @@
1
- import { jsxs as r, jsx as t } from "react/jsx-runtime";
2
- import { useCallback as C } from "react";
1
+ import { jsxs as r, jsx as e } from "react/jsx-runtime";
2
+ import { useCallback as g } from "react";
3
3
  import { useDragAndDrop as _ } from "../../hooks/useDragAndDrop/useDragAndDrop.js";
4
- import { useHotkey as D } from "../../hooks/useHotkeys/useHotkey.js";
5
- import { className as P } from "../../utils/className/className.js";
6
- import { useDevPanelVisible as g, useDevPanelCollapsed as b, useDevPanelPosition as y, useDevPanelSections as N, useDevPanelActions as K } from "../../utils/store/store.js";
7
- import { EmptyContent as k } from "../EmptyContent/EmptyContent.js";
8
- import { Section as w } from "../Section/Section.js";
9
- import '../../assets/DevPanel.css';const x = "_devPanelContainer_1rv6u_30", E = "_header_1rv6u_41", V = "_title_1rv6u_50", j = "_button_1rv6u_60", S = "_content_1rv6u_78", e = {
10
- devPanelContainer: x,
11
- header: E,
12
- title: V,
13
- button: j,
14
- content: S
15
- }, A = {
4
+ import { useHotkey as C } from "../../hooks/useHotkeys/useHotkey.js";
5
+ import { useDevPanelStore as w } from "../../store/store.js";
6
+ import { className as b } from "../../utils/className/className.js";
7
+ import { EmptyContent as y } from "../EmptyContent/EmptyContent.js";
8
+ import { Section as D } from "../Section/Section.js";
9
+ import '../../assets/DevPanel.css';const P = "_devPanelContainer_1vath_1", x = "_header_1vath_12", K = "_title_1vath_21", N = "_button_1vath_31", k = "_collapsed_1vath_53", A = "_content_1vath_60", t = {
10
+ devPanelContainer: P,
11
+ header: x,
12
+ title: K,
13
+ button: N,
14
+ collapsed: k,
15
+ content: A
16
+ }, j = {
16
17
  ctrlKey: !0,
17
18
  shiftKey: !0,
18
19
  key: "a",
19
20
  altKey: !1,
20
21
  metaKey: !1
21
22
  };
22
- function F({ panelTitle: c = "Dev panel", ...u }) {
23
- const i = g(), n = b(), l = y(), d = N(), o = K(), m = C(
23
+ function O({ panelTitle: c = "Dev panel", ...d }) {
24
+ const { isVisible: l, isCollapsed: o, position: a, sections: h, ...n } = w(), m = g(
24
25
  (s) => {
25
- o.setPosition(s);
26
+ n.setPosition(s);
26
27
  },
27
- [o]
28
- ), { isDragging: v, elementRef: p, handleMouseDown: f } = _({
28
+ [n]
29
+ ), { isDragging: p, elementRef: v, handleMouseDown: u } = _({
29
30
  onPositionChange: m
30
31
  });
31
- if (D({
32
+ if (C({
32
33
  description: "Show Dev Panel",
33
34
  preventDefault: !0,
34
- action: () => o.setVisible(!i),
35
- ...A,
36
- ...u.hotKeyConfig,
35
+ action: () => n.setVisible(!l),
36
+ ...j,
37
+ ...d.hotKeyConfig,
37
38
  target: window
38
- }), process.env.NODE_ENV !== "development" || !i)
39
+ }), !l)
39
40
  return null;
40
- const a = Object.entries(d);
41
+ const i = Object.entries(h);
41
42
  return /* @__PURE__ */ r(
42
43
  "div",
43
44
  {
44
- ref: p,
45
- ...P(e.devPanelContainer, {
46
- [e.dragging]: v
45
+ ref: v,
46
+ ...b(t.devPanelContainer, {
47
+ [t.dragging]: p
47
48
  }),
48
49
  style: {
49
- left: l.x,
50
- top: l.y,
51
- height: n ? "auto" : void 0
50
+ left: a.x,
51
+ top: a.y,
52
+ height: o ? "auto" : void 0
52
53
  },
53
54
  children: [
54
- /* @__PURE__ */ r("div", { className: e.header, onMouseDown: f, children: [
55
- /* @__PURE__ */ t("button", { className: e.button, onClick: () => o.setCollapsed(!n), title: n ? "Expand" : "Collapse", children: n ? "" : "" }),
56
- /* @__PURE__ */ t("div", { className: e.title, children: c }),
57
- /* @__PURE__ */ t("button", { className: e.button, onClick: () => o.setVisible(!1), title: "Close", children: "" })
55
+ /* @__PURE__ */ r("div", { className: t.header, onMouseDown: u, children: [
56
+ /* @__PURE__ */ e("button", { className: t.button, onClick: () => n.setCollapsed(!o), title: o ? "Expand" : "Collapse", children: /* @__PURE__ */ e("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", className: o ? 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" }) }) }),
57
+ /* @__PURE__ */ e("div", { className: t.title, children: c }),
58
+ /* @__PURE__ */ e("button", { className: t.button, onClick: () => n.setVisible(!1), title: "Close", 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" }) }) })
58
59
  ] }),
59
- !n && /* @__PURE__ */ t("div", { className: e.content, children: a.length ? a.map(([s, h]) => /* @__PURE__ */ t(w, { sectionName: s, section: h }, `section-${s}`)) : /* @__PURE__ */ t(k, {}) })
60
+ !o && /* @__PURE__ */ e("div", { className: t.content, children: i.length ? i.map(([s, f]) => /* @__PURE__ */ e(D, { sectionName: s, section: f }, `section-${s}`)) : /* @__PURE__ */ e(y, {}) })
60
61
  ]
61
62
  }
62
63
  );
63
64
  }
64
65
  export {
65
- F as DevPanel
66
+ O as DevPanel
66
67
  };
@@ -1,9 +1,7 @@
1
1
  import { ControlsGroup } from '../ControlRenderer/controls/types';
2
- import { HotkeyConfig, Position } from '../../types';
3
- export type DevPanelHoyKeyConfig = Pick<HotkeyConfig, "key" | "shiftKey" | "altKey" | "ctrlKey" | "metaKey">;
2
+ export type DevPanelHotkeyConfig = Pick<HotkeyConfig, "key" | "shiftKey" | "altKey" | "ctrlKey" | "metaKey">;
4
3
 
5
4
  export interface DevPanelProps {
6
- theme?: "light" | "dark";
7
5
  panelTitle?: string;
8
6
  /**
9
7
  * Hotkey configuration for toggling the DevPanel visibility.
@@ -18,7 +16,7 @@ export interface DevPanelProps {
18
16
  * }
19
17
  * ```
20
18
  */
21
- hotKeyConfig?: DevPanelHoyKeyConfig;
19
+ hotKeyConfig?: DevPanelHotkeyConfig;
22
20
  }
23
21
 
24
22
  export interface DevPanelSection {
@@ -45,3 +43,8 @@ export interface DevPanelActions {
45
43
  }
46
44
 
47
45
  export type DevPanelStore = DevPanelState & DevPanelActions;
46
+
47
+ export interface Position {
48
+ x: number;
49
+ y: number;
50
+ }
@@ -1,9 +1,9 @@
1
1
  import { jsxs as t, jsx as e } from "react/jsx-runtime";
2
- import '../../assets/EmptyContent.css';const o = "_empty_1re8c_1", r = {
2
+ import '../../assets/EmptyContent.css';const o = "_empty_1xo8g_1", s = {
3
3
  empty: o
4
4
  };
5
5
  function n() {
6
- return /* @__PURE__ */ t("div", { className: r.empty, children: [
6
+ return /* @__PURE__ */ t("div", { className: s.empty, children: [
7
7
  "No controls registered yet.",
8
8
  /* @__PURE__ */ e("br", {}),
9
9
  " ",
@@ -1,9 +1,9 @@
1
1
  import { jsx as n } from "react/jsx-runtime";
2
- import '../../assets/Input.css';const i = "_input_w2bi0_1", p = {
3
- input: i
2
+ import '../../assets/Input.css';const p = "_input_161wd_1", u = {
3
+ input: p
4
4
  };
5
5
  function s(t) {
6
- return /* @__PURE__ */ n("input", { ...t, className: p.input });
6
+ return /* @__PURE__ */ n("input", { ...t, className: u.input });
7
7
  }
8
8
  export {
9
9
  s as Input
@@ -0,0 +1,20 @@
1
+ type LoggerProps = {
2
+ /** The data object to display in JSON format */
3
+ items: object;
4
+ /** Optional title for the logger panel */
5
+ title?: string;
6
+ /** Theme preference - 'auto' detects system preference */
7
+ theme?: "light" | "dark" | "auto";
8
+ /** Whether the logger should start collapsed */
9
+ defaultCollapsed?: boolean;
10
+ /** Whether the logger should be visible by default */
11
+ defaultVisible?: boolean;
12
+ /** Callback function called when the logger is closed */
13
+ onClose?: () => void;
14
+ };
15
+ /**
16
+ * A floating, collapsible logger component that displays object data in JSON format.
17
+ * @returns JSX element or null if not visible
18
+ */
19
+ export declare function Logger({ items, title, theme, defaultCollapsed, defaultVisible, onClose }: LoggerProps): import("react/jsx-runtime").JSX.Element | null;
20
+ export {};
@@ -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
+ };