@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.
- package/README.md +43 -1
- package/dist/assets/index.css +1 -1
- package/dist/assets/index10.css +1 -1
- package/dist/assets/index11.css +1 -1
- package/dist/assets/index12.css +1 -1
- package/dist/assets/index13.css +1 -1
- package/dist/assets/index14.css +1 -1
- package/dist/assets/index15.css +1 -1
- package/dist/assets/index2.css +1 -1
- package/dist/assets/index3.css +1 -1
- package/dist/assets/index4.css +1 -1
- package/dist/assets/index5.css +1 -1
- package/dist/assets/index6.css +1 -1
- package/dist/assets/index7.css +1 -1
- package/dist/assets/index8.css +1 -1
- package/dist/assets/index9.css +1 -1
- package/dist/components/ControlErrorBoundary/index.d.ts +24 -0
- package/dist/components/ControlErrorBoundary/index.js +17 -0
- package/dist/components/ControlRenderer/controls/BooleanControl/index.js +10 -9
- package/dist/components/ControlRenderer/controls/ButtonControl/index.js +4 -3
- package/dist/components/ControlRenderer/controls/ButtonGroupControl/index.js +6 -5
- package/dist/components/ControlRenderer/controls/ColorControl/index.js +2 -1
- package/dist/components/ControlRenderer/controls/DateControl/index.js +8 -7
- package/dist/components/ControlRenderer/controls/DragAndDropControl/index.js +15 -14
- package/dist/components/ControlRenderer/controls/LocalStorageControl/index.js +111 -110
- package/dist/components/ControlRenderer/controls/MultiSelectControl/index.d.ts +2 -0
- package/dist/components/ControlRenderer/controls/MultiSelectControl/index.js +8 -5
- package/dist/components/ControlRenderer/controls/MultiSelectControl/types.d.ts +2 -0
- package/dist/components/ControlRenderer/controls/NumberControl/index.js +10 -9
- package/dist/components/ControlRenderer/controls/RangeControl/index.js +6 -5
- package/dist/components/ControlRenderer/controls/SelectControl/index.js +5 -4
- package/dist/components/ControlRenderer/controls/SeparatorControl/index.js +2 -1
- package/dist/components/ControlRenderer/controls/TextControl/index.js +7 -6
- package/dist/components/ControlRenderer/controls/index.js +1 -0
- package/dist/components/ControlRenderer/index.js +28 -26
- package/dist/components/DevPanel/index.js +12 -11
- package/dist/components/DevPanel/types.d.ts +17 -0
- package/dist/components/DevPanelPortal/index.js +5 -4
- package/dist/components/EmptyContent/index.js +2 -1
- package/dist/components/Icon/index.js +11 -10
- package/dist/components/Input/index.js +2 -1
- package/dist/components/Section/index.js +2 -1
- package/dist/components/Select/index.js +11 -10
- package/dist/components/Textarea/index.js +5 -4
- package/dist/components/index.js +3 -2
- package/dist/hooks/useDebounceCallback/index.js +1 -0
- package/dist/hooks/useDevPanel/consoleApi.d.ts +37 -0
- package/dist/hooks/useDevPanel/consoleApi.js +16 -0
- package/dist/hooks/useDevPanel/index.d.ts +5 -1
- package/dist/hooks/useDevPanel/index.js +50 -41
- package/dist/hooks/useDevPanel/mountDevPanelPortal.d.ts +18 -0
- package/dist/hooks/useDevPanel/mountDevPanelPortal.js +20 -0
- package/dist/hooks/useDragAndDrop/index.js +1 -0
- package/dist/hooks/useHotKey/index.js +4 -3
- package/dist/hooks/useHotkeys/index.js +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +4 -3
- package/dist/managers/DevPanelManager.js +1 -0
- package/dist/store/BaseStoreService.d.ts +2 -7
- package/dist/store/BaseStoreService.js +14 -7
- package/dist/store/ControlPersistenceService.d.ts +2 -0
- package/dist/store/ControlPersistenceService.js +34 -26
- package/dist/store/SectionsStore.js +3 -2
- package/dist/store/UIStore.d.ts +14 -0
- package/dist/store/UIStore.js +37 -22
- package/dist/utils/className/className.js +6 -5
- package/dist/utils/className/index.js +3 -2
- package/dist/utils/copyToClipboard/copyToClipboard.js +1 -0
- package/dist/utils/copyToClipboard/index.js +3 -2
- package/dist/utils/createHotkey/createHotkey.js +4 -3
- package/dist/utils/createHotkey/index.js +3 -2
- package/dist/utils/debounce/debounce.js +4 -3
- package/dist/utils/debounce/index.js +3 -2
- package/dist/utils/deepEqual/deepEqual.d.ts +19 -0
- package/dist/utils/deepEqual/deepEqual.js +22 -0
- package/dist/utils/formatHotkey/formatHotkey.js +1 -0
- package/dist/utils/formatHotkey/index.js +1 -0
- package/dist/utils/getConstrainedPosition/getConstrainedPosition.js +6 -5
- package/dist/utils/getConstrainedPosition/index.js +3 -2
- package/dist/utils/getCurrentElementPosition/getCurrentElementPosition.js +1 -0
- package/dist/utils/getCurrentElementPosition/index.js +3 -2
- package/dist/utils/getPositionAdjustment/getPositionAdjustment.js +6 -5
- package/dist/utils/getPositionAdjustment/index.js +3 -2
- package/dist/utils/getStringPreview/getStringPreview.js +3 -2
- package/dist/utils/getStringPreview/index.js +1 -0
- package/dist/utils/hasControlChanged/hasControlChanged.js +7 -5
- package/dist/utils/hasControlChanged/index.js +3 -2
- package/dist/utils/isMacOS/index.js +3 -2
- package/dist/utils/isMacOS/isMacOS.js +3 -2
- package/dist/utils/isValidPersistedValue/isValidPersistedValue.d.ts +13 -0
- package/dist/utils/isValidPersistedValue/isValidPersistedValue.js +22 -0
- package/dist/utils/prettifyJson/index.js +3 -2
- package/dist/utils/prettifyJson/prettifyJson.js +5 -4
- package/package.json +7 -3
- package/dist/assets/index16.css +0 -1
|
@@ -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
|
-
|
|
2
|
-
import {
|
|
3
|
-
import
|
|
4
|
-
|
|
5
|
-
|
|
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 =
|
|
9
|
-
return /* @__PURE__ */
|
|
10
|
-
/* @__PURE__ */
|
|
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__ */
|
|
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/
|
|
3
|
+
import '../../../../assets/index13.css';const o = "_button_umswk_1", s = {
|
|
3
4
|
button: o
|
|
4
5
|
};
|
|
5
|
-
function
|
|
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
|
-
|
|
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/
|
|
4
|
-
buttonGroupContainer:
|
|
4
|
+
import '../../../../assets/index12.css';const l = "_buttonGroupContainer_1wyhv_1", i = {
|
|
5
|
+
buttonGroupContainer: l
|
|
5
6
|
};
|
|
6
|
-
function
|
|
7
|
-
return /* @__PURE__ */ t("div", { className:
|
|
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
|
-
|
|
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/
|
|
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
|
-
|
|
2
|
-
import {
|
|
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] =
|
|
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
|
|
11
|
+
function s(u) {
|
|
11
12
|
const a = u.target.value;
|
|
12
13
|
n === "onBlur" && e.onChange(a);
|
|
13
14
|
}
|
|
14
|
-
return
|
|
15
|
+
return o(() => {
|
|
15
16
|
t(e.value);
|
|
16
|
-
}, [e.value]), /* @__PURE__ */
|
|
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:
|
|
26
|
+
...n === "onBlur" && { onBlur: s }
|
|
26
27
|
}
|
|
27
28
|
);
|
|
28
29
|
}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
|
|
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/
|
|
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,
|
|
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(", ")}`),
|
|
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
|
-
|
|
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,
|
|
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(),
|
|
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(),
|
|
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(),
|
|
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__ */
|
|
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__ */
|
|
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__ */
|
|
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__ */
|
|
109
|
-
/* @__PURE__ */
|
|
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
|
-
|
|
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
|
|
4
|
-
import { getStringPreview as
|
|
5
|
-
import { prettifyJson as
|
|
6
|
-
import '../../../../assets/
|
|
7
|
-
container:
|
|
8
|
-
header:
|
|
9
|
-
count:
|
|
10
|
-
actions:
|
|
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:
|
|
22
|
-
valueActions:
|
|
22
|
+
field: te,
|
|
23
|
+
valueActions: ae,
|
|
23
24
|
fieldLabel: le,
|
|
24
|
-
input:
|
|
25
|
-
textarea:
|
|
26
|
-
valueText:
|
|
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:
|
|
34
|
+
empty: ve
|
|
34
35
|
};
|
|
35
|
-
function
|
|
36
|
-
const [
|
|
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
|
|
42
|
-
e.push({ key: i, value:
|
|
42
|
+
const B = localStorage.getItem(i);
|
|
43
|
+
e.push({ key: i, value: B || "" });
|
|
43
44
|
}
|
|
44
45
|
}
|
|
45
|
-
const
|
|
46
|
-
|
|
46
|
+
const s = e.sort((d, i) => d.key.localeCompare(i.key));
|
|
47
|
+
x(s);
|
|
47
48
|
const b = /* @__PURE__ */ new Map();
|
|
48
|
-
|
|
49
|
+
s.forEach((d) => {
|
|
49
50
|
b.set(d.key, {
|
|
50
51
|
collapsed: !0,
|
|
51
52
|
valueExpanded: !1,
|
|
52
|
-
formattedValue:
|
|
53
|
+
formattedValue: $(d.value)
|
|
53
54
|
});
|
|
54
|
-
}), w(b),
|
|
55
|
-
}, [
|
|
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
|
-
),
|
|
61
|
-
|
|
62
|
-
}, []),
|
|
61
|
+
), I = l.useCallback((e, s) => {
|
|
62
|
+
y(e), _(s);
|
|
63
|
+
}, []), T = l.useCallback(
|
|
63
64
|
(e) => {
|
|
64
|
-
localStorage.setItem(e,
|
|
65
|
+
localStorage.setItem(e, k), y(null), _(""), o();
|
|
65
66
|
},
|
|
66
|
-
[
|
|
67
|
-
),
|
|
68
|
-
|
|
69
|
-
}, []),
|
|
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,
|
|
75
|
-
}, [r,
|
|
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
|
|
78
|
-
|
|
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,
|
|
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
|
-
[
|
|
89
|
+
[s]: !i[s]
|
|
89
90
|
}), d) : b;
|
|
90
91
|
});
|
|
91
|
-
}, []),
|
|
92
|
-
(e,
|
|
93
|
-
(e.key === "Enter" || e.key === " ") && h(
|
|
92
|
+
}, []), V = l.useCallback(
|
|
93
|
+
(e, s) => {
|
|
94
|
+
(e.key === "Enter" || e.key === " ") && h(s, "collapsed");
|
|
94
95
|
},
|
|
95
96
|
[h]
|
|
96
|
-
),
|
|
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__ */
|
|
106
|
-
/* @__PURE__ */
|
|
107
|
-
/* @__PURE__ */
|
|
108
|
-
|
|
109
|
-
|
|
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__ */
|
|
112
|
-
/* @__PURE__ */
|
|
113
|
-
/* @__PURE__ */
|
|
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
|
-
|
|
117
|
-
/* @__PURE__ */
|
|
118
|
-
/* @__PURE__ */
|
|
119
|
-
/* @__PURE__ */
|
|
120
|
-
/* @__PURE__ */
|
|
121
|
-
/* @__PURE__ */
|
|
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:
|
|
126
|
+
className: t.input,
|
|
126
127
|
placeholder: "key_name",
|
|
127
128
|
value: r,
|
|
128
129
|
onChange: (e) => N(e.target.value),
|
|
129
|
-
disabled:
|
|
130
|
+
disabled: c.disabled
|
|
130
131
|
}
|
|
131
132
|
)
|
|
132
133
|
] }),
|
|
133
|
-
/* @__PURE__ */
|
|
134
|
-
/* @__PURE__ */
|
|
135
|
-
/* @__PURE__ */
|
|
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:
|
|
139
|
+
className: t.textarea,
|
|
139
140
|
placeholder: '{"example": "value"}',
|
|
140
|
-
value:
|
|
141
|
+
value: g,
|
|
141
142
|
onChange: (e) => S(e.target.value),
|
|
142
|
-
disabled:
|
|
143
|
+
disabled: c.disabled,
|
|
143
144
|
rows: 3
|
|
144
145
|
}
|
|
145
146
|
)
|
|
146
147
|
] })
|
|
147
148
|
] }),
|
|
148
|
-
/* @__PURE__ */
|
|
149
|
-
/* @__PURE__ */
|
|
150
|
-
/* @__PURE__ */
|
|
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__ */
|
|
154
|
-
/* @__PURE__ */
|
|
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: `${
|
|
158
|
+
className: `${t.cardHeader} ${t.clickable}`,
|
|
158
159
|
onClick: () => h(e.key, "collapsed"),
|
|
159
160
|
role: "button",
|
|
160
161
|
tabIndex: 0,
|
|
161
|
-
onKeyDown: (
|
|
162
|
+
onKeyDown: (s) => V(s, e.key),
|
|
162
163
|
children: [
|
|
163
|
-
/* @__PURE__ */
|
|
164
|
-
/* @__PURE__ */
|
|
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__ */
|
|
169
|
-
/* @__PURE__ */
|
|
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:
|
|
173
|
-
value:
|
|
174
|
-
onChange: (
|
|
175
|
-
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__ */
|
|
180
|
-
/* @__PURE__ */
|
|
181
|
-
/* @__PURE__ */
|
|
182
|
-
e.value.length > 100 && /* @__PURE__ */
|
|
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:
|
|
186
|
+
className: t.btnToggle,
|
|
186
187
|
onClick: () => h(e.key, "valueExpanded"),
|
|
187
|
-
disabled:
|
|
188
|
+
disabled: c.disabled,
|
|
188
189
|
children: u.get(e.key)?.valueExpanded ? "▲ Show less" : "▼ Show more"
|
|
189
190
|
}
|
|
190
191
|
),
|
|
191
|
-
/* @__PURE__ */
|
|
192
|
+
/* @__PURE__ */ a(
|
|
192
193
|
"button",
|
|
193
194
|
{
|
|
194
|
-
className:
|
|
195
|
-
onClick: () =>
|
|
196
|
-
disabled:
|
|
195
|
+
className: t.btnToggle,
|
|
196
|
+
onClick: () => K(e.key, e.value),
|
|
197
|
+
disabled: c.disabled,
|
|
197
198
|
title: "Copy content",
|
|
198
|
-
children:
|
|
199
|
+
children: E === e.key ? "✓ Copied" : "📎 Copy"
|
|
199
200
|
}
|
|
200
201
|
)
|
|
201
202
|
] })
|
|
202
203
|
] }) }),
|
|
203
|
-
/* @__PURE__ */
|
|
204
|
-
/* @__PURE__ */
|
|
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:
|
|
208
|
-
onClick: () =>
|
|
209
|
-
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__ */
|
|
215
|
+
/* @__PURE__ */ a(
|
|
215
216
|
"button",
|
|
216
217
|
{
|
|
217
|
-
className:
|
|
218
|
-
onClick:
|
|
219
|
-
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__ */
|
|
225
|
-
/* @__PURE__ */
|
|
225
|
+
] }) : /* @__PURE__ */ n(m, { children: [
|
|
226
|
+
/* @__PURE__ */ a(
|
|
226
227
|
"button",
|
|
227
228
|
{
|
|
228
|
-
className:
|
|
229
|
-
onClick: () =>
|
|
230
|
-
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__ */
|
|
236
|
+
/* @__PURE__ */ a(
|
|
236
237
|
"button",
|
|
237
238
|
{
|
|
238
|
-
className:
|
|
239
|
-
onClick: () =>
|
|
240
|
-
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
|
-
|
|
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
|