react-confirm 0.3.0 → 0.4.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 +92 -101
- package/lib/confirmable.js +17 -40
- package/lib/context.js +43 -0
- package/lib/createConfirmation.js +8 -17
- package/lib/index.js +16 -12
- package/lib/mounter/domTree.js +2 -10
- package/lib/mounter/reactTree.js +20 -43
- package/package.json +11 -5
- package/src/context.js +37 -0
- package/src/index.js +14 -1
- package/src/mounter/reactTree.js +2 -1
- package/typescript/context.d.ts +38 -0
- package/typescript/index.d.ts +15 -8
package/README.md
CHANGED
|
@@ -1,142 +1,133 @@
|
|
|
1
1
|
# react-confirm
|
|
2
|
-
react-confirm is a lightweight library that simplifies the implementation of confirmation dialogs in React applications by offering a Promise-based API that works seamlessly with async/await syntax, similar to `window.confirm`.
|
|
3
2
|
|
|
4
|
-
|
|
3
|
+
Create confirmation dialogs as simple as `window.confirm()`, but with full customization and Promise-based API.
|
|
5
4
|
|
|
6
5
|
[](https://badge.fury.io/js/react-confirm)
|
|
7
6
|
|
|
8
|
-
## Demo
|
|
9
|
-
[](https://stackblitz.com/fork/github/haradakunihiko/react-confirm-sample/tree/main/1_typescript)
|
|
10
|
-
|
|
11
|
-
## Motivation
|
|
12
|
-
React is a powerful library that allows for reactive rendering based on component state. However, managing temporary states like confirmation dialogs can quickly become complex. The question is: is it worth implementing these states within your app? The answer is not always a clear yes.
|
|
13
|
-
|
|
14
7
|
## What you can do
|
|
15
|
-
react-confirm library offers several benefits:
|
|
16
|
-
|
|
17
|
-
- You can open a dialog component by calling a function without appending it into your React tree. The function returns a promise, allowing you to handle confirmation results with callbacks.
|
|
18
|
-
- You can pass arguments to the function and use them inside the dialog component.
|
|
19
|
-
- You can retrieve values from the component in the promise.
|
|
20
|
-
- The library provides flexibility in designing the dialog. There is no limitation in the type of components you can use, whether it be input forms or multiple buttons. You can even check out the demo site to see examples of how to customize the dialog.
|
|
21
|
-
|
|
22
|
-
## Versions
|
|
23
|
-
|
|
24
|
-
- React 18+ users should use `react-confirm` version 0.2.x or 0.3.x
|
|
25
|
-
- React <=17 users should stick to `react-confirm` version 0.1.x
|
|
26
8
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
9
|
+
**🎯 Simple confirmation dialogs**
|
|
10
|
+
```typescript
|
|
11
|
+
const result = await confirm({ message: 'Delete this item?' });
|
|
12
|
+
if (result) {
|
|
13
|
+
// User confirmed
|
|
14
|
+
}
|
|
15
|
+
```
|
|
32
16
|
|
|
33
|
-
|
|
17
|
+
**🎨 Fully customizable UI** - No built-in styling. Use your own components, UI libraries, or design system.
|
|
34
18
|
|
|
35
|
-
|
|
36
|
-
import * as React from 'react';
|
|
19
|
+
**⚡ Promise-based API** - Works seamlessly with async/await, no complex state management needed.
|
|
37
20
|
|
|
38
|
-
|
|
39
|
-
import Button from 'react-bootstrap/Button'
|
|
21
|
+
**🔄 React Context support** - Access your app's context, themes, and providers from within dialogs.
|
|
40
22
|
|
|
41
|
-
|
|
23
|
+
**📦 Lightweight** - No dependencies, small bundle size.
|
|
42
24
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
};
|
|
25
|
+
## Demo
|
|
26
|
+
[](https://stackblitz.com/fork/github/haradakunihiko/react-confirm-sample/tree/main/1_typescript)
|
|
46
27
|
|
|
47
|
-
|
|
48
|
-
<Dialog onHide={() => proceed(false)} show={show}>
|
|
49
|
-
{confirmation}
|
|
50
|
-
<button onClick={() => proceed(false)}>CANCEL</button>
|
|
51
|
-
<button onClick={() => proceed(true)}>OK</button>
|
|
52
|
-
</Dialog>
|
|
53
|
-
);
|
|
28
|
+
## Quick Start
|
|
54
29
|
|
|
55
|
-
|
|
30
|
+
### 1. Install
|
|
31
|
+
```bash
|
|
32
|
+
npm install react-confirm
|
|
56
33
|
```
|
|
57
34
|
|
|
58
|
-
### Create
|
|
59
|
-
```
|
|
60
|
-
import
|
|
61
|
-
import
|
|
35
|
+
### 2. Create your dialog and confirmation function
|
|
36
|
+
```typescript
|
|
37
|
+
import React from 'react';
|
|
38
|
+
import { confirmable, createConfirmation, type ConfirmDialogProps } from 'react-confirm';
|
|
39
|
+
|
|
40
|
+
const MyDialog = ({ show, proceed, message }: ConfirmDialogProps<{ message: string }, boolean>) => (
|
|
41
|
+
<div className={`dialog-overlay ${show ? 'show' : 'hide'}`}>
|
|
42
|
+
<div className="dialog">
|
|
43
|
+
<p>{message}</p>
|
|
44
|
+
<button onClick={() => proceed(true)}>Yes</button>
|
|
45
|
+
<button onClick={() => proceed(false)}>No</button>
|
|
46
|
+
</div>
|
|
47
|
+
</div>
|
|
48
|
+
);
|
|
62
49
|
|
|
63
|
-
|
|
64
|
-
export const confirm = createConfirmation(YourDialog);
|
|
50
|
+
export const confirm = createConfirmation(confirmable(MyDialog));
|
|
65
51
|
```
|
|
66
52
|
|
|
67
|
-
###
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
const
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
53
|
+
### 3. Use it!
|
|
54
|
+
```typescript
|
|
55
|
+
import { confirm } from './confirm';
|
|
56
|
+
|
|
57
|
+
const handleDelete = async (): Promise<void> => {
|
|
58
|
+
// Fully type-safe: message is required, result is boolean
|
|
59
|
+
const result = await confirm({
|
|
60
|
+
message: 'Are you sure you want to delete this item?'
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
if (result) {
|
|
64
|
+
// User confirmed - proceed with deletion
|
|
65
|
+
deleteItem();
|
|
80
66
|
}
|
|
81
|
-
}
|
|
67
|
+
};
|
|
82
68
|
|
|
69
|
+
// In your component
|
|
70
|
+
<button onClick={handleDelete}>Delete Item</button>
|
|
83
71
|
```
|
|
84
72
|
|
|
85
|
-
|
|
73
|
+
## Using with React Context
|
|
86
74
|
|
|
87
|
-
|
|
88
|
-
[](https://stackblitz.com/fork/github/haradakunihiko/react-confirm-sample/tree/main/2_typescript_using_context)
|
|
75
|
+
If your dialog needs to access React Context (themes, authentication, etc.), use the context-aware approach:
|
|
89
76
|
|
|
90
|
-
|
|
77
|
+
### Simple Context Usage
|
|
91
78
|
|
|
92
|
-
|
|
79
|
+
Key differences from Quick Start:
|
|
93
80
|
|
|
94
|
-
```
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
const mounter = createReactTreeMounter();
|
|
98
|
-
|
|
99
|
-
export const createConfirmation = createConfirmationCreater(mounter);
|
|
100
|
-
export const MountPoint = createMountPoint(mounter);
|
|
101
|
-
```
|
|
81
|
+
```typescript
|
|
82
|
+
// 1. Import ContextAwareConfirmation instead of createConfirmation
|
|
83
|
+
import { confirmable, ContextAwareConfirmation, type ConfirmDialogProps } from 'react-confirm';
|
|
102
84
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
const YourRootComponent = () => {
|
|
85
|
+
// 2. Add ConfirmationRoot to your app
|
|
86
|
+
function App(): JSX.Element {
|
|
106
87
|
return (
|
|
107
|
-
<
|
|
108
|
-
<
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
88
|
+
<ThemeProvider>
|
|
89
|
+
<div>
|
|
90
|
+
<ContextAwareConfirmation.ConfirmationRoot />
|
|
91
|
+
<YourAppContent />
|
|
92
|
+
</div>
|
|
93
|
+
</ThemeProvider>
|
|
94
|
+
);
|
|
112
95
|
}
|
|
113
|
-
```
|
|
114
96
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
97
|
+
// 3. Your dialog can now use context
|
|
98
|
+
const ThemedDialog = ({ show, proceed, message }: ConfirmDialogProps<Props, boolean>) => {
|
|
99
|
+
const theme = useContext(ThemeContext); // ✅ Context works!
|
|
100
|
+
// ... rest of dialog implementation
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
// 4. Use ContextAwareConfirmation.createConfirmation
|
|
104
|
+
const confirm = ContextAwareConfirmation.createConfirmation(confirmable(ThemedDialog));
|
|
118
105
|
```
|
|
119
106
|
|
|
120
|
-
|
|
107
|
+
## TypeScript Support
|
|
108
|
+
|
|
109
|
+
TypeScript automatically infers types from your dialog's Props definition, making the confirmation function fully type-safe.
|
|
121
110
|
|
|
122
|
-
```
|
|
123
|
-
|
|
111
|
+
```typescript
|
|
112
|
+
// Option 1: Using React.FC with ConfirmDialogProps
|
|
113
|
+
const Confirmation1: React.FC<ConfirmDialogProps<Props, Response>> = (props) => (<Dialog />);
|
|
114
|
+
|
|
115
|
+
// Option 2: Using ConfirmDialog type
|
|
116
|
+
const Confirmation2: ConfirmDialog<Props, Response> = (props) => (<Dialog />);
|
|
124
117
|
```
|
|
125
118
|
|
|
126
|
-
### example
|
|
127
|
-
Context example with Chakra-ui in [codesandbox](https://codesandbox.io/s/react-confirm-with-chakra-ui-oidpf1)
|
|
128
119
|
|
|
129
|
-
##
|
|
130
|
-
|
|
120
|
+
## React Version Compatibility
|
|
121
|
+
|
|
122
|
+
- **React 18+**: Use `react-confirm` version 0.2.x or 0.3.x
|
|
123
|
+
- **React ≤17**: Use `react-confirm` version 0.1.x
|
|
131
124
|
|
|
132
|
-
```ts
|
|
133
|
-
const Confirmation1: React.FC<ConfirmDialogProps<Props, Response>> = (props) => (<Dialog></Dialog>)
|
|
134
|
-
const Confirmation2: ConfirmDialog<Props, Response> = (props) => (<Dialog></Dialog>)
|
|
135
|
-
```
|
|
136
125
|
|
|
137
|
-
|
|
126
|
+
## More Examples
|
|
138
127
|
|
|
128
|
+
- [TypeScript Example](https://stackblitz.com/fork/github/haradakunihiko/react-confirm-sample/tree/main/1_typescript)
|
|
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)
|
|
139
132
|
|
|
140
|
-
|
|
141
|
-
- [chakra-ui(using context) demo in codesandbox](https://codesandbox.io/s/react-confirm-with-chakra-ui-oidpf1)
|
|
142
|
-
- [material-ui example](https://github.com/haradakunihiko/react-confirm/tree/master/example/material-ui)
|
|
133
|
+
For additional reference examples, you can also check the [react-confirm-sample](https://github.com/haradakunihiko/react-confirm-sample/) repository, which contains archived historical examples and some alternative implementations. **Check the examples above first for the latest patterns.**
|
package/lib/confirmable.js
CHANGED
|
@@ -1,65 +1,44 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
-
function _typeof(
|
|
4
|
-
|
|
3
|
+
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
|
|
5
4
|
Object.defineProperty(exports, "__esModule", {
|
|
6
5
|
value: true
|
|
7
6
|
});
|
|
8
7
|
exports["default"] = void 0;
|
|
9
|
-
|
|
10
8
|
var _react = _interopRequireWildcard(require("react"));
|
|
11
|
-
|
|
12
9
|
var _excluded = ["dispose", "reject", "resolve"];
|
|
13
|
-
|
|
14
|
-
function
|
|
15
|
-
|
|
16
|
-
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
|
17
|
-
|
|
18
|
-
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
|
|
19
|
-
|
|
20
|
-
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
|
|
21
|
-
|
|
10
|
+
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, "default": e }; if (null === e || "object" != _typeof(e) && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t in e) { "default" !== _t && {}.hasOwnProperty.call(e, _t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t)) && (i.get || i.set) ? o(f, _t, i) : f[_t] = e[_t]); } return f; })(e, t); }
|
|
11
|
+
function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) { ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } } return n; }, _extends.apply(null, arguments); }
|
|
12
|
+
function _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest(); }
|
|
22
13
|
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
|
23
|
-
|
|
24
|
-
function
|
|
25
|
-
|
|
26
|
-
function
|
|
27
|
-
|
|
28
|
-
function
|
|
29
|
-
|
|
30
|
-
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
|
|
31
|
-
|
|
32
|
-
function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }
|
|
33
|
-
|
|
34
|
-
function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
|
|
35
|
-
|
|
14
|
+
function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
|
|
15
|
+
function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) { n[e] = r[e]; } return n; }
|
|
16
|
+
function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0) { ; } } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t["return"] && (u = t["return"](), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
|
|
17
|
+
function _arrayWithHoles(r) { if (Array.isArray(r)) return r; }
|
|
18
|
+
function _objectWithoutProperties(e, t) { if (null == e) return {}; var o, r, i = _objectWithoutPropertiesLoose(e, t); if (Object.getOwnPropertySymbols) { var n = Object.getOwnPropertySymbols(e); for (r = 0; r < n.length; r++) { o = n[r], -1 === t.indexOf(o) && {}.propertyIsEnumerable.call(e, o) && (i[o] = e[o]); } } return i; }
|
|
19
|
+
function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) { if ({}.hasOwnProperty.call(r, n)) { if (-1 !== e.indexOf(n)) continue; t[n] = r[n]; } } return t; }
|
|
36
20
|
var confirmable = function confirmable(Component) {
|
|
37
21
|
return function (_ref) {
|
|
38
22
|
var dispose = _ref.dispose,
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
23
|
+
reject = _ref.reject,
|
|
24
|
+
resolve = _ref.resolve,
|
|
25
|
+
other = _objectWithoutProperties(_ref, _excluded);
|
|
43
26
|
var _useState = (0, _react.useState)(true),
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
27
|
+
_useState2 = _slicedToArray(_useState, 2),
|
|
28
|
+
show = _useState2[0],
|
|
29
|
+
setShow = _useState2[1];
|
|
48
30
|
var dismiss = function dismiss() {
|
|
49
31
|
setShow(false);
|
|
50
32
|
dispose();
|
|
51
33
|
};
|
|
52
|
-
|
|
53
34
|
var cancel = function cancel(value) {
|
|
54
35
|
setShow(false);
|
|
55
36
|
reject(value);
|
|
56
37
|
};
|
|
57
|
-
|
|
58
38
|
var proceed = function proceed(value) {
|
|
59
39
|
setShow(false);
|
|
60
40
|
resolve(value);
|
|
61
41
|
};
|
|
62
|
-
|
|
63
42
|
return /*#__PURE__*/_react["default"].createElement(Component, _extends({
|
|
64
43
|
cancel: cancel,
|
|
65
44
|
dismiss: dismiss,
|
|
@@ -68,6 +47,4 @@ var confirmable = function confirmable(Component) {
|
|
|
68
47
|
}, other));
|
|
69
48
|
};
|
|
70
49
|
};
|
|
71
|
-
|
|
72
|
-
var _default = confirmable;
|
|
73
|
-
exports["default"] = _default;
|
|
50
|
+
var _default = exports["default"] = confirmable;
|
package/lib/context.js
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.ContextAwareConfirmation = void 0;
|
|
7
|
+
exports.createConfirmationContext = createConfirmationContext;
|
|
8
|
+
var _reactTree = require("./mounter/reactTree");
|
|
9
|
+
var _createConfirmation2 = require("./createConfirmation");
|
|
10
|
+
/**
|
|
11
|
+
* Creates a React context-aware confirmation system.
|
|
12
|
+
* This provides a simple interface for using confirmations within React component tree.
|
|
13
|
+
*
|
|
14
|
+
* @param {HTMLElement} [mountNode] - Optional DOM node to mount dialogs in
|
|
15
|
+
* @returns {Object} Object containing createConfirmation function and ConfirmationRoot component
|
|
16
|
+
*/
|
|
17
|
+
function createConfirmationContext(mountNode) {
|
|
18
|
+
var mounter = (0, _reactTree.createReactTreeMounter)(mountNode);
|
|
19
|
+
var _createConfirmation = (0, _createConfirmation2.createConfirmationCreater)(mounter);
|
|
20
|
+
var ConfirmationRoot = (0, _reactTree.createMountPoint)(mounter);
|
|
21
|
+
return {
|
|
22
|
+
/**
|
|
23
|
+
* Creates a confirmation function for a given component
|
|
24
|
+
* @param {React.ComponentType} component - The confirmable component
|
|
25
|
+
* @param {number} [unmountDelay=1000] - Delay before unmounting the component
|
|
26
|
+
* @returns {Function} Confirmation function that returns a Promise
|
|
27
|
+
*/
|
|
28
|
+
createConfirmation: function createConfirmation(component, unmountDelay) {
|
|
29
|
+
return _createConfirmation(component, unmountDelay);
|
|
30
|
+
},
|
|
31
|
+
/**
|
|
32
|
+
* React component that must be rendered in your app to display confirmations
|
|
33
|
+
* Place this component at the root level of your app or where you want confirmations to appear
|
|
34
|
+
*/
|
|
35
|
+
ConfirmationRoot: ConfirmationRoot
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Context-aware confirmation system for convenient usage
|
|
41
|
+
* Use this if you don't need custom mount nodes
|
|
42
|
+
*/
|
|
43
|
+
var ContextAwareConfirmation = exports.ContextAwareConfirmation = createConfirmationContext();
|
|
@@ -4,16 +4,14 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports["default"] = exports.createConfirmationCreater = void 0;
|
|
7
|
-
|
|
8
7
|
var _domTree = require("./mounter/domTree");
|
|
9
|
-
|
|
10
|
-
function ownKeys(
|
|
11
|
-
|
|
12
|
-
function
|
|
13
|
-
|
|
14
|
-
function
|
|
15
|
-
|
|
16
|
-
var createConfirmationCreater = function createConfirmationCreater(mounter) {
|
|
8
|
+
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
|
|
9
|
+
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
10
|
+
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
11
|
+
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
|
|
12
|
+
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; }
|
|
13
|
+
function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
|
|
14
|
+
var createConfirmationCreater = exports.createConfirmationCreater = function createConfirmationCreater(mounter) {
|
|
17
15
|
return function (Component) {
|
|
18
16
|
var unmountDelay = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1000;
|
|
19
17
|
var mountingNode = arguments.length > 2 ? arguments[2] : undefined;
|
|
@@ -31,13 +29,11 @@ var createConfirmationCreater = function createConfirmationCreater(mounter) {
|
|
|
31
29
|
throw e;
|
|
32
30
|
}
|
|
33
31
|
});
|
|
34
|
-
|
|
35
32
|
function dispose() {
|
|
36
33
|
setTimeout(function () {
|
|
37
34
|
mounter.unmount(mountId);
|
|
38
35
|
}, unmountDelay);
|
|
39
36
|
}
|
|
40
|
-
|
|
41
37
|
return promise.then(function (result) {
|
|
42
38
|
dispose();
|
|
43
39
|
return result;
|
|
@@ -48,9 +44,4 @@ var createConfirmationCreater = function createConfirmationCreater(mounter) {
|
|
|
48
44
|
};
|
|
49
45
|
};
|
|
50
46
|
};
|
|
51
|
-
|
|
52
|
-
exports.createConfirmationCreater = createConfirmationCreater;
|
|
53
|
-
|
|
54
|
-
var _default = createConfirmationCreater((0, _domTree.createDomTreeMounter)());
|
|
55
|
-
|
|
56
|
-
exports["default"] = _default;
|
|
47
|
+
var _default = exports["default"] = createConfirmationCreater((0, _domTree.createDomTreeMounter)());
|
package/lib/index.js
CHANGED
|
@@ -1,10 +1,15 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
-
function _typeof(
|
|
4
|
-
|
|
3
|
+
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
|
|
5
4
|
Object.defineProperty(exports, "__esModule", {
|
|
6
5
|
value: true
|
|
7
6
|
});
|
|
7
|
+
Object.defineProperty(exports, "ContextAwareConfirmation", {
|
|
8
|
+
enumerable: true,
|
|
9
|
+
get: function get() {
|
|
10
|
+
return _context.ContextAwareConfirmation;
|
|
11
|
+
}
|
|
12
|
+
});
|
|
8
13
|
Object.defineProperty(exports, "confirmable", {
|
|
9
14
|
enumerable: true,
|
|
10
15
|
get: function get() {
|
|
@@ -17,6 +22,12 @@ Object.defineProperty(exports, "createConfirmation", {
|
|
|
17
22
|
return _createConfirmation["default"];
|
|
18
23
|
}
|
|
19
24
|
});
|
|
25
|
+
Object.defineProperty(exports, "createConfirmationContext", {
|
|
26
|
+
enumerable: true,
|
|
27
|
+
get: function get() {
|
|
28
|
+
return _context.createConfirmationContext;
|
|
29
|
+
}
|
|
30
|
+
});
|
|
20
31
|
Object.defineProperty(exports, "createConfirmationCreater", {
|
|
21
32
|
enumerable: true,
|
|
22
33
|
get: function get() {
|
|
@@ -41,17 +52,10 @@ Object.defineProperty(exports, "createReactTreeMounter", {
|
|
|
41
52
|
return _reactTree.createReactTreeMounter;
|
|
42
53
|
}
|
|
43
54
|
});
|
|
44
|
-
|
|
45
55
|
var _confirmable = _interopRequireDefault(require("./confirmable"));
|
|
46
|
-
|
|
47
56
|
var _createConfirmation = _interopRequireWildcard(require("./createConfirmation"));
|
|
48
|
-
|
|
49
57
|
var _domTree = require("./mounter/domTree");
|
|
50
|
-
|
|
51
58
|
var _reactTree = require("./mounter/reactTree");
|
|
52
|
-
|
|
53
|
-
function
|
|
54
|
-
|
|
55
|
-
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
|
56
|
-
|
|
57
|
-
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
|
|
59
|
+
var _context = require("./context");
|
|
60
|
+
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, "default": e }; if (null === e || "object" != _typeof(e) && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t in e) { "default" !== _t && {}.hasOwnProperty.call(e, _t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t)) && (i.get || i.set) ? o(f, _t, i) : f[_t] = e[_t]); } return f; })(e, t); }
|
|
61
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { "default": e }; }
|
package/lib/mounter/domTree.js
CHANGED
|
@@ -4,36 +4,28 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.createDomTreeMounter = createDomTreeMounter;
|
|
7
|
-
|
|
8
7
|
var _react = _interopRequireDefault(require("react"));
|
|
9
|
-
|
|
10
8
|
var _client = require("react-dom/client");
|
|
11
|
-
|
|
12
|
-
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
|
|
13
|
-
|
|
9
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { "default": e }; }
|
|
14
10
|
function createDomTreeMounter(defaultMountNode) {
|
|
15
11
|
var confirms = {};
|
|
16
12
|
var callbacks = {};
|
|
17
|
-
|
|
18
13
|
function mount(Component, props, mountNode) {
|
|
19
14
|
var key = Math.floor(Math.random() * (1 << 30)).toString(16);
|
|
20
15
|
var wrapper = (mountNode || defaultMountNode || document.body).appendChild(document.createElement('div'));
|
|
21
16
|
confirms[key] = wrapper;
|
|
22
17
|
var root = (0, _client.createRoot)(wrapper);
|
|
23
|
-
root.render(
|
|
18
|
+
root.render(/*#__PURE__*/_react["default"].createElement(Component, props));
|
|
24
19
|
callbacks.mounted && callbacks.mounted();
|
|
25
20
|
return key;
|
|
26
21
|
}
|
|
27
|
-
|
|
28
22
|
function unmount(key) {
|
|
29
23
|
var wrapper = confirms[key];
|
|
30
24
|
delete confirms[key];
|
|
31
|
-
|
|
32
25
|
if (wrapper && wrapper.parentNode) {
|
|
33
26
|
wrapper.parentNode.removeChild(wrapper);
|
|
34
27
|
}
|
|
35
28
|
}
|
|
36
|
-
|
|
37
29
|
return {
|
|
38
30
|
mount: mount,
|
|
39
31
|
unmount: unmount,
|
package/lib/mounter/reactTree.js
CHANGED
|
@@ -1,46 +1,30 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
-
function _typeof(
|
|
4
|
-
|
|
3
|
+
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
|
|
5
4
|
Object.defineProperty(exports, "__esModule", {
|
|
6
5
|
value: true
|
|
7
6
|
});
|
|
8
7
|
exports.createMountPoint = createMountPoint;
|
|
9
8
|
exports.createReactTreeMounter = createReactTreeMounter;
|
|
10
|
-
|
|
11
9
|
var _react = _interopRequireWildcard(require("react"));
|
|
12
|
-
|
|
13
10
|
var _reactDom = require("react-dom");
|
|
14
|
-
|
|
15
|
-
function
|
|
16
|
-
|
|
17
|
-
function
|
|
18
|
-
|
|
19
|
-
function
|
|
20
|
-
|
|
21
|
-
function
|
|
22
|
-
|
|
23
|
-
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
|
|
24
|
-
|
|
25
|
-
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
26
|
-
|
|
27
|
-
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
|
|
28
|
-
|
|
11
|
+
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, "default": e }; if (null === e || "object" != _typeof(e) && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t in e) { "default" !== _t && {}.hasOwnProperty.call(e, _t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t)) && (i.get || i.set) ? o(f, _t, i) : f[_t] = e[_t]); } return f; })(e, t); }
|
|
12
|
+
function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) { ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } } return n; }, _extends.apply(null, arguments); }
|
|
13
|
+
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
14
|
+
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
15
|
+
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
|
|
16
|
+
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; }
|
|
17
|
+
function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
|
|
18
|
+
function _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest(); }
|
|
29
19
|
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
|
30
|
-
|
|
31
|
-
function
|
|
32
|
-
|
|
33
|
-
function
|
|
34
|
-
|
|
35
|
-
function _iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]; if (_i == null) return; var _arr = []; var _n = true; var _d = false; var _s, _e; try { for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
|
|
36
|
-
|
|
37
|
-
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
|
|
38
|
-
|
|
20
|
+
function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
|
|
21
|
+
function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) { n[e] = r[e]; } return n; }
|
|
22
|
+
function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0) { ; } } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t["return"] && (u = t["return"](), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
|
|
23
|
+
function _arrayWithHoles(r) { if (Array.isArray(r)) return r; }
|
|
39
24
|
function createReactTreeMounter(mountNode) {
|
|
40
25
|
var confirms = {};
|
|
41
26
|
var callbacks = {};
|
|
42
|
-
|
|
43
|
-
function mount(Component, props) {
|
|
27
|
+
function mount(Component, props, _mountNode) {
|
|
44
28
|
var key = Math.floor(Math.random() * (1 << 30)).toString(16);
|
|
45
29
|
confirms[key] = {
|
|
46
30
|
Component: Component,
|
|
@@ -48,17 +32,15 @@ function createReactTreeMounter(mountNode) {
|
|
|
48
32
|
};
|
|
49
33
|
callbacks.mounted && callbacks.mounted(confirms);
|
|
50
34
|
return key;
|
|
35
|
+
// _mountNode is ignored - ReactTreeMounter uses options.mountNode instead
|
|
51
36
|
}
|
|
52
|
-
|
|
53
37
|
function unmount(key) {
|
|
54
38
|
delete confirms[key];
|
|
55
39
|
callbacks.mounted && callbacks.mounted(confirms);
|
|
56
40
|
}
|
|
57
|
-
|
|
58
41
|
function setMountedCallback(func) {
|
|
59
42
|
callbacks.mounted = func;
|
|
60
43
|
}
|
|
61
|
-
|
|
62
44
|
return {
|
|
63
45
|
mount: mount,
|
|
64
46
|
unmount: unmount,
|
|
@@ -68,33 +50,28 @@ function createReactTreeMounter(mountNode) {
|
|
|
68
50
|
}
|
|
69
51
|
};
|
|
70
52
|
}
|
|
71
|
-
|
|
72
53
|
function createMountPoint(reactTreeMounter) {
|
|
73
54
|
return function () {
|
|
74
55
|
var _useState = (0, _react.useState)({}),
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
56
|
+
_useState2 = _slicedToArray(_useState, 2),
|
|
57
|
+
confirmComponents = _useState2[0],
|
|
58
|
+
setConfirmComponents = _useState2[1];
|
|
79
59
|
(0, _react.useEffect)(function () {
|
|
80
60
|
return reactTreeMounter.options.setMountedCallback(function (components) {
|
|
81
61
|
setConfirmComponents(_objectSpread({}, components));
|
|
82
62
|
});
|
|
83
63
|
}, []);
|
|
84
|
-
|
|
85
64
|
var element = /*#__PURE__*/_react["default"].createElement(_react["default"].Fragment, null, Object.keys(confirmComponents).map(function (key) {
|
|
86
65
|
var _confirmComponents$ke = confirmComponents[key],
|
|
87
|
-
|
|
88
|
-
|
|
66
|
+
Component = _confirmComponents$ke.Component,
|
|
67
|
+
props = _confirmComponents$ke.props;
|
|
89
68
|
return /*#__PURE__*/_react["default"].createElement(Component, _extends({
|
|
90
69
|
key: key
|
|
91
70
|
}, props));
|
|
92
71
|
}));
|
|
93
|
-
|
|
94
72
|
if (reactTreeMounter.options.mountNode) {
|
|
95
73
|
element = /*#__PURE__*/(0, _reactDom.createPortal)(element, reactTreeMounter.options.mountNode);
|
|
96
74
|
}
|
|
97
|
-
|
|
98
75
|
return element;
|
|
99
76
|
};
|
|
100
77
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-confirm",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0-0",
|
|
4
4
|
"description": "Small library which makes your Dialog component callable",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"repository": {
|
|
@@ -25,7 +25,9 @@
|
|
|
25
25
|
"clean": "rimraf lib",
|
|
26
26
|
"build": "babel src --out-dir lib",
|
|
27
27
|
"prepublish": "npm run clean && npm run build",
|
|
28
|
-
"test": "jest"
|
|
28
|
+
"test": "jest",
|
|
29
|
+
"test:types": "jest __tests__/typescript/",
|
|
30
|
+
"typecheck": "tsc --noEmit"
|
|
29
31
|
},
|
|
30
32
|
"author": "",
|
|
31
33
|
"license": "MIT",
|
|
@@ -35,19 +37,23 @@
|
|
|
35
37
|
},
|
|
36
38
|
"devDependencies": {
|
|
37
39
|
"@babel/cli": "^7.17.6",
|
|
38
|
-
"@babel/core": "^7.
|
|
40
|
+
"@babel/core": "^7.27.4",
|
|
39
41
|
"@babel/preset-env": "^7.16.11",
|
|
40
42
|
"@babel/preset-react": "^7.16.7",
|
|
41
43
|
"@testing-library/jest-dom": "^5.16.5",
|
|
42
44
|
"@testing-library/react": "^14.0.0",
|
|
43
|
-
"
|
|
45
|
+
"@types/jest": "^29.5.0",
|
|
46
|
+
"@types/react": "^18.2.0",
|
|
47
|
+
"@types/react-dom": "^18.2.0",
|
|
44
48
|
"babel-jest": "^29.5.0",
|
|
45
49
|
"jest": "^29.5.0",
|
|
46
50
|
"jest-environment-jsdom": "^29.5.0",
|
|
47
51
|
"react": ">=18.2.0",
|
|
48
52
|
"react-dom": ">=18.2.0",
|
|
49
53
|
"regenerator-runtime": "^0.13.11",
|
|
50
|
-
"rimraf": "^3.0.2"
|
|
54
|
+
"rimraf": "^3.0.2",
|
|
55
|
+
"ts-jest": "^29.1.0",
|
|
56
|
+
"typescript": "^5.0.0"
|
|
51
57
|
},
|
|
52
58
|
"dependencies": {},
|
|
53
59
|
"typings": "typescript/index.d.ts"
|
package/src/context.js
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { createReactTreeMounter, createMountPoint } from './mounter/reactTree';
|
|
2
|
+
import { createConfirmationCreater } from './createConfirmation';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Creates a React context-aware confirmation system.
|
|
6
|
+
* This provides a simple interface for using confirmations within React component tree.
|
|
7
|
+
*
|
|
8
|
+
* @param {HTMLElement} [mountNode] - Optional DOM node to mount dialogs in
|
|
9
|
+
* @returns {Object} Object containing createConfirmation function and ConfirmationRoot component
|
|
10
|
+
*/
|
|
11
|
+
export function createConfirmationContext(mountNode) {
|
|
12
|
+
const mounter = createReactTreeMounter(mountNode);
|
|
13
|
+
const createConfirmation = createConfirmationCreater(mounter);
|
|
14
|
+
const ConfirmationRoot = createMountPoint(mounter);
|
|
15
|
+
|
|
16
|
+
return {
|
|
17
|
+
/**
|
|
18
|
+
* Creates a confirmation function for a given component
|
|
19
|
+
* @param {React.ComponentType} component - The confirmable component
|
|
20
|
+
* @param {number} [unmountDelay=1000] - Delay before unmounting the component
|
|
21
|
+
* @returns {Function} Confirmation function that returns a Promise
|
|
22
|
+
*/
|
|
23
|
+
createConfirmation: (component, unmountDelay) => createConfirmation(component, unmountDelay),
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* React component that must be rendered in your app to display confirmations
|
|
27
|
+
* Place this component at the root level of your app or where you want confirmations to appear
|
|
28
|
+
*/
|
|
29
|
+
ConfirmationRoot
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Context-aware confirmation system for convenient usage
|
|
35
|
+
* Use this if you don't need custom mount nodes
|
|
36
|
+
*/
|
|
37
|
+
export const ContextAwareConfirmation = createConfirmationContext();
|
package/src/index.js
CHANGED
|
@@ -2,5 +2,18 @@ import confirmable from './confirmable';
|
|
|
2
2
|
import createConfirmation, { createConfirmationCreater } from './createConfirmation';
|
|
3
3
|
import { createDomTreeMounter } from './mounter/domTree';
|
|
4
4
|
import { createReactTreeMounter, createMountPoint } from './mounter/reactTree';
|
|
5
|
+
import {
|
|
6
|
+
createConfirmationContext,
|
|
7
|
+
ContextAwareConfirmation
|
|
8
|
+
} from './context';
|
|
5
9
|
|
|
6
|
-
export {
|
|
10
|
+
export {
|
|
11
|
+
confirmable,
|
|
12
|
+
createConfirmation,
|
|
13
|
+
createConfirmationCreater,
|
|
14
|
+
createDomTreeMounter,
|
|
15
|
+
createReactTreeMounter,
|
|
16
|
+
createMountPoint,
|
|
17
|
+
createConfirmationContext,
|
|
18
|
+
ContextAwareConfirmation
|
|
19
|
+
};
|
package/src/mounter/reactTree.js
CHANGED
|
@@ -5,11 +5,12 @@ export function createReactTreeMounter(mountNode) {
|
|
|
5
5
|
const confirms = {};
|
|
6
6
|
const callbacks = {};
|
|
7
7
|
|
|
8
|
-
function mount(Component, props){
|
|
8
|
+
function mount(Component, props, _mountNode){
|
|
9
9
|
const key = Math.floor(Math.random() * (1 << 30)).toString(16);
|
|
10
10
|
confirms[key] = { Component, props};
|
|
11
11
|
callbacks.mounted && callbacks.mounted(confirms);
|
|
12
12
|
return key;
|
|
13
|
+
// _mountNode is ignored - ReactTreeMounter uses options.mountNode instead
|
|
13
14
|
}
|
|
14
15
|
function unmount(key) {
|
|
15
16
|
delete confirms[key];
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { ConfirmDialog, ConfirmableDialog } from './index';
|
|
3
|
+
|
|
4
|
+
export interface ConfirmationContext {
|
|
5
|
+
/**
|
|
6
|
+
* Creates a confirmation function for a given component
|
|
7
|
+
* @param component - The confirmable component
|
|
8
|
+
* @param unmountDelay - Delay before unmounting the component (default: 1000ms)
|
|
9
|
+
* @returns Confirmation function that returns a Promise
|
|
10
|
+
*/
|
|
11
|
+
createConfirmation: <P, R>(
|
|
12
|
+
component: ConfirmableDialog<P, R>,
|
|
13
|
+
unmountDelay?: number
|
|
14
|
+
) => (props: P) => Promise<R>;
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* React component that must be rendered in your app to display confirmations
|
|
18
|
+
* Place this component at the root level of your app or where you want confirmations to appear
|
|
19
|
+
*/
|
|
20
|
+
ConfirmationRoot: React.ComponentType;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Creates a React context-aware confirmation system.
|
|
25
|
+
* This provides a simple interface for using confirmations within React component tree.
|
|
26
|
+
*
|
|
27
|
+
* @param mountNode - Optional DOM node to mount dialogs in
|
|
28
|
+
* @returns Object containing createConfirmation function and ConfirmationRoot component
|
|
29
|
+
*/
|
|
30
|
+
export declare function createConfirmationContext(
|
|
31
|
+
mountNode?: Element | DocumentFragment | HTMLElement
|
|
32
|
+
): ConfirmationContext;
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Context-aware confirmation system for convenient usage
|
|
36
|
+
* Use this if you don't need custom mount nodes
|
|
37
|
+
*/
|
|
38
|
+
export declare const ContextAwareConfirmation: ConfirmationContext;
|
package/typescript/index.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import * as React from 'react';
|
|
|
2
2
|
|
|
3
3
|
type ConfirmableProps<P, R> = {
|
|
4
4
|
dispose: () => void;
|
|
5
|
-
resolve: PromiseLike<R
|
|
5
|
+
resolve: (value: R | PromiseLike<R>) => void;
|
|
6
6
|
reject: (reason?: any) => void;
|
|
7
7
|
} & P;
|
|
8
8
|
|
|
@@ -32,18 +32,25 @@ export declare function createConfirmation<P, R>(
|
|
|
32
32
|
): (props: P) => Promise<R>;
|
|
33
33
|
|
|
34
34
|
type Mounter = {
|
|
35
|
-
mount: (component: React.ComponentType, ) => string
|
|
35
|
+
mount: (component: React.ComponentType, props: any, mountNode?: HTMLElement) => string
|
|
36
36
|
unmount: (key: string) => void
|
|
37
37
|
}
|
|
38
38
|
|
|
39
39
|
type TreeMounter = {
|
|
40
40
|
options: {
|
|
41
|
-
setMountedCallback: (callback: any) => void
|
|
42
|
-
mountNode
|
|
41
|
+
setMountedCallback: (callback: (components: any) => void) => void
|
|
42
|
+
mountNode?: Element | DocumentFragment | HTMLElement
|
|
43
43
|
}
|
|
44
|
-
} & Mounter
|
|
44
|
+
} & Mounter
|
|
45
45
|
|
|
46
|
-
export declare function createReactTreeMounter(mountNode?: HTMLElement): TreeMounter;
|
|
47
|
-
export declare function createMountPoint(
|
|
48
|
-
export declare function createDomTreeMounter(
|
|
46
|
+
export declare function createReactTreeMounter(mountNode?: Element | DocumentFragment | HTMLElement): TreeMounter;
|
|
47
|
+
export declare function createMountPoint(mounter: TreeMounter): React.ComponentType;
|
|
48
|
+
export declare function createDomTreeMounter(defaultMountNode?: Element | DocumentFragment | HTMLElement): Mounter;
|
|
49
49
|
export declare function createConfirmationCreater(mounter: Mounter): typeof createConfirmation;
|
|
50
|
+
|
|
51
|
+
// Context-aware confirmation system
|
|
52
|
+
export {
|
|
53
|
+
createConfirmationContext,
|
|
54
|
+
ContextAwareConfirmation,
|
|
55
|
+
ConfirmationContext
|
|
56
|
+
} from './context';
|