@maomaolabs/core 1.0.1 → 1.0.2

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.
Files changed (2) hide show
  1. package/README.md +123 -110
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -1,61 +1,65 @@
1
1
  <div align="center">
2
- <h1>@maomaolabs/core</h1>
3
2
 
4
- <p>
5
- <strong>A standalone lightweight React library that brings a complete, performant, and responsive desktop window management experience to the web.</strong>
6
- </p>
3
+ <img src="./docs/assets/0.gif" alt="@maomaolabs/core — Desktop Window Management for the Web" width="100%" style="border-radius: 12px;" />
7
4
 
8
- <p align="center">
9
- <img src="./docs/assets/0.gif" alt="MaoMao OS Desktop Experience" width="100%" style="border-radius: 8px;" />
10
- </p>
5
+ <h1>@maomaolabs/core</h1>
6
+
7
+ <p><strong>A standalone, lightweight React library that brings a complete desktop window management experience to the web.</strong><br/>Drag, resize, snap, minimize, maximize — all performant and mobile-ready out of the box.</p>
11
8
 
12
9
  <p>
13
10
  <a href="https://www.npmjs.com/package/@maomaolabs/core"><img src="https://img.shields.io/npm/v/@maomaolabs/core?style=for-the-badge&color=000000" alt="NPM Version" /></a>
14
- <a href="https://github.com/maomaolabs/core/blob/main/LICENSE"><img src="https://img.shields.io/npm/l/@maomaolabs/core?style=for-the-badge&color=000000" alt="License" /></a>
11
+ <a href="https://github.com/maomaolabs/core/blob/main/LICENSE"><img src="https://img.shields.io/npm/l/@maomaolabs/core?style=for-the-badge&color=000" alt="License" /></a>
15
12
  <img src="https://img.shields.io/badge/React-18.0.0+-blue?style=for-the-badge&logo=react&color=000000" alt="React 18+" />
16
13
  </p>
17
- </div>
18
-
19
- <br />
20
14
 
21
- ## ✨ Key Features
22
-
23
- **Uncompromised performance**
24
- Zero unnecessary re-renders thanks to context splitting (`useWindows` vs `useWindowActions`).
25
- <p align="center">
26
- <img src="./docs/assets/1.png" alt="Performance architecture diagram" width="100%" style="border-radius: 8px;" />
27
- </p>
28
-
29
- **Complete window lifecycle**
30
- Seamlessly open, close, minimize, maximize, resize, and drag windows.
31
- <p align="center">
32
- <img src="./docs/assets/4.gif" alt="Window lifecycle demonstration" width="100%" style="border-radius: 8px;" />
33
- </p>
15
+ </div>
34
16
 
35
- **Built-in snapping**
36
- Native-feeling edge snapping (half screen) and corner snapping (quarter screen) functionality.
37
- <p align="center">
38
- <img src="./docs/assets/5.gif" alt="Window snapping demonstration" width="100%" style="border-radius: 8px;" />
39
- </p>
17
+ ---
40
18
 
41
- **Responsive design**
42
- Automatically adapts interactions for mobile and desktop environments.
43
- <p align="center">
44
- <img src="./docs/assets/6.png" alt="Responsive design showcase" width="300" style="border-radius: 8px; box-shadow: 0 4px 12px rgba(0,0,0,0.1);" />
45
- </p>
19
+ ## ✨ Features
20
+
21
+ <table>
22
+ <tr>
23
+ <td width="50%">
24
+ <h3>⚡ Zero unnecessary re-renders</h3>
25
+ Context is split into <code>useWindows</code> (state) and <code>useWindowActions</code> (actions). Components that only dispatch actions never re-render on state changes.
26
+ <br/><br/>
27
+ <img src="./docs/assets/1.png" alt="Performance architecture" width="100%" style="border-radius: 8px;" />
28
+ </td>
29
+ <td width="50%">
30
+ <h3>🪟 Complete window lifecycle</h3>
31
+ Open, close, minimize, maximize, drag and resize windows with native-feeling interactions on both desktop and mobile.
32
+ <br/><br/>
33
+ <img src="./docs/assets/4.gif" alt="Window lifecycle" width="100%" style="border-radius: 8px;" />
34
+ </td>
35
+ </tr>
36
+ <tr>
37
+ <td width="50%" valign="top">
38
+ <h3>🧲 Built-in snapping</h3>
39
+ Half-screen (edge) and quarter-screen (corner) snapping with real-time preview overlays, just like a native OS.
40
+ <br/><br/>
41
+ <img src="./docs/assets/5.gif" alt="Window snapping" width="100%" style="border-radius: 8px;" />
42
+ </td>
43
+ <td width="50%" valign="top">
44
+ <h3>🧰 Out-of-the-box Toolbar</h3>
45
+ A fully customizable taskbar that handles individual app launchers, folder groupings, and minimized window management.
46
+ <br/><br/>
47
+ <img src="./docs/assets/7.png" alt="Toolbar" width="100%" style="border-radius: 8px;" />
48
+ </td>
49
+ </tr>
50
+ </table>
46
51
 
47
- **Out-of-the-box Toolbar**
48
- A highly customizable taskbar handling both individual apps and folder groupings.
49
- <p align="center">
50
- <img src="./docs/assets/7.png" alt="Toolbar demonstration" width="100%" style="border-radius: 8px;" />
51
- </p>
52
+ <div align="center">
53
+ <h3>📱 Responsive by default</h3>
54
+ Interactions automatically adapt between mouse and touch environments. No configuration needed.
55
+ <br/><br/>
56
+ <img src="./docs/assets/6.png" alt="Responsive design" width="320" style="border-radius: 8px;" />
57
+ </div>
52
58
 
53
59
  ---
54
60
 
55
61
  ## 📦 Installation
56
62
 
57
- Install via your preferred package manager (requires `react` and `react-dom` >= 18.0.0):
58
-
59
63
  ```bash
60
64
  npm install @maomaolabs/core
61
65
  # or
@@ -64,24 +68,24 @@ yarn add @maomaolabs/core
64
68
  pnpm add @maomaolabs/core
65
69
  ```
66
70
 
71
+ > Requires `react` and `react-dom` >= 18.0.0 as peer dependencies.
72
+
67
73
  ---
68
74
 
69
75
  ## 🚀 Quick Start
70
76
 
71
- Get a window running in under 30 seconds:
72
-
73
77
  ```tsx
74
78
  import { WindowSystemProvider, WindowManager, useWindowActions } from '@maomaolabs/core';
75
- import '@maomaolabs/core/dist/style.css'; // Critical for native feeling interactions
79
+ import '@maomaolabs/core/dist/style.css';
76
80
 
77
81
  const AppLauncher = () => {
78
82
  const { openWindow } = useWindowActions();
79
83
 
80
84
  return (
81
- <button onClick={() => openWindow({
82
- id: 'hello',
83
- title: 'Hello',
84
- component: <div>World!</div>
85
+ <button onClick={() => openWindow({
86
+ id: 'hello',
87
+ title: 'Hello World',
88
+ component: <div>Hello from a managed window!</div>
85
89
  })}>
86
90
  Launch App
87
91
  </button>
@@ -98,26 +102,26 @@ export default function App() {
98
102
  }
99
103
  ```
100
104
 
105
+ > ⚠️ Don't forget the CSS import — it's required for drag, resize, and snap overlays to work correctly.
106
+
101
107
  ---
102
108
 
103
- ## 📖 Detailed Usage Guide
109
+ ## 📖 Usage Guide
104
110
 
105
- ### Integrating the Toolbar
111
+ ### With Toolbar
106
112
 
107
- For a full desktop experience, include the `Toolbar` component to manage minimized windows and app launchers, including folder support.
113
+ The `Toolbar` component provides a ready-made taskbar with app launchers, folder support, and minimized window restoration.
108
114
 
109
- <p align="center">
110
- <img src="./docs/assets/2.png" alt="Toolbar integration overview" width="100%" style="border-radius: 8px;" />
111
- </p>
115
+ <img src="./docs/assets/2.png" alt="Toolbar integration" width="100%" style="border-radius: 8px;" />
112
116
 
113
117
  ```tsx
114
118
  import { WindowSystemProvider, WindowManager, Toolbar } from '@maomaolabs/core';
115
119
 
116
120
  const DESKTOP_ITEMS = [
117
121
  {
118
- id: 'browser-app',
122
+ id: 'browser',
119
123
  title: 'Browser',
120
- component: <div />, // Your app component
124
+ component: <div />,
121
125
  initialSize: { width: 800, height: 600 }
122
126
  },
123
127
  {
@@ -141,18 +145,18 @@ export default function Desktop() {
141
145
 
142
146
  ### Accessing Window State
143
147
 
144
- If you need to render UI based on currently open windows (e.g., a custom taskbar), use the `useWindows` hook. **Warning**: This triggers a re-render on any window state change (drag, resize, etc).
148
+ Use `useWindows` when you need to render UI based on open windows (e.g., a custom taskbar or badge counter).
145
149
 
146
- <p align="center">
147
- <img src="./docs/assets/3.png" alt="Window state management diagram" width="100%" style="border-radius: 8px;" />
148
- </p>
150
+ <img src="./docs/assets/3.png" alt="Window state access" width="100%" style="border-radius: 8px;" />
151
+
152
+ > ⚠️ **Warning:** `useWindows` triggers a re-render on **every** window state change (drag, resize, focus). Only use it where necessary.
149
153
 
150
154
  ```tsx
151
155
  import { useWindows } from '@maomaolabs/core';
152
156
 
153
157
  const OpenAppCounter = () => {
154
158
  const windows = useWindows();
155
- return <div>Active apps: {windows.length}</div>;
159
+ return <div>Active windows: {windows.length}</div>;
156
160
  };
157
161
  ```
158
162
 
@@ -160,80 +164,89 @@ const OpenAppCounter = () => {
160
164
 
161
165
  ## 📚 API Reference
162
166
 
163
- ### Core Components
167
+ ### Components
164
168
 
165
169
  | Component | Description | Props |
166
170
  | :--- | :--- | :--- |
167
- | `WindowSystemProvider` | Context provider required for the window system. Wrap your app with this. | `children: ReactNode` |
168
- | `WindowManager` | Renders active windows and snap overlays. Must be inside the provider. | *None* |
169
- | `Toolbar` | Renders the taskbar with app launchers and manages minimized windows. | `toolbarItems: ToolbarItem[]`, `showLogo?: boolean` |
171
+ | `WindowSystemProvider` | Root context provider. Wrap your entire app with this. | `children: ReactNode` |
172
+ | `WindowManager` | Renders all active windows and snap preview overlays. | |
173
+ | `Toolbar` | Taskbar with app launchers and folder support. | `toolbarItems: ToolbarItem[]`, `showLogo?: boolean` |
170
174
 
171
- ### Core Hooks
175
+ ### Hooks
172
176
 
173
- **`useWindowActions()`**
174
- Returns an object with methods to manipulate windows without subscribing to window state changes.
175
- - `openWindow(window: WindowDefinition): void` - Opens a new window or focuses it if already open.
176
- - `closeWindow(id: string): void` - Destroys a window instance.
177
- - `focusWindow(id: string): void` - Brings a window to the top of the z-index stack.
178
- - `updateWindow(id: string, data: Partial<WindowInstance>): void` - Patches an existing window's state.
177
+ #### `useWindowActions()`
178
+ Returns window manipulation methods. **Does not subscribe to window state** safe to call anywhere without performance concerns.
179
179
 
180
- **`useWindows()`**
181
- - Returns: `WindowInstance[]` - The list of all currently active window instances.
180
+ | Method | Signature | Description |
181
+ | :--- | :--- | :--- |
182
+ | `openWindow` | `(window: WindowDefinition) => void` | Opens a new window, or focuses it if already open. |
183
+ | `closeWindow` | `(id: string) => void` | Destroys a window instance. |
184
+ | `focusWindow` | `(id: string) => void` | Brings a window to the top of the z-index stack. |
185
+ | `updateWindow` | `(id: string, data: Partial<WindowInstance>) => void` | Patches an existing window's state. |
182
186
 
183
- **`useWindowSnap()`**
184
- - Returns: `{ snapPreview: { side: 'left' | 'right' | 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right' } | null, setSnapPreview: Function }`
187
+ #### `useWindows()`
188
+ Returns `WindowInstance[]` the list of all currently active windows. Re-renders on every state change.
185
189
 
186
- ### Interfaces
190
+ #### `useWindowSnap()`
191
+ Returns `{ snapPreview, setSnapPreview }` for reading and controlling the active snap preview overlay.
187
192
 
188
- **`WindowDefinition`** *(Used for opening windows)*
193
+ ---
189
194
 
190
- | Property | Type | Description |
191
- | :--- | :--- | :--- |
192
- | `id` | `string` | **Required.** Unique identifier for the window instance. |
193
- | `title` | `string` | **Required.** Text displayed in the window header. |
194
- | `component` | `React.ReactNode` | **Required.** The view to be rendered inside the window. |
195
- | `icon` | `React.ReactNode` | Optional element (e.g., SVG/image) for headers/toolbars. |
196
- | `initialSize` | `{ width: number; height: number }` | Optional starting dimensions. |
197
- | `initialPosition` | `{ x: number; y: number }` | Optional starting coordinates. |
198
- | `layer` | `'base' \| 'normal' \| 'alwaysOnTop' \| 'modal'` | Window render priority layer. |
199
- | `isMaximized` | `boolean` | If true, spawns the window spanning the screen. |
200
- | `canMinimize` | `boolean` | Allows the user to hide the window. |
201
- | `canMaximize` | `boolean` | Allows the user to toggle screen-spanning. |
202
- | `canClose` | `boolean` | Allows the user to destroy the window. |
203
-
204
- **`FolderDefinition`** *(Used within Toolbars to group apps)*
205
-
206
- | Property | Type | Description |
207
- | :--- | :--- | :--- |
208
- | `id` | `string` | **Required.** Unique identifier for the folder. |
209
- | `title` | `string` | **Required.** Folder name. |
210
- | `apps` | `WindowDefinition[]` | **Required.** Array of windows contained within. |
211
- | `icon` | `React.ReactNode` | Optional visual descriptor. |
195
+ ### Interfaces
212
196
 
213
- > **Note:** `ToolbarItem` is a union type of `WindowDefinition | FolderDefinition`.
197
+ #### `WindowDefinition`
198
+
199
+ | Property | Type | Required | Description |
200
+ | :--- | :--- | :---: | :--- |
201
+ | `id` | `string` | ✅ | Unique identifier for the window. |
202
+ | `title` | `string` | ✅ | Text shown in the window title bar. |
203
+ | `component` | `ReactNode` | ✅ | Content rendered inside the window. |
204
+ | `icon` | `ReactNode` | — | Icon shown in the title bar and toolbar. |
205
+ | `initialSize` | `{ width: number; height: number }` | — | Starting dimensions in pixels. |
206
+ | `initialPosition` | `{ x: number; y: number }` | — | Starting coordinates in pixels. |
207
+ | `layer` | `'base' \| 'normal' \| 'alwaysOnTop' \| 'modal'` | — | Z-index render layer. |
208
+ | `isMaximized` | `boolean` | — | Spawns the window in maximized state. |
209
+ | `canMinimize` | `boolean` | — | Shows the minimize control. |
210
+ | `canMaximize` | `boolean` | — | Shows the maximize/restore control. |
211
+ | `canClose` | `boolean` | — | Shows the close control. |
212
+
213
+ #### `FolderDefinition`
214
+
215
+ | Property | Type | Required | Description |
216
+ | :--- | :--- | :---: | :--- |
217
+ | `id` | `string` | ✅ | Unique identifier for the folder. |
218
+ | `title` | `string` | ✅ | Folder display name. |
219
+ | `apps` | `WindowDefinition[]` | ✅ | Windows grouped inside this folder. |
220
+ | `icon` | `ReactNode` | — | Optional visual icon. |
221
+
222
+ > `ToolbarItem = WindowDefinition | FolderDefinition`
214
223
 
215
224
  ---
216
225
 
217
- ## ⚙️ Configuration
226
+ ## ⚙️ Styling
218
227
 
219
- This library does not use environment variables. Styling behavior is primarily managed via the required CSS import:
228
+ The library requires a single CSS import to function correctly:
220
229
 
221
230
  ```tsx
222
231
  import '@maomaolabs/core/dist/style.css';
223
232
  ```
224
- Ensure your Vite/Webpack setup is configured to import and bundle CSS from `node_modules`.
233
+
234
+ Ensure your bundler (Vite, Webpack, etc.) is configured to process CSS from `node_modules`.
225
235
 
226
236
  ---
227
237
 
228
- ## 🤝 Contribution
238
+ ## 🤝 Contributing
239
+
240
+ ```bash
241
+ npm install # Install dependencies
242
+ npm run dev # Start dev server with hot reload
243
+ npm run test # Run test suite (Vitest)
244
+ ```
229
245
 
230
- We welcome PRs. To run locally:
231
- 1. `npm install`
232
- 2. `npm run dev` to watch changes and test locally.
233
- 3. `npm run test` before committing to ensure Vitest suites pass.
246
+ PRs are welcome. Please ensure all tests pass before submitting.
234
247
 
235
248
  ---
236
249
 
237
250
  ## 📝 License
238
251
 
239
- MIT License. See `LICENSE` for more information.
252
+ MIT © [MaoMao Labs](https://github.com/maomaolabs)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@maomaolabs/core",
3
- "version": "1.0.1",
3
+ "version": "1.0.2",
4
4
  "private": false,
5
5
  "publishConfig": {
6
6
  "access": "public"