react-dockable-desktop 1.0.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 ADDED
@@ -0,0 +1,327 @@
1
+ # React Dockable Desktop
2
+
3
+ [![npm version](https://img.shields.io/badge/npm-v1.0.0-blue.svg)](#)
4
+ [![license](https://img.shields.io/badge/license-MIT-green.svg)](#)
5
+ [![Demo](https://img.shields.io/badge/demo-live-brightgreen.svg)](https://felipecarrillo100.github.io/react-dockable-desktop/)
6
+
7
+ A beautiful, premium, state-of-the-art React window manager and dockable layout engine. It features fluid split-docking grids, resizable floating windows, dynamic taskbars, and tabbed panels with **zero-unmount DOM persistence** and **built-in internationalization (i18n) support**.
8
+
9
+ [**Live Interactive Demo πŸš€**](https://felipecarrillo100.github.io/react-dockable-desktop/)
10
+
11
+ ---
12
+
13
+ ## 🌟 Key Features
14
+
15
+ * **πŸ“¦ Dockable Splits & Tab Grid**: Drag-and-drop panels to split screens or group them together into tabbed containers.
16
+ * **πŸ—ΊοΈ Workspace Edge Docking**: Drag a tab or floating window to the outer edges of the screen (left, right, top, bottom) to instantly dock it as a full-width or full-height column/row.
17
+ * **πŸͺ Floating Windows**: Seamlessly pop panels out into floating windows with smooth drag-and-drop movement, custom resizing, maximize, and minimize behaviors.
18
+ * **🎨 Custom Global Style Classes**: Inject custom, global styles at the provider level (`modalClass`, `modalBodyClass`, `sidePanelClass`, `sidePanelBodyClass`, `windowClass`, and `windowBodyClass`) to style widgets uniformly.
19
+ * **πŸ₯ž Aspect-Ratio Modal Engine**: Modals automatically wrap and shrink-to-fit content snugly, but cap height and scroll gracefully at visual aspect-ratio thresholds (4:3 for small/medium, 16:10 for large layouts).
20
+ * **πŸ”¬ Zero-Unmount DOM Persistence**: Heavy widgets (like Leaflet Maps, WebGL viewports, terminal consoles, or stateful forms) maintain their DOM nodes and state. The engine moves existing DOM structures into a hidden document fragment host rather than unmounting them.
21
+ * **🌍 i18n Ready**: Native translation pipeline designed to adapt with tools like `react-intl` (`intl.formatMessage`) or custom formatting libraries. Translate tab headers, floating window titles, taskbars, and right-click context actions dynamically.
22
+ * **πŸ’Ž Glassmorphic & Modern Styling**: Sleek dark mode aesthetics, interactive micro-animations, and fluid transitions.
23
+ * **πŸ”Œ Inter-Panel Pub/Sub Event Bus**: A robust messaging system for lightweight, decoupled communication between active panels.
24
+
25
+ ---
26
+
27
+ ## πŸš€ Installation
28
+
29
+ ```bash
30
+ npm install react-dockable-desktop replace-react-contexify
31
+ ```
32
+
33
+ Ensure the styling for both the layout engine and context menu is imported in your main entry file (e.g., `index.js` or `main.tsx`):
34
+
35
+ ```typescript
36
+ import 'replace-react-contexify/styles.css';
37
+ import 'react-dockable-desktop/styles.css';
38
+ ```
39
+
40
+ ---
41
+
42
+ ## πŸ’» Running the Demo Environments
43
+
44
+ The project includes two built-in demo setups to explore and test the window manager layout features:
45
+
46
+ ### 1. Leaflet & Monaco Open Source Demo (Default)
47
+ A clean, lightweight dashboard demo suitable for public deployment. It showcases Leaflet 2D/3D map integration (with dynamic CARTO Light/Dark tile styles mapping to dashboard theme switches) and Monaco Editor panels.
48
+ ```bash
49
+ npm run dev
50
+ ```
51
+
52
+ ### 2. LuciadRIA Earth 3D Demo (Isolated)
53
+ An isolated sandbox dashboard demonstrating premium 3D Earth visualizations in the `EPSG:4978` reference reference frame using LuciadRIA. *Note: Requires a valid LuciadRIA developer license locally to run.*
54
+ ```bash
55
+ npm run dev:ria
56
+ ```
57
+
58
+ ---
59
+
60
+ ## πŸ› οΈ Getting Started
61
+
62
+ ### 1. Define and Register Custom Panels
63
+
64
+ Register your components with `PanelRegistry`. This exposes them to the window manager layout engine for spawning and custom configuration.
65
+
66
+ ```typescript
67
+ import React from 'react';
68
+ import { PanelRegistry } from 'react-dockable-desktop';
69
+
70
+ // Example Panel Component
71
+ const MapView: React.FC = () => {
72
+ return (
73
+ <div style={{ width: '100%', height: '100%', padding: '1rem', color: '#fff' }}>
74
+ <h3>Interactive Map</h3>
75
+ <p>This DOM is preserved across tabs, floats, and minimizations!</p>
76
+ </div>
77
+ );
78
+ };
79
+
80
+ // Register
81
+ PanelRegistry.register('mainMap', MapView, {
82
+ title: { id: 'app.mapTitle', defaultMessage: 'Satellite Map View' },
83
+ canClose: false, // Permanent panel
84
+ canMinimize: true,
85
+ canDrag: true,
86
+ favoritePosition: { x: 100, y: 120, width: 600, height: 400 }
87
+ });
88
+ ```
89
+
90
+ ### 2. Set Up the WindowManager Context Provider
91
+
92
+ Wrap your workspace inside the `WindowManagerProvider` and render the `Desktop` component:
93
+
94
+ ```typescript
95
+ import React from 'react';
96
+ import { WindowManagerProvider, Desktop } from 'react-dockable-desktop';
97
+
98
+ function App() {
99
+ return (
100
+ <WindowManagerProvider>
101
+ <div style={{ width: '100vw', height: '100vh' }}>
102
+ <Desktop />
103
+ </div>
104
+ </WindowManagerProvider>
105
+ );
106
+ }
107
+
108
+ export default App;
109
+ ```
110
+
111
+ ---
112
+
113
+ ## 🌍 Internationalization (i18n)
114
+
115
+ `react-dockable-desktop` is built with dynamic translation in mind. Titles and context menus can accept either raw `string` values or a structured descriptor object resembling `ContextMenuPredefinedMessage`.
116
+
117
+ ### Message Descriptor Format
118
+
119
+ ```typescript
120
+ interface ContextMenuPredefinedMessage {
121
+ id: string;
122
+ defaultMessage?: string;
123
+ values?: Record<string, string | number>;
124
+ }
125
+ ```
126
+
127
+ ### Integrating custom formatters (e.g., `react-intl`)
128
+
129
+ To route messages through your application's translation engine, pass a `formatMessage` callback to the `WindowManagerProvider`.
130
+
131
+ ```typescript
132
+ import React from 'react';
133
+ import { useIntl } from 'react-intl';
134
+ import { WindowManagerProvider, Desktop } from 'react-dockable-desktop';
135
+
136
+ function App() {
137
+ const intl = useIntl();
138
+
139
+ // Map descriptor payload directly to react-intl formatter
140
+ const handleFormatMessage = (msg: { id: string; defaultMessage?: string; values?: any }) => {
141
+ return intl.formatMessage({ id: msg.id, defaultMessage: msg.defaultMessage }, msg.values);
142
+ };
143
+
144
+ return (
145
+ <WindowManagerProvider formatMessage={handleFormatMessage}>
146
+ <div style={{ width: '100vw', height: '100vh' }}>
147
+ <Desktop />
148
+ </div>
149
+ </WindowManagerProvider>
150
+ );
151
+ }
152
+ ```
153
+
154
+ *If no `formatMessage` function is provided, the engine defaults to a fallback formatting template parser resolving placeholders like `Hello {user}` using values.*
155
+
156
+ ---
157
+
158
+ ## πŸŽ›οΈ Programmatic Spawning and Layout API
159
+
160
+ Consume actions from the layout context anywhere inside or outside your panel components using the provided hooks.
161
+
162
+ ```typescript
163
+ import { useWindowManagerActions, useWindowManagerState } from 'react-dockable-desktop';
164
+
165
+ const SidebarControls = () => {
166
+ const { openPanel, closePanel, saveLayout, loadLayout } = useWindowManagerActions();
167
+ const state = useWindowManagerState();
168
+
169
+ const handleOpenConsole = () => {
170
+ openPanel('debug-console', 'terminal', {
171
+ title: { id: 'app.console', defaultMessage: 'System Console Log' },
172
+ initialTarget: 'floating' // Options: 'docked' | 'floating' | 'tabbed'
173
+ });
174
+ };
175
+
176
+ return (
177
+ <div>
178
+ <button onClick={handleOpenConsole}>Spawn Console</button>
179
+ <button onClick={() => alert(saveLayout())}>Backup Layout</button>
180
+ </div>
181
+ );
182
+ };
183
+ ```
184
+
185
+ ### Hook Reference
186
+
187
+ | Hook Name | Return Type | Description |
188
+ | :--- | :--- | :--- |
189
+ | `useWindowManagerState()` | `WindowState` | Access grid layout trees, list of active floating windows, minimized windows list, and general dragging statuses. |
190
+ | `useWindowManagerActions()` | `WindowActions` | Spawns, minimizes, restores, docks, floats, maximizes, or closes panels. Also handles split sizing, custom locations, and layout serialization (`saveLayout` / `loadLayout`). |
191
+ | `useFormatMessage()` | `(msg: ContextMenuPredefinedMessage) => string` | Returns the translation message formatter hook matching the provider preset configuration. |
192
+ | `usePanelContext()` | `{ publish, subscribe }` | Dynamic decoupled event bus helper for active panels. |
193
+ | `usePanelId()` | `string` | Returns the unique instance ID of the panel calling the hook. |
194
+
195
+ ---
196
+
197
+ ## πŸ›‘οΈ Form Container Context (Close Interception & Dirty States)
198
+
199
+ `react-dockable-desktop` provides a context-driven panel container contract to support dirty form tracking, dynamic title overrides, and close action guards. Child elements can access this container context using the `useFormContainer()` hook.
200
+
201
+ ### Context Hook Functions
202
+
203
+ | Function / Property | Type | Description |
204
+ | :--- | :--- | :--- |
205
+ | `setDirty(dirty)` | `(dirty: boolean) => void` | Marks the container as dirty. An asterisk `*` will be appended to the panel title (in tabs, minimized taskbars, and floating headers). Attempting to close the panel will trigger a confirmation warning modal. |
206
+ | `onCloseRequested(handler)` | `(handler: () => boolean \| Promise<boolean>) => () => void` | Registers an interception handler. When the panel is closed, this function is triggered. If it returns `false`, the closing is cancelled. Returns an unregister cleanup function. |
207
+ | `setTitle(title)` | `(title: string \| ContextMenuPredefinedMessage) => void` | Overrides the tab / window title dynamically from the child element. |
208
+ | `requestClose(options)` | `(options?: { force?: boolean }) => void` | Request the parent panel container to close programmatically. If `force: true` is passed, it closes immediately, bypassing any dirty checks or guards. |
209
+ | `instanceId` | `string` | The unique ID of the panel. |
210
+
211
+ ### Implementation Example
212
+
213
+ ```typescript
214
+ import React, { useState, useEffect } from 'react';
215
+ import { useFormContainer } from 'react-dockable-desktop';
216
+
217
+ const EditFormPanel: React.FC = () => {
218
+ const container = useFormContainer();
219
+ const [text, setText] = useState('');
220
+
221
+ // 1. Mark dirty when typing
222
+ const handleChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {
223
+ setText(e.target.value);
224
+ container.setDirty(true); // Appends '*' to tab header and prompts warning on close
225
+ };
226
+
227
+ const handleSave = () => {
228
+ container.setDirty(false); // Resets dirty state
229
+ alert('Saved successfully!');
230
+ };
231
+
232
+ // 2. Intercept and block closing based on conditions
233
+ useEffect(() => {
234
+ const unregister = container.onCloseRequested(() => {
235
+ if (text.includes('BLOCK')) {
236
+ alert('Cannot close while the word "BLOCK" is present!');
237
+ return false; // Blocks closure
238
+ }
239
+ return true; // Allows closure
240
+ });
241
+ return unregister;
242
+ }, [container, text]);
243
+
244
+ return (
245
+ <div style={{ padding: '1rem', color: '#fff' }}>
246
+ <h5>Dynamic Form Editor</h5>
247
+ <textarea value={text} onChange={handleChange} />
248
+ <button onClick={handleSave}>Save</button>
249
+ <button onClick={() => container.requestClose()}>Cancel & Close</button>
250
+ </div>
251
+ );
252
+ };
253
+ ```
254
+
255
+ ---
256
+
257
+ ## πŸ”Œ Inter-Panel Event Communication Bus
258
+
259
+ Avoid complex state management boilerplate. Active panels can broadcast lightweight messages across the workspace seamlessly:
260
+
261
+ ```typescript
262
+ import React, { useEffect } from 'react';
263
+ import { usePanelContext } from 'react-dockable-desktop';
264
+
265
+ // Subscriber Panel (e.g. Console Log Viewer)
266
+ const ConsoleView: React.FC = () => {
267
+ const { subscribe } = usePanelContext();
268
+
269
+ useEffect(() => {
270
+ const unsubscribe = subscribe('CONSOLE_LOG', (payload) => {
271
+ console.log('Received log message: ', payload.message);
272
+ });
273
+ return () => unsubscribe();
274
+ }, [subscribe]);
275
+
276
+ return <div>Console Viewer</div>;
277
+ };
278
+
279
+ // Publisher Panel (e.g. Map View)
280
+ const MapView: React.FC = () => {
281
+ const { publish } = usePanelContext();
282
+
283
+ const handleInteract = () => {
284
+ publish('CONSOLE_LOG', { message: 'User zoomed map viewport.' });
285
+ };
286
+
287
+ return <button onClick={handleInteract}>Click Map</button>;
288
+ };
289
+ ```
290
+
291
+ ---
292
+
293
+ ## 🎨 Layout Presets & Configuration Options
294
+
295
+ You can customized defaults, positioning attributes, and sizes using the registry builder options:
296
+
297
+ ```typescript
298
+ PanelRegistry.register('unique-panel-key', PanelComponent, {
299
+ title: 'Default Title String', // fallback
300
+ canMinimize: true,
301
+ canDrag: true,
302
+ canClose: true,
303
+ initialTarget: 'docked', // or 'floating'
304
+ favoritePosition: {
305
+ x: 400,
306
+ y: 200,
307
+ width: 500,
308
+ height: 350
309
+ }
310
+ });
311
+ ```
312
+
313
+ To customize CSS layout attributes, you can override variables in your stylesheet:
314
+ ```css
315
+ :root {
316
+ --accent-color: #00f0ff;
317
+ --bg-dark-color: #12131a;
318
+ --glass-bg: rgba(18, 19, 26, 0.65);
319
+ --border-color: rgba(255, 255, 255, 0.08);
320
+ }
321
+ ```
322
+
323
+ ---
324
+
325
+ ## πŸ“„ License
326
+
327
+ MIT. Free to use, adapt, and build upon.
package/dist/index.cjs ADDED
@@ -0,0 +1,2 @@
1
+ var Bt=Object.create;var Ye=Object.defineProperty;var Ht=Object.getOwnPropertyDescriptor;var At=Object.getOwnPropertyNames;var $t=Object.getPrototypeOf,Gt=Object.prototype.hasOwnProperty;var Yt=(n,l)=>{for(var a in l)Ye(n,a,{get:l[a],enumerable:!0})},ut=(n,l,a,h)=>{if(l&&typeof l=="object"||typeof l=="function")for(let S of At(l))!Gt.call(n,S)&&S!==a&&Ye(n,S,{get:()=>l[S],enumerable:!(h=Ht(l,S))||h.enumerable});return n};var Xt=(n,l,a)=>(a=n!=null?Bt($t(n)):{},ut(l||!n||!n.__esModule?Ye(a,"default",{value:n,enumerable:!0}):a,n)),qt=n=>ut(Ye({},"__esModule",{value:!0}),n);var rn={};Yt(rn,{ConfirmationForm:()=>Tt,FormContainerContext:()=>qe,FormContainerProvider:()=>Ie,LeftPanelRenderer:()=>St,ModalStackRenderer:()=>Nt,PanelProvider:()=>It,PanelRegistry:()=>oe,RightPanelRenderer:()=>zt,SidePanelRenderer:()=>Lt,Sidebar:()=>Et,WindowManager:()=>Ct,WindowManagerProvider:()=>yt,defaultPredefinedMessages:()=>ze,formatLabel:()=>Y,useFormContainer:()=>je,useFormatMessage:()=>Ce,usePanelActions:()=>Ee,usePanelContext:()=>bt,usePanelState:()=>Me,usePredefinedMessages:()=>Fe,useStyleClasses:()=>we,useWindowManagerActions:()=>ke,useWindowManagerState:()=>Se});module.exports=qt(rn);var W=Xt(require("react"),1),it=require("react-dom");var C=require("react");var nt=class{registry=new Map;register(l,a,h){this.registry.set(l,{Component:a,defaultOptions:h})}get(l){return this.registry.get(l)}getRegisteredIds(){return Array.from(this.registry.keys())}},oe=new nt;var ze={floatWindow:{id:"dockable-desktop-floatWindow",defaultMessage:"Float Window"},minimizePanel:{id:"dockable-desktop-minimizePanel",defaultMessage:"Minimize Panel"},closeTab:{id:"dockable-desktop-closeTab",defaultMessage:"Close Tab"},restorePanel:{id:"dockable-desktop-restorePanel",defaultMessage:"Restore Panel"},maximizePanel:{id:"dockable-desktop-maximizePanel",defaultMessage:"Maximize Panel"},closePanel:{id:"dockable-desktop-closePanel",defaultMessage:"Close Panel"},dockWindow:{id:"dockable-desktop-dockWindow",defaultMessage:"Dock Window"},minimize:{id:"dockable-desktop-minimize",defaultMessage:"Minimize"},maximize:{id:"dockable-desktop-maximize",defaultMessage:"Maximize"},restoreSize:{id:"dockable-desktop-restoreSize",defaultMessage:"Restore Size"},close:{id:"dockable-desktop-close",defaultMessage:"Close"},closeEmptyGroup:{id:"dockable-desktop-closeEmptyGroup",defaultMessage:"Close empty split group"},anchorToRightEdge:{id:"dockable-desktop-anchorToRightEdge",defaultMessage:"Anchor to Right Edge"},anchorToBottomEdge:{id:"dockable-desktop-anchorToBottomEdge",defaultMessage:"Anchor to Bottom Edge"},windowAnchoringOptions:{id:"dockable-desktop-windowAnchoringOptions",defaultMessage:"Window Anchoring Options"}};var Le=require("react/jsx-runtime"),gt=(0,C.createContext)(null),ft=(0,C.createContext)(null),pt=(0,C.createContext)(null),mt=(0,C.createContext)(ze),ht=(0,C.createContext)({}),we=()=>(0,C.useContext)(ht),ot=class{listeners={};subscribe(l,a){return this.listeners[l]||(this.listeners[l]=[]),this.listeners[l].push(a),()=>{this.listeners[l]=this.listeners[l].filter(h=>h!==a)}}publish(l,a){this.listeners[l]&&this.listeners[l].forEach(h=>h(a))}},jt={type:"branch",orientation:"vertical",sizes:[.75,.25],children:[{type:"leaf",id:"group-left-top",panels:["main-map","main-editor"],activePanelId:"main-map"},{type:"leaf",id:"group-left-bottom",panels:["system-console","help-docs"],activePanelId:"system-console"}]},Kt={"main-map":{id:"main-map",title:"Main Map",component:"mainMap",state:"docked"},"main-editor":{id:"main-editor",title:"Code Editor",component:"editor",state:"docked"},"system-console":{id:"system-console",title:"Console Output",component:"terminal",state:"docked"},"help-docs":{id:"help-docs",title:"Help Center",component:"help",state:"docked"},"live-preview":{id:"live-preview",title:"Live Preview Output",component:"preview",state:"floating"}},Ut=[{id:"live-preview",x:450,y:200,width:320,height:250,z:1e3}],yt=({children:n,formatMessage:l,predefinedMessages:a,modalClass:h,modalBodyClass:S,sidePanelClass:w,sidePanelBodyClass:E,windowClass:D,windowBodyClass:b})=>{let[M,y]=(0,C.useState)({gridRoot:jt,floating:Ut,minimized:[],panels:Kt,draggedPanelId:null,pendingClose:null}),f=(0,C.useRef)(M);f.current=M;let m=(0,C.useRef)({}),R=(0,C.useMemo)(()=>({...ze,...a}),[a]),A=(0,C.useRef)(new ot),v=(0,C.useRef)(1e3),u=(0,C.useCallback)((e,s)=>A.current.subscribe(e,s),[]),x=(0,C.useCallback)((e,s)=>{A.current.publish(e,s)},[]),I=(0,C.useCallback)((e,s)=>{let o=typeof e.x=="string"?parseFloat(e.x):e.x,r=typeof e.y=="string"?parseFloat(e.y):e.y,i=typeof e.width=="string"?parseFloat(e.width):e.width,t=typeof e.height=="string"?parseFloat(e.height):e.height;isNaN(o)&&(o=300),isNaN(r)&&(r=150),isNaN(i)&&(i=450),isNaN(t)&&(t=350);let c=H=>s.some(O=>{let k=typeof O.x=="string"?parseFloat(O.x):O.x,T=typeof O.y=="string"?parseFloat(O.y):O.y;return!O.maximized&&Math.abs(k-H.x)<20&&Math.abs(T-H.y)<20}),g=0;for(;c({x:o,y:r})&&g<10;)o+=30,r+=30,g++;let P=Math.max(100,window.innerWidth||1024),z=Math.max(100,window.innerHeight||768);return(o+i>P||r+t>z)&&(o=100+g%5*30,r=100+g%5*30),o=Math.max(0,Math.min(o,P-100)),r=Math.max(0,Math.min(r,z-40)),{x:o,y:r,width:i,height:t}},[]),F=(0,C.useCallback)(e=>{v.current+=1;let s=v.current;y(o=>{let r=o.panels[e];if(!r)return o;if(r.state==="floating")return{...o,floating:o.floating.map(i=>i.id===e?{...i,z:s}:i)};if(r.state==="docked"){let i=t=>t.type==="leaf"?t.panels.includes(e)?{...t,activePanelId:e}:t:{...t,children:t.children.map(i)};return{...o,gridRoot:i(o.gridRoot)}}return o})},[]),p=(e,s)=>{if(e.type==="leaf"){let o=e.panels.indexOf(s);if(o===-1)return e;let r=e.panels.filter(c=>c!==s),i=e.activePanelId===s?r[o]||r[o-1]||r[0]||null:e.activePanelId,t={...e,panels:r,activePanelId:i};return r.length===0&&!e.keepOnEmpty?null:t}else{let o=e.children.map(t=>p(t,s)).filter(t=>t!==null);if(o.length===0)return null;if(o.length===1)return o[0];let r=e.sizes.slice(0,o.length),i=r.reduce((t,c)=>t+c,0);return{...e,children:o,sizes:r.map(t=>t/i)}}},N=(e,s,o)=>{if(e.type==="leaf"){if(e.id===s){let r=e.panels.includes(o)?e.panels:[...e.panels,o];return{...e,panels:r,activePanelId:o}}return e}else return{...e,children:e.children.map(r=>N(r,s,o))}},L=e=>{if(e.type==="leaf")return e.id;for(let s of e.children){let o=L(s);if(o)return o}return null},B=(0,C.useCallback)((e,s,o)=>{y(r=>{let i=r.panels[e],t=oe.get(s),c=o?.title||o?.title||t?.defaultOptions?.title||e,g=o?.initialTarget||t?.defaultOptions?.initialTarget||"docked",P=t?.defaultOptions?.favoritePosition||{x:300,y:150,width:450,height:350};if(i)if(i.state==="minimized"){let k=r.minimized.filter(T=>T.id!==e);if(g==="floating"||!r.gridRoot){v.current+=1;let T=I(P,r.floating);return{...r,minimized:k,floating:[...r.floating,{...T,id:e,z:v.current}],panels:{...r.panels,[e]:{...i,state:"floating"}}}}else{let T=L(r.gridRoot)||"group-left-top";return{...r,minimized:k,gridRoot:N(r.gridRoot,T,e),panels:{...r.panels,[e]:{...i,state:"docked"}}}}}else{if(i.state==="floating")return F(e),r;{let k=T=>T.type==="leaf"?T.panels.includes(e)?{...T,activePanelId:e}:T:{...T,children:T.children.map(k)};return{...r,gridRoot:k(r.gridRoot)}}}let H={id:e,title:c,component:s,state:g==="tabbed"?"docked":g},O={...r.panels,[e]:H};if(g==="floating"){v.current+=1;let k=I(P,r.floating),T=o?.stickyRight??t?.defaultOptions?.defaultStickyRight??!1,U=o?.stickyBottom??t?.defaultOptions?.defaultStickyBottom??!1,j=Math.max(100,window.innerWidth||1024),Z=Math.max(100,window.innerHeight||768),te=typeof k.width=="string"?parseFloat(k.width):k.width,pe=typeof k.height=="string"?parseFloat(k.height):k.height,me=k.x,xe=k.y,Ne=10;return T&&(me=j-te-Ne),U&&(xe=Z-pe-Ne),{...r,floating:[...r.floating,{...k,id:e,z:v.current,x:me,y:xe,stickyRight:T,stickyBottom:U}],panels:O}}else{let k=L(r.gridRoot)||"group-left-top";return{...r,gridRoot:N(r.gridRoot,k,e),panels:O}}})},[I,F]),$=(0,C.useCallback)(e=>{y(s=>{let o=s.panels[e];if(!o||oe.get(o.component)?.defaultOptions?.canClose===!1)return s;delete m.current[e];let i={...s.panels};delete i[e];let t=p(s.gridRoot,e);return{...s,gridRoot:t||{type:"leaf",id:"group-default",panels:[],activePanelId:null},floating:s.floating.filter(c=>c.id!==e),minimized:s.minimized.filter(c=>c.id!==e),panels:i}})},[]),X=(0,C.useCallback)((e,s)=>{m.current[e]=s},[]),ue=(0,C.useCallback)(e=>{delete m.current[e]},[]),ee=(0,C.useCallback)((e,s)=>{y(o=>{let r=o.panels[e];return r?{...o,panels:{...o.panels,[e]:{...r,dirty:s}}}:o})},[]),se=(0,C.useCallback)((e,s)=>{y(o=>{let r=o.panels[e];return r?{...o,panels:{...o.panels,[e]:{...r,title:s}}}:o})},[]),le=(0,C.useCallback)(e=>{y(s=>s.pendingClose?(s.pendingClose.resolve(e),{...s,pendingClose:null}):s)},[]),re=(0,C.useCallback)(async(e,s)=>{if(s?.force){$(e);return}let o=m.current[e];o&&!await o()||f.current.panels[e]?.dirty&&!await new Promise(t=>{y(c=>({...c,pendingClose:{id:e,resolve:t}}))})||$(e)},[$]),ge=(0,C.useCallback)(e=>{y(s=>{let o=s.panels[e];if(!o||o.state==="minimized"||oe.get(o.component)?.defaultOptions?.canMinimize===!1)return s;let i,t;if(o.state==="floating"){let g=s.floating.find(P=>P.id===e);g&&(i={x:g.x,y:g.y,width:g.width,height:g.height,stickyRight:g.stickyRight,stickyBottom:g.stickyBottom})}else if(o.state==="docked"){let g=P=>{if(P.type==="leaf")return P.panels.includes(e)?P.id:null;for(let z of P.children){let H=g(z);if(H)return H}return null};t=g(s.gridRoot)}let c=p(s.gridRoot,e);return{...s,gridRoot:c||{type:"leaf",id:"group-default",panels:[],activePanelId:null},floating:s.floating.filter(g=>g.id!==e),minimized:[...s.minimized,{id:e,title:o.title,component:o.component}],panels:{...s.panels,[e]:{...o,state:"minimized",previousState:o.state,lastFloatingRect:i,lastLeafId:t}}}})},[]),ve=(0,C.useCallback)(e=>{y(s=>{let o=s.panels[e];if(!o||o.state!=="minimized")return s;let r=s.minimized.filter(t=>t.id!==e);if((o.previousState||"docked")==="floating"){v.current+=1;let t=oe.get(o.component),c=o.lastFloatingRect||t?.defaultOptions?.favoritePosition||{x:300,y:150,width:450,height:350},g=I(c,s.floating);return{...s,minimized:r,floating:[...s.floating,{...g,id:e,z:v.current,stickyRight:!!o.lastFloatingRect?.stickyRight,stickyBottom:!!o.lastFloatingRect?.stickyBottom}],panels:{...s.panels,[e]:{...o,state:"floating"}}}}else{let t=(z,H)=>z.type==="leaf"?z.id===H:z.children.some(O=>t(O,H)),c=o.lastLeafId&&t(s.gridRoot,o.lastLeafId),g=oe.get(o.component),P=g?.defaultOptions?.canDrag!==!1;if(c)return{...s,minimized:r,gridRoot:N(s.gridRoot,o.lastLeafId,e),panels:{...s.panels,[e]:{...o,state:"docked"}}};if(P){v.current+=1;let z=o.lastFloatingRect||g?.defaultOptions?.favoritePosition||{x:300,y:150,width:450,height:350},H=I(z,s.floating);return{...s,minimized:r,floating:[...s.floating,{...H,id:e,z:v.current,stickyRight:!!o.lastFloatingRect?.stickyRight,stickyBottom:!!o.lastFloatingRect?.stickyBottom}],panels:{...s.panels,[e]:{...o,state:"floating"}}}}else{let z=L(s.gridRoot)||"group-left-top";return{...s,minimized:r,gridRoot:N(s.gridRoot,z,e),panels:{...s.panels,[e]:{...o,state:"docked"}}}}}})},[I]),he=(0,C.useCallback)((e,s)=>{y(o=>{let r=o.panels[e];if(!r||oe.get(r.component)?.defaultOptions?.canDrag===!1)return o;let t=oe.get(r.component),c=s||t?.defaultOptions?.favoritePosition||{x:300,y:150,width:450,height:350},g=p(o.gridRoot,e);v.current+=1;let P=I(c,o.floating);return{...o,gridRoot:g||{type:"leaf",id:"group-default",panels:[],activePanelId:null},floating:[...o.floating,{...P,id:e,z:v.current}],panels:{...o.panels,[e]:{...r,state:"floating"}}}})},[I]),fe=(0,C.useCallback)((e,s)=>{y(o=>{let r=o.panels[e];if(!r)return o;let i=o.floating.filter(g=>g.id!==e),t=p(o.gridRoot,e),c=s||L(t||o.gridRoot)||"group-left-top";return{...o,gridRoot:N(t||o.gridRoot,c,e),floating:i,panels:{...o.panels,[e]:{...r,state:"docked"}}}})},[]),ye=(e,s,o,r)=>{if(e.type==="leaf"){if(e.id===s){let i={type:"leaf",id:`group-split-${Date.now()}-${Math.floor(Math.random()*1e3)}`,panels:[o],activePanelId:o};return{type:"branch",orientation:r==="left"||r==="right"?"horizontal":"vertical",sizes:[.5,.5],children:r==="left"||r==="top"?[i,e]:[e,i]}}return e}else return{...e,children:e.children.map(i=>ye(i,s,o,r))}},ne=(0,C.useCallback)(e=>{y(s=>({...s,draggedPanelId:e}))},[]),be=(0,C.useCallback)((e,s,o)=>{y(r=>{let i=r.panels[e];if(!i)return r;let t=r.floating.filter(P=>P.id!==e),c=p(r.gridRoot,e),g;return o==="center"?g=N(c||r.gridRoot,s,e):g=ye(c||r.gridRoot,s,e,o),{...r,gridRoot:g,floating:t,panels:{...r.panels,[e]:{...i,state:"docked"}},draggedPanelId:null}})},[]),q=(0,C.useCallback)((e,s)=>{y(o=>{let r=o.panels[e];if(!r)return o;let i=o.floating.filter(H=>H.id!==e),t=p(o.gridRoot,e),c={type:"leaf",id:`group-edge-${Date.now()}-${Math.floor(Math.random()*1e3)}`,panels:[e],activePanelId:e},g=s==="left"||s==="right"?"horizontal":"vertical",P=s==="left"||s==="top"?[c,t||o.gridRoot]:[t||o.gridRoot,c];return{...o,gridRoot:{type:"branch",orientation:g,sizes:s==="left"||s==="top"?[.3,.7]:[.7,.3],children:P},floating:i,panels:{...o.panels,[e]:{...r,state:"docked"}},draggedPanelId:null}})},[]),G=(0,C.useCallback)((e,s,o)=>{y(r=>{let i=r.panels[e];if(!i)return r;let t=p(r.gridRoot,e),c=z=>{if(z.type==="leaf"){if(z.id===s){let H=z.panels.filter(T=>T!==e),O=Math.max(0,Math.min(o,H.length)),k=[...H];return k.splice(O,0,e),{...z,panels:k,activePanelId:e}}return z}else return{...z,children:z.children.map(c)}},g=c(t||r.gridRoot),P=r.floating.filter(z=>z.id!==e);return{...r,gridRoot:g,floating:P,panels:{...r.panels,[e]:{...i,state:"docked"}},draggedPanelId:null}})},[]),Re=(0,C.useCallback)(e=>{y(s=>{let o=i=>{if(i.type==="leaf")return i.id===e&&i.canClose!==!1?null:i;{let t=i.children.map(P=>o(P)).filter(P=>P!==null);if(t.length===0)return null;if(t.length===1)return t[0];let c=i.sizes.slice(0,t.length),g=c.reduce((P,z)=>P+z,0);return{...i,children:t,sizes:c.map(P=>P/g)}}},r=o(s.gridRoot);return{...s,gridRoot:r||{type:"leaf",id:"group-default",panels:[],activePanelId:null}}})},[]),He=(0,C.useCallback)(e=>{y(s=>({...s,floating:s.floating.map(o=>o.id===e?{...o,maximized:!o.maximized}:o)}))},[]),Ae=(0,C.useCallback)((e,s)=>{let o=(r,i)=>{if(r.type==="leaf")return r;if(i===e.length)return{...r,sizes:s};let t=e[i],c=r.children.map((g,P)=>P===t?o(g,i+1):g);return{...r,children:c}};y(r=>({...r,gridRoot:o(r.gridRoot,0)}))},[]),$e=(0,C.useCallback)((e,s)=>{y(o=>({...o,floating:o.floating.map(r=>r.id===e?{...r,...s}:r)}))},[]),Ge=(0,C.useCallback)(()=>JSON.stringify({gridRoot:M.gridRoot,floating:M.floating,minimized:M.minimized,panels:M.panels}),[M]),We=(0,C.useCallback)(e=>{try{let s=JSON.parse(e);s.gridRoot&&s.floating&&s.minimized&&s.panels&&y({gridRoot:s.gridRoot,floating:s.floating,minimized:s.minimized,panels:s.panels,draggedPanelId:null,pendingClose:null})}catch(s){console.error("Failed to parse layout configuration:",s)}},[]),Pe=(0,C.useMemo)(()=>({openPanel:B,closePanel:$,minimizePanel:ge,restorePanel:ve,floatPanel:he,dockPanel:fe,maximizePanel:He,updateSplitSizes:Ae,updateFloatingPosition:$e,bringToFront:F,saveLayout:Ge,loadLayout:We,publish:x,subscribe:u,setDraggedPanelId:ne,dockPanelToGroup:be,movePanelOrder:G,closeLeafGroup:Re,registerCloseGuard:X,unregisterCloseGuard:ue,setPanelDirty:ee,updatePanelTitle:se,requestClosePanel:re,resolvePendingClose:le,dockPanelToWorkspaceEdge:q}),[B,$,ge,ve,he,fe,He,Ae,$e,F,Ge,We,x,u,ne,be,G,Re,X,ue,ee,se,re,le,q]),Ve=e=>{let s=e.defaultMessage||e.id;return e.values&&Object.entries(e.values).forEach(([o,r])=>{s=s.replace(`{${o}}`,String(r))}),s},_e=(0,C.useMemo)(()=>({modalClass:h,modalBodyClass:S,sidePanelClass:w,sidePanelBodyClass:E,windowClass:D,windowBodyClass:b}),[h,S,w,E,D,b]);return(0,Le.jsx)(ht.Provider,{value:_e,children:(0,Le.jsx)(gt.Provider,{value:M,children:(0,Le.jsx)(ft.Provider,{value:Pe,children:(0,Le.jsx)(pt.Provider,{value:l||Ve,children:(0,Le.jsx)(mt.Provider,{value:R,children:n})})})})})},Se=()=>{let n=(0,C.useContext)(gt);if(!n)throw new Error("useWindowManagerState must be used within WindowManagerProvider");return n},ke=()=>{let n=(0,C.useContext)(ft);if(!n)throw new Error("useWindowManagerActions must be used within WindowManagerProvider");return n},Ce=()=>(0,C.useContext)(pt)||(l=>{let a=l.defaultMessage||l.id;return l.values&&Object.entries(l.values).forEach(([h,S])=>{a=a.replace(`{${h}}`,String(S))}),a}),Y=(n,l)=>n?typeof n=="string"?n:l(n):"",bt=()=>{let{publish:n,subscribe:l}=ke();return{publish:n,subscribe:l}},Fe=()=>(0,C.useContext)(mt);var vt=require("replace-react-contexify"),vn=require("replace-react-contexify/styles.css");var Xe=require("react"),Jt={requestClose:()=>{console.warn("FormContainerContract: requestClose called but no container is present")},setDirty:()=>{},onCloseRequested:()=>()=>{},setTitle:()=>{},setIcon:()=>{},containerType:"standalone",instanceId:"standalone",onClose:()=>()=>{},onMinimize:()=>()=>{},onRestore:()=>()=>{},onResize:()=>()=>{}},qe=(0,Xe.createContext)(Jt),Ie=qe.Provider,je=()=>(0,Xe.useContext)(qe);var d=require("react/jsx-runtime"),De=new Map,Ue="preserved-dom-container",st=(0,d.jsxs)("svg",{width:"14",height:"14",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",style:{display:"block"},children:[(0,d.jsx)("rect",{x:"3",y:"3",width:"7",height:"9",rx:"1"}),(0,d.jsx)("rect",{x:"14",y:"3",width:"7",height:"5",rx:"1"}),(0,d.jsx)("rect",{x:"14",y:"12",width:"7",height:"9",rx:"1"}),(0,d.jsx)("rect",{x:"3",y:"16",width:"7",height:"5",rx:"1"})]}),Pt=n=>{let l=De.get(n);return l||(l=document.createElement("div"),l.style.width="100%",l.style.height="100%",De.set(n,l)),l},Zt=(n,l)=>{let a=oe.get(l);if(!a)return(0,d.jsxs)("div",{className:"w-100 h-100 d-flex flex-column align-items-center justify-content-center bg-transparent text-danger font-monospace p-3 text-center",style:{border:"2px dashed var(--bs-danger, #dc3545)"},children:[(0,d.jsx)("h6",{className:"fw-bold mb-1",children:"\u26A0\uFE0F Component Unregistered"}),(0,d.jsxs)("span",{className:"small text-muted",children:["Key: ",l]})]});let h=a.Component;return(0,d.jsx)(h,{panelId:n})},at=new Map,Te=new Map,Ke=n=>{let l=Te.get(n);return l||(l={onClose:new Set,onMinimize:new Set,onRestore:new Set,onResize:new Set},Te.set(n,l)),l},xt=({panelId:n})=>{let l=(0,W.useRef)(null);return(0,W.useEffect)(()=>{let a=l.current;if(!a)return;let h=Pt(n);a.appendChild(h);let S=new ResizeObserver(w=>{for(let E of w){let{width:D,height:b}=E.contentRect;if(D>0&&b>0){at.set(n,{width:D,height:b});let M=Te.get(n);M&&M.onResize.forEach(y=>y(D,b))}}});return S.observe(a),()=>{S.disconnect();let w=document.getElementById(Ue);w||(w=document.createElement("div"),w.id=Ue,w.style.display="none",document.body.appendChild(w)),w.appendChild(h)}},[n]),(0,d.jsx)("div",{ref:l,className:"w-100 h-100"})},Qt=({panelId:n})=>{let l=Se(),a=(0,W.useRef)(null),h=l.panels[n],S=h?oe.get(h.component):null,w=S?.defaultOptions?.disableLivePreview||!1,[E,D]=(0,W.useState)({width:800,height:500,scale:.25});if((0,W.useEffect)(()=>{if(w)return;let b=a.current;if(!b)return;let M=De.get(n);if(!M)return;let y=at.get(n)||{width:800,height:500},f=y.width,m=y.height,v=Math.min(220/f,140/m);return D({width:f,height:m,scale:v}),b.appendChild(M),()=>{let u=document.getElementById(Ue);u||(u=document.createElement("div"),u.id=Ue,u.style.display="none",document.body.appendChild(u)),u.appendChild(M)}},[n,w]),w){let b=at.get(n)||{width:800,height:500},f=Math.min(220/b.width,140/b.height),m=b.width*f,R=b.height*f,A=S?.defaultOptions?.icon||(0,d.jsx)("span",{children:"\u{1F533}"});return(0,d.jsxs)("div",{className:"taskbar-item-preview-frame d-flex flex-column align-items-center justify-content-center text-muted",style:{width:`${m}px`,height:`${R}px`,background:"linear-gradient(135deg, rgba(30, 41, 59, 0.9) 0%, rgba(15, 23, 42, 0.95) 100%)",border:"1px dashed var(--taskbar-item-border, rgba(255, 255, 255, 0.15))"},children:[(0,d.jsx)("div",{className:"taskbar-preview-placeholder-icon mb-1.5",style:{transform:"scale(1.2)",filter:"drop-shadow(0 0 8px rgba(56, 189, 248, 0.4))"},children:A}),(0,d.jsx)("div",{style:{fontSize:"9px",fontWeight:500,letterSpacing:"0.5px",opacity:.7,textTransform:"uppercase"},children:"Active Session"})]})}return(0,d.jsx)("div",{className:"taskbar-item-preview-frame",style:{width:`${E.width*E.scale}px`,height:`${E.height*E.scale}px`},children:(0,d.jsx)("div",{ref:a,className:"taskbar-item-preview-host",style:{width:`${E.width}px`,height:`${E.height}px`,transform:`scale(${E.scale})`,transformOrigin:"top left",position:"absolute",top:0,left:0}})})},Vt=({panelId:n,children:l})=>{let a=Se(),{requestClosePanel:h,setPanelDirty:S,registerCloseGuard:w,unregisterCloseGuard:E,updatePanelTitle:D}=ke(),b=a.minimized.some(f=>f.id===n),M=(0,W.useRef)(b);(0,W.useEffect)(()=>{let f=Te.get(n);f&&(b&&!M.current?f.onMinimize.forEach(m=>m()):!b&&M.current&&f.onRestore.forEach(m=>m()),M.current=b)},[b,n]),(0,W.useEffect)(()=>()=>{let f=Te.get(n);f&&(f.onClose.forEach(m=>m()),Te.delete(n))},[n]);let y=W.default.useMemo(()=>({requestClose:f=>h(n,f),setDirty:f=>S(n,f),onCloseRequested:f=>(w(n,f),()=>E(n)),setTitle:f=>D(n,f),instanceId:n,onClose:f=>{let m=Ke(n);return m.onClose.add(f),()=>m.onClose.delete(f)},onMinimize:f=>{let m=Ke(n);return m.onMinimize.add(f),()=>m.onMinimize.delete(f)},onRestore:f=>{let m=Ke(n);return m.onRestore.add(f),()=>m.onRestore.delete(f)},onResize:f=>{let m=Ke(n);return m.onResize.add(f),()=>m.onResize.delete(f)}}),[n,h,S,w,E,D]);return(0,d.jsx)(Ie,{value:y,children:l})},wt=({node:n,path:l,onTabRightClick:a,activeDropZone:h,onHoverDropZone:S,onTabDragStart:w,hoveredTab:E,onTabHover:D,defaultPanelIcon:b})=>{let{updateSplitSizes:M}=ke();if(n.type==="leaf")return(0,d.jsx)(_t,{leaf:n,onTabRightClick:a,activeDropZone:h,onHoverDropZone:S,onTabDragStart:w,hoveredTab:E,onTabHover:D,defaultPanelIcon:b});let y=n.orientation==="horizontal",f=(m,R)=>{R.preventDefault();let A=y?R.clientX:R.clientY,v=[...n.sizes],u=R.currentTarget.parentElement,x=u?y?u.clientWidth:u.clientHeight:y?1e3:800,I=p=>{let B=((y?p.clientX:p.clientY)-A)/x,$=[...v];$[m]+=B,$[m+1]-=B,$[m]>.1&&$[m+1]>.1&&M(l,$)},F=()=>{window.removeEventListener("mousemove",I),window.removeEventListener("mouseup",F)};window.addEventListener("mousemove",I),window.addEventListener("mouseup",F)};return(0,d.jsx)("div",{className:`d-flex w-100 h-100 ${y?"flex-row":"flex-column"}`,style:{overflow:"hidden",position:"relative"},children:n.children.map((m,R)=>{let A=n.sizes[R]*100;return(0,d.jsxs)(W.default.Fragment,{children:[(0,d.jsx)("div",{style:{flexGrow:n.sizes[R],flexBasis:`${A}%`,overflow:"hidden",position:"relative"},children:(0,d.jsx)(wt,{node:m,path:[...l,R],onTabRightClick:a,activeDropZone:h,onHoverDropZone:S,onTabDragStart:w,hoveredTab:E,onTabHover:D,defaultPanelIcon:b})}),R<n.children.length-1&&(0,d.jsx)("div",{onMouseDown:v=>f(R,v),style:{cursor:y?"col-resize":"row-resize",width:y?"6px":"100%",height:y?"100%":"6px",backgroundColor:"var(--resizer-bg)",zIndex:20,transition:"background-color 0.2s"},className:"resizer-bar hover-highlight"})]},R)})})},_t=({leaf:n,onTabRightClick:l,activeDropZone:a,onHoverDropZone:h,onTabDragStart:S,hoveredTab:w,onTabHover:E,defaultPanelIcon:D})=>{let b=Se(),{requestClosePanel:M,openPanel:y,closeLeafGroup:f}=ke(),m=Ce(),R=Fe(),{windowClass:A,windowBodyClass:v}=we(),u=x=>{y(x,b.panels[x].component)};return(0,d.jsxs)("div",{className:`workspace-panel w-100 h-100 d-flex flex-column ${A??""}`,style:{overflow:"hidden",position:"relative"},children:[(0,d.jsxs)("div",{className:"workspace-tab-bar d-flex flex-row justify-content-between align-items-center",style:{minHeight:"38px"},children:[(0,d.jsx)("div",{className:"d-flex flex-row overflow-x-auto flex-grow-1 tab-headers-container",style:{scrollbarWidth:"none"},onMouseMove:x=>{b.draggedPanelId&&x.target===x.currentTarget&&E(n.id,"EMPTY",n.panels.length,"right")},onMouseLeave:x=>{b.draggedPanelId&&x.target===x.currentTarget&&E(n.id,"",-1,null)},children:n.panels.map((x,I)=>{let F=b.panels[x];if(!F)return null;let p=n.activePanelId===x,L=oe.get(F.component)?.defaultOptions,B=w&&w.leafId===n.id&&w.panelId===x,$=I===n.panels.length-1,X=w&&w.leafId===n.id&&w.panelId==="EMPTY"&&$,ue=B?w.side==="left"?"drag-hover-left":"drag-hover-right":X?"drag-hover-right":"";return(0,d.jsxs)("div",{onClick:()=>u(x),onMouseDown:ee=>{L?.canDrag!==!1&&S(x,ee)},onContextMenu:ee=>l(x,ee),onMouseMove:ee=>{if(b.draggedPanelId){let se=ee.currentTarget.getBoundingClientRect(),re=ee.clientX-se.left<se.width/2?"left":"right";E(n.id,x,I,re)}},onMouseLeave:()=>{b.draggedPanelId&&E(n.id,"",-1,null)},className:`workspace-tab ${p?"active workspace-tab-active":"workspace-tab-inactive"} ${ue}`,style:{cursor:L?.canDrag===!1?"default":"pointer"},children:[(0,d.jsxs)("span",{className:"text-truncate d-flex align-items-center",style:{maxWidth:"120px"},children:[(0,d.jsx)("span",{className:"workspace-tab-icon",children:L?.icon||D||st}),(0,d.jsxs)("span",{children:[Y(F.title,m),F.dirty?" *":""]})]}),L?.canClose!==!1&&(0,d.jsx)("span",{onClick:ee=>{ee.stopPropagation(),M(x)},title:Y(R.closeTab,m),className:"close-tab-x ms-auto d-flex align-items-center justify-content-center",style:{width:"18px",height:"18px"},children:(0,d.jsx)("svg",{width:"12",height:"12",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2.5",children:(0,d.jsx)("path",{d:"M18 6L6 18M6 6l12 12"})})})]},x)})}),n.panels.length===0&&n.keepOnEmpty&&n.canClose!==!1&&(0,d.jsx)("span",{onClick:()=>f(n.id),className:"close-tab-x d-flex align-items-center justify-content-center me-2 header-close-empty-group",style:{width:"18px",height:"18px",cursor:"pointer"},title:Y(R.closeEmptyGroup,m),children:(0,d.jsx)("svg",{width:"12",height:"12",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2.5",children:(0,d.jsx)("path",{d:"M18 6L6 18M6 6l12 12"})})})]}),(0,d.jsxs)("div",{className:`flex-grow-1 w-100 h-100 bg-transparent ${v??""}`,style:{position:"relative",overflow:"hidden"},children:[n.activePanelId&&b.panels[n.activePanelId]?(0,d.jsx)(xt,{panelId:n.activePanelId},n.activePanelId):(0,d.jsx)("div",{className:"w-100 h-100 d-flex align-items-center justify-content-center font-monospace text-muted small empty-leaf-placeholder",children:(0,d.jsx)("span",{children:"Empty Workspace Section"})}),b.draggedPanelId!==null&&(0,d.jsx)("div",{className:"dock-drop-zone-overlay",children:(0,d.jsxs)("div",{className:"dock-target-cross",children:[(0,d.jsx)("div",{onMouseEnter:()=>h(n.id,"top"),onMouseLeave:()=>h(n.id,null),className:"dock-target-box dock-target-top",children:"\u25B2"}),(0,d.jsx)("div",{onMouseEnter:()=>h(n.id,"bottom"),onMouseLeave:()=>h(n.id,null),className:"dock-target-box dock-target-bottom",children:"\u25BC"}),(0,d.jsx)("div",{onMouseEnter:()=>h(n.id,"left"),onMouseLeave:()=>h(n.id,null),className:"dock-target-box dock-target-left",children:"\u25C0"}),(0,d.jsx)("div",{onMouseEnter:()=>h(n.id,"right"),onMouseLeave:()=>h(n.id,null),className:"dock-target-box dock-target-right",children:"\u25B6"}),(0,d.jsx)("div",{onMouseEnter:()=>h(n.id,"center"),onMouseLeave:()=>h(n.id,null),className:"dock-target-box dock-target-center",children:"\u25A3"})]})}),b.draggedPanelId!==null&&a!==null&&a.leafId===n.id&&(0,d.jsx)("div",{className:"dock-preview-highlight",style:{left:a.position==="right"?"50%":"0",top:a.position==="bottom"?"50%":"0",width:a.position==="left"||a.position==="right"?"50%":"100%",height:a.position==="top"||a.position==="bottom"?"50%":"100%"}})]})]})},en=({skin:n="vscode",defaultPanelIcon:l})=>{let a=Se(),{restorePanel:h,minimizePanel:S,requestClosePanel:w,resolvePendingClose:E,maximizePanel:D,updateFloatingPosition:b,bringToFront:M,floatPanel:y,setDraggedPanelId:f,dockPanelToGroup:m,movePanelOrder:R,dockPanelToWorkspaceEdge:A}=ke(),v=Ce(),u=Fe(),{windowClass:x,windowBodyClass:I}=we(),[F,p]=(0,W.useState)([]),N=(0,W.useRef)(null),L=(0,W.useRef)(null),[B,$]=(0,W.useState)(null),X=(0,W.useRef)(null),[ue,ee]=(0,W.useState)(!1);(0,W.useEffect)(()=>()=>{X.current&&clearTimeout(X.current)},[]);let[se,le]=(0,W.useState)(null),re=(0,W.useRef)(null),[ge,ve]=(0,W.useState)({x:0,y:0}),[he,fe]=(0,W.useState)(null),ye=(0,W.useRef)(null),ne=i=>{fe(i),ye.current=i},[be,q]=(0,W.useState)(null),G=(0,W.useRef)(null),Re=(i,t,c,g)=>{let P=g?{leafId:i,panelId:t,index:c,side:g}:null;q(P),G.current=P},He=(i,t)=>{let c=t?{leafId:i,position:t}:null;le(c),re.current=c},Ae=(i,t)=>{if(t.button!==0)return;let c=t.clientX,g=t.clientY,P=!1,z=k=>{let T=k.clientX-c,U=k.clientY-g;!P&&(Math.abs(T)>5||Math.abs(U)>5)&&(P=!0,f(i)),P&&ve({x:k.clientX,y:k.clientY})},H=k=>{if(window.removeEventListener("mousemove",z),window.removeEventListener("mouseup",O),P){let T=re.current,U=G.current,j=ye.current;if(j)A(i,j);else if(U){let Z=U.index;U.side==="right"&&(Z+=1),R(i,U.leafId,Z)}else T?m(i,T.leafId,T.position):y(i,{x:k.clientX-150,y:k.clientY-15,width:450,height:350});f(null),le(null),re.current=null,q(null),G.current=null,ne(null)}},O=k=>{H(k)};window.addEventListener("mousemove",z),window.addEventListener("mouseup",O)},$e=(i,t)=>{t.preventDefault();let c=a.panels[i];if(!c)return;let P=oe.get(c.component)?.defaultOptions,z=[];P?.canDrag!==!1&&z.push({label:Y(u.floatWindow,v),action:()=>y(i)}),P?.canMinimize!==!1&&z.push({label:Y(u.minimizePanel,v),action:()=>S(i)}),z.length>0&&P?.canClose!==!1&&z.push({separator:!0}),P?.canClose!==!1&&z.push({label:Y(u.closeTab,v),action:()=>w(i)}),z.length!==0&&L.current?.show({event:t,contextMenu:{items:z}})},Ge=(i,t)=>{t.preventDefault(),$(null),L.current?.show({event:t,contextMenu:{items:[{label:Y(u.restorePanel,v),action:()=>h(i)},{label:Y(u.maximizePanel,v),action:()=>D(i)},{separator:!0},{label:Y(u.closePanel,v),action:()=>w(i)}]}})};(0,W.useEffect)(()=>{let i=Object.keys(a.panels);p(i);for(let t of Array.from(De.keys()))i.includes(t)||De.delete(t)},[a.panels]),(0,W.useEffect)(()=>{let i=()=>{a.draggedPanelId!==null&&(f(null),le(null),q(null))};return window.addEventListener("blur",i),()=>{window.removeEventListener("blur",i)}},[a.draggedPanelId]);let We=(0,W.useRef)(null),[Pe,Ve]=(0,W.useState)({width:1024,height:768});(0,W.useEffect)(()=>{let i=We.current;if(!i)return;let t=new ResizeObserver(c=>{if(!c||c.length===0)return;let g=c[0].contentRect;Ve({width:Math.max(100,g.width),height:Math.max(100,g.height)})});return t.observe(i),()=>{t.disconnect()}},[]),(0,W.useEffect)(()=>{let i=Pe.width,t=Pe.height;a.floating.forEach(c=>{let g=typeof c.width=="string"?parseFloat(c.width):c.width,P=typeof c.height=="string"?parseFloat(c.height):c.height,z=typeof c.x=="string"?parseFloat(c.x):c.x,H=typeof c.y=="string"?parseFloat(c.y):c.y,O=g,k=P,T=z,U=H,j=!1;O>i&&(O=Math.max(200,i-20),j=!0),k>t&&(k=Math.max(150,t-40),j=!0);let Z=10;if(c.stickyRight)T=i-O-Z,j=!0;else{let te=i-100;T>te&&(T=Math.max(0,te),j=!0)}if(c.stickyBottom)U=t-k-Z,j=!0;else{let te=t-40;U>te&&(U=Math.max(0,te),j=!0)}j&&b(c.id,{x:T,y:U,width:O,height:k})})},[Pe,a.floating,b]),(0,W.useEffect)(()=>{let i=t=>{if(t.button!==0)return;let c=t.target;if(!c)return;let g=c.closest(".floating-window");if(!g)return;let P=g.getAttribute("data-window-id");P&&M(P)};return document.addEventListener("mousedown",i),()=>{document.removeEventListener("mousedown",i)}},[M]);let _e=(i,t)=>{let c=a.floating.find(Z=>Z.id===i);if(!c||c.maximized)return;M(i);let g=t.clientX,P=t.clientY,H=t.currentTarget.closest(".floating-window"),O=H?H.offsetLeft:0,k=H?H.offsetTop:0,T=!1,U=Z=>{let te=Z.clientX-g,pe=Z.clientY-P;if(!T&&(Math.abs(te)>5||Math.abs(pe)>5)&&(T=!0,f(i)),T){let me=O+te,xe=k+pe;b(i,{x:me,y:xe,stickyRight:!1,stickyBottom:!1})}},j=()=>{if(T){let Z=re.current,te=G.current,pe=ye.current;if(pe)A(i,pe);else if(te){let me=te.index;te.side==="right"&&(me+=1),R(i,te.leafId,me)}else Z&&m(i,Z.leafId,Z.position);f(null),le(null),re.current=null,q(null),G.current=null,ne(null)}window.removeEventListener("mousemove",U),window.removeEventListener("mouseup",j)};window.addEventListener("mousemove",U),window.addEventListener("mouseup",j)},e=(i,t)=>{t.stopPropagation();let c=a.floating.find(j=>j.id===i);if(!c||c.maximized)return;M(i);let g=t.clientX,P=t.clientY,H=t.currentTarget.closest(".floating-window"),O=H?H.offsetWidth:400,k=H?H.offsetHeight:300,T=j=>{let Z=j.clientX-g,te=j.clientY-P,pe=Math.max(200,O+Z),me=Math.max(150,k+te),xe=c.x,Ne=c.y,et=Pe.width,tt=Pe.height,Wt=typeof c.x=="string"?parseFloat(c.x):c.x,Ft=typeof c.y=="string"?parseFloat(c.y):c.y,Dt=typeof c.width=="string"?parseFloat(c.width):c.width,Ot=typeof c.height=="string"?parseFloat(c.height):c.height,dt=Math.abs(Wt+Dt-et)<4,ct=Math.abs(Ft+Ot-tt)<4;dt&&(xe=et-pe,xe<0&&(xe=0,pe=et)),ct&&(Ne=tt-me,Ne<0&&(Ne=0,me=tt)),b(i,{x:xe,y:Ne,width:pe,height:me,stickyRight:dt,stickyBottom:ct})},U=()=>{window.removeEventListener("mousemove",T),window.removeEventListener("mouseup",U)};window.addEventListener("mousemove",T),window.addEventListener("mouseup",U)},s=i=>{if(N.current){let t=i==="left"?-150:150;N.current.scrollBy({left:t,behavior:"smooth"})}},[o,r]=(0,W.useState)("dark");return(0,W.useEffect)(()=>{let i=()=>{let c=document.documentElement.getAttribute("data-bs-theme")==="light"?"light":"dark";r(c)};i();let t=new MutationObserver(i);return t.observe(document.documentElement,{attributes:!0,attributeFilter:["data-bs-theme"]}),()=>t.disconnect()},[]),(0,d.jsxs)("div",{"data-workspace-skin":n,"data-bs-theme":o,className:"d-flex flex-column w-100 h-100 overflow-hidden",style:{userSelect:"none"},children:[(0,d.jsxs)("div",{ref:We,className:`flex-grow-1 w-100 position-relative ${a.draggedPanelId?"dragging-active":""}`,style:{overflow:"hidden"},children:[a.draggedPanelId!==null&&(0,d.jsxs)(d.Fragment,{children:[(0,d.jsx)("div",{className:"workspace-edge-trigger edge-trigger-left",onMouseEnter:()=>ne("left"),onMouseLeave:()=>ne(null)}),(0,d.jsx)("div",{className:"workspace-edge-trigger edge-trigger-right",onMouseEnter:()=>ne("right"),onMouseLeave:()=>ne(null)}),(0,d.jsx)("div",{className:"workspace-edge-trigger edge-trigger-top",onMouseEnter:()=>ne("top"),onMouseLeave:()=>ne(null)}),(0,d.jsx)("div",{className:"workspace-edge-trigger edge-trigger-bottom",onMouseEnter:()=>ne("bottom"),onMouseLeave:()=>ne(null)})]}),a.draggedPanelId!==null&&he!==null&&(0,d.jsx)("div",{className:`workspace-edge-preview edge-preview-${he}`}),(0,d.jsx)("div",{className:"w-100 h-100",style:{overflow:"hidden",position:"relative"},children:a.gridRoot?(0,d.jsx)(wt,{node:a.gridRoot,path:[],onTabRightClick:$e,activeDropZone:se,onHoverDropZone:He,onTabDragStart:Ae,hoveredTab:be,onTabHover:Re,defaultPanelIcon:l}):(0,d.jsx)("div",{className:"w-100 h-100 d-flex align-items-center justify-content-center text-muted font-monospace small",children:"Grid Empty"})}),(()=>{let i=a.floating.length>0?Math.max(...a.floating.map(t=>t.z)):0;return a.floating.map(t=>{let c=a.panels[t.id];if(!c)return null;let g=t.maximized,P=a.draggedPanelId===t.id,z=t.z===i&&a.floating.length>0,O=oe.get(c.component)?.defaultOptions;return(0,d.jsxs)("div",{"data-window-id":t.id,className:`floating-window ${g?"maximized":""} ${z?"v2-window-focused":""} ${x??""}`,style:{position:"absolute",left:g?0:typeof t.x=="number"?`${t.x}px`:t.x,top:g?0:typeof t.y=="number"?`${t.y}px`:t.y,width:g?"100%":typeof t.width=="number"?`${t.width}px`:t.width,height:g?"100%":typeof t.height=="number"?`${t.height}px`:t.height,zIndex:t.z,pointerEvents:P?"none":"auto"},children:[(0,d.jsxs)("div",{onDoubleClick:()=>D(t.id),onMouseDown:k=>{O?.canDrag!==!1&&_e(t.id,k)},className:"floating-window-titlebar d-flex flex-row justify-content-between align-items-center cursor-move",style:{cursor:g||O?.canDrag===!1?"default":"move"},children:[(0,d.jsxs)("span",{className:"floating-window-title text-truncate me-2 d-flex align-items-center",children:[(0,d.jsx)("span",{className:"window-title-icon",children:O?.icon||l||st}),(0,d.jsxs)("span",{children:[Y(c.title,v),c.dirty?" *":""]})]}),(0,d.jsxs)("div",{className:"d-flex align-items-center gap-1.5",onMouseDown:k=>k.stopPropagation(),children:[O?.canDrag!==!1&&(0,d.jsx)("button",{type:"button",title:Y(u.windowAnchoringOptions,v),onClick:k=>{let T=!!t.stickyRight,U=!!t.stickyBottom;L.current?.show({event:k,contextMenu:{items:[{label:Y(u.anchorToRightEdge,v),checkbox:{active:!0,enabled:!0,value:T},action:()=>{let j=Pe.width,Z=typeof t.width=="string"?parseFloat(t.width):t.width;T?b(t.id,{stickyRight:!1}):b(t.id,{x:j-Z-10,stickyRight:!0})}},{label:Y(u.anchorToBottomEdge,v),checkbox:{active:!0,enabled:!0,value:U},action:()=>{let j=Pe.height,Z=typeof t.height=="string"?parseFloat(t.height):t.height;U?b(t.id,{stickyBottom:!1}):b(t.id,{y:j-Z-10,stickyBottom:!0})}}]}})},className:"custom-tab-btn btn-anchor-tab",children:(0,d.jsxs)("svg",{className:`anchor-icon ${t.stickyRight&&t.stickyBottom?"anchor-sticky-both":t.stickyRight?"anchor-sticky-right":t.stickyBottom?"anchor-sticky-bottom":""}`,width:"11",height:"11",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2.5",children:[(0,d.jsx)("circle",{cx:"12",cy:"5",r:"2"}),(0,d.jsx)("path",{d:"M12 7v7m0 0a4 4 0 0 1-4-4M12 14a4 4 0 0 0 4-4M5 18h14"})]})}),O?.canMinimize!==!1&&(0,d.jsx)("button",{type:"button",title:Y(u.minimize,v),onClick:()=>S(t.id),className:"custom-tab-btn",children:(0,d.jsx)("svg",{width:"10",height:"10",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"3",children:(0,d.jsx)("path",{d:"M5 12h14"})})}),(0,d.jsx)("button",{type:"button",title:g?Y(u.restoreSize,v):Y(u.maximize,v),onClick:()=>D(t.id),className:"custom-tab-btn",children:(0,d.jsx)("svg",{width:"10",height:"10",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2.5",children:(0,d.jsx)("rect",{x:"4",y:"4",width:"16",height:"16",rx:"1.5"})})}),O?.canClose!==!1&&(0,d.jsx)("button",{type:"button",title:Y(u.close,v),onClick:()=>w(t.id),className:"custom-tab-btn btn-close-tab",children:(0,d.jsx)("svg",{width:"10",height:"10",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"3",children:(0,d.jsx)("path",{d:"M18 6L6 18M6 6l12 12"})})})]})]}),(0,d.jsx)("div",{className:`flex-grow-1 w-100 overflow-hidden ${I??""}`,style:{position:"relative"},children:(0,d.jsx)(xt,{panelId:t.id},t.id)}),!g&&(0,d.jsx)("div",{onMouseDown:k=>e(t.id,k),style:{position:"absolute",right:0,bottom:0,width:"14px",height:"14px",cursor:"se-resize",zIndex:30,background:"linear-gradient(135deg, transparent 50%, rgba(255,255,255,0.2) 50%)"}})]},t.id)})})()]}),a.minimized.length>0&&(0,d.jsxs)("div",{className:"flex-shrink-0 w-100 d-flex flex-row align-items-center taskbar-footer-container px-3 py-1.5 justify-content-center",style:{height:"48px",zIndex:100},children:[(0,d.jsx)("button",{type:"button",onClick:()=>s("left"),className:"btn btn-sm btn-link taskbar-nav-btn text-decoration-none py-0 font-monospace",style:{display:a.minimized.length>4?"block":"none"},children:"\u25C0"}),(0,d.jsx)("div",{ref:N,className:"d-flex flex-row gap-2 overflow-x-auto align-items-center mx-2 px-1 py-0.5 scrollbar-hidden",style:{maxWidth:"800px",scrollbarWidth:"none",scrollSnapType:"x mandatory"},children:a.minimized.map(i=>{let c=oe.get(i.component)?.defaultOptions?.icon||l||st;return(0,d.jsx)("div",{onClick:()=>h(i.id),onContextMenu:g=>Ge(i.id,g),onMouseEnter:g=>{if(ue)return;X.current&&clearTimeout(X.current);let P=g.currentTarget.getBoundingClientRect();$({id:i.id,rect:P,title:i.title,component:i.component})},onMouseLeave:()=>{X.current=setTimeout(()=>{$(null)},150)},className:"taskbar-glassmorphic-item rounded d-flex align-items-center justify-content-center cursor-pointer hover-elevate",style:{backdropFilter:"blur(6px)",transition:"all 0.2s",cursor:"pointer",scrollSnapAlign:"start",width:"38px",height:"38px",position:"relative",padding:0},children:(0,d.jsx)("span",{className:"taskbar-item-icon d-flex align-items-center justify-content-center",children:c})},i.id)})}),B&&(0,it.createPortal)((0,d.jsxs)("div",{className:"taskbar-item-tooltip d-flex flex-column gap-1",style:{position:"fixed",left:`${B.rect.left+B.rect.width/2}px`,top:`${B.rect.top-8}px`,transform:"translateX(-50%) translateY(-100%)",opacity:1,pointerEvents:"auto",zIndex:999999},onMouseEnter:()=>{X.current&&clearTimeout(X.current)},onMouseLeave:()=>{$(null)},children:[(0,d.jsxs)("div",{className:"d-flex flex-row align-items-center justify-content-between w-100 gap-3 px-1 py-0.5",children:[(0,d.jsxs)("span",{className:"tooltip-title-text text-truncate",style:{maxWidth:"140px"},children:[Y(B.title,v),a.panels[B.id]?.dirty?" *":""]}),(0,d.jsx)("span",{onClick:i=>{i.stopPropagation(),w(B.id),$(null)},title:Y(u.closePanel,v),className:"tooltip-close-x d-flex align-items-center justify-content-center",children:(0,d.jsx)("svg",{width:"12",height:"12",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2.5",children:(0,d.jsx)("path",{d:"M18 6L6 18M6 6l12 12"})})})]}),(0,d.jsx)(Qt,{panelId:B.id})]}),document.body),(0,d.jsx)("button",{type:"button",onClick:()=>s("right"),className:"btn btn-sm btn-link taskbar-nav-btn text-decoration-none py-0 font-monospace",style:{display:a.minimized.length>4?"block":"none"},children:"\u25B6"})]}),F.map(i=>{let t=a.panels[i];if(!t)return null;let c=Pt(i);return(0,it.createPortal)((0,d.jsx)(Vt,{panelId:i,children:(0,d.jsx)("div",{style:{width:"100%",height:"100%"},children:Zt(i,t.component)})}),c,i)}),(0,d.jsx)(vt.JsonContextMenu,{ref:L,id:"workspace-context-menu",theme:"dark",onShow:()=>ee(!0),onHide:()=>ee(!1)}),a.draggedPanelId!==null&&!a.floating.some(i=>i.id===a.draggedPanelId)&&(0,d.jsxs)("div",{className:"position-fixed bg-black bg-opacity-80 border border-info rounded text-info font-monospace px-3 py-1.5 shadow-lg d-flex align-items-center gap-2",style:{left:ge.x+12,top:ge.y+12,zIndex:1e5,pointerEvents:"none",fontSize:"0.75rem",boxShadow:"0 8px 24px rgba(0,0,0,0.5)",borderLeft:"3px solid var(--accent-color)",whiteSpace:"nowrap"},children:["\u{1F4C4} ",Y(a.panels[a.draggedPanelId]?.title,v)||"Tab"]}),a.pendingClose&&(()=>{let i=a.panels[a.pendingClose.id],t=i?Y(i.title,v):"Panel";return(0,d.jsx)("div",{className:"close-warning-overlay",children:(0,d.jsxs)("div",{className:"close-warning-modal",children:[(0,d.jsxs)("div",{className:"close-warning-header",children:[(0,d.jsx)("div",{className:"close-warning-icon",children:"\u26A0\uFE0F"}),(0,d.jsx)("h5",{className:"close-warning-title",children:"Unsaved Changes"})]}),(0,d.jsxs)("p",{className:"close-warning-message",children:['"',t,'" has unsaved changes. Do you want to discard your changes and close the panel?']}),(0,d.jsxs)("div",{className:"close-warning-footer",children:[(0,d.jsx)("button",{type:"button",className:"btn-warning-action btn-warning-cancel",onClick:()=>E(!1),children:"Cancel"}),(0,d.jsx)("button",{type:"button",className:"btn-warning-action btn-warning-discard",onClick:()=>E(!0),children:"Discard Changes"})]})]})})})()]})},Ct=en;var K=require("react"),lt=require("react/jsx-runtime"),tn=0,rt=()=>`panel-${++tn}-${Date.now()}`,Je=new Map,Mt={leftPanel:null,rightPanel:null,modals:[]},Rt=(0,K.createContext)(null),kt=(0,K.createContext)(null),It=({children:n})=>{let[l,a]=(0,K.useState)(Mt),h=(0,K.useRef)(l);h.current=l;let S=(0,K.useCallback)((u,x)=>{Je.set(u,x)},[]),w=(0,K.useCallback)(u=>{Je.delete(u)},[]),E=(0,K.useCallback)(async(u,x,I={})=>{let F=h.current.leftPanel;if(F){let L=Je.get(F.id);if(L&&!await L())return null}let p=rt(),N={id:p,Component:u,props:x,containerType:"left-panel",options:I};return a(L=>({...L,leftPanel:N})),p},[]),D=(0,K.useCallback)(async(u,x,I={})=>{let F=h.current.rightPanel;if(F){let L=Je.get(F.id);if(L&&!await L())return null}let p=rt(),N={id:p,Component:u,props:x,containerType:"right-panel",options:I};return a(L=>({...L,rightPanel:N})),p},[]),b=(0,K.useCallback)((u,x,I={})=>{let F=rt(),p=x.title,N={...I,title:I.title||p||"Confirmation"},L={id:F,Component:u,props:x,containerType:"modal",options:N};return a(B=>({...B,modals:[...B.modals,L]})),F},[]),M=(0,K.useCallback)(u=>{a(x=>({leftPanel:x.leftPanel?.id===u?null:x.leftPanel,rightPanel:x.rightPanel?.id===u?null:x.rightPanel,modals:x.modals.filter(I=>I.id!==u)}))},[]),y=(0,K.useCallback)(()=>{a(Mt)},[]),f=(0,K.useCallback)(()=>{a(u=>({...u,modals:[]}))},[]),m=(0,K.useCallback)(u=>l.leftPanel?.id===u?l.leftPanel:l.rightPanel?.id===u?l.rightPanel:l.modals.find(x=>x.id===u),[l]),R=(0,K.useCallback)((u,x)=>{a(I=>({leftPanel:I.leftPanel?.id===u?{...I.leftPanel,...x}:I.leftPanel,rightPanel:I.rightPanel?.id===u?{...I.rightPanel,...x}:I.rightPanel,modals:I.modals.map(F=>F.id===u?{...F,...x}:F)}))},[]),A=(0,K.useCallback)((u,x)=>{R(u,{dirty:x})},[R]),v=(0,K.useMemo)(()=>({openLeftPanel:E,openRightPanel:D,openModal:b,close:M,closeAll:y,closeAllModals:f,getInstance:m,updateInstance:R,setDirty:A,registerCloseHandler:S,unregisterCloseHandler:w}),[E,D,b,M,y,f,m,R,A,S,w]);return(0,lt.jsx)(Rt.Provider,{value:l,children:(0,lt.jsx)(kt.Provider,{value:v,children:n})})},Me=()=>{let n=(0,K.useContext)(Rt);if(!n)throw new Error("usePanelState must be used within PanelProvider");return n},Ee=()=>{let n=(0,K.useContext)(kt);if(!n)throw new Error("usePanelActions must be used within PanelProvider");return n};var _=require("react");var Oe=require("react");var de=require("react/jsx-runtime"),Ze=({zIndex:n,onDiscard:l,onCancel:a,message:h,title:S})=>{let w=(0,Oe.useRef)(null);return(0,Oe.useEffect)(()=>{let M=setTimeout(()=>{w.current?.focus()},50);return()=>clearTimeout(M)},[]),(0,Oe.useEffect)(()=>{let M=y=>{y.key==="Escape"&&(y.stopPropagation(),y.preventDefault(),a())};return document.addEventListener("keydown",M,!0),()=>document.removeEventListener("keydown",M,!0)},[a]),(0,de.jsx)("div",{className:"close-warning-overlay",style:{zIndex:n},children:(0,de.jsxs)("div",{className:"close-warning-modal",children:[(0,de.jsxs)("div",{className:"close-warning-header",children:[(0,de.jsx)("div",{className:"close-warning-icon",children:"\u26A0\uFE0F"}),(0,de.jsx)("h5",{className:"close-warning-title",children:S||"Unsaved Changes"})]}),(0,de.jsx)("p",{className:"close-warning-message",children:h||"You have unsaved changes that will be lost."}),(0,de.jsx)("p",{className:"close-warning-message",style:{fontWeight:500,margin:0},children:"Do you want to discard your changes and close?"}),(0,de.jsxs)("div",{className:"close-warning-footer",children:[(0,de.jsx)("button",{type:"button",className:"btn-warning-action btn-warning-cancel",onClick:a,ref:w,children:"Cancel"}),(0,de.jsx)("button",{type:"button",className:"btn-warning-action btn-warning-discard",onClick:l,children:"Discard Changes"})]})]})})};var V=require("react/jsx-runtime"),nn=({modal:n,index:l,isTopmost:a})=>{let{close:h,updateInstance:S,setDirty:w}=Ee(),E=Ce(),{modalClass:D,modalBodyClass:b}=we(),M=(0,_.useRef)(null),[y,f]=(0,_.useState)(!1),m=(0,_.useRef)(null),{id:R,Component:A,props:v,options:u,dirty:x}=n,I=u,[F,p]=(0,_.useState)(I.icon||null),N=(0,_.useRef)(I);N.current=I;let L=(0,_.useCallback)(()=>new Promise(q=>{m.current=q,f(!0)}),[]),B=(0,_.useCallback)(()=>{m.current?.(!0),m.current=null,f(!1)},[]),$=(0,_.useCallback)(()=>{m.current?.(!1),m.current=null,f(!1)},[]),X=(0,_.useCallback)(async q=>{if(q?.force){h(R);return}if(M.current){if(!await M.current())return;h(R);return}x&&!await L()||h(R)},[h,R,x,L]),ue=(0,_.useCallback)(q=>w(R,q),[w,R]),ee=(0,_.useCallback)(q=>S(R,{options:{...N.current,title:q}}),[S,R]),se=(0,_.useCallback)(q=>p(q),[]),le=(0,_.useCallback)(q=>(M.current=q,()=>{M.current=null}),[]),re=(0,_.useMemo)(()=>({requestClose:X,setDirty:ue,setTitle:ee,setIcon:se,onCloseRequested:le,containerType:"modal",instanceId:R}),[X,ue,ee,se,le,R]),ge=Y(I.title,E),ve=x?`${ge} *`:ge,he=I.size?`v2-modal-size-${I.size}`:"v2-modal-size-auto",fe=I.closable!==!1;(0,_.useEffect)(()=>{if(!a||!fe||y)return;let q=G=>{G.key==="Escape"&&(G.stopPropagation(),X())};return document.addEventListener("keydown",q),()=>document.removeEventListener("keydown",q)},[X,fe,a,y]);let ne=1e4+l*10,be=ne+5;return(0,V.jsxs)(V.Fragment,{children:[(0,V.jsxs)("div",{className:"v2-modal-overlay",style:{zIndex:ne},children:[(0,V.jsx)("div",{className:"v2-modal-curtain",onClick:fe?()=>X():void 0}),(0,V.jsxs)("div",{className:`v2-modal-window ${he} ${D??""}`,children:[(0,V.jsxs)("div",{className:"v2-modal-header",children:[F&&(0,V.jsx)("div",{className:"v2-modal-icon",children:F}),(0,V.jsx)("h4",{className:"v2-modal-title",children:ve}),fe&&(0,V.jsx)("button",{className:"v2-modal-close-button",onClick:()=>X(),title:"Close",type:"button",children:(0,V.jsx)("svg",{width:"14",height:"14",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2.5",children:(0,V.jsx)("path",{d:"M18 6L6 18M6 6l12 12"})})})]}),(0,V.jsx)("div",{className:`v2-modal-body ${b??""}`,children:(0,V.jsx)(Ie,{value:re,children:(0,V.jsx)(A,{...v,panelId:R})})})]})]}),y&&(0,V.jsx)(Ze,{zIndex:be,onDiscard:B,onCancel:$})]})},on=()=>{let{modals:n}=Me();return n.length===0?null:(0,V.jsx)(V.Fragment,{children:n.map((l,a)=>(0,V.jsx)(nn,{modal:l,index:a,isTopmost:a===n.length-1},l.id))})},Nt=on;var Q=require("react");var J=require("react/jsx-runtime"),Qe=({panel:n,position:l,defaultWidth:a})=>{let{close:h,updateInstance:S,setDirty:w,registerCloseHandler:E,unregisterCloseHandler:D}=Ee(),{modals:b}=Me(),M=Ce(),{sidePanelClass:y,sidePanelBodyClass:f}=we(),m=(0,Q.useRef)(null),[R,A]=(0,Q.useState)(!1),v=(0,Q.useRef)(null),{id:u,Component:x,props:I,options:F,dirty:p}=n,N=F,[L,B]=(0,Q.useState)(N.icon||null),$=(0,Q.useRef)(N);$.current=N;let X=(0,Q.useCallback)(()=>new Promise(G=>{v.current=G,A(!0)}),[]),ue=(0,Q.useCallback)(()=>{v.current?.(!0),v.current=null,A(!1)},[]),ee=(0,Q.useCallback)(()=>{v.current?.(!1),v.current=null,A(!1)},[]),se=(0,Q.useCallback)(async G=>{if(G?.force){h(u);return}if(m.current){if(!await m.current())return;h(u);return}p&&!await X()||h(u)},[h,u,p,X]),le=(0,Q.useCallback)(async()=>m.current?await m.current():!p,[p]);(0,Q.useEffect)(()=>(E(u,le),()=>D(u)),[u,le,E,D]);let re=(0,Q.useCallback)(G=>w(u,G),[w,u]),ge=(0,Q.useCallback)(G=>S(u,{options:{...$.current,title:G}}),[S,u]),ve=(0,Q.useCallback)(G=>B(G),[]),he=(0,Q.useCallback)(G=>(m.current=G,()=>{m.current=null}),[]),fe=(0,Q.useMemo)(()=>({requestClose:se,setDirty:re,setTitle:ge,setIcon:ve,onCloseRequested:he,containerType:l==="left"?"left-panel":"right-panel",instanceId:u}),[se,re,ge,ve,he,l,u]),ye=Y(N.title,M),ne=p?`${ye} *`:ye;(0,Q.useEffect)(()=>{let G=Re=>{Re.key==="Escape"&&b.length===0&&!R&&se()};return document.addEventListener("keydown",G),()=>document.removeEventListener("keydown",G)},[se,b.length,R]);let be=N.width||a||400,q=typeof be=="number"?`${be}px`:be;return(0,J.jsxs)(J.Fragment,{children:[(0,J.jsx)("div",{className:`v2-side-panel v2-side-panel-${l} v2-side-panel-visible ${y??""}`,style:{width:q},children:(0,J.jsxs)("div",{className:"v2-side-panel-window",children:[(0,J.jsxs)("div",{className:"v2-side-panel-header",children:[L&&(0,J.jsx)("div",{className:"v2-side-panel-icon",children:L}),(0,J.jsx)("h4",{className:"v2-side-panel-title",children:ne}),(0,J.jsx)("button",{className:"v2-side-panel-close-button",onClick:()=>se(),title:"Close",type:"button",children:(0,J.jsx)("svg",{width:"14",height:"14",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2.5",children:(0,J.jsx)("path",{d:"M18 6L6 18M6 6l12 12"})})})]}),(0,J.jsx)("div",{className:`v2-side-panel-body ${f??""}`,children:(0,J.jsx)(Ie,{value:fe,children:(0,J.jsx)(x,{...I,panelId:u})})})]})}),R&&(0,J.jsx)(Ze,{zIndex:2e4,onDiscard:ue,onCancel:ee})]})},sn=({defaultWidth:n})=>{let{leftPanel:l,rightPanel:a}=Me();return(0,J.jsxs)(J.Fragment,{children:[l&&(0,J.jsx)(Qe,{panel:l,position:"left",defaultWidth:n},l.id),a&&(0,J.jsx)(Qe,{panel:a,position:"right",defaultWidth:n},a.id)]})},St=({defaultWidth:n})=>{let{leftPanel:l}=Me();return l?(0,J.jsx)(Qe,{panel:l,position:"left",defaultWidth:n},l.id):null},zt=({defaultWidth:n})=>{let{rightPanel:l}=Me();return l?(0,J.jsx)(Qe,{panel:l,position:"right",defaultWidth:n},l.id):null},Lt=sn;var Be=require("react");var ce=require("react/jsx-runtime"),an=({title:n,message:l,alert:a,alertType:h="info",useYesNoTitles:S=!1,onOK:w,onCancel:E})=>{let{requestClose:D,setIcon:b,setTitle:M}=je(),y=(0,Be.useRef)(null);(0,Be.useEffect)(()=>{if(n){let u=typeof n=="string"?n:n.defaultMessage||n.id;M(u)}b&&b((0,ce.jsx)("span",{children:"\u2753"}))},[n,M,b]),(0,Be.useEffect)(()=>{y.current?.focus()},[]);let f=typeof l=="string"?l:l.defaultMessage||l.id,m=S?"No":"Cancel",R=S?"Yes":"OK",A=u=>{u.preventDefault(),w?.(),D()},v=()=>{E?.(),D()};return(0,ce.jsxs)("form",{onSubmit:A,className:"p-3 d-flex flex-column gap-3",children:[a&&(0,ce.jsxs)("div",{className:`alert alert-${h==="danger"?"danger":h} d-flex align-items-center gap-2 m-0 p-2.5 small`,children:[(0,ce.jsx)("span",{children:"\u2139\uFE0F"}),(0,ce.jsx)("span",{children:a})]}),(0,ce.jsx)("div",{style:{fontSize:"0.9rem",color:"inherit",lineHeight:1.5},children:f}),(0,ce.jsx)("hr",{className:"my-2 opacity-10"}),(0,ce.jsxs)("div",{className:"d-flex justify-content-end gap-2",children:[(0,ce.jsx)("button",{type:"button",className:"btn btn-sm btn-outline-secondary font-monospace",onClick:v,children:m}),(0,ce.jsx)("button",{type:"submit",className:"btn btn-sm btn-primary font-monospace",ref:y,children:R})]})]})},Tt=an;var ie=require("react"),ae=require("react/jsx-runtime"),Et=(0,ie.forwardRef)(function({position:l="right",tabs:a,drawerWidth:h="220px",activeTabId:S,onActiveTabChange:w,children:E},D){let b=S!==void 0,[M,y]=(0,ie.useState)(null),f=b?S:M,[m,R]=(0,ie.useState)(()=>{let p=new Set;for(let N of a)N.eagerMount&&p.add(N.id);return p});(0,ie.useEffect)(()=>{let p=a.filter(N=>N.eagerMount&&!m.has(N.id));p.length>0&&R(N=>{let L=new Set(N);for(let B of p)L.add(B.id);return L})},[a]);let A=(0,ie.useRef)(f??null);(0,ie.useEffect)(()=>{A.current=f??null},[f]);let v=(0,ie.useCallback)(p=>{b||y(p),w?.(p)},[b,w]);(0,ie.useImperativeHandle)(D,()=>({openTab:p=>v(p),closeDrawer:()=>v(null),getActiveTab:()=>A.current}),[v]);let u=p=>{v(f===p?null:p)},x=(0,ie.useCallback)(()=>v(null),[v]);(0,ie.useEffect)(()=>{f&&!m.has(f)&&R(p=>{let N=new Set(p);return N.add(f),N})},[f,m]),(0,ie.useEffect)(()=>{f===null&&R(p=>{let N=!1,L=new Set(p);for(let B of p){let $=a.find(X=>X.id===B);$&&!$.eagerMount&&!$.preserveState&&(L.delete(B),N=!0)}return N?L:p})},[f,a]);let I=(0,ae.jsx)("div",{className:`sidebar-tabs-strip ${l}`,style:{width:"56px",height:"100%"},children:a.map(p=>{let N=f===p.id;return(0,ae.jsx)("button",{type:"button",onClick:()=>u(p.id),className:`sidebar-tab-btn ${N?"active":""}`,title:p.label,"aria-pressed":N,children:p.icon},p.id)})}),F=(0,ae.jsx)("div",{className:`sidebar-content-drawer h-100 ${l}`,style:{width:f?h:"0px",minWidth:f?h:"0px",overflow:"hidden",flexShrink:0},children:a.map(p=>{if(!m.has(p.id))return null;let L=f===p.id,B=()=>v(p.id);return(0,ae.jsxs)("div",{style:{display:L?"flex":"none",flexDirection:"column",height:"100%",width:"100%"},children:[(0,ae.jsxs)("div",{className:"d-flex align-items-center justify-content-between border-bottom border-secondary-subtle px-3 py-2 flex-shrink-0",style:{background:"rgba(0,0,0,0.08)",minHeight:"38px"},children:[(0,ae.jsx)("span",{className:"sidebar-header-title",children:p.label}),(0,ae.jsx)("button",{type:"button",onClick:x,className:"btn btn-link p-0 text-secondary d-flex align-items-center",style:{textDecoration:"none"},title:"Close panel","aria-label":"Close panel",children:(0,ae.jsxs)("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",children:[(0,ae.jsx)("line",{x1:"18",y1:"6",x2:"6",y2:"18"}),(0,ae.jsx)("line",{x1:"6",y1:"6",x2:"18",y2:"18"})]})})]}),(0,ae.jsx)("div",{className:"flex-grow-1 overflow-auto",children:p.renderContent(p.id,x,B)})]},p.id)})});return(0,ae.jsxs)(ae.Fragment,{children:[l==="left"&&I,l==="left"&&F,E,l==="right"&&F,l==="right"&&I]})});0&&(module.exports={ConfirmationForm,FormContainerContext,FormContainerProvider,LeftPanelRenderer,ModalStackRenderer,PanelProvider,PanelRegistry,RightPanelRenderer,SidePanelRenderer,Sidebar,WindowManager,WindowManagerProvider,defaultPredefinedMessages,formatLabel,useFormContainer,useFormatMessage,usePanelActions,usePanelContext,usePanelState,usePredefinedMessages,useStyleClasses,useWindowManagerActions,useWindowManagerState});
2
+ //# sourceMappingURL=index.cjs.map