react-flow-modal 0.4.0 → 0.5.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 +36 -47
- package/dist/index.cjs +9 -11
- package/dist/index.d.cts +6 -8
- package/dist/index.d.ts +6 -8
- package/dist/index.js +9 -10
- package/package.json +1 -1
- package/src/ModalHost.tsx +4 -8
- package/src/index.ts +1 -2
- package/src/useModal.tsx +1 -1
- package/src/useModalContext.ts +0 -6
package/README.md
CHANGED
|
@@ -22,7 +22,9 @@ yarn add react-flow-modal
|
|
|
22
22
|
## Basic Usage
|
|
23
23
|
|
|
24
24
|
```tsx
|
|
25
|
-
import {
|
|
25
|
+
import { StrictMode } from 'react';
|
|
26
|
+
import { createRoot } from 'react-dom/client';
|
|
27
|
+
import { ModalProvider, useModal, ModalHost } from "react-flow-modal";
|
|
26
28
|
|
|
27
29
|
function ConfirmModal({
|
|
28
30
|
onConfirm,
|
|
@@ -66,6 +68,7 @@ function App() {
|
|
|
66
68
|
const modal = useModal();
|
|
67
69
|
|
|
68
70
|
const onClick = async () => {
|
|
71
|
+
// render modal and await resolve
|
|
69
72
|
const result = await modal.open("confirm", (resolve) => (
|
|
70
73
|
<ConfirmModal
|
|
71
74
|
onConfirm={() => resolve(true)}
|
|
@@ -73,24 +76,22 @@ function App() {
|
|
|
73
76
|
/>
|
|
74
77
|
));
|
|
75
78
|
|
|
79
|
+
// flow resumed
|
|
76
80
|
console.log("Result:", result);
|
|
77
81
|
};
|
|
78
82
|
|
|
79
83
|
return <button onClick={onClick}>Open Confirm Modal</button>;
|
|
80
84
|
}
|
|
81
85
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
export default function Root() {
|
|
87
|
-
return (
|
|
86
|
+
createRoot(document.getElementById('root')!).render(
|
|
87
|
+
<StrictMode>
|
|
88
88
|
<ModalProvider>
|
|
89
89
|
<App />
|
|
90
|
-
<
|
|
90
|
+
<ModalHost />
|
|
91
91
|
</ModalProvider>
|
|
92
|
-
|
|
93
|
-
|
|
92
|
+
</StrictMode>,
|
|
93
|
+
)
|
|
94
|
+
|
|
94
95
|
```
|
|
95
96
|
|
|
96
97
|
---
|
|
@@ -101,8 +102,10 @@ To support exit animations, modals must be rendered inside the same
|
|
|
101
102
|
React tree as `AnimatePresence`.
|
|
102
103
|
|
|
103
104
|
```tsx
|
|
104
|
-
import {
|
|
105
|
-
import {
|
|
105
|
+
import { StrictMode } from 'react';
|
|
106
|
+
import { createRoot } from 'react-dom/client';
|
|
107
|
+
import { ModalHost, ModalProvider } from 'react-flow-modal';
|
|
108
|
+
import { AnimatePresence, motion } from 'motion/react';
|
|
106
109
|
|
|
107
110
|
function ConfirmModal({
|
|
108
111
|
onConfirm,
|
|
@@ -113,6 +116,7 @@ function ConfirmModal({
|
|
|
113
116
|
}) {
|
|
114
117
|
return (
|
|
115
118
|
<motion.div
|
|
119
|
+
key="confirm-modal-container"
|
|
116
120
|
initial={{ opacity: 0 }}
|
|
117
121
|
animate={{ opacity: 1 }}
|
|
118
122
|
exit={{ opacity: 0 }}
|
|
@@ -135,6 +139,7 @@ function ConfirmModal({
|
|
|
135
139
|
padding: 24,
|
|
136
140
|
borderRadius: 8,
|
|
137
141
|
minWidth: 300,
|
|
142
|
+
color: "black",
|
|
138
143
|
}}
|
|
139
144
|
>
|
|
140
145
|
<h3>Are you sure?</h3>
|
|
@@ -149,39 +154,24 @@ function ConfirmModal({
|
|
|
149
154
|
);
|
|
150
155
|
}
|
|
151
156
|
|
|
152
|
-
|
|
153
|
-
const modal = useModal();
|
|
154
|
-
|
|
155
|
-
const onClick = async () => {
|
|
156
|
-
const result = await modal.open("confirm", (resolve) => (
|
|
157
|
-
<ConfirmModal
|
|
158
|
-
onConfirm={() => resolve(true)}
|
|
159
|
-
onCancel={() => resolve(false)}
|
|
160
|
-
/>
|
|
161
|
-
));
|
|
162
|
-
|
|
163
|
-
console.log("Result:", result);
|
|
164
|
-
};
|
|
165
|
-
|
|
166
|
-
return <button onClick={onClick}>Open Confirm Modal</button>;
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
function ModalRenderer() {
|
|
170
|
-
return (
|
|
171
|
-
<AnimatePresence>
|
|
172
|
-
{renderModals()}
|
|
173
|
-
</AnimatePresence>
|
|
174
|
-
);
|
|
175
|
-
}
|
|
157
|
+
...
|
|
176
158
|
|
|
177
|
-
|
|
178
|
-
|
|
159
|
+
createRoot(document.getElementById('root')!).render(
|
|
160
|
+
<StrictMode>
|
|
179
161
|
<ModalProvider>
|
|
180
162
|
<App />
|
|
181
|
-
<
|
|
163
|
+
<ModalHost>
|
|
164
|
+
{(modals) => (
|
|
165
|
+
<AnimatePresence>
|
|
166
|
+
{modals}
|
|
167
|
+
</AnimatePresence>
|
|
168
|
+
)}
|
|
169
|
+
</ModalHost>
|
|
182
170
|
</ModalProvider>
|
|
183
|
-
|
|
184
|
-
|
|
171
|
+
</StrictMode>,
|
|
172
|
+
)
|
|
173
|
+
|
|
174
|
+
|
|
185
175
|
```
|
|
186
176
|
|
|
187
177
|
---
|
|
@@ -208,11 +198,13 @@ Returns an object that controls the modal flow.
|
|
|
208
198
|
}
|
|
209
199
|
```
|
|
210
200
|
|
|
211
|
-
###
|
|
201
|
+
### ModalHost
|
|
212
202
|
```ts
|
|
213
|
-
|
|
203
|
+
const ModalHost: FC<{
|
|
204
|
+
children?: (modals: ReactElement[]) => React.ReactNode;
|
|
205
|
+
}>;
|
|
214
206
|
```
|
|
215
|
-
Renders the entire modal stack. This
|
|
207
|
+
Renders the entire modal stack. This component should be rendered **once** in your React tree.
|
|
216
208
|
|
|
217
209
|
---
|
|
218
210
|
|
|
@@ -221,9 +213,6 @@ Renders the entire modal stack. This function should be rendered **once** in you
|
|
|
221
213
|
> ⚠️ Always resolve or reject the promise.
|
|
222
214
|
> Leaving it pending will block the async flow.
|
|
223
215
|
|
|
224
|
-
> ⚠️ `renderModals()` should be rendered once.
|
|
225
|
-
> Rendering it multiple times may result in duplicated modals.
|
|
226
|
-
|
|
227
216
|
---
|
|
228
217
|
|
|
229
218
|
## Why react-flow-modal?
|
package/dist/index.cjs
CHANGED
|
@@ -22,7 +22,6 @@ var index_exports = {};
|
|
|
22
22
|
__export(index_exports, {
|
|
23
23
|
ModalHost: () => ModalHost,
|
|
24
24
|
ModalProvider: () => ModalProvider,
|
|
25
|
-
renderModals: () => renderModals,
|
|
26
25
|
useModal: () => useModal
|
|
27
26
|
});
|
|
28
27
|
module.exports = __toCommonJS(index_exports);
|
|
@@ -44,6 +43,9 @@ var ModalProvider = ({ children }) => {
|
|
|
44
43
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ModalContext.Provider, { value: { stack, setStack }, children });
|
|
45
44
|
};
|
|
46
45
|
|
|
46
|
+
// src/useModal.tsx
|
|
47
|
+
var import_react4 = require("react");
|
|
48
|
+
|
|
47
49
|
// src/useModalContext.ts
|
|
48
50
|
var import_react3 = require("react");
|
|
49
51
|
var useModalContext = () => {
|
|
@@ -53,12 +55,9 @@ var useModalContext = () => {
|
|
|
53
55
|
}
|
|
54
56
|
return context;
|
|
55
57
|
};
|
|
56
|
-
var renderModals = () => {
|
|
57
|
-
const { stack } = useModalContext();
|
|
58
|
-
return stack.map((item) => item);
|
|
59
|
-
};
|
|
60
58
|
|
|
61
59
|
// src/useModal.tsx
|
|
60
|
+
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
62
61
|
var useModal = () => {
|
|
63
62
|
const { setStack } = useModalContext();
|
|
64
63
|
const pop = () => {
|
|
@@ -76,23 +75,22 @@ var useModal = () => {
|
|
|
76
75
|
reject(reason);
|
|
77
76
|
pop();
|
|
78
77
|
});
|
|
79
|
-
push(element);
|
|
78
|
+
push(/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react4.Fragment, { children: element }, `modal-${key}`));
|
|
80
79
|
});
|
|
81
80
|
};
|
|
82
81
|
return { open };
|
|
83
82
|
};
|
|
84
83
|
|
|
85
84
|
// src/ModalHost.tsx
|
|
86
|
-
var
|
|
87
|
-
var
|
|
88
|
-
var ModalHost = () => {
|
|
85
|
+
var import_react5 = require("react");
|
|
86
|
+
var ModalHost = ({ children }) => {
|
|
89
87
|
const { stack } = useModalContext();
|
|
90
|
-
|
|
88
|
+
if (!children) return stack.filter(import_react5.isValidElement);
|
|
89
|
+
return children(stack.filter(import_react5.isValidElement));
|
|
91
90
|
};
|
|
92
91
|
// Annotate the CommonJS export names for ESM import in node:
|
|
93
92
|
0 && (module.exports = {
|
|
94
93
|
ModalHost,
|
|
95
94
|
ModalProvider,
|
|
96
|
-
renderModals,
|
|
97
95
|
useModal
|
|
98
96
|
});
|
package/dist/index.d.cts
CHANGED
|
@@ -1,15 +1,13 @@
|
|
|
1
|
-
import
|
|
2
|
-
import react__default, { FC, PropsWithChildren } from 'react';
|
|
1
|
+
import React$1, { FC, PropsWithChildren, ReactElement } from 'react';
|
|
3
2
|
|
|
4
3
|
declare const ModalProvider: FC<PropsWithChildren>;
|
|
5
4
|
|
|
6
5
|
declare const useModal: () => {
|
|
7
|
-
open: <T>(key: string, render: (resolve: (value: T) => void, reject: (reason?: unknown) => void) =>
|
|
6
|
+
open: <T>(key: string, render: (resolve: (value: T) => void, reject: (reason?: unknown) => void) => React$1.ReactNode) => Promise<T>;
|
|
8
7
|
};
|
|
9
8
|
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
declare const ModalHost: FC<{
|
|
10
|
+
children?: (modals: ReactElement[]) => React.ReactNode;
|
|
11
|
+
}>;
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
export { ModalHost, ModalProvider, renderModals, useModal };
|
|
13
|
+
export { ModalHost, ModalProvider, useModal };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,15 +1,13 @@
|
|
|
1
|
-
import
|
|
2
|
-
import react__default, { FC, PropsWithChildren } from 'react';
|
|
1
|
+
import React$1, { FC, PropsWithChildren, ReactElement } from 'react';
|
|
3
2
|
|
|
4
3
|
declare const ModalProvider: FC<PropsWithChildren>;
|
|
5
4
|
|
|
6
5
|
declare const useModal: () => {
|
|
7
|
-
open: <T>(key: string, render: (resolve: (value: T) => void, reject: (reason?: unknown) => void) =>
|
|
6
|
+
open: <T>(key: string, render: (resolve: (value: T) => void, reject: (reason?: unknown) => void) => React$1.ReactNode) => Promise<T>;
|
|
8
7
|
};
|
|
9
8
|
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
declare const ModalHost: FC<{
|
|
10
|
+
children?: (modals: ReactElement[]) => React.ReactNode;
|
|
11
|
+
}>;
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
export { ModalHost, ModalProvider, renderModals, useModal };
|
|
13
|
+
export { ModalHost, ModalProvider, useModal };
|
package/dist/index.js
CHANGED
|
@@ -15,6 +15,9 @@ var ModalProvider = ({ children }) => {
|
|
|
15
15
|
return /* @__PURE__ */ jsx(ModalContext.Provider, { value: { stack, setStack }, children });
|
|
16
16
|
};
|
|
17
17
|
|
|
18
|
+
// src/useModal.tsx
|
|
19
|
+
import { Fragment } from "react";
|
|
20
|
+
|
|
18
21
|
// src/useModalContext.ts
|
|
19
22
|
import { useContext } from "react";
|
|
20
23
|
var useModalContext = () => {
|
|
@@ -24,12 +27,9 @@ var useModalContext = () => {
|
|
|
24
27
|
}
|
|
25
28
|
return context;
|
|
26
29
|
};
|
|
27
|
-
var renderModals = () => {
|
|
28
|
-
const { stack } = useModalContext();
|
|
29
|
-
return stack.map((item) => item);
|
|
30
|
-
};
|
|
31
30
|
|
|
32
31
|
// src/useModal.tsx
|
|
32
|
+
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
33
33
|
var useModal = () => {
|
|
34
34
|
const { setStack } = useModalContext();
|
|
35
35
|
const pop = () => {
|
|
@@ -47,22 +47,21 @@ var useModal = () => {
|
|
|
47
47
|
reject(reason);
|
|
48
48
|
pop();
|
|
49
49
|
});
|
|
50
|
-
push(element);
|
|
50
|
+
push(/* @__PURE__ */ jsx2(Fragment, { children: element }, `modal-${key}`));
|
|
51
51
|
});
|
|
52
52
|
};
|
|
53
53
|
return { open };
|
|
54
54
|
};
|
|
55
55
|
|
|
56
56
|
// src/ModalHost.tsx
|
|
57
|
-
import {
|
|
58
|
-
|
|
59
|
-
var ModalHost = () => {
|
|
57
|
+
import { isValidElement } from "react";
|
|
58
|
+
var ModalHost = ({ children }) => {
|
|
60
59
|
const { stack } = useModalContext();
|
|
61
|
-
|
|
60
|
+
if (!children) return stack.filter(isValidElement);
|
|
61
|
+
return children(stack.filter(isValidElement));
|
|
62
62
|
};
|
|
63
63
|
export {
|
|
64
64
|
ModalHost,
|
|
65
65
|
ModalProvider,
|
|
66
|
-
renderModals,
|
|
67
66
|
useModal
|
|
68
67
|
};
|
package/package.json
CHANGED
package/src/ModalHost.tsx
CHANGED
|
@@ -1,13 +1,9 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { FC, isValidElement, ReactElement } from 'react';
|
|
2
2
|
import { useModalContext } from './useModalContext';
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
export const ModalHost: FC = () => {
|
|
4
|
+
export const ModalHost: FC<{ children?: (modals: ReactElement[]) => React.ReactNode }> = ({ children }) => {
|
|
6
5
|
const { stack } = useModalContext();
|
|
7
6
|
|
|
8
|
-
return (
|
|
9
|
-
|
|
10
|
-
{stack.map((item) => (item))}
|
|
11
|
-
</Fragment>
|
|
12
|
-
);
|
|
7
|
+
if (!children) return stack.filter(isValidElement);
|
|
8
|
+
return children(stack.filter(isValidElement));
|
|
13
9
|
};
|
package/src/index.ts
CHANGED
package/src/useModal.tsx
CHANGED