react-confirm-alert 3.1.0 → 3.2.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 +5 -5
- package/dist/index.esm.js +11 -3
- package/lib/index.js +11 -3
- package/package.json +3 -2
- package/src/react-confirm-alert.css +189 -0
- package/style.css +316 -0
package/Readme.md
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
# react-confirm-alert
|
|
2
2
|
|
|
3
|
-
Confirm, alert and prompt dialogs for React 18 and 19. `await confirm()`, a native modal, focus that moves in and back, and the
|
|
3
|
+
Confirm, alert and prompt dialogs for React 18 and 19. `await confirm()`, a native modal, focus that moves in and back, and the 3.0 `confirmAlert` unchanged.
|
|
4
4
|
|
|
5
5
|
[](https://badge.fury.io/js/react-confirm-alert)
|
|
6
6
|
|
|
7
|
-
[Docs](https://ga-mo.github.io/react-confirm-alert/docs/) · [Playground](https://ga-mo.github.io/react-confirm-alert/playground/) · [
|
|
7
|
+
[Docs](https://ga-mo.github.io/react-confirm-alert/docs/) · [Playground](https://ga-mo.github.io/react-confirm-alert/playground/) · [What's new in 3.1](https://ga-mo.github.io/react-confirm-alert/docs/whats-new-in-3-1/)
|
|
8
8
|
|
|
9
9
|
## Install
|
|
10
10
|
|
|
@@ -25,7 +25,7 @@ if (await confirm({ title: 'Delete file?', message: 'This cannot be undone.', to
|
|
|
25
25
|
|
|
26
26
|
`confirm()` resolves `true` or `false`. `alert()` and `prompt()` work the same way, and `<DialogHost />` placed inside your providers lets dialogs read their context.
|
|
27
27
|
|
|
28
|
-
##
|
|
28
|
+
## 3.0 code keeps working
|
|
29
29
|
|
|
30
30
|
```jsx
|
|
31
31
|
import { confirmAlert } from 'react-confirm-alert'
|
|
@@ -41,7 +41,7 @@ confirmAlert({
|
|
|
41
41
|
})
|
|
42
42
|
```
|
|
43
43
|
|
|
44
|
-
Same options, DOM, class names and CSS path as
|
|
44
|
+
Same options, DOM, class names and CSS path as 3.0.
|
|
45
45
|
|
|
46
46
|
## Tailwind CSS
|
|
47
47
|
|
|
@@ -64,7 +64,7 @@ Importing the CSS into `layer(components)` lets Tailwind utilities win without `
|
|
|
64
64
|
| `import { confirm }` | 3,851 B |
|
|
65
65
|
| CSS | 1,095 B |
|
|
66
66
|
|
|
67
|
-
Measured on 2026-10-23 with size-limit 14.3.0 (`npx size-limit`, config in `.size-limit.json`): the ESM build bundled and minified with React and React DOM excluded, then gzipped.
|
|
67
|
+
Measured on 2026-10-23 with size-limit 14.3.0 (`npx size-limit`, config in `.size-limit.json`): the ESM build bundled and minified with React and React DOM excluded, then gzipped. 3.0.6 measured the same way is 2,396 B, including `prop-types`. The extra bytes are the native modal, focus handling, stacked and queued dialogs, and dialogs that render inside your providers.
|
|
68
68
|
|
|
69
69
|
## Older versions
|
|
70
70
|
|
package/dist/index.esm.js
CHANGED
|
@@ -348,7 +348,7 @@ function closeDialog$1(id, { sync = true } = {}) {
|
|
|
348
348
|
commit(() => store.set(remove(store.get(), id)), sync);
|
|
349
349
|
return;
|
|
350
350
|
}
|
|
351
|
-
Promise.all(exits.map((a) => a.finished)).
|
|
351
|
+
Promise.all(exits.map((a) => a.finished.catch(() => {}))).then(() => store.set(remove(store.get(), id)));
|
|
352
352
|
}
|
|
353
353
|
var reopenQueued = false;
|
|
354
354
|
function reopenClosedFrames() {
|
|
@@ -440,7 +440,10 @@ function DialogFrame(props) {
|
|
|
440
440
|
const isBusy = () => !!props.id && runtime().busy.has(props.id);
|
|
441
441
|
const onKeyDown = (e) => {
|
|
442
442
|
var _props$onKeyDown;
|
|
443
|
-
(_props$onKeyDown = props.onKeyDown) === null || _props$onKeyDown === void 0 || _props$onKeyDown.call(props, e,
|
|
443
|
+
(_props$onKeyDown = props.onKeyDown) === null || _props$onKeyDown === void 0 || _props$onKeyDown.call(props, e, () => {
|
|
444
|
+
e.preventDefault();
|
|
445
|
+
props.onDismiss();
|
|
446
|
+
});
|
|
444
447
|
if (!native && !props.legacy && e.key === "Escape" && props.closeOnEscape && !isBusy()) props.onDismiss();
|
|
445
448
|
};
|
|
446
449
|
const slot = slotsFor(props.layers);
|
|
@@ -453,6 +456,7 @@ function DialogFrame(props) {
|
|
|
453
456
|
"data-rca": "",
|
|
454
457
|
"data-state": props.state,
|
|
455
458
|
"data-kind": props.kind,
|
|
459
|
+
"data-skin": props.legacy ? void 0 : "",
|
|
456
460
|
"data-tone": (_props$tone = props.tone) !== null && _props$tone !== void 0 ? _props$tone : "default",
|
|
457
461
|
"data-depth": String((_props$depth = props.depth) !== null && _props$depth !== void 0 ? _props$depth : 0),
|
|
458
462
|
"data-topmost": ((_props$topmost = props.topmost) !== null && _props$topmost !== void 0 ? _props$topmost : true) ? "" : void 0,
|
|
@@ -510,7 +514,11 @@ function LegacyContent({ props, titleId, close, id }) {
|
|
|
510
514
|
const keyboard = (event) => {
|
|
511
515
|
var _topmost, _props$keyCodeForClos, _props$closeOnEscape, _props$onkeyPress;
|
|
512
516
|
if (id && ((_topmost = topmost(store.get())) === null || _topmost === void 0 ? void 0 : _topmost.id) !== id) return;
|
|
513
|
-
const { props
|
|
517
|
+
const { props } = latest.current;
|
|
518
|
+
const close = () => {
|
|
519
|
+
event.preventDefault();
|
|
520
|
+
latest.current.close();
|
|
521
|
+
};
|
|
514
522
|
const keyCode = event.keyCode;
|
|
515
523
|
if (((_props$keyCodeForClos = props.keyCodeForClose) !== null && _props$keyCodeForClos !== void 0 ? _props$keyCodeForClos : []).includes(keyCode)) close();
|
|
516
524
|
if (((_props$closeOnEscape = props.closeOnEscape) !== null && _props$closeOnEscape !== void 0 ? _props$closeOnEscape : true) && keyCode === 27) {
|
package/lib/index.js
CHANGED
|
@@ -352,7 +352,7 @@ function closeDialog$1(id, { sync = true } = {}) {
|
|
|
352
352
|
commit(() => store.set(remove(store.get(), id)), sync);
|
|
353
353
|
return;
|
|
354
354
|
}
|
|
355
|
-
Promise.all(exits.map((a) => a.finished)).
|
|
355
|
+
Promise.all(exits.map((a) => a.finished.catch(() => {}))).then(() => store.set(remove(store.get(), id)));
|
|
356
356
|
}
|
|
357
357
|
var reopenQueued = false;
|
|
358
358
|
function reopenClosedFrames() {
|
|
@@ -444,7 +444,10 @@ function DialogFrame(props) {
|
|
|
444
444
|
const isBusy = () => !!props.id && runtime().busy.has(props.id);
|
|
445
445
|
const onKeyDown = (e) => {
|
|
446
446
|
var _props$onKeyDown;
|
|
447
|
-
(_props$onKeyDown = props.onKeyDown) === null || _props$onKeyDown === void 0 || _props$onKeyDown.call(props, e,
|
|
447
|
+
(_props$onKeyDown = props.onKeyDown) === null || _props$onKeyDown === void 0 || _props$onKeyDown.call(props, e, () => {
|
|
448
|
+
e.preventDefault();
|
|
449
|
+
props.onDismiss();
|
|
450
|
+
});
|
|
448
451
|
if (!native && !props.legacy && e.key === "Escape" && props.closeOnEscape && !isBusy()) props.onDismiss();
|
|
449
452
|
};
|
|
450
453
|
const slot = slotsFor(props.layers);
|
|
@@ -457,6 +460,7 @@ function DialogFrame(props) {
|
|
|
457
460
|
"data-rca": "",
|
|
458
461
|
"data-state": props.state,
|
|
459
462
|
"data-kind": props.kind,
|
|
463
|
+
"data-skin": props.legacy ? void 0 : "",
|
|
460
464
|
"data-tone": (_props$tone = props.tone) !== null && _props$tone !== void 0 ? _props$tone : "default",
|
|
461
465
|
"data-depth": String((_props$depth = props.depth) !== null && _props$depth !== void 0 ? _props$depth : 0),
|
|
462
466
|
"data-topmost": ((_props$topmost = props.topmost) !== null && _props$topmost !== void 0 ? _props$topmost : true) ? "" : void 0,
|
|
@@ -514,7 +518,11 @@ function LegacyContent({ props, titleId, close, id }) {
|
|
|
514
518
|
const keyboard = (event) => {
|
|
515
519
|
var _topmost, _props$keyCodeForClos, _props$closeOnEscape, _props$onkeyPress;
|
|
516
520
|
if (id && ((_topmost = topmost(store.get())) === null || _topmost === void 0 ? void 0 : _topmost.id) !== id) return;
|
|
517
|
-
const { props
|
|
521
|
+
const { props } = latest.current;
|
|
522
|
+
const close = () => {
|
|
523
|
+
event.preventDefault();
|
|
524
|
+
latest.current.close();
|
|
525
|
+
};
|
|
518
526
|
const keyCode = event.keyCode;
|
|
519
527
|
if (((_props$keyCodeForClos = props.keyCodeForClose) !== null && _props$keyCodeForClos !== void 0 ? _props$keyCodeForClos : []).includes(keyCode)) close();
|
|
520
528
|
if (((_props$closeOnEscape = props.closeOnEscape) !== null && _props$closeOnEscape !== void 0 ? _props$closeOnEscape : true) && keyCode === 27) {
|
package/package.json
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-confirm-alert",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.2.0",
|
|
4
4
|
"description": "react component confirm dialog.",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"module": "dist/index.esm.js",
|
|
7
7
|
"scripts": {
|
|
8
|
-
"build": "vite build && node -e \"require('fs').rmSync('typings',{recursive:true,force:true})\" && tsc -p tsconfig.build.json",
|
|
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
9
|
"prepublishOnly": "npm run build",
|
|
10
10
|
"test": "vitest run",
|
|
11
11
|
"test:fixtures": "node fixtures/run.mjs",
|
|
@@ -42,6 +42,7 @@
|
|
|
42
42
|
"dist",
|
|
43
43
|
"typings",
|
|
44
44
|
"src/react-confirm-alert.css",
|
|
45
|
+
"style.css",
|
|
45
46
|
"index.d.ts"
|
|
46
47
|
],
|
|
47
48
|
"devDependencies": {
|
|
@@ -32,6 +32,8 @@ body.react-confirm-alert-body-element {
|
|
|
32
32
|
border-radius: var(--rca-radius, 10px);
|
|
33
33
|
box-shadow: var(--rca-shadow, 0 20px 75px rgba(0, 0, 0, 0.13));
|
|
34
34
|
color: var(--rca-fg, #666);
|
|
35
|
+
/* confirmAlert renders message as text right in the body; keep its line breaks (#38). */
|
|
36
|
+
white-space: pre-line;
|
|
35
37
|
}
|
|
36
38
|
|
|
37
39
|
.react-confirm-alert-body > h1 {
|
|
@@ -125,3 +127,190 @@ dialog.react-confirm-alert-overlay::backdrop {
|
|
|
125
127
|
opacity: 1;
|
|
126
128
|
}
|
|
127
129
|
}
|
|
130
|
+
|
|
131
|
+
/* The default look of every dialog except confirmAlert, which has no data-skin and keeps the 3.0 look above; unstyled drops the overlay class, so none of this applies.
|
|
132
|
+
--_* are internal defaults: a --rca-* variable set by the app always wins over them. */
|
|
133
|
+
.react-confirm-alert-overlay[data-skin] {
|
|
134
|
+
--_bg: #fff;
|
|
135
|
+
--_fg: #71717a;
|
|
136
|
+
--_title: #09090b;
|
|
137
|
+
--_border: #e4e4e7;
|
|
138
|
+
--_hover: #f4f4f5;
|
|
139
|
+
--_primary: #18181b;
|
|
140
|
+
--_primary-fg: #fff;
|
|
141
|
+
--_ring: #a1a1aa;
|
|
142
|
+
--_danger: #dc2626;
|
|
143
|
+
--_error: #dc2626;
|
|
144
|
+
box-sizing: border-box;
|
|
145
|
+
padding: 16px;
|
|
146
|
+
background: var(--rca-backdrop, rgba(0, 0, 0, 0.5));
|
|
147
|
+
opacity: 1;
|
|
148
|
+
animation: rca-in var(--rca-duration, 200ms) var(--rca-easing, cubic-bezier(0.32, 0.72, 0, 1)) both;
|
|
149
|
+
}
|
|
150
|
+
/* Dark is opt-in: the app's .dark class or data-theme="dark" on an ancestor, usually <html>. */
|
|
151
|
+
:is(.dark, [data-theme=dark]) .react-confirm-alert-overlay[data-skin] {
|
|
152
|
+
--_bg: #18181b;
|
|
153
|
+
--_fg: #a1a1aa;
|
|
154
|
+
--_title: #fafafa;
|
|
155
|
+
--_border: #3f3f46;
|
|
156
|
+
--_hover: #27272a;
|
|
157
|
+
--_primary: #fafafa;
|
|
158
|
+
--_primary-fg: #18181b;
|
|
159
|
+
--_ring: #71717a;
|
|
160
|
+
--_error: #f87171;
|
|
161
|
+
background: var(--rca-backdrop, rgba(0, 0, 0, 0.7));
|
|
162
|
+
}
|
|
163
|
+
.react-confirm-alert-overlay[data-skin] .react-confirm-alert {
|
|
164
|
+
max-width: 100%;
|
|
165
|
+
animation: rca-pop var(--rca-duration, 200ms) var(--rca-easing, cubic-bezier(0.32, 0.72, 0, 1)) both;
|
|
166
|
+
}
|
|
167
|
+
.react-confirm-alert-overlay[data-skin] .react-confirm-alert-body {
|
|
168
|
+
box-sizing: border-box;
|
|
169
|
+
width: var(--rca-width, 420px);
|
|
170
|
+
max-width: 100%;
|
|
171
|
+
padding: var(--rca-padding, 24px);
|
|
172
|
+
border: 1px solid var(--rca-border, var(--_border));
|
|
173
|
+
border-radius: var(--rca-radius, 10px);
|
|
174
|
+
background: var(--rca-bg, var(--_bg));
|
|
175
|
+
box-shadow: var(--rca-shadow, 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -4px rgba(0, 0, 0, 0.1));
|
|
176
|
+
color: var(--rca-fg, var(--_fg));
|
|
177
|
+
font-family: var(--rca-font, inherit);
|
|
178
|
+
font-size: 14px;
|
|
179
|
+
line-height: 1.5;
|
|
180
|
+
}
|
|
181
|
+
.react-confirm-alert-overlay[data-skin][data-state=closing] {
|
|
182
|
+
animation: rca-out 150ms ease-in both;
|
|
183
|
+
}
|
|
184
|
+
.react-confirm-alert-overlay[data-skin][data-state=closing] .react-confirm-alert {
|
|
185
|
+
animation: rca-pop-out 150ms ease-in both;
|
|
186
|
+
}
|
|
187
|
+
.react-confirm-alert-overlay[data-skin] [data-slot=title] {
|
|
188
|
+
margin: 0 0 8px;
|
|
189
|
+
font-size: 18px;
|
|
190
|
+
font-weight: 600;
|
|
191
|
+
line-height: 1.3;
|
|
192
|
+
letter-spacing: -0.01em;
|
|
193
|
+
color: var(--rca-title, var(--_title));
|
|
194
|
+
}
|
|
195
|
+
.react-confirm-alert-overlay[data-skin] [data-slot=field] {
|
|
196
|
+
margin-top: 16px;
|
|
197
|
+
}
|
|
198
|
+
.react-confirm-alert-overlay[data-skin] [data-slot=label] {
|
|
199
|
+
display: block;
|
|
200
|
+
margin-bottom: 6px;
|
|
201
|
+
font-size: 13px;
|
|
202
|
+
font-weight: 500;
|
|
203
|
+
color: var(--rca-title, var(--_title));
|
|
204
|
+
}
|
|
205
|
+
.react-confirm-alert-overlay[data-skin] [data-slot=input] {
|
|
206
|
+
box-sizing: border-box;
|
|
207
|
+
width: 100%;
|
|
208
|
+
height: 36px;
|
|
209
|
+
padding: 0 12px;
|
|
210
|
+
border: 1px solid var(--rca-border, var(--_border));
|
|
211
|
+
border-radius: 6px;
|
|
212
|
+
background: transparent;
|
|
213
|
+
color: var(--rca-title, var(--_title));
|
|
214
|
+
font: inherit;
|
|
215
|
+
outline: none;
|
|
216
|
+
transition: border-color 150ms, box-shadow 150ms;
|
|
217
|
+
}
|
|
218
|
+
.react-confirm-alert-overlay[data-skin] [data-slot=input]:focus {
|
|
219
|
+
border-color: var(--rca-ring, var(--_ring));
|
|
220
|
+
box-shadow: 0 0 0 3px color-mix(in srgb, var(--rca-ring, var(--_ring)) 50%, transparent);
|
|
221
|
+
}
|
|
222
|
+
.react-confirm-alert-overlay[data-skin] [data-slot=input][aria-invalid=true] {
|
|
223
|
+
border-color: var(--rca-danger, var(--_error));
|
|
224
|
+
box-shadow: 0 0 0 3px color-mix(in srgb, var(--rca-danger, var(--_error)) 20%, transparent);
|
|
225
|
+
}
|
|
226
|
+
.react-confirm-alert-overlay[data-skin] [data-slot=error] {
|
|
227
|
+
margin: 6px 0 0;
|
|
228
|
+
font-size: 13px;
|
|
229
|
+
color: var(--rca-danger, var(--_error));
|
|
230
|
+
}
|
|
231
|
+
.react-confirm-alert-overlay[data-skin] .react-confirm-alert-button-group {
|
|
232
|
+
justify-content: flex-end;
|
|
233
|
+
gap: var(--rca-gap, 8px);
|
|
234
|
+
margin-top: 24px;
|
|
235
|
+
}
|
|
236
|
+
.react-confirm-alert-overlay[data-skin] .react-confirm-alert-button-group > button {
|
|
237
|
+
display: inline-flex;
|
|
238
|
+
align-items: center;
|
|
239
|
+
justify-content: center;
|
|
240
|
+
gap: 8px;
|
|
241
|
+
height: 36px;
|
|
242
|
+
margin: 0;
|
|
243
|
+
padding: 0 16px;
|
|
244
|
+
border: 1px solid var(--rca-border, var(--_border));
|
|
245
|
+
border-radius: var(--rca-button-radius, 6px);
|
|
246
|
+
background: var(--rca-bg, var(--_bg));
|
|
247
|
+
color: var(--rca-title, var(--_title));
|
|
248
|
+
font-family: inherit;
|
|
249
|
+
font-size: 14px;
|
|
250
|
+
font-weight: 500;
|
|
251
|
+
line-height: 1;
|
|
252
|
+
white-space: nowrap;
|
|
253
|
+
transition: background-color 150ms, transform 150ms;
|
|
254
|
+
}
|
|
255
|
+
.react-confirm-alert-overlay[data-skin] .react-confirm-alert-button-group > button:hover {
|
|
256
|
+
background: var(--_hover);
|
|
257
|
+
}
|
|
258
|
+
.react-confirm-alert-overlay[data-skin] .react-confirm-alert-button-group > [data-variant=primary] {
|
|
259
|
+
border-color: transparent;
|
|
260
|
+
background: var(--rca-button-bg, var(--_primary));
|
|
261
|
+
color: var(--rca-button-fg, var(--_primary-fg));
|
|
262
|
+
}
|
|
263
|
+
.react-confirm-alert-overlay[data-skin] .react-confirm-alert-button-group > [data-variant=danger] {
|
|
264
|
+
border-color: transparent;
|
|
265
|
+
background: var(--rca-danger, var(--_danger));
|
|
266
|
+
color: #fff;
|
|
267
|
+
}
|
|
268
|
+
.react-confirm-alert-overlay[data-skin] .react-confirm-alert-button-group > :is([data-variant=primary],[data-variant=danger]):hover {
|
|
269
|
+
opacity: 0.9;
|
|
270
|
+
}
|
|
271
|
+
.react-confirm-alert-overlay[data-skin] .react-confirm-alert-button-group > button:active {
|
|
272
|
+
transform: scale(0.97);
|
|
273
|
+
}
|
|
274
|
+
.react-confirm-alert-overlay[data-skin] .react-confirm-alert-button-group > button:focus-visible {
|
|
275
|
+
outline: var(--rca-focus-ring, 2px solid var(--_ring));
|
|
276
|
+
outline-offset: 2px;
|
|
277
|
+
}
|
|
278
|
+
.react-confirm-alert-overlay[data-skin] .react-confirm-alert-button-group > button:disabled {
|
|
279
|
+
cursor: default;
|
|
280
|
+
opacity: 0.6;
|
|
281
|
+
}
|
|
282
|
+
.react-confirm-alert-overlay[data-skin] .react-confirm-alert-button-group > button[aria-busy=true] {
|
|
283
|
+
cursor: progress;
|
|
284
|
+
opacity: 1;
|
|
285
|
+
}
|
|
286
|
+
.react-confirm-alert-overlay[data-skin] .react-confirm-alert-button-group > button[aria-busy=true]::before {
|
|
287
|
+
content: '';
|
|
288
|
+
width: 12px;
|
|
289
|
+
height: 12px;
|
|
290
|
+
border: 2px solid currentColor;
|
|
291
|
+
border-right-color: transparent;
|
|
292
|
+
border-radius: 50%;
|
|
293
|
+
animation: rca-spin 700ms linear infinite;
|
|
294
|
+
}
|
|
295
|
+
@media (max-width: 480px) {
|
|
296
|
+
.react-confirm-alert-overlay[data-skin] .react-confirm-alert-button-group {
|
|
297
|
+
flex-direction: column-reverse;
|
|
298
|
+
}
|
|
299
|
+
.react-confirm-alert-overlay[data-skin] .react-confirm-alert-button-group > button {
|
|
300
|
+
height: 40px;
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
@media (prefers-reduced-motion: reduce) {
|
|
304
|
+
.react-confirm-alert-overlay[data-skin],
|
|
305
|
+
.react-confirm-alert-overlay[data-skin] .react-confirm-alert {
|
|
306
|
+
animation: none;
|
|
307
|
+
}
|
|
308
|
+
.react-confirm-alert-overlay[data-skin] .react-confirm-alert-button-group > button {
|
|
309
|
+
transition: none;
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
@keyframes rca-in { from { opacity: 0; } }
|
|
313
|
+
@keyframes rca-out { to { opacity: 0; } }
|
|
314
|
+
@keyframes rca-pop { from { opacity: 0; transform: scale(0.95); } }
|
|
315
|
+
@keyframes rca-pop-out { to { opacity: 0; transform: scale(0.95); } }
|
|
316
|
+
@keyframes rca-spin { to { transform: rotate(360deg); } }
|
package/style.css
ADDED
|
@@ -0,0 +1,316 @@
|
|
|
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
|
+
/* confirmAlert renders message as text right in the body; keep its line breaks (#38). */
|
|
36
|
+
white-space: pre-line;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
.react-confirm-alert-body > h1 {
|
|
40
|
+
margin-top: 0;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
.react-confirm-alert-body > h3 {
|
|
44
|
+
margin: 0;
|
|
45
|
+
font-size: 16px;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
.react-confirm-alert-button-group {
|
|
49
|
+
display: flex;
|
|
50
|
+
justify-content: flex-start;
|
|
51
|
+
margin-top: 20px;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
.react-confirm-alert-button-group > button {
|
|
55
|
+
outline: none;
|
|
56
|
+
background: var(--rca-button-bg, #333);
|
|
57
|
+
border: none;
|
|
58
|
+
display: inline-block;
|
|
59
|
+
padding: 6px 18px;
|
|
60
|
+
color: var(--rca-button-fg, #eee);
|
|
61
|
+
margin-right: var(--rca-gap, 10px);
|
|
62
|
+
border-radius: var(--rca-button-radius, 5px);
|
|
63
|
+
font-size: 12px;
|
|
64
|
+
cursor: pointer;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/* Keyboard focus is visible again (B15); a mouse click shows no ring. */
|
|
68
|
+
.react-confirm-alert-button-group > button:focus-visible {
|
|
69
|
+
outline: var(--rca-focus-ring, 2px solid Highlight);
|
|
70
|
+
outline-offset: 2px;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/* modal: true renders the overlay as a <dialog> in the top layer. Reset the browser's dialog box so it
|
|
74
|
+
looks like the v3 overlay, and never set display while it is closed. */
|
|
75
|
+
dialog.react-confirm-alert-overlay {
|
|
76
|
+
width: 100%;
|
|
77
|
+
height: 100%;
|
|
78
|
+
max-width: none;
|
|
79
|
+
max-height: none;
|
|
80
|
+
margin: 0;
|
|
81
|
+
padding: 0;
|
|
82
|
+
border: 0;
|
|
83
|
+
color: inherit;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
dialog.react-confirm-alert-overlay:not([open]) {
|
|
87
|
+
display: none;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
dialog.react-confirm-alert-overlay::backdrop {
|
|
91
|
+
background: transparent;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
.react-confirm-alert-button-group > [data-variant='danger'] {
|
|
95
|
+
background: var(--rca-danger, #c62828);
|
|
96
|
+
color: #fff;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
[data-rca]:not([data-kind='custom']) [data-slot='title'] {
|
|
100
|
+
margin: 0 0 8px;
|
|
101
|
+
font-size: 1.25em;
|
|
102
|
+
font-weight: 600;
|
|
103
|
+
color: var(--rca-title, #222);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
.react-confirm-alert [data-slot='message'] {
|
|
107
|
+
margin: 0;
|
|
108
|
+
white-space: pre-line;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
.react-confirm-alert:focus {
|
|
112
|
+
outline: none;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
@media (prefers-reduced-motion: reduce) {
|
|
116
|
+
.react-confirm-alert-overlay {
|
|
117
|
+
animation: none;
|
|
118
|
+
opacity: 1;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
@keyframes react-confirm-alert-fadeIn {
|
|
123
|
+
from {
|
|
124
|
+
opacity: 0;
|
|
125
|
+
}
|
|
126
|
+
to {
|
|
127
|
+
opacity: 1;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/* The default look of every dialog except confirmAlert, which has no data-skin and keeps the 3.0 look above; unstyled drops the overlay class, so none of this applies.
|
|
132
|
+
--_* are internal defaults: a --rca-* variable set by the app always wins over them. */
|
|
133
|
+
.react-confirm-alert-overlay[data-skin] {
|
|
134
|
+
--_bg: #fff;
|
|
135
|
+
--_fg: #71717a;
|
|
136
|
+
--_title: #09090b;
|
|
137
|
+
--_border: #e4e4e7;
|
|
138
|
+
--_hover: #f4f4f5;
|
|
139
|
+
--_primary: #18181b;
|
|
140
|
+
--_primary-fg: #fff;
|
|
141
|
+
--_ring: #a1a1aa;
|
|
142
|
+
--_danger: #dc2626;
|
|
143
|
+
--_error: #dc2626;
|
|
144
|
+
box-sizing: border-box;
|
|
145
|
+
padding: 16px;
|
|
146
|
+
background: var(--rca-backdrop, rgba(0, 0, 0, 0.5));
|
|
147
|
+
opacity: 1;
|
|
148
|
+
animation: rca-in var(--rca-duration, 200ms) var(--rca-easing, cubic-bezier(0.32, 0.72, 0, 1)) both;
|
|
149
|
+
}
|
|
150
|
+
/* Dark is opt-in: the app's .dark class or data-theme="dark" on an ancestor, usually <html>. */
|
|
151
|
+
:is(.dark, [data-theme=dark]) .react-confirm-alert-overlay[data-skin] {
|
|
152
|
+
--_bg: #18181b;
|
|
153
|
+
--_fg: #a1a1aa;
|
|
154
|
+
--_title: #fafafa;
|
|
155
|
+
--_border: #3f3f46;
|
|
156
|
+
--_hover: #27272a;
|
|
157
|
+
--_primary: #fafafa;
|
|
158
|
+
--_primary-fg: #18181b;
|
|
159
|
+
--_ring: #71717a;
|
|
160
|
+
--_error: #f87171;
|
|
161
|
+
background: var(--rca-backdrop, rgba(0, 0, 0, 0.7));
|
|
162
|
+
}
|
|
163
|
+
.react-confirm-alert-overlay[data-skin] .react-confirm-alert {
|
|
164
|
+
max-width: 100%;
|
|
165
|
+
animation: rca-pop var(--rca-duration, 200ms) var(--rca-easing, cubic-bezier(0.32, 0.72, 0, 1)) both;
|
|
166
|
+
}
|
|
167
|
+
.react-confirm-alert-overlay[data-skin] .react-confirm-alert-body {
|
|
168
|
+
box-sizing: border-box;
|
|
169
|
+
width: var(--rca-width, 420px);
|
|
170
|
+
max-width: 100%;
|
|
171
|
+
padding: var(--rca-padding, 24px);
|
|
172
|
+
border: 1px solid var(--rca-border, var(--_border));
|
|
173
|
+
border-radius: var(--rca-radius, 10px);
|
|
174
|
+
background: var(--rca-bg, var(--_bg));
|
|
175
|
+
box-shadow: var(--rca-shadow, 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -4px rgba(0, 0, 0, 0.1));
|
|
176
|
+
color: var(--rca-fg, var(--_fg));
|
|
177
|
+
font-family: var(--rca-font, inherit);
|
|
178
|
+
font-size: 14px;
|
|
179
|
+
line-height: 1.5;
|
|
180
|
+
}
|
|
181
|
+
.react-confirm-alert-overlay[data-skin][data-state=closing] {
|
|
182
|
+
animation: rca-out 150ms ease-in both;
|
|
183
|
+
}
|
|
184
|
+
.react-confirm-alert-overlay[data-skin][data-state=closing] .react-confirm-alert {
|
|
185
|
+
animation: rca-pop-out 150ms ease-in both;
|
|
186
|
+
}
|
|
187
|
+
.react-confirm-alert-overlay[data-skin] [data-slot=title] {
|
|
188
|
+
margin: 0 0 8px;
|
|
189
|
+
font-size: 18px;
|
|
190
|
+
font-weight: 600;
|
|
191
|
+
line-height: 1.3;
|
|
192
|
+
letter-spacing: -0.01em;
|
|
193
|
+
color: var(--rca-title, var(--_title));
|
|
194
|
+
}
|
|
195
|
+
.react-confirm-alert-overlay[data-skin] [data-slot=field] {
|
|
196
|
+
margin-top: 16px;
|
|
197
|
+
}
|
|
198
|
+
.react-confirm-alert-overlay[data-skin] [data-slot=label] {
|
|
199
|
+
display: block;
|
|
200
|
+
margin-bottom: 6px;
|
|
201
|
+
font-size: 13px;
|
|
202
|
+
font-weight: 500;
|
|
203
|
+
color: var(--rca-title, var(--_title));
|
|
204
|
+
}
|
|
205
|
+
.react-confirm-alert-overlay[data-skin] [data-slot=input] {
|
|
206
|
+
box-sizing: border-box;
|
|
207
|
+
width: 100%;
|
|
208
|
+
height: 36px;
|
|
209
|
+
padding: 0 12px;
|
|
210
|
+
border: 1px solid var(--rca-border, var(--_border));
|
|
211
|
+
border-radius: 6px;
|
|
212
|
+
background: transparent;
|
|
213
|
+
color: var(--rca-title, var(--_title));
|
|
214
|
+
font: inherit;
|
|
215
|
+
outline: none;
|
|
216
|
+
transition: border-color 150ms, box-shadow 150ms;
|
|
217
|
+
}
|
|
218
|
+
.react-confirm-alert-overlay[data-skin] [data-slot=input]:focus {
|
|
219
|
+
border-color: var(--rca-ring, var(--_ring));
|
|
220
|
+
box-shadow: 0 0 0 3px color-mix(in srgb, var(--rca-ring, var(--_ring)) 50%, transparent);
|
|
221
|
+
}
|
|
222
|
+
.react-confirm-alert-overlay[data-skin] [data-slot=input][aria-invalid=true] {
|
|
223
|
+
border-color: var(--rca-danger, var(--_error));
|
|
224
|
+
box-shadow: 0 0 0 3px color-mix(in srgb, var(--rca-danger, var(--_error)) 20%, transparent);
|
|
225
|
+
}
|
|
226
|
+
.react-confirm-alert-overlay[data-skin] [data-slot=error] {
|
|
227
|
+
margin: 6px 0 0;
|
|
228
|
+
font-size: 13px;
|
|
229
|
+
color: var(--rca-danger, var(--_error));
|
|
230
|
+
}
|
|
231
|
+
.react-confirm-alert-overlay[data-skin] .react-confirm-alert-button-group {
|
|
232
|
+
justify-content: flex-end;
|
|
233
|
+
gap: var(--rca-gap, 8px);
|
|
234
|
+
margin-top: 24px;
|
|
235
|
+
}
|
|
236
|
+
.react-confirm-alert-overlay[data-skin] .react-confirm-alert-button-group > button {
|
|
237
|
+
display: inline-flex;
|
|
238
|
+
align-items: center;
|
|
239
|
+
justify-content: center;
|
|
240
|
+
gap: 8px;
|
|
241
|
+
height: 36px;
|
|
242
|
+
margin: 0;
|
|
243
|
+
padding: 0 16px;
|
|
244
|
+
border: 1px solid var(--rca-border, var(--_border));
|
|
245
|
+
border-radius: var(--rca-button-radius, 6px);
|
|
246
|
+
background: var(--rca-bg, var(--_bg));
|
|
247
|
+
color: var(--rca-title, var(--_title));
|
|
248
|
+
font-family: inherit;
|
|
249
|
+
font-size: 14px;
|
|
250
|
+
font-weight: 500;
|
|
251
|
+
line-height: 1;
|
|
252
|
+
white-space: nowrap;
|
|
253
|
+
transition: background-color 150ms, transform 150ms;
|
|
254
|
+
}
|
|
255
|
+
.react-confirm-alert-overlay[data-skin] .react-confirm-alert-button-group > button:hover {
|
|
256
|
+
background: var(--_hover);
|
|
257
|
+
}
|
|
258
|
+
.react-confirm-alert-overlay[data-skin] .react-confirm-alert-button-group > [data-variant=primary] {
|
|
259
|
+
border-color: transparent;
|
|
260
|
+
background: var(--rca-button-bg, var(--_primary));
|
|
261
|
+
color: var(--rca-button-fg, var(--_primary-fg));
|
|
262
|
+
}
|
|
263
|
+
.react-confirm-alert-overlay[data-skin] .react-confirm-alert-button-group > [data-variant=danger] {
|
|
264
|
+
border-color: transparent;
|
|
265
|
+
background: var(--rca-danger, var(--_danger));
|
|
266
|
+
color: #fff;
|
|
267
|
+
}
|
|
268
|
+
.react-confirm-alert-overlay[data-skin] .react-confirm-alert-button-group > :is([data-variant=primary],[data-variant=danger]):hover {
|
|
269
|
+
opacity: 0.9;
|
|
270
|
+
}
|
|
271
|
+
.react-confirm-alert-overlay[data-skin] .react-confirm-alert-button-group > button:active {
|
|
272
|
+
transform: scale(0.97);
|
|
273
|
+
}
|
|
274
|
+
.react-confirm-alert-overlay[data-skin] .react-confirm-alert-button-group > button:focus-visible {
|
|
275
|
+
outline: var(--rca-focus-ring, 2px solid var(--_ring));
|
|
276
|
+
outline-offset: 2px;
|
|
277
|
+
}
|
|
278
|
+
.react-confirm-alert-overlay[data-skin] .react-confirm-alert-button-group > button:disabled {
|
|
279
|
+
cursor: default;
|
|
280
|
+
opacity: 0.6;
|
|
281
|
+
}
|
|
282
|
+
.react-confirm-alert-overlay[data-skin] .react-confirm-alert-button-group > button[aria-busy=true] {
|
|
283
|
+
cursor: progress;
|
|
284
|
+
opacity: 1;
|
|
285
|
+
}
|
|
286
|
+
.react-confirm-alert-overlay[data-skin] .react-confirm-alert-button-group > button[aria-busy=true]::before {
|
|
287
|
+
content: '';
|
|
288
|
+
width: 12px;
|
|
289
|
+
height: 12px;
|
|
290
|
+
border: 2px solid currentColor;
|
|
291
|
+
border-right-color: transparent;
|
|
292
|
+
border-radius: 50%;
|
|
293
|
+
animation: rca-spin 700ms linear infinite;
|
|
294
|
+
}
|
|
295
|
+
@media (max-width: 480px) {
|
|
296
|
+
.react-confirm-alert-overlay[data-skin] .react-confirm-alert-button-group {
|
|
297
|
+
flex-direction: column-reverse;
|
|
298
|
+
}
|
|
299
|
+
.react-confirm-alert-overlay[data-skin] .react-confirm-alert-button-group > button {
|
|
300
|
+
height: 40px;
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
@media (prefers-reduced-motion: reduce) {
|
|
304
|
+
.react-confirm-alert-overlay[data-skin],
|
|
305
|
+
.react-confirm-alert-overlay[data-skin] .react-confirm-alert {
|
|
306
|
+
animation: none;
|
|
307
|
+
}
|
|
308
|
+
.react-confirm-alert-overlay[data-skin] .react-confirm-alert-button-group > button {
|
|
309
|
+
transition: none;
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
@keyframes rca-in { from { opacity: 0; } }
|
|
313
|
+
@keyframes rca-out { to { opacity: 0; } }
|
|
314
|
+
@keyframes rca-pop { from { opacity: 0; transform: scale(0.95); } }
|
|
315
|
+
@keyframes rca-pop-out { to { opacity: 0; transform: scale(0.95); } }
|
|
316
|
+
@keyframes rca-spin { to { transform: rotate(360deg); } }
|