@helloworldqq/react-modal 1.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 +581 -0
- package/dist/cli.d.ts +10 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/hook/index.d.ts +24 -0
- package/dist/hook/index.d.ts.map +1 -0
- package/dist/hook/tag.d.ts +2 -0
- package/dist/hook/tag.d.ts.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +208 -0
- package/dist/index.js.map +1 -0
- package/dist/index.modern.js +203 -0
- package/dist/index.modern.js.map +1 -0
- package/dist/provider/index.d.ts +8 -0
- package/dist/provider/index.d.ts.map +1 -0
- package/dist/store/index.d.ts +22 -0
- package/dist/store/index.d.ts.map +1 -0
- package/package.json +82 -0
package/README.md
ADDED
|
@@ -0,0 +1,581 @@
|
|
|
1
|
+
# React Hook Disclosure Modal
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/@vnquang24/react-modal)
|
|
4
|
+
[](https://opensource.org/licenses/MIT)
|
|
5
|
+
|
|
6
|
+
Thư viện React hook mạnh mẽ và linh hoạt để quản lý modal với API khai báo rõ ràng. Hoàn hảo cho các ứng dụng cần quản lý nhiều modal với khả năng truyền dữ liệu.
|
|
7
|
+
|
|
8
|
+
**Tương thích với React 16.8+, 17, 18 và 19 (bao gồm 19.2.3)** và hoạt động tốt với các thư viện UI như **Ant Design 6**, **Material UI**, **Chakra UI**, v.v.
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## Mục Lục
|
|
13
|
+
|
|
14
|
+
- [Cài Đặt](#cài-đặt)
|
|
15
|
+
- [Bắt Đầu Nhanh](#bắt-đầu-nhanh)
|
|
16
|
+
- [Tài Liệu API](#tài-liệu-api)
|
|
17
|
+
- [ReactHookModalProvider](#reacthookmodalprovider)
|
|
18
|
+
- [useDisclosure Hook](#usedisclosure-hook)
|
|
19
|
+
- [Các Tùy Chọn Hook (DisclosureHookProps)](#các-tùy-chọn-hook-disclosurehookprops)
|
|
20
|
+
- [Giá Trị Trả Về Của Hook](#giá-trị-trả-về-của-hook)
|
|
21
|
+
- [Sử Dụng Nâng Cao](#sử-dụng-nâng-cao)
|
|
22
|
+
- [Truyền Dữ Liệu Vào Modal](#truyền-dữ-liệu-vào-modal)
|
|
23
|
+
- [Trả Dữ Liệu Từ Modal (onOk)](#trả-dữ-liệu-từ-modal-onok)
|
|
24
|
+
- [Sử Dụng Callbacks](#sử-dụng-callbacks)
|
|
25
|
+
- [Hỗ Trợ TypeScript](#hỗ-trợ-typescript)
|
|
26
|
+
- [Ví Dụ](#ví-dụ)
|
|
27
|
+
- [Modal Cơ Bản](#modal-cơ-bản)
|
|
28
|
+
- [Modal Xác Nhận](#modal-xác-nhận)
|
|
29
|
+
- [Modal Form Với Trả Dữ Liệu](#modal-form-với-trả-dữ-liệu)
|
|
30
|
+
- [Với Ant Design 6](#với-ant-design-6)
|
|
31
|
+
- [Tương Thích](#tương-thích)
|
|
32
|
+
- [Giấy Phép](#giấy-phép)
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## Cài Đặt
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
npm install @vnquang24/react-modal
|
|
40
|
+
# hoặc
|
|
41
|
+
yarn add @vnquang24/react-modal
|
|
42
|
+
# hoặc
|
|
43
|
+
pnpm add @vnquang24/react-modal
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
## Bắt Đầu Nhanh
|
|
49
|
+
|
|
50
|
+
```tsx
|
|
51
|
+
import React from 'react'
|
|
52
|
+
import { ReactHookModalProvider, useDisclosure } from '@vnquang24/react-modal'
|
|
53
|
+
import { Modal, Button } from 'antd'
|
|
54
|
+
|
|
55
|
+
// 1. Định nghĩa component modal của bạn
|
|
56
|
+
const MyModal = () => {
|
|
57
|
+
const { isOpen, onClose } = useDisclosure({ tag: 'MyModal' })
|
|
58
|
+
|
|
59
|
+
return (
|
|
60
|
+
<Modal open={isOpen} onCancel={onClose} onOk={onClose} title="Modal Của Tôi">
|
|
61
|
+
Xin chào!
|
|
62
|
+
</Modal>
|
|
63
|
+
)
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// 2. Đăng ký modals và sử dụng
|
|
67
|
+
const modals = { MyModal }
|
|
68
|
+
|
|
69
|
+
const App = () => {
|
|
70
|
+
const { onOpen } = useDisclosure({ tag: 'MyModal' })
|
|
71
|
+
|
|
72
|
+
return (
|
|
73
|
+
<ReactHookModalProvider modals={modals}>
|
|
74
|
+
<Button onClick={onOpen}>Mở Modal</Button>
|
|
75
|
+
</ReactHookModalProvider>
|
|
76
|
+
)
|
|
77
|
+
}
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
---
|
|
81
|
+
|
|
82
|
+
## Tài Liệu API
|
|
83
|
+
|
|
84
|
+
### ReactHookModalProvider
|
|
85
|
+
|
|
86
|
+
Component provider quản lý tất cả các modal đã đăng ký.
|
|
87
|
+
|
|
88
|
+
```tsx
|
|
89
|
+
<ReactHookModalProvider modals={modals}>
|
|
90
|
+
{children}
|
|
91
|
+
</ReactHookModalProvider>
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
| Prop | Kiểu | Bắt buộc | Mô tả |
|
|
95
|
+
|------|------|----------|-------|
|
|
96
|
+
| `modals` | `Record<string, React.ComponentType>` | ✅ | Object chứa các component modal, key là tag |
|
|
97
|
+
| `children` | `React.ReactNode` | ✅ | Các component con của ứng dụng |
|
|
98
|
+
|
|
99
|
+
---
|
|
100
|
+
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
|
|
101
|
+
### useDisclosure Hook
|
|
102
|
+
|
|
103
|
+
Hook chính để điều khiển trạng thái modal.
|
|
104
|
+
|
|
105
|
+
```tsx
|
|
106
|
+
const disclosure = useDisclosure<Input, Output>(options)
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
#### Kiểu Generic
|
|
110
|
+
|
|
111
|
+
| Kiểu | Mặc định | Mô tả |
|
|
112
|
+
|------|----------|-------|
|
|
113
|
+
| `Input` | `Any` | Kiểu dữ liệu truyền VÀO modal qua `onOpen(input)` |
|
|
114
|
+
| `Output` | `Any` | Kiểu dữ liệu trả về TỪ modal qua `onOk(output)` |
|
|
115
|
+
|
|
116
|
+
---
|
|
117
|
+
|
|
118
|
+
### Các Tùy Chọn Hook (DisclosureHookProps)
|
|
119
|
+
|
|
120
|
+
```tsx
|
|
121
|
+
interface DisclosureHookProps<Output> {
|
|
122
|
+
tag: string // Bắt buộc: Định danh duy nhất cho modal
|
|
123
|
+
isOpen?: boolean // Tùy chọn: Trạng thái mở ban đầu
|
|
124
|
+
onOpen?: () => void // Tùy chọn: Callback khi modal mở
|
|
125
|
+
onClose?: () => void // Tùy chọn: Callback khi modal đóng
|
|
126
|
+
onToggle?: () => void // Tùy chọn: Callback khi modal chuyển đổi trạng thái
|
|
127
|
+
onChange?: (isOpen: boolean) => void // Tùy chọn: Callback khi trạng thái thay đổi
|
|
128
|
+
onOk?: (output?: Output) => void // Tùy chọn: Callback khi onOk được gọi
|
|
129
|
+
onCancel?: () => void // Tùy chọn: Callback khi hủy
|
|
130
|
+
}
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
| Tùy chọn | Kiểu | Bắt buộc | Mô tả |
|
|
134
|
+
|----------|------|----------|-------|
|
|
135
|
+
| `tag` | `string` | ✅ | Định danh duy nhất cho modal. Phải khớp với key trong object `modals` |
|
|
136
|
+
| `isOpen` | `boolean` | ❌ | Trạng thái mở ban đầu (ít khi cần) |
|
|
137
|
+
| `onOpen` | `() => void` | ❌ | Callback được kích hoạt khi modal mở |
|
|
138
|
+
| `onClose` | `() => void` | ❌ | Callback được kích hoạt khi modal đóng |
|
|
139
|
+
| `onToggle` | `() => void` | ❌ | Callback được kích hoạt khi modal chuyển đổi trạng thái |
|
|
140
|
+
| `onChange` | `(isOpen: boolean) => void` | ❌ | Callback được kích hoạt khi trạng thái mở thay đổi |
|
|
141
|
+
| `onOk` | `(output?: Output) => void` | ❌ | Callback được kích hoạt khi `onOk` được gọi với dữ liệu output |
|
|
142
|
+
| `onCancel` | `() => void` | ❌ | Callback được kích hoạt khi hủy |
|
|
143
|
+
|
|
144
|
+
---
|
|
145
|
+
|
|
146
|
+
### Giá Trị Trả Về Của Hook
|
|
147
|
+
|
|
148
|
+
```tsx
|
|
149
|
+
const {
|
|
150
|
+
isOpen, // boolean: Trạng thái mở hiện tại
|
|
151
|
+
input, // Input | undefined: Dữ liệu được truyền vào modal
|
|
152
|
+
onOpen, // (input?: Input) => void: Mở modal
|
|
153
|
+
onClose, // () => void: Đóng modal
|
|
154
|
+
onToggle, // () => void: Chuyển đổi trạng thái modal
|
|
155
|
+
onOk, // (output?: Output) => void: Xác nhận và truyền dữ liệu về
|
|
156
|
+
onChange, // (isOpen: boolean) => void: Đặt trạng thái mở trực tiếp
|
|
157
|
+
updateInput, // (input?: Input) => void: Cập nhật input mà không kích hoạt callback onOpen
|
|
158
|
+
store // Store: Truy cập trực tiếp store (sử dụng nâng cao)
|
|
159
|
+
} = useDisclosure(options)
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
| Giá trị trả về | Kiểu | Mô tả |
|
|
163
|
+
|----------------|------|-------|
|
|
164
|
+
| `isOpen` | `boolean` | Modal có đang mở hay không |
|
|
165
|
+
| `input` | `Input \| undefined` | Dữ liệu được truyền vào modal qua `onOpen(data)` |
|
|
166
|
+
| `onOpen` | `(input?: Input) => void` | Mở modal, có thể kèm dữ liệu input |
|
|
167
|
+
| `onClose` | `() => void` | Đóng modal |
|
|
168
|
+
| `onToggle` | `() => void` | Chuyển đổi trạng thái mở/đóng của modal |
|
|
169
|
+
| `onOk` | `(output?: Output) => void` | Đóng modal và kích hoạt callback `onOk` với output |
|
|
170
|
+
| `onChange` | `(isOpen: boolean) => void` | Đặt trạng thái mở trực tiếp |
|
|
171
|
+
| `updateInput` | `(input?: Input) => void` | Cập nhật dữ liệu input mà không kích hoạt callbacks |
|
|
172
|
+
| `store` | `Store` | Truy cập trực tiếp TanStack Store (nâng cao) |
|
|
173
|
+
|
|
174
|
+
---
|
|
175
|
+
|
|
176
|
+
## Sử Dụng Nâng Cao
|
|
177
|
+
|
|
178
|
+
### Truyền Dữ Liệu Vào Modal
|
|
179
|
+
|
|
180
|
+
Truyền dữ liệu khi mở modal:
|
|
181
|
+
|
|
182
|
+
```tsx
|
|
183
|
+
// Component cha
|
|
184
|
+
const { onOpen } = useDisclosure<UserData>({ tag: 'EditUserModal' })
|
|
185
|
+
|
|
186
|
+
// Mở với dữ liệu
|
|
187
|
+
onOpen({ id: 1, name: 'Nguyễn Văn A', email: 'nguyenvana@example.com' })
|
|
188
|
+
|
|
189
|
+
// Bên trong modal
|
|
190
|
+
const EditUserModal = () => {
|
|
191
|
+
const { isOpen, input, onClose } = useDisclosure<UserData>({ tag: 'EditUserModal' })
|
|
192
|
+
|
|
193
|
+
return (
|
|
194
|
+
<Modal open={isOpen} onCancel={onClose}>
|
|
195
|
+
<p>Đang chỉnh sửa: {input?.name}</p>
|
|
196
|
+
<p>Email: {input?.email}</p>
|
|
197
|
+
</Modal>
|
|
198
|
+
)
|
|
199
|
+
}
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
---
|
|
203
|
+
|
|
204
|
+
### Trả Dữ Liệu Từ Modal (onOk)
|
|
205
|
+
|
|
206
|
+
Trả dữ liệu từ modal về component cha:
|
|
207
|
+
|
|
208
|
+
```tsx
|
|
209
|
+
// Component cha - nhận dữ liệu qua callback onOk
|
|
210
|
+
const { onOpen } = useDisclosure<void, FormData>({
|
|
211
|
+
tag: 'FormModal',
|
|
212
|
+
onOk: (result) => {
|
|
213
|
+
console.log('Form đã gửi:', result)
|
|
214
|
+
// result được định kiểu là FormData
|
|
215
|
+
}
|
|
216
|
+
})
|
|
217
|
+
|
|
218
|
+
// Bên trong modal - gửi dữ liệu về
|
|
219
|
+
const FormModal = () => {
|
|
220
|
+
const { isOpen, onClose, onOk } = useDisclosure<void, FormData>({ tag: 'FormModal' })
|
|
221
|
+
const [formData, setFormData] = useState<FormData>({ name: '', email: '' })
|
|
222
|
+
|
|
223
|
+
const handleSubmit = () => {
|
|
224
|
+
onOk(formData) // Kích hoạt callback onOk ở component cha
|
|
225
|
+
onClose()
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
return (
|
|
229
|
+
<Modal open={isOpen} onCancel={onClose} onOk={handleSubmit}>
|
|
230
|
+
<input
|
|
231
|
+
value={formData.name}
|
|
232
|
+
onChange={(e) => setFormData({ ...formData, name: e.target.value })}
|
|
233
|
+
/>
|
|
234
|
+
</Modal>
|
|
235
|
+
)
|
|
236
|
+
}
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
---
|
|
240
|
+
|
|
241
|
+
### Sử Dụng Callbacks
|
|
242
|
+
|
|
243
|
+
Tất cả các callback vòng đời:
|
|
244
|
+
|
|
245
|
+
```tsx
|
|
246
|
+
const { onOpen, onClose } = useDisclosure({
|
|
247
|
+
tag: 'MyModal',
|
|
248
|
+
|
|
249
|
+
// Được gọi khi modal mở
|
|
250
|
+
onOpen: () => {
|
|
251
|
+
console.log('Modal đã mở')
|
|
252
|
+
analytics.track('modal_opened')
|
|
253
|
+
},
|
|
254
|
+
|
|
255
|
+
// Được gọi khi modal đóng
|
|
256
|
+
onClose: () => {
|
|
257
|
+
console.log('Modal đã đóng')
|
|
258
|
+
form.reset()
|
|
259
|
+
},
|
|
260
|
+
|
|
261
|
+
// Được gọi khi modal chuyển đổi trạng thái
|
|
262
|
+
onToggle: () => {
|
|
263
|
+
console.log('Modal đã chuyển đổi trạng thái')
|
|
264
|
+
},
|
|
265
|
+
|
|
266
|
+
// Được gọi khi trạng thái mở thay đổi (cả hai hướng)
|
|
267
|
+
onChange: (isOpen) => {
|
|
268
|
+
console.log('Trạng thái modal đã thay đổi:', isOpen)
|
|
269
|
+
},
|
|
270
|
+
|
|
271
|
+
// Được gọi khi onOk được kích hoạt với dữ liệu
|
|
272
|
+
onOk: (output) => {
|
|
273
|
+
console.log('Modal đã xác nhận với:', output)
|
|
274
|
+
saveData(output)
|
|
275
|
+
},
|
|
276
|
+
|
|
277
|
+
// Được gọi khi hủy
|
|
278
|
+
onCancel: () => {
|
|
279
|
+
console.log('Modal đã bị hủy')
|
|
280
|
+
}
|
|
281
|
+
})
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
---
|
|
285
|
+
|
|
286
|
+
### Hỗ Trợ TypeScript
|
|
287
|
+
|
|
288
|
+
Hỗ trợ TypeScript đầy đủ với generics:
|
|
289
|
+
|
|
290
|
+
```tsx
|
|
291
|
+
// Định nghĩa các kiểu của bạn
|
|
292
|
+
interface UserInput {
|
|
293
|
+
userId: number
|
|
294
|
+
mode: 'edit' | 'view'
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
interface UserOutput {
|
|
298
|
+
name: string
|
|
299
|
+
email: string
|
|
300
|
+
saved: boolean
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
// Sử dụng với generics
|
|
304
|
+
const { onOpen, input } = useDisclosure<UserInput, UserOutput>({
|
|
305
|
+
tag: 'UserModal',
|
|
306
|
+
onOk: (output) => {
|
|
307
|
+
// output được định kiểu là UserOutput | undefined
|
|
308
|
+
if (output?.saved) {
|
|
309
|
+
toast.success(`Đã lưu ${output.name}`)
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
})
|
|
313
|
+
|
|
314
|
+
// TypeScript biết các kiểu
|
|
315
|
+
onOpen({ userId: 1, mode: 'edit' }) // ✅ Đúng
|
|
316
|
+
onOpen({ wrong: 'data' }) // ❌ Lỗi kiểu
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
---
|
|
320
|
+
|
|
321
|
+
## Ví Dụ
|
|
322
|
+
|
|
323
|
+
### Modal Cơ Bản
|
|
324
|
+
|
|
325
|
+
```tsx
|
|
326
|
+
import { Modal, Button } from 'antd'
|
|
327
|
+
import { useDisclosure } from '@vnquang24/react-modal'
|
|
328
|
+
|
|
329
|
+
const BasicModal = () => {
|
|
330
|
+
const { isOpen, onClose } = useDisclosure({ tag: 'BasicModal' })
|
|
331
|
+
|
|
332
|
+
return (
|
|
333
|
+
<Modal
|
|
334
|
+
open={isOpen}
|
|
335
|
+
onCancel={onClose}
|
|
336
|
+
onOk={onClose}
|
|
337
|
+
title="Modal Cơ Bản"
|
|
338
|
+
>
|
|
339
|
+
<p>Đây là modal cơ bản không có truyền dữ liệu.</p>
|
|
340
|
+
</Modal>
|
|
341
|
+
)
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
// Sử dụng
|
|
345
|
+
const { onOpen } = useDisclosure({ tag: 'BasicModal' })
|
|
346
|
+
<Button onClick={onOpen}>Mở Modal Cơ Bản</Button>
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
---
|
|
350
|
+
|
|
351
|
+
### Modal Xác Nhận
|
|
352
|
+
|
|
353
|
+
```tsx
|
|
354
|
+
const ConfirmDeleteModal = () => {
|
|
355
|
+
const { isOpen, input, onClose, onOk } = useDisclosure<{ itemId: number; itemName: string }, boolean>({
|
|
356
|
+
tag: 'ConfirmDelete'
|
|
357
|
+
})
|
|
358
|
+
|
|
359
|
+
const handleConfirm = () => {
|
|
360
|
+
onOk(true) // Trả về true để chỉ ra đã xác nhận
|
|
361
|
+
onClose()
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
const handleCancel = () => {
|
|
365
|
+
onOk(false) // Trả về false để chỉ ra đã hủy
|
|
366
|
+
onClose()
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
return (
|
|
370
|
+
<Modal
|
|
371
|
+
open={isOpen}
|
|
372
|
+
onCancel={handleCancel}
|
|
373
|
+
onOk={handleConfirm}
|
|
374
|
+
title="Xác Nhận Xóa"
|
|
375
|
+
okText="Xóa"
|
|
376
|
+
okType="danger"
|
|
377
|
+
>
|
|
378
|
+
<p>Bạn có chắc chắn muốn xóa "{input?.itemName}" không?</p>
|
|
379
|
+
</Modal>
|
|
380
|
+
)
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
// Sử dụng
|
|
384
|
+
const { onOpen } = useDisclosure<{ itemId: number; itemName: string }, boolean>({
|
|
385
|
+
tag: 'ConfirmDelete',
|
|
386
|
+
onOk: (confirmed) => {
|
|
387
|
+
if (confirmed) {
|
|
388
|
+
deleteItem(itemId)
|
|
389
|
+
toast.success('Đã xóa thành công!')
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
})
|
|
393
|
+
|
|
394
|
+
<Button danger onClick={() => onOpen({ itemId: 123, itemName: 'Mục của tôi' })}>
|
|
395
|
+
Xóa Mục
|
|
396
|
+
</Button>
|
|
397
|
+
```
|
|
398
|
+
|
|
399
|
+
---
|
|
400
|
+
|
|
401
|
+
### Modal Form Với Trả Dữ Liệu
|
|
402
|
+
|
|
403
|
+
```tsx
|
|
404
|
+
interface FormInput {
|
|
405
|
+
initialData?: { name: string; email: string }
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
interface FormOutput {
|
|
409
|
+
name: string
|
|
410
|
+
email: string
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
const UserFormModal = () => {
|
|
414
|
+
const { isOpen, input, onClose, onOk } = useDisclosure<FormInput, FormOutput>({
|
|
415
|
+
tag: 'UserForm'
|
|
416
|
+
})
|
|
417
|
+
|
|
418
|
+
const [form] = Form.useForm()
|
|
419
|
+
|
|
420
|
+
useEffect(() => {
|
|
421
|
+
if (isOpen && input?.initialData) {
|
|
422
|
+
form.setFieldsValue(input.initialData)
|
|
423
|
+
}
|
|
424
|
+
}, [isOpen, input])
|
|
425
|
+
|
|
426
|
+
const handleSubmit = async () => {
|
|
427
|
+
const values = await form.validateFields()
|
|
428
|
+
onOk(values) // Trả dữ liệu form về component cha
|
|
429
|
+
onClose()
|
|
430
|
+
form.resetFields()
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
return (
|
|
434
|
+
<Modal
|
|
435
|
+
open={isOpen}
|
|
436
|
+
onCancel={onClose}
|
|
437
|
+
onOk={handleSubmit}
|
|
438
|
+
title={input?.initialData ? 'Chỉnh Sửa Người Dùng' : 'Tạo Người Dùng'}
|
|
439
|
+
>
|
|
440
|
+
<Form form={form} layout="vertical">
|
|
441
|
+
<Form.Item name="name" label="Tên" rules={[{ required: true, message: 'Vui lòng nhập tên' }]}>
|
|
442
|
+
<Input />
|
|
443
|
+
</Form.Item>
|
|
444
|
+
<Form.Item name="email" label="Email" rules={[{ required: true, type: 'email', message: 'Vui lòng nhập email hợp lệ' }]}>
|
|
445
|
+
<Input />
|
|
446
|
+
</Form.Item>
|
|
447
|
+
</Form>
|
|
448
|
+
</Modal>
|
|
449
|
+
)
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
// Sử dụng - Tạo người dùng mới
|
|
453
|
+
const { onOpen: openCreate } = useDisclosure<FormInput, FormOutput>({
|
|
454
|
+
tag: 'UserForm',
|
|
455
|
+
onOk: (userData) => {
|
|
456
|
+
createUser(userData)
|
|
457
|
+
toast.success('Đã tạo người dùng!')
|
|
458
|
+
}
|
|
459
|
+
})
|
|
460
|
+
|
|
461
|
+
// Sử dụng - Chỉnh sửa người dùng hiện có
|
|
462
|
+
const { onOpen: openEdit } = useDisclosure<FormInput, FormOutput>({
|
|
463
|
+
tag: 'UserForm',
|
|
464
|
+
onOk: (userData) => {
|
|
465
|
+
updateUser(userId, userData)
|
|
466
|
+
toast.success('Đã cập nhật người dùng!')
|
|
467
|
+
}
|
|
468
|
+
})
|
|
469
|
+
|
|
470
|
+
<Button onClick={() => openCreate({})}>Tạo Người Dùng</Button>
|
|
471
|
+
<Button onClick={() => openEdit({ initialData: existingUser })}>Chỉnh Sửa Người Dùng</Button>
|
|
472
|
+
```
|
|
473
|
+
|
|
474
|
+
---
|
|
475
|
+
|
|
476
|
+
### Với Ant Design 6
|
|
477
|
+
|
|
478
|
+
Ví dụ hoàn chỉnh với Ant Design 6:
|
|
479
|
+
|
|
480
|
+
```tsx
|
|
481
|
+
import React from 'react'
|
|
482
|
+
import { Modal, Button, Space, Form, Input, message } from 'antd'
|
|
483
|
+
import { ReactHookModalProvider, useDisclosure } from '@vnquang24/react-modal'
|
|
484
|
+
|
|
485
|
+
// Các Component Modal
|
|
486
|
+
const WelcomeModal = () => {
|
|
487
|
+
const { isOpen, onClose, input } = useDisclosure<{ username: string }>({
|
|
488
|
+
tag: 'WelcomeModal'
|
|
489
|
+
})
|
|
490
|
+
|
|
491
|
+
return (
|
|
492
|
+
<Modal open={isOpen} onCancel={onClose} onOk={onClose} title="Chào Mừng!">
|
|
493
|
+
<p>Xin chào, {input?.username}! Chào mừng bạn đến với ứng dụng của chúng tôi.</p>
|
|
494
|
+
</Modal>
|
|
495
|
+
)
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
const SettingsModal = () => {
|
|
499
|
+
const { isOpen, onClose, onOk } = useDisclosure<void, { theme: string }>({
|
|
500
|
+
tag: 'SettingsModal'
|
|
501
|
+
})
|
|
502
|
+
|
|
503
|
+
const handleSave = () => {
|
|
504
|
+
onOk({ theme: 'dark' })
|
|
505
|
+
onClose()
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
return (
|
|
509
|
+
<Modal open={isOpen} onCancel={onClose} onOk={handleSave} title="Cài Đặt">
|
|
510
|
+
<p>Cấu hình cài đặt của bạn tại đây...</p>
|
|
511
|
+
</Modal>
|
|
512
|
+
)
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
// Đăng ký tất cả modals
|
|
516
|
+
const modals = {
|
|
517
|
+
WelcomeModal,
|
|
518
|
+
SettingsModal
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
// Ứng dụng chính
|
|
522
|
+
const App = () => {
|
|
523
|
+
const { onOpen: openWelcome } = useDisclosure<{ username: string }>({
|
|
524
|
+
tag: 'WelcomeModal'
|
|
525
|
+
})
|
|
526
|
+
|
|
527
|
+
const { onOpen: openSettings } = useDisclosure<void, { theme: string }>({
|
|
528
|
+
tag: 'SettingsModal',
|
|
529
|
+
onOk: (settings) => {
|
|
530
|
+
message.success(`Đã đổi theme sang: ${settings?.theme}`)
|
|
531
|
+
}
|
|
532
|
+
})
|
|
533
|
+
|
|
534
|
+
return (
|
|
535
|
+
<ReactHookModalProvider modals={modals}>
|
|
536
|
+
<Space>
|
|
537
|
+
<Button type="primary" onClick={() => openWelcome({ username: 'Nguyễn Văn A' })}>
|
|
538
|
+
Hiển Thị Chào Mừng
|
|
539
|
+
</Button>
|
|
540
|
+
<Button onClick={openSettings}>
|
|
541
|
+
Mở Cài Đặt
|
|
542
|
+
</Button>
|
|
543
|
+
</Space>
|
|
544
|
+
</ReactHookModalProvider>
|
|
545
|
+
)
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
export default App
|
|
549
|
+
```
|
|
550
|
+
|
|
551
|
+
---
|
|
552
|
+
|
|
553
|
+
## Tương Thích
|
|
554
|
+
|
|
555
|
+
| Phiên bản React | Hỗ trợ |
|
|
556
|
+
|-----------------|--------|
|
|
557
|
+
| 16.8+ | ✅ |
|
|
558
|
+
| 17.x | ✅ |
|
|
559
|
+
| 18.x | ✅ |
|
|
560
|
+
| 19.x | ✅ |
|
|
561
|
+
|
|
562
|
+
| Thư viện UI | Đã test |
|
|
563
|
+
|-----------------|---------|
|
|
564
|
+
| Ant Design 6 | ✅ |
|
|
565
|
+
| Material UI 5+ | ✅ |
|
|
566
|
+
| Chakra UI 2+ | ✅ |
|
|
567
|
+
| Headless UI | ✅ |
|
|
568
|
+
| Radix UI | ✅ |
|
|
569
|
+
| Modal tự viết | ✅ |
|
|
570
|
+
|
|
571
|
+
---
|
|
572
|
+
|
|
573
|
+
## Dependencies
|
|
574
|
+
|
|
575
|
+
- `@tanstack/react-store` - Để quản lý state
|
|
576
|
+
|
|
577
|
+
---
|
|
578
|
+
|
|
579
|
+
## Giấy Phép
|
|
580
|
+
|
|
581
|
+
MIT © [vnquang24](https://github.com/vnquang24)
|
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
declare const writeFileSync: any;
|
|
3
|
+
declare const Project: any;
|
|
4
|
+
declare const pathFile: string;
|
|
5
|
+
declare const project: any;
|
|
6
|
+
declare const sourceFile: any;
|
|
7
|
+
declare const exportedDeclarations: any;
|
|
8
|
+
declare const pathGenerate = "node_modules/react-hook-disclosure-modal/dist/hook/tag.d.ts";
|
|
9
|
+
declare const allTags: unknown[];
|
|
10
|
+
//# sourceMappingURL=cli.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["src/cli.ts"],"names":[],"mappings":";AACA,QAAA,MAAQ,aAAa,KAAkB,CAAA;AAEvC,QAAA,MAAQ,OAAO,KAAwB,CAAA;AACvC,QAAA,MAAM,QAAQ,QAAkB,CAAA;AAKhC,QAAA,MAAM,OAAO,KAIZ,CAAA;AACD,QAAA,MAAM,UAAU,KAAwC,CAAA;AACxD,QAAA,MAAM,oBAAoB,KAAuC,CAAA;AACjE,QAAA,MAAM,YAAY,gEAAgE,CAAA;AAClF,QAAA,MAAM,OAAO,WAAyD,CAAA"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { TagType } from './tag';
|
|
2
|
+
export declare type Any = string | number | boolean | object | undefined | Record<string, any>;
|
|
3
|
+
export interface DisclosureHookProps<O> {
|
|
4
|
+
tag: TagType;
|
|
5
|
+
isOpen?: boolean;
|
|
6
|
+
onOpen?: () => void;
|
|
7
|
+
onClose?: () => void;
|
|
8
|
+
onToggle?: () => void;
|
|
9
|
+
onChange?: (isOpen: boolean) => void;
|
|
10
|
+
onOk?: (output?: O) => void;
|
|
11
|
+
onCancel?: () => void;
|
|
12
|
+
}
|
|
13
|
+
export declare const useDisclosure: <Input = Any, Output = Any>(disclosureHook: DisclosureHookProps<Output>) => {
|
|
14
|
+
isOpen: boolean;
|
|
15
|
+
input: Input | undefined;
|
|
16
|
+
onOpen: (input?: Input | undefined) => void;
|
|
17
|
+
onClose: () => void;
|
|
18
|
+
onToggle: () => void;
|
|
19
|
+
onOk: (output?: Output | undefined) => void;
|
|
20
|
+
onChange: (isOpen: boolean) => void;
|
|
21
|
+
updateInput: (input?: Input | undefined) => void;
|
|
22
|
+
store: import("@tanstack/store").Store<import("../store").State, (cb: import("../store").State) => import("../store").State>;
|
|
23
|
+
};
|
|
24
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/hook/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,OAAO,CAAA;AAG/B,oBAAY,GAAG,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,GAAG,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;AAEtF,MAAM,WAAW,mBAAmB,CAAC,CAAC;IACpC,GAAG,EAAE,OAAO,CAAA;IACZ,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,MAAM,CAAC,EAAE,MAAM,IAAI,CAAA;IACnB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAA;IACpB,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAA;IACrB,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,IAAI,CAAA;IACpC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,KAAK,IAAI,CAAA;IAC3B,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAA;CACtB;AAED,eAAO,MAAM,aAAa;;;;;;;uBAqDc,OAAO;;;CAgC9C,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tag.d.ts","sourceRoot":"","sources":["../src/hook/tag.ts"],"names":[],"mappings":"AAAA,oBAAY,OAAO,GAAG,MAAM,CAAA"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
declare type ModalComponent = React.FunctionComponent<any> | React.ComponentType<any>;
|
|
3
|
+
export declare type ReactHookModalProviderProps = {
|
|
4
|
+
children: React.ReactNode;
|
|
5
|
+
modals: Record<string, ModalComponent>;
|
|
6
|
+
};
|
|
7
|
+
export declare const ReactHookModalProvider: ({ children, modals }: ReactHookModalProviderProps) => React.JSX.Element;
|
|
8
|
+
export * from './hook';
|
|
9
|
+
export * from './provider';
|
|
10
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["src/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAG9B,aAAK,cAAc,GAAG,KAAK,CAAC,iBAAiB,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,aAAa,CAAC,GAAG,CAAC,CAAA;AAE7E,oBAAY,2BAA2B,GAAG;IACxC,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;IACzB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAA;CACvC,CAAA;AAED,eAAO,MAAM,sBAAsB,yBAGhC,2BAA2B,sBAO7B,CAAA;AAED,cAAc,QAAQ,CAAA;AACtB,cAAc,YAAY,CAAA"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
|
|
2
|
+
|
|
3
|
+
var React = require('react');
|
|
4
|
+
var React__default = _interopDefault(React);
|
|
5
|
+
var reactStore = require('@tanstack/react-store');
|
|
6
|
+
|
|
7
|
+
function _extends() {
|
|
8
|
+
return _extends = Object.assign ? Object.assign.bind() : function (n) {
|
|
9
|
+
for (var e = 1; e < arguments.length; e++) {
|
|
10
|
+
var t = arguments[e];
|
|
11
|
+
for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]);
|
|
12
|
+
}
|
|
13
|
+
return n;
|
|
14
|
+
}, _extends.apply(null, arguments);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
var store = new reactStore.Store({
|
|
18
|
+
modalTags: {}
|
|
19
|
+
});
|
|
20
|
+
var openModal = function openModal(tag, input) {
|
|
21
|
+
store.setState(function (state) {
|
|
22
|
+
var _extends2;
|
|
23
|
+
return {
|
|
24
|
+
modalTags: _extends({}, state.modalTags, (_extends2 = {}, _extends2[tag] = _extends({}, state.modalTags[tag], {
|
|
25
|
+
input: input != null ? input : true
|
|
26
|
+
}), _extends2))
|
|
27
|
+
};
|
|
28
|
+
});
|
|
29
|
+
};
|
|
30
|
+
var okModal = function okModal(tag, output) {
|
|
31
|
+
store.setState(function (state) {
|
|
32
|
+
var _extends3;
|
|
33
|
+
return {
|
|
34
|
+
modalTags: _extends({}, state.modalTags, (_extends3 = {}, _extends3[tag] = _extends({}, state.modalTags[tag], {
|
|
35
|
+
output: output
|
|
36
|
+
}), _extends3))
|
|
37
|
+
};
|
|
38
|
+
});
|
|
39
|
+
};
|
|
40
|
+
var closeModal = function closeModal(tag) {
|
|
41
|
+
store.setState(function (state) {
|
|
42
|
+
var _extends4;
|
|
43
|
+
return {
|
|
44
|
+
modalTags: _extends({}, state.modalTags, (_extends4 = {}, _extends4[tag] = {
|
|
45
|
+
input: false
|
|
46
|
+
}, _extends4))
|
|
47
|
+
};
|
|
48
|
+
});
|
|
49
|
+
};
|
|
50
|
+
var toggleModal = function toggleModal(tag) {
|
|
51
|
+
store.setState(function (state) {
|
|
52
|
+
var _state$modalTags$tag, _extends5;
|
|
53
|
+
return {
|
|
54
|
+
modalTags: _extends({}, state.modalTags, (_extends5 = {}, _extends5[tag] = _extends({}, state.modalTags[tag], {
|
|
55
|
+
input: !((_state$modalTags$tag = state.modalTags[tag]) !== null && _state$modalTags$tag !== void 0 && _state$modalTags$tag.input)
|
|
56
|
+
}), _extends5))
|
|
57
|
+
};
|
|
58
|
+
});
|
|
59
|
+
};
|
|
60
|
+
var clearModalTag = function clearModalTag(tag) {
|
|
61
|
+
store.setState(function (state) {
|
|
62
|
+
var newModalTags = _extends({}, state.modalTags);
|
|
63
|
+
delete newModalTags[tag];
|
|
64
|
+
return {
|
|
65
|
+
modalTags: newModalTags
|
|
66
|
+
};
|
|
67
|
+
});
|
|
68
|
+
};
|
|
69
|
+
var clearAllModalTags = function clearAllModalTags() {
|
|
70
|
+
store.setState(function () {
|
|
71
|
+
return {
|
|
72
|
+
modalTags: {}
|
|
73
|
+
};
|
|
74
|
+
});
|
|
75
|
+
};
|
|
76
|
+
var useModalStore = function useModalStore(stateCallback) {
|
|
77
|
+
return reactStore.useStore(store, stateCallback);
|
|
78
|
+
};
|
|
79
|
+
var useModalActions = function useModalActions(actionCallback) {
|
|
80
|
+
return actionCallback({
|
|
81
|
+
openModal: openModal,
|
|
82
|
+
okModal: okModal,
|
|
83
|
+
closeModal: closeModal,
|
|
84
|
+
toggleModal: toggleModal,
|
|
85
|
+
clearModalTag: clearModalTag,
|
|
86
|
+
clearAllModalTags: clearAllModalTags
|
|
87
|
+
});
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
var ModalWrapper = React.memo(function ModalWrapper(_ref) {
|
|
91
|
+
var modals = _ref.modals;
|
|
92
|
+
var modalTags = useModalStore(function (state) {
|
|
93
|
+
return state.modalTags;
|
|
94
|
+
});
|
|
95
|
+
var modalOpened = React.useMemo(function () {
|
|
96
|
+
return Object.entries(modals).filter(function (_ref2) {
|
|
97
|
+
var _modalTags$tag;
|
|
98
|
+
var tag = _ref2[0];
|
|
99
|
+
return !!((_modalTags$tag = modalTags[tag]) !== null && _modalTags$tag !== void 0 && _modalTags$tag.input);
|
|
100
|
+
}).map(function (_ref3) {
|
|
101
|
+
var tag = _ref3[0],
|
|
102
|
+
Modal = _ref3[1];
|
|
103
|
+
return React__default.createElement(Modal, {
|
|
104
|
+
key: tag
|
|
105
|
+
});
|
|
106
|
+
});
|
|
107
|
+
}, [modals, modalTags]);
|
|
108
|
+
return React__default.createElement(React__default.Fragment, null, modalOpened);
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
var useDisclosure = function useDisclosure(disclosureHook) {
|
|
112
|
+
var tag = disclosureHook.tag;
|
|
113
|
+
var disclosureHookRef = React.useRef(disclosureHook);
|
|
114
|
+
disclosureHookRef.current = disclosureHook;
|
|
115
|
+
var inputState = useModalStore(function (state) {
|
|
116
|
+
var _state$modalTags$tag;
|
|
117
|
+
return (_state$modalTags$tag = state.modalTags[tag]) === null || _state$modalTags$tag === void 0 ? void 0 : _state$modalTags$tag.input;
|
|
118
|
+
});
|
|
119
|
+
var outputState = useModalStore(function (state) {
|
|
120
|
+
var _state$modalTags$tag2;
|
|
121
|
+
return (_state$modalTags$tag2 = state.modalTags[tag]) === null || _state$modalTags$tag2 === void 0 ? void 0 : _state$modalTags$tag2.output;
|
|
122
|
+
});
|
|
123
|
+
var clearDisclosureTag = useModalActions(function (actions) {
|
|
124
|
+
return actions.clearModalTag;
|
|
125
|
+
});
|
|
126
|
+
var onOpenAction = useModalActions(function (actions) {
|
|
127
|
+
return actions.openModal;
|
|
128
|
+
});
|
|
129
|
+
var okAction = useModalActions(function (actions) {
|
|
130
|
+
return actions.okModal;
|
|
131
|
+
});
|
|
132
|
+
var onCloseAction = useModalActions(function (actions) {
|
|
133
|
+
return actions.closeModal;
|
|
134
|
+
});
|
|
135
|
+
var onToggleAction = useModalActions(function (actions) {
|
|
136
|
+
return actions.toggleModal;
|
|
137
|
+
});
|
|
138
|
+
var updateInput = React.useCallback(function (input) {
|
|
139
|
+
var processedInput = input;
|
|
140
|
+
if (processedInput && typeof processedInput == 'object' && 'preventDefault' in processedInput) {
|
|
141
|
+
processedInput = undefined;
|
|
142
|
+
}
|
|
143
|
+
onOpenAction(tag, processedInput);
|
|
144
|
+
}, [tag, onOpenAction]);
|
|
145
|
+
var onOpen = React.useCallback(function (input) {
|
|
146
|
+
var _disclosureHookRef$cu, _disclosureHookRef$cu2;
|
|
147
|
+
updateInput(input);
|
|
148
|
+
(_disclosureHookRef$cu = disclosureHookRef.current) === null || _disclosureHookRef$cu === void 0 ? void 0 : (_disclosureHookRef$cu2 = _disclosureHookRef$cu.onOpen) === null || _disclosureHookRef$cu2 === void 0 ? void 0 : _disclosureHookRef$cu2.call(_disclosureHookRef$cu);
|
|
149
|
+
}, [updateInput]);
|
|
150
|
+
var onClose = React.useCallback(function () {
|
|
151
|
+
var _disclosureHookRef$cu3, _disclosureHookRef$cu4;
|
|
152
|
+
onCloseAction(tag);
|
|
153
|
+
(_disclosureHookRef$cu3 = disclosureHookRef.current) === null || _disclosureHookRef$cu3 === void 0 ? void 0 : (_disclosureHookRef$cu4 = _disclosureHookRef$cu3.onClose) === null || _disclosureHookRef$cu4 === void 0 ? void 0 : _disclosureHookRef$cu4.call(_disclosureHookRef$cu3);
|
|
154
|
+
}, [tag, onCloseAction]);
|
|
155
|
+
var onToggle = React.useCallback(function () {
|
|
156
|
+
var _disclosureHookRef$cu5, _disclosureHookRef$cu6;
|
|
157
|
+
onToggleAction(tag);
|
|
158
|
+
(_disclosureHookRef$cu5 = disclosureHookRef.current) === null || _disclosureHookRef$cu5 === void 0 ? void 0 : (_disclosureHookRef$cu6 = _disclosureHookRef$cu5.onToggle) === null || _disclosureHookRef$cu6 === void 0 ? void 0 : _disclosureHookRef$cu6.call(_disclosureHookRef$cu5);
|
|
159
|
+
}, [tag, onToggleAction]);
|
|
160
|
+
var onOk = React.useCallback(function (output) {
|
|
161
|
+
var _disclosureHookRef$cu7, _disclosureHookRef$cu8;
|
|
162
|
+
(_disclosureHookRef$cu7 = disclosureHookRef.current) === null || _disclosureHookRef$cu7 === void 0 ? void 0 : (_disclosureHookRef$cu8 = _disclosureHookRef$cu7.onOk) === null || _disclosureHookRef$cu8 === void 0 ? void 0 : _disclosureHookRef$cu8.call(_disclosureHookRef$cu7, output);
|
|
163
|
+
okAction(tag, output);
|
|
164
|
+
}, [tag, okAction]);
|
|
165
|
+
var onChange = React.useCallback(function (isOpen) {
|
|
166
|
+
var _disclosureHookRef$cu9, _disclosureHookRef$cu0;
|
|
167
|
+
if (isOpen) {
|
|
168
|
+
onOpen();
|
|
169
|
+
} else {
|
|
170
|
+
onClose();
|
|
171
|
+
}
|
|
172
|
+
(_disclosureHookRef$cu9 = disclosureHookRef.current) === null || _disclosureHookRef$cu9 === void 0 ? void 0 : (_disclosureHookRef$cu0 = _disclosureHookRef$cu9.onChange) === null || _disclosureHookRef$cu0 === void 0 ? void 0 : _disclosureHookRef$cu0.call(_disclosureHookRef$cu9, isOpen);
|
|
173
|
+
}, [onOpen, onClose]);
|
|
174
|
+
React.useEffect(function () {
|
|
175
|
+
return function () {
|
|
176
|
+
clearDisclosureTag(tag);
|
|
177
|
+
};
|
|
178
|
+
}, [tag, clearDisclosureTag]);
|
|
179
|
+
React.useEffect(function () {
|
|
180
|
+
if (outputState) {
|
|
181
|
+
onOk(outputState);
|
|
182
|
+
}
|
|
183
|
+
}, [outputState, onOk]);
|
|
184
|
+
return {
|
|
185
|
+
isOpen: !!inputState,
|
|
186
|
+
input: typeof inputState === 'boolean' ? undefined : inputState,
|
|
187
|
+
onOpen: onOpen,
|
|
188
|
+
onClose: onClose,
|
|
189
|
+
onToggle: onToggle,
|
|
190
|
+
onOk: onOk,
|
|
191
|
+
onChange: onChange,
|
|
192
|
+
updateInput: updateInput,
|
|
193
|
+
store: store
|
|
194
|
+
};
|
|
195
|
+
};
|
|
196
|
+
|
|
197
|
+
var ReactHookModalProvider = function ReactHookModalProvider(_ref) {
|
|
198
|
+
var children = _ref.children,
|
|
199
|
+
modals = _ref.modals;
|
|
200
|
+
return React.createElement(React.Fragment, null, React.createElement(ModalWrapper, {
|
|
201
|
+
modals: modals
|
|
202
|
+
}), children);
|
|
203
|
+
};
|
|
204
|
+
|
|
205
|
+
exports.ModalWrapper = ModalWrapper;
|
|
206
|
+
exports.ReactHookModalProvider = ReactHookModalProvider;
|
|
207
|
+
exports.useDisclosure = useDisclosure;
|
|
208
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../src/store/index.ts","../src/provider/index.tsx","../src/hook/index.ts","../src/index.tsx"],"sourcesContent":["import { Store, useStore } from \"@tanstack/react-store\";\n\n// You can instantiate the store outside of React components too!\n\nimport { Any } from '../hook'\n\nexport type State = {\n modalTags: {\n [tag: string]: {\n input?: Any\n output?: Any\n }\n }\n}\n\nexport type Action = {\n openModal: (tag: string, input?: Any) => void\n okModal: (tag: string, output?: Any) => void\n closeModal: (tag: string) => void\n toggleModal: (tag: string) => void\n clearModalTag: (tag: string) => void\n clearAllModalTags: () => void\n}\nexport const store = new Store<State>({\n modalTags: {}\n});\n\n\nconst openModal = (tag: string, input?: Any) => {\n store.setState((state) => ({\n modalTags: {\n ...state.modalTags,\n [tag]: {\n ...state.modalTags[tag],\n input: input ?? true // Default to true if no input is provided\n }\n }\n }))\n}\nconst okModal = (tag: string, output?: Any) => {\n store.setState((state) => ({\n modalTags: {\n ...state.modalTags,\n [tag]: {\n ...state.modalTags[tag],\n output\n }\n }\n }))\n}\nconst closeModal = (tag: string) => {\n store.setState((state) => ({\n modalTags: {\n ...state.modalTags,\n [tag]: { input: false }\n }\n }))\n}\nconst toggleModal = (tag: string) => {\n store.setState((state) => ({\n modalTags: {\n ...state.modalTags,\n [tag]: {\n ...state.modalTags[tag],\n input: !state.modalTags[tag]?.input\n }\n }\n }))\n}\nconst clearModalTag = (tag: string) => {\n store.setState((state) => {\n const newModalTags = { ...state.modalTags };\n delete newModalTags[tag];\n return { modalTags: newModalTags };\n })\n}\nconst clearAllModalTags = () => {\n store.setState(() => ({ modalTags: {} }))\n}\n\nexport const useModalStore = <T>(\n stateCallback: (state: State) => T,\n): T => {\n return useStore(store, stateCallback)\n}\n\nexport const useModalActions = <T>(\n actionCallback: (action: Action) => T\n): T => {\n return actionCallback(\n {\n openModal,\n okModal,\n closeModal,\n toggleModal,\n clearModalTag,\n clearAllModalTags\n }\n )\n}","import React, { useMemo, memo } from 'react'\nimport { useModalStore, State } from '../store'\n\ntype ModalComponent = React.FunctionComponent<any> | React.ComponentType<any>\n\nexport interface ModalWrapperProps {\n modals: Record<string, ModalComponent>\n}\n\nexport const ModalWrapper = memo(function ModalWrapper({\n modals\n}: ModalWrapperProps) {\n const modalTags = useModalStore((state: State) => state.modalTags)\n \n const modalOpened = useMemo(() => {\n return Object.entries(modals)\n .filter(([tag]) => !!modalTags[tag]?.input)\n .map(([tag, Modal]) => <Modal key={tag} />)\n }, [modals, modalTags])\n \n return <React.Fragment>{modalOpened}</React.Fragment>\n})\n","import { useEffect, useCallback, useRef } from 'react'\nimport { TagType } from './tag'\nimport { useModalStore, useModalActions, store } from '../store'\n\nexport type Any = string | number | boolean | object | undefined | Record<string, any>\n\nexport interface DisclosureHookProps<O> {\n tag: TagType\n isOpen?: boolean\n onOpen?: () => void\n onClose?: () => void\n onToggle?: () => void\n onChange?: (isOpen: boolean) => void\n onOk?: (output?: O) => void\n onCancel?: () => void\n}\n\nexport const useDisclosure = <Input = Any, Output = Any>(\n disclosureHook: DisclosureHookProps<Output>\n) => {\n const tag = disclosureHook.tag\n \n // Use refs to store callbacks to avoid stale closures\n const disclosureHookRef = useRef(disclosureHook)\n disclosureHookRef.current = disclosureHook\n\n const inputState = useModalStore(\n (state) => state.modalTags[tag]?.input\n ) as Input\n const outputState = useModalStore(\n (state) => state.modalTags[tag]?.output\n ) as Output\n const clearDisclosureTag = useModalActions(\n (actions) => actions.clearModalTag\n )\n\n const onOpenAction = useModalActions((actions) => actions.openModal)\n const okAction = useModalActions((actions) => actions.okModal)\n const onCloseAction = useModalActions((actions) => actions.closeModal)\n const onToggleAction = useModalActions((actions) => actions.toggleModal)\n\n const updateInput = useCallback((input?: Input) => {\n // If input is a function, call it and set the result as input\n let processedInput = input\n if (processedInput && typeof processedInput == 'object' && 'preventDefault' in processedInput) {\n processedInput = undefined\n }\n onOpenAction(tag, processedInput as Any)\n }, [tag, onOpenAction])\n\n const onOpen = useCallback((input?: Input) => {\n updateInput(input)\n disclosureHookRef.current?.onOpen?.()\n }, [updateInput])\n\n const onClose = useCallback(() => {\n onCloseAction(tag)\n disclosureHookRef.current?.onClose?.()\n }, [tag, onCloseAction])\n\n const onToggle = useCallback(() => {\n onToggleAction(tag)\n disclosureHookRef.current?.onToggle?.()\n }, [tag, onToggleAction])\n\n const onOk = useCallback((output?: Output) => {\n disclosureHookRef.current?.onOk?.(output)\n okAction(tag, output as Any)\n }, [tag, okAction])\n\n const onChange = useCallback((isOpen: boolean) => {\n if (isOpen) {\n onOpen()\n } else {\n onClose()\n }\n disclosureHookRef.current?.onChange?.(isOpen)\n }, [onOpen, onClose])\n\n useEffect(() => {\n return () => {\n clearDisclosureTag(tag)\n }\n }, [tag, clearDisclosureTag])\n\n useEffect(() => {\n if (outputState) {\n onOk(outputState as Output)\n }\n }, [outputState, onOk])\n\n return {\n isOpen: !!inputState,\n input: typeof inputState === 'boolean' ? undefined : inputState,\n onOpen,\n onClose,\n onToggle,\n onOk,\n onChange,\n updateInput,\n store\n }\n}\n","import * as React from 'react'\nimport { ModalWrapper } from './provider'\n\ntype ModalComponent = React.FunctionComponent<any> | React.ComponentType<any>\n\nexport type ReactHookModalProviderProps = {\n children: React.ReactNode\n modals: Record<string, ModalComponent>\n}\n\nexport const ReactHookModalProvider = ({\n children,\n modals\n}: ReactHookModalProviderProps) => {\n return (\n <React.Fragment>\n <ModalWrapper modals={modals} />\n {children}\n </React.Fragment>\n )\n}\n\nexport * from './hook'\nexport * from './provider'\n"],"names":["store","Store","modalTags","openModal","tag","input","setState","state","_extends2","_extends","okModal","output","_extends3","closeModal","_extends4","toggleModal","_state$modalTags$tag","_extends5","clearModalTag","newModalTags","clearAllModalTags","useModalStore","stateCallback","useStore","useModalActions","actionCallback","ModalWrapper","memo","_ref","modals","modalOpened","useMemo","Object","entries","filter","_ref2","_modalTags$tag","map","_ref3","Modal","React","key","Fragment","useDisclosure","disclosureHook","disclosureHookRef","useRef","current","inputState","outputState","_state$modalTags$tag2","clearDisclosureTag","actions","onOpenAction","okAction","onCloseAction","onToggleAction","updateInput","useCallback","processedInput","undefined","onOpen","_disclosureHookRef$cu","_disclosureHookRef$cu2","call","onClose","_disclosureHookRef$cu3","_disclosureHookRef$cu4","onToggle","_disclosureHookRef$cu5","_disclosureHookRef$cu6","onOk","_disclosureHookRef$cu7","_disclosureHookRef$cu8","onChange","isOpen","_disclosureHookRef$cu9","_disclosureHookRef$cu0","useEffect","ReactHookModalProvider","children"],"mappings":"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"}
|
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
import React__default, { memo, useMemo, useRef, useCallback, useEffect, createElement, Fragment } from 'react';
|
|
2
|
+
import { Store, useStore } from '@tanstack/react-store';
|
|
3
|
+
|
|
4
|
+
function _extends() {
|
|
5
|
+
return _extends = Object.assign ? Object.assign.bind() : function (n) {
|
|
6
|
+
for (var e = 1; e < arguments.length; e++) {
|
|
7
|
+
var t = arguments[e];
|
|
8
|
+
for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]);
|
|
9
|
+
}
|
|
10
|
+
return n;
|
|
11
|
+
}, _extends.apply(null, arguments);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
var store = new Store({
|
|
15
|
+
modalTags: {}
|
|
16
|
+
});
|
|
17
|
+
var openModal = function openModal(tag, input) {
|
|
18
|
+
store.setState(function (state) {
|
|
19
|
+
var _extends2;
|
|
20
|
+
return {
|
|
21
|
+
modalTags: _extends({}, state.modalTags, (_extends2 = {}, _extends2[tag] = _extends({}, state.modalTags[tag], {
|
|
22
|
+
input: input != null ? input : true
|
|
23
|
+
}), _extends2))
|
|
24
|
+
};
|
|
25
|
+
});
|
|
26
|
+
};
|
|
27
|
+
var okModal = function okModal(tag, output) {
|
|
28
|
+
store.setState(function (state) {
|
|
29
|
+
var _extends3;
|
|
30
|
+
return {
|
|
31
|
+
modalTags: _extends({}, state.modalTags, (_extends3 = {}, _extends3[tag] = _extends({}, state.modalTags[tag], {
|
|
32
|
+
output: output
|
|
33
|
+
}), _extends3))
|
|
34
|
+
};
|
|
35
|
+
});
|
|
36
|
+
};
|
|
37
|
+
var closeModal = function closeModal(tag) {
|
|
38
|
+
store.setState(function (state) {
|
|
39
|
+
var _extends4;
|
|
40
|
+
return {
|
|
41
|
+
modalTags: _extends({}, state.modalTags, (_extends4 = {}, _extends4[tag] = {
|
|
42
|
+
input: false
|
|
43
|
+
}, _extends4))
|
|
44
|
+
};
|
|
45
|
+
});
|
|
46
|
+
};
|
|
47
|
+
var toggleModal = function toggleModal(tag) {
|
|
48
|
+
store.setState(function (state) {
|
|
49
|
+
var _state$modalTags$tag, _extends5;
|
|
50
|
+
return {
|
|
51
|
+
modalTags: _extends({}, state.modalTags, (_extends5 = {}, _extends5[tag] = _extends({}, state.modalTags[tag], {
|
|
52
|
+
input: !((_state$modalTags$tag = state.modalTags[tag]) !== null && _state$modalTags$tag !== void 0 && _state$modalTags$tag.input)
|
|
53
|
+
}), _extends5))
|
|
54
|
+
};
|
|
55
|
+
});
|
|
56
|
+
};
|
|
57
|
+
var clearModalTag = function clearModalTag(tag) {
|
|
58
|
+
store.setState(function (state) {
|
|
59
|
+
var newModalTags = _extends({}, state.modalTags);
|
|
60
|
+
delete newModalTags[tag];
|
|
61
|
+
return {
|
|
62
|
+
modalTags: newModalTags
|
|
63
|
+
};
|
|
64
|
+
});
|
|
65
|
+
};
|
|
66
|
+
var clearAllModalTags = function clearAllModalTags() {
|
|
67
|
+
store.setState(function () {
|
|
68
|
+
return {
|
|
69
|
+
modalTags: {}
|
|
70
|
+
};
|
|
71
|
+
});
|
|
72
|
+
};
|
|
73
|
+
var useModalStore = function useModalStore(stateCallback) {
|
|
74
|
+
return useStore(store, stateCallback);
|
|
75
|
+
};
|
|
76
|
+
var useModalActions = function useModalActions(actionCallback) {
|
|
77
|
+
return actionCallback({
|
|
78
|
+
openModal: openModal,
|
|
79
|
+
okModal: okModal,
|
|
80
|
+
closeModal: closeModal,
|
|
81
|
+
toggleModal: toggleModal,
|
|
82
|
+
clearModalTag: clearModalTag,
|
|
83
|
+
clearAllModalTags: clearAllModalTags
|
|
84
|
+
});
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
var ModalWrapper = memo(function ModalWrapper(_ref) {
|
|
88
|
+
var modals = _ref.modals;
|
|
89
|
+
var modalTags = useModalStore(function (state) {
|
|
90
|
+
return state.modalTags;
|
|
91
|
+
});
|
|
92
|
+
var modalOpened = useMemo(function () {
|
|
93
|
+
return Object.entries(modals).filter(function (_ref2) {
|
|
94
|
+
var _modalTags$tag;
|
|
95
|
+
var tag = _ref2[0];
|
|
96
|
+
return !!((_modalTags$tag = modalTags[tag]) !== null && _modalTags$tag !== void 0 && _modalTags$tag.input);
|
|
97
|
+
}).map(function (_ref3) {
|
|
98
|
+
var tag = _ref3[0],
|
|
99
|
+
Modal = _ref3[1];
|
|
100
|
+
return React__default.createElement(Modal, {
|
|
101
|
+
key: tag
|
|
102
|
+
});
|
|
103
|
+
});
|
|
104
|
+
}, [modals, modalTags]);
|
|
105
|
+
return React__default.createElement(React__default.Fragment, null, modalOpened);
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
var useDisclosure = function useDisclosure(disclosureHook) {
|
|
109
|
+
var tag = disclosureHook.tag;
|
|
110
|
+
var disclosureHookRef = useRef(disclosureHook);
|
|
111
|
+
disclosureHookRef.current = disclosureHook;
|
|
112
|
+
var inputState = useModalStore(function (state) {
|
|
113
|
+
var _state$modalTags$tag;
|
|
114
|
+
return (_state$modalTags$tag = state.modalTags[tag]) === null || _state$modalTags$tag === void 0 ? void 0 : _state$modalTags$tag.input;
|
|
115
|
+
});
|
|
116
|
+
var outputState = useModalStore(function (state) {
|
|
117
|
+
var _state$modalTags$tag2;
|
|
118
|
+
return (_state$modalTags$tag2 = state.modalTags[tag]) === null || _state$modalTags$tag2 === void 0 ? void 0 : _state$modalTags$tag2.output;
|
|
119
|
+
});
|
|
120
|
+
var clearDisclosureTag = useModalActions(function (actions) {
|
|
121
|
+
return actions.clearModalTag;
|
|
122
|
+
});
|
|
123
|
+
var onOpenAction = useModalActions(function (actions) {
|
|
124
|
+
return actions.openModal;
|
|
125
|
+
});
|
|
126
|
+
var okAction = useModalActions(function (actions) {
|
|
127
|
+
return actions.okModal;
|
|
128
|
+
});
|
|
129
|
+
var onCloseAction = useModalActions(function (actions) {
|
|
130
|
+
return actions.closeModal;
|
|
131
|
+
});
|
|
132
|
+
var onToggleAction = useModalActions(function (actions) {
|
|
133
|
+
return actions.toggleModal;
|
|
134
|
+
});
|
|
135
|
+
var updateInput = useCallback(function (input) {
|
|
136
|
+
var processedInput = input;
|
|
137
|
+
if (processedInput && typeof processedInput == 'object' && 'preventDefault' in processedInput) {
|
|
138
|
+
processedInput = undefined;
|
|
139
|
+
}
|
|
140
|
+
onOpenAction(tag, processedInput);
|
|
141
|
+
}, [tag, onOpenAction]);
|
|
142
|
+
var onOpen = useCallback(function (input) {
|
|
143
|
+
var _disclosureHookRef$cu, _disclosureHookRef$cu2;
|
|
144
|
+
updateInput(input);
|
|
145
|
+
(_disclosureHookRef$cu = disclosureHookRef.current) === null || _disclosureHookRef$cu === void 0 ? void 0 : (_disclosureHookRef$cu2 = _disclosureHookRef$cu.onOpen) === null || _disclosureHookRef$cu2 === void 0 ? void 0 : _disclosureHookRef$cu2.call(_disclosureHookRef$cu);
|
|
146
|
+
}, [updateInput]);
|
|
147
|
+
var onClose = useCallback(function () {
|
|
148
|
+
var _disclosureHookRef$cu3, _disclosureHookRef$cu4;
|
|
149
|
+
onCloseAction(tag);
|
|
150
|
+
(_disclosureHookRef$cu3 = disclosureHookRef.current) === null || _disclosureHookRef$cu3 === void 0 ? void 0 : (_disclosureHookRef$cu4 = _disclosureHookRef$cu3.onClose) === null || _disclosureHookRef$cu4 === void 0 ? void 0 : _disclosureHookRef$cu4.call(_disclosureHookRef$cu3);
|
|
151
|
+
}, [tag, onCloseAction]);
|
|
152
|
+
var onToggle = useCallback(function () {
|
|
153
|
+
var _disclosureHookRef$cu5, _disclosureHookRef$cu6;
|
|
154
|
+
onToggleAction(tag);
|
|
155
|
+
(_disclosureHookRef$cu5 = disclosureHookRef.current) === null || _disclosureHookRef$cu5 === void 0 ? void 0 : (_disclosureHookRef$cu6 = _disclosureHookRef$cu5.onToggle) === null || _disclosureHookRef$cu6 === void 0 ? void 0 : _disclosureHookRef$cu6.call(_disclosureHookRef$cu5);
|
|
156
|
+
}, [tag, onToggleAction]);
|
|
157
|
+
var onOk = useCallback(function (output) {
|
|
158
|
+
var _disclosureHookRef$cu7, _disclosureHookRef$cu8;
|
|
159
|
+
(_disclosureHookRef$cu7 = disclosureHookRef.current) === null || _disclosureHookRef$cu7 === void 0 ? void 0 : (_disclosureHookRef$cu8 = _disclosureHookRef$cu7.onOk) === null || _disclosureHookRef$cu8 === void 0 ? void 0 : _disclosureHookRef$cu8.call(_disclosureHookRef$cu7, output);
|
|
160
|
+
okAction(tag, output);
|
|
161
|
+
}, [tag, okAction]);
|
|
162
|
+
var onChange = useCallback(function (isOpen) {
|
|
163
|
+
var _disclosureHookRef$cu9, _disclosureHookRef$cu0;
|
|
164
|
+
if (isOpen) {
|
|
165
|
+
onOpen();
|
|
166
|
+
} else {
|
|
167
|
+
onClose();
|
|
168
|
+
}
|
|
169
|
+
(_disclosureHookRef$cu9 = disclosureHookRef.current) === null || _disclosureHookRef$cu9 === void 0 ? void 0 : (_disclosureHookRef$cu0 = _disclosureHookRef$cu9.onChange) === null || _disclosureHookRef$cu0 === void 0 ? void 0 : _disclosureHookRef$cu0.call(_disclosureHookRef$cu9, isOpen);
|
|
170
|
+
}, [onOpen, onClose]);
|
|
171
|
+
useEffect(function () {
|
|
172
|
+
return function () {
|
|
173
|
+
clearDisclosureTag(tag);
|
|
174
|
+
};
|
|
175
|
+
}, [tag, clearDisclosureTag]);
|
|
176
|
+
useEffect(function () {
|
|
177
|
+
if (outputState) {
|
|
178
|
+
onOk(outputState);
|
|
179
|
+
}
|
|
180
|
+
}, [outputState, onOk]);
|
|
181
|
+
return {
|
|
182
|
+
isOpen: !!inputState,
|
|
183
|
+
input: typeof inputState === 'boolean' ? undefined : inputState,
|
|
184
|
+
onOpen: onOpen,
|
|
185
|
+
onClose: onClose,
|
|
186
|
+
onToggle: onToggle,
|
|
187
|
+
onOk: onOk,
|
|
188
|
+
onChange: onChange,
|
|
189
|
+
updateInput: updateInput,
|
|
190
|
+
store: store
|
|
191
|
+
};
|
|
192
|
+
};
|
|
193
|
+
|
|
194
|
+
var ReactHookModalProvider = function ReactHookModalProvider(_ref) {
|
|
195
|
+
var children = _ref.children,
|
|
196
|
+
modals = _ref.modals;
|
|
197
|
+
return createElement(Fragment, null, createElement(ModalWrapper, {
|
|
198
|
+
modals: modals
|
|
199
|
+
}), children);
|
|
200
|
+
};
|
|
201
|
+
|
|
202
|
+
export { ModalWrapper, ReactHookModalProvider, useDisclosure };
|
|
203
|
+
//# sourceMappingURL=index.modern.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.modern.js","sources":["../src/store/index.ts","../src/provider/index.tsx","../src/hook/index.ts","../src/index.tsx"],"sourcesContent":["import { Store, useStore } from \"@tanstack/react-store\";\n\n// You can instantiate the store outside of React components too!\n\nimport { Any } from '../hook'\n\nexport type State = {\n modalTags: {\n [tag: string]: {\n input?: Any\n output?: Any\n }\n }\n}\n\nexport type Action = {\n openModal: (tag: string, input?: Any) => void\n okModal: (tag: string, output?: Any) => void\n closeModal: (tag: string) => void\n toggleModal: (tag: string) => void\n clearModalTag: (tag: string) => void\n clearAllModalTags: () => void\n}\nexport const store = new Store<State>({\n modalTags: {}\n});\n\n\nconst openModal = (tag: string, input?: Any) => {\n store.setState((state) => ({\n modalTags: {\n ...state.modalTags,\n [tag]: {\n ...state.modalTags[tag],\n input: input ?? true // Default to true if no input is provided\n }\n }\n }))\n}\nconst okModal = (tag: string, output?: Any) => {\n store.setState((state) => ({\n modalTags: {\n ...state.modalTags,\n [tag]: {\n ...state.modalTags[tag],\n output\n }\n }\n }))\n}\nconst closeModal = (tag: string) => {\n store.setState((state) => ({\n modalTags: {\n ...state.modalTags,\n [tag]: { input: false }\n }\n }))\n}\nconst toggleModal = (tag: string) => {\n store.setState((state) => ({\n modalTags: {\n ...state.modalTags,\n [tag]: {\n ...state.modalTags[tag],\n input: !state.modalTags[tag]?.input\n }\n }\n }))\n}\nconst clearModalTag = (tag: string) => {\n store.setState((state) => {\n const newModalTags = { ...state.modalTags };\n delete newModalTags[tag];\n return { modalTags: newModalTags };\n })\n}\nconst clearAllModalTags = () => {\n store.setState(() => ({ modalTags: {} }))\n}\n\nexport const useModalStore = <T>(\n stateCallback: (state: State) => T,\n): T => {\n return useStore(store, stateCallback)\n}\n\nexport const useModalActions = <T>(\n actionCallback: (action: Action) => T\n): T => {\n return actionCallback(\n {\n openModal,\n okModal,\n closeModal,\n toggleModal,\n clearModalTag,\n clearAllModalTags\n }\n )\n}","import React, { useMemo, memo } from 'react'\nimport { useModalStore, State } from '../store'\n\ntype ModalComponent = React.FunctionComponent<any> | React.ComponentType<any>\n\nexport interface ModalWrapperProps {\n modals: Record<string, ModalComponent>\n}\n\nexport const ModalWrapper = memo(function ModalWrapper({\n modals\n}: ModalWrapperProps) {\n const modalTags = useModalStore((state: State) => state.modalTags)\n \n const modalOpened = useMemo(() => {\n return Object.entries(modals)\n .filter(([tag]) => !!modalTags[tag]?.input)\n .map(([tag, Modal]) => <Modal key={tag} />)\n }, [modals, modalTags])\n \n return <React.Fragment>{modalOpened}</React.Fragment>\n})\n","import { useEffect, useCallback, useRef } from 'react'\nimport { TagType } from './tag'\nimport { useModalStore, useModalActions, store } from '../store'\n\nexport type Any = string | number | boolean | object | undefined | Record<string, any>\n\nexport interface DisclosureHookProps<O> {\n tag: TagType\n isOpen?: boolean\n onOpen?: () => void\n onClose?: () => void\n onToggle?: () => void\n onChange?: (isOpen: boolean) => void\n onOk?: (output?: O) => void\n onCancel?: () => void\n}\n\nexport const useDisclosure = <Input = Any, Output = Any>(\n disclosureHook: DisclosureHookProps<Output>\n) => {\n const tag = disclosureHook.tag\n \n // Use refs to store callbacks to avoid stale closures\n const disclosureHookRef = useRef(disclosureHook)\n disclosureHookRef.current = disclosureHook\n\n const inputState = useModalStore(\n (state) => state.modalTags[tag]?.input\n ) as Input\n const outputState = useModalStore(\n (state) => state.modalTags[tag]?.output\n ) as Output\n const clearDisclosureTag = useModalActions(\n (actions) => actions.clearModalTag\n )\n\n const onOpenAction = useModalActions((actions) => actions.openModal)\n const okAction = useModalActions((actions) => actions.okModal)\n const onCloseAction = useModalActions((actions) => actions.closeModal)\n const onToggleAction = useModalActions((actions) => actions.toggleModal)\n\n const updateInput = useCallback((input?: Input) => {\n // If input is a function, call it and set the result as input\n let processedInput = input\n if (processedInput && typeof processedInput == 'object' && 'preventDefault' in processedInput) {\n processedInput = undefined\n }\n onOpenAction(tag, processedInput as Any)\n }, [tag, onOpenAction])\n\n const onOpen = useCallback((input?: Input) => {\n updateInput(input)\n disclosureHookRef.current?.onOpen?.()\n }, [updateInput])\n\n const onClose = useCallback(() => {\n onCloseAction(tag)\n disclosureHookRef.current?.onClose?.()\n }, [tag, onCloseAction])\n\n const onToggle = useCallback(() => {\n onToggleAction(tag)\n disclosureHookRef.current?.onToggle?.()\n }, [tag, onToggleAction])\n\n const onOk = useCallback((output?: Output) => {\n disclosureHookRef.current?.onOk?.(output)\n okAction(tag, output as Any)\n }, [tag, okAction])\n\n const onChange = useCallback((isOpen: boolean) => {\n if (isOpen) {\n onOpen()\n } else {\n onClose()\n }\n disclosureHookRef.current?.onChange?.(isOpen)\n }, [onOpen, onClose])\n\n useEffect(() => {\n return () => {\n clearDisclosureTag(tag)\n }\n }, [tag, clearDisclosureTag])\n\n useEffect(() => {\n if (outputState) {\n onOk(outputState as Output)\n }\n }, [outputState, onOk])\n\n return {\n isOpen: !!inputState,\n input: typeof inputState === 'boolean' ? undefined : inputState,\n onOpen,\n onClose,\n onToggle,\n onOk,\n onChange,\n updateInput,\n store\n }\n}\n","import * as React from 'react'\nimport { ModalWrapper } from './provider'\n\ntype ModalComponent = React.FunctionComponent<any> | React.ComponentType<any>\n\nexport type ReactHookModalProviderProps = {\n children: React.ReactNode\n modals: Record<string, ModalComponent>\n}\n\nexport const ReactHookModalProvider = ({\n children,\n modals\n}: ReactHookModalProviderProps) => {\n return (\n <React.Fragment>\n <ModalWrapper modals={modals} />\n {children}\n </React.Fragment>\n )\n}\n\nexport * from './hook'\nexport * from './provider'\n"],"names":["store","Store","modalTags","openModal","tag","input","setState","state","_extends2","_extends","okModal","output","_extends3","closeModal","_extends4","toggleModal","_state$modalTags$tag","_extends5","clearModalTag","newModalTags","clearAllModalTags","useModalStore","stateCallback","useStore","useModalActions","actionCallback","ModalWrapper","memo","_ref","modals","modalOpened","useMemo","Object","entries","filter","_ref2","_modalTags$tag","map","_ref3","Modal","React","key","Fragment","useDisclosure","disclosureHook","disclosureHookRef","useRef","current","inputState","outputState","_state$modalTags$tag2","clearDisclosureTag","actions","onOpenAction","okAction","onCloseAction","onToggleAction","updateInput","useCallback","processedInput","undefined","onOpen","_disclosureHookRef$cu","_disclosureHookRef$cu2","call","onClose","_disclosureHookRef$cu3","_disclosureHookRef$cu4","onToggle","_disclosureHookRef$cu5","_disclosureHookRef$cu6","onOk","_disclosureHookRef$cu7","_disclosureHookRef$cu8","onChange","isOpen","_disclosureHookRef$cu9","_disclosureHookRef$cu0","useEffect","ReactHookModalProvider","children"],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
declare type ModalComponent = React.FunctionComponent<any> | React.ComponentType<any>;
|
|
3
|
+
export interface ModalWrapperProps {
|
|
4
|
+
modals: Record<string, ModalComponent>;
|
|
5
|
+
}
|
|
6
|
+
export declare const ModalWrapper: React.NamedExoticComponent<ModalWrapperProps>;
|
|
7
|
+
export {};
|
|
8
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/provider/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAwB,MAAM,OAAO,CAAA;AAG5C,aAAK,cAAc,GAAG,KAAK,CAAC,iBAAiB,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,aAAa,CAAC,GAAG,CAAC,CAAA;AAE7E,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAA;CACvC;AAED,eAAO,MAAM,YAAY,+CAYvB,CAAA"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { Store } from "@tanstack/react-store";
|
|
2
|
+
import { Any } from '../hook';
|
|
3
|
+
export declare type State = {
|
|
4
|
+
modalTags: {
|
|
5
|
+
[tag: string]: {
|
|
6
|
+
input?: Any;
|
|
7
|
+
output?: Any;
|
|
8
|
+
};
|
|
9
|
+
};
|
|
10
|
+
};
|
|
11
|
+
export declare type Action = {
|
|
12
|
+
openModal: (tag: string, input?: Any) => void;
|
|
13
|
+
okModal: (tag: string, output?: Any) => void;
|
|
14
|
+
closeModal: (tag: string) => void;
|
|
15
|
+
toggleModal: (tag: string) => void;
|
|
16
|
+
clearModalTag: (tag: string) => void;
|
|
17
|
+
clearAllModalTags: () => void;
|
|
18
|
+
};
|
|
19
|
+
export declare const store: Store<State, (cb: State) => State>;
|
|
20
|
+
export declare const useModalStore: <T>(stateCallback: (state: State) => T) => T;
|
|
21
|
+
export declare const useModalActions: <T>(actionCallback: (action: Action) => T) => T;
|
|
22
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/store/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAY,MAAM,uBAAuB,CAAC;AAIxD,OAAO,EAAE,GAAG,EAAE,MAAM,SAAS,CAAA;AAE7B,oBAAY,KAAK,GAAG;IAClB,SAAS,EAAE;QACT,CAAC,GAAG,EAAE,MAAM,GAAG;YACb,KAAK,CAAC,EAAE,GAAG,CAAA;YACX,MAAM,CAAC,EAAE,GAAG,CAAA;SACb,CAAA;KACF,CAAA;CACF,CAAA;AAED,oBAAY,MAAM,GAAG;IACnB,SAAS,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,GAAG,KAAK,IAAI,CAAA;IAC7C,OAAO,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,GAAG,KAAK,IAAI,CAAA;IAC5C,UAAU,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAA;IACjC,WAAW,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAA;IAClC,aAAa,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAA;IACpC,iBAAiB,EAAE,MAAM,IAAI,CAAA;CAC9B,CAAA;AACD,eAAO,MAAM,KAAK,oCAEhB,CAAC;AAuDH,eAAO,MAAM,aAAa,6BACD,KAAK,YAG7B,CAAA;AAED,eAAO,MAAM,eAAe,+BACD,MAAM,YAYhC,CAAA"}
|
package/package.json
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@helloworldqq/react-modal",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "React hook disclosure modal - A powerful and flexible React hook library for managing modals",
|
|
5
|
+
"author": "helloworldqq",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "git+https://github.com/vnquang24/react-modal.git"
|
|
10
|
+
},
|
|
11
|
+
"homepage": "https://github.com/vnquang24/react-modal#readme",
|
|
12
|
+
"bugs": {
|
|
13
|
+
"url": "https://github.com/vnquang24/react-modal/issues"
|
|
14
|
+
},
|
|
15
|
+
"publishConfig": {
|
|
16
|
+
"access": "public"
|
|
17
|
+
},
|
|
18
|
+
"keywords": [
|
|
19
|
+
"react",
|
|
20
|
+
"modal",
|
|
21
|
+
"hook",
|
|
22
|
+
"disclosure",
|
|
23
|
+
"dialog",
|
|
24
|
+
"react-modal",
|
|
25
|
+
"react-hook",
|
|
26
|
+
"antd",
|
|
27
|
+
"ant-design",
|
|
28
|
+
"react-19",
|
|
29
|
+
"typescript"
|
|
30
|
+
],
|
|
31
|
+
"main": "dist/index.js",
|
|
32
|
+
"module": "dist/index.modern.js",
|
|
33
|
+
"source": "src/index.tsx",
|
|
34
|
+
"types": "dist/index.d.ts",
|
|
35
|
+
"engines": {
|
|
36
|
+
"node": ">=18"
|
|
37
|
+
},
|
|
38
|
+
"scripts": {
|
|
39
|
+
"build": "microbundle-crl --no-compress --format modern,cjs",
|
|
40
|
+
"start": "microbundle-crl watch --no-compress --format modern,cjs",
|
|
41
|
+
"prepare": "run-s build",
|
|
42
|
+
"test": "run-s test:lint test:build",
|
|
43
|
+
"test:build": "run-s build",
|
|
44
|
+
"test:lint": "eslint .",
|
|
45
|
+
"format": "prettier --write ."
|
|
46
|
+
},
|
|
47
|
+
"peerDependencies": {
|
|
48
|
+
"react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
|
|
49
|
+
},
|
|
50
|
+
"devDependencies": {
|
|
51
|
+
"@testing-library/jest-dom": "^6.4.2",
|
|
52
|
+
"@testing-library/react": "^14.2.1",
|
|
53
|
+
"@testing-library/user-event": "^14.5.2",
|
|
54
|
+
"@types/jest": "^29.5.12",
|
|
55
|
+
"@types/node": "^20.11.24",
|
|
56
|
+
"@types/react": "^19.0.0",
|
|
57
|
+
"@types/react-dom": "^19.0.0",
|
|
58
|
+
"@typescript-eslint/eslint-plugin": "^7.1.0",
|
|
59
|
+
"@typescript-eslint/parser": "^7.1.0",
|
|
60
|
+
"cross-env": "^7.0.3",
|
|
61
|
+
"eslint": "^8.57.0",
|
|
62
|
+
"eslint-config-prettier": "^9.1.0",
|
|
63
|
+
"eslint-plugin-import": "^2.29.1",
|
|
64
|
+
"eslint-plugin-prettier": "^5.1.3",
|
|
65
|
+
"eslint-plugin-react": "^7.33.2",
|
|
66
|
+
"eslint-plugin-react-hooks": "^4.6.0",
|
|
67
|
+
"microbundle-crl": "^0.13.11",
|
|
68
|
+
"npm-run-all": "^4.1.5",
|
|
69
|
+
"prettier": "^3.2.5",
|
|
70
|
+
"react": "^19.0.0",
|
|
71
|
+
"react-dom": "^19.0.0",
|
|
72
|
+
"ts-morph": "^26.0.0",
|
|
73
|
+
"typescript": "^5.3.3"
|
|
74
|
+
},
|
|
75
|
+
"files": [
|
|
76
|
+
"dist"
|
|
77
|
+
],
|
|
78
|
+
"dependencies": {
|
|
79
|
+
"@tanstack/react-store": "^0.7.3"
|
|
80
|
+
},
|
|
81
|
+
"packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e"
|
|
82
|
+
}
|