@berenjena/react-dev-panel 2.1.0 → 2.3.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.
Files changed (37) hide show
  1. package/README.md +26 -5
  2. package/dist/assets/index10.css +1 -1
  3. package/dist/assets/index11.css +1 -1
  4. package/dist/assets/index12.css +1 -1
  5. package/dist/assets/index13.css +1 -1
  6. package/dist/assets/index14.css +1 -0
  7. package/dist/assets/index15.css +1 -0
  8. package/dist/assets/index2.css +1 -1
  9. package/dist/assets/index5.css +1 -1
  10. package/dist/assets/index6.css +1 -1
  11. package/dist/assets/index7.css +1 -1
  12. package/dist/assets/index8.css +1 -1
  13. package/dist/assets/index9.css +1 -1
  14. package/dist/components/ControlRenderer/controls/BooleanControl/index.js +1 -1
  15. package/dist/components/ControlRenderer/controls/ButtonControl/index.js +1 -1
  16. package/dist/components/ControlRenderer/controls/ButtonGroupControl/index.js +1 -1
  17. package/dist/components/ControlRenderer/controls/ColorControl/index.js +1 -1
  18. package/dist/components/ControlRenderer/controls/DragAndDropControl/index.d.ts +2 -0
  19. package/dist/components/ControlRenderer/controls/DragAndDropControl/index.js +117 -0
  20. package/dist/components/ControlRenderer/controls/DragAndDropControl/types.d.ts +20 -0
  21. package/dist/components/ControlRenderer/controls/RangeControl/index.js +1 -1
  22. package/dist/components/ControlRenderer/controls/SeparatorControl/index.js +1 -1
  23. package/dist/components/ControlRenderer/controls/TextControl/index.js +16 -16
  24. package/dist/components/ControlRenderer/controls/TextControl/types.d.ts +1 -0
  25. package/dist/components/ControlRenderer/controls/index.d.ts +1 -0
  26. package/dist/components/ControlRenderer/controls/index.js +2 -1
  27. package/dist/components/ControlRenderer/controls/types.d.ts +3 -0
  28. package/dist/components/ControlRenderer/index.js +26 -26
  29. package/dist/components/DevPanel/index.js +33 -35
  30. package/dist/components/Input/index.js +1 -1
  31. package/dist/components/Select/index.js +53 -53
  32. package/dist/components/Textarea/index.d.ts +5 -0
  33. package/dist/components/Textarea/index.js +18 -0
  34. package/dist/hooks/useDevPanel/index.js +45 -17
  35. package/dist/store/ControlPersistenceService.d.ts +33 -0
  36. package/dist/store/ControlPersistenceService.js +61 -0
  37. package/package.json +1 -1
@@ -1,10 +1,10 @@
1
- import { jsxs as y, Fragment as M, jsx as a } from "react/jsx-runtime";
2
- import { useRef as x, useState as H, useCallback as q, useEffect as P } from "react";
1
+ import { jsxs as y, Fragment as q, jsx as a } from "react/jsx-runtime";
2
+ import { useRef as x, useState as C, useCallback as z, useEffect as P } from "react";
3
3
  import { createPortal as T } from "react-dom";
4
4
  import { Icon as j } from "../Icon/index.js";
5
5
  import { useDevPanelPosition as B } from "../../store/UIStore.js";
6
6
  import { className as F } from "../../utils/className/className.js";
7
- import '../../assets/index6.css';const W = "_select_1hbiz_217", U = "_trigger_1hbiz_222", G = "_open_1hbiz_271", J = "_value_1hbiz_275", K = "_placeholder_1hbiz_284", Q = "_arrow_1hbiz_288", X = "_dropdownPortal_1hbiz_303", Y = "_dropdown_1hbiz_303", Z = "_option_1hbiz_342", ee = "_selected_1hbiz_360", te = "_checkbox_1hbiz_369", ne = "_label_1hbiz_390", r = {
7
+ import '../../assets/index7.css';const W = "_select_ug510_217", U = "_trigger_ug510_222", G = "_open_ug510_271", J = "_value_ug510_275", K = "_placeholder_ug510_284", Q = "_arrow_ug510_288", X = "_dropdownPortal_ug510_303", Y = "_dropdown_ug510_303", Z = "_option_ug510_342", ee = "_selected_ug510_361", te = "_checkbox_ug510_370", ne = "_label_ug510_391", r = {
8
8
  select: W,
9
9
  trigger: U,
10
10
  open: G,
@@ -18,66 +18,66 @@ import '../../assets/index6.css';const W = "_select_1hbiz_217", U = "_trigger_1h
18
18
  checkbox: te,
19
19
  label: ne
20
20
  };
21
- function ae({ value: p, options: _, onChange: z, disabled: f = !1, multiple: u = !1, placeholder: L = "Select..." }) {
22
- const w = B(), g = x(null), h = x(null), k = x(null), [c, m] = H(!1), [b, E] = H({
21
+ function ae({ value: f, options: v, onChange: L, disabled: h = !1, multiple: u = !1, placeholder: k = "Select..." }) {
22
+ const g = B(), w = x(null), p = x(null), E = x(null), [i, m] = C(!1), [_, N] = C({
23
23
  top: 0,
24
24
  left: 0,
25
25
  width: 0,
26
26
  maxHeight: 200
27
- }), d = u ? Array.isArray(p) ? p : [] : typeof p == "string" ? p : "", C = S(), D = u ? d.length === 0 : !d, s = q(() => {
28
- c && E(N());
29
- }, [c]);
30
- function N() {
31
- if (!h.current)
27
+ }), d = u ? Array.isArray(f) ? f : [] : typeof f == "string" ? f : "", D = A(), S = u ? d.length === 0 : !d, c = z(() => {
28
+ i && N(O());
29
+ }, [i]);
30
+ function O() {
31
+ if (!p.current)
32
32
  return {
33
33
  top: 0,
34
34
  left: 0,
35
35
  width: 0,
36
36
  maxHeight: 200
37
37
  };
38
- const e = h.current.getBoundingClientRect(), t = window.innerHeight, n = window.innerWidth, o = 200, l = 4, i = t - e.bottom - l, v = e.top - l, R = i < o && v > i, V = R ? e.top - Math.min(o, v) : e.bottom + l, $ = Math.max(8, Math.min(e.left, n - e.width - 8)), I = R ? Math.min(o, v) : Math.min(o, i);
38
+ const e = p.current.getBoundingClientRect(), t = window.innerHeight, n = window.innerWidth, o = 200, l = 4, s = t - e.bottom - l, b = e.top - l, H = s < o && b > s, $ = H ? e.top - Math.min(o, b) : e.bottom + l, I = Math.max(8, Math.min(e.left, n - e.width - 8)), M = H ? Math.min(o, b) : Math.min(o, s);
39
39
  return {
40
- top: V,
41
- left: $,
40
+ top: $,
41
+ left: I,
42
42
  width: e.width,
43
- maxHeight: I
43
+ maxHeight: M
44
44
  };
45
45
  }
46
- function O(e) {
46
+ function R(e) {
47
47
  if (u) {
48
48
  const t = d, n = t.includes(e) ? t.filter((o) => o !== e) : [...t, e];
49
- z(n);
49
+ L(n);
50
50
  } else
51
- z(e), m(!1);
51
+ L(e), m(!1);
52
52
  }
53
- function S() {
53
+ function A() {
54
54
  if (u) {
55
55
  const e = d;
56
56
  if (e.length === 0)
57
- return L;
57
+ return k;
58
58
  if (e.length === 1) {
59
- const t = _.find((o) => (typeof o == "string" ? o : o.value) === e[0]);
59
+ const t = v.find((o) => (typeof o == "string" ? o : o.value) === e[0]);
60
60
  return (typeof t == "string" ? t : t?.label) || e[0];
61
61
  }
62
62
  return `${e.length} selected`;
63
63
  } else {
64
64
  const e = d;
65
65
  if (!e)
66
- return L;
67
- const t = _.find((o) => (typeof o == "string" ? o : o.value) === e);
66
+ return k;
67
+ const t = v.find((o) => (typeof o == "string" ? o : o.value) === e);
68
68
  return (typeof t == "string" ? t : t?.label) || e;
69
69
  }
70
70
  }
71
- function A() {
72
- f || (c ? m(!1) : (E(N()), m(!0)));
71
+ function V() {
72
+ h || (i ? m(!1) : (N(O()), m(!0)));
73
73
  }
74
74
  return P(() => {
75
- if (!c) return;
76
- s(), window.addEventListener("resize", s), window.addEventListener("scroll", s, !0);
77
- const e = g.current?.closest("[data-dev-panel]") || document.querySelector("[data-dev-panel]");
78
- e && e.addEventListener("scroll", s, !0);
75
+ if (!i) return;
76
+ c(), window.addEventListener("resize", c), window.addEventListener("scroll", c, !0);
77
+ const e = w.current?.closest("[data-dev-panel]") || document.querySelector("[data-dev-panel]");
78
+ e && e.addEventListener("scroll", c, !0);
79
79
  let t = null;
80
- if (h.current && "IntersectionObserver" in window) {
80
+ if (p.current && "IntersectionObserver" in window) {
81
81
  const n = {
82
82
  top: 0,
83
83
  left: 0,
@@ -87,25 +87,25 @@ function ae({ value: p, options: _, onChange: z, disabled: f = !1, multiple: u =
87
87
  t = new IntersectionObserver(
88
88
  (o) => {
89
89
  const l = o[0];
90
- if (l && l.target === h.current) {
91
- const i = l.boundingClientRect;
92
- (i.top !== n.top || i.left !== n.left || i.width !== n.width || i.height !== n.height) && (n.top = i.top, n.left = i.left, n.width = i.width, n.height = i.height, s());
90
+ if (l && l.target === p.current) {
91
+ const s = l.boundingClientRect;
92
+ (s.top !== n.top || s.left !== n.left || s.width !== n.width || s.height !== n.height) && (n.top = s.top, n.left = s.left, n.width = s.width, n.height = s.height, c());
93
93
  }
94
94
  },
95
95
  {
96
96
  threshold: [0, 0.1, 0.5, 1]
97
97
  }
98
- ), t.observe(h.current);
98
+ ), t.observe(p.current);
99
99
  }
100
100
  return () => {
101
- window.removeEventListener("resize", s), window.removeEventListener("scroll", s, !0), e && e.removeEventListener("scroll", s, !0), t && t.disconnect();
101
+ window.removeEventListener("resize", c), window.removeEventListener("scroll", c, !0), e && e.removeEventListener("scroll", c, !0), t && t.disconnect();
102
102
  };
103
- }, [c, s]), P(() => {
104
- const e = k.current;
105
- (!e || e.x !== w.x || e.y !== w.y) && (k.current = w, c && requestAnimationFrame(s));
106
- }, [c, w, s]), P(() => {
103
+ }, [i, c]), P(() => {
104
+ const e = E.current;
105
+ (!e || e.x !== g.x || e.y !== g.y) && (E.current = g, i && requestAnimationFrame(c));
106
+ }, [i, g, c]), P(() => {
107
107
  function e(t) {
108
- if (g.current && !g.current.contains(t.target)) {
108
+ if (w.current && !w.current.contains(t.target)) {
109
109
  const n = document.querySelector(`.${r.dropdownPortal}`);
110
110
  if (n && n.contains(t.target))
111
111
  return;
@@ -115,35 +115,35 @@ function ae({ value: p, options: _, onChange: z, disabled: f = !1, multiple: u =
115
115
  return document.addEventListener("mousedown", e), () => {
116
116
  document.removeEventListener("mousedown", e);
117
117
  };
118
- }, []), /* @__PURE__ */ y(M, { children: [
118
+ }, []), /* @__PURE__ */ y(q, { children: [
119
119
  /* @__PURE__ */ a(
120
120
  "div",
121
121
  {
122
- ref: g,
122
+ ref: w,
123
123
  ...F(r.select, {
124
- [r.disabled]: f,
125
- [r.open]: c
124
+ [r.disabled]: h,
125
+ [r.open]: i
126
126
  }),
127
- children: /* @__PURE__ */ y("button", { ref: h, type: "button", className: r.trigger, onClick: A, disabled: f, children: [
128
- /* @__PURE__ */ a("span", { className: `${r.value} ${D ? r.placeholder : ""}`, children: C }),
127
+ children: /* @__PURE__ */ y("button", { ref: p, type: "button", className: r.trigger, onClick: V, disabled: h, children: [
128
+ /* @__PURE__ */ a("span", { className: `${r.value} ${S ? r.placeholder : ""}`, children: D }),
129
129
  /* @__PURE__ */ a(j, { name: "ArrowDown", className: r.arrow })
130
130
  ] })
131
131
  }
132
132
  ),
133
133
  typeof window < "u" && T(
134
- c && !f && /* @__PURE__ */ a(
134
+ i && !h && /* @__PURE__ */ a(
135
135
  "div",
136
136
  {
137
137
  className: r.dropdownPortal,
138
138
  style: {
139
139
  position: "fixed",
140
- top: b.top,
141
- left: b.left,
142
- width: b.width,
143
- maxHeight: b.maxHeight,
140
+ top: _.top,
141
+ left: _.left,
142
+ width: _.width,
143
+ maxHeight: _.maxHeight,
144
144
  zIndex: 9999
145
145
  },
146
- children: /* @__PURE__ */ a("div", { className: r.dropdown, children: _.map((e) => {
146
+ children: /* @__PURE__ */ a("div", { className: r.dropdown, children: v.map((e) => {
147
147
  const t = typeof e == "string" ? e : e.value, n = typeof e == "string" ? e : e.label, o = u ? d.includes(t) : d === t;
148
148
  return u ? /* @__PURE__ */ y("label", { className: r.option, children: [
149
149
  /* @__PURE__ */ a(
@@ -151,7 +151,7 @@ function ae({ value: p, options: _, onChange: z, disabled: f = !1, multiple: u =
151
151
  {
152
152
  type: "checkbox",
153
153
  checked: o,
154
- onChange: () => O(t),
154
+ onChange: () => R(t),
155
155
  className: r.checkbox
156
156
  }
157
157
  ),
@@ -161,7 +161,7 @@ function ae({ value: p, options: _, onChange: z, disabled: f = !1, multiple: u =
161
161
  {
162
162
  type: "button",
163
163
  className: `${r.option} ${o ? r.selected : ""}`,
164
- onClick: () => O(t),
164
+ onClick: () => R(t),
165
165
  children: n
166
166
  },
167
167
  t
@@ -0,0 +1,5 @@
1
+ interface TextareaProps extends React.TextareaHTMLAttributes<HTMLTextAreaElement> {
2
+ disableAutoExpand?: boolean;
3
+ }
4
+ export declare function Textarea(props: TextareaProps): React.ReactNode;
5
+ export {};
@@ -0,0 +1,18 @@
1
+ import { jsx as c } from "react/jsx-runtime";
2
+ import '../../assets/index6.css';const h = "_textarea_83ckv_217", x = {
3
+ textarea: h
4
+ }, a = 240;
5
+ function g(r) {
6
+ const { disableAutoExpand: o, onChange: n, ...s } = r;
7
+ function l(e) {
8
+ if (!o && e.currentTarget) {
9
+ const t = e.currentTarget;
10
+ t.style.height = "auto", t.style.height = `${t.scrollHeight}px`, t.scrollHeight > a ? t.style.overflowY = "auto" : t.style.overflowY = "hidden";
11
+ }
12
+ n?.(e);
13
+ }
14
+ return /* @__PURE__ */ c("textarea", { ...s, className: x.textarea, onChange: l, style: { maxHeight: `${a}px` } });
15
+ }
16
+ export {
17
+ g as Textarea
18
+ };
@@ -1,24 +1,52 @@
1
- import { useRef as f, useEffect as i, createElement as l } from "react";
2
- import { createRoot as m } from "react-dom/client";
3
- import { DevPanelPortal as p } from "../../components/DevPanelPortal/index.js";
4
- import { DevPanelManager as v } from "../../managers/DevPanelManager.js";
5
- import { useDevPanelSections as g, useDevPanelSectionActions as S } from "../../store/SectionsStore.js";
6
- import { hasControlsChanged as D } from "../../utils/hasControlChanged/hasControlChanged.js";
7
- function y(t, n, r) {
8
- const c = g(), { registerSection: u, unregisterSection: a } = S(), s = f(void 0), o = f(null);
9
- o.current || (o.current = v.getInstance()), i(() => {
10
- const e = o.current, d = c[t] !== void 0;
11
- D(n, s.current) || !d ? (u(t, n), s.current = n, e.addSection(t, r)) : r && e.updateProps(r);
12
- }, [t, n, r, c, u]), i(() => () => {
13
- const e = o.current;
14
- a(t), e.removeSection(t);
15
- }, [t, a]), i(() => {
1
+ import { useRef as d, useEffect as s, createElement as v } from "react";
2
+ import { createRoot as S } from "react-dom/client";
3
+ import { DevPanelPortal as E } from "../../components/DevPanelPortal/index.js";
4
+ import { DevPanelManager as P } from "../../managers/DevPanelManager.js";
5
+ import { controlPersistenceService as m } from "../../store/ControlPersistenceService.js";
6
+ import { useDevPanelSections as w, useDevPanelSectionActions as D } from "../../store/SectionsStore.js";
7
+ import { hasControlsChanged as R } from "../../utils/hasControlChanged/hasControlChanged.js";
8
+ function j(t, o, i) {
9
+ const p = w(), { registerSection: g, unregisterSection: h } = D(), C = d(void 0), c = d(null), f = d(/* @__PURE__ */ new Set());
10
+ c.current || (c.current = P.getInstance()), s(() => {
11
+ Object.entries(o).forEach(([e, n]) => {
12
+ const r = `${t}-${e}`;
13
+ if (n.persist && !f.current.has(r)) {
14
+ const a = m.getPersistedValue(t, e);
15
+ a !== void 0 && "onChange" in n && typeof n.onChange == "function" && n.onChange(a), f.current.add(r);
16
+ }
17
+ });
18
+ }, [t, o]);
19
+ const u = d({});
20
+ s(() => {
21
+ const e = {};
22
+ Object.entries(o).forEach(([n, r]) => {
23
+ if (r.persist && "onChange" in r && typeof r.onChange == "function") {
24
+ const a = r.onChange;
25
+ e[n] = {
26
+ ...r,
27
+ onChange: (l) => {
28
+ m.setPersistedValue(t, n, l), a(l);
29
+ }
30
+ };
31
+ } else
32
+ e[n] = r;
33
+ }), u.current = e;
34
+ }, [t, o]), s(() => {
35
+ const e = c.current, n = p[t] !== void 0;
36
+ R(u.current, C.current) || !n ? (g(t, u.current), C.current = u.current, e.addSection(t, i)) : i && e.updateProps(i);
37
+ }, [t, o, i, p, g]), s(() => {
38
+ const e = f.current;
39
+ return () => {
40
+ const n = c.current;
41
+ h(t), n.removeSection(t), e.clear();
42
+ };
43
+ }, [t, h]), s(() => {
16
44
  if (window.__devPanelAutoMounted) return;
17
45
  window.__devPanelAutoMounted = !0;
18
46
  const e = document.createElement("div");
19
- e.id = "dev-panel-portal-container", e.style.display = "none", document.body.appendChild(e), m(e).render(l(p));
47
+ e.id = "dev-panel-portal-container", e.style.display = "none", document.body.appendChild(e), S(e).render(v(E));
20
48
  }, []);
21
49
  }
22
50
  export {
23
- y as useDevPanel
51
+ j as useDevPanel
24
52
  };
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Service for persisting individual control values
3
+ */
4
+ declare class ControlPersistenceService {
5
+ private readonly storageKey;
6
+ /**
7
+ * Gets persisted value for a control
8
+ * @param sectionName - Name of the section
9
+ * @param controlKey - Key of the control within the section
10
+ * @returns Persisted value or undefined if not found
11
+ */
12
+ getPersistedValue(sectionName: string, controlKey: string): unknown;
13
+ /**
14
+ * Sets persisted value for a control
15
+ * @param sectionName - Name of the section
16
+ * @param controlKey - Key of the control within the section
17
+ * @param value - Value to persist
18
+ */
19
+ setPersistedValue(sectionName: string, controlKey: string, value: unknown): void;
20
+ /**
21
+ * Removes persisted value for a control
22
+ * @param sectionName - Name of the section
23
+ * @param controlKey - Key of the control within the section
24
+ */
25
+ removePersistedValue(sectionName: string, controlKey: string): void;
26
+ /**
27
+ * Removes all persisted values for a section
28
+ * @param sectionName - Name of the section
29
+ */
30
+ removeSection(sectionName: string): void;
31
+ }
32
+ export declare const controlPersistenceService: ControlPersistenceService;
33
+ export {};
@@ -0,0 +1,61 @@
1
+ class a {
2
+ storageKey = "dev-panel-controls-persistence";
3
+ /**
4
+ * Gets persisted value for a control
5
+ * @param sectionName - Name of the section
6
+ * @param controlKey - Key of the control within the section
7
+ * @returns Persisted value or undefined if not found
8
+ */
9
+ getPersistedValue(e, s) {
10
+ try {
11
+ const t = localStorage.getItem(this.storageKey);
12
+ return t ? JSON.parse(t)[e]?.[s] : void 0;
13
+ } catch {
14
+ return;
15
+ }
16
+ }
17
+ /**
18
+ * Sets persisted value for a control
19
+ * @param sectionName - Name of the section
20
+ * @param controlKey - Key of the control within the section
21
+ * @param value - Value to persist
22
+ */
23
+ setPersistedValue(e, s, t) {
24
+ try {
25
+ const r = localStorage.getItem(this.storageKey), o = r ? JSON.parse(r) : {};
26
+ o[e] || (o[e] = {}), o[e][s] = t, localStorage.setItem(this.storageKey, JSON.stringify(o));
27
+ } catch {
28
+ }
29
+ }
30
+ /**
31
+ * Removes persisted value for a control
32
+ * @param sectionName - Name of the section
33
+ * @param controlKey - Key of the control within the section
34
+ */
35
+ removePersistedValue(e, s) {
36
+ try {
37
+ const t = localStorage.getItem(this.storageKey);
38
+ if (!t) return;
39
+ const r = JSON.parse(t);
40
+ r[e] && (delete r[e][s], Object.keys(r[e]).length === 0 && delete r[e], localStorage.setItem(this.storageKey, JSON.stringify(r)));
41
+ } catch {
42
+ }
43
+ }
44
+ /**
45
+ * Removes all persisted values for a section
46
+ * @param sectionName - Name of the section
47
+ */
48
+ removeSection(e) {
49
+ try {
50
+ const s = localStorage.getItem(this.storageKey);
51
+ if (!s) return;
52
+ const t = JSON.parse(s);
53
+ delete t[e], localStorage.setItem(this.storageKey, JSON.stringify(t));
54
+ } catch {
55
+ }
56
+ }
57
+ }
58
+ const l = new a();
59
+ export {
60
+ l as controlPersistenceService
61
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "private": false,
3
- "version": "2.1.0",
3
+ "version": "2.3.0",
4
4
  "license": "MIT",
5
5
  "name": "@berenjena/react-dev-panel",
6
6
  "description": "A React development panel with various tools and utilities.",