@berenjena/react-dev-panel 2.2.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.
package/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # React Dev Panel
1
+ # React Dev P- **Zero Configuration** - Auto-mounting and unmounting, no providers or setup requirednel
2
2
 
3
3
  ![NPM Version](https://badgen.net/npm/v/@berenjena/react-dev-panel)
4
4
  ![npm package minimized gzipped size](<https://img.shields.io/bundlejs/size/%40berenjena%2Freact-dev-panel?label=Bundle%20size%20(gzip)>)
@@ -10,11 +10,12 @@ A powerful, type-safe development panel for React that allows developers to insp
10
10
  ## ✨ Features
11
11
 
12
12
  - 🎛️ **Rich Control Types** - Boolean, Number, Text, Select, Color, Range, Date, Button, ButtonGroup, and Separator controls
13
- - 🚀 **Zero Configuration** - Auto-mounting and unmounting, no providers or setup required
13
+ - **Automatic Persistence** - Control values automatically saved to localStorage and restored on reload
14
+ - �🚀 **Zero Configuration** - Auto-mounting and unmounting, no providers or setup required
14
15
  - 🎨 **Themeable** - Built-in themes and CSS custom properties for customization
15
16
  - ⌨️ **Keyboard Shortcuts** - Customizable hotkeys for panel toggle
16
17
  - 📖 **TypeScript First** - Full type safety and IntelliSense support
17
- - **Auto State Management** - Automatic portal rendering and lifecycle management
18
+ - **Auto State Management** - Automatic portal rendering and lifecycle management
18
19
  - 📦 **Lightweight** - Only requires React as peer dependency
19
20
 
20
21
  ## 📦 Installation
@@ -31,7 +32,7 @@ yarn add -D @berenjena/react-dev-panel
31
32
  pnpm add -D @berenjena/react-dev-panel
32
33
  ```
33
34
 
34
- ## 🚀 Quick Start
35
+ ## Quick Start
35
36
 
36
37
  The package exposes a single hook: `useDevPanel`. This hook handles everything automatically:
37
38
 
@@ -57,6 +58,7 @@ function App() {
57
58
  type: "text",
58
59
  value: name,
59
60
  label: "Full Name",
61
+ persist: true, // Automatically save and restore value
60
62
  onChange: setName,
61
63
  },
62
64
  age: {
@@ -65,12 +67,14 @@ function App() {
65
67
  label: "Age",
66
68
  min: 0,
67
69
  max: 120,
70
+ persist: true, // Value persists across page reloads
68
71
  onChange: setAge,
69
72
  },
70
73
  isActive: {
71
74
  type: "boolean",
72
75
  value: isActive,
73
76
  label: "Active User",
77
+ persist: true,
74
78
  onChange: setIsActive,
75
79
  },
76
80
  theme: {
@@ -78,6 +82,7 @@ function App() {
78
82
  value: theme,
79
83
  label: "Theme",
80
84
  options: ["light", "dark", "auto"],
85
+ persist: true,
81
86
  onChange: setTheme,
82
87
  },
83
88
  });
@@ -107,6 +112,7 @@ React Dev Panel provides rich control types for different data types. Here are s
107
112
  value: 'Hello World',
108
113
  label: 'Message',
109
114
  placeholder: 'Enter message...',
115
+ persist: true, // Value automatically saved to localStorage
110
116
  onChange: (value: string) => setValue(value),
111
117
  }
112
118
  ```
@@ -120,6 +126,7 @@ React Dev Panel provides rich control types for different data types. Here are s
120
126
  label: 'Count',
121
127
  min: 0,
122
128
  max: 100,
129
+ persist: true, // Persists across page reloads
123
130
  onChange: (value: number) => setValue(value),
124
131
  }
125
132
  ```
@@ -131,10 +138,23 @@ React Dev Panel provides rich control types for different data types. Here are s
131
138
  type: 'boolean',
132
139
  value: true,
133
140
  label: 'Enable Feature',
141
+ persist: true, // Checkbox state is remembered
134
142
  onChange: (value: boolean) => setValue(value),
135
143
  }
136
144
  ```
137
145
 
146
+ ### Color Control
147
+
148
+ ```tsx
149
+ {
150
+ type: 'color',
151
+ value: '#ff6200',
152
+ label: 'Theme Color',
153
+ persist: true, // Color choice is automatically saved
154
+ onChange: (value: string) => setValue(value),
155
+ }
156
+ ```
157
+
138
158
  ### Button Control
139
159
 
140
160
  ```tsx
@@ -178,7 +198,7 @@ useDevPanel("My Section", controls, {
178
198
  });
179
199
  ```
180
200
 
181
- ## 🔧 Advanced Usage
201
+ ## Advanced Usage
182
202
 
183
203
  ### Multiple Panel Sections
184
204
 
@@ -251,6 +271,7 @@ React Dev Panel supports two different event handling strategies for input contr
251
271
  ### Core Guides
252
272
 
253
273
  - **[Control Types](./guides/CONTROLS.md)** - Complete guide to all available controls
274
+ - **[Data Persistence](./guides/PERSISTENCE.md)** - Automatic value persistence and state management
254
275
  - **[Event Handling](./guides/EVENT_HANDLING.md)** - onChange vs onBlur strategies and best practices
255
276
  - **[Styling & Theming](./guides/STYLING.md)** - Customization, themes, and responsive design
256
277
  - **[Advanced Usage](./guides/ADVANCED_USAGE.md)** - Complex patterns, state management, and optimization
@@ -1 +1 @@
1
- ._controlRendererContainer_1s60v_1{display:grid}._controlRendererContainer_1s60v_1 ._controlContainer_1s60v_4{gap:var(--dev-panel-spacing-md);display:grid;align-items:center;color:var(--dev-panel-text-color);padding:var(--dev-panel-spacing-xs);border-radius:var(--dev-panel-border-radius);transition:var(--dev-panel-transition)}._controlRendererContainer_1s60v_1 ._controlContainer_1s60v_4._hoverable_1s60v_13:hover{background:var(--dev-panel-surface-color-hover)}._controlRendererContainer_1s60v_1 ._controlContainer_1s60v_4:not(._fullWidth_1s60v_16){grid-template-columns:120px 1fr}._controlRendererContainer_1s60v_1 ._controlContainer_1s60v_4._fullWidth_1s60v_16 ._label_1s60v_19{margin-bottom:var(--dev-panel-spacing-sm)}._controlRendererContainer_1s60v_1 ._controlContainer_1s60v_4 ._controlWrapper_1s60v_22{display:flex;align-items:center}._controlRendererContainer_1s60v_1 ._controlContainer_1s60v_4 ._controlWrapper_1s60v_22._justifyStart_1s60v_26{justify-content:flex-start}._controlRendererContainer_1s60v_1 ._controlContainer_1s60v_4 ._controlWrapper_1s60v_22:not(._justifyStart_1s60v_26){justify-content:flex-end}._controlRendererContainer_1s60v_1 ._controlContainer_1s60v_4 ._label_1s60v_19{text-align:start;font-weight:var(--dev-panel-font-weight-medium);font-size:var(--dev-panel-font-size-sm);color:var(--dev-panel-text-color);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;line-height:var(--dev-panel-line-height-tight)}._controlRendererContainer_1s60v_1 ._description_1s60v_42{font-size:var(--dev-panel-font-size-xs);color:var(--dev-panel-text-color-muted);line-height:var(--dev-panel-line-height-normal);padding-inline:var(--dev-panel-spacing-xs);margin-top:var(--dev-panel-spacing-sm);font-style:italic;text-align:right}._controlRendererContainer_1s60v_1 ._loading_1s60v_51{font-size:var(--dev-panel-font-size-xs);color:var(--dev-panel-text-color-muted);text-align:center;padding:var(--dev-panel-spacing-lg);display:flex;align-items:center;justify-content:center;gap:var(--dev-panel-spacing-sm)}._controlRendererContainer_1s60v_1 ._loading_1s60v_51:before{content:"";width:12px;height:12px;border:2px solid var(--dev-panel-border-color);border-top:2px solid var(--dev-panel-accent-color);border-radius:var(--dev-panel-border-radius-full);animation:_spin_1s60v_1 1s linear infinite}._controlRendererContainer_1s60v_1 ._error_1s60v_70{font-size:var(--dev-panel-font-size-xs);color:var(--dev-panel-error-color);text-align:center;padding:var(--dev-panel-spacing-lg);background:color-mix(in srgb,var(--dev-panel-error-color) 10%,transparent);border:1px solid color-mix(in srgb,var(--dev-panel-error-color) 30%,transparent);border-radius:var(--dev-panel-border-radius);margin:var(--dev-panel-spacing-sm) 0}@keyframes _spin_1s60v_1{0%{transform:rotate(0)}to{transform:rotate(360deg)}}
1
+ ._controlRendererContainer_jru2l_1{display:grid;word-break:break-word}._controlRendererContainer_jru2l_1 ._controlContainer_jru2l_5{gap:var(--dev-panel-spacing-md);display:grid;align-items:center;color:var(--dev-panel-text-color);padding:var(--dev-panel-spacing-xs);border-radius:var(--dev-panel-border-radius);transition:var(--dev-panel-transition);min-width:1px}._controlRendererContainer_jru2l_1 ._controlContainer_jru2l_5._hoverable_jru2l_15:hover{background:var(--dev-panel-surface-color-hover)}._controlRendererContainer_jru2l_1 ._controlContainer_jru2l_5:not(._fullWidth_jru2l_18){grid-template-columns:120px calc(100% - 120px - var(--dev-panel-spacing-md))}._controlRendererContainer_jru2l_1 ._controlContainer_jru2l_5._fullWidth_jru2l_18 ._label_jru2l_21{margin-bottom:var(--dev-panel-spacing-sm)}._controlRendererContainer_jru2l_1 ._controlContainer_jru2l_5 ._controlWrapper_jru2l_24{display:flex;align-items:center;word-break:break-word;overflow-wrap:break-word}._controlRendererContainer_jru2l_1 ._controlContainer_jru2l_5 ._controlWrapper_jru2l_24._justifyStart_jru2l_30{justify-content:flex-start}._controlRendererContainer_jru2l_1 ._controlContainer_jru2l_5 ._controlWrapper_jru2l_24:not(._justifyStart_jru2l_30){justify-content:flex-end}._controlRendererContainer_jru2l_1 ._controlContainer_jru2l_5 ._label_jru2l_21{text-align:start;font-weight:var(--dev-panel-font-weight-medium);font-size:var(--dev-panel-font-size-sm);color:var(--dev-panel-text-color);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;line-height:var(--dev-panel-line-height-tight)}._controlRendererContainer_jru2l_1 ._description_jru2l_46{font-size:var(--dev-panel-font-size-xs);color:var(--dev-panel-text-color-muted);line-height:var(--dev-panel-line-height-normal);padding-inline:var(--dev-panel-spacing-xs);margin-top:var(--dev-panel-spacing-sm);font-style:italic;text-align:right}._controlRendererContainer_jru2l_1 ._loading_jru2l_55{font-size:var(--dev-panel-font-size-xs);color:var(--dev-panel-text-color-muted);text-align:center;padding:var(--dev-panel-spacing-lg);display:flex;align-items:center;justify-content:center;gap:var(--dev-panel-spacing-sm)}._controlRendererContainer_jru2l_1 ._loading_jru2l_55:before{content:"";width:12px;height:12px;border:2px solid var(--dev-panel-border-color);border-top:2px solid var(--dev-panel-accent-color);border-radius:var(--dev-panel-border-radius-full);animation:_spin_jru2l_1 1s linear infinite}._controlRendererContainer_jru2l_1 ._error_jru2l_74{font-size:var(--dev-panel-font-size-xs);color:var(--dev-panel-error-color);text-align:center;padding:var(--dev-panel-spacing-lg);background:color-mix(in srgb,var(--dev-panel-error-color) 10%,transparent);border:1px solid color-mix(in srgb,var(--dev-panel-error-color) 30%,transparent);border-radius:var(--dev-panel-border-radius);margin:var(--dev-panel-spacing-sm) 0}@keyframes _spin_jru2l_1{0%{transform:rotate(0)}to{transform:rotate(360deg)}}
@@ -1 +1 @@
1
- :root{--dev-panel-font-family: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Helvetica Neue", Arial, sans-serif;--dev-panel-font-weight-normal: 400;--dev-panel-font-weight-medium: 500;--dev-panel-font-weight-semibold: 600;--dev-panel-font-weight-bold: 700;--dev-panel-font-size-xs: 10px;--dev-panel-font-size-sm: 12px;--dev-panel-font-size-md: 14px;--dev-panel-font-size-lg: 16px;--dev-panel-font-size-xl: 18px;--dev-panel-line-height-tight: 1.25;--dev-panel-line-height-normal: 1.5;--dev-panel-line-height-relaxed: 1.75;--dev-panel-accent-color: #2563eb;--dev-panel-accent-color-hover: #1d4ed8;--dev-panel-accent-color-active: #1e40af;--dev-panel-accent-color-disabled: #2563eb30;--dev-panel-primary-color: #2563eb;--dev-panel-primary-color-hover: #1d4ed8;--dev-panel-primary-color-active: #1e40af;--dev-panel-primary-color-disabled: #2563eb30;--dev-panel-secondary-color: #64748b;--dev-panel-secondary-color-hover: #475569;--dev-panel-secondary-color-active: #334155;--dev-panel-success-color: #10b981;--dev-panel-success-color-hover: #059669;--dev-panel-success-color-active: #047857;--dev-panel-warning-color: #f59e0b;--dev-panel-warning-color-hover: #d97706;--dev-panel-warning-color-active: #b45309;--dev-panel-error-color: #ef4444;--dev-panel-error-color-hover: #dc2626;--dev-panel-error-color-active: #b91c1c;--dev-panel-info-color: #06b6d4;--dev-panel-info-color-hover: #0891b2;--dev-panel-info-color-active: #0e7490;--dev-panel-background-color: #1e293b;--dev-panel-background-color-secondary: #334155;--dev-panel-background-color-tertiary: #475569;--dev-panel-foreground-color: #0f172a;--dev-panel-surface-color: #334155;--dev-panel-surface-color-hover: #475569;--dev-panel-surface-color-active: #64748b;--dev-panel-text-color: #f1f5f9;--dev-panel-text-color-secondary: #cbd5e1;--dev-panel-text-color-muted: #94a3b8;--dev-panel-text-color-disabled: #64748b;--dev-panel-text-color-on-accent: #ffffff;--dev-panel-text-color-on-surface: #f1f5f9;--dev-panel-border-color: #475569;--dev-panel-border-color-light: #64748b;--dev-panel-border-color-strong: #334155;--dev-panel-border-color-accent: #2563eb;--dev-panel-input-background-color: #0f172a;--dev-panel-input-background-color-hover: #1e293b;--dev-panel-input-background-color-focus: #1e293b;--dev-panel-input-border-color: #475569;--dev-panel-input-border-color-hover: #64748b;--dev-panel-input-border-color-focus: #2563eb;--dev-panel-input-text-color: #f1f5f9;--dev-panel-input-placeholder-color: #64748b;--dev-panel-input-border-width: 1px;--dev-panel-spacing-base: 4px;--dev-panel-spacing-xs: calc(var(--dev-panel-spacing-base) * .5);--dev-panel-spacing-sm: var(--dev-panel-spacing-base);--dev-panel-spacing-md: calc(var(--dev-panel-spacing-base) * 2);--dev-panel-spacing-lg: calc(var(--dev-panel-spacing-base) * 3);--dev-panel-spacing-xl: calc(var(--dev-panel-spacing-base) * 4);--dev-panel-spacing-2xl: calc(var(--dev-panel-spacing-base) * 5);--dev-panel-spacing-3xl: calc(var(--dev-panel-spacing-base) * 6);--dev-panel-spacing-4xl: calc(var(--dev-panel-spacing-base) * 8);--dev-panel-spacing: var(--dev-panel-spacing-lg);--dev-panel-shadow-xs: 0 1px 2px 0 rgb(0 0 0 / .05);--dev-panel-shadow-sm: 0 1px 3px 0 rgb(0 0 0 / .1), 0 1px 2px -1px rgb(0 0 0 / .1);--dev-panel-shadow-md: 0 4px 6px -1px rgb(0 0 0 / .1), 0 2px 4px -2px rgb(0 0 0 / .1);--dev-panel-shadow-lg: 0 10px 15px -3px rgb(0 0 0 / .1), 0 4px 6px -4px rgb(0 0 0 / .1);--dev-panel-shadow-xl: 0 20px 25px -5px rgb(0 0 0 / .1), 0 8px 10px -6px rgb(0 0 0 / .1);--dev-panel-shadow-2xl: 0 25px 50px -12px rgb(0 0 0 / .25);--dev-panel-shadow-inner: inset 0 2px 4px 0 rgb(0 0 0 / .05);--dev-panel-shadow: var(--dev-panel-shadow-xl);--dev-panel-border-radius-none: 0;--dev-panel-border-radius-sm: 2px;--dev-panel-border-radius-md: 4px;--dev-panel-border-radius-lg: 6px;--dev-panel-border-radius-xl: 8px;--dev-panel-border-radius-2xl: 12px;--dev-panel-border-radius-full: 9999px;--dev-panel-border-radius: var(--dev-panel-border-radius-lg);--dev-panel-max-width: 400px;--dev-panel-min-width: 280px;--dev-panel-max-height: 600px;--dev-panel-min-height: auto;--dev-panel-header-height: auto;--dev-panel-inputs-height: 32px;--dev-panel-inputs-height-sm: 28px;--dev-panel-inputs-height-lg: 36px;--dev-panel-button-height: 32px;--dev-panel-button-height-sm: 28px;--dev-panel-button-height-lg: 36px;--dev-panel-transition-fast: all .15s cubic-bezier(.4, 0, .2, 1);--dev-panel-transition-normal: all .2s cubic-bezier(.4, 0, .2, 1);--dev-panel-transition-slow: all .3s cubic-bezier(.4, 0, .2, 1);--dev-panel-transition: var(--dev-panel-transition-normal);--dev-panel-z-index-dropdown: 1000;--dev-panel-z-index-sticky: 1020;--dev-panel-z-index-fixed: 1030;--dev-panel-z-index-modal-backdrop: 1040;--dev-panel-z-index-modal: 1050;--dev-panel-z-index-popover: 1060;--dev-panel-z-index-tooltip: 1070;--dev-panel-z-index-toast: 1080;--dev-panel-z-index: var(--dev-panel-z-index-modal);--dev-panel-opacity-0: 0;--dev-panel-opacity-5: .05;--dev-panel-opacity-10: .1;--dev-panel-opacity-20: .2;--dev-panel-opacity-25: .25;--dev-panel-opacity-30: .3;--dev-panel-opacity-40: .4;--dev-panel-opacity-50: .5;--dev-panel-opacity-60: .6;--dev-panel-opacity-70: .7;--dev-panel-opacity-75: .75;--dev-panel-opacity-80: .8;--dev-panel-opacity-90: .9;--dev-panel-opacity-95: .95;--dev-panel-opacity-100: 1;--dev-panel-scrollbar-width: 6px;--dev-panel-scrollbar-track-color: var(--dev-panel-background-color-secondary);--dev-panel-scrollbar-thumb-color: var(--dev-panel-border-color);--dev-panel-scrollbar-thumb-hover-color: var(--dev-panel-border-color-light)}@media (prefers-color-scheme: light){:root{color-scheme:light;--dev-panel-background-color: #f8fafc;--dev-panel-background-color-secondary: #f1f5f9;--dev-panel-background-color-tertiary: #e2e8f0;--dev-panel-foreground-color: #ffffff;--dev-panel-surface-color: #ffffff;--dev-panel-surface-color-hover: #e2e8f0;--dev-panel-surface-color-active: #e2e8f0;--dev-panel-text-color: #0f172a;--dev-panel-text-color-secondary: #334155;--dev-panel-text-color-muted: #64748b;--dev-panel-text-color-disabled: #94a3b8;--dev-panel-text-color-on-accent: #ffffff;--dev-panel-text-color-on-surface: #0f172a;--dev-panel-border-color: #e2e8f0;--dev-panel-border-color-light: #cbd5e1;--dev-panel-border-color-strong: #94a3b8;--dev-panel-border-color-accent: #2563eb;--dev-panel-input-background-color: #ffffff;--dev-panel-input-background-color-hover: #ffcccc;--dev-panel-input-background-color-focus: #ffffff;--dev-panel-input-border-color: #e2e8f0;--dev-panel-input-border-color-hover: #cbd5e1;--dev-panel-input-border-color-focus: #2563eb;--dev-panel-input-text-color: #0f172a;--dev-panel-input-placeholder-color: #64748b;--dev-panel-shadow-xs: 0 1px 2px 0 rgb(0 0 0 / .03);--dev-panel-shadow-sm: 0 1px 3px 0 rgb(0 0 0 / .08), 0 1px 2px -1px rgb(0 0 0 / .08);--dev-panel-shadow-md: 0 4px 6px -1px rgb(0 0 0 / .08), 0 2px 4px -2px rgb(0 0 0 / .08);--dev-panel-shadow-lg: 0 10px 15px -3px rgb(0 0 0 / .08), 0 4px 6px -4px rgb(0 0 0 / .08);--dev-panel-shadow-xl: 0 20px 25px -5px rgb(0 0 0 / .08), 0 8px 10px -6px rgb(0 0 0 / .08);--dev-panel-shadow-2xl: 0 25px 50px -12px rgb(0 0 0 / .15);--dev-panel-shadow-inner: inset 0 2px 4px 0 rgb(0 0 0 / .03);--dev-panel-shadow: var(--dev-panel-shadow-xl);--dev-panel-scrollbar-thumb-color: var(--dev-panel-border-color-light);--dev-panel-scrollbar-thumb-hover-color: var(--dev-panel-border-color-strong)}}:root[data-dev-panel-theme=dark]{color-scheme:dark}:root[data-dev-panel-theme=light]{--dev-panel-background-color: #f8fafc;--dev-panel-background-color-secondary: #f1f5f9;--dev-panel-background-color-tertiary: #e2e8f0;--dev-panel-foreground-color: #ffffff;--dev-panel-surface-color: #ffffff;--dev-panel-surface-color-hover: #e2e8f0;--dev-panel-surface-color-active: #e2e8f0;--dev-panel-text-color: #0f172a;--dev-panel-text-color-secondary: #334155;--dev-panel-text-color-muted: #64748b;--dev-panel-text-color-disabled: #94a3b8;--dev-panel-text-color-on-accent: #ffffff;--dev-panel-text-color-on-surface: #0f172a;--dev-panel-border-color: #e2e8f0;--dev-panel-border-color-light: #cbd5e1;--dev-panel-border-color-strong: #94a3b8;--dev-panel-border-color-accent: #2563eb;--dev-panel-input-background-color: #ffffff;--dev-panel-input-background-color-hover: #ffcccc;--dev-panel-input-background-color-focus: #ffffff;--dev-panel-input-border-color: #e2e8f0;--dev-panel-input-border-color-hover: #cbd5e1;--dev-panel-input-border-color-focus: #2563eb;--dev-panel-input-text-color: #0f172a;--dev-panel-input-placeholder-color: #64748b;--dev-panel-shadow-xs: 0 1px 2px 0 rgb(0 0 0 / .03);--dev-panel-shadow-sm: 0 1px 3px 0 rgb(0 0 0 / .08), 0 1px 2px -1px rgb(0 0 0 / .08);--dev-panel-shadow-md: 0 4px 6px -1px rgb(0 0 0 / .08), 0 2px 4px -2px rgb(0 0 0 / .08);--dev-panel-shadow-lg: 0 10px 15px -3px rgb(0 0 0 / .08), 0 4px 6px -4px rgb(0 0 0 / .08);--dev-panel-shadow-xl: 0 20px 25px -5px rgb(0 0 0 / .08), 0 8px 10px -6px rgb(0 0 0 / .08);--dev-panel-shadow-2xl: 0 25px 50px -12px rgb(0 0 0 / .15);--dev-panel-shadow-inner: inset 0 2px 4px 0 rgb(0 0 0 / .03);--dev-panel-shadow: var(--dev-panel-shadow-xl);--dev-panel-scrollbar-thumb-color: var(--dev-panel-border-color-light);--dev-panel-scrollbar-thumb-hover-color: var(--dev-panel-border-color-strong);color-scheme:light}._select_1hbiz_217{position:relative;width:100%}._trigger_1hbiz_222{display:block;width:100%;height:var(--dev-panel-inputs-height-sm);padding:var(--dev-panel-spacing-sm) var(--dev-panel-spacing-md);font-family:var(--dev-panel-font-family);font-size:var(--dev-panel-font-size-sm);line-height:var(--dev-panel-line-height-normal);color:var(--dev-panel-input-text-color);background-color:var(--dev-panel-input-background-color);border-radius:var(--dev-panel-border-radius);transition:var(--dev-panel-transition);display:flex;align-items:center;justify-content:space-between;border:var(--dev-panel-input-border-width) solid var(--dev-panel-input-border-color);cursor:pointer}._trigger_1hbiz_222::placeholder{color:var(--dev-panel-input-placeholder-color)}._trigger_1hbiz_222:focus{outline:none;border-color:var(--dev-panel-input-border-color-focus);box-shadow:0 0 0 3px #6366f133}._trigger_1hbiz_222:disabled{opacity:var(--dev-panel-opacity-50);background-color:var(--dev-panel-surface-color);border-color:var(--dev-panel-border-color);cursor:not-allowed}._trigger_1hbiz_222:hover:not(:disabled){border-color:var(--dev-panel-input-border-color-hover)}._trigger_1hbiz_222:focus{outline:none;border-color:var(--dev-panel-input-border-color-focus);box-shadow:0 0 0 3px color-mix(in srgb,var(--dev-panel-accent-color) 20%,transparent)}._trigger_1hbiz_222:disabled{cursor:not-allowed;opacity:var(--dev-panel-opacity-50);background-color:var(--dev-panel-surface-color)}._trigger_1hbiz_222._open_1hbiz_271{border-color:var(--dev-panel-input-border-color-focus)}._value_1hbiz_275{flex:1;text-align:left;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--dev-panel-input-text-color);font-size:var(--dev-panel-font-size-sm)}._value_1hbiz_275._placeholder_1hbiz_284{color:var(--dev-panel-input-placeholder-color)}._arrow_1hbiz_288{display:block;width:16px;height:16px;margin-left:var(--dev-panel-spacing-sm);transition:var(--dev-panel-transition);flex-shrink:0}._open_1hbiz_271 ._arrow_1hbiz_288{transform:rotate(180deg)}._arrow_1hbiz_288 path{fill:var(--dev-panel-text-color-muted)}._dropdownPortal_1hbiz_303{position:fixed;z-index:9999}._dropdownPortal_1hbiz_303 *{box-sizing:border-box}._dropdown_1hbiz_303{scrollbar-width:thin;scrollbar-color:var(--dev-panel-scrollbar-thumb-color) var(--dev-panel-scrollbar-track-color);max-height:200px;background-color:var(--dev-panel-foreground-color);border:1px solid var(--dev-panel-border-color);border-radius:var(--dev-panel-border-radius);overflow-y:auto;box-shadow:var(--dev-panel-shadow-lg);animation:_dropdown-fade-in_1hbiz_1 .15s ease-out}._dropdown_1hbiz_303::-webkit-scrollbar{width:var(--dev-panel-scrollbar-width);height:var(--dev-panel-scrollbar-width)}._dropdown_1hbiz_303::-webkit-scrollbar-track{background:var(--dev-panel-scrollbar-track-color);border-radius:var(--dev-panel-border-radius-md)}._dropdown_1hbiz_303::-webkit-scrollbar-thumb{background:var(--dev-panel-scrollbar-thumb-color);border-radius:var(--dev-panel-border-radius-md);transition:var(--dev-panel-transition-fast)}._dropdown_1hbiz_303::-webkit-scrollbar-thumb:hover{background:var(--dev-panel-scrollbar-thumb-hover-color)}._dropdown_1hbiz_303::-webkit-scrollbar-corner{background:var(--dev-panel-scrollbar-track-color)}._option_1hbiz_342{position:relative;display:flex;align-items:center;padding:var(--dev-panel-spacing-sm) var(--dev-panel-spacing-md);transition:var(--dev-panel-transition);background-color:var(--dev-panel-foreground-color);color:var(--dev-panel-text-color);border:none;width:100%;text-align:left;font-family:var(--dev-panel-font-family);font-size:var(--dev-panel-font-size-sm);cursor:pointer}._option_1hbiz_342:hover{background-color:var(--dev-panel-surface-color-hover)}._option_1hbiz_342._selected_1hbiz_360{background-color:var(--dev-panel-accent-color);color:var(--dev-panel-text-color-on-accent)}._option_1hbiz_342:focus{outline:none;background-color:var(--dev-panel-surface-color-hover)}._checkbox_1hbiz_369{appearance:none;width:16px;height:16px;border:1px solid var(--dev-panel-border-color);border-radius:3px;margin-right:var(--dev-panel-spacing-sm);position:relative;background-color:var(--dev-panel-input-background-color);flex-shrink:0;cursor:pointer}._checkbox_1hbiz_369:checked{background-color:var(--dev-panel-accent-color);border-color:var(--dev-panel-accent-color)}._checkbox_1hbiz_369:focus{outline:none;box-shadow:0 0 0 2px color-mix(in srgb,var(--dev-panel-accent-color) 20%,transparent)}._label_1hbiz_390{flex:1;pointer-events:none}@keyframes _dropdown-fade-in_1hbiz_1{0%{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:translateY(0)}}
1
+ :root{--dev-panel-font-family: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Helvetica Neue", Arial, sans-serif;--dev-panel-font-weight-normal: 400;--dev-panel-font-weight-medium: 500;--dev-panel-font-weight-semibold: 600;--dev-panel-font-weight-bold: 700;--dev-panel-font-size-xs: 10px;--dev-panel-font-size-sm: 12px;--dev-panel-font-size-md: 14px;--dev-panel-font-size-lg: 16px;--dev-panel-font-size-xl: 18px;--dev-panel-line-height-tight: 1.25;--dev-panel-line-height-normal: 1.5;--dev-panel-line-height-relaxed: 1.75;--dev-panel-accent-color: #2563eb;--dev-panel-accent-color-hover: #1d4ed8;--dev-panel-accent-color-active: #1e40af;--dev-panel-accent-color-disabled: #2563eb30;--dev-panel-primary-color: #2563eb;--dev-panel-primary-color-hover: #1d4ed8;--dev-panel-primary-color-active: #1e40af;--dev-panel-primary-color-disabled: #2563eb30;--dev-panel-secondary-color: #64748b;--dev-panel-secondary-color-hover: #475569;--dev-panel-secondary-color-active: #334155;--dev-panel-success-color: #10b981;--dev-panel-success-color-hover: #059669;--dev-panel-success-color-active: #047857;--dev-panel-warning-color: #f59e0b;--dev-panel-warning-color-hover: #d97706;--dev-panel-warning-color-active: #b45309;--dev-panel-error-color: #ef4444;--dev-panel-error-color-hover: #dc2626;--dev-panel-error-color-active: #b91c1c;--dev-panel-info-color: #06b6d4;--dev-panel-info-color-hover: #0891b2;--dev-panel-info-color-active: #0e7490;--dev-panel-background-color: #1e293b;--dev-panel-background-color-secondary: #334155;--dev-panel-background-color-tertiary: #475569;--dev-panel-foreground-color: #0f172a;--dev-panel-surface-color: #334155;--dev-panel-surface-color-hover: #475569;--dev-panel-surface-color-active: #64748b;--dev-panel-text-color: #f1f5f9;--dev-panel-text-color-secondary: #cbd5e1;--dev-panel-text-color-muted: #94a3b8;--dev-panel-text-color-disabled: #64748b;--dev-panel-text-color-on-accent: #ffffff;--dev-panel-text-color-on-surface: #f1f5f9;--dev-panel-border-color: #475569;--dev-panel-border-color-light: #64748b;--dev-panel-border-color-strong: #334155;--dev-panel-border-color-accent: #2563eb;--dev-panel-input-background-color: #0f172a;--dev-panel-input-background-color-hover: #1e293b;--dev-panel-input-background-color-focus: #1e293b;--dev-panel-input-border-color: #475569;--dev-panel-input-border-color-hover: #64748b;--dev-panel-input-border-color-focus: #2563eb;--dev-panel-input-text-color: #f1f5f9;--dev-panel-input-placeholder-color: #64748b;--dev-panel-input-border-width: 1px;--dev-panel-spacing-base: 4px;--dev-panel-spacing-xs: calc(var(--dev-panel-spacing-base) * .5);--dev-panel-spacing-sm: var(--dev-panel-spacing-base);--dev-panel-spacing-md: calc(var(--dev-panel-spacing-base) * 2);--dev-panel-spacing-lg: calc(var(--dev-panel-spacing-base) * 3);--dev-panel-spacing-xl: calc(var(--dev-panel-spacing-base) * 4);--dev-panel-spacing-2xl: calc(var(--dev-panel-spacing-base) * 5);--dev-panel-spacing-3xl: calc(var(--dev-panel-spacing-base) * 6);--dev-panel-spacing-4xl: calc(var(--dev-panel-spacing-base) * 8);--dev-panel-spacing: var(--dev-panel-spacing-lg);--dev-panel-shadow-xs: 0 1px 2px 0 rgb(0 0 0 / .05);--dev-panel-shadow-sm: 0 1px 3px 0 rgb(0 0 0 / .1), 0 1px 2px -1px rgb(0 0 0 / .1);--dev-panel-shadow-md: 0 4px 6px -1px rgb(0 0 0 / .1), 0 2px 4px -2px rgb(0 0 0 / .1);--dev-panel-shadow-lg: 0 10px 15px -3px rgb(0 0 0 / .1), 0 4px 6px -4px rgb(0 0 0 / .1);--dev-panel-shadow-xl: 0 20px 25px -5px rgb(0 0 0 / .1), 0 8px 10px -6px rgb(0 0 0 / .1);--dev-panel-shadow-2xl: 0 25px 50px -12px rgb(0 0 0 / .25);--dev-panel-shadow-inner: inset 0 2px 4px 0 rgb(0 0 0 / .05);--dev-panel-shadow: var(--dev-panel-shadow-xl);--dev-panel-border-radius-none: 0;--dev-panel-border-radius-sm: 2px;--dev-panel-border-radius-md: 4px;--dev-panel-border-radius-lg: 6px;--dev-panel-border-radius-xl: 8px;--dev-panel-border-radius-2xl: 12px;--dev-panel-border-radius-full: 9999px;--dev-panel-border-radius: var(--dev-panel-border-radius-lg);--dev-panel-max-width: 400px;--dev-panel-min-width: 280px;--dev-panel-max-height: 600px;--dev-panel-min-height: auto;--dev-panel-header-height: auto;--dev-panel-inputs-height: 32px;--dev-panel-inputs-height-sm: 28px;--dev-panel-inputs-height-lg: 36px;--dev-panel-button-height: 32px;--dev-panel-button-height-sm: 28px;--dev-panel-button-height-lg: 36px;--dev-panel-transition-fast: all .15s cubic-bezier(.4, 0, .2, 1);--dev-panel-transition-normal: all .2s cubic-bezier(.4, 0, .2, 1);--dev-panel-transition-slow: all .3s cubic-bezier(.4, 0, .2, 1);--dev-panel-transition: var(--dev-panel-transition-normal);--dev-panel-z-index-dropdown: 1000;--dev-panel-z-index-sticky: 1020;--dev-panel-z-index-fixed: 1030;--dev-panel-z-index-modal-backdrop: 1040;--dev-panel-z-index-modal: 1050;--dev-panel-z-index-popover: 1060;--dev-panel-z-index-tooltip: 1070;--dev-panel-z-index-toast: 1080;--dev-panel-z-index: var(--dev-panel-z-index-modal);--dev-panel-opacity-0: 0;--dev-panel-opacity-5: .05;--dev-panel-opacity-10: .1;--dev-panel-opacity-20: .2;--dev-panel-opacity-25: .25;--dev-panel-opacity-30: .3;--dev-panel-opacity-40: .4;--dev-panel-opacity-50: .5;--dev-panel-opacity-60: .6;--dev-panel-opacity-70: .7;--dev-panel-opacity-75: .75;--dev-panel-opacity-80: .8;--dev-panel-opacity-90: .9;--dev-panel-opacity-95: .95;--dev-panel-opacity-100: 1;--dev-panel-scrollbar-width: 6px;--dev-panel-scrollbar-track-color: var(--dev-panel-background-color-secondary);--dev-panel-scrollbar-thumb-color: var(--dev-panel-border-color);--dev-panel-scrollbar-thumb-hover-color: var(--dev-panel-border-color-light)}@media (prefers-color-scheme: light){:root{color-scheme:light;--dev-panel-background-color: #f8fafc;--dev-panel-background-color-secondary: #f1f5f9;--dev-panel-background-color-tertiary: #e2e8f0;--dev-panel-foreground-color: #ffffff;--dev-panel-surface-color: #ffffff;--dev-panel-surface-color-hover: #e2e8f0;--dev-panel-surface-color-active: #e2e8f0;--dev-panel-text-color: #0f172a;--dev-panel-text-color-secondary: #334155;--dev-panel-text-color-muted: #64748b;--dev-panel-text-color-disabled: #94a3b8;--dev-panel-text-color-on-accent: #ffffff;--dev-panel-text-color-on-surface: #0f172a;--dev-panel-border-color: #e2e8f0;--dev-panel-border-color-light: #cbd5e1;--dev-panel-border-color-strong: #94a3b8;--dev-panel-border-color-accent: #2563eb;--dev-panel-input-background-color: #ffffff;--dev-panel-input-background-color-hover: #ffcccc;--dev-panel-input-background-color-focus: #ffffff;--dev-panel-input-border-color: #e2e8f0;--dev-panel-input-border-color-hover: #cbd5e1;--dev-panel-input-border-color-focus: #2563eb;--dev-panel-input-text-color: #0f172a;--dev-panel-input-placeholder-color: #64748b;--dev-panel-shadow-xs: 0 1px 2px 0 rgb(0 0 0 / .03);--dev-panel-shadow-sm: 0 1px 3px 0 rgb(0 0 0 / .08), 0 1px 2px -1px rgb(0 0 0 / .08);--dev-panel-shadow-md: 0 4px 6px -1px rgb(0 0 0 / .08), 0 2px 4px -2px rgb(0 0 0 / .08);--dev-panel-shadow-lg: 0 10px 15px -3px rgb(0 0 0 / .08), 0 4px 6px -4px rgb(0 0 0 / .08);--dev-panel-shadow-xl: 0 20px 25px -5px rgb(0 0 0 / .08), 0 8px 10px -6px rgb(0 0 0 / .08);--dev-panel-shadow-2xl: 0 25px 50px -12px rgb(0 0 0 / .15);--dev-panel-shadow-inner: inset 0 2px 4px 0 rgb(0 0 0 / .03);--dev-panel-shadow: var(--dev-panel-shadow-xl);--dev-panel-scrollbar-thumb-color: var(--dev-panel-border-color-light);--dev-panel-scrollbar-thumb-hover-color: var(--dev-panel-border-color-strong)}}:root[data-dev-panel-theme=dark]{color-scheme:dark}:root[data-dev-panel-theme=light]{--dev-panel-background-color: #f8fafc;--dev-panel-background-color-secondary: #f1f5f9;--dev-panel-background-color-tertiary: #e2e8f0;--dev-panel-foreground-color: #ffffff;--dev-panel-surface-color: #ffffff;--dev-panel-surface-color-hover: #e2e8f0;--dev-panel-surface-color-active: #e2e8f0;--dev-panel-text-color: #0f172a;--dev-panel-text-color-secondary: #334155;--dev-panel-text-color-muted: #64748b;--dev-panel-text-color-disabled: #94a3b8;--dev-panel-text-color-on-accent: #ffffff;--dev-panel-text-color-on-surface: #0f172a;--dev-panel-border-color: #e2e8f0;--dev-panel-border-color-light: #cbd5e1;--dev-panel-border-color-strong: #94a3b8;--dev-panel-border-color-accent: #2563eb;--dev-panel-input-background-color: #ffffff;--dev-panel-input-background-color-hover: #ffcccc;--dev-panel-input-background-color-focus: #ffffff;--dev-panel-input-border-color: #e2e8f0;--dev-panel-input-border-color-hover: #cbd5e1;--dev-panel-input-border-color-focus: #2563eb;--dev-panel-input-text-color: #0f172a;--dev-panel-input-placeholder-color: #64748b;--dev-panel-shadow-xs: 0 1px 2px 0 rgb(0 0 0 / .03);--dev-panel-shadow-sm: 0 1px 3px 0 rgb(0 0 0 / .08), 0 1px 2px -1px rgb(0 0 0 / .08);--dev-panel-shadow-md: 0 4px 6px -1px rgb(0 0 0 / .08), 0 2px 4px -2px rgb(0 0 0 / .08);--dev-panel-shadow-lg: 0 10px 15px -3px rgb(0 0 0 / .08), 0 4px 6px -4px rgb(0 0 0 / .08);--dev-panel-shadow-xl: 0 20px 25px -5px rgb(0 0 0 / .08), 0 8px 10px -6px rgb(0 0 0 / .08);--dev-panel-shadow-2xl: 0 25px 50px -12px rgb(0 0 0 / .15);--dev-panel-shadow-inner: inset 0 2px 4px 0 rgb(0 0 0 / .03);--dev-panel-shadow: var(--dev-panel-shadow-xl);--dev-panel-scrollbar-thumb-color: var(--dev-panel-border-color-light);--dev-panel-scrollbar-thumb-hover-color: var(--dev-panel-border-color-strong);color-scheme:light}._select_ug510_217{position:relative;width:100%}._trigger_ug510_222{display:block;width:100%;height:var(--dev-panel-inputs-height-sm);padding:var(--dev-panel-spacing-sm) var(--dev-panel-spacing-md);font-family:var(--dev-panel-font-family);font-size:var(--dev-panel-font-size-sm);line-height:var(--dev-panel-line-height-normal);color:var(--dev-panel-input-text-color);background-color:var(--dev-panel-input-background-color);border-radius:var(--dev-panel-border-radius);transition:var(--dev-panel-transition);display:flex;align-items:center;justify-content:space-between;border:var(--dev-panel-input-border-width) solid var(--dev-panel-input-border-color);cursor:pointer}._trigger_ug510_222::placeholder{color:var(--dev-panel-input-placeholder-color)}._trigger_ug510_222:focus{outline:none;border-color:var(--dev-panel-input-border-color-focus);box-shadow:0 0 0 3px #6366f133}._trigger_ug510_222:disabled{opacity:var(--dev-panel-opacity-50);background-color:var(--dev-panel-surface-color);border-color:var(--dev-panel-border-color);cursor:not-allowed}._trigger_ug510_222:hover:not(:disabled){border-color:var(--dev-panel-input-border-color-hover)}._trigger_ug510_222:focus{outline:none;border-color:var(--dev-panel-input-border-color-focus);box-shadow:0 0 0 3px color-mix(in srgb,var(--dev-panel-accent-color) 20%,transparent)}._trigger_ug510_222:disabled{cursor:not-allowed;opacity:var(--dev-panel-opacity-50);background-color:var(--dev-panel-surface-color)}._trigger_ug510_222._open_ug510_271{border-color:var(--dev-panel-input-border-color-focus)}._value_ug510_275{flex:1;text-align:left;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--dev-panel-input-text-color);font-size:var(--dev-panel-font-size-sm)}._value_ug510_275._placeholder_ug510_284{color:var(--dev-panel-input-placeholder-color)}._arrow_ug510_288{display:block;width:16px;height:16px;margin-left:var(--dev-panel-spacing-sm);transition:var(--dev-panel-transition);flex-shrink:0}._open_ug510_271 ._arrow_ug510_288{transform:rotate(180deg)}._arrow_ug510_288 path{fill:var(--dev-panel-text-color-muted)}._dropdownPortal_ug510_303{position:fixed;z-index:9999}._dropdownPortal_ug510_303 *{box-sizing:border-box}._dropdown_ug510_303{scrollbar-width:thin;scrollbar-color:var(--dev-panel-scrollbar-thumb-color) var(--dev-panel-scrollbar-track-color);max-height:200px;background-color:var(--dev-panel-foreground-color);border:1px solid var(--dev-panel-border-color);border-radius:var(--dev-panel-border-radius);overflow-y:auto;box-shadow:var(--dev-panel-shadow-lg);animation:_dropdown-fade-in_ug510_1 .15s ease-out}._dropdown_ug510_303::-webkit-scrollbar{width:var(--dev-panel-scrollbar-width);height:var(--dev-panel-scrollbar-width)}._dropdown_ug510_303::-webkit-scrollbar-track{background:var(--dev-panel-scrollbar-track-color);border-radius:var(--dev-panel-border-radius-md)}._dropdown_ug510_303::-webkit-scrollbar-thumb{background:var(--dev-panel-scrollbar-thumb-color);border-radius:var(--dev-panel-border-radius-md);transition:var(--dev-panel-transition-fast)}._dropdown_ug510_303::-webkit-scrollbar-thumb:hover{background:var(--dev-panel-scrollbar-thumb-hover-color)}._dropdown_ug510_303::-webkit-scrollbar-corner{background:var(--dev-panel-scrollbar-track-color)}._option_ug510_342{position:relative;display:flex;align-items:center;padding:var(--dev-panel-spacing-sm) var(--dev-panel-spacing-md);transition:var(--dev-panel-transition);background-color:var(--dev-panel-foreground-color);color:var(--dev-panel-text-color);border:none;width:100%;text-align:left;font-family:var(--dev-panel-font-family);font-size:var(--dev-panel-font-size-sm);cursor:pointer;overflow-wrap:anywhere}._option_ug510_342:hover{background-color:var(--dev-panel-surface-color-hover)}._option_ug510_342._selected_ug510_361{background-color:var(--dev-panel-accent-color);color:var(--dev-panel-text-color-on-accent)}._option_ug510_342:focus{outline:none;background-color:var(--dev-panel-surface-color-hover)}._checkbox_ug510_370{appearance:none;width:16px;height:16px;border:1px solid var(--dev-panel-border-color);border-radius:3px;margin-right:var(--dev-panel-spacing-sm);position:relative;background-color:var(--dev-panel-input-background-color);flex-shrink:0;cursor:pointer}._checkbox_ug510_370:checked{background-color:var(--dev-panel-accent-color);border-color:var(--dev-panel-accent-color)}._checkbox_ug510_370:focus{outline:none;box-shadow:0 0 0 2px color-mix(in srgb,var(--dev-panel-accent-color) 20%,transparent)}._label_ug510_391{flex:1;pointer-events:none}@keyframes _dropdown-fade-in_ug510_1{0%{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:translateY(0)}}
@@ -14,6 +14,7 @@ export interface BaseControl {
14
14
  label?: string;
15
15
  description?: string;
16
16
  disabled?: boolean;
17
+ persist?: boolean;
17
18
  }
18
19
 
19
20
  export interface BaseInputControl extends BaseControl {
@@ -1,22 +1,22 @@
1
1
  import { jsxs as t, jsx as n } from "react/jsx-runtime";
2
2
  import { Suspense as c } from "react";
3
- import { className as s } from "../../utils/className/className.js";
3
+ import { className as l } from "../../utils/className/className.js";
4
4
  import { controls as d } from "./controls/index.js";
5
- import '../../assets/index5.css';const p = "_controlRendererContainer_1s60v_1", _ = "_controlContainer_1s60v_4", u = "_hoverable_1s60v_13", v = "_fullWidth_1s60v_16", f = "_label_1s60v_19", h = "_controlWrapper_1s60v_22", b = "_justifyStart_1s60v_26", C = "_description_1s60v_42", m = "_loading_1s60v_51", y = "_error_1s60v_70", e = {
5
+ import '../../assets/index5.css';const p = "_controlRendererContainer_jru2l_1", u = "_controlContainer_jru2l_5", _ = "_hoverable_jru2l_15", f = "_fullWidth_jru2l_18", h = "_label_jru2l_21", b = "_controlWrapper_jru2l_24", j = "_justifyStart_jru2l_30", C = "_description_jru2l_46", m = "_loading_jru2l_55", y = "_error_jru2l_74", e = {
6
6
  controlRendererContainer: p,
7
- controlContainer: _,
8
- hoverable: u,
9
- fullWidth: v,
10
- label: f,
11
- controlWrapper: h,
12
- justifyStart: b,
7
+ controlContainer: u,
8
+ hoverable: _,
9
+ fullWidth: f,
10
+ label: h,
11
+ controlWrapper: b,
12
+ justifyStart: j,
13
13
  description: C,
14
14
  loading: m,
15
15
  error: y
16
- }, g = ["button", "buttonGroup", "separator", "dragAndDrop"], W = ["separator", "dragAndDrop"], j = ["button", "separator", "dragAndDrop"];
17
- function A({ name: l, control: r }) {
18
- const i = r?.label || l;
19
- function a() {
16
+ }, v = ["button", "buttonGroup", "separator", "dragAndDrop"], g = ["separator", "dragAndDrop"], W = ["button", "separator", "dragAndDrop"];
17
+ function A({ name: i, control: r }) {
18
+ const a = r?.label || i;
19
+ function s() {
20
20
  if (!r || !r.type)
21
21
  return /* @__PURE__ */ n("div", { className: e.error, children: "Control type is not defined" });
22
22
  const o = d[r.type];
@@ -26,19 +26,19 @@ function A({ name: l, control: r }) {
26
26
  /* @__PURE__ */ t(
27
27
  "div",
28
28
  {
29
- ...s(e.controlContainer, {
30
- [e.fullWidth]: g.includes(r.type),
31
- [e.hoverable]: !W.includes(r.type)
29
+ ...l(e.controlContainer, {
30
+ [e.fullWidth]: v.includes(r.type),
31
+ [e.hoverable]: !g.includes(r.type)
32
32
  }),
33
33
  children: [
34
- !j.includes(r.type) && /* @__PURE__ */ n("label", { className: e.label, children: i }),
34
+ !W.includes(r.type) && /* @__PURE__ */ n("label", { className: e.label, children: a }),
35
35
  /* @__PURE__ */ n(
36
36
  "div",
37
37
  {
38
- ...s(e.controlWrapper, {
38
+ ...l(e.controlWrapper, {
39
39
  [e.justifyStart]: r.type === "separator"
40
40
  }),
41
- children: a()
41
+ children: s()
42
42
  }
43
43
  )
44
44
  ]
@@ -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/index7.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/index7.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
@@ -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.2.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.",