@berenjena/react-dev-panel 1.0.3 → 1.0.4

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 CHANGED
@@ -1,9 +1,9 @@
1
1
  # React Dev Panel
2
2
 
3
- [![npm version](https://badge.fury.io/js/@berenjena%2Freact-dev-panel.svg)](https://badge.fury.io/js/@berenjena%2Freact-dev-panel)
4
- [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
5
- [![Weekly Downloads](https://img.shields.io/npm/dw/@berenjena/react-dev-panel)](https://www.npmjs.com/package/@berenjena/react-dev-panel)
6
- ![npm package minimized gzipped size](https://img.shields.io/bundlejs/size/%40berenjena%2Freact-dev-panel?label=gzipped)
3
+ ![NPM Version](https://badgen.net/npm/v/@berenjena/react-dev-panel)
4
+ ![npm package minimized gzipped size](<https://img.shields.io/bundlejs/size/%40berenjena%2Freact-dev-panel?label=Bundle%20size%20(gzip)>)
5
+ [![License: MIT](https://badgen.net/npm/license/@berenjena/react-dev-panel)](https://opensource.org/licenses/MIT)
6
+ [![Weekly Downloads](https://badgen.net/npm/dw/@berenjena/react-dev-panel)](https://www.npmjs.com/package/@berenjena/react-dev-panel)
7
7
 
8
8
  A powerful, type-safe React development panel that provides an intuitive interface for controlling component props, debugging state, and rapid prototyping during development.
9
9
 
@@ -11,27 +11,10 @@ A powerful, type-safe React development panel that provides an intuitive interfa
11
11
 
12
12
  - 🎛️ **Rich Control Types** - Boolean, Number, Text, Select, Color, Range, Date, Button, and Separator controls
13
13
  - 🎨 **Themeable** - Consistent design system with CSS custom properties
14
- - 📱 **Responsive** - Adapts to different screen sizes and can be positioned anywhere
15
14
  - ⌨️ **Keyboard Shortcuts** - Quick access with customizable hotkeys
16
- - 🔄 **State Management** - Built-in state persistence
17
15
  - 📖 **TypeScript First** - Full type safety and IntelliSense support
18
16
  - 🚀 **Zero Dependencies** - Only requires React (peer dependency)
19
-
20
- ## 📊 Package Stats
21
-
22
- - **Bundle Size**: ~35KB (minified)
23
- - **Total Files**: 142
24
- - **License**: MIT
25
-
26
- ## 🆕 What's New
27
-
28
- ### Recent Updates (v1.0.1+)
29
-
30
- - **🔄 Zero External Dependencies**: Replaced Zustand with React's built-in `useSyncExternalStore` for state management
31
- - **📊 Logger Component**: New floating, collapsible logger component for debugging object data in JSON format
32
- - **⚡ Performance Optimizations**: Selective subscriptions for better re-render performance
33
- - **🔧 Development Mode Improvements**: Removed development mode checks - panel now works in all environments
34
- - **📝 Enhanced Documentation**: Comprehensive code documentation and better TypeScript support
17
+ - 📦 **Bundle Size**: ![npm package minimized gzipped size](<https://img.shields.io/bundlejs/size/%40berenjena%2Freact-dev-panel?label=Bundle%20size%20(gzip)>)
35
18
 
36
19
  ## 📦 Installation
37
20
 
@@ -106,6 +89,8 @@ function App() {
106
89
 
107
90
  ## 🎛️ Control Types
108
91
 
92
+ React Dev Panel provides rich control types for different data types. Here are some quick examples:
93
+
109
94
  ### Text Control
110
95
 
111
96
  ```tsx
@@ -114,7 +99,6 @@ function App() {
114
99
  value: 'Hello World',
115
100
  label: 'Message',
116
101
  placeholder: 'Enter message...',
117
- event: 'onBlur', // or 'onChange'
118
102
  onChange: (value: string) => setValue(value),
119
103
  }
120
104
  ```
@@ -128,7 +112,6 @@ function App() {
128
112
  label: 'Count',
129
113
  min: 0,
130
114
  max: 100,
131
- step: 1,
132
115
  onChange: (value: number) => setValue(value),
133
116
  }
134
117
  ```
@@ -144,61 +127,6 @@ function App() {
144
127
  }
145
128
  ```
146
129
 
147
- ### Select Control
148
-
149
- ```tsx
150
- {
151
- type: 'select',
152
- value: 'option1',
153
- label: 'Choose Option',
154
- options: ['option1', 'option2', 'option3'],
155
- // or with labels:
156
- options: [
157
- { label: 'Option 1', value: 'opt1' },
158
- { label: 'Option 2', value: 'opt2' },
159
- ],
160
- onChange: (value: string) => setValue(value),
161
- }
162
- ```
163
-
164
- ### Color Control
165
-
166
- ```tsx
167
- {
168
- type: 'color',
169
- value: '#ff6200',
170
- label: 'Brand Color',
171
- onChange: (value: string) => setValue(value),
172
- }
173
- ```
174
-
175
- ### Range Control
176
-
177
- ```tsx
178
- {
179
- type: 'range',
180
- value: 50,
181
- label: 'Volume',
182
- min: 0,
183
- max: 100,
184
- step: 1,
185
- onChange: (value: number) => setValue(value),
186
- }
187
- ```
188
-
189
- ### Date Control
190
-
191
- ```tsx
192
- {
193
- type: 'date',
194
- value: '2025-07-26',
195
- label: 'Start Date',
196
- min: '2025-01-01',
197
- max: '2025-12-31',
198
- onChange: (value: string) => setValue(value),
199
- }
200
- ```
201
-
202
130
  ### Button Control
203
131
 
204
132
  ```tsx
@@ -209,63 +137,22 @@ function App() {
209
137
  }
210
138
  ```
211
139
 
212
- ### Button Group Control
213
-
214
- ```tsx
215
- {
216
- type: 'buttonGroup',
217
- label: 'Actions',
218
- buttons: [
219
- { label: 'Save', onClick: handleSave },
220
- { label: 'Load', onClick: handleLoad },
221
- { label: 'Reset', onClick: handleReset, disabled: true },
222
- ],
223
- }
224
- ```
225
-
226
- ### Separator Control
227
-
228
- ```tsx
229
- // Line separator
230
- { type: 'separator' }
231
-
232
- // Space separator
233
- { type: 'separator', style: 'space' }
234
-
235
- // Label separator
236
- { type: 'separator', style: 'label', label: 'Advanced Settings' }
237
- ```
140
+ **📖 [View all control types and detailed documentation →](./guides/CONTROLS.md)**
238
141
 
239
142
  ## 🎨 Styling and Theming
240
143
 
241
- The dev panel uses CSS custom properties for easy theming:
144
+ The dev panel uses CSS custom properties for easy theming. Here's a quick example:
242
145
 
243
146
  ```css
244
147
  :root {
245
148
  --dev-panel-background-color: #1a1a1a;
246
149
  --dev-panel-text-color: #ffffff;
247
- --dev-panel-text-color-highlight: #ffffff;
248
- --dev-panel-text-color-muted: #888888;
249
150
  --dev-panel-accent-color: #ff6200;
250
151
  --dev-panel-border-color: #333333;
251
- --dev-panel-input-background-color: #2a2a2a;
252
- --dev-panel-highlight-color: #ff620020;
253
- --dev-panel-font-size-xs: 11px;
254
- --dev-panel-font-size-sm: 12px;
255
- --dev-panel-spacing-xs: 4px;
256
- --dev-panel-spacing-sm: 8px;
257
- --dev-panel-spacing-md: 16px;
258
- --dev-panel-border-radius: 4px;
259
- --dev-panel-inputs-height: 24px;
260
- --dev-panel-transition: all 0.2s ease;
261
152
  }
262
153
  ```
263
154
 
264
- ### Custom Panel Positioning
265
-
266
- ```tsx
267
- <DevPanel panelTitle="Custom Panel" position={{ x: 100, y: 100 }} defaultExpanded={true} />
268
- ```
155
+ **📖 [Complete theming guide and customization options →](./guides/STYLING.md)**
269
156
 
270
157
  ## ⌨️ Keyboard Shortcuts
271
158
 
@@ -312,32 +199,16 @@ function App() {
312
199
  }
313
200
  ```
314
201
 
315
- ### Conditional Controls
316
-
317
- ```tsx
318
- useDevPanel("Settings", {
319
- mode: {
320
- type: "select",
321
- value: mode,
322
- options: ["simple", "advanced"],
323
- onChange: setMode,
324
- },
325
- // Only show advanced settings when mode is 'advanced'
326
- ...(mode === "advanced" && {
327
- separator1: { type: "separator", style: "label", label: "Advanced" },
328
- complexValue: {
329
- type: "range",
330
- value: complexValue,
331
- min: 0,
332
- max: 1000,
333
- onChange: setComplexValue,
334
- },
335
- }),
336
- });
337
- ```
202
+ **📖 [Advanced patterns, state management, and optimization →](./guides/ADVANCED_USAGE.md)**
338
203
 
339
204
  ### Event Handling Options
340
205
 
206
+ React Dev Panel supports two different event handling strategies for input controls:
207
+
208
+ **onChange Event**: Provides real-time updates as the user types or interacts with the control. This is ideal for immediate feedback and live previews, but may trigger more frequent re-renders.
209
+
210
+ **onBlur Event**: Updates the value only when the user finishes interacting with the control (loses focus). This approach is more performance-friendly for expensive operations and provides a better user experience when dealing with API calls or heavy computations.
211
+
341
212
  ```tsx
342
213
  {
343
214
  type: 'text',
@@ -354,6 +225,19 @@ useDevPanel("Settings", {
354
225
  }
355
226
  ```
356
227
 
228
+ ## 📚 Documentation
229
+
230
+ ### Core Guides
231
+
232
+ - **[Control Types](./guides/CONTROLS.md)** - Complete guide to all available controls
233
+ - **[Event Handling](./guides/EVENT_HANDLING.md)** - onChange vs onBlur strategies and best practices
234
+ - **[Styling & Theming](./guides/STYLING.md)** - Customization, themes, and responsive design
235
+ - **[Advanced Usage](./guides/ADVANCED_USAGE.md)** - Complex patterns, state management, and optimization
236
+
237
+ ### Development
238
+
239
+ - **[Development Guide](./guides/DEVELOPMENT.md)** - Setup, contributing, and project structure
240
+
357
241
  ## 📚 API Reference
358
242
 
359
243
  ### `useDevPanel(groupName: string, controls: ControlsGroup)`
@@ -385,28 +269,9 @@ Registers keyboard shortcuts.
385
269
 
386
270
  ## 🛠️ Development
387
271
 
388
- ### Prerequisites
389
-
390
- - Node.js 18+
391
- - React 18+
272
+ Want to contribute or set up the project locally?
392
273
 
393
- ### Setup
394
-
395
- ```bash
396
- git clone https://github.com/Berenjenas/react-dev-panel.git
397
- cd react-dev-panel
398
- npm install
399
- ```
400
-
401
- ### Available Scripts
402
-
403
- ```bash
404
- npm run dev # Start development server
405
- npm run build # Build for production
406
- npm run storybook # Start Storybook
407
- npm run test # Run tests
408
- npm run lint # Lint code
409
- ```
274
+ **📖 [Development setup, contributing guidelines, and project structure →](./guides/DEVELOPMENT.md)**
410
275
 
411
276
  ## 📖 Storybook
412
277
 
@@ -428,10 +293,6 @@ We welcome contributions! Please see our [Contributing Guide](CONTRIBUTING.md) f
428
293
  4. Push to the branch (`git push origin feature/amazing-feature`)
429
294
  5. Open a Pull Request
430
295
 
431
- ## 📄 License
432
-
433
- This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
434
-
435
296
  ## 🔗 Links
436
297
 
437
298
  - [NPM Package](https://www.npmjs.com/package/@berenjena/react-dev-panel)
@@ -0,0 +1,227 @@
1
+ import { useSyncExternalStore as n } from "react";
2
+ import { BaseStoreService as c } from "./store/BaseStoreService.js";
3
+ const S = "dev-panel-sections-storage";
4
+ class p extends c {
5
+ /**
6
+ * Creates a new DevPanelSectionsService instance.
7
+ */
8
+ constructor() {
9
+ super(S, {}, !1, !1);
10
+ }
11
+ /**
12
+ * Transforms current sections state to persistable format.
13
+ * Since this store doesn't persist, this method returns a dummy value.
14
+ *
15
+ * @param _state - The current sections state (unused)
16
+ * @returns Empty persistable state
17
+ * @protected
18
+ */
19
+ toPersistableState(e) {
20
+ return { sectionCollapseState: {} };
21
+ }
22
+ /**
23
+ * Transforms persisted state back to current state format.
24
+ * Since this store doesn't persist, this method returns the default state.
25
+ *
26
+ * @param _persistedState - The persisted sections state (unused)
27
+ * @param defaultState - The default state to fall back to
28
+ * @returns The default state
29
+ * @protected
30
+ */
31
+ fromPersistedState(e, t) {
32
+ return t;
33
+ }
34
+ /**
35
+ * Gets the service name for error messages.
36
+ *
37
+ * @returns The service name
38
+ * @protected
39
+ */
40
+ getServiceName() {
41
+ return "sections";
42
+ }
43
+ /**
44
+ * Registers a new section with the dev panel.
45
+ * If a section with the same name already exists, it preserves the existing collapse state.
46
+ * New sections start in expanded state (isCollapsed: false).
47
+ *
48
+ * @param name - Unique name for the section
49
+ * @param controls - Array of control configurations for the section
50
+ */
51
+ registerSection = (e, t) => {
52
+ this.setState((i) => {
53
+ const u = i[e]?.isCollapsed ?? !1;
54
+ return {
55
+ ...i,
56
+ [e]: {
57
+ name: e,
58
+ controls: t,
59
+ isCollapsed: u
60
+ }
61
+ };
62
+ });
63
+ };
64
+ /**
65
+ * Removes a section from the dev panel.
66
+ *
67
+ * @param name - Name of the section to remove
68
+ */
69
+ unregisterSection = (e) => {
70
+ this.setState((t) => {
71
+ const { [e]: i, ...a } = t;
72
+ return a;
73
+ });
74
+ };
75
+ /**
76
+ * Toggles the collapsed state of a specific section.
77
+ *
78
+ * @param name - Name of the section to toggle
79
+ */
80
+ toggleSectionCollapse = (e) => {
81
+ this.setState((t) => {
82
+ const i = t[e];
83
+ return i ? {
84
+ ...t,
85
+ [e]: {
86
+ ...i,
87
+ isCollapsed: !i.isCollapsed
88
+ }
89
+ } : t;
90
+ });
91
+ };
92
+ /**
93
+ * Clears all sections.
94
+ */
95
+ reset = () => {
96
+ this.setState(() => ({}));
97
+ };
98
+ }
99
+ const o = new p();
100
+ function C() {
101
+ return n(o.subscribe, o.getSnapshot);
102
+ }
103
+ function h() {
104
+ return {
105
+ registerSection: o.registerSection,
106
+ unregisterSection: o.unregisterSection,
107
+ toggleSectionCollapse: o.toggleSectionCollapse,
108
+ reset: o.reset
109
+ };
110
+ }
111
+ const g = "dev-panel-ui-storage", d = { x: 20, y: 20 }, l = {
112
+ isVisible: !1,
113
+ isCollapsed: !1,
114
+ position: d
115
+ };
116
+ class b extends c {
117
+ /**
118
+ * Creates a new DevPanelUIService instance and loads persisted state from localStorage.
119
+ */
120
+ constructor() {
121
+ super(g, l, !0, !0);
122
+ }
123
+ /**
124
+ * Transforms current state to persistable format.
125
+ *
126
+ * @param state - The current UI state
127
+ * @returns The state in persistable format
128
+ * @protected
129
+ */
130
+ toPersistableState(e) {
131
+ return {
132
+ ...e
133
+ };
134
+ }
135
+ /**
136
+ * Transforms persisted state back to current state format.
137
+ *
138
+ * @param persistedState - The persisted UI state
139
+ * @param defaultState - The default state to fall back to
140
+ * @returns The state in current format
141
+ * @protected
142
+ */
143
+ fromPersistedState(e, t) {
144
+ return {
145
+ ...t,
146
+ ...e
147
+ };
148
+ }
149
+ /**
150
+ * Gets the service name for error messages.
151
+ *
152
+ * @returns The service name
153
+ * @protected
154
+ */
155
+ getServiceName() {
156
+ return "UI";
157
+ }
158
+ /**
159
+ * Sets the visibility state of the dev panel.
160
+ *
161
+ * @param visible - Whether the panel should be visible
162
+ */
163
+ setVisible = (e) => {
164
+ this.setState((t) => ({ ...t, isVisible: e }));
165
+ };
166
+ /**
167
+ * Sets the collapsed state of the dev panel.
168
+ *
169
+ * @param collapsed - Whether the panel should be collapsed
170
+ */
171
+ setCollapsed = (e) => {
172
+ this.setState((t) => ({ ...t, isCollapsed: e }));
173
+ };
174
+ /**
175
+ * Updates the position of the dev panel.
176
+ *
177
+ * @param position - New position coordinates {x, y}
178
+ */
179
+ setPosition = (e) => {
180
+ this.setState((t) => ({ ...t, position: e }));
181
+ };
182
+ /**
183
+ * Resets the dev panel UI to its default state.
184
+ * Resets position and sets visibility and collapse to false.
185
+ */
186
+ reset = () => {
187
+ this.setState(() => ({ ...l }));
188
+ };
189
+ }
190
+ const s = new b();
191
+ function P() {
192
+ return {
193
+ ...n(s.subscribe, s.getSnapshot),
194
+ setVisible: s.setVisible,
195
+ setCollapsed: s.setCollapsed,
196
+ setPosition: s.setPosition,
197
+ reset: s.reset
198
+ };
199
+ }
200
+ function D() {
201
+ return n(s.subscribe, () => s.getSnapshot().isVisible);
202
+ }
203
+ function V() {
204
+ return n(s.subscribe, () => s.getSnapshot().isCollapsed);
205
+ }
206
+ function x() {
207
+ return n(s.subscribe, () => s.getSnapshot().position);
208
+ }
209
+ function m() {
210
+ return {
211
+ setVisible: s.setVisible,
212
+ setCollapsed: s.setCollapsed,
213
+ setPosition: s.setPosition,
214
+ reset: s.reset
215
+ };
216
+ }
217
+ const I = P;
218
+ export {
219
+ h as a,
220
+ P as b,
221
+ D as c,
222
+ V as d,
223
+ x as e,
224
+ m as f,
225
+ I as g,
226
+ C as u
227
+ };
@@ -1,13 +1,17 @@
1
- import { jsxs as t, jsx as n } from "react/jsx-runtime";
2
- import { Input as l } from "../../../Input/Input.js";
3
- import '../../../../assets/ColorControl.css';const o = "_container_ds1no_1", r = {
4
- container: o
1
+ import { jsxs as r, jsx as n } from "react/jsx-runtime";
2
+ import { Input as o } from "../../../Input/Input.js";
3
+ import { useDebouncedCallback as d } from "../../../../hooks/useDebounceCallback/useDebounceCallback.js";
4
+ import '../../../../assets/ColorControl.css';const s = "_container_ds1no_1", i = {
5
+ container: s
5
6
  };
6
- function d({ control: e }) {
7
- return /* @__PURE__ */ t("div", { className: r.container, children: [
8
- /* @__PURE__ */ n("label", { children: /* @__PURE__ */ n(l, { type: "color", value: e.value, disabled: e.disabled, onChange: (a) => e.onChange(a.target.value) }) }),
7
+ function C({ control: e }) {
8
+ const l = d(e.onChange, 100), t = (a) => {
9
+ l(a.target.value);
10
+ };
11
+ return /* @__PURE__ */ r("div", { className: i.container, children: [
12
+ /* @__PURE__ */ n("label", { children: /* @__PURE__ */ n(o, { type: "color", value: e.value, disabled: e.disabled, onChange: t }) }),
9
13
  /* @__PURE__ */ n(
10
- l,
14
+ o,
11
15
  {
12
16
  type: "text",
13
17
  value: e.value,
@@ -19,5 +23,5 @@ function d({ control: e }) {
19
23
  ] });
20
24
  }
21
25
  export {
22
- d as ColorControl
26
+ C as ColorControl
23
27
  };
@@ -1,67 +1,67 @@
1
- import { jsxs as r, jsx as e } from "react/jsx-runtime";
2
- import { useCallback as g } from "react";
3
- import { useDragAndDrop as _ } from "../../hooks/useDragAndDrop/useDragAndDrop.js";
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 = {
1
+ import { jsxs as c, jsx as e } from "react/jsx-runtime";
2
+ import { useCallback as C } from "react";
3
+ import { useDragAndDrop as w } from "../../hooks/useDragAndDrop/useDragAndDrop.js";
4
+ import { useHotkey as b } from "../../hooks/useHotkeys/useHotkey.js";
5
+ import { b as y, u as D } from "../../UIStore-CQdr4U-2.js";
6
+ import { className as P } from "../../utils/className/className.js";
7
+ import { EmptyContent as x } from "../EmptyContent/EmptyContent.js";
8
+ import { Section as K } from "../Section/Section.js";
9
+ import '../../assets/DevPanel.css';const N = "_devPanelContainer_1vath_1", k = "_header_1vath_12", A = "_title_1vath_21", j = "_button_1vath_31", E = "_collapsed_1vath_53", H = "_content_1vath_60", t = {
10
+ devPanelContainer: N,
11
+ header: k,
12
+ title: A,
13
+ button: j,
14
+ collapsed: E,
15
+ content: H
16
+ }, M = {
17
17
  ctrlKey: !0,
18
18
  shiftKey: !0,
19
19
  key: "a",
20
20
  altKey: !1,
21
21
  metaKey: !1
22
22
  };
23
- function O({ panelTitle: c = "Dev panel", ...d }) {
24
- const { isVisible: l, isCollapsed: o, position: a, sections: h, ...n } = w(), m = g(
25
- (s) => {
26
- n.setPosition(s);
23
+ function U({ panelTitle: d = "Dev panel", ...h }) {
24
+ const { isVisible: s, isCollapsed: n, position: l, setVisible: a, setCollapsed: m, setPosition: i } = y(), p = D(), v = C(
25
+ (o) => {
26
+ i(o);
27
27
  },
28
- [n]
29
- ), { isDragging: p, elementRef: v, handleMouseDown: u } = _({
30
- onPositionChange: m
28
+ [i]
29
+ ), { isDragging: u, elementRef: f, handleMouseDown: g } = w({
30
+ onPositionChange: v
31
31
  });
32
- if (C({
32
+ if (b({
33
33
  description: "Show Dev Panel",
34
34
  preventDefault: !0,
35
- action: () => n.setVisible(!l),
36
- ...j,
37
- ...d.hotKeyConfig,
35
+ action: () => a(!s),
36
+ ...M,
37
+ ...h.hotKeyConfig,
38
38
  target: window
39
- }), !l)
39
+ }), !s)
40
40
  return null;
41
- const i = Object.entries(h);
42
- return /* @__PURE__ */ r(
41
+ const r = Object.entries(p);
42
+ return /* @__PURE__ */ c(
43
43
  "div",
44
44
  {
45
- ref: v,
46
- ...b(t.devPanelContainer, {
47
- [t.dragging]: p
45
+ ref: f,
46
+ ...P(t.devPanelContainer, {
47
+ [t.dragging]: u
48
48
  }),
49
49
  style: {
50
- left: a.x,
51
- top: a.y,
52
- height: o ? "auto" : void 0
50
+ left: l.x,
51
+ top: l.y,
52
+ height: n ? "auto" : void 0
53
53
  },
54
54
  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" }) }) })
55
+ /* @__PURE__ */ c("div", { className: t.header, onMouseDown: g, children: [
56
+ /* @__PURE__ */ e("button", { className: t.button, onClick: () => m(!n), title: n ? "Expand" : "Collapse", children: /* @__PURE__ */ e("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", className: n ? 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: d }),
58
+ /* @__PURE__ */ e("button", { className: t.button, onClick: () => a(!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" }) }) })
59
59
  ] }),
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
+ !n && /* @__PURE__ */ e("div", { className: t.content, children: r.length ? r.map(([o, _]) => /* @__PURE__ */ e(K, { sectionName: o, section: _ }, `section-${o}`)) : /* @__PURE__ */ e(x, {}) })
61
61
  ]
62
62
  }
63
63
  );
64
64
  }
65
65
  export {
66
- O as DevPanel
66
+ U as DevPanel
67
67
  };
@@ -32,6 +32,8 @@ export interface DevPanelState {
32
32
  position: Position;
33
33
  }
34
34
 
35
+ export type DevPanelUIState = Omit<DevPanelState, "sections">;
36
+
35
37
  export interface DevPanelActions {
36
38
  setVisible: (visible: boolean) => void;
37
39
  setCollapsed: (collapsed: boolean) => void;