react-confirm-alert 3.0.6 → 3.1.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 +56 -89
- package/dist/index.esm.js +1058 -0
- package/dist/package.json +1 -0
- package/index.d.ts +2 -31
- package/lib/index.js +1071 -295
- package/package.json +36 -40
- package/src/react-confirm-alert.css +64 -54
- package/style.css +127 -0
- package/typings/Dialog.d.ts +27 -0
- package/typings/DialogFrame.d.ts +28 -0
- package/typings/DialogHost.d.ts +17 -0
- package/typings/DialogStack.d.ts +5 -0
- package/typings/api.d.ts +21 -0
- package/typings/classNames.d.ts +16 -0
- package/typings/compat.d.ts +48 -0
- package/typings/fallbackRoot.d.ts +4 -0
- package/typings/index.d.ts +9 -0
- package/typings/lifecycle.d.ts +7 -0
- package/typings/page.d.ts +2 -0
- package/typings/store.d.ts +59 -0
- package/typings/types.d.ts +138 -0
package/package.json
CHANGED
|
@@ -1,21 +1,23 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-confirm-alert",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.1.1",
|
|
4
4
|
"description": "react component confirm dialog.",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
|
+
"module": "dist/index.esm.js",
|
|
6
7
|
"scripts": {
|
|
7
|
-
"
|
|
8
|
-
"
|
|
9
|
-
"test
|
|
10
|
-
"
|
|
11
|
-
"
|
|
12
|
-
"build": "npm run
|
|
13
|
-
"
|
|
14
|
-
"
|
|
8
|
+
"build": "vite build && node -e \"require('fs').rmSync('typings',{recursive:true,force:true})\" && tsc -p tsconfig.build.json && node -e \"require('fs').copyFileSync('src/react-confirm-alert.css','style.css')\"",
|
|
9
|
+
"prepublishOnly": "npm run build",
|
|
10
|
+
"test": "vitest run",
|
|
11
|
+
"test:fixtures": "node fixtures/run.mjs",
|
|
12
|
+
"test:types": "tsc -p tsconfig.json && tsc -p tsconfig.test-d.json",
|
|
13
|
+
"docs:build": "npm run build --prefix website",
|
|
14
|
+
"check:package": "publint --strict && attw --pack . && size-limit",
|
|
15
|
+
"version-packages": "changeset version && npm install --package-lock-only",
|
|
16
|
+
"release": "npm run build && npm run check:package && changeset publish"
|
|
15
17
|
},
|
|
16
18
|
"repository": {
|
|
17
19
|
"type": "git",
|
|
18
|
-
"url": "https://github.com/GA-MO/react-confirm-alert.git"
|
|
20
|
+
"url": "git+https://github.com/GA-MO/react-confirm-alert.git"
|
|
19
21
|
},
|
|
20
22
|
"keywords": [
|
|
21
23
|
"react alert example",
|
|
@@ -37,43 +39,37 @@
|
|
|
37
39
|
"typings": "./index.d.ts",
|
|
38
40
|
"files": [
|
|
39
41
|
"lib",
|
|
42
|
+
"dist",
|
|
43
|
+
"typings",
|
|
40
44
|
"src/react-confirm-alert.css",
|
|
45
|
+
"style.css",
|
|
41
46
|
"index.d.ts"
|
|
42
47
|
],
|
|
43
48
|
"devDependencies": {
|
|
44
|
-
"
|
|
45
|
-
"
|
|
46
|
-
"
|
|
47
|
-
"
|
|
48
|
-
"
|
|
49
|
-
"
|
|
50
|
-
"
|
|
51
|
-
"
|
|
52
|
-
"
|
|
53
|
-
"
|
|
54
|
-
"
|
|
55
|
-
"
|
|
56
|
-
"eslint": "^4.5.0",
|
|
57
|
-
"eslint-config-standard": "^10.2.1",
|
|
58
|
-
"eslint-config-standard-react": "^5.0.0",
|
|
59
|
-
"eslint-plugin-import": "^2.7.0",
|
|
60
|
-
"eslint-plugin-node": "^5.1.1",
|
|
61
|
-
"eslint-plugin-promise": "^3.5.0",
|
|
62
|
-
"eslint-plugin-react": "^7.3.0",
|
|
63
|
-
"eslint-plugin-standard": "^3.0.1",
|
|
64
|
-
"mocha": "^3.5.0",
|
|
65
|
-
"prop-types": "^15.6.2",
|
|
49
|
+
"@arethetypeswrong/cli": "^0.18.5",
|
|
50
|
+
"@changesets/changelog-github": "^1.0.1",
|
|
51
|
+
"@changesets/cli": "^3.0.3",
|
|
52
|
+
"@size-limit/preset-small-lib": "^14.3.0",
|
|
53
|
+
"@types/react": "^18.3.31",
|
|
54
|
+
"@types/react-dom": "^18.3.7",
|
|
55
|
+
"@vitejs/plugin-react": "^6.1.2",
|
|
56
|
+
"@vitest/browser": "^5.0.5",
|
|
57
|
+
"@vitest/browser-playwright": "^5.0.5",
|
|
58
|
+
"jsdom": "^30.1.3",
|
|
59
|
+
"playwright": "^1.64.1",
|
|
60
|
+
"publint": "^0.3.25",
|
|
66
61
|
"react": "^18.1.0",
|
|
67
62
|
"react-dom": "^18.1.0",
|
|
68
|
-
"
|
|
69
|
-
"
|
|
70
|
-
"
|
|
71
|
-
"
|
|
72
|
-
"webpack": "^3.5.5",
|
|
73
|
-
"webpack-dev-server": "^2.7.1"
|
|
63
|
+
"size-limit": "^14.3.0",
|
|
64
|
+
"typescript": "^7.0.2",
|
|
65
|
+
"vite": "^8.3.5",
|
|
66
|
+
"vitest": "^5.0.5"
|
|
74
67
|
},
|
|
75
68
|
"peerDependencies": {
|
|
76
69
|
"react": ">=18.0.0",
|
|
77
|
-
"react-dom": ">=
|
|
78
|
-
}
|
|
70
|
+
"react-dom": ">=18.0.0"
|
|
71
|
+
},
|
|
72
|
+
"sideEffects": [
|
|
73
|
+
"**/*.css"
|
|
74
|
+
]
|
|
79
75
|
}
|
|
@@ -3,9 +3,8 @@ body.react-confirm-alert-body-element {
|
|
|
3
3
|
}
|
|
4
4
|
|
|
5
5
|
.react-confirm-alert-blur {
|
|
6
|
-
filter:
|
|
7
|
-
filter: blur(2px);
|
|
8
|
-
-webkit-filter: blur(2px);
|
|
6
|
+
filter: blur(var(--rca-blur, 2px));
|
|
7
|
+
-webkit-filter: blur(var(--rca-blur, 2px));
|
|
9
8
|
}
|
|
10
9
|
|
|
11
10
|
.react-confirm-alert-overlay {
|
|
@@ -14,38 +13,25 @@ body.react-confirm-alert-body-element {
|
|
|
14
13
|
left: 0;
|
|
15
14
|
right: 0;
|
|
16
15
|
bottom: 0;
|
|
17
|
-
z-index: 99;
|
|
18
|
-
background: rgba(255, 255, 255, 0.9);
|
|
19
|
-
display: -webkit-flex;
|
|
20
|
-
display: -moz-flex;
|
|
21
|
-
display: -ms-flex;
|
|
22
|
-
display: -o-flex;
|
|
16
|
+
z-index: var(--rca-z-index, 99);
|
|
17
|
+
background: var(--rca-backdrop, rgba(255, 255, 255, 0.9));
|
|
23
18
|
display: flex;
|
|
24
19
|
justify-content: center;
|
|
25
|
-
-ms-align-items: center;
|
|
26
20
|
align-items: center;
|
|
27
21
|
opacity: 0;
|
|
28
|
-
|
|
29
|
-
-moz-animation: react-confirm-alert-fadeIn 0.5s 0.2s forwards;
|
|
30
|
-
-o-animation: react-confirm-alert-fadeIn 0.5s 0.2s forwards;
|
|
31
|
-
animation: react-confirm-alert-fadeIn 0.5s 0.2s forwards;
|
|
22
|
+
animation: react-confirm-alert-fadeIn var(--rca-duration, 0.5s) var(--rca-easing, ease) var(--rca-delay, 0.2s) forwards;
|
|
32
23
|
}
|
|
33
24
|
|
|
34
25
|
.react-confirm-alert-body {
|
|
35
|
-
font-family: Arial, Helvetica, sans-serif;
|
|
36
|
-
width: 400px;
|
|
37
|
-
|
|
26
|
+
font-family: var(--rca-font, Arial, Helvetica, sans-serif);
|
|
27
|
+
width: var(--rca-width, 400px);
|
|
28
|
+
max-width: calc(100vw - 92px);
|
|
29
|
+
padding: var(--rca-padding, 30px);
|
|
38
30
|
text-align: left;
|
|
39
|
-
background: #fff;
|
|
40
|
-
border-radius: 10px;
|
|
41
|
-
box-shadow: 0 20px 75px rgba(0, 0, 0, 0.13);
|
|
42
|
-
color: #666;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
.react-confirm-alert-svg {
|
|
46
|
-
position: absolute;
|
|
47
|
-
top: 0;
|
|
48
|
-
left: 0;
|
|
31
|
+
background: var(--rca-bg, #fff);
|
|
32
|
+
border-radius: var(--rca-radius, 10px);
|
|
33
|
+
box-shadow: var(--rca-shadow, 0 20px 75px rgba(0, 0, 0, 0.13));
|
|
34
|
+
color: var(--rca-fg, #666);
|
|
49
35
|
}
|
|
50
36
|
|
|
51
37
|
.react-confirm-alert-body > h1 {
|
|
@@ -58,10 +44,6 @@ body.react-confirm-alert-body-element {
|
|
|
58
44
|
}
|
|
59
45
|
|
|
60
46
|
.react-confirm-alert-button-group {
|
|
61
|
-
display: -webkit-flex;
|
|
62
|
-
display: -moz-flex;
|
|
63
|
-
display: -ms-flex;
|
|
64
|
-
display: -o-flex;
|
|
65
47
|
display: flex;
|
|
66
48
|
justify-content: flex-start;
|
|
67
49
|
margin-top: 20px;
|
|
@@ -69,40 +51,68 @@ body.react-confirm-alert-body-element {
|
|
|
69
51
|
|
|
70
52
|
.react-confirm-alert-button-group > button {
|
|
71
53
|
outline: none;
|
|
72
|
-
background: #333;
|
|
54
|
+
background: var(--rca-button-bg, #333);
|
|
73
55
|
border: none;
|
|
74
56
|
display: inline-block;
|
|
75
57
|
padding: 6px 18px;
|
|
76
|
-
color: #eee;
|
|
77
|
-
margin-right: 10px;
|
|
78
|
-
border-radius: 5px;
|
|
58
|
+
color: var(--rca-button-fg, #eee);
|
|
59
|
+
margin-right: var(--rca-gap, 10px);
|
|
60
|
+
border-radius: var(--rca-button-radius, 5px);
|
|
79
61
|
font-size: 12px;
|
|
80
62
|
cursor: pointer;
|
|
81
63
|
}
|
|
82
64
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
to {
|
|
88
|
-
opacity: 1;
|
|
89
|
-
}
|
|
65
|
+
/* Keyboard focus is visible again (B15); a mouse click shows no ring. */
|
|
66
|
+
.react-confirm-alert-button-group > button:focus-visible {
|
|
67
|
+
outline: var(--rca-focus-ring, 2px solid Highlight);
|
|
68
|
+
outline-offset: 2px;
|
|
90
69
|
}
|
|
91
70
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
71
|
+
/* modal: true renders the overlay as a <dialog> in the top layer. Reset the browser's dialog box so it
|
|
72
|
+
looks like the v3 overlay, and never set display while it is closed. */
|
|
73
|
+
dialog.react-confirm-alert-overlay {
|
|
74
|
+
width: 100%;
|
|
75
|
+
height: 100%;
|
|
76
|
+
max-width: none;
|
|
77
|
+
max-height: none;
|
|
78
|
+
margin: 0;
|
|
79
|
+
padding: 0;
|
|
80
|
+
border: 0;
|
|
81
|
+
color: inherit;
|
|
99
82
|
}
|
|
100
83
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
84
|
+
dialog.react-confirm-alert-overlay:not([open]) {
|
|
85
|
+
display: none;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
dialog.react-confirm-alert-overlay::backdrop {
|
|
89
|
+
background: transparent;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
.react-confirm-alert-button-group > [data-variant='danger'] {
|
|
93
|
+
background: var(--rca-danger, #c62828);
|
|
94
|
+
color: #fff;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
[data-rca]:not([data-kind='custom']) [data-slot='title'] {
|
|
98
|
+
margin: 0 0 8px;
|
|
99
|
+
font-size: 1.25em;
|
|
100
|
+
font-weight: 600;
|
|
101
|
+
color: var(--rca-title, #222);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
.react-confirm-alert [data-slot='message'] {
|
|
105
|
+
margin: 0;
|
|
106
|
+
white-space: pre-line;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
.react-confirm-alert:focus {
|
|
110
|
+
outline: none;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
@media (prefers-reduced-motion: reduce) {
|
|
114
|
+
.react-confirm-alert-overlay {
|
|
115
|
+
animation: none;
|
|
106
116
|
opacity: 1;
|
|
107
117
|
}
|
|
108
118
|
}
|
package/style.css
ADDED
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
body.react-confirm-alert-body-element {
|
|
2
|
+
overflow: hidden;
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
.react-confirm-alert-blur {
|
|
6
|
+
filter: blur(var(--rca-blur, 2px));
|
|
7
|
+
-webkit-filter: blur(var(--rca-blur, 2px));
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
.react-confirm-alert-overlay {
|
|
11
|
+
position: fixed;
|
|
12
|
+
top: 0;
|
|
13
|
+
left: 0;
|
|
14
|
+
right: 0;
|
|
15
|
+
bottom: 0;
|
|
16
|
+
z-index: var(--rca-z-index, 99);
|
|
17
|
+
background: var(--rca-backdrop, rgba(255, 255, 255, 0.9));
|
|
18
|
+
display: flex;
|
|
19
|
+
justify-content: center;
|
|
20
|
+
align-items: center;
|
|
21
|
+
opacity: 0;
|
|
22
|
+
animation: react-confirm-alert-fadeIn var(--rca-duration, 0.5s) var(--rca-easing, ease) var(--rca-delay, 0.2s) forwards;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
.react-confirm-alert-body {
|
|
26
|
+
font-family: var(--rca-font, Arial, Helvetica, sans-serif);
|
|
27
|
+
width: var(--rca-width, 400px);
|
|
28
|
+
max-width: calc(100vw - 92px);
|
|
29
|
+
padding: var(--rca-padding, 30px);
|
|
30
|
+
text-align: left;
|
|
31
|
+
background: var(--rca-bg, #fff);
|
|
32
|
+
border-radius: var(--rca-radius, 10px);
|
|
33
|
+
box-shadow: var(--rca-shadow, 0 20px 75px rgba(0, 0, 0, 0.13));
|
|
34
|
+
color: var(--rca-fg, #666);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
.react-confirm-alert-body > h1 {
|
|
38
|
+
margin-top: 0;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
.react-confirm-alert-body > h3 {
|
|
42
|
+
margin: 0;
|
|
43
|
+
font-size: 16px;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
.react-confirm-alert-button-group {
|
|
47
|
+
display: flex;
|
|
48
|
+
justify-content: flex-start;
|
|
49
|
+
margin-top: 20px;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
.react-confirm-alert-button-group > button {
|
|
53
|
+
outline: none;
|
|
54
|
+
background: var(--rca-button-bg, #333);
|
|
55
|
+
border: none;
|
|
56
|
+
display: inline-block;
|
|
57
|
+
padding: 6px 18px;
|
|
58
|
+
color: var(--rca-button-fg, #eee);
|
|
59
|
+
margin-right: var(--rca-gap, 10px);
|
|
60
|
+
border-radius: var(--rca-button-radius, 5px);
|
|
61
|
+
font-size: 12px;
|
|
62
|
+
cursor: pointer;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/* Keyboard focus is visible again (B15); a mouse click shows no ring. */
|
|
66
|
+
.react-confirm-alert-button-group > button:focus-visible {
|
|
67
|
+
outline: var(--rca-focus-ring, 2px solid Highlight);
|
|
68
|
+
outline-offset: 2px;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/* modal: true renders the overlay as a <dialog> in the top layer. Reset the browser's dialog box so it
|
|
72
|
+
looks like the v3 overlay, and never set display while it is closed. */
|
|
73
|
+
dialog.react-confirm-alert-overlay {
|
|
74
|
+
width: 100%;
|
|
75
|
+
height: 100%;
|
|
76
|
+
max-width: none;
|
|
77
|
+
max-height: none;
|
|
78
|
+
margin: 0;
|
|
79
|
+
padding: 0;
|
|
80
|
+
border: 0;
|
|
81
|
+
color: inherit;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
dialog.react-confirm-alert-overlay:not([open]) {
|
|
85
|
+
display: none;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
dialog.react-confirm-alert-overlay::backdrop {
|
|
89
|
+
background: transparent;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
.react-confirm-alert-button-group > [data-variant='danger'] {
|
|
93
|
+
background: var(--rca-danger, #c62828);
|
|
94
|
+
color: #fff;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
[data-rca]:not([data-kind='custom']) [data-slot='title'] {
|
|
98
|
+
margin: 0 0 8px;
|
|
99
|
+
font-size: 1.25em;
|
|
100
|
+
font-weight: 600;
|
|
101
|
+
color: var(--rca-title, #222);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
.react-confirm-alert [data-slot='message'] {
|
|
105
|
+
margin: 0;
|
|
106
|
+
white-space: pre-line;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
.react-confirm-alert:focus {
|
|
110
|
+
outline: none;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
@media (prefers-reduced-motion: reduce) {
|
|
114
|
+
.react-confirm-alert-overlay {
|
|
115
|
+
animation: none;
|
|
116
|
+
opacity: 1;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
@keyframes react-confirm-alert-fadeIn {
|
|
121
|
+
from {
|
|
122
|
+
opacity: 0;
|
|
123
|
+
}
|
|
124
|
+
to {
|
|
125
|
+
opacity: 1;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { type KeyboardEvent, type ReactNode, type ReactElement } from 'react';
|
|
2
|
+
import type { DialogClassNames, AlertOptions, ConfirmOptions, PromptOptions } from './types';
|
|
3
|
+
interface InPlace {
|
|
4
|
+
open: boolean;
|
|
5
|
+
onOpenChange: (open: boolean) => void;
|
|
6
|
+
}
|
|
7
|
+
export interface DialogProps extends InPlace {
|
|
8
|
+
children: ReactNode;
|
|
9
|
+
modal?: boolean | undefined;
|
|
10
|
+
closeOnEscape?: boolean | undefined;
|
|
11
|
+
closeOnClickOutside?: boolean | undefined;
|
|
12
|
+
onKeyDown?: ((event: KeyboardEvent<HTMLElement>, close: () => void) => void) | undefined;
|
|
13
|
+
unstyled?: boolean | undefined;
|
|
14
|
+
classNames?: DialogClassNames | undefined;
|
|
15
|
+
'aria-label'?: string | undefined;
|
|
16
|
+
'aria-labelledby'?: string | undefined;
|
|
17
|
+
'aria-describedby'?: string | undefined;
|
|
18
|
+
}
|
|
19
|
+
type Declarative<O> = InPlace & Omit<O, 'signal' | 'strategy'>;
|
|
20
|
+
export type ConfirmDialogProps = Declarative<AlertOptions> | Declarative<ConfirmOptions> | (Declarative<PromptOptions> & {
|
|
21
|
+
onSubmit: (value: string) => void | Promise<void>;
|
|
22
|
+
});
|
|
23
|
+
/** A dialog rendered where it is placed, so its children read the latest state of the component (#63 #66). */
|
|
24
|
+
export declare function Dialog(props: DialogProps): ReactElement | null;
|
|
25
|
+
/** confirm, alert or prompt rendered in place and driven by `open`. */
|
|
26
|
+
export declare function ConfirmDialog(props: ConfirmDialogProps): ReactElement | null;
|
|
27
|
+
export {};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { type KeyboardEvent, type ReactNode, type ReactElement } from 'react';
|
|
2
|
+
import type { DialogId, DialogKind, StyleOptions } from './types';
|
|
3
|
+
export interface DialogFrameProps {
|
|
4
|
+
id?: DialogId;
|
|
5
|
+
modal: boolean;
|
|
6
|
+
state: 'open' | 'closing';
|
|
7
|
+
kind: DialogKind;
|
|
8
|
+
/** style layers, widest first (see classNames.ts) */
|
|
9
|
+
layers: readonly StyleOptions[];
|
|
10
|
+
/** v3 overlayClassName, added to the dialog slot */
|
|
11
|
+
extraClass?: string | undefined;
|
|
12
|
+
tone?: 'default' | 'danger' | undefined;
|
|
13
|
+
depth?: number | undefined;
|
|
14
|
+
topmost?: boolean | undefined;
|
|
15
|
+
label?: string | undefined;
|
|
16
|
+
labelledBy?: string | undefined;
|
|
17
|
+
describedBy?: string | undefined;
|
|
18
|
+
role: 'dialog' | 'alertdialog';
|
|
19
|
+
closeOnClickOutside: boolean;
|
|
20
|
+
closeOnEscape: boolean;
|
|
21
|
+
/** the v3 API reads Escape from document keydown and focuses the panel */
|
|
22
|
+
legacy: boolean;
|
|
23
|
+
onKeyDown?: ((event: KeyboardEvent<HTMLElement>, close: () => void) => void) | undefined;
|
|
24
|
+
onClickOutside?: (() => void) | undefined;
|
|
25
|
+
onDismiss: () => void;
|
|
26
|
+
children: ReactNode;
|
|
27
|
+
}
|
|
28
|
+
export declare function DialogFrame(props: DialogFrameProps): ReactElement;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { type ReactElement } from 'react';
|
|
2
|
+
import { alert, closeAll, confirm, openDialog, prompt } from './api';
|
|
3
|
+
export interface DialogHostProps {
|
|
4
|
+
/** when this value changes, every open dialog is dismissed, e.g. pass the pathname */
|
|
5
|
+
dismissKey?: unknown;
|
|
6
|
+
}
|
|
7
|
+
export declare function DialogHost({ dismissKey }: DialogHostProps): ReactElement;
|
|
8
|
+
declare const dialogs: {
|
|
9
|
+
alert: typeof alert;
|
|
10
|
+
confirm: typeof confirm;
|
|
11
|
+
prompt: typeof prompt;
|
|
12
|
+
openDialog: typeof openDialog;
|
|
13
|
+
closeAll: typeof closeAll;
|
|
14
|
+
};
|
|
15
|
+
/** The same functions as the module exports, so a component reads as one that opens dialogs. */
|
|
16
|
+
export declare function useDialog(): typeof dialogs;
|
|
17
|
+
export {};
|
package/typings/api.d.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { type ReactNode, type ReactElement } from 'react';
|
|
2
|
+
import type { AlertOptions, ConfirmOptions, CustomOptions, DialogHandle, DialogId, DialogRenderProps, PromptOptions } from './types';
|
|
3
|
+
export declare function Body({ props, children }: {
|
|
4
|
+
props: DialogRenderProps<any>;
|
|
5
|
+
children: ReactNode;
|
|
6
|
+
}): ReactElement;
|
|
7
|
+
export declare function Buttons<R>({ props, signal: getSignal, focus }: {
|
|
8
|
+
props: DialogRenderProps<R>;
|
|
9
|
+
signal: () => AbortSignal;
|
|
10
|
+
focus: number;
|
|
11
|
+
}): ReactElement;
|
|
12
|
+
export declare function alert(input: string | Omit<AlertOptions, 'kind'>): Promise<void>;
|
|
13
|
+
export declare function confirm(input: string | Omit<ConfirmOptions, 'kind'>): Promise<boolean>;
|
|
14
|
+
export declare function PromptBody({ props, options }: {
|
|
15
|
+
props: DialogRenderProps<string>;
|
|
16
|
+
options: Omit<PromptOptions, 'kind'>;
|
|
17
|
+
}): ReactElement;
|
|
18
|
+
export declare function prompt(input: string | Omit<PromptOptions, 'kind'>): Promise<string | null>;
|
|
19
|
+
export declare function openDialog<R = void>(options: Omit<CustomOptions<R>, 'kind'>): DialogHandle<R>;
|
|
20
|
+
export declare function closeDialog(id: DialogId): void;
|
|
21
|
+
export declare function closeAll(): void;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { DialogClassNames, DialogDefaults, DialogSlot, StyleOptions } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* Style layers from widest to narrowest. confirmAlert keeps the v3 look unless the app sets
|
|
4
|
+
* confirmAlert defaults, so app-wide unstyled or classNames never reach it by surprise.
|
|
5
|
+
*/
|
|
6
|
+
export declare function styleLayers(options: StyleOptions, legacy: boolean): StyleOptions[];
|
|
7
|
+
export declare function classFor(slot: DialogSlot, layers: readonly StyleOptions[], extra?: string): string | undefined;
|
|
8
|
+
export type SlotProps = (slot: DialogSlot, extra?: string) => {
|
|
9
|
+
className: string | undefined;
|
|
10
|
+
'data-slot': DialogSlot;
|
|
11
|
+
};
|
|
12
|
+
export declare const slotsFor: (layers: readonly StyleOptions[]) => SlotProps;
|
|
13
|
+
export declare const SlotContext: import("react").Context<SlotProps>;
|
|
14
|
+
export declare const useSlot: () => SlotProps;
|
|
15
|
+
export declare function configureDialogs(defaults: DialogDefaults): void;
|
|
16
|
+
export type { DialogClassNames };
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { Component, type ButtonHTMLAttributes, type ReactElement, type ReactNode } from 'react';
|
|
2
|
+
import type { DialogClassNames, Strategy } from './types';
|
|
3
|
+
export type ReactConfirmAlertButton = {
|
|
4
|
+
label: string;
|
|
5
|
+
className?: string;
|
|
6
|
+
} & ButtonHTMLAttributes<HTMLButtonElement>;
|
|
7
|
+
export interface ReactConfirmAlertProps {
|
|
8
|
+
targetId?: string;
|
|
9
|
+
title?: string;
|
|
10
|
+
message?: string;
|
|
11
|
+
buttons?: Array<ReactConfirmAlertButton>;
|
|
12
|
+
childrenElement?: () => ReactNode;
|
|
13
|
+
customUI?: (customUiOptions: {
|
|
14
|
+
title: string;
|
|
15
|
+
message: string;
|
|
16
|
+
buttons: Array<ReactConfirmAlertButton>;
|
|
17
|
+
onClose: () => void;
|
|
18
|
+
}) => ReactNode;
|
|
19
|
+
closeOnClickOutside?: boolean;
|
|
20
|
+
closeOnEscape?: boolean;
|
|
21
|
+
/** @deprecated use onKeyDown with the new API */
|
|
22
|
+
keyCodeForClose?: Array<number>;
|
|
23
|
+
willUnmount?: () => void;
|
|
24
|
+
afterClose?: () => void;
|
|
25
|
+
onClickOutside?: () => void;
|
|
26
|
+
onKeypressEscape?: (event: KeyboardEvent) => void;
|
|
27
|
+
/** @deprecated use onKeyDown with the new API */
|
|
28
|
+
onkeyPress?: (event: KeyboardEvent, close: () => void) => void;
|
|
29
|
+
overlayClassName?: string;
|
|
30
|
+
/** render a native modal <dialog> in the top layer instead of the v3 overlay (default false) */
|
|
31
|
+
modal?: boolean;
|
|
32
|
+
/** what happens to a dialog that is already open (default 'replace', as in v3) */
|
|
33
|
+
strategy?: Strategy;
|
|
34
|
+
/** leave out the v3 class names */
|
|
35
|
+
unstyled?: boolean;
|
|
36
|
+
/** classes per slot, added after the app defaults */
|
|
37
|
+
classNames?: DialogClassNames;
|
|
38
|
+
}
|
|
39
|
+
export type ConfirmAlertOptions = ReactConfirmAlertProps;
|
|
40
|
+
export declare function confirmAlert(properties: ReactConfirmAlertProps): void;
|
|
41
|
+
/**
|
|
42
|
+
* Rendered in place, open while mounted. The parent unmounts it from a button's onClick.
|
|
43
|
+
* @deprecated use <ConfirmDialog open>
|
|
44
|
+
*/
|
|
45
|
+
export default class ReactConfirmAlert extends Component<ReactConfirmAlertProps> {
|
|
46
|
+
componentWillUnmount(): void;
|
|
47
|
+
render(): ReactElement;
|
|
48
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export { confirmAlert, default } from './compat';
|
|
2
|
+
export type { ConfirmAlertOptions, ReactConfirmAlertButton, ReactConfirmAlertProps } from './compat';
|
|
3
|
+
export { alert, closeAll, closeDialog, confirm, openDialog, prompt } from './api';
|
|
4
|
+
export { DialogHost, useDialog } from './DialogHost';
|
|
5
|
+
export { configureDialogs } from './classNames';
|
|
6
|
+
export type { DialogHostProps } from './DialogHost';
|
|
7
|
+
export { ConfirmDialog, Dialog } from './Dialog';
|
|
8
|
+
export type { ConfirmDialogProps, DialogProps } from './Dialog';
|
|
9
|
+
export type { AlertOptions, BaseOptions, ButtonContext, ButtonDataAttributes, DialogClassNames, DialogDataAttributes, DialogDefaults, DialogSlot, SlotDataAttributes, StyleOptions, ConfirmOptions, CustomOptions, DialogButton, DialogHandle, DialogId, DialogKind, DialogRenderProps, PromptOptions, Strategy } from './types';
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { DialogId, EntryOptions, Strategy } from './types';
|
|
2
|
+
export declare function registerFrame(id: DialogId, frame: HTMLElement | null, panel: HTMLElement | null): void;
|
|
3
|
+
export declare function openEntry(options: EntryOptions, target: string | null, strategy: Strategy, settle?: (result: unknown) => void): DialogId;
|
|
4
|
+
export declare function closeDialog(id: DialogId, { sync }?: {
|
|
5
|
+
sync?: boolean | undefined;
|
|
6
|
+
}): void;
|
|
7
|
+
export declare function reopenClosedFrames(): void;
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import type { Root } from 'react-dom/client';
|
|
2
|
+
import type { DialogDefaults, DialogId, EntryOptions, Strategy } from './types';
|
|
3
|
+
export type Phase = 'queued' | 'open' | 'closing';
|
|
4
|
+
export interface Entry {
|
|
5
|
+
id: DialogId;
|
|
6
|
+
options: EntryOptions;
|
|
7
|
+
phase: Phase;
|
|
8
|
+
/** id of the element the dialog renders into, or null for the default container */
|
|
9
|
+
target: string | null;
|
|
10
|
+
/** v3 blurs body.children[0] only when the library created the default container */
|
|
11
|
+
blur: boolean;
|
|
12
|
+
settle: (result: unknown) => void;
|
|
13
|
+
}
|
|
14
|
+
export interface StoreState {
|
|
15
|
+
entries: readonly Entry[];
|
|
16
|
+
/** mounted DialogHosts; the last one renders the default container's dialogs */
|
|
17
|
+
hosts: readonly symbol[];
|
|
18
|
+
}
|
|
19
|
+
export declare const emptyState: StoreState;
|
|
20
|
+
export declare function push(state: StoreState, entry: Omit<Entry, 'phase'>, strategy: Strategy): StoreState;
|
|
21
|
+
export declare function beginClose(state: StoreState, id: DialogId): StoreState;
|
|
22
|
+
export declare function remove(state: StoreState, id: DialogId): StoreState;
|
|
23
|
+
export declare function update(state: StoreState, id: DialogId, patch: Partial<EntryOptions>): StoreState;
|
|
24
|
+
export declare function addHost(state: StoreState, host: symbol): StoreState;
|
|
25
|
+
export declare function removeHost(state: StoreState, host: symbol): StoreState;
|
|
26
|
+
export declare function promoteQueued(state: StoreState): StoreState;
|
|
27
|
+
export declare function topmost(state: StoreState): Entry | undefined;
|
|
28
|
+
export interface Store {
|
|
29
|
+
get: () => StoreState;
|
|
30
|
+
set: (next: StoreState) => void;
|
|
31
|
+
subscribe: (listener: () => void) => () => void;
|
|
32
|
+
nextId: () => DialogId;
|
|
33
|
+
}
|
|
34
|
+
interface Container {
|
|
35
|
+
element: HTMLElement;
|
|
36
|
+
root: Root;
|
|
37
|
+
created: boolean;
|
|
38
|
+
}
|
|
39
|
+
export interface Runtime {
|
|
40
|
+
state: StoreState;
|
|
41
|
+
counter: number;
|
|
42
|
+
listeners: Set<() => void>;
|
|
43
|
+
containers: Map<string | null, Container>;
|
|
44
|
+
frames: Map<DialogId, {
|
|
45
|
+
frame: HTMLElement;
|
|
46
|
+
panel: HTMLElement | null;
|
|
47
|
+
}>;
|
|
48
|
+
blurred: Element | null;
|
|
49
|
+
/** dialogs whose button is waiting on a Promise; Escape and outside clicks wait too */
|
|
50
|
+
busy: Set<DialogId>;
|
|
51
|
+
pageSynced: boolean;
|
|
52
|
+
/** open <Dialog> and <ConfirmDialog> elements, which live outside the store but lock scroll too */
|
|
53
|
+
inPlace: number;
|
|
54
|
+
defaults: DialogDefaults;
|
|
55
|
+
watchingContainers: boolean;
|
|
56
|
+
}
|
|
57
|
+
export declare function runtime(): Runtime;
|
|
58
|
+
export declare const store: Store;
|
|
59
|
+
export {};
|