@berenjena/react-dev-panel 2.4.1 → 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.
Files changed (95) hide show
  1. package/README.md +43 -1
  2. package/dist/assets/index.css +1 -1
  3. package/dist/assets/index10.css +1 -1
  4. package/dist/assets/index11.css +1 -1
  5. package/dist/assets/index12.css +1 -1
  6. package/dist/assets/index13.css +1 -1
  7. package/dist/assets/index14.css +1 -1
  8. package/dist/assets/index15.css +1 -1
  9. package/dist/assets/index2.css +1 -1
  10. package/dist/assets/index3.css +1 -1
  11. package/dist/assets/index4.css +1 -1
  12. package/dist/assets/index5.css +1 -1
  13. package/dist/assets/index6.css +1 -1
  14. package/dist/assets/index7.css +1 -1
  15. package/dist/assets/index8.css +1 -1
  16. package/dist/assets/index9.css +1 -1
  17. package/dist/components/ControlErrorBoundary/index.d.ts +24 -0
  18. package/dist/components/ControlErrorBoundary/index.js +17 -0
  19. package/dist/components/ControlRenderer/controls/BooleanControl/index.js +10 -9
  20. package/dist/components/ControlRenderer/controls/ButtonControl/index.js +4 -3
  21. package/dist/components/ControlRenderer/controls/ButtonGroupControl/index.js +6 -5
  22. package/dist/components/ControlRenderer/controls/ColorControl/index.js +2 -1
  23. package/dist/components/ControlRenderer/controls/DateControl/index.js +8 -7
  24. package/dist/components/ControlRenderer/controls/DragAndDropControl/index.js +15 -14
  25. package/dist/components/ControlRenderer/controls/LocalStorageControl/index.js +111 -110
  26. package/dist/components/ControlRenderer/controls/MultiSelectControl/index.d.ts +2 -0
  27. package/dist/components/ControlRenderer/controls/MultiSelectControl/index.js +8 -5
  28. package/dist/components/ControlRenderer/controls/MultiSelectControl/types.d.ts +2 -0
  29. package/dist/components/ControlRenderer/controls/NumberControl/index.js +10 -9
  30. package/dist/components/ControlRenderer/controls/RangeControl/index.js +6 -5
  31. package/dist/components/ControlRenderer/controls/SelectControl/index.js +5 -4
  32. package/dist/components/ControlRenderer/controls/SeparatorControl/index.js +2 -1
  33. package/dist/components/ControlRenderer/controls/TextControl/index.js +7 -6
  34. package/dist/components/ControlRenderer/controls/index.js +1 -0
  35. package/dist/components/ControlRenderer/index.js +28 -26
  36. package/dist/components/DevPanel/index.js +12 -11
  37. package/dist/components/DevPanel/types.d.ts +17 -0
  38. package/dist/components/DevPanelPortal/index.js +5 -4
  39. package/dist/components/EmptyContent/index.js +2 -1
  40. package/dist/components/Icon/index.js +11 -10
  41. package/dist/components/Input/index.js +2 -1
  42. package/dist/components/Section/index.js +2 -1
  43. package/dist/components/Select/index.js +11 -10
  44. package/dist/components/Textarea/index.js +5 -4
  45. package/dist/components/index.js +3 -2
  46. package/dist/hooks/useDebounceCallback/index.js +1 -0
  47. package/dist/hooks/useDevPanel/consoleApi.d.ts +37 -0
  48. package/dist/hooks/useDevPanel/consoleApi.js +16 -0
  49. package/dist/hooks/useDevPanel/index.d.ts +5 -1
  50. package/dist/hooks/useDevPanel/index.js +50 -41
  51. package/dist/hooks/useDevPanel/mountDevPanelPortal.d.ts +18 -0
  52. package/dist/hooks/useDevPanel/mountDevPanelPortal.js +20 -0
  53. package/dist/hooks/useDragAndDrop/index.js +1 -0
  54. package/dist/hooks/useHotKey/index.js +4 -3
  55. package/dist/hooks/useHotkeys/index.js +1 -0
  56. package/dist/index.d.ts +1 -0
  57. package/dist/index.js +4 -3
  58. package/dist/managers/DevPanelManager.js +1 -0
  59. package/dist/store/BaseStoreService.d.ts +2 -7
  60. package/dist/store/BaseStoreService.js +14 -7
  61. package/dist/store/ControlPersistenceService.d.ts +2 -0
  62. package/dist/store/ControlPersistenceService.js +34 -26
  63. package/dist/store/SectionsStore.js +3 -2
  64. package/dist/store/UIStore.d.ts +14 -0
  65. package/dist/store/UIStore.js +37 -22
  66. package/dist/utils/className/className.js +6 -5
  67. package/dist/utils/className/index.js +3 -2
  68. package/dist/utils/copyToClipboard/copyToClipboard.js +1 -0
  69. package/dist/utils/copyToClipboard/index.js +3 -2
  70. package/dist/utils/createHotkey/createHotkey.js +4 -3
  71. package/dist/utils/createHotkey/index.js +3 -2
  72. package/dist/utils/debounce/debounce.js +4 -3
  73. package/dist/utils/debounce/index.js +3 -2
  74. package/dist/utils/deepEqual/deepEqual.d.ts +19 -0
  75. package/dist/utils/deepEqual/deepEqual.js +22 -0
  76. package/dist/utils/formatHotkey/formatHotkey.js +1 -0
  77. package/dist/utils/formatHotkey/index.js +1 -0
  78. package/dist/utils/getConstrainedPosition/getConstrainedPosition.js +6 -5
  79. package/dist/utils/getConstrainedPosition/index.js +3 -2
  80. package/dist/utils/getCurrentElementPosition/getCurrentElementPosition.js +1 -0
  81. package/dist/utils/getCurrentElementPosition/index.js +3 -2
  82. package/dist/utils/getPositionAdjustment/getPositionAdjustment.js +6 -5
  83. package/dist/utils/getPositionAdjustment/index.js +3 -2
  84. package/dist/utils/getStringPreview/getStringPreview.js +3 -2
  85. package/dist/utils/getStringPreview/index.js +1 -0
  86. package/dist/utils/hasControlChanged/hasControlChanged.js +7 -5
  87. package/dist/utils/hasControlChanged/index.js +3 -2
  88. package/dist/utils/isMacOS/index.js +3 -2
  89. package/dist/utils/isMacOS/isMacOS.js +3 -2
  90. package/dist/utils/isValidPersistedValue/isValidPersistedValue.d.ts +13 -0
  91. package/dist/utils/isValidPersistedValue/isValidPersistedValue.js +22 -0
  92. package/dist/utils/prettifyJson/index.js +3 -2
  93. package/dist/utils/prettifyJson/prettifyJson.js +5 -4
  94. package/package.json +7 -3
  95. package/dist/assets/index16.css +0 -1
@@ -0,0 +1,24 @@
1
+ import { Component, ErrorInfo, ReactNode } from 'react';
2
+ interface ControlErrorBoundaryProps {
3
+ /** Control rendered inside the boundary. */
4
+ children: ReactNode;
5
+ /** UI shown when the child throws. */
6
+ fallback: ReactNode;
7
+ /** Identifier (control name) used in the logged error. */
8
+ name?: string;
9
+ }
10
+ interface ControlErrorBoundaryState {
11
+ hasError: boolean;
12
+ }
13
+ /**
14
+ * Error boundary that isolates a single control's render failures so a broken
15
+ * or misconfigured control (or a failed lazy import) cannot crash the whole
16
+ * dev panel or the host application.
17
+ */
18
+ export declare class ControlErrorBoundary extends Component<ControlErrorBoundaryProps, ControlErrorBoundaryState> {
19
+ state: ControlErrorBoundaryState;
20
+ static getDerivedStateFromError(): ControlErrorBoundaryState;
21
+ componentDidCatch(error: Error, info: ErrorInfo): void;
22
+ render(): ReactNode;
23
+ }
24
+ export {};
@@ -0,0 +1,17 @@
1
+ "use client";
2
+ import { Component as t } from "react";
3
+ class s extends t {
4
+ state = { hasError: !1 };
5
+ static getDerivedStateFromError() {
6
+ return { hasError: !0 };
7
+ }
8
+ componentDidCatch(r, e) {
9
+ console.error(`[DevPanel] Control "${this.props.name ?? "unknown"}" failed to render:`, r, e.componentStack);
10
+ }
11
+ render() {
12
+ return this.state.hasError ? this.props.fallback : this.props.children;
13
+ }
14
+ }
15
+ export {
16
+ s as ControlErrorBoundary
17
+ };
@@ -1,13 +1,14 @@
1
- import { jsxs as n, jsx as r } from "react/jsx-runtime";
2
- import { useRef as c } from "react";
3
- import '../../../../assets/index16.css';const l = "_slider_1rjjb_235", t = {
4
- switch: "_switch_1rjjb_217",
5
- slider: l
1
+ "use client";
2
+ import { jsxs as c, jsx as t } from "react/jsx-runtime";
3
+ import { useRef as l } from "react";
4
+ import '../../../../assets/index14.css';const r = "_slider_ktq7k_19", n = {
5
+ switch: "_switch_ktq7k_1",
6
+ slider: r
6
7
  };
7
8
  function d({ control: e }) {
8
- const s = c(`boolean-control-${e.label || Math.ceil(Math.random() * 1e5)}`);
9
- return /* @__PURE__ */ n("label", { className: t.switch, children: [
10
- /* @__PURE__ */ r(
9
+ const s = l(`boolean-control-${e.label || Math.ceil(Math.random() * 1e5)}`);
10
+ return /* @__PURE__ */ c("label", { className: n.switch, children: [
11
+ /* @__PURE__ */ t(
11
12
  "input",
12
13
  {
13
14
  type: "checkbox",
@@ -18,7 +19,7 @@ function d({ control: e }) {
18
19
  onChange: (a) => e.onChange(a.target.checked)
19
20
  }
20
21
  ),
21
- /* @__PURE__ */ r("span", { className: t.slider })
22
+ /* @__PURE__ */ t("span", { className: n.slider })
22
23
  ] });
23
24
  }
24
25
  export {
@@ -1,10 +1,11 @@
1
+ "use client";
1
2
  import { jsx as n } from "react/jsx-runtime";
2
- import '../../../../assets/index15.css';const o = "_button_1h30c_217", s = {
3
+ import '../../../../assets/index13.css';const o = "_button_umswk_1", s = {
3
4
  button: o
4
5
  };
5
- function e({ control: t }) {
6
+ function u({ control: t }) {
6
7
  return /* @__PURE__ */ n("button", { onClick: t.onClick, disabled: t.disabled, className: s.button, children: t.label });
7
8
  }
8
9
  export {
9
- e as ButtonControl
10
+ u as ButtonControl
10
11
  };
@@ -1,10 +1,11 @@
1
+ "use client";
1
2
  import { jsx as t } from "react/jsx-runtime";
2
3
  import { ButtonControl as e } from "../ButtonControl/index.js";
3
- import '../../../../assets/index14.css';const i = "_buttonGroupContainer_1irhu_217", l = {
4
- buttonGroupContainer: i
4
+ import '../../../../assets/index12.css';const l = "_buttonGroupContainer_1wyhv_1", i = {
5
+ buttonGroupContainer: l
5
6
  };
6
- function p({ control: n }) {
7
- return /* @__PURE__ */ t("div", { className: l.buttonGroupContainer, children: n.buttons.map((o, r) => /* @__PURE__ */ t(
7
+ function s({ control: n }) {
8
+ return /* @__PURE__ */ t("div", { className: i.buttonGroupContainer, children: n.buttons.map((o, r) => /* @__PURE__ */ t(
8
9
  e,
9
10
  {
10
11
  control: {
@@ -18,5 +19,5 @@ function p({ control: n }) {
18
19
  )) });
19
20
  }
20
21
  export {
21
- p as ButtonGroupControl
22
+ s as ButtonGroupControl
22
23
  };
@@ -1,8 +1,9 @@
1
+ "use client";
1
2
  import { jsxs as m, jsx as l } from "react/jsx-runtime";
2
3
  import { useState as v, useEffect as C } from "react";
3
4
  import { Input as p } from "../../../Input/index.js";
4
5
  import { useDebouncedCallback as b } from "../../../../hooks/useDebounceCallback/index.js";
5
- import '../../../../assets/index13.css';const y = "_container_1oo6z_1", x = "_colorPreview_1oo6z_7", V = "_errorMessage_1oo6z_52", c = {
6
+ import '../../../../assets/index11.css';const y = "_container_1oo6z_1", x = "_colorPreview_1oo6z_7", V = "_errorMessage_1oo6z_52", c = {
6
7
  container: y,
7
8
  colorPreview: x,
8
9
  errorMessage: V
@@ -1,19 +1,20 @@
1
- import { jsx as m } from "react/jsx-runtime";
2
- import { useState as o, useEffect as s } from "react";
1
+ "use client";
2
+ import { jsx as f } from "react/jsx-runtime";
3
+ import { useState as m, useEffect as o } from "react";
3
4
  import { Input as r } from "../../../Input/index.js";
4
5
  function h({ control: e }) {
5
- const n = e.event || "onBlur", [l, t] = o(e.value);
6
+ const n = e.event || "onBlur", [l, t] = m(e.value);
6
7
  function i(u) {
7
8
  const a = u.target.value;
8
9
  t(a), n === "onChange" && e.onChange(a);
9
10
  }
10
- function f(u) {
11
+ function s(u) {
11
12
  const a = u.target.value;
12
13
  n === "onBlur" && e.onChange(a);
13
14
  }
14
- return s(() => {
15
+ return o(() => {
15
16
  t(e.value);
16
- }, [e.value]), /* @__PURE__ */ m(
17
+ }, [e.value]), /* @__PURE__ */ f(
17
18
  r,
18
19
  {
19
20
  type: "date",
@@ -22,7 +23,7 @@ function h({ control: e }) {
22
23
  max: e.max,
23
24
  disabled: e.disabled,
24
25
  onChange: i,
25
- ...n === "onBlur" && { onBlur: f }
26
+ ...n === "onBlur" && { onBlur: s }
26
27
  }
27
28
  );
28
29
  }
@@ -1,7 +1,8 @@
1
- import { jsxs as u, Fragment as k, jsx as r } from "react/jsx-runtime";
1
+ "use client";
2
+ import { jsxs as u, Fragment as k, jsx as i } from "react/jsx-runtime";
2
3
  import { useState as n, useRef as R, useCallback as t } from "react";
3
4
  import { className as M } from "../../../../utils/className/className.js";
4
- import '../../../../assets/index12.css';const I = "_dropZone_p0d3i_9", Z = "_disabled_p0d3i_26", j = "_active_p0d3i_45", A = "_supportedFormats_p0d3i_60", P = "_dropText_p0d3i_66", N = "_droppedFile_p0d3i_71", E = "_droppedText_p0d3i_79", L = "_errorMessage_p0d3i_86", d = {
5
+ import '../../../../assets/index10.css';const I = "_dropZone_p0d3i_9", Z = "_disabled_p0d3i_26", j = "_active_p0d3i_45", A = "_supportedFormats_p0d3i_60", P = "_dropText_p0d3i_66", N = "_droppedFile_p0d3i_71", E = "_droppedText_p0d3i_79", L = "_errorMessage_p0d3i_86", d = {
5
6
  dropZone: I,
6
7
  disabled: Z,
7
8
  active: j,
@@ -12,7 +13,7 @@ import '../../../../assets/index12.css';const I = "_dropZone_p0d3i_9", Z = "_dis
12
13
  errorMessage: L
13
14
  };
14
15
  function V({ control: s }) {
15
- const [D, i] = n(!1), [o, f] = n(null), [v, b] = n(!0), [g, l] = n(""), c = R(null), _ = t(
16
+ const [D, r] = n(!1), [o, f] = n(null), [v, b] = n(!0), [g, l] = n(""), c = R(null), _ = t(
16
17
  (e) => {
17
18
  if (!s.allowedFileTypes)
18
19
  return !0;
@@ -24,13 +25,13 @@ function V({ control: s }) {
24
25
  (e) => {
25
26
  if (s.allowedFileTypes && !_(e.name)) {
26
27
  l(`File type not allowed.
27
- Supported formats: ${s.allowedFileTypes.join(", ")}`), i(!1);
28
+ Supported formats: ${s.allowedFileTypes.join(", ")}`), r(!1);
28
29
  return;
29
30
  }
30
31
  l("");
31
32
  const a = new FileReader();
32
33
  a.onload = () => {
33
- i(!1);
34
+ r(!1);
34
35
  const F = {
35
36
  base64: a.result,
36
37
  file: e,
@@ -43,7 +44,7 @@ function V({ control: s }) {
43
44
  f(F), b(!1), s.onDrop(F);
44
45
  }, a.readAsDataURL(e);
45
46
  },
46
- [s, _, l, f, b, i]
47
+ [s, _, l, f, b, r]
47
48
  ), h = t(() => {
48
49
  !o && c.current && !s.disabled && c.current.click();
49
50
  }, [o, s.disabled]), T = t(
@@ -54,7 +55,7 @@ function V({ control: s }) {
54
55
  [p]
55
56
  ), w = t(
56
57
  (e) => {
57
- s.disabled || (e.preventDefault(), e.stopPropagation(), i(!0), l(""));
58
+ s.disabled || (e.preventDefault(), e.stopPropagation(), r(!0), l(""));
58
59
  },
59
60
  [s.disabled]
60
61
  ), y = t(
@@ -67,17 +68,17 @@ function V({ control: s }) {
67
68
  [p, s.disabled]
68
69
  ), x = t(
69
70
  (e) => {
70
- s.disabled || (e.preventDefault(), e.stopPropagation(), i(!0), l(""));
71
+ s.disabled || (e.preventDefault(), e.stopPropagation(), r(!0), l(""));
71
72
  },
72
73
  [s.disabled]
73
74
  ), C = t(
74
75
  (e) => {
75
- s.disabled || (e.preventDefault(), e.stopPropagation(), i(!1));
76
+ s.disabled || (e.preventDefault(), e.stopPropagation(), r(!1));
76
77
  },
77
78
  [s.disabled]
78
79
  );
79
80
  return /* @__PURE__ */ u(k, { children: [
80
- /* @__PURE__ */ r(
81
+ /* @__PURE__ */ i(
81
82
  "input",
82
83
  {
83
84
  ref: c,
@@ -88,7 +89,7 @@ function V({ control: s }) {
88
89
  disabled: s.disabled
89
90
  }
90
91
  ),
91
- /* @__PURE__ */ r(
92
+ /* @__PURE__ */ i(
92
93
  "div",
93
94
  {
94
95
  ...M(d.dropZone, {
@@ -100,13 +101,13 @@ function V({ control: s }) {
100
101
  onDragLeave: C,
101
102
  onDrop: y,
102
103
  onClick: h,
103
- children: g ? /* @__PURE__ */ r("div", { className: d.errorMessage, children: /* @__PURE__ */ r("p", { children: g }) }) : o ? /* @__PURE__ */ r("div", { className: d.droppedFile, children: /* @__PURE__ */ u("p", { className: d.droppedText, children: [
104
+ children: g ? /* @__PURE__ */ i("div", { className: d.errorMessage, children: /* @__PURE__ */ i("p", { children: g }) }) : o ? /* @__PURE__ */ i("div", { className: d.droppedFile, children: /* @__PURE__ */ u("p", { className: d.droppedText, children: [
104
105
  "Dropped '",
105
106
  o.name,
106
107
  "'"
107
108
  ] }) }) : v ? /* @__PURE__ */ u("div", { children: [
108
- /* @__PURE__ */ r("p", { className: d.dropText, children: "Drag & Drop a file here or click to browse" }),
109
- /* @__PURE__ */ r("p", { className: d.supportedFormats, children: s.allowedFileTypes ? `Supported formats: ${s.allowedFileTypes.join(", ")}` : "All file types are supported" })
109
+ /* @__PURE__ */ i("p", { className: d.dropText, children: "Drag & Drop a file here or click to browse" }),
110
+ /* @__PURE__ */ i("p", { className: d.supportedFormats, children: s.allowedFileTypes ? `Supported formats: ${s.allowedFileTypes.join(", ")}` : "All file types are supported" })
110
111
  ] }) : null
111
112
  }
112
113
  )
@@ -1,13 +1,14 @@
1
- import { jsxs as s, jsx as t, Fragment as f } from "react/jsx-runtime";
1
+ "use client";
2
+ import { jsxs as n, jsx as a, Fragment as m } from "react/jsx-runtime";
2
3
  import l from "react";
3
- import { copyToClipboard as H } from "../../../../utils/copyToClipboard/copyToClipboard.js";
4
- import { getStringPreview as $ } from "../../../../utils/getStringPreview/getStringPreview.js";
5
- import { prettifyJson as M } from "../../../../utils/prettifyJson/prettifyJson.js";
6
- import '../../../../assets/index11.css';const j = "_container_cgfc3_217", P = "_header_cgfc3_224", J = "_count_cgfc3_230", q = "_actions_cgfc3_236", z = "_btnRefresh_cgfc3_241", G = "_btnAdd_cgfc3_242", O = "_itemsList_cgfc3_279", Q = "_card_cgfc3_285", U = "_cardHeader_cgfc3_297", W = "_clickable_cgfc3_308", X = "_collapseIcon_cgfc3_312", Y = "_cardTitle_cgfc3_323", Z = "_keyCode_cgfc3_329", ee = "_cardBody_cgfc3_337", ae = "_field_cgfc3_344", te = "_valueActions_cgfc3_354", le = "_fieldLabel_cgfc3_359", ce = "_input_cgfc3_367", se = "_textarea_cgfc3_399", ne = "_valueText_cgfc3_445", de = "_btnToggle_cgfc3_461", oe = "_cardActions_cgfc3_492", ie = "_btnSave_cgfc3_498", re = "_btnCancel_cgfc3_499", ue = "_btnEdit_cgfc3_500", be = "_btnDelete_cgfc3_501", _e = "_empty_cgfc3_567", a = {
7
- container: j,
8
- header: P,
9
- count: J,
10
- actions: q,
4
+ import { copyToClipboard as F } from "../../../../utils/copyToClipboard/copyToClipboard.js";
5
+ import { getStringPreview as H } from "../../../../utils/getStringPreview/getStringPreview.js";
6
+ import { prettifyJson as $ } from "../../../../utils/prettifyJson/prettifyJson.js";
7
+ import '../../../../assets/index9.css';const M = "_container_1qtvu_1", j = "_header_1qtvu_8", P = "_count_1qtvu_14", J = "_actions_1qtvu_20", z = "_btnRefresh_1qtvu_25", G = "_btnAdd_1qtvu_26", O = "_itemsList_1qtvu_63", Q = "_card_1qtvu_69", U = "_cardHeader_1qtvu_81", W = "_clickable_1qtvu_92", X = "_collapseIcon_1qtvu_96", Y = "_cardTitle_1qtvu_107", Z = "_keyCode_1qtvu_113", ee = "_cardBody_1qtvu_121", te = "_field_1qtvu_128", ae = "_valueActions_1qtvu_138", le = "_fieldLabel_1qtvu_143", se = "_input_1qtvu_151", ne = "_textarea_1qtvu_183", ce = "_valueText_1qtvu_229", de = "_btnToggle_1qtvu_245", oe = "_cardActions_1qtvu_276", ie = "_btnSave_1qtvu_282", re = "_btnCancel_1qtvu_283", ue = "_btnEdit_1qtvu_284", be = "_btnDelete_1qtvu_285", ve = "_empty_1qtvu_351", t = {
8
+ container: M,
9
+ header: j,
10
+ count: P,
11
+ actions: J,
11
12
  btnRefresh: z,
12
13
  btnAdd: G,
13
14
  itemsList: O,
@@ -18,82 +19,82 @@ import '../../../../assets/index11.css';const j = "_container_cgfc3_217", P = "_
18
19
  cardTitle: Y,
19
20
  keyCode: Z,
20
21
  cardBody: ee,
21
- field: ae,
22
- valueActions: te,
22
+ field: te,
23
+ valueActions: ae,
23
24
  fieldLabel: le,
24
- input: ce,
25
- textarea: se,
26
- valueText: ne,
25
+ input: se,
26
+ textarea: ne,
27
+ valueText: ce,
27
28
  btnToggle: de,
28
29
  cardActions: oe,
29
30
  btnSave: ie,
30
31
  btnCancel: re,
31
32
  btnEdit: ue,
32
33
  btnDelete: be,
33
- empty: _e
34
+ empty: ve
34
35
  };
35
- function ve({ control: n }) {
36
- const [_, E] = l.useState([]), [C, m] = l.useState(null), [y, g] = l.useState(""), [r, N] = l.useState(""), [v, S] = l.useState(""), [k, p] = l.useState(!1), [u, w] = l.useState(/* @__PURE__ */ new Map()), [A, x] = l.useState(null), o = l.useCallback(() => {
36
+ function ge({ control: c }) {
37
+ const [v, x] = l.useState([]), [f, y] = l.useState(null), [k, _] = l.useState(""), [r, N] = l.useState(""), [g, S] = l.useState(""), [p, C] = l.useState(!1), [u, w] = l.useState(/* @__PURE__ */ new Map()), [E, q] = l.useState(null), o = l.useCallback(() => {
37
38
  const e = [];
38
39
  for (let d = 0; d < localStorage.length; d++) {
39
40
  const i = localStorage.key(d);
40
41
  if (i) {
41
- const F = localStorage.getItem(i);
42
- e.push({ key: i, value: F || "" });
42
+ const B = localStorage.getItem(i);
43
+ e.push({ key: i, value: B || "" });
43
44
  }
44
45
  }
45
- const c = e.sort((d, i) => d.key.localeCompare(i.key));
46
- E(c);
46
+ const s = e.sort((d, i) => d.key.localeCompare(i.key));
47
+ x(s);
47
48
  const b = /* @__PURE__ */ new Map();
48
- c.forEach((d) => {
49
+ s.forEach((d) => {
49
50
  b.set(d.key, {
50
51
  collapsed: !0,
51
52
  valueExpanded: !1,
52
- formattedValue: M(d.value)
53
+ formattedValue: $(d.value)
53
54
  });
54
- }), w(b), n.onRefresh?.();
55
- }, [n]), I = l.useCallback(
55
+ }), w(b), c.onRefresh?.();
56
+ }, [c]), A = l.useCallback(
56
57
  (e) => {
57
58
  confirm(`Delete "${e}" from localStorage?`) && (localStorage.removeItem(e), o());
58
59
  },
59
60
  [o]
60
- ), T = l.useCallback((e, c) => {
61
- m(e), g(c);
62
- }, []), L = l.useCallback(
61
+ ), I = l.useCallback((e, s) => {
62
+ y(e), _(s);
63
+ }, []), T = l.useCallback(
63
64
  (e) => {
64
- localStorage.setItem(e, y), m(null), g(""), o();
65
+ localStorage.setItem(e, k), y(null), _(""), o();
65
66
  },
66
- [y, o]
67
- ), D = l.useCallback(() => {
68
- m(null), g("");
69
- }, []), K = l.useCallback(() => {
67
+ [k, o]
68
+ ), L = l.useCallback(() => {
69
+ y(null), _("");
70
+ }, []), D = l.useCallback(() => {
70
71
  if (r.trim() === "") {
71
72
  alert("The key cannot be empty");
72
73
  return;
73
74
  }
74
- localStorage.getItem(r) !== null && !confirm(`The key "${r}" already exists. Do you want to overwrite it?`) || (localStorage.setItem(r, v), N(""), S(""), p(!1), o());
75
- }, [r, v, o]), V = l.useCallback(async (e, c) => {
75
+ localStorage.getItem(r) !== null && !confirm(`The key "${r}" already exists. Do you want to overwrite it?`) || (localStorage.setItem(r, g), N(""), S(""), C(!1), o());
76
+ }, [r, g, o]), K = l.useCallback(async (e, s) => {
76
77
  try {
77
- await H(c), x(e), setTimeout(() => {
78
- x(null);
78
+ await F(s), q(e), setTimeout(() => {
79
+ q(null);
79
80
  }, 2e3);
80
81
  } catch {
81
82
  alert("Failed to copy to clipboard");
82
83
  }
83
- }, []), h = l.useCallback((e, c) => {
84
+ }, []), h = l.useCallback((e, s) => {
84
85
  w((b) => {
85
86
  const d = new Map(b), i = d.get(e);
86
87
  return i ? (d.set(e, {
87
88
  ...i,
88
- [c]: !i[c]
89
+ [s]: !i[s]
89
90
  }), d) : b;
90
91
  });
91
- }, []), R = l.useCallback(
92
- (e, c) => {
93
- (e.key === "Enter" || e.key === " ") && h(c, "collapsed");
92
+ }, []), V = l.useCallback(
93
+ (e, s) => {
94
+ (e.key === "Enter" || e.key === " ") && h(s, "collapsed");
94
95
  },
95
96
  [h]
96
- ), B = l.useCallback((e, c = 100) => $(e, c), []);
97
+ ), R = l.useCallback((e, s = 100) => H(e, s), []);
97
98
  return l.useEffect(() => {
98
99
  o();
99
100
  function e() {
@@ -102,142 +103,142 @@ function ve({ control: n }) {
102
103
  return window.addEventListener("storage", e), () => {
103
104
  window.removeEventListener("storage", e);
104
105
  };
105
- }, []), /* @__PURE__ */ s("div", { className: a.container, children: [
106
- /* @__PURE__ */ s("div", { className: a.header, children: [
107
- /* @__PURE__ */ s("span", { className: a.count, children: [
108
- _.length,
109
- _.length === 1 ? " item" : " items"
106
+ }, []), /* @__PURE__ */ n("div", { className: t.container, children: [
107
+ /* @__PURE__ */ n("div", { className: t.header, children: [
108
+ /* @__PURE__ */ n("span", { className: t.count, children: [
109
+ v.length,
110
+ v.length === 1 ? " item" : " items"
110
111
  ] }),
111
- /* @__PURE__ */ s("div", { className: a.actions, children: [
112
- /* @__PURE__ */ t("button", { className: a.btnRefresh, onClick: o, disabled: n.disabled, title: "Refresh", children: "🔄" }),
113
- /* @__PURE__ */ t("button", { className: a.btnAdd, onClick: () => p(!k), disabled: n.disabled, title: "Add new", children: k ? "✕" : "+" })
112
+ /* @__PURE__ */ n("div", { className: t.actions, children: [
113
+ /* @__PURE__ */ a("button", { className: t.btnRefresh, onClick: o, disabled: c.disabled, title: "Refresh", children: "🔄" }),
114
+ /* @__PURE__ */ a("button", { className: t.btnAdd, onClick: () => C(!p), disabled: c.disabled, title: "Add new", children: p ? "✕" : "+" })
114
115
  ] })
115
116
  ] }),
116
- k && /* @__PURE__ */ s("div", { className: a.card, children: [
117
- /* @__PURE__ */ t("div", { className: a.cardHeader, children: /* @__PURE__ */ t("span", { className: a.cardTitle, children: "New entry" }) }),
118
- /* @__PURE__ */ s("div", { className: a.cardBody, children: [
119
- /* @__PURE__ */ s("div", { className: a.field, children: [
120
- /* @__PURE__ */ t("label", { className: a.fieldLabel, children: "Key" }),
121
- /* @__PURE__ */ t(
117
+ p && /* @__PURE__ */ n("div", { className: t.card, children: [
118
+ /* @__PURE__ */ a("div", { className: t.cardHeader, children: /* @__PURE__ */ a("span", { className: t.cardTitle, children: "New entry" }) }),
119
+ /* @__PURE__ */ n("div", { className: t.cardBody, children: [
120
+ /* @__PURE__ */ n("div", { className: t.field, children: [
121
+ /* @__PURE__ */ a("label", { className: t.fieldLabel, children: "Key" }),
122
+ /* @__PURE__ */ a(
122
123
  "input",
123
124
  {
124
125
  type: "text",
125
- className: a.input,
126
+ className: t.input,
126
127
  placeholder: "key_name",
127
128
  value: r,
128
129
  onChange: (e) => N(e.target.value),
129
- disabled: n.disabled
130
+ disabled: c.disabled
130
131
  }
131
132
  )
132
133
  ] }),
133
- /* @__PURE__ */ s("div", { className: a.field, children: [
134
- /* @__PURE__ */ t("label", { className: a.fieldLabel, children: "Value" }),
135
- /* @__PURE__ */ t(
134
+ /* @__PURE__ */ n("div", { className: t.field, children: [
135
+ /* @__PURE__ */ a("label", { className: t.fieldLabel, children: "Value" }),
136
+ /* @__PURE__ */ a(
136
137
  "textarea",
137
138
  {
138
- className: a.textarea,
139
+ className: t.textarea,
139
140
  placeholder: '{"example": "value"}',
140
- value: v,
141
+ value: g,
141
142
  onChange: (e) => S(e.target.value),
142
- disabled: n.disabled,
143
+ disabled: c.disabled,
143
144
  rows: 3
144
145
  }
145
146
  )
146
147
  ] })
147
148
  ] }),
148
- /* @__PURE__ */ s("div", { className: a.cardActions, children: [
149
- /* @__PURE__ */ t("button", { className: a.btnSave, onClick: K, disabled: n.disabled, children: "Save" }),
150
- /* @__PURE__ */ t("button", { className: a.btnCancel, onClick: () => p(!1), disabled: n.disabled, children: "Cancel" })
149
+ /* @__PURE__ */ n("div", { className: t.cardActions, children: [
150
+ /* @__PURE__ */ a("button", { className: t.btnSave, onClick: D, disabled: c.disabled, children: "Save" }),
151
+ /* @__PURE__ */ a("button", { className: t.btnCancel, onClick: () => C(!1), disabled: c.disabled, children: "Cancel" })
151
152
  ] })
152
153
  ] }),
153
- /* @__PURE__ */ t("div", { className: a.itemsList, children: _.length === 0 ? /* @__PURE__ */ t("div", { className: a.empty, children: "No data in localStorage" }) : _.map((e) => /* @__PURE__ */ s("div", { className: a.card, children: [
154
- /* @__PURE__ */ s(
154
+ /* @__PURE__ */ a("div", { className: t.itemsList, children: v.length === 0 ? /* @__PURE__ */ a("div", { className: t.empty, children: "No data in localStorage" }) : v.map((e) => /* @__PURE__ */ n("div", { className: t.card, children: [
155
+ /* @__PURE__ */ n(
155
156
  "div",
156
157
  {
157
- className: `${a.cardHeader} ${a.clickable}`,
158
+ className: `${t.cardHeader} ${t.clickable}`,
158
159
  onClick: () => h(e.key, "collapsed"),
159
160
  role: "button",
160
161
  tabIndex: 0,
161
- onKeyDown: (c) => R(c, e.key),
162
+ onKeyDown: (s) => V(s, e.key),
162
163
  children: [
163
- /* @__PURE__ */ t("span", { className: a.collapseIcon, children: u.get(e.key)?.collapsed ? "▶" : "▼" }),
164
- /* @__PURE__ */ t("code", { className: a.keyCode, children: e.key })
164
+ /* @__PURE__ */ a("span", { className: t.collapseIcon, children: u.get(e.key)?.collapsed ? "▶" : "▼" }),
165
+ /* @__PURE__ */ a("code", { className: t.keyCode, children: e.key })
165
166
  ]
166
167
  }
167
168
  ),
168
- !u.get(e.key)?.collapsed && /* @__PURE__ */ s(f, { children: [
169
- /* @__PURE__ */ t("div", { className: a.cardBody, children: C === e.key ? /* @__PURE__ */ t(
169
+ !u.get(e.key)?.collapsed && /* @__PURE__ */ n(m, { children: [
170
+ /* @__PURE__ */ a("div", { className: t.cardBody, children: f === e.key ? /* @__PURE__ */ a(
170
171
  "textarea",
171
172
  {
172
- className: a.textarea,
173
- value: y,
174
- onChange: (c) => g(c.target.value),
175
- disabled: n.disabled,
173
+ className: t.textarea,
174
+ value: k,
175
+ onChange: (s) => _(s.target.value),
176
+ disabled: c.disabled,
176
177
  rows: 6,
177
178
  autoFocus: !0
178
179
  }
179
- ) : /* @__PURE__ */ s(f, { children: [
180
- /* @__PURE__ */ t("pre", { className: a.valueText, children: u.get(e.key)?.valueExpanded ? u.get(e.key)?.formattedValue : B(u.get(e.key)?.formattedValue || e.value) }),
181
- /* @__PURE__ */ s("div", { className: a.valueActions, children: [
182
- e.value.length > 100 && /* @__PURE__ */ t(
180
+ ) : /* @__PURE__ */ n(m, { children: [
181
+ /* @__PURE__ */ a("pre", { className: t.valueText, children: u.get(e.key)?.valueExpanded ? u.get(e.key)?.formattedValue : R(u.get(e.key)?.formattedValue || e.value) }),
182
+ /* @__PURE__ */ n("div", { className: t.valueActions, children: [
183
+ e.value.length > 100 && /* @__PURE__ */ a(
183
184
  "button",
184
185
  {
185
- className: a.btnToggle,
186
+ className: t.btnToggle,
186
187
  onClick: () => h(e.key, "valueExpanded"),
187
- disabled: n.disabled,
188
+ disabled: c.disabled,
188
189
  children: u.get(e.key)?.valueExpanded ? "▲ Show less" : "▼ Show more"
189
190
  }
190
191
  ),
191
- /* @__PURE__ */ t(
192
+ /* @__PURE__ */ a(
192
193
  "button",
193
194
  {
194
- className: a.btnToggle,
195
- onClick: () => V(e.key, e.value),
196
- disabled: n.disabled,
195
+ className: t.btnToggle,
196
+ onClick: () => K(e.key, e.value),
197
+ disabled: c.disabled,
197
198
  title: "Copy content",
198
- children: A === e.key ? "✓ Copied" : "📎 Copy"
199
+ children: E === e.key ? "✓ Copied" : "📎 Copy"
199
200
  }
200
201
  )
201
202
  ] })
202
203
  ] }) }),
203
- /* @__PURE__ */ t("div", { className: a.cardActions, children: C === e.key ? /* @__PURE__ */ s(f, { children: [
204
- /* @__PURE__ */ t(
204
+ /* @__PURE__ */ a("div", { className: t.cardActions, children: f === e.key ? /* @__PURE__ */ n(m, { children: [
205
+ /* @__PURE__ */ a(
205
206
  "button",
206
207
  {
207
- className: a.btnSave,
208
- onClick: () => L(e.key),
209
- disabled: n.disabled,
208
+ className: t.btnSave,
209
+ onClick: () => T(e.key),
210
+ disabled: c.disabled,
210
211
  title: "Save",
211
212
  children: "💾 Save"
212
213
  }
213
214
  ),
214
- /* @__PURE__ */ t(
215
+ /* @__PURE__ */ a(
215
216
  "button",
216
217
  {
217
- className: a.btnCancel,
218
- onClick: D,
219
- disabled: n.disabled,
218
+ className: t.btnCancel,
219
+ onClick: L,
220
+ disabled: c.disabled,
220
221
  title: "Cancel",
221
222
  children: "✕ Cancel"
222
223
  }
223
224
  )
224
- ] }) : /* @__PURE__ */ s(f, { children: [
225
- /* @__PURE__ */ t(
225
+ ] }) : /* @__PURE__ */ n(m, { children: [
226
+ /* @__PURE__ */ a(
226
227
  "button",
227
228
  {
228
- className: a.btnEdit,
229
- onClick: () => T(e.key, e.value),
230
- disabled: n.disabled,
229
+ className: t.btnEdit,
230
+ onClick: () => I(e.key, e.value),
231
+ disabled: c.disabled,
231
232
  title: "Edit",
232
233
  children: "✏️ Edit"
233
234
  }
234
235
  ),
235
- /* @__PURE__ */ t(
236
+ /* @__PURE__ */ a(
236
237
  "button",
237
238
  {
238
- className: a.btnDelete,
239
- onClick: () => I(e.key),
240
- disabled: n.disabled,
239
+ className: t.btnDelete,
240
+ onClick: () => A(e.key),
241
+ disabled: c.disabled,
241
242
  title: "Delete",
242
243
  children: "🗑️ Delete"
243
244
  }
@@ -248,5 +249,5 @@ function ve({ control: n }) {
248
249
  ] });
249
250
  }
250
251
  export {
251
- ve as LocalStorageControl
252
+ ge as LocalStorageControl
252
253
  };
@@ -9,6 +9,8 @@ import { MultiSelectControlProps } from './types';
9
9
  * @param props.control.options - Array of available options (strings or objects with label/value)
10
10
  * @param props.control.onChange - Callback function triggered when selection changes
11
11
  * @param props.control.disabled - Optional flag to disable the control
12
+ * @param props.control.searchable - Optional flag to show a search input that filters the options
13
+ * @param props.control.searchPlaceholder - Optional placeholder for the search input
12
14
  * @returns JSX element representing the multi-select control
13
15
  *
14
16
  * @example