react-confirm 0.4.0 → 0.5.0-4
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 +21 -6
- package/dist/confirmable.d.ts +3 -0
- package/dist/confirmable.js +46 -0
- package/dist/context.d.ts +3 -0
- package/dist/context.js +18 -0
- package/dist/controls.d.ts +34 -0
- package/dist/controls.js +93 -0
- package/dist/createConfirmation.d.ts +4 -0
- package/dist/createConfirmation.js +56 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.js +56 -0
- package/dist/mounter/domTree.d.ts +2 -0
- package/dist/mounter/domTree.js +43 -0
- package/dist/mounter/reactTree.d.ts +3 -0
- package/dist/mounter/reactTree.js +62 -0
- package/dist/types.d.ts +43 -0
- package/dist/types.js +6 -0
- package/package.json +34 -18
- package/src/confirmable.tsx +35 -0
- package/src/context.ts +17 -0
- package/src/controls.ts +103 -0
- package/src/createConfirmation.ts +55 -0
- package/src/index.ts +32 -0
- package/src/mounter/domTree.tsx +36 -0
- package/src/mounter/reactTree.tsx +62 -0
- package/src/types.ts +60 -0
- package/lib/confirmable.js +0 -50
- package/lib/context.js +0 -26
- package/lib/createConfirmation.js +0 -47
- package/lib/index.js +0 -61
- package/lib/mounter/domTree.js +0 -34
- package/lib/mounter/reactTree.js +0 -77
- package/src/confirmable.js +0 -31
- package/src/context.js +0 -20
- package/src/createConfirmation.js +0 -31
- package/src/index.js +0 -19
- package/src/mounter/domTree.js +0 -35
- package/src/mounter/reactTree.js +0 -56
- package/typescript/index.d.ts +0 -86
package/README.md
CHANGED
|
@@ -70,6 +70,23 @@ const handleDelete = async (): Promise<void> => {
|
|
|
70
70
|
<button onClick={handleDelete}>Delete Item</button>
|
|
71
71
|
```
|
|
72
72
|
|
|
73
|
+
## External Control
|
|
74
|
+
|
|
75
|
+
You can close pending confirmation dialogs from outside using the `proceed` function. This is useful when you need to close a dialog from a different part of your application.
|
|
76
|
+
|
|
77
|
+
```typescript
|
|
78
|
+
import { proceed } from 'react-confirm';
|
|
79
|
+
|
|
80
|
+
const p = confirm({ message: 'Continue?' });
|
|
81
|
+
|
|
82
|
+
// Auto-close after 10 seconds
|
|
83
|
+
setTimeout(() => {
|
|
84
|
+
proceed(p, false);
|
|
85
|
+
}, 10000);
|
|
86
|
+
|
|
87
|
+
const result = await p;
|
|
88
|
+
```
|
|
89
|
+
|
|
73
90
|
## Using with React Context
|
|
74
91
|
|
|
75
92
|
If your dialog needs to access React Context (themes, authentication, etc.), use the context-aware approach:
|
|
@@ -123,11 +140,9 @@ const Confirmation2: ConfirmDialog<Props, Response> = (props) => (<Dialog />);
|
|
|
123
140
|
- **React ≤17**: Use `react-confirm` version 0.1.x
|
|
124
141
|
|
|
125
142
|
|
|
126
|
-
##
|
|
143
|
+
## Examples
|
|
127
144
|
|
|
128
|
-
- [
|
|
129
|
-
- [Context Example](https://stackblitz.com/fork/github/haradakunihiko/react-confirm-sample/tree/main/2_typescript_using_context)
|
|
130
|
-
- [Bootstrap Example](https://codesandbox.io/s/react-confirm-with-react-bootstrap-kjju1)
|
|
131
|
-
- [Chakra UI Example](https://codesandbox.io/s/react-confirm-with-chakra-ui-oidpf1)
|
|
145
|
+
- [Simple Example](https://stackblitz.com/fork/github/haradakunihiko/react-confirm-sample/tree/main/1_typescript) - Complete TypeScript implementation.
|
|
146
|
+
- [Context Example](https://stackblitz.com/fork/github/haradakunihiko/react-confirm-sample/tree/main/2_typescript_using_context) - Using React Context with themes and providers
|
|
132
147
|
|
|
133
|
-
|
|
148
|
+
Source code for these examples can be found in the [react-confirm-sample](https://github.com/haradakunihiko/react-confirm-sample/) repository, which also contains some archived older implementations.
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __assign = (this && this.__assign) || function () {
|
|
3
|
+
__assign = Object.assign || function(t) {
|
|
4
|
+
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
5
|
+
s = arguments[i];
|
|
6
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
7
|
+
t[p] = s[p];
|
|
8
|
+
}
|
|
9
|
+
return t;
|
|
10
|
+
};
|
|
11
|
+
return __assign.apply(this, arguments);
|
|
12
|
+
};
|
|
13
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
14
|
+
var t = {};
|
|
15
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
16
|
+
t[p] = s[p];
|
|
17
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
18
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
19
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
20
|
+
t[p[i]] = s[p[i]];
|
|
21
|
+
}
|
|
22
|
+
return t;
|
|
23
|
+
};
|
|
24
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
25
|
+
var jsx_runtime_1 = require("react/jsx-runtime");
|
|
26
|
+
var react_1 = require("react");
|
|
27
|
+
var confirmable = function (Component) {
|
|
28
|
+
return function (_a) {
|
|
29
|
+
var dispose = _a.dispose, reject = _a.reject, resolve = _a.resolve, other = __rest(_a, ["dispose", "reject", "resolve"]);
|
|
30
|
+
var _b = (0, react_1.useState)(true), show = _b[0], setShow = _b[1];
|
|
31
|
+
var dismiss = function () {
|
|
32
|
+
setShow(false);
|
|
33
|
+
dispose();
|
|
34
|
+
};
|
|
35
|
+
var cancel = function (value) {
|
|
36
|
+
setShow(false);
|
|
37
|
+
reject(value);
|
|
38
|
+
};
|
|
39
|
+
var proceed = function (value) {
|
|
40
|
+
setShow(false);
|
|
41
|
+
resolve(value);
|
|
42
|
+
};
|
|
43
|
+
return ((0, jsx_runtime_1.jsx)(Component, __assign({ cancel: cancel, dismiss: dismiss, proceed: proceed, show: show }, other)));
|
|
44
|
+
};
|
|
45
|
+
};
|
|
46
|
+
exports.default = confirmable;
|
package/dist/context.js
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ContextAwareConfirmation = void 0;
|
|
4
|
+
exports.createConfirmationContext = createConfirmationContext;
|
|
5
|
+
var reactTree_1 = require("./mounter/reactTree");
|
|
6
|
+
var createConfirmation_1 = require("./createConfirmation");
|
|
7
|
+
function createConfirmationContext(mountNode) {
|
|
8
|
+
var mounter = (0, reactTree_1.createReactTreeMounter)(mountNode);
|
|
9
|
+
var createConfirmation = (0, createConfirmation_1.createConfirmationCreater)(mounter);
|
|
10
|
+
var ConfirmationRoot = (0, reactTree_1.createMountPoint)(mounter);
|
|
11
|
+
return {
|
|
12
|
+
createConfirmation: function (component, unmountDelay) {
|
|
13
|
+
return createConfirmation(component, unmountDelay);
|
|
14
|
+
},
|
|
15
|
+
ConfirmationRoot: ConfirmationRoot,
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
exports.ContextAwareConfirmation = createConfirmationContext();
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Control handle for a confirmation dialog
|
|
3
|
+
*/
|
|
4
|
+
export type ConfirmationHandle<R> = {
|
|
5
|
+
resolve: (value: R) => void;
|
|
6
|
+
reject: (reason?: any) => void;
|
|
7
|
+
dispose: () => void;
|
|
8
|
+
settled?: boolean;
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* Register a Promise and its handle to the registry
|
|
12
|
+
*/
|
|
13
|
+
export declare function register<R>(promise: Promise<R>, handle: ConfirmationHandle<R>): void;
|
|
14
|
+
/**
|
|
15
|
+
* Resolve a confirmation dialog and close it
|
|
16
|
+
* @param promise The Promise to resolve
|
|
17
|
+
* @param response The response value to resolve with
|
|
18
|
+
* @returns true if successful
|
|
19
|
+
*/
|
|
20
|
+
export declare function proceed<R>(promise: Promise<R>, response: R): boolean;
|
|
21
|
+
/**
|
|
22
|
+
* Close a confirmation dialog without resolving or rejecting the Promise
|
|
23
|
+
* The Promise remains pending
|
|
24
|
+
* @param promise The Promise to dismiss
|
|
25
|
+
* @returns true if successful
|
|
26
|
+
*/
|
|
27
|
+
export declare function dismiss<R>(promise: Promise<R>): boolean;
|
|
28
|
+
/**
|
|
29
|
+
* Reject a confirmation dialog and close it
|
|
30
|
+
* @param promise The Promise to reject
|
|
31
|
+
* @param reason The rejection reason
|
|
32
|
+
* @returns true if successful
|
|
33
|
+
*/
|
|
34
|
+
export declare function cancel<R>(promise: Promise<R>, reason?: unknown): boolean;
|
package/dist/controls.js
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Lightweight registry to control pending confirmations from outside
|
|
3
|
+
// Stores only control handles (resolve/reject/dispose), not UI state
|
|
4
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
5
|
+
exports.register = register;
|
|
6
|
+
exports.proceed = proceed;
|
|
7
|
+
exports.dismiss = dismiss;
|
|
8
|
+
exports.cancel = cancel;
|
|
9
|
+
var active = new Map();
|
|
10
|
+
/**
|
|
11
|
+
* Register a Promise and its handle to the registry
|
|
12
|
+
*/
|
|
13
|
+
function register(promise, handle) {
|
|
14
|
+
active.set(promise, handle);
|
|
15
|
+
// Auto cleanup after settlement
|
|
16
|
+
promise
|
|
17
|
+
.finally(function () {
|
|
18
|
+
var h = active.get(promise);
|
|
19
|
+
if (h)
|
|
20
|
+
h.settled = true;
|
|
21
|
+
active.delete(promise);
|
|
22
|
+
})
|
|
23
|
+
.catch(function () {
|
|
24
|
+
// Already handled by finally
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Resolve a confirmation dialog and close it
|
|
29
|
+
* @param promise The Promise to resolve
|
|
30
|
+
* @param response The response value to resolve with
|
|
31
|
+
* @returns true if successful
|
|
32
|
+
*/
|
|
33
|
+
function proceed(promise, response) {
|
|
34
|
+
var handle = active.get(promise);
|
|
35
|
+
if (!handle || handle.settled)
|
|
36
|
+
return false;
|
|
37
|
+
try {
|
|
38
|
+
handle.resolve(response);
|
|
39
|
+
}
|
|
40
|
+
finally {
|
|
41
|
+
try {
|
|
42
|
+
handle.dispose();
|
|
43
|
+
}
|
|
44
|
+
catch (_a) {
|
|
45
|
+
// Ignore
|
|
46
|
+
}
|
|
47
|
+
active.delete(promise);
|
|
48
|
+
}
|
|
49
|
+
return true;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Close a confirmation dialog without resolving or rejecting the Promise
|
|
53
|
+
* The Promise remains pending
|
|
54
|
+
* @param promise The Promise to dismiss
|
|
55
|
+
* @returns true if successful
|
|
56
|
+
*/
|
|
57
|
+
function dismiss(promise) {
|
|
58
|
+
var handle = active.get(promise);
|
|
59
|
+
if (!handle || handle.settled)
|
|
60
|
+
return false;
|
|
61
|
+
try {
|
|
62
|
+
handle.dispose();
|
|
63
|
+
}
|
|
64
|
+
catch (_a) {
|
|
65
|
+
// Ignore
|
|
66
|
+
}
|
|
67
|
+
active.delete(promise);
|
|
68
|
+
return true;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Reject a confirmation dialog and close it
|
|
72
|
+
* @param promise The Promise to reject
|
|
73
|
+
* @param reason The rejection reason
|
|
74
|
+
* @returns true if successful
|
|
75
|
+
*/
|
|
76
|
+
function cancel(promise, reason) {
|
|
77
|
+
var handle = active.get(promise);
|
|
78
|
+
if (!handle || handle.settled)
|
|
79
|
+
return false;
|
|
80
|
+
try {
|
|
81
|
+
handle.reject(reason);
|
|
82
|
+
}
|
|
83
|
+
finally {
|
|
84
|
+
try {
|
|
85
|
+
handle.dispose();
|
|
86
|
+
}
|
|
87
|
+
catch (_a) {
|
|
88
|
+
// Ignore
|
|
89
|
+
}
|
|
90
|
+
active.delete(promise);
|
|
91
|
+
}
|
|
92
|
+
return true;
|
|
93
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { ConfirmableDialog, Mounter } from './types';
|
|
2
|
+
export declare const createConfirmationCreater: (mounter: Mounter) => <P, R>(Component: ConfirmableDialog<P, R>, unmountDelay?: number, mountingNode?: HTMLElement) => (props: P) => Promise<R>;
|
|
3
|
+
declare const _default: <P, R>(component: ConfirmableDialog<P, R>, unmountDelay?: number, mountingNode?: HTMLElement) => (props: P) => Promise<R>;
|
|
4
|
+
export default _default;
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __assign = (this && this.__assign) || function () {
|
|
3
|
+
__assign = Object.assign || function(t) {
|
|
4
|
+
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
5
|
+
s = arguments[i];
|
|
6
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
7
|
+
t[p] = s[p];
|
|
8
|
+
}
|
|
9
|
+
return t;
|
|
10
|
+
};
|
|
11
|
+
return __assign.apply(this, arguments);
|
|
12
|
+
};
|
|
13
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
+
exports.createConfirmationCreater = void 0;
|
|
15
|
+
var domTree_1 = require("./mounter/domTree");
|
|
16
|
+
var controls_1 = require("./controls");
|
|
17
|
+
var createConfirmationCreater = function (mounter) {
|
|
18
|
+
return function (Component, unmountDelay, mountingNode) {
|
|
19
|
+
if (unmountDelay === void 0) { unmountDelay = 1000; }
|
|
20
|
+
return function (props) {
|
|
21
|
+
var mountId;
|
|
22
|
+
var resolveRef = function () { };
|
|
23
|
+
function dispose() {
|
|
24
|
+
setTimeout(function () {
|
|
25
|
+
mounter.unmount(mountId);
|
|
26
|
+
}, unmountDelay);
|
|
27
|
+
}
|
|
28
|
+
var rejectRef = function () { };
|
|
29
|
+
var inner = new Promise(function (resolve, reject) {
|
|
30
|
+
resolveRef = resolve;
|
|
31
|
+
rejectRef = reject;
|
|
32
|
+
try {
|
|
33
|
+
mountId = mounter.mount(Component, __assign({ reject: reject, resolve: resolve, dispose: dispose }, props), mountingNode);
|
|
34
|
+
}
|
|
35
|
+
catch (e) {
|
|
36
|
+
// keep behavior identical to JS version
|
|
37
|
+
console.error(e);
|
|
38
|
+
throw e;
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
var wrapped = inner.then(function (result) {
|
|
42
|
+
dispose();
|
|
43
|
+
return result;
|
|
44
|
+
}, function (err) {
|
|
45
|
+
dispose();
|
|
46
|
+
return Promise.reject(err);
|
|
47
|
+
});
|
|
48
|
+
// Register to controls layer for external control
|
|
49
|
+
(0, controls_1.register)(wrapped, { resolve: resolveRef, reject: rejectRef, dispose: dispose });
|
|
50
|
+
return wrapped;
|
|
51
|
+
};
|
|
52
|
+
};
|
|
53
|
+
};
|
|
54
|
+
exports.createConfirmationCreater = createConfirmationCreater;
|
|
55
|
+
var defaultCreateConfirmation = (0, exports.createConfirmationCreater)((0, domTree_1.createDomTreeMounter)());
|
|
56
|
+
exports.default = defaultCreateConfirmation;
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import confirmable from './confirmable';
|
|
2
|
+
import createConfirmation, { createConfirmationCreater } from './createConfirmation';
|
|
3
|
+
import { createDomTreeMounter } from './mounter/domTree';
|
|
4
|
+
import { createReactTreeMounter, createMountPoint } from './mounter/reactTree';
|
|
5
|
+
import { createConfirmationContext, ContextAwareConfirmation } from './context';
|
|
6
|
+
import { proceed, dismiss, cancel } from './controls';
|
|
7
|
+
export type { ConfirmDialogProps, ConfirmDialog, ConfirmableDialog, Mounter, TreeMounter, ConfirmationContext, } from './types';
|
|
8
|
+
export { confirmable, createConfirmation, createConfirmationCreater, createDomTreeMounter, createReactTreeMounter, createMountPoint, createConfirmationContext, ContextAwareConfirmation, proceed, dismiss, cancel, };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.cancel = exports.dismiss = exports.proceed = exports.ContextAwareConfirmation = exports.createConfirmationContext = exports.createMountPoint = exports.createReactTreeMounter = exports.createDomTreeMounter = exports.createConfirmationCreater = exports.createConfirmation = exports.confirmable = void 0;
|
|
40
|
+
var confirmable_1 = __importDefault(require("./confirmable"));
|
|
41
|
+
exports.confirmable = confirmable_1.default;
|
|
42
|
+
var createConfirmation_1 = __importStar(require("./createConfirmation"));
|
|
43
|
+
exports.createConfirmation = createConfirmation_1.default;
|
|
44
|
+
Object.defineProperty(exports, "createConfirmationCreater", { enumerable: true, get: function () { return createConfirmation_1.createConfirmationCreater; } });
|
|
45
|
+
var domTree_1 = require("./mounter/domTree");
|
|
46
|
+
Object.defineProperty(exports, "createDomTreeMounter", { enumerable: true, get: function () { return domTree_1.createDomTreeMounter; } });
|
|
47
|
+
var reactTree_1 = require("./mounter/reactTree");
|
|
48
|
+
Object.defineProperty(exports, "createReactTreeMounter", { enumerable: true, get: function () { return reactTree_1.createReactTreeMounter; } });
|
|
49
|
+
Object.defineProperty(exports, "createMountPoint", { enumerable: true, get: function () { return reactTree_1.createMountPoint; } });
|
|
50
|
+
var context_1 = require("./context");
|
|
51
|
+
Object.defineProperty(exports, "createConfirmationContext", { enumerable: true, get: function () { return context_1.createConfirmationContext; } });
|
|
52
|
+
Object.defineProperty(exports, "ContextAwareConfirmation", { enumerable: true, get: function () { return context_1.ContextAwareConfirmation; } });
|
|
53
|
+
var controls_1 = require("./controls");
|
|
54
|
+
Object.defineProperty(exports, "proceed", { enumerable: true, get: function () { return controls_1.proceed; } });
|
|
55
|
+
Object.defineProperty(exports, "dismiss", { enumerable: true, get: function () { return controls_1.dismiss; } });
|
|
56
|
+
Object.defineProperty(exports, "cancel", { enumerable: true, get: function () { return controls_1.cancel; } });
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __assign = (this && this.__assign) || function () {
|
|
3
|
+
__assign = Object.assign || function(t) {
|
|
4
|
+
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
5
|
+
s = arguments[i];
|
|
6
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
7
|
+
t[p] = s[p];
|
|
8
|
+
}
|
|
9
|
+
return t;
|
|
10
|
+
};
|
|
11
|
+
return __assign.apply(this, arguments);
|
|
12
|
+
};
|
|
13
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
+
exports.createDomTreeMounter = createDomTreeMounter;
|
|
15
|
+
var jsx_runtime_1 = require("react/jsx-runtime");
|
|
16
|
+
var client_1 = require("react-dom/client");
|
|
17
|
+
function createDomTreeMounter(defaultMountNode) {
|
|
18
|
+
var confirms = {};
|
|
19
|
+
var callbacks = {};
|
|
20
|
+
function mount(Component, props, mountNode) {
|
|
21
|
+
var key = Math.floor(Math.random() * (1 << 30)).toString(16);
|
|
22
|
+
var parent = (mountNode || defaultMountNode || document.body);
|
|
23
|
+
var wrapper = parent.appendChild(document.createElement('div'));
|
|
24
|
+
confirms[key] = wrapper;
|
|
25
|
+
var root = (0, client_1.createRoot)(wrapper);
|
|
26
|
+
root.render((0, jsx_runtime_1.jsx)(Component, __assign({}, props)));
|
|
27
|
+
callbacks.mounted && callbacks.mounted();
|
|
28
|
+
return key;
|
|
29
|
+
}
|
|
30
|
+
function unmount(key) {
|
|
31
|
+
var wrapper = confirms[key];
|
|
32
|
+
delete confirms[key];
|
|
33
|
+
if (wrapper && wrapper.parentNode) {
|
|
34
|
+
wrapper.parentNode.removeChild(wrapper);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return {
|
|
38
|
+
mount: mount,
|
|
39
|
+
unmount: unmount,
|
|
40
|
+
// keep runtime `options` for backward-compat; not part of public type
|
|
41
|
+
options: {},
|
|
42
|
+
};
|
|
43
|
+
}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { TreeMounter } from '../types';
|
|
2
|
+
export declare function createReactTreeMounter(mountNode?: Element | DocumentFragment | HTMLElement): TreeMounter;
|
|
3
|
+
export declare function createMountPoint(reactTreeMounter: TreeMounter): () => import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __assign = (this && this.__assign) || function () {
|
|
3
|
+
__assign = Object.assign || function(t) {
|
|
4
|
+
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
5
|
+
s = arguments[i];
|
|
6
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
7
|
+
t[p] = s[p];
|
|
8
|
+
}
|
|
9
|
+
return t;
|
|
10
|
+
};
|
|
11
|
+
return __assign.apply(this, arguments);
|
|
12
|
+
};
|
|
13
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
+
exports.createReactTreeMounter = createReactTreeMounter;
|
|
15
|
+
exports.createMountPoint = createMountPoint;
|
|
16
|
+
var jsx_runtime_1 = require("react/jsx-runtime");
|
|
17
|
+
var react_1 = require("react");
|
|
18
|
+
var react_dom_1 = require("react-dom");
|
|
19
|
+
function createReactTreeMounter(mountNode) {
|
|
20
|
+
var confirms = {};
|
|
21
|
+
var callbacks = {};
|
|
22
|
+
function mount(Component, props, _mountNode) {
|
|
23
|
+
var key = Math.floor(Math.random() * (1 << 30)).toString(16);
|
|
24
|
+
confirms[key] = { Component: Component, props: props };
|
|
25
|
+
callbacks.mounted && callbacks.mounted(confirms);
|
|
26
|
+
return key;
|
|
27
|
+
// _mountNode is ignored - ReactTreeMounter uses options.mountNode instead
|
|
28
|
+
}
|
|
29
|
+
function unmount(key) {
|
|
30
|
+
delete confirms[key];
|
|
31
|
+
callbacks.mounted && callbacks.mounted(confirms);
|
|
32
|
+
}
|
|
33
|
+
function setMountedCallback(func) {
|
|
34
|
+
callbacks.mounted = func;
|
|
35
|
+
}
|
|
36
|
+
return {
|
|
37
|
+
mount: mount,
|
|
38
|
+
unmount: unmount,
|
|
39
|
+
options: {
|
|
40
|
+
setMountedCallback: setMountedCallback,
|
|
41
|
+
mountNode: mountNode,
|
|
42
|
+
},
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
function createMountPoint(reactTreeMounter) {
|
|
46
|
+
return function () {
|
|
47
|
+
var _a = (0, react_1.useState)({}), confirmComponents = _a[0], setConfirmComponents = _a[1];
|
|
48
|
+
(0, react_1.useEffect)(function () {
|
|
49
|
+
return reactTreeMounter.options.setMountedCallback(function (components) {
|
|
50
|
+
setConfirmComponents(__assign({}, components));
|
|
51
|
+
});
|
|
52
|
+
}, []);
|
|
53
|
+
var element = ((0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: Object.keys(confirmComponents).map(function (key) {
|
|
54
|
+
var _a = confirmComponents[key], Component = _a.Component, props = _a.props;
|
|
55
|
+
return (0, jsx_runtime_1.jsx)(Component, __assign({}, props), key);
|
|
56
|
+
}) }));
|
|
57
|
+
if (reactTreeMounter.options.mountNode) {
|
|
58
|
+
element = (0, react_dom_1.createPortal)(element, reactTreeMounter.options.mountNode);
|
|
59
|
+
}
|
|
60
|
+
return element;
|
|
61
|
+
};
|
|
62
|
+
}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
export type ConfirmableProps<P, R> = {
|
|
3
|
+
dispose: () => void;
|
|
4
|
+
resolve: (value: R | PromiseLike<R>) => void;
|
|
5
|
+
reject: (reason?: any) => void;
|
|
6
|
+
} & P;
|
|
7
|
+
export type ConfirmDialogProps<P, R> = {
|
|
8
|
+
/** Dismiss dialog without resolving the promise. */
|
|
9
|
+
dismiss: () => void;
|
|
10
|
+
/** Resolve the promise with the given value. */
|
|
11
|
+
proceed: (value: R) => void;
|
|
12
|
+
/** Reject the promise with the given value. */
|
|
13
|
+
cancel: (value?: any) => void;
|
|
14
|
+
/** Indicates if the dialog should be shown aka. someone is waiting for a promise. */
|
|
15
|
+
show: boolean;
|
|
16
|
+
} & P;
|
|
17
|
+
export type ConfirmDialog<P, R> = React.ComponentType<ConfirmDialogProps<P, R>>;
|
|
18
|
+
export type ConfirmableDialog<P, R> = React.ComponentType<ConfirmableProps<P, R>>;
|
|
19
|
+
export type Mounter = {
|
|
20
|
+
mount: (component: React.ComponentType, props: any, mountNode?: HTMLElement) => string;
|
|
21
|
+
unmount: (key: string) => void;
|
|
22
|
+
};
|
|
23
|
+
export type TreeMounter = {
|
|
24
|
+
options: {
|
|
25
|
+
setMountedCallback: (callback: (components: any) => void) => void;
|
|
26
|
+
mountNode?: Element | DocumentFragment | HTMLElement;
|
|
27
|
+
};
|
|
28
|
+
} & Mounter;
|
|
29
|
+
export interface ConfirmationContext {
|
|
30
|
+
/**
|
|
31
|
+
* Creates a confirmation function for a given component
|
|
32
|
+
* @param component - The confirmable component
|
|
33
|
+
* @param unmountDelay - Delay before unmounting the component (default: 1000ms)
|
|
34
|
+
* @returns Confirmation function that returns a Promise
|
|
35
|
+
*/
|
|
36
|
+
createConfirmation: <P, R>(component: ConfirmableDialog<P, R>, unmountDelay?: number) => (props: P) => Promise<R>;
|
|
37
|
+
/**
|
|
38
|
+
* React component that must be rendered in your app to display confirmations
|
|
39
|
+
* Place this component at the root level of your app or where you want confirmations to appear
|
|
40
|
+
*/
|
|
41
|
+
ConfirmationRoot: React.ComponentType;
|
|
42
|
+
}
|
|
43
|
+
export declare const __types_marker: 0;
|
package/dist/types.js
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.__types_marker = void 0;
|
|
4
|
+
// Force declaration file emission for this module
|
|
5
|
+
// This value is never imported by runtime code; it only ensures dist/types.d.ts exists.
|
|
6
|
+
exports.__types_marker = 0;
|
package/package.json
CHANGED
|
@@ -1,8 +1,18 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-confirm",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "
|
|
5
|
-
"main": "
|
|
3
|
+
"version": "0.5.0-4",
|
|
4
|
+
"description": "A lightweight React library that simplifies confirmation dialogs with a Promise-based API — like window.confirm(), but fully customizable.",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": {
|
|
9
|
+
"types": "./dist/index.d.ts",
|
|
10
|
+
"import": "./dist/index.js",
|
|
11
|
+
"require": "./dist/index.js",
|
|
12
|
+
"default": "./dist/index.js"
|
|
13
|
+
},
|
|
14
|
+
"./package.json": "./package.json"
|
|
15
|
+
},
|
|
6
16
|
"repository": {
|
|
7
17
|
"type": "git",
|
|
8
18
|
"url": "https://github.com/haradakunihiko/react-confirm.git"
|
|
@@ -13,39 +23,46 @@
|
|
|
13
23
|
"keywords": [
|
|
14
24
|
"react",
|
|
15
25
|
"reactjs",
|
|
16
|
-
"confirm"
|
|
26
|
+
"confirm",
|
|
27
|
+
"confirmation",
|
|
28
|
+
"dialog",
|
|
29
|
+
"modal",
|
|
30
|
+
"promise",
|
|
31
|
+
"async",
|
|
32
|
+
"typescript",
|
|
33
|
+
"ui",
|
|
34
|
+
"component"
|
|
17
35
|
],
|
|
18
36
|
"homepage": "https://github.com/haradakunihiko/react-confirm",
|
|
37
|
+
"sideEffects": false,
|
|
19
38
|
"files": [
|
|
20
|
-
"
|
|
39
|
+
"dist",
|
|
21
40
|
"src",
|
|
22
|
-
"
|
|
41
|
+
"README.md",
|
|
42
|
+
"LICENSE"
|
|
23
43
|
],
|
|
24
44
|
"scripts": {
|
|
25
|
-
"
|
|
26
|
-
"
|
|
27
|
-
"
|
|
45
|
+
"pretest": "npm run build",
|
|
46
|
+
"clean": "rimraf dist lib",
|
|
47
|
+
"build": "tsc -p tsconfig.build.json",
|
|
48
|
+
"prepublishOnly": "npm run clean && npm run build && npm test",
|
|
28
49
|
"test": "jest",
|
|
29
50
|
"test:types": "jest __tests__/typescript/",
|
|
30
|
-
"typecheck": "tsc --noEmit"
|
|
51
|
+
"typecheck": "npm run build && tsc --noEmit",
|
|
52
|
+
"typecheck:tests": "npm run build && tsc -p tsconfig.tests.json"
|
|
31
53
|
},
|
|
32
|
-
"author": "",
|
|
54
|
+
"author": "haradakunihiko",
|
|
33
55
|
"license": "MIT",
|
|
34
56
|
"peerDependencies": {
|
|
35
57
|
"react": ">=18.x",
|
|
36
58
|
"react-dom": ">=18.x"
|
|
37
59
|
},
|
|
38
60
|
"devDependencies": {
|
|
39
|
-
"@babel/cli": "^7.17.6",
|
|
40
|
-
"@babel/core": "^7.27.4",
|
|
41
|
-
"@babel/preset-env": "^7.16.11",
|
|
42
|
-
"@babel/preset-react": "^7.16.7",
|
|
43
61
|
"@testing-library/jest-dom": "^5.16.5",
|
|
44
62
|
"@testing-library/react": "^14.0.0",
|
|
45
63
|
"@types/jest": "^29.5.0",
|
|
46
64
|
"@types/react": "^18.2.0",
|
|
47
65
|
"@types/react-dom": "^18.2.0",
|
|
48
|
-
"babel-jest": "^29.5.0",
|
|
49
66
|
"jest": "^29.5.0",
|
|
50
67
|
"jest-environment-jsdom": "^29.5.0",
|
|
51
68
|
"react": ">=18.2.0",
|
|
@@ -55,6 +72,5 @@
|
|
|
55
72
|
"ts-jest": "^29.1.0",
|
|
56
73
|
"typescript": "^5.0.0"
|
|
57
74
|
},
|
|
58
|
-
"dependencies": {}
|
|
59
|
-
"typings": "typescript/index.d.ts"
|
|
75
|
+
"dependencies": {}
|
|
60
76
|
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import React, { useState } from 'react';
|
|
2
|
+
import type { ConfirmableProps, ConfirmDialog, ConfirmableDialog } from './types';
|
|
3
|
+
|
|
4
|
+
const confirmable: <P, R>(Component: ConfirmDialog<P, R>) => ConfirmableDialog<P, R> =
|
|
5
|
+
<P, R>(Component: ConfirmDialog<P, R>) =>
|
|
6
|
+
({ dispose, reject, resolve, ...other }: ConfirmableProps<P, R>) => {
|
|
7
|
+
const [show, setShow] = useState(true);
|
|
8
|
+
|
|
9
|
+
const dismiss = () => {
|
|
10
|
+
setShow(false);
|
|
11
|
+
dispose();
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
const cancel = (value?: any) => {
|
|
15
|
+
setShow(false);
|
|
16
|
+
reject(value);
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
const proceed = (value: R) => {
|
|
20
|
+
setShow(false);
|
|
21
|
+
resolve(value);
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
return (
|
|
25
|
+
<Component
|
|
26
|
+
cancel={cancel}
|
|
27
|
+
dismiss={dismiss}
|
|
28
|
+
proceed={proceed}
|
|
29
|
+
show={show}
|
|
30
|
+
{...(other as P)}
|
|
31
|
+
/>
|
|
32
|
+
);
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
export default confirmable;
|