@lcashe/react-modal-controller 1.0.0 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +93 -8
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
# react-modal-controller
|
|
2
2
|
|
|
3
|
-
Tiny and type-safe modal controller for React
|
|
3
|
+
Tiny and type-safe modal controller for React.
|
|
4
|
+
|
|
5
|
+
Works with React, Next.js and other React-based frameworks.
|
|
4
6
|
|
|
5
7
|
- No global modal registry
|
|
6
|
-
- No reducers
|
|
8
|
+
- No reducers or external state managers
|
|
7
9
|
- No boilerplate
|
|
8
|
-
-
|
|
10
|
+
- Automatic TypeScript prop inference
|
|
9
11
|
|
|
10
12
|
---
|
|
11
13
|
|
|
@@ -17,9 +19,11 @@ Tiny and type-safe modal controller for React and Next.js.
|
|
|
17
19
|
- [Important](#important)
|
|
18
20
|
- [Simple Example](#simple-example)
|
|
19
21
|
- [Modal With Props](#modal-with-props)
|
|
22
|
+
- [TypeScript Inference](#typescript-inference)
|
|
20
23
|
- [Dynamic Initial Props](#dynamic-initial-props)
|
|
21
24
|
- [Auto Close Example](#auto-close-example)
|
|
22
25
|
- [Multiple Modals](#multiple-modals)
|
|
26
|
+
- [Multiple Same Modals](#multiple-same-modals)
|
|
23
27
|
- [API](#api)
|
|
24
28
|
|
|
25
29
|
---
|
|
@@ -50,17 +54,66 @@ ReactDOM.createRoot(document.getElementById('root')!).render(
|
|
|
50
54
|
);
|
|
51
55
|
```
|
|
52
56
|
|
|
57
|
+
`ModalScope` stores and renders all active modals internally.
|
|
58
|
+
|
|
59
|
+
Every modal opened through `useModalController`
|
|
60
|
+
will automatically appear inside the nearest `ModalScope`.
|
|
61
|
+
|
|
53
62
|
---
|
|
54
63
|
|
|
55
64
|
# Next.js Setup
|
|
56
65
|
|
|
66
|
+
## App Router
|
|
67
|
+
|
|
68
|
+
`app/providers.tsx`
|
|
69
|
+
|
|
70
|
+
```tsx
|
|
71
|
+
'use client';
|
|
72
|
+
|
|
73
|
+
import { PropsWithChildren } from 'react';
|
|
74
|
+
|
|
75
|
+
import { ModalScope } from '@lcashe/react-modal-controller';
|
|
76
|
+
|
|
77
|
+
export const Providers = ({ children }: PropsWithChildren) => {
|
|
78
|
+
return <ModalScope>{children}</ModalScope>;
|
|
79
|
+
};
|
|
80
|
+
```
|
|
81
|
+
|
|
57
82
|
`app/layout.tsx`
|
|
58
83
|
|
|
59
84
|
```tsx
|
|
85
|
+
import { Providers } from './providers';
|
|
86
|
+
|
|
87
|
+
export default function RootLayout({
|
|
88
|
+
children,
|
|
89
|
+
}: {
|
|
90
|
+
children: React.ReactNode;
|
|
91
|
+
}) {
|
|
92
|
+
return (
|
|
93
|
+
<html lang="en">
|
|
94
|
+
<body>
|
|
95
|
+
<Providers>{children}</Providers>
|
|
96
|
+
</body>
|
|
97
|
+
</html>
|
|
98
|
+
);
|
|
99
|
+
}
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
## Pages Router
|
|
103
|
+
|
|
104
|
+
`pages/_app.tsx`
|
|
105
|
+
|
|
106
|
+
```tsx
|
|
107
|
+
import type { AppProps } from 'next/app';
|
|
108
|
+
|
|
60
109
|
import { ModalScope } from '@lcashe/react-modal-controller';
|
|
61
110
|
|
|
62
|
-
export default function
|
|
63
|
-
return
|
|
111
|
+
export default function App({ Component, pageProps }: AppProps) {
|
|
112
|
+
return (
|
|
113
|
+
<ModalScope>
|
|
114
|
+
<Component {...pageProps} />
|
|
115
|
+
</ModalScope>
|
|
116
|
+
);
|
|
64
117
|
}
|
|
65
118
|
```
|
|
66
119
|
|
|
@@ -91,6 +144,8 @@ type ModalProps = {
|
|
|
91
144
|
};
|
|
92
145
|
```
|
|
93
146
|
|
|
147
|
+
These props are injected automatically by the controller.
|
|
148
|
+
|
|
94
149
|
---
|
|
95
150
|
|
|
96
151
|
# Simple Example
|
|
@@ -100,7 +155,6 @@ type ModalProps = {
|
|
|
100
155
|
```tsx
|
|
101
156
|
'use client';
|
|
102
157
|
|
|
103
|
-
|
|
104
158
|
type ModalProps = {
|
|
105
159
|
opened: boolean;
|
|
106
160
|
onClose: VoidFunction;
|
|
@@ -185,7 +239,7 @@ export const Component = () => {
|
|
|
185
239
|
<button
|
|
186
240
|
onClick={() =>
|
|
187
241
|
modal.open({
|
|
188
|
-
title: 'Another title',
|
|
242
|
+
title: 'Another title',
|
|
189
243
|
})
|
|
190
244
|
}
|
|
191
245
|
>
|
|
@@ -195,6 +249,20 @@ export const Component = () => {
|
|
|
195
249
|
};
|
|
196
250
|
```
|
|
197
251
|
|
|
252
|
+
`initialProps` are merged with props passed into `open()`.
|
|
253
|
+
|
|
254
|
+
```tsx
|
|
255
|
+
const modal = useModalController(Modal, {
|
|
256
|
+
title: 'Default title',
|
|
257
|
+
});
|
|
258
|
+
|
|
259
|
+
modal.open({
|
|
260
|
+
title: 'Another title',
|
|
261
|
+
});
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
The second object overrides the first one.
|
|
265
|
+
|
|
198
266
|
---
|
|
199
267
|
|
|
200
268
|
# TypeScript Inference
|
|
@@ -223,6 +291,16 @@ const modal = useModalController(Modal, {
|
|
|
223
291
|
|
|
224
292
|
When `title` changes, the next `open()` call will use the latest value.
|
|
225
293
|
|
|
294
|
+
This makes it safe to use reactive values:
|
|
295
|
+
|
|
296
|
+
```tsx
|
|
297
|
+
const modal = useModalController(Modal, {
|
|
298
|
+
title: currentTitle,
|
|
299
|
+
});
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
The controller always keeps the latest values internally.
|
|
303
|
+
|
|
226
304
|
---
|
|
227
305
|
|
|
228
306
|
# Auto Close Example
|
|
@@ -282,9 +360,12 @@ const secondModal = useModalController(Modal);
|
|
|
282
360
|
|
|
283
361
|
...
|
|
284
362
|
|
|
285
|
-
secondModal.open() //
|
|
363
|
+
secondModal.open(); // opens only the second modal
|
|
286
364
|
```
|
|
287
365
|
|
|
366
|
+
Modals are mounted globally inside `ModalScope`,
|
|
367
|
+
but every controller manages its own isolated modal state.
|
|
368
|
+
|
|
288
369
|
---
|
|
289
370
|
|
|
290
371
|
# API
|
|
@@ -301,6 +382,8 @@ Returns:
|
|
|
301
382
|
}
|
|
302
383
|
```
|
|
303
384
|
|
|
385
|
+
---
|
|
386
|
+
|
|
304
387
|
## `open(props?)`
|
|
305
388
|
|
|
306
389
|
Open modal with optional props.
|
|
@@ -333,6 +416,8 @@ Remove modal from the store completely.
|
|
|
333
416
|
modal.remove();
|
|
334
417
|
```
|
|
335
418
|
|
|
419
|
+
Usually useful when you want to completely destroy modal state manually.
|
|
420
|
+
|
|
336
421
|
---
|
|
337
422
|
|
|
338
423
|
# License
|