@gustavolmo/react-window-manager 0.1.0 → 0.1.1
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 +198 -0
- package/package.json +1 -1
package/README.md
ADDED
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
# React Window Manager
|
|
2
|
+
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
### Install the package
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
pnpm add @gustavolmo/react-window-manager
|
|
11
|
+
# or
|
|
12
|
+
npm install @gustavolmo/react-window-manager
|
|
13
|
+
# or
|
|
14
|
+
yarn add @gustavolmo/react-window-manager
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Requirements
|
|
18
|
+
|
|
19
|
+
### You must have:
|
|
20
|
+
|
|
21
|
+
- **React 18+ (or 19)**
|
|
22
|
+
- **React DOM**
|
|
23
|
+
- **Zustand**
|
|
24
|
+
|
|
25
|
+
Install it with
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
pnpm add react react-dom zustand
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
### Styling
|
|
32
|
+
|
|
33
|
+
This library ships with its own compiled CSS.
|
|
34
|
+
|
|
35
|
+
Import the stylesheet once at your application root:
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
import "@gustavolmo/react-window-manager/index.css"
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
The styling properties of compoents accept tailwind or regular css classes
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
## Overview
|
|
46
|
+
|
|
47
|
+
A lightweight desktop-style window manager built with:
|
|
48
|
+
|
|
49
|
+
- **React**
|
|
50
|
+
- **Zustand** (isolated state per window)
|
|
51
|
+
- A shared **WorkspaceLayout**
|
|
52
|
+
- Independent **WindowLayout** instances
|
|
53
|
+
- External **WindowButton** controllers
|
|
54
|
+
|
|
55
|
+
Each window instance is fully isolated, draggable, dockable, and externally controllable via its own store.
|
|
56
|
+
|
|
57
|
+
---
|
|
58
|
+
|
|
59
|
+
## 1. Create a Window Store
|
|
60
|
+
|
|
61
|
+
Initialize a window instance early (module scope recommended):
|
|
62
|
+
|
|
63
|
+
```ts
|
|
64
|
+
const myWindow = createWindowStore('window-my-id')
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
- The ID must be unique.
|
|
68
|
+
- The return value is a standard Zustand hook.
|
|
69
|
+
- Each window is automatically registered internally.
|
|
70
|
+
|
|
71
|
+
You can create multiple windows:
|
|
72
|
+
|
|
73
|
+
```ts
|
|
74
|
+
const firstWindow = createWindowStore('window-first')
|
|
75
|
+
const secondWindow = createWindowStore('window-second')
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
---
|
|
79
|
+
|
|
80
|
+
## 2. Wrap Everything in `WorkspaceLayout`
|
|
81
|
+
|
|
82
|
+
All windows must be rendered inside a shared workspace:
|
|
83
|
+
|
|
84
|
+
```tsx
|
|
85
|
+
<WorkspaceLayout>
|
|
86
|
+
{/* WindowLayout components */}
|
|
87
|
+
</WorkspaceLayout>
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
The workspace acts as:
|
|
91
|
+
|
|
92
|
+
- The rendering surface
|
|
93
|
+
- The stacking context
|
|
94
|
+
- The coordinate system for all windows
|
|
95
|
+
|
|
96
|
+
---
|
|
97
|
+
|
|
98
|
+
## 3. Render a Window
|
|
99
|
+
|
|
100
|
+
Use `WindowLayout` and pass:
|
|
101
|
+
|
|
102
|
+
- `useWindowStore` → the store instance
|
|
103
|
+
- `windowName` → title (string or ReactNode)
|
|
104
|
+
- `defaultDock` → initial docking behavior (optional)
|
|
105
|
+
|
|
106
|
+
```tsx
|
|
107
|
+
<WindowLayout
|
|
108
|
+
useWindowStore={myWindow}
|
|
109
|
+
windowName="My Window"
|
|
110
|
+
defaultDock="right"
|
|
111
|
+
>
|
|
112
|
+
<div>Any React content</div>
|
|
113
|
+
</WindowLayout>
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
Supported docking modes:
|
|
117
|
+
|
|
118
|
+
- `"left"`
|
|
119
|
+
- `"right"`
|
|
120
|
+
- `"full"`
|
|
121
|
+
|
|
122
|
+
Responsive docking can be computed:
|
|
123
|
+
|
|
124
|
+
```tsx
|
|
125
|
+
defaultDock={window.innerWidth < 800 ? 'full' : 'left'}
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
---
|
|
129
|
+
|
|
130
|
+
## 4. Control a Window with `WindowButton`
|
|
131
|
+
|
|
132
|
+
Place a control button anywhere in your UI:
|
|
133
|
+
|
|
134
|
+
```tsx
|
|
135
|
+
<WindowButton useWindowStore={myWindow}>
|
|
136
|
+
<p>Open Window</p>
|
|
137
|
+
</WindowButton>
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
- Multiple buttons can control the same window.
|
|
141
|
+
- Buttons are fully decoupled from layout.
|
|
142
|
+
- No prop drilling is required.
|
|
143
|
+
|
|
144
|
+
---
|
|
145
|
+
|
|
146
|
+
## 5. Access Window State
|
|
147
|
+
|
|
148
|
+
Since the store is a standard Zustand hook, you can read window state directly:
|
|
149
|
+
|
|
150
|
+
```ts
|
|
151
|
+
const { isDragging, isResizing } = myWindow()
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
Example use case:
|
|
155
|
+
|
|
156
|
+
```tsx
|
|
157
|
+
className={
|
|
158
|
+
isDragging || isResizing
|
|
159
|
+
? 'pointer-events-none'
|
|
160
|
+
: 'pointer-events-auto'
|
|
161
|
+
}
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
This is useful when embedding iframes or other complex interactive content.
|
|
165
|
+
|
|
166
|
+
---
|
|
167
|
+
|
|
168
|
+
## 6. Access via Registry (Optional)
|
|
169
|
+
|
|
170
|
+
Windows are also registered globally by ID:
|
|
171
|
+
|
|
172
|
+
```ts
|
|
173
|
+
const { isOpen } = windowRegistry['window-my-id']()
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
This is useful when you do not have direct access to the original store reference.
|
|
177
|
+
|
|
178
|
+
---
|
|
179
|
+
|
|
180
|
+
## Architecture Summary
|
|
181
|
+
|
|
182
|
+
- `createWindowStore(id)` → creates isolated window state
|
|
183
|
+
- `WorkspaceLayout` → shared window surface
|
|
184
|
+
- `WindowLayout` → draggable and dockable container
|
|
185
|
+
- `WindowButton` → external controller
|
|
186
|
+
- Zustand → reactive state management
|
|
187
|
+
|
|
188
|
+
---
|
|
189
|
+
|
|
190
|
+
## Design Principles
|
|
191
|
+
|
|
192
|
+
- Fully decoupled window instances
|
|
193
|
+
- No global prop chains
|
|
194
|
+
- Arbitrary React content support (apps, iframes, components)
|
|
195
|
+
- Independent lifecycle per window
|
|
196
|
+
- Scalable to many concurrent windows
|
|
197
|
+
|
|
198
|
+
This enables building browser-based desktop-style interfaces with minimal setup and clean separation of concerns.
|