overkit 0.0.2 → 0.0.3
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 +314 -314
- package/package.json +75 -75
package/README.md
CHANGED
|
@@ -1,314 +1,314 @@
|
|
|
1
|
-
# Overkit
|
|
2
|
-
|
|
3
|
-
Simplified overlay management system for React and Next.js. Uses Zustand for state management and allows creating modals, drawers, sheets, and more with ease.
|
|
4
|
-
|
|
5
|
-
## Features
|
|
6
|
-
|
|
7
|
-
- **Centralized State**: State management with Zustand
|
|
8
|
-
- **Simple Triggers**: Open overlays with a single click
|
|
9
|
-
- **Portals**: Flexible rendering with tunnel-rat
|
|
10
|
-
- **TypeScript**: Complete and safe typing
|
|
11
|
-
- **Dynamic Configuration**: Props based on store state
|
|
12
|
-
- **Built-in Hooks**: Access state from any component
|
|
13
|
-
|
|
14
|
-
## Installation
|
|
15
|
-
|
|
16
|
-
```bash
|
|
17
|
-
npm install overkit
|
|
18
|
-
# or
|
|
19
|
-
yarn add overkit
|
|
20
|
-
# or
|
|
21
|
-
pnpm add overkit
|
|
22
|
-
```
|
|
23
|
-
|
|
24
|
-
## Dependencies
|
|
25
|
-
|
|
26
|
-
```bash
|
|
27
|
-
npm install zustand @radix-ui/react-slot tunnel-rat
|
|
28
|
-
```
|
|
29
|
-
|
|
30
|
-
## Basic Usage
|
|
31
|
-
|
|
32
|
-
### 1. Create a Registry
|
|
33
|
-
|
|
34
|
-
First, create a base component that will serve as the overlay (Modal, Drawer, Sheet, etc.):
|
|
35
|
-
|
|
36
|
-
```tsx
|
|
37
|
-
// components/modal.tsx
|
|
38
|
-
import { registry, type RegistryComponentProps } from "overkit";
|
|
39
|
-
|
|
40
|
-
const Modal = ({
|
|
41
|
-
open,
|
|
42
|
-
onOpenChange,
|
|
43
|
-
title,
|
|
44
|
-
description,
|
|
45
|
-
children,
|
|
46
|
-
}: RegistryComponentProps) => {
|
|
47
|
-
if (!open) return null;
|
|
48
|
-
|
|
49
|
-
return (
|
|
50
|
-
<div className="modal-backdrop" onClick={() => onOpenChange?.(false)}>
|
|
51
|
-
<div className="modal-content">
|
|
52
|
-
<h2>{title}</h2>
|
|
53
|
-
<p>{description}</p>
|
|
54
|
-
{children}
|
|
55
|
-
</div>
|
|
56
|
-
</div>
|
|
57
|
-
);
|
|
58
|
-
};
|
|
59
|
-
|
|
60
|
-
export const ModalRegistry = registry({
|
|
61
|
-
name: "modal",
|
|
62
|
-
render: Modal,
|
|
63
|
-
});
|
|
64
|
-
```
|
|
65
|
-
|
|
66
|
-
### 2. Configure Overkit
|
|
67
|
-
|
|
68
|
-
```tsx
|
|
69
|
-
// overlays.tsx
|
|
70
|
-
import { Overkit } from "overkit";
|
|
71
|
-
import { ModalRegistry } from "./modal";
|
|
72
|
-
|
|
73
|
-
const o = new Overkit(["userModal", "confirmDialog"] as const)
|
|
74
|
-
.with(ModalRegistry)
|
|
75
|
-
.build();
|
|
76
|
-
|
|
77
|
-
// Create simple overlay
|
|
78
|
-
const userDialog = o.create("userModal", "modal").configure({
|
|
79
|
-
title: "User Profile",
|
|
80
|
-
description: "Manage your profile information",
|
|
81
|
-
});
|
|
82
|
-
|
|
83
|
-
// Create overlay with extended state
|
|
84
|
-
const confirmDialog = o
|
|
85
|
-
.create("confirmDialog", "modal")
|
|
86
|
-
.extend<{ message: string }>(() => ({
|
|
87
|
-
message: "",
|
|
88
|
-
}))
|
|
89
|
-
.configure({
|
|
90
|
-
title: "Confirm Action",
|
|
91
|
-
description: "Are you sure?",
|
|
92
|
-
});
|
|
93
|
-
|
|
94
|
-
// Export components
|
|
95
|
-
export const UserModalTrigger = userDialog.trigger;
|
|
96
|
-
export const UserModalView = userDialog.view;
|
|
97
|
-
|
|
98
|
-
export const ConfirmTrigger = confirmDialog.trigger;
|
|
99
|
-
export const ConfirmView = confirmDialog.view;
|
|
100
|
-
export const useOverkitStore = o.useOverkitStore;
|
|
101
|
-
```
|
|
102
|
-
|
|
103
|
-
### 3. Use in Your App
|
|
104
|
-
|
|
105
|
-
```tsx
|
|
106
|
-
// page.tsx
|
|
107
|
-
import { UserModalTrigger, UserModalView } from "./overlays";
|
|
108
|
-
|
|
109
|
-
export default function Page() {
|
|
110
|
-
return (
|
|
111
|
-
<div>
|
|
112
|
-
<UserModalTrigger>
|
|
113
|
-
<button>Open User Modal</button>
|
|
114
|
-
</UserModalTrigger>
|
|
115
|
-
|
|
116
|
-
<UserModalView />
|
|
117
|
-
</div>
|
|
118
|
-
);
|
|
119
|
-
}
|
|
120
|
-
```
|
|
121
|
-
|
|
122
|
-
## API
|
|
123
|
-
|
|
124
|
-
### `Overkit`
|
|
125
|
-
|
|
126
|
-
The main class for creating and managing overlays.
|
|
127
|
-
|
|
128
|
-
```tsx
|
|
129
|
-
const o = new Overkit(["key1", "key2"] as const).with(RegistryItem).build();
|
|
130
|
-
```
|
|
131
|
-
|
|
132
|
-
### `.create(key, registryName)`
|
|
133
|
-
|
|
134
|
-
Creates a new overlay.
|
|
135
|
-
|
|
136
|
-
```tsx
|
|
137
|
-
const dialog = o.create("myDialog", "modal");
|
|
138
|
-
```
|
|
139
|
-
|
|
140
|
-
### `.extend<State>(storeCreator)`
|
|
141
|
-
|
|
142
|
-
Extends the overlay state with additional properties.
|
|
143
|
-
|
|
144
|
-
```tsx
|
|
145
|
-
const dialog = o
|
|
146
|
-
.create("myDialog", "modal")
|
|
147
|
-
.extend<{ count: number }>((set) => ({
|
|
148
|
-
count: 0,
|
|
149
|
-
increment: () => set((state) => ({ count: state.count + 1 })),
|
|
150
|
-
}));
|
|
151
|
-
```
|
|
152
|
-
|
|
153
|
-
### `.configure(options)`
|
|
154
|
-
|
|
155
|
-
Configures the overlay properties. You can use static values or functions that receive the store:
|
|
156
|
-
|
|
157
|
-
```tsx
|
|
158
|
-
const dialog = o
|
|
159
|
-
.create("productDialog", "modal")
|
|
160
|
-
.extend<{ mode: "create" | "edit" }>((set) => ({
|
|
161
|
-
mode: "create",
|
|
162
|
-
setMode: (mode) => set({ mode }),
|
|
163
|
-
}))
|
|
164
|
-
.configure({
|
|
165
|
-
// Static values
|
|
166
|
-
title: "Product",
|
|
167
|
-
|
|
168
|
-
// Functions with store access
|
|
169
|
-
title: (store) =>
|
|
170
|
-
store?.mode === "create" ? "Create Product" : "Edit Product",
|
|
171
|
-
description: (store) =>
|
|
172
|
-
store?.mode === "create"
|
|
173
|
-
? "Create a new product"
|
|
174
|
-
: "Edit existing product",
|
|
175
|
-
className: (store) =>
|
|
176
|
-
store?.mode === "create" ? "mode-create" : "mode-edit",
|
|
177
|
-
});
|
|
178
|
-
```
|
|
179
|
-
|
|
180
|
-
### `trigger`
|
|
181
|
-
|
|
182
|
-
Component to open the overlay.
|
|
183
|
-
|
|
184
|
-
```tsx
|
|
185
|
-
<Trigger>
|
|
186
|
-
<button>Open</button>
|
|
187
|
-
</Trigger>
|
|
188
|
-
|
|
189
|
-
// With initial store values
|
|
190
|
-
<Trigger count={100}>
|
|
191
|
-
<button>Open with 100</button>
|
|
192
|
-
</Trigger>
|
|
193
|
-
|
|
194
|
-
// With componentProps for the view
|
|
195
|
-
<Trigger componentProps={{ items: ["a", "b", "c"] }}>
|
|
196
|
-
<button>Open with Items</button>
|
|
197
|
-
</Trigger>
|
|
198
|
-
```
|
|
199
|
-
|
|
200
|
-
### `view`
|
|
201
|
-
|
|
202
|
-
Component that renders the overlay content.
|
|
203
|
-
|
|
204
|
-
```tsx
|
|
205
|
-
// Basic
|
|
206
|
-
const View = dialog.view(() => <div>Content</div>);
|
|
207
|
-
|
|
208
|
-
// With props
|
|
209
|
-
const View = dialog.view<{ items: string[] }>(({ items }) => (
|
|
210
|
-
<ul>
|
|
211
|
-
{items.map((item) => (
|
|
212
|
-
<li key={item}>{item}</li>
|
|
213
|
-
))}
|
|
214
|
-
</ul>
|
|
215
|
-
));
|
|
216
|
-
|
|
217
|
-
// With close function
|
|
218
|
-
const View = dialog.view(({ close }) => (
|
|
219
|
-
<div>
|
|
220
|
-
<button onClick={close}>Close</button>
|
|
221
|
-
</div>
|
|
222
|
-
));
|
|
223
|
-
|
|
224
|
-
// With useInnerContext (requires .extend())
|
|
225
|
-
const View = dialog.view(({ useInnerContext }) => {
|
|
226
|
-
const count = useInnerContext((state) => state.count);
|
|
227
|
-
const increment = useInnerContext((state) => state.increment);
|
|
228
|
-
|
|
229
|
-
return (
|
|
230
|
-
<div>
|
|
231
|
-
<p>Count: {count}</p>
|
|
232
|
-
<button onClick={increment}>Increment</button>
|
|
233
|
-
</div>
|
|
234
|
-
);
|
|
235
|
-
});
|
|
236
|
-
```
|
|
237
|
-
|
|
238
|
-
### `useOverkitStore`
|
|
239
|
-
|
|
240
|
-
Hook to access the global state of all overlays.
|
|
241
|
-
|
|
242
|
-
```tsx
|
|
243
|
-
const isOpen = useOverkitStore((state) => state.states.myDialog);
|
|
244
|
-
const setOpen = useOverkitStore((state) => state.setMyDialog);
|
|
245
|
-
|
|
246
|
-
// Open/close programmatically
|
|
247
|
-
setOpen(true);
|
|
248
|
-
setOpen(false);
|
|
249
|
-
```
|
|
250
|
-
|
|
251
|
-
## Advanced Examples
|
|
252
|
-
|
|
253
|
-
### Product Sheet (Create/Edit)
|
|
254
|
-
|
|
255
|
-
```tsx
|
|
256
|
-
const productSheet = o
|
|
257
|
-
.create("productSheet", "Sheet")
|
|
258
|
-
.extend<ProductState>((set) => ({
|
|
259
|
-
mode: "create",
|
|
260
|
-
setMode: (mode) => set({ mode }),
|
|
261
|
-
}))
|
|
262
|
-
.configure({
|
|
263
|
-
title: (store) => {
|
|
264
|
-
return store?.mode === "create" ? "Create a Product" : "Edit Product";
|
|
265
|
-
},
|
|
266
|
-
description: (store) => {
|
|
267
|
-
return store?.mode === "create"
|
|
268
|
-
? "Fill in the details of the product you want to create"
|
|
269
|
-
: "Fill in the details of the product you want to edit";
|
|
270
|
-
},
|
|
271
|
-
className: "!max-w-none w-3/8",
|
|
272
|
-
});
|
|
273
|
-
```
|
|
274
|
-
|
|
275
|
-
### Counter with Extended State
|
|
276
|
-
|
|
277
|
-
```tsx
|
|
278
|
-
const counterDialog = o
|
|
279
|
-
.create("counter", "modal")
|
|
280
|
-
.extend<{ count: number }>((set) => ({
|
|
281
|
-
count: 0,
|
|
282
|
-
}))
|
|
283
|
-
.configure({
|
|
284
|
-
title: "Counter Dialog",
|
|
285
|
-
});
|
|
286
|
-
|
|
287
|
-
// Open with initial value
|
|
288
|
-
<counterDialog.trigger count={100}>
|
|
289
|
-
<button>Open with 100</button>
|
|
290
|
-
</counterDialog.trigger>;
|
|
291
|
-
|
|
292
|
-
// Use in the view
|
|
293
|
-
const CounterView = counterDialog.view(({ useInnerContext }) => {
|
|
294
|
-
const count = useInnerContext((state) => state.count);
|
|
295
|
-
return <div>Count: {count}</div>;
|
|
296
|
-
});
|
|
297
|
-
```
|
|
298
|
-
|
|
299
|
-
## TypeScript
|
|
300
|
-
|
|
301
|
-
Overkit is fully typed. When creating overlays, types are automatically inferred:
|
|
302
|
-
|
|
303
|
-
```tsx
|
|
304
|
-
// Keys are validated at compile time
|
|
305
|
-
const o = new Overkit(["dialog1", "dialog2"] as const);
|
|
306
|
-
|
|
307
|
-
// TypeScript knows only "dialog1" and "dialog2" are valid
|
|
308
|
-
o.create("dialog1", "modal"); // ✅
|
|
309
|
-
o.create("dialog3", "modal"); // ❌ Type error
|
|
310
|
-
```
|
|
311
|
-
|
|
312
|
-
## License
|
|
313
|
-
|
|
314
|
-
MIT
|
|
1
|
+
# Overkit
|
|
2
|
+
|
|
3
|
+
Simplified overlay management system for React and Next.js. Uses Zustand for state management and allows creating modals, drawers, sheets, and more with ease.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **Centralized State**: State management with Zustand
|
|
8
|
+
- **Simple Triggers**: Open overlays with a single click
|
|
9
|
+
- **Portals**: Flexible rendering with tunnel-rat
|
|
10
|
+
- **TypeScript**: Complete and safe typing
|
|
11
|
+
- **Dynamic Configuration**: Props based on store state
|
|
12
|
+
- **Built-in Hooks**: Access state from any component
|
|
13
|
+
|
|
14
|
+
## Installation
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
npm install overkit
|
|
18
|
+
# or
|
|
19
|
+
yarn add overkit
|
|
20
|
+
# or
|
|
21
|
+
pnpm add overkit
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Dependencies
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
npm install zustand @radix-ui/react-slot tunnel-rat
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Basic Usage
|
|
31
|
+
|
|
32
|
+
### 1. Create a Registry
|
|
33
|
+
|
|
34
|
+
First, create a base component that will serve as the overlay (Modal, Drawer, Sheet, etc.):
|
|
35
|
+
|
|
36
|
+
```tsx
|
|
37
|
+
// components/modal.tsx
|
|
38
|
+
import { registry, type RegistryComponentProps } from "overkit";
|
|
39
|
+
|
|
40
|
+
const Modal = ({
|
|
41
|
+
open,
|
|
42
|
+
onOpenChange,
|
|
43
|
+
title,
|
|
44
|
+
description,
|
|
45
|
+
children,
|
|
46
|
+
}: RegistryComponentProps) => {
|
|
47
|
+
if (!open) return null;
|
|
48
|
+
|
|
49
|
+
return (
|
|
50
|
+
<div className="modal-backdrop" onClick={() => onOpenChange?.(false)}>
|
|
51
|
+
<div className="modal-content">
|
|
52
|
+
<h2>{title}</h2>
|
|
53
|
+
<p>{description}</p>
|
|
54
|
+
{children}
|
|
55
|
+
</div>
|
|
56
|
+
</div>
|
|
57
|
+
);
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
export const ModalRegistry = registry({
|
|
61
|
+
name: "modal",
|
|
62
|
+
render: Modal,
|
|
63
|
+
});
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### 2. Configure Overkit
|
|
67
|
+
|
|
68
|
+
```tsx
|
|
69
|
+
// overlays.tsx
|
|
70
|
+
import { Overkit } from "overkit";
|
|
71
|
+
import { ModalRegistry } from "./modal";
|
|
72
|
+
|
|
73
|
+
const o = new Overkit(["userModal", "confirmDialog"] as const)
|
|
74
|
+
.with(ModalRegistry)
|
|
75
|
+
.build();
|
|
76
|
+
|
|
77
|
+
// Create simple overlay
|
|
78
|
+
const userDialog = o.create("userModal", "modal").configure({
|
|
79
|
+
title: "User Profile",
|
|
80
|
+
description: "Manage your profile information",
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
// Create overlay with extended state
|
|
84
|
+
const confirmDialog = o
|
|
85
|
+
.create("confirmDialog", "modal")
|
|
86
|
+
.extend<{ message: string }>(() => ({
|
|
87
|
+
message: "",
|
|
88
|
+
}))
|
|
89
|
+
.configure({
|
|
90
|
+
title: "Confirm Action",
|
|
91
|
+
description: "Are you sure?",
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
// Export components
|
|
95
|
+
export const UserModalTrigger = userDialog.trigger;
|
|
96
|
+
export const UserModalView = userDialog.view;
|
|
97
|
+
|
|
98
|
+
export const ConfirmTrigger = confirmDialog.trigger;
|
|
99
|
+
export const ConfirmView = confirmDialog.view;
|
|
100
|
+
export const useOverkitStore = o.useOverkitStore;
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### 3. Use in Your App
|
|
104
|
+
|
|
105
|
+
```tsx
|
|
106
|
+
// page.tsx
|
|
107
|
+
import { UserModalTrigger, UserModalView } from "./overlays";
|
|
108
|
+
|
|
109
|
+
export default function Page() {
|
|
110
|
+
return (
|
|
111
|
+
<div>
|
|
112
|
+
<UserModalTrigger>
|
|
113
|
+
<button>Open User Modal</button>
|
|
114
|
+
</UserModalTrigger>
|
|
115
|
+
|
|
116
|
+
<UserModalView />
|
|
117
|
+
</div>
|
|
118
|
+
);
|
|
119
|
+
}
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
## API
|
|
123
|
+
|
|
124
|
+
### `Overkit`
|
|
125
|
+
|
|
126
|
+
The main class for creating and managing overlays.
|
|
127
|
+
|
|
128
|
+
```tsx
|
|
129
|
+
const o = new Overkit(["key1", "key2"] as const).with(RegistryItem).build();
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
### `.create(key, registryName)`
|
|
133
|
+
|
|
134
|
+
Creates a new overlay.
|
|
135
|
+
|
|
136
|
+
```tsx
|
|
137
|
+
const dialog = o.create("myDialog", "modal");
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
### `.extend<State>(storeCreator)`
|
|
141
|
+
|
|
142
|
+
Extends the overlay state with additional properties.
|
|
143
|
+
|
|
144
|
+
```tsx
|
|
145
|
+
const dialog = o
|
|
146
|
+
.create("myDialog", "modal")
|
|
147
|
+
.extend<{ count: number }>((set) => ({
|
|
148
|
+
count: 0,
|
|
149
|
+
increment: () => set((state) => ({ count: state.count + 1 })),
|
|
150
|
+
}));
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
### `.configure(options)`
|
|
154
|
+
|
|
155
|
+
Configures the overlay properties. You can use static values or functions that receive the store:
|
|
156
|
+
|
|
157
|
+
```tsx
|
|
158
|
+
const dialog = o
|
|
159
|
+
.create("productDialog", "modal")
|
|
160
|
+
.extend<{ mode: "create" | "edit" }>((set) => ({
|
|
161
|
+
mode: "create",
|
|
162
|
+
setMode: (mode) => set({ mode }),
|
|
163
|
+
}))
|
|
164
|
+
.configure({
|
|
165
|
+
// Static values
|
|
166
|
+
title: "Product",
|
|
167
|
+
|
|
168
|
+
// Functions with store access
|
|
169
|
+
title: (store) =>
|
|
170
|
+
store?.mode === "create" ? "Create Product" : "Edit Product",
|
|
171
|
+
description: (store) =>
|
|
172
|
+
store?.mode === "create"
|
|
173
|
+
? "Create a new product"
|
|
174
|
+
: "Edit existing product",
|
|
175
|
+
className: (store) =>
|
|
176
|
+
store?.mode === "create" ? "mode-create" : "mode-edit",
|
|
177
|
+
});
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
### `trigger`
|
|
181
|
+
|
|
182
|
+
Component to open the overlay.
|
|
183
|
+
|
|
184
|
+
```tsx
|
|
185
|
+
<Trigger>
|
|
186
|
+
<button>Open</button>
|
|
187
|
+
</Trigger>
|
|
188
|
+
|
|
189
|
+
// With initial store values
|
|
190
|
+
<Trigger count={100}>
|
|
191
|
+
<button>Open with 100</button>
|
|
192
|
+
</Trigger>
|
|
193
|
+
|
|
194
|
+
// With componentProps for the view
|
|
195
|
+
<Trigger componentProps={{ items: ["a", "b", "c"] }}>
|
|
196
|
+
<button>Open with Items</button>
|
|
197
|
+
</Trigger>
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
### `view`
|
|
201
|
+
|
|
202
|
+
Component that renders the overlay content.
|
|
203
|
+
|
|
204
|
+
```tsx
|
|
205
|
+
// Basic
|
|
206
|
+
const View = dialog.view(() => <div>Content</div>);
|
|
207
|
+
|
|
208
|
+
// With props
|
|
209
|
+
const View = dialog.view<{ items: string[] }>(({ items }) => (
|
|
210
|
+
<ul>
|
|
211
|
+
{items.map((item) => (
|
|
212
|
+
<li key={item}>{item}</li>
|
|
213
|
+
))}
|
|
214
|
+
</ul>
|
|
215
|
+
));
|
|
216
|
+
|
|
217
|
+
// With close function
|
|
218
|
+
const View = dialog.view(({ close }) => (
|
|
219
|
+
<div>
|
|
220
|
+
<button onClick={close}>Close</button>
|
|
221
|
+
</div>
|
|
222
|
+
));
|
|
223
|
+
|
|
224
|
+
// With useInnerContext (requires .extend())
|
|
225
|
+
const View = dialog.view(({ useInnerContext }) => {
|
|
226
|
+
const count = useInnerContext((state) => state.count);
|
|
227
|
+
const increment = useInnerContext((state) => state.increment);
|
|
228
|
+
|
|
229
|
+
return (
|
|
230
|
+
<div>
|
|
231
|
+
<p>Count: {count}</p>
|
|
232
|
+
<button onClick={increment}>Increment</button>
|
|
233
|
+
</div>
|
|
234
|
+
);
|
|
235
|
+
});
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
### `useOverkitStore`
|
|
239
|
+
|
|
240
|
+
Hook to access the global state of all overlays.
|
|
241
|
+
|
|
242
|
+
```tsx
|
|
243
|
+
const isOpen = useOverkitStore((state) => state.states.myDialog);
|
|
244
|
+
const setOpen = useOverkitStore((state) => state.setMyDialog);
|
|
245
|
+
|
|
246
|
+
// Open/close programmatically
|
|
247
|
+
setOpen(true);
|
|
248
|
+
setOpen(false);
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
## Advanced Examples
|
|
252
|
+
|
|
253
|
+
### Product Sheet (Create/Edit)
|
|
254
|
+
|
|
255
|
+
```tsx
|
|
256
|
+
const productSheet = o
|
|
257
|
+
.create("productSheet", "Sheet")
|
|
258
|
+
.extend<ProductState>((set) => ({
|
|
259
|
+
mode: "create",
|
|
260
|
+
setMode: (mode) => set({ mode }),
|
|
261
|
+
}))
|
|
262
|
+
.configure({
|
|
263
|
+
title: (store) => {
|
|
264
|
+
return store?.mode === "create" ? "Create a Product" : "Edit Product";
|
|
265
|
+
},
|
|
266
|
+
description: (store) => {
|
|
267
|
+
return store?.mode === "create"
|
|
268
|
+
? "Fill in the details of the product you want to create"
|
|
269
|
+
: "Fill in the details of the product you want to edit";
|
|
270
|
+
},
|
|
271
|
+
className: "!max-w-none w-3/8",
|
|
272
|
+
});
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
### Counter with Extended State
|
|
276
|
+
|
|
277
|
+
```tsx
|
|
278
|
+
const counterDialog = o
|
|
279
|
+
.create("counter", "modal")
|
|
280
|
+
.extend<{ count: number }>((set) => ({
|
|
281
|
+
count: 0,
|
|
282
|
+
}))
|
|
283
|
+
.configure({
|
|
284
|
+
title: "Counter Dialog",
|
|
285
|
+
});
|
|
286
|
+
|
|
287
|
+
// Open with initial value
|
|
288
|
+
<counterDialog.trigger count={100}>
|
|
289
|
+
<button>Open with 100</button>
|
|
290
|
+
</counterDialog.trigger>;
|
|
291
|
+
|
|
292
|
+
// Use in the view
|
|
293
|
+
const CounterView = counterDialog.view(({ useInnerContext }) => {
|
|
294
|
+
const count = useInnerContext((state) => state.count);
|
|
295
|
+
return <div>Count: {count}</div>;
|
|
296
|
+
});
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
## TypeScript
|
|
300
|
+
|
|
301
|
+
Overkit is fully typed. When creating overlays, types are automatically inferred:
|
|
302
|
+
|
|
303
|
+
```tsx
|
|
304
|
+
// Keys are validated at compile time
|
|
305
|
+
const o = new Overkit(["dialog1", "dialog2"] as const);
|
|
306
|
+
|
|
307
|
+
// TypeScript knows only "dialog1" and "dialog2" are valid
|
|
308
|
+
o.create("dialog1", "modal"); // ✅
|
|
309
|
+
o.create("dialog3", "modal"); // ❌ Type error
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
## License
|
|
313
|
+
|
|
314
|
+
MIT
|
package/package.json
CHANGED
|
@@ -1,75 +1,75 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "overkit",
|
|
3
|
-
"version": "0.0.
|
|
4
|
-
"description": "Simplified overlay management system for React",
|
|
5
|
-
"type": "module",
|
|
6
|
-
"main": "./dist/index.mjs",
|
|
7
|
-
"module": "./dist/index.mjs",
|
|
8
|
-
"types": "./dist/index.d.mts",
|
|
9
|
-
"exports": {
|
|
10
|
-
".": {
|
|
11
|
-
"types": "./dist/index.d.mts",
|
|
12
|
-
"import": "./dist/index.mjs",
|
|
13
|
-
"require": "./dist/index.mjs"
|
|
14
|
-
}
|
|
15
|
-
},
|
|
16
|
-
"files": [
|
|
17
|
-
"dist",
|
|
18
|
-
"README.md"
|
|
19
|
-
],
|
|
20
|
-
"scripts": {
|
|
21
|
-
"build": "tsdown",
|
|
22
|
-
"test": "vitest",
|
|
23
|
-
"test:ui": "vitest --ui",
|
|
24
|
-
"test:run": "vitest run"
|
|
25
|
-
},
|
|
26
|
-
"keywords": [
|
|
27
|
-
"react",
|
|
28
|
-
"reactjs",
|
|
29
|
-
"overlay",
|
|
30
|
-
"modal",
|
|
31
|
-
"dialog",
|
|
32
|
-
"drawer",
|
|
33
|
-
"sheet",
|
|
34
|
-
"portal",
|
|
35
|
-
"zustand",
|
|
36
|
-
"state-management",
|
|
37
|
-
"typescript"
|
|
38
|
-
],
|
|
39
|
-
"author": {
|
|
40
|
-
"name": "Jean Caiza",
|
|
41
|
-
"email": "jeanmcm@hotmail.com",
|
|
42
|
-
"url": "https://github.com/jfortez"
|
|
43
|
-
},
|
|
44
|
-
"license": "MIT",
|
|
45
|
-
"repository": {
|
|
46
|
-
"type": "git",
|
|
47
|
-
"url": "https://github.com/jfortez/overkit.git",
|
|
48
|
-
"directory": "lib/overkit"
|
|
49
|
-
},
|
|
50
|
-
"bugs": {
|
|
51
|
-
"url": "https://github.com/jfortez/overkit/issues"
|
|
52
|
-
},
|
|
53
|
-
"homepage": "https://github.com/jfortez/overkit#readme",
|
|
54
|
-
"devDependencies": {
|
|
55
|
-
"@testing-library/jest-dom": "^6.9.1",
|
|
56
|
-
"@testing-library/react": "^16.0.0",
|
|
57
|
-
"@types/bun": "latest",
|
|
58
|
-
"@types/react": "^19.0.0",
|
|
59
|
-
"@types/react-dom": "^19.0.0",
|
|
60
|
-
"@vitejs/plugin-react": "^4.3.0",
|
|
61
|
-
"jsdom": "^25.0.0",
|
|
62
|
-
"tsdown": "^0.20.3",
|
|
63
|
-
"typescript": "^5.0.0",
|
|
64
|
-
"vitest": "^2.1.0"
|
|
65
|
-
},
|
|
66
|
-
"peerDependencies": {
|
|
67
|
-
"react": ">=18.0.0",
|
|
68
|
-
"react-dom": ">=18.0.0"
|
|
69
|
-
},
|
|
70
|
-
"dependencies": {
|
|
71
|
-
"zustand": "^5.0.0",
|
|
72
|
-
"@radix-ui/react-slot": "^1.1.0",
|
|
73
|
-
"tunnel-rat": "^0.1.0"
|
|
74
|
-
}
|
|
75
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "overkit",
|
|
3
|
+
"version": "0.0.3",
|
|
4
|
+
"description": "Simplified overlay management system for React",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.mjs",
|
|
7
|
+
"module": "./dist/index.mjs",
|
|
8
|
+
"types": "./dist/index.d.mts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"types": "./dist/index.d.mts",
|
|
12
|
+
"import": "./dist/index.mjs",
|
|
13
|
+
"require": "./dist/index.mjs"
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
"files": [
|
|
17
|
+
"dist",
|
|
18
|
+
"README.md"
|
|
19
|
+
],
|
|
20
|
+
"scripts": {
|
|
21
|
+
"build": "tsdown",
|
|
22
|
+
"test": "vitest",
|
|
23
|
+
"test:ui": "vitest --ui",
|
|
24
|
+
"test:run": "vitest run"
|
|
25
|
+
},
|
|
26
|
+
"keywords": [
|
|
27
|
+
"react",
|
|
28
|
+
"reactjs",
|
|
29
|
+
"overlay",
|
|
30
|
+
"modal",
|
|
31
|
+
"dialog",
|
|
32
|
+
"drawer",
|
|
33
|
+
"sheet",
|
|
34
|
+
"portal",
|
|
35
|
+
"zustand",
|
|
36
|
+
"state-management",
|
|
37
|
+
"typescript"
|
|
38
|
+
],
|
|
39
|
+
"author": {
|
|
40
|
+
"name": "Jean Caiza",
|
|
41
|
+
"email": "jeanmcm@hotmail.com",
|
|
42
|
+
"url": "https://github.com/jfortez"
|
|
43
|
+
},
|
|
44
|
+
"license": "MIT",
|
|
45
|
+
"repository": {
|
|
46
|
+
"type": "git",
|
|
47
|
+
"url": "https://github.com/jfortez/overkit.git",
|
|
48
|
+
"directory": "lib/overkit"
|
|
49
|
+
},
|
|
50
|
+
"bugs": {
|
|
51
|
+
"url": "https://github.com/jfortez/overkit/issues"
|
|
52
|
+
},
|
|
53
|
+
"homepage": "https://github.com/jfortez/overkit#readme",
|
|
54
|
+
"devDependencies": {
|
|
55
|
+
"@testing-library/jest-dom": "^6.9.1",
|
|
56
|
+
"@testing-library/react": "^16.0.0",
|
|
57
|
+
"@types/bun": "latest",
|
|
58
|
+
"@types/react": "^19.0.0",
|
|
59
|
+
"@types/react-dom": "^19.0.0",
|
|
60
|
+
"@vitejs/plugin-react": "^4.3.0",
|
|
61
|
+
"jsdom": "^25.0.0",
|
|
62
|
+
"tsdown": "^0.20.3",
|
|
63
|
+
"typescript": "^5.0.0",
|
|
64
|
+
"vitest": "^2.1.0"
|
|
65
|
+
},
|
|
66
|
+
"peerDependencies": {
|
|
67
|
+
"react": ">=18.0.0",
|
|
68
|
+
"react-dom": ">=18.0.0"
|
|
69
|
+
},
|
|
70
|
+
"dependencies": {
|
|
71
|
+
"zustand": "^5.0.0",
|
|
72
|
+
"@radix-ui/react-slot": "^1.1.0",
|
|
73
|
+
"tunnel-rat": "^0.1.0"
|
|
74
|
+
}
|
|
75
|
+
}
|