react-confirm 0.4.0 → 0.5.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 +4 -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/createConfirmation.d.ts +4 -0
- package/dist/createConfirmation.js +48 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +52 -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/createConfirmation.ts +43 -0
- package/src/{index.js → index.ts} +9 -0
- package/src/mounter/domTree.tsx +36 -0
- package/src/mounter/reactTree.tsx +62 -0
- package/src/types.ts +59 -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/mounter/domTree.js +0 -35
- package/src/mounter/reactTree.js +0 -56
- package/typescript/index.d.ts +0 -86
package/README.md
CHANGED
|
@@ -123,11 +123,9 @@ const Confirmation2: ConfirmDialog<Props, Response> = (props) => (<Dialog />);
|
|
|
123
123
|
- **React ≤17**: Use `react-confirm` version 0.1.x
|
|
124
124
|
|
|
125
125
|
|
|
126
|
-
##
|
|
126
|
+
## Examples
|
|
127
127
|
|
|
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)
|
|
128
|
+
- [Simple Example](https://stackblitz.com/fork/github/haradakunihiko/react-confirm-sample/tree/main/1_typescript) - Complete TypeScript implementation.
|
|
129
|
+
- [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
130
|
|
|
133
|
-
|
|
131
|
+
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,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,48 @@
|
|
|
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 createConfirmationCreater = function (mounter) {
|
|
17
|
+
return function (Component, unmountDelay, mountingNode) {
|
|
18
|
+
if (unmountDelay === void 0) { unmountDelay = 1000; }
|
|
19
|
+
return function (props) {
|
|
20
|
+
var mountId;
|
|
21
|
+
var promise = new Promise(function (resolve, reject) {
|
|
22
|
+
try {
|
|
23
|
+
mountId = mounter.mount(Component, __assign({ reject: reject, resolve: resolve, dispose: dispose }, props), mountingNode);
|
|
24
|
+
}
|
|
25
|
+
catch (e) {
|
|
26
|
+
// keep behavior identical to JS version
|
|
27
|
+
console.error(e);
|
|
28
|
+
throw e;
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
function dispose() {
|
|
32
|
+
setTimeout(function () {
|
|
33
|
+
mounter.unmount(mountId);
|
|
34
|
+
}, unmountDelay);
|
|
35
|
+
}
|
|
36
|
+
return promise.then(function (result) {
|
|
37
|
+
dispose();
|
|
38
|
+
return result;
|
|
39
|
+
}, function (result) {
|
|
40
|
+
dispose();
|
|
41
|
+
return Promise.reject(result);
|
|
42
|
+
});
|
|
43
|
+
};
|
|
44
|
+
};
|
|
45
|
+
};
|
|
46
|
+
exports.createConfirmationCreater = createConfirmationCreater;
|
|
47
|
+
var defaultCreateConfirmation = (0, exports.createConfirmationCreater)((0, domTree_1.createDomTreeMounter)());
|
|
48
|
+
exports.default = defaultCreateConfirmation;
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
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
|
+
export type { ConfirmDialogProps, ConfirmDialog, ConfirmableDialog, Mounter, TreeMounter, ConfirmationContext, } from './types';
|
|
7
|
+
export { confirmable, createConfirmation, createConfirmationCreater, createDomTreeMounter, createReactTreeMounter, createMountPoint, createConfirmationContext, ContextAwareConfirmation };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
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.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; } });
|
|
@@ -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-1",
|
|
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;
|
package/src/context.ts
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { createReactTreeMounter, createMountPoint } from './mounter/reactTree';
|
|
2
|
+
import { createConfirmationCreater } from './createConfirmation';
|
|
3
|
+
import type { ConfirmableDialog, ConfirmationContext } from './types';
|
|
4
|
+
|
|
5
|
+
export function createConfirmationContext(mountNode?: Element | DocumentFragment | HTMLElement): ConfirmationContext {
|
|
6
|
+
const mounter = createReactTreeMounter(mountNode);
|
|
7
|
+
const createConfirmation = createConfirmationCreater(mounter);
|
|
8
|
+
const ConfirmationRoot = createMountPoint(mounter);
|
|
9
|
+
|
|
10
|
+
return {
|
|
11
|
+
createConfirmation: <P, R>(component: ConfirmableDialog<P, R>, unmountDelay?: number) =>
|
|
12
|
+
createConfirmation(component, unmountDelay),
|
|
13
|
+
ConfirmationRoot,
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export const ContextAwareConfirmation: ConfirmationContext = createConfirmationContext();
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type React from 'react';
|
|
2
|
+
import { createDomTreeMounter } from './mounter/domTree';
|
|
3
|
+
import type { ConfirmableDialog, Mounter } from './types';
|
|
4
|
+
|
|
5
|
+
export const createConfirmationCreater = (mounter: Mounter) =>
|
|
6
|
+
<P, R>(Component: ConfirmableDialog<P, R>, unmountDelay: number = 1000, mountingNode?: HTMLElement) => {
|
|
7
|
+
return (props: P): Promise<R> => {
|
|
8
|
+
let mountId: string;
|
|
9
|
+
const promise = new Promise<R>((resolve, reject) => {
|
|
10
|
+
try {
|
|
11
|
+
mountId = mounter.mount(Component as React.ComponentType<any>, { reject, resolve, dispose, ...props }, mountingNode);
|
|
12
|
+
} catch (e) {
|
|
13
|
+
// keep behavior identical to JS version
|
|
14
|
+
console.error(e);
|
|
15
|
+
throw e;
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
function dispose() {
|
|
20
|
+
setTimeout(() => {
|
|
21
|
+
mounter.unmount(mountId);
|
|
22
|
+
}, unmountDelay);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
return promise.then(
|
|
26
|
+
(result) => {
|
|
27
|
+
dispose();
|
|
28
|
+
return result;
|
|
29
|
+
},
|
|
30
|
+
(result) => {
|
|
31
|
+
dispose();
|
|
32
|
+
return Promise.reject(result);
|
|
33
|
+
}
|
|
34
|
+
);
|
|
35
|
+
};
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
const defaultCreateConfirmation = createConfirmationCreater(createDomTreeMounter());
|
|
39
|
+
export default defaultCreateConfirmation as <P, R>(
|
|
40
|
+
component: ConfirmableDialog<P, R>,
|
|
41
|
+
unmountDelay?: number,
|
|
42
|
+
mountingNode?: HTMLElement
|
|
43
|
+
) => (props: P) => Promise<R>;
|
|
@@ -7,6 +7,15 @@ import {
|
|
|
7
7
|
ContextAwareConfirmation
|
|
8
8
|
} from './context';
|
|
9
9
|
|
|
10
|
+
export type {
|
|
11
|
+
ConfirmDialogProps,
|
|
12
|
+
ConfirmDialog,
|
|
13
|
+
ConfirmableDialog,
|
|
14
|
+
Mounter,
|
|
15
|
+
TreeMounter,
|
|
16
|
+
ConfirmationContext,
|
|
17
|
+
} from './types';
|
|
18
|
+
|
|
10
19
|
export {
|
|
11
20
|
confirmable,
|
|
12
21
|
createConfirmation,
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { createRoot } from 'react-dom/client';
|
|
3
|
+
import type { Mounter } from '../types';
|
|
4
|
+
|
|
5
|
+
export function createDomTreeMounter(defaultMountNode?: Element | DocumentFragment | HTMLElement): Mounter {
|
|
6
|
+
const confirms: Record<string, HTMLElement> = {};
|
|
7
|
+
const callbacks: { mounted?: () => void } = {};
|
|
8
|
+
|
|
9
|
+
function mount(Component: React.ComponentType<any>, props: any, mountNode?: HTMLElement) {
|
|
10
|
+
const key = Math.floor(Math.random() * (1 << 30)).toString(16);
|
|
11
|
+
const parent = (mountNode || (defaultMountNode as Element | DocumentFragment) || document.body) as Element | DocumentFragment;
|
|
12
|
+
const wrapper = parent.appendChild(document.createElement('div'));
|
|
13
|
+
confirms[key] = wrapper;
|
|
14
|
+
|
|
15
|
+
const root = createRoot(wrapper);
|
|
16
|
+
root.render(<Component {...props} />);
|
|
17
|
+
callbacks.mounted && callbacks.mounted();
|
|
18
|
+
return key;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function unmount(key: string) {
|
|
22
|
+
const wrapper = confirms[key];
|
|
23
|
+
delete confirms[key];
|
|
24
|
+
|
|
25
|
+
if (wrapper && wrapper.parentNode) {
|
|
26
|
+
wrapper.parentNode.removeChild(wrapper);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
return ({
|
|
31
|
+
mount,
|
|
32
|
+
unmount,
|
|
33
|
+
// keep runtime `options` for backward-compat; not part of public type
|
|
34
|
+
options: {},
|
|
35
|
+
} as unknown) as Mounter;
|
|
36
|
+
}
|