react-dockable-desktop 3.0.0 → 3.2.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 +290 -69
- package/dist/index.cjs +24 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +240 -25
- package/dist/index.d.ts +240 -25
- package/dist/index.js +24 -3
- package/dist/index.js.map +1 -1
- package/dist/styles.css +1092 -52
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,28 +1,33 @@
|
|
|
1
1
|
# React Dockable Desktop
|
|
2
2
|
|
|
3
|
-
[](https://www.npmjs.com/package/react-dockable-desktop)
|
|
4
|
+
[](https://www.typescriptlang.org/)
|
|
5
|
+
[](#touch--mobile)
|
|
4
6
|
[](#license)
|
|
5
7
|
[](https://felipecarrillo100.github.io/react-dockable-desktop/demo/)
|
|
6
8
|
[](https://felipecarrillo100.github.io/react-dockable-desktop/)
|
|
7
9
|
|
|
8
|
-
A premium
|
|
10
|
+
A premium dockable layout engine for React. Build desktop-class applications with fluid split-docking grids, tabbed panels, resizable floating windows, and **zero-unmount DOM preservation** — so WebGL contexts, live maps, and stateful editors never lose their state when moved or re-tabbed.
|
|
9
11
|
|
|
10
|
-
**[Full Documentation](https://felipecarrillo100.github.io/react-dockable-desktop/)** |
|
|
11
12
|
**[Live Demo](https://felipecarrillo100.github.io/react-dockable-desktop/demo/)** |
|
|
13
|
+
**[Full Documentation](https://felipecarrillo100.github.io/react-dockable-desktop/)** |
|
|
12
14
|
**[API Reference](https://felipecarrillo100.github.io/react-dockable-desktop/api/)**
|
|
13
15
|
|
|
14
16
|
---
|
|
15
17
|
|
|
16
|
-
##
|
|
18
|
+
## Features
|
|
17
19
|
|
|
18
|
-
- **
|
|
19
|
-
- **Workspace Edge Docking** — drag to outer edges to dock as full-width
|
|
20
|
-
- **Floating Windows** — pop panels into resizable floating windows
|
|
21
|
-
- **
|
|
22
|
-
- **
|
|
23
|
-
- **
|
|
24
|
-
- **
|
|
25
|
-
- **
|
|
20
|
+
- **Split-Docking Grid** — drag panels to split any zone into rows/columns or group into tabbed containers
|
|
21
|
+
- **Workspace Edge Docking** — drag to the outer edges to dock a panel as a full-width or full-height strip
|
|
22
|
+
- **Floating Windows** — pop panels into freely resizable floating windows; 8-direction resize handles (N/NE/E/SE/S/SW/W/NW), maximize, minimize
|
|
23
|
+
- **Touch & Mobile Ready** — full iPad and Android support: long-press to drag tabs, touch resize, 44px coarse-pointer targets throughout
|
|
24
|
+
- **Zero-Unmount DOM Persistence** — panel DOM nodes are moved, never destroyed; WebGL, maps, terminals, and forms retain full state
|
|
25
|
+
- **i18n & RTL** — full Right-to-Left layout support; `dir="rtl"` flips every control, tab order, and drop zone automatically
|
|
26
|
+
- **Inter-Panel Pub/Sub** — lightweight typed event bus for decoupled panel-to-panel communication
|
|
27
|
+
- **Imperative API** — `WorkspaceClient` opens, closes, focuses, and serializes panels from anywhere — inside or outside React
|
|
28
|
+
- **Layout Serialization** — save and restore the full workspace as a JSON string; survives page reloads
|
|
29
|
+
- **7 Built-in Skins** — VSCode, macOS, Chrome, Slate, Nord, Obsidian, Tokyo — all fully themeable via CSS variables
|
|
30
|
+
- **TypeScript-first** — complete type definitions included; no separate `@types/` package needed
|
|
26
31
|
|
|
27
32
|
---
|
|
28
33
|
|
|
@@ -32,28 +37,33 @@ A premium React window manager and dockable layout engine. Fluid split-docking g
|
|
|
32
37
|
npm install react-dockable-desktop replace-react-contexify
|
|
33
38
|
```
|
|
34
39
|
|
|
35
|
-
Import styles in your entry file:
|
|
40
|
+
Import styles in your app entry file. **Order matters** — the contexify sheet must come first:
|
|
36
41
|
|
|
37
42
|
```ts
|
|
38
43
|
import 'replace-react-contexify/styles.css';
|
|
39
44
|
import 'react-dockable-desktop/styles.css';
|
|
40
45
|
```
|
|
41
46
|
|
|
47
|
+
**Requirements:** React ≥ 16.8 · Node ≥ 18
|
|
48
|
+
|
|
42
49
|
---
|
|
43
50
|
|
|
44
51
|
## Quick Start
|
|
45
52
|
|
|
46
53
|
### 1. Create a WorkspaceClient
|
|
47
54
|
|
|
55
|
+
Define your panel catalog and create a `WorkspaceClient` **outside React**, at module scope. It acts as the bridge between your imperative code and the React tree.
|
|
56
|
+
|
|
48
57
|
```ts
|
|
58
|
+
// workspace.ts
|
|
49
59
|
import { WorkspaceClient } from 'react-dockable-desktop';
|
|
50
|
-
import MapPanel
|
|
60
|
+
import MapPanel from './panels/MapPanel';
|
|
51
61
|
import EditorPanel from './panels/EditorPanel';
|
|
52
62
|
|
|
53
|
-
export const
|
|
63
|
+
export const workspace = new WorkspaceClient({
|
|
54
64
|
panels: {
|
|
55
65
|
map: { component: MapPanel, defaultOptions: { title: 'Map View' } },
|
|
56
|
-
editor: { component: EditorPanel, defaultOptions: { title: 'Editor'
|
|
66
|
+
editor: { component: EditorPanel, defaultOptions: { title: 'Editor' } },
|
|
57
67
|
},
|
|
58
68
|
initialState: localStorage.getItem('workspace-layout'),
|
|
59
69
|
});
|
|
@@ -61,97 +71,308 @@ export const client = new WorkspaceClient({
|
|
|
61
71
|
|
|
62
72
|
### 2. Mount the Provider
|
|
63
73
|
|
|
74
|
+
`DockableDesktopProvider` is the single composite provider — it wraps everything the library needs:
|
|
75
|
+
|
|
64
76
|
```tsx
|
|
65
|
-
|
|
66
|
-
import {
|
|
77
|
+
// App.tsx
|
|
78
|
+
import { DockableDesktopProvider, WindowManager, ModalStackRenderer } from 'react-dockable-desktop';
|
|
79
|
+
import { workspace } from './workspace';
|
|
67
80
|
|
|
68
|
-
function App() {
|
|
81
|
+
export default function App() {
|
|
69
82
|
return (
|
|
70
|
-
<
|
|
71
|
-
<
|
|
72
|
-
<
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
<SidePanelRenderer />
|
|
77
|
-
</PanelProvider>
|
|
78
|
-
</WindowManagerProvider>
|
|
83
|
+
<DockableDesktopProvider client={workspace}>
|
|
84
|
+
<div style={{ width: '100vw', height: '100vh' }}>
|
|
85
|
+
<WindowManager />
|
|
86
|
+
</div>
|
|
87
|
+
<ModalStackRenderer />
|
|
88
|
+
</DockableDesktopProvider>
|
|
79
89
|
);
|
|
80
90
|
}
|
|
81
91
|
```
|
|
82
92
|
|
|
83
|
-
|
|
93
|
+
> **Important:** the `WindowManager` container must have an explicit height. A `height: 100%` that resolves to zero will produce a development warning.
|
|
94
|
+
|
|
95
|
+
### 3. Open Panels
|
|
84
96
|
|
|
85
97
|
```ts
|
|
86
|
-
// From anywhere outside React:
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
//
|
|
92
|
-
|
|
93
|
-
|
|
98
|
+
// From anywhere — inside or outside React:
|
|
99
|
+
workspace.openPanel('map-1', 'map');
|
|
100
|
+
workspace.openPanel('ed-1', 'editor', { title: 'config.json', initialTarget: 'floating' });
|
|
101
|
+
workspace.focusPanel('map-1');
|
|
102
|
+
|
|
103
|
+
// Layout persistence:
|
|
104
|
+
localStorage.setItem('workspace-layout', workspace.saveLayout());
|
|
105
|
+
|
|
106
|
+
// Query state without a hook:
|
|
107
|
+
workspace.isOpen('map-1'); // boolean
|
|
108
|
+
workspace.getOpenPanelIds(); // string[]
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
Panels can now be dragged, split, tabbed, floated, and minimized out of the box.
|
|
112
|
+
|
|
113
|
+
---
|
|
114
|
+
|
|
115
|
+
## Writing a Panel Component
|
|
116
|
+
|
|
117
|
+
A panel is any React component. Use built-in hooks to integrate with the layout:
|
|
118
|
+
|
|
119
|
+
```tsx
|
|
120
|
+
import { useFormContainer, usePanelId } from 'react-dockable-desktop';
|
|
121
|
+
|
|
122
|
+
export default function EditorPanel() {
|
|
123
|
+
const panelId = usePanelId(); // this panel's instance ID — no prop needed
|
|
124
|
+
const { setDirty, setTitle } = useFormContainer();
|
|
125
|
+
|
|
126
|
+
const handleChange = (value: string) => {
|
|
127
|
+
setDirty(true); // blocks close until user confirms discard
|
|
128
|
+
setTitle('config.json *'); // updates the tab title live
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
return <textarea onChange={e => handleChange(e.target.value)} />;
|
|
132
|
+
}
|
|
94
133
|
```
|
|
95
134
|
|
|
96
135
|
---
|
|
97
136
|
|
|
98
137
|
## Hooks
|
|
99
138
|
|
|
100
|
-
|
|
139
|
+
Call these inside any component within the `DockableDesktopProvider` tree:
|
|
101
140
|
|
|
102
|
-
| Hook | Returns |
|
|
141
|
+
| Hook | Returns | Use For |
|
|
103
142
|
| :--- | :--- | :--- |
|
|
104
|
-
| `useWindowManagerActions()` | `WindowActions` | Open, close,
|
|
105
|
-
| `useWindowManagerState()` | `WindowState`
|
|
143
|
+
| `useWindowManagerActions()` | `WindowActions` | Open, close, float, dock, minimize, maximize, serialize panels |
|
|
144
|
+
| `useWindowManagerState(selector?)` | `WindowState` or selected slice | Read layout, floating windows, active panel ID |
|
|
145
|
+
| `usePanelActions()` | `PanelActions` | Open modal overlays and left/right side drawers |
|
|
146
|
+
| `usePanelContext()` | `{ publish, subscribe }` | Inter-panel typed event bus |
|
|
147
|
+
| `useFormContainer()` | `FormContainerContract` | Dirty state, close guards, dynamic panel title/icon |
|
|
148
|
+
| `usePanelId()` | `string` | The panel's own instance ID — no prop drilling needed |
|
|
149
|
+
| `useToolbar()` | `ToolbarContextValue` | Read/write Toolbar state (active tool, modifiers) from any panel |
|
|
150
|
+
| `useSidebar()` | `SidebarContextValue` | Open/close Sidebar tabs from any component in the Sidebar tree |
|
|
151
|
+
| `useSidebarTab()` | `SidebarTabContext` | Self-control for content inside a Sidebar tab |
|
|
152
|
+
| `usePanelContextMenu(items)` | `void` | Inject dynamic context menu items into this panel's right-click menu |
|
|
106
153
|
| `useRegistry()` | `PanelRegistryClass` | The scoped panel registry for the current provider |
|
|
107
|
-
| `
|
|
108
|
-
|
|
109
|
-
|
|
154
|
+
| `useFormatMessage()` | `MessageFormatter` | i18n formatter matching the current provider's locale |
|
|
155
|
+
|
|
156
|
+
**State selectors** prevent unnecessary re-renders:
|
|
157
|
+
|
|
158
|
+
```ts
|
|
159
|
+
// Only re-renders when activePanelId changes — not on every layout mutation:
|
|
160
|
+
const activeId = useWindowManagerState(s => s.activePanelId);
|
|
161
|
+
const panelCount = useWindowManagerState(s => Object.keys(s.panels).length);
|
|
162
|
+
```
|
|
110
163
|
|
|
111
164
|
---
|
|
112
165
|
|
|
113
|
-
##
|
|
166
|
+
## WorkspaceClient Reference
|
|
114
167
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
168
|
+
```ts
|
|
169
|
+
const workspace = new WorkspaceClient({ panels, initialState?, formatMessage?, dir? });
|
|
170
|
+
|
|
171
|
+
// Panel lifecycle
|
|
172
|
+
workspace.openPanel(id, component, options?) // options: title, initialTarget, stickyRight, stickyBottom
|
|
173
|
+
workspace.closePanel(id)
|
|
174
|
+
workspace.focusPanel(id) // raises floating / selects tab for docked
|
|
175
|
+
workspace.floatPanel(id, rect?) // detach to a floating window
|
|
176
|
+
workspace.dockPanel(id) // return floating to the grid
|
|
177
|
+
workspace.minimizePanel(id)
|
|
178
|
+
workspace.restorePanel(id)
|
|
179
|
+
workspace.maximizePanel(id)
|
|
180
|
+
|
|
181
|
+
// Synchronous state queries (no hook needed)
|
|
182
|
+
workspace.isOpen(id) // → boolean
|
|
183
|
+
workspace.getOpenPanelIds() // → string[]
|
|
184
|
+
|
|
185
|
+
// Layout persistence
|
|
186
|
+
workspace.saveLayout() // → JSON string
|
|
187
|
+
workspace.loadLayout(json) // → boolean (true = success)
|
|
188
|
+
|
|
189
|
+
// Event bus
|
|
190
|
+
workspace.publish(event, data)
|
|
191
|
+
workspace.subscribe(event, callback) // → unsubscribe()
|
|
192
|
+
workspace.onPanelOpen(cb)
|
|
193
|
+
workspace.onPanelClose(cb)
|
|
194
|
+
workspace.onPanelMinimize(cb)
|
|
195
|
+
workspace.onPanelRestore(cb)
|
|
196
|
+
|
|
197
|
+
// Direction
|
|
198
|
+
workspace.setDirection('ltr' | 'rtl')
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
---
|
|
119
202
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
-
|
|
126
|
-
|
|
203
|
+
## Layout Persistence
|
|
204
|
+
|
|
205
|
+
```ts
|
|
206
|
+
// Save on unload (or on any meaningful user action):
|
|
207
|
+
window.addEventListener('beforeunload', () => {
|
|
208
|
+
localStorage.setItem('workspace-layout', workspace.saveLayout());
|
|
209
|
+
});
|
|
127
210
|
|
|
128
|
-
|
|
211
|
+
// Restore by passing the saved string to the constructor:
|
|
212
|
+
new WorkspaceClient({
|
|
213
|
+
panels: { ... },
|
|
214
|
+
initialState: localStorage.getItem('workspace-layout'),
|
|
215
|
+
});
|
|
216
|
+
```
|
|
129
217
|
|
|
130
218
|
---
|
|
131
219
|
|
|
132
|
-
##
|
|
220
|
+
## Side Panels & Modals
|
|
133
221
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
222
|
+
Add `SidePanelRenderer` and `ModalStackRenderer` to your app root. Placement matters — `SidePanelRenderer` must be **inside** the workspace container so drawers position correctly; `ModalStackRenderer` goes **outside** as a full-screen overlay:
|
|
223
|
+
|
|
224
|
+
```tsx
|
|
225
|
+
// App.tsx
|
|
226
|
+
import { SidePanelRenderer, ModalStackRenderer } from 'react-dockable-desktop';
|
|
227
|
+
|
|
228
|
+
function App() {
|
|
229
|
+
return (
|
|
230
|
+
<DockableDesktopProvider client={workspace}>
|
|
231
|
+
<div style={{ width: '100vw', height: '100vh', overflow: 'hidden', position: 'relative' }}>
|
|
232
|
+
<WindowManager />
|
|
233
|
+
<SidePanelRenderer /> {/* inside — drawers position relative to this container */}
|
|
234
|
+
</div>
|
|
235
|
+
<ModalStackRenderer /> {/* outside — full-screen overlay */}
|
|
236
|
+
</DockableDesktopProvider>
|
|
237
|
+
);
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
// From any panel component:
|
|
241
|
+
const { openModal, openRightPanel } = usePanelActions();
|
|
242
|
+
|
|
243
|
+
openModal(MyForm, { itemId: 42 }, { title: 'Edit Item', size: 'medium' });
|
|
244
|
+
openRightPanel(PropertiesPanel, { nodeId }, { title: 'Properties', width: 320 });
|
|
137
245
|
```
|
|
138
246
|
|
|
139
247
|
---
|
|
140
248
|
|
|
249
|
+
## Touch & Mobile
|
|
250
|
+
|
|
251
|
+
Touch support is built in for v3.1.0+. No extra setup required:
|
|
252
|
+
|
|
253
|
+
- **Tab drag** — long-press (300ms) on any tab to start dragging; haptic feedback on supported devices
|
|
254
|
+
- **Floating window drag** — long-press the titlebar, then drag
|
|
255
|
+
- **Resize** — drag any of the 8 resize handles; minimum 44px touch targets throughout
|
|
256
|
+
- **Split resizer** — drag the 1px divider line; the hit area extends into the safe direction to avoid accidental tab activation
|
|
257
|
+
- **Tab bar scroll** — swipe horizontally in the tab strip to scroll when there are many tabs
|
|
258
|
+
|
|
259
|
+
---
|
|
260
|
+
|
|
261
|
+
## i18n & RTL
|
|
262
|
+
|
|
263
|
+
```tsx
|
|
264
|
+
<DockableDesktopProvider
|
|
265
|
+
dir="rtl"
|
|
266
|
+
formatMessage={(msg) => intl.formatMessage({ id: msg.id, defaultMessage: msg.defaultMessage })}
|
|
267
|
+
predefinedMessages={customMessages}
|
|
268
|
+
>
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
`dir` can be `'ltr'` (default) or `'rtl'`. All layout, split directions, tab ordering, drop zones, and context menus flip automatically. You can also switch at runtime:
|
|
272
|
+
|
|
273
|
+
```ts
|
|
274
|
+
workspace.setDirection('rtl');
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
---
|
|
278
|
+
|
|
279
|
+
## Skins
|
|
280
|
+
|
|
281
|
+
```tsx
|
|
282
|
+
<WindowManager skin="vscode" /> // default
|
|
283
|
+
<WindowManager skin="macos" />
|
|
284
|
+
<WindowManager skin="nord" />
|
|
285
|
+
<WindowManager skin="tokyo" />
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
| Skin | Character | Active state (Sidebar & Toolbar) |
|
|
289
|
+
|------|-----------|----------------------------------|
|
|
290
|
+
| `vscode` | VS Code dark (default) | Transparent fill, 2 px accent bar |
|
|
291
|
+
| `macos` | Glass Chip — accent fill, rounded corners | 36 px floating chip, white inner ring |
|
|
292
|
+
| `chrome` | Google Chrome tab geometry | Sidebar: half-pill bridge. Toolbar: 2 px bar |
|
|
293
|
+
| `slate` | Fluent Slate — deep navy | Floating 36 px accent-tinted pill |
|
|
294
|
+
| `nord` | Arctic Frost — muted Nord palette | Short horizontal line below icon |
|
|
295
|
+
| `obsidian` | Vercel Midnight — pure black/white | Deep glow + icon drop-shadow |
|
|
296
|
+
| `tokyo` | Tokyo Night — purple accent | Neon glow + vivid icon drop-shadow |
|
|
297
|
+
|
|
298
|
+
All built-in skins include dark and light variants. Create your own skin by overriding CSS custom properties under a `[data-workspace-skin="myskin"]` selector. See the [Theming Guide](https://felipecarrillo100.github.io/react-dockable-desktop/guide/theming) for the full variable reference and the [Per-skin active state guide](https://felipecarrillo100.github.io/react-dockable-desktop/guide/theming#per-skin-active-state-design-language) to customise the Sidebar/Toolbar active indicator in your own skin.
|
|
299
|
+
|
|
300
|
+
---
|
|
301
|
+
|
|
302
|
+
## What's New
|
|
303
|
+
|
|
304
|
+
### v3.2.0
|
|
305
|
+
- **Per-skin active state design language** — Sidebar tabs and Toolbar buttons now use a per-skin visual pattern (transparent bar, floating chip, pill, line, neon glow), driven by new CSS design tokens — fully overridable in custom skins. CSS-only, no API changes.
|
|
306
|
+
- **Documentation overhaul** — All guides updated to cover the full v3.1.0 API surface.
|
|
307
|
+
|
|
308
|
+
### v3.1.0
|
|
309
|
+
- **`<Toolbar>` component** — Vertical/horizontal strip hosting `action`, `radio`, `toggle`, `group`, and `separator` items. `useToolbar()` reads/writes state from any panel. `ToolbarGroupItem` adds a collapsed tool-family flyout with controlled mode support.
|
|
310
|
+
- **`<WindowManager taskbarVisibility>`** — Three modes: `'always'` (permanent bar, new default), `'compact'` (shows only with minimized panels), `'autohide'` (overlay bar with 8 px peek strip).
|
|
311
|
+
- **Sidebar resizable drawer** — Drag the drawer edge to resize. Props: `defaultWidth` (px), `minWidth`, `maxWidth`, `onWidthChange`. `drawerWidth` (string) deprecated.
|
|
312
|
+
- **Sidebar `visible` / `stripVisible`** — `visible` collapses the entire sidebar; `stripVisible` collapses only the activity bar. New handle methods: `showStrip()`, `hideStrip()`, `setWidth(px)`, `getWidth()`.
|
|
313
|
+
- **`useSidebar()` / `useSidebarTab()` hooks** — Programmatic Sidebar control from any component in the tree.
|
|
314
|
+
- **`usePanelContextMenu()` hook** — Inject dynamic right-click context menu items from inside a panel component.
|
|
315
|
+
- **Touch & iPad/Android support** — Pointer Events migration; long-press (300 ms) activates tab drag; taskbar chips support hover preview and long-press context menu on touch.
|
|
316
|
+
- **8-direction resize handles** — Floating windows now have N, NE, E, SE, S, SW, W, NW resize handles.
|
|
317
|
+
- **Skin scope fix** — `data-workspace-skin` now applied to `document.documentElement` so Toolbar and Sidebar always inherit the correct skin.
|
|
318
|
+
|
|
319
|
+
### v3.0.0
|
|
320
|
+
- **`DockableDesktopProvider`** — single composite provider replaces the manual `WindowManagerProvider + PanelProvider` nesting
|
|
321
|
+
- **RTL support** — `dir` prop on provider; `setDirection()` on client; full mirroring of all controls
|
|
322
|
+
- **State selectors** — `useWindowManagerState(s => s.activePanelId)` for surgical re-renders
|
|
323
|
+
- **Dynamic ModalStack** — clean overlay system with dirty-state close guards
|
|
324
|
+
- **`usePanelId()` hook** — zero-prop-drilling panel identity
|
|
325
|
+
- **Typed event bus** — `WorkspaceClient<AppEvents>` for type-safe inter-panel messaging
|
|
326
|
+
|
|
327
|
+
### v2.0.0 — Breaking Changes
|
|
328
|
+
|
|
329
|
+
| Removed | Replacement |
|
|
330
|
+
| :--- | :--- |
|
|
331
|
+
| `bringToFront(id)` | `focusPanel(id)` — works for both floating and docked panels |
|
|
332
|
+
| `setActivePanel(id)` | `focusPanel(id)` |
|
|
333
|
+
|
|
334
|
+
Full details in the [Migration Guide](https://felipecarrillo100.github.io/react-dockable-desktop/guide/migration).
|
|
335
|
+
|
|
336
|
+
---
|
|
337
|
+
|
|
141
338
|
## Documentation
|
|
142
339
|
|
|
143
|
-
|
|
340
|
+
Complete guides, API reference, and interactive demo at:
|
|
341
|
+
|
|
342
|
+
**[https://felipecarrillo100.github.io/react-dockable-desktop/](https://felipecarrillo100.github.io/react-dockable-desktop/)**
|
|
144
343
|
|
|
145
|
-
|
|
344
|
+
| Guide | Description |
|
|
345
|
+
| :--- | :--- |
|
|
346
|
+
| [Installation](https://felipecarrillo100.github.io/react-dockable-desktop/guide/installation) | Requirements, CSS import order, module formats |
|
|
347
|
+
| [Quick Start](https://felipecarrillo100.github.io/react-dockable-desktop/guide/quick-start) | Minimal working app with layout persistence |
|
|
348
|
+
| [WorkspaceClient](https://felipecarrillo100.github.io/react-dockable-desktop/guide/workspace-client) | Full imperative API, multiple providers, i18n config |
|
|
349
|
+
| [Panel Registry](https://felipecarrillo100.github.io/react-dockable-desktop/guide/panel-registry) | `defaultOptions`, scoped vs global registry |
|
|
350
|
+
| [Layout System](https://felipecarrillo100.github.io/react-dockable-desktop/guide/layout) | Opening, floating, minimizing, serializing layouts |
|
|
351
|
+
| [Panel Lifecycle & Forms](https://felipecarrillo100.github.io/react-dockable-desktop/guide/forms-and-panels) | Dirty state, close guards, `useFormContainer` |
|
|
352
|
+
| [Modals & Side Panels](https://felipecarrillo100.github.io/react-dockable-desktop/guide/modals-and-drawers) | Modal stack, drawers, `Sidebar` component |
|
|
353
|
+
| [Event Bus](https://felipecarrillo100.github.io/react-dockable-desktop/guide/event-bus) | Typed pub/sub, built-in lifecycle events |
|
|
354
|
+
| [Theming](https://felipecarrillo100.github.io/react-dockable-desktop/guide/theming) | CSS variables, custom skins, dark/light modes |
|
|
355
|
+
| [Advanced Topics](https://felipecarrillo100.github.io/react-dockable-desktop/guide/advanced) | RTL, multiple workspaces, custom header actions |
|
|
356
|
+
| [Best Practices](https://felipecarrillo100.github.io/react-dockable-desktop/guide/best-practices) | Patterns for production-ready implementations |
|
|
357
|
+
| [Migration Guide](https://felipecarrillo100.github.io/react-dockable-desktop/guide/migration) | Upgrade from v1 → v2 → v3 |
|
|
358
|
+
| [API Reference](https://felipecarrillo100.github.io/react-dockable-desktop/api/) | Full type-level reference for all exports |
|
|
359
|
+
|
|
360
|
+
---
|
|
146
361
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
362
|
+
## Development
|
|
363
|
+
|
|
364
|
+
```bash
|
|
365
|
+
git clone https://github.com/felipecarrillo100/react-dockable-desktop.git
|
|
366
|
+
cd react-dockable-desktop
|
|
367
|
+
npm install
|
|
368
|
+
npm run dev # Leaflet + Monaco open-source demo
|
|
369
|
+
npm run dev:ria # LuciadRIA 3D Earth demo (requires license)
|
|
370
|
+
npm test # vitest unit suite
|
|
371
|
+
npm run build # build dist/
|
|
372
|
+
```
|
|
152
373
|
|
|
153
374
|
---
|
|
154
375
|
|
|
155
376
|
## License
|
|
156
377
|
|
|
157
|
-
MIT
|
|
378
|
+
MIT — free to use, adapt, and build upon.
|