react-dockable-desktop 1.2.0 β 2.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 +157 -365
- package/dist/index.cjs +3 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +337 -34
- package/dist/index.d.ts +337 -34
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/styles.css +15 -15
- package/package.json +13 -6
package/README.md
CHANGED
|
@@ -1,365 +1,157 @@
|
|
|
1
|
-
# React Dockable Desktop
|
|
2
|
-
|
|
3
|
-
[](#)
|
|
5
|
-
[](https://felipecarrillo100.github.io/react-dockable-desktop/)
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
---
|
|
28
|
-
|
|
29
|
-
##
|
|
30
|
-
|
|
31
|
-
```bash
|
|
32
|
-
npm install react-dockable-desktop replace-react-contexify
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
```
|
|
38
|
-
import 'replace-react-contexify/styles.css';
|
|
39
|
-
import 'react-dockable-desktop/styles.css';
|
|
40
|
-
```
|
|
41
|
-
|
|
42
|
-
---
|
|
43
|
-
|
|
44
|
-
##
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
</
|
|
79
|
-
);
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
```
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
<div style={{ width: '100vw', height: '100vh' }}>
|
|
159
|
-
<Desktop />
|
|
160
|
-
</div>
|
|
161
|
-
</WindowManagerProvider>
|
|
162
|
-
);
|
|
163
|
-
}
|
|
164
|
-
```
|
|
165
|
-
|
|
166
|
-
*If no `formatMessage` function is provided, the engine defaults to a fallback formatting template parser resolving placeholders like `Hello {user}` using values.*
|
|
167
|
-
|
|
168
|
-
### Right-to-Left (RTL) Layout Support
|
|
169
|
-
|
|
170
|
-
The library features built-in, theme-resilient Right-to-Left (RTL) rendering. It automatically mirrors tab stacking flows, close icon alignments, custom header buttons, side drawers (which slide in from the opposite edge), titlebars, and taskbar icons.
|
|
171
|
-
|
|
172
|
-
#### 1. Automatic Detection (Zero Configuration)
|
|
173
|
-
Simply apply the HTML `dir="rtl"` attribute to the container enclosing your layout, or globally on the `<html>`/`<body>` nodes. The workspace will observe it using a `MutationObserver` and mirror dynamically:
|
|
174
|
-
```html
|
|
175
|
-
<div dir="rtl">
|
|
176
|
-
<Desktop />
|
|
177
|
-
</div>
|
|
178
|
-
```
|
|
179
|
-
|
|
180
|
-
#### 2. Explicit Programmatic Control
|
|
181
|
-
To force a specific direction regardless of the surrounding HTML structure, pass the `dir` prop directly to the provider:
|
|
182
|
-
```typescript
|
|
183
|
-
<WindowManagerProvider dir="rtl">
|
|
184
|
-
<Desktop />
|
|
185
|
-
</WindowManagerProvider>
|
|
186
|
-
```
|
|
187
|
-
|
|
188
|
-
---
|
|
189
|
-
|
|
190
|
-
## ποΈ Programmatic Spawning and Layout API
|
|
191
|
-
|
|
192
|
-
Consume actions from the layout context anywhere inside or outside your panel components using the provided hooks.
|
|
193
|
-
|
|
194
|
-
```typescript
|
|
195
|
-
import { useWindowManagerActions, useWindowManagerState } from 'react-dockable-desktop';
|
|
196
|
-
|
|
197
|
-
const SidebarControls = () => {
|
|
198
|
-
const { openPanel, closePanel, saveLayout, loadLayout } = useWindowManagerActions();
|
|
199
|
-
const state = useWindowManagerState();
|
|
200
|
-
|
|
201
|
-
const handleOpenConsole = () => {
|
|
202
|
-
openPanel('debug-console', 'terminal', {
|
|
203
|
-
title: { id: 'app.console', defaultMessage: 'System Console Log' },
|
|
204
|
-
initialTarget: 'floating' // Options: 'docked' | 'floating' | 'tabbed'
|
|
205
|
-
});
|
|
206
|
-
};
|
|
207
|
-
|
|
208
|
-
return (
|
|
209
|
-
<div>
|
|
210
|
-
<button onClick={handleOpenConsole}>Spawn Console</button>
|
|
211
|
-
<button onClick={() => alert(saveLayout())}>Backup Layout</button>
|
|
212
|
-
</div>
|
|
213
|
-
);
|
|
214
|
-
};
|
|
215
|
-
```
|
|
216
|
-
|
|
217
|
-
### Hook Reference
|
|
218
|
-
|
|
219
|
-
| Hook Name | Return Type | Description |
|
|
220
|
-
| :--- | :--- | :--- |
|
|
221
|
-
| `useWindowManagerState()` | `WindowState` | Access grid layout trees, list of active floating windows, minimized windows list, and general dragging statuses. |
|
|
222
|
-
| `useWindowManagerActions()` | `WindowActions` | Spawns, minimizes, restores, docks, floats, maximizes, or closes panels. Also handles split sizing, custom locations, and layout serialization (`saveLayout` / `loadLayout`). |
|
|
223
|
-
| `useFormatMessage()` | `(msg: ContextMenuPredefinedMessage) => string` | Returns the translation message formatter hook matching the provider preset configuration. |
|
|
224
|
-
| `usePanelContext()` | `{ publish, subscribe }` | Dynamic decoupled event bus helper for active panels. |
|
|
225
|
-
| `useStyleClasses()` | `StyleClasses` | Returns the custom CSS class overrides configured on the provider (`windowClass`, `windowBodyClass`, etc.). |
|
|
226
|
-
|
|
227
|
-
---
|
|
228
|
-
|
|
229
|
-
## π‘οΈ Form Container Context (Close Interception & Dirty States)
|
|
230
|
-
|
|
231
|
-
`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.
|
|
232
|
-
|
|
233
|
-
### Context Hook Functions
|
|
234
|
-
|
|
235
|
-
| Function / Property | Type | Description |
|
|
236
|
-
| :--- | :--- | :--- |
|
|
237
|
-
| `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. |
|
|
238
|
-
| `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. |
|
|
239
|
-
| `setTitle(title)` | `(title: string \| ContextMenuPredefinedMessage) => void` | Overrides the tab / window title dynamically from the child element. |
|
|
240
|
-
| `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. |
|
|
241
|
-
| `instanceId` | `string` | The unique ID of the panel. |
|
|
242
|
-
|
|
243
|
-
### Implementation Example
|
|
244
|
-
|
|
245
|
-
```typescript
|
|
246
|
-
import React, { useState, useEffect } from 'react';
|
|
247
|
-
import { useFormContainer } from 'react-dockable-desktop';
|
|
248
|
-
|
|
249
|
-
const EditFormPanel: React.FC = () => {
|
|
250
|
-
const container = useFormContainer();
|
|
251
|
-
const [text, setText] = useState('');
|
|
252
|
-
|
|
253
|
-
// 1. Mark dirty when typing
|
|
254
|
-
const handleChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {
|
|
255
|
-
setText(e.target.value);
|
|
256
|
-
container.setDirty(true); // Appends '*' to tab header and prompts warning on close
|
|
257
|
-
};
|
|
258
|
-
|
|
259
|
-
const handleSave = () => {
|
|
260
|
-
container.setDirty(false); // Resets dirty state
|
|
261
|
-
alert('Saved successfully!');
|
|
262
|
-
};
|
|
263
|
-
|
|
264
|
-
// 2. Intercept and block closing based on conditions
|
|
265
|
-
useEffect(() => {
|
|
266
|
-
const unregister = container.onCloseRequested(() => {
|
|
267
|
-
if (text.includes('BLOCK')) {
|
|
268
|
-
alert('Cannot close while the word "BLOCK" is present!');
|
|
269
|
-
return false; // Blocks closure
|
|
270
|
-
}
|
|
271
|
-
return true; // Allows closure
|
|
272
|
-
});
|
|
273
|
-
return unregister;
|
|
274
|
-
}, [container, text]);
|
|
275
|
-
|
|
276
|
-
return (
|
|
277
|
-
<div style={{ padding: '1rem', color: '#fff' }}>
|
|
278
|
-
<h5>Dynamic Form Editor</h5>
|
|
279
|
-
<textarea value={text} onChange={handleChange} />
|
|
280
|
-
<button onClick={handleSave}>Save</button>
|
|
281
|
-
<button onClick={() => container.requestClose()}>Cancel & Close</button>
|
|
282
|
-
</div>
|
|
283
|
-
);
|
|
284
|
-
};
|
|
285
|
-
```
|
|
286
|
-
|
|
287
|
-
---
|
|
288
|
-
|
|
289
|
-
## π Inter-Panel Event Communication Bus
|
|
290
|
-
|
|
291
|
-
Avoid complex state management boilerplate. Active panels can broadcast lightweight messages across the workspace seamlessly:
|
|
292
|
-
|
|
293
|
-
```typescript
|
|
294
|
-
import React, { useEffect } from 'react';
|
|
295
|
-
import { usePanelContext } from 'react-dockable-desktop';
|
|
296
|
-
|
|
297
|
-
// Subscriber Panel (e.g. Console Log Viewer)
|
|
298
|
-
const ConsoleView: React.FC = () => {
|
|
299
|
-
const { subscribe } = usePanelContext();
|
|
300
|
-
|
|
301
|
-
useEffect(() => {
|
|
302
|
-
const unsubscribe = subscribe('CONSOLE_LOG', (payload) => {
|
|
303
|
-
console.log('Received log message: ', payload.message);
|
|
304
|
-
});
|
|
305
|
-
return () => unsubscribe();
|
|
306
|
-
}, [subscribe]);
|
|
307
|
-
|
|
308
|
-
return <div>Console Viewer</div>;
|
|
309
|
-
};
|
|
310
|
-
|
|
311
|
-
// Publisher Panel (e.g. Map View)
|
|
312
|
-
const MapView: React.FC = () => {
|
|
313
|
-
const { publish } = usePanelContext();
|
|
314
|
-
|
|
315
|
-
const handleInteract = () => {
|
|
316
|
-
publish('CONSOLE_LOG', { message: 'User zoomed map viewport.' });
|
|
317
|
-
};
|
|
318
|
-
|
|
319
|
-
return <button onClick={handleInteract}>Click Map</button>;
|
|
320
|
-
};
|
|
321
|
-
```
|
|
322
|
-
|
|
323
|
-
---
|
|
324
|
-
|
|
325
|
-
## π¨ Layout Presets & Configuration Options
|
|
326
|
-
|
|
327
|
-
You can customized defaults, positioning attributes, and sizes using the registry builder options:
|
|
328
|
-
|
|
329
|
-
```typescript
|
|
330
|
-
PanelRegistry.register('unique-panel-key', PanelComponent, {
|
|
331
|
-
title: 'Default Title String', // fallback
|
|
332
|
-
canMinimize: true,
|
|
333
|
-
canDrag: true,
|
|
334
|
-
canClose: true,
|
|
335
|
-
initialTarget: 'docked', // or 'floating'
|
|
336
|
-
favoritePosition: {
|
|
337
|
-
x: 400,
|
|
338
|
-
y: 200,
|
|
339
|
-
width: 500,
|
|
340
|
-
height: 350
|
|
341
|
-
}
|
|
342
|
-
});
|
|
343
|
-
```
|
|
344
|
-
|
|
345
|
-
To customize CSS layout attributes, you can override variables in your stylesheet:
|
|
346
|
-
```css
|
|
347
|
-
:root {
|
|
348
|
-
--accent-color: #00f0ff;
|
|
349
|
-
--bg-dark-color: #12131a;
|
|
350
|
-
--glass-bg: rgba(18, 19, 26, 0.65);
|
|
351
|
-
--border-color: rgba(255, 255, 255, 0.08);
|
|
352
|
-
}
|
|
353
|
-
```
|
|
354
|
-
|
|
355
|
-
---
|
|
356
|
-
|
|
357
|
-
## π Architecture
|
|
358
|
-
|
|
359
|
-
For a deep-dive into the layout tree model, DOM persistence strategy, overlay system, RTL detection, and build pipeline, see [ARCHITECTURE.md](ARCHITECTURE.md).
|
|
360
|
-
|
|
361
|
-
---
|
|
362
|
-
|
|
363
|
-
## π License
|
|
364
|
-
|
|
365
|
-
MIT. Free to use, adapt, and build upon.
|
|
1
|
+
# React Dockable Desktop
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/react-dockable-desktop)
|
|
4
|
+
[](#license)
|
|
5
|
+
[](https://felipecarrillo100.github.io/react-dockable-desktop/demo/)
|
|
6
|
+
[](https://felipecarrillo100.github.io/react-dockable-desktop/)
|
|
7
|
+
|
|
8
|
+
A premium React window manager and dockable layout engine. Fluid split-docking grids, resizable floating windows, dynamic taskbars, and tabbed panels with **zero-unmount DOM persistence** and **built-in i18n/RTL support**.
|
|
9
|
+
|
|
10
|
+
**[Full Documentation](https://felipecarrillo100.github.io/react-dockable-desktop/)** |
|
|
11
|
+
**[Live Demo](https://felipecarrillo100.github.io/react-dockable-desktop/demo/)** |
|
|
12
|
+
**[API Reference](https://felipecarrillo100.github.io/react-dockable-desktop/api/)**
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## Key Features
|
|
17
|
+
|
|
18
|
+
- **Dockable Splits & Tab Grid** β drag panels to split screens or group them into tabbed containers
|
|
19
|
+
- **Workspace Edge Docking** β drag to outer edges to dock as full-width/height columns or rows
|
|
20
|
+
- **Floating Windows** β pop panels into resizable floating windows with maximize and minimize
|
|
21
|
+
- **Zero-Unmount DOM Persistence** β WebGL, maps, terminals, and stateful forms keep their DOM node and state when moved
|
|
22
|
+
- **i18n & RTL** β full Right-to-Left layout support with automatic `dir="rtl"` detection
|
|
23
|
+
- **Inter-Panel Pub/Sub** β decoupled lightweight messaging between active panels
|
|
24
|
+
- **Imperative API** β `WorkspaceClient` lets you open, close, focus, and serialize panels from anywhere outside React
|
|
25
|
+
- **Layout Serialization** β save/restore the full workspace layout as a JSON string
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## Installation
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
npm install react-dockable-desktop replace-react-contexify
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Import styles in your entry file:
|
|
36
|
+
|
|
37
|
+
```ts
|
|
38
|
+
import 'replace-react-contexify/styles.css';
|
|
39
|
+
import 'react-dockable-desktop/styles.css';
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
## Quick Start
|
|
45
|
+
|
|
46
|
+
### 1. Create a WorkspaceClient
|
|
47
|
+
|
|
48
|
+
```ts
|
|
49
|
+
import { WorkspaceClient } from 'react-dockable-desktop';
|
|
50
|
+
import MapPanel from './panels/MapPanel';
|
|
51
|
+
import EditorPanel from './panels/EditorPanel';
|
|
52
|
+
|
|
53
|
+
export const client = new WorkspaceClient({
|
|
54
|
+
panels: {
|
|
55
|
+
map: { component: MapPanel, defaultOptions: { title: 'Map View' } },
|
|
56
|
+
editor: { component: EditorPanel, defaultOptions: { title: 'Editor' } },
|
|
57
|
+
},
|
|
58
|
+
initialState: localStorage.getItem('workspace-layout'),
|
|
59
|
+
});
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### 2. Mount the Provider
|
|
63
|
+
|
|
64
|
+
```tsx
|
|
65
|
+
import { WindowManagerProvider, WindowManager, PanelProvider, ModalStackRenderer, SidePanelRenderer } from 'react-dockable-desktop';
|
|
66
|
+
import { client } from './workspaceClient';
|
|
67
|
+
|
|
68
|
+
function App() {
|
|
69
|
+
return (
|
|
70
|
+
<WindowManagerProvider client={client}>
|
|
71
|
+
<PanelProvider>
|
|
72
|
+
<div style={{ width: '100vw', height: '100vh' }}>
|
|
73
|
+
<WindowManager />
|
|
74
|
+
</div>
|
|
75
|
+
<ModalStackRenderer />
|
|
76
|
+
<SidePanelRenderer />
|
|
77
|
+
</PanelProvider>
|
|
78
|
+
</WindowManagerProvider>
|
|
79
|
+
);
|
|
80
|
+
}
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### 3. Open Panels Imperatively
|
|
84
|
+
|
|
85
|
+
```ts
|
|
86
|
+
// From anywhere outside React:
|
|
87
|
+
client.openPanel('map-1', 'map', { title: 'Satellite View' });
|
|
88
|
+
client.focusPanel('map-1');
|
|
89
|
+
client.saveLayout();
|
|
90
|
+
|
|
91
|
+
// Query state:
|
|
92
|
+
client.isOpen('map-1'); // boolean
|
|
93
|
+
client.getOpenPanelIds(); // string[]
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
---
|
|
97
|
+
|
|
98
|
+
## Hooks
|
|
99
|
+
|
|
100
|
+
Use these inside any component within the provider tree:
|
|
101
|
+
|
|
102
|
+
| Hook | Returns | Description |
|
|
103
|
+
| :--- | :--- | :--- |
|
|
104
|
+
| `useWindowManagerActions()` | `WindowActions` | Open, close, focus, dock, float, minimize, maximize, serialize panels |
|
|
105
|
+
| `useWindowManagerState()` | `WindowState` | Reactive access to grid layout, floating windows, minimized panels |
|
|
106
|
+
| `useRegistry()` | `PanelRegistryClass` | The scoped panel registry for the current provider |
|
|
107
|
+
| `usePanelContext()` | `{ publish, subscribe }` | Inter-panel pub/sub event bus |
|
|
108
|
+
| `useFormContainer()` | `FormContainerContract` | Dirty-state tracking, dynamic title overrides, close guards |
|
|
109
|
+
| `useFormatMessage()` | `(msg) => string` | Translation formatter matching the provider's i18n config |
|
|
110
|
+
|
|
111
|
+
---
|
|
112
|
+
|
|
113
|
+
## v2.0.0 β Breaking Changes
|
|
114
|
+
|
|
115
|
+
| Removed | Replacement |
|
|
116
|
+
| :--- | :--- |
|
|
117
|
+
| `bringToFront(id)` | `focusPanel(id)` β works for both floating and docked panels |
|
|
118
|
+
| `setActivePanel(id)` on `WindowActions` | `focusPanel(id)` |
|
|
119
|
+
|
|
120
|
+
**New in v2.0.0:**
|
|
121
|
+
- `focusPanel(id)` β unified "show this panel" method
|
|
122
|
+
- `isOpen(id): boolean` β synchronous panel state query
|
|
123
|
+
- `getOpenPanelIds(): string[]` β list all open panel IDs
|
|
124
|
+
- Pending-call queue: imperative calls before the provider mounts are automatically buffered and replayed
|
|
125
|
+
- DEV-mode warning if `client=` prop is missing on the provider
|
|
126
|
+
- DEV-mode warning if `replace-react-contexify` CSS is not detected
|
|
127
|
+
|
|
128
|
+
See the [Migration Guide](https://felipecarrillo100.github.io/react-dockable-desktop/guide/migration) for the full list of changes.
|
|
129
|
+
|
|
130
|
+
---
|
|
131
|
+
|
|
132
|
+
## Demo Environments
|
|
133
|
+
|
|
134
|
+
```bash
|
|
135
|
+
npm run dev # Leaflet + Monaco open-source demo
|
|
136
|
+
npm run dev:ria # LuciadRIA 3D Earth demo (requires license)
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
---
|
|
140
|
+
|
|
141
|
+
## Documentation
|
|
142
|
+
|
|
143
|
+
Full narrative guides, API reference, and the interactive demo are published at:
|
|
144
|
+
|
|
145
|
+
**https://felipecarrillo100.github.io/react-dockable-desktop/**
|
|
146
|
+
|
|
147
|
+
- [Getting Started](https://felipecarrillo100.github.io/react-dockable-desktop/guide/)
|
|
148
|
+
- [WorkspaceClient Guide](https://felipecarrillo100.github.io/react-dockable-desktop/guide/workspace-client)
|
|
149
|
+
- [Layout System](https://felipecarrillo100.github.io/react-dockable-desktop/guide/layout)
|
|
150
|
+
- [API Reference](https://felipecarrillo100.github.io/react-dockable-desktop/api/)
|
|
151
|
+
- [Migration v1 β v2](https://felipecarrillo100.github.io/react-dockable-desktop/guide/migration)
|
|
152
|
+
|
|
153
|
+
---
|
|
154
|
+
|
|
155
|
+
## License
|
|
156
|
+
|
|
157
|
+
MIT. Free to use, adapt, and build upon.
|