react-confirm-lite 1.5.4 → 1.5.6
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 -644
- package/dist/index.d.ts +4 -2
- package/dist/index.js +13 -2
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -11,13 +11,6 @@
|
|
|
11
11
|
|
|
12
12
|

|
|
13
13
|
|
|
14
|
-
## What's new?
|
|
15
|
-
Just optimized, but now you will have to give an id to api and ConfirmContainer only if you're using multiple containers on the same page and want to show the specfic container when a specific api is called otherwise it will show the first rendered component. But one more thing if don't want to give the id and want to show the closest to the button then you can pass an argument to the api like this.
|
|
16
|
-
```ts
|
|
17
|
-
confirm('Are you sure?',true)
|
|
18
|
-
```
|
|
19
|
-
then it will show the closest otherwise will show the first rendered.
|
|
20
|
-
|
|
21
14
|
## 🔗 Live Demo
|
|
22
15
|
|
|
23
16
|
[](https://stackblitz.com/edit/vitejs-vite-bfthlpmw?file=src%2FApp.tsx)
|
|
@@ -76,641 +69,9 @@ One more thing that if you want to show the closest container to button to which
|
|
|
76
69
|
```ts
|
|
77
70
|
confirm('Are you sure?', true)
|
|
78
71
|
```
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
```tsx
|
|
84
|
-
const result = await confirm('Message here');
|
|
85
|
-
// Returns true for OK, false for Cancel, null for ESC/outside click
|
|
86
|
-
```
|
|
87
|
-
|
|
88
|
-
### ✅ 18 Built-in Animations
|
|
89
|
-
Choose from various animations:
|
|
90
|
-
- `slide` (default) - Smooth slide up/down
|
|
91
|
-
- `fadeScale` - Fade with scale effect
|
|
92
|
-
- `bounce` - Playful bounce animation
|
|
93
|
-
- `flip` - 3D flip effect
|
|
94
|
-
- `zoom` - Zoom in/out
|
|
95
|
-
- `rotate` - Rotate animation
|
|
96
|
-
- `fadeUp` / `fadeDown` - Directional fade
|
|
97
|
-
- `drop` - 3D drop effect
|
|
98
|
-
- `slideRight` / `slideLeft` - Horizontal slides
|
|
99
|
-
- `slideVertical` - Vertical slide
|
|
100
|
-
- `slideDown` - Slide down
|
|
101
|
-
- `rotateRight` - Rotate from right
|
|
102
|
-
- `zoomSmall` / `bounceSmall` - Subtle animations
|
|
103
|
-
- `fadeBlur` / `fadeShrink` - Creative effects
|
|
104
|
-
|
|
105
|
-
### ✅ 6 Color Schemes
|
|
106
|
-
Pre-built color themes:
|
|
107
|
-
- `dark` (default) - Dark theme
|
|
108
|
-
- `light` - Light theme
|
|
109
|
-
- `blue` - Blue theme
|
|
110
|
-
- `red` - Perfect for destructive actions
|
|
111
|
-
- `green` - Success actions
|
|
112
|
-
- `purple` - Premium/feature actions
|
|
113
|
-
|
|
114
|
-
### ✅ Interactive Controls
|
|
115
|
-
- `closeOnEscape` (default: true) - Press ESC to close
|
|
116
|
-
- `closeOnClickOutside` (default: true) - Click backdrop to close
|
|
117
|
-
- Returns `null` when closed via ESC or backdrop click
|
|
118
|
-
|
|
119
|
-
### ✅ Customizable Options
|
|
120
|
-
Control every aspect:
|
|
121
|
-
- Custom OK/Cancel button text
|
|
122
|
-
- Separate animation durations for enter/exit
|
|
123
|
-
- Override colors per dialog
|
|
124
|
-
- Custom CSS classes for all elements
|
|
125
|
-
|
|
126
|
-
### ✅ Queue System
|
|
127
|
-
Multiple confirm requests automatically queue and show one at a time:
|
|
128
|
-
```tsx
|
|
129
|
-
// These will show sequentially
|
|
130
|
-
await confirm('First?');
|
|
131
|
-
await confirm('Second?');
|
|
132
|
-
await confirm('Third?');
|
|
133
|
-
```
|
|
134
|
-
|
|
135
|
-
### ✅ Zero Configuration
|
|
136
|
-
No CSS imports needed. Styles are automatically injected.
|
|
137
|
-
|
|
138
|
-
## 🎨 Usage Examples
|
|
139
|
-
|
|
140
|
-
### Basic Usage
|
|
141
|
-
```tsx
|
|
142
|
-
const result = await confirm('Delete this item?');
|
|
143
|
-
if (result) {
|
|
144
|
-
// User clicked OK
|
|
145
|
-
deleteItem();
|
|
146
|
-
} else if (result === false) {
|
|
147
|
-
// User clicked Cancel
|
|
148
|
-
console.log('Cancelled');
|
|
149
|
-
} else if (result === null) {
|
|
150
|
-
// User pressed ESC or clicked outside
|
|
151
|
-
console.log('Closed via ESC/backdrop');
|
|
152
|
-
}
|
|
153
|
-
```
|
|
154
|
-
|
|
155
|
-
### Custom Dialog Options
|
|
156
|
-
```tsx
|
|
157
|
-
const result = await confirm({
|
|
158
|
-
title: 'Delete Account',
|
|
159
|
-
message: 'This will permanently delete your account and all data.',
|
|
160
|
-
okText: 'Delete Forever',
|
|
161
|
-
cancelText: 'Cancel',
|
|
162
|
-
colorSchema: 'red'
|
|
163
|
-
});
|
|
164
|
-
```
|
|
165
|
-
|
|
166
|
-
### Disable ESC and Backdrop Closing
|
|
167
|
-
```tsx
|
|
168
|
-
<ConfirmContainer
|
|
169
|
-
closeOnEscape={false}
|
|
170
|
-
closeOnClickOutside={false}
|
|
171
|
-
/>
|
|
172
|
-
// Now dialog can only be closed with Cancel/OK buttons
|
|
173
|
-
```
|
|
174
|
-
|
|
175
|
-
## 🔧 API Reference
|
|
176
|
-
|
|
177
|
-
### Confirm Container Props
|
|
178
|
-
|
|
179
|
-
| Prop | Type | Default | Description |
|
|
180
|
-
|------|------|---------|-------------|
|
|
181
|
-
|`id`|`string`| `random` | To show a specific container with a specific confirm() app |
|
|
182
|
-
| `animation` | `AnimationType` | `'slide'` | Animation type (18 options) |
|
|
183
|
-
| `animationDuration` | `number` | `300` | Base animation duration (ms) |
|
|
184
|
-
| `animationDurationIn` | `number` | - | Enter animation duration |
|
|
185
|
-
| `animationDurationOut` | `number` | - | Exit animation duration |
|
|
186
|
-
| `defaultColorSchema` | `ColorSchema` | `'dark'` | Default color scheme |
|
|
187
|
-
| `closeOnEscape` | `boolean` | `true` | Close with ESC key |
|
|
188
|
-
| `closeOnClickOutside` | `boolean` | `true` | Close on backdrop click |
|
|
189
|
-
| `classes` | `ConfirmClasses` | `{}` | Custom CSS classes |
|
|
190
|
-
<!-- | `closest` | `boolean` | `false` | If you want to show the closest container when api is called then do this true but it may be slow.| -->
|
|
191
|
-
|
|
192
|
-
### Confirm Function
|
|
193
|
-
|
|
194
|
-
```tsx
|
|
195
|
-
// String input (simple)
|
|
196
|
-
await confirm('Simple message');
|
|
197
|
-
|
|
198
|
-
// Object input (full options)
|
|
199
|
-
await confirm({
|
|
200
|
-
title: 'Custom Title', // Optional
|
|
201
|
-
message: 'Required message', // Required
|
|
202
|
-
okText: 'Proceed', // Optional
|
|
203
|
-
cancelText: 'Go Back', // Optional
|
|
204
|
-
colorSchema: 'blue', // Optional
|
|
205
|
-
});
|
|
206
|
-
```
|
|
207
|
-
|
|
208
|
-
**Return values:**
|
|
209
|
-
- `true` - User clicked OK
|
|
210
|
-
- `false` - User clicked Cancel
|
|
211
|
-
- `null` - User pressed ESC or clicked outside (if enabled)
|
|
212
|
-
|
|
213
|
-
### Custom Styling with CSS Classes
|
|
214
|
-
|
|
215
|
-
```tsx
|
|
216
|
-
<ConfirmContainer
|
|
217
|
-
classes={{
|
|
218
|
-
overlay: "my-overlay-class", // Background overlay
|
|
219
|
-
wrapper: "my-modal-class", // Modal container
|
|
220
|
-
title: "my-title-class", // Title text
|
|
221
|
-
message: "my-message-class", // Message text
|
|
222
|
-
button: "my-button-class", // Both buttons
|
|
223
|
-
cancel: "my-cancel-class", // Cancel button only
|
|
224
|
-
ok: "my-ok-class", // OK button only
|
|
225
|
-
}}
|
|
226
|
-
/>
|
|
227
|
-
```
|
|
228
|
-
|
|
229
|
-
## 🎭 Custom UI with Render Prop
|
|
230
|
-
|
|
231
|
-
Want complete control over the UI? Use the render prop:
|
|
232
|
-
|
|
233
|
-
```tsx
|
|
234
|
-
<ConfirmContainer animationDuration={500}>
|
|
235
|
-
{({
|
|
236
|
-
isVisible,
|
|
237
|
-
confirm,
|
|
238
|
-
handleCancel,
|
|
239
|
-
handleOk,
|
|
240
|
-
containerRef,
|
|
241
|
-
animationClass,
|
|
242
|
-
animationStyle
|
|
243
|
-
}) => (
|
|
244
|
-
<div className={`modal-overlay ${isVisible ? 'show' : 'hide'}`}>
|
|
245
|
-
{/* Your custom backdrop */}
|
|
246
|
-
<div className="backdrop" onClick={handleCancel} />
|
|
247
|
-
|
|
248
|
-
{/* Your custom modal */}
|
|
249
|
-
<div
|
|
250
|
-
ref={containerRef}
|
|
251
|
-
className={`custom-modal ${animationClass}`}
|
|
252
|
-
style={animationStyle}
|
|
253
|
-
>
|
|
254
|
-
<h2>{confirm.title}</h2>
|
|
255
|
-
<p>{confirm.message}</p>
|
|
256
|
-
|
|
257
|
-
<div className="buttons">
|
|
258
|
-
<button onClick={handleCancel}>
|
|
259
|
-
{confirm.cancelText || 'Cancel'}
|
|
260
|
-
</button>
|
|
261
|
-
<button onClick={handleOk}>
|
|
262
|
-
{confirm.okText || 'OK'}
|
|
263
|
-
</button>
|
|
264
|
-
</div>
|
|
265
|
-
</div>
|
|
266
|
-
</div>
|
|
267
|
-
)}
|
|
268
|
-
</ConfirmContainer>
|
|
269
|
-
```
|
|
270
|
-
|
|
271
|
-
**Available render props:**
|
|
272
|
-
- `isVisible`: Boolean indicating if dialog should be visible
|
|
273
|
-
- `confirm`: The current confirm options object
|
|
274
|
-
- `handleCancel`: Function to cancel the dialog (returns false)
|
|
275
|
-
- `handleOk`: Function to confirm the dialog (returns true)
|
|
276
|
-
- `containerRef`: React ref for the modal container
|
|
277
|
-
- `colorSchema`: Current color scheme
|
|
278
|
-
- `animationClass`: CSS class for current animation
|
|
279
|
-
- `animationStyle`: Style object with animation duration
|
|
280
|
-
- `lockScroll`: Boolean, If will be true then scroll will be locked when dialog will show.
|
|
281
|
-
|
|
282
|
-
## 📱 Real-World Examples
|
|
283
|
-
|
|
284
|
-
### Delete Confirmation with ESC Disabled
|
|
285
|
-
```tsx
|
|
286
|
-
const handleDelete = async () => {
|
|
287
|
-
// Force user to make explicit choice
|
|
288
|
-
const result = await confirm({
|
|
289
|
-
title: 'Delete Item',
|
|
290
|
-
message: 'This action cannot be undone. Are you sure?',
|
|
291
|
-
okText: 'Delete',
|
|
292
|
-
cancelText: 'Keep',
|
|
293
|
-
colorSchema: 'red'
|
|
294
|
-
});
|
|
295
|
-
|
|
296
|
-
// Result can only be true or false (no null since ESC/backdrop disabled)
|
|
297
|
-
if (result) {
|
|
298
|
-
await deleteItem();
|
|
299
|
-
}
|
|
300
|
-
};
|
|
301
|
-
|
|
302
|
-
// In your component
|
|
303
|
-
<ConfirmContainer closeOnEscape={false} closeOnClickOutside={false} />
|
|
304
|
-
```
|
|
305
|
-
|
|
306
|
-
### Form Submission with Backdrop Only
|
|
307
|
-
```tsx
|
|
308
|
-
// Allow closing by clicking backdrop but not ESC
|
|
309
|
-
<ConfirmContainer closeOnEscape={false} closeOnClickOutside={true} />
|
|
310
|
-
|
|
311
|
-
const handleSubmit = async () => {
|
|
312
|
-
const result = await confirm({
|
|
313
|
-
title: 'Submit Form',
|
|
314
|
-
message: 'Ready to submit this form?',
|
|
315
|
-
okText: 'Submit',
|
|
316
|
-
cancelText: 'Review',
|
|
317
|
-
colorSchema: 'green'
|
|
318
|
-
});
|
|
319
|
-
|
|
320
|
-
if (result) {
|
|
321
|
-
await submitForm();
|
|
322
|
-
} else if (result === null) {
|
|
323
|
-
// User clicked backdrop
|
|
324
|
-
console.log('Closed by clicking outside');
|
|
325
|
-
}
|
|
326
|
-
};
|
|
327
|
-
```
|
|
328
|
-
|
|
329
|
-
### Different Behaviors for Different Dialogs
|
|
330
|
-
```tsx
|
|
331
|
-
// Global: ESC and backdrop disabled
|
|
332
|
-
<ConfirmContainer
|
|
333
|
-
closeOnEscape={false}
|
|
334
|
-
closeOnClickOutside={false}
|
|
335
|
-
/>
|
|
336
|
-
|
|
337
|
-
// Some dialogs can override via custom UI
|
|
338
|
-
const handleFlexibleDialog = async () => {
|
|
339
|
-
// Create custom UI that allows ESC/backdrop
|
|
340
|
-
const result = await confirm('Flexible dialog?');
|
|
341
|
-
// result can be true, false, or null
|
|
342
|
-
};
|
|
343
|
-
```
|
|
344
|
-
|
|
345
|
-
## 🏗️ Container Configuration
|
|
346
|
-
|
|
347
|
-
### Global Settings
|
|
348
|
-
```tsx
|
|
349
|
-
<ConfirmContainer
|
|
350
|
-
defaultColorSchema="light" // Light theme by default
|
|
351
|
-
animation="zoom" // Zoom animation for all dialogs
|
|
352
|
-
animationDuration={400} // 400ms animations
|
|
353
|
-
closeOnEscape={true} // Allow ESC to close
|
|
354
|
-
closeOnClickOutside={true} // Allow backdrop click to close
|
|
355
|
-
animationDurationIn={350} // Enter: 350ms
|
|
356
|
-
animationDurationOut={250} // Exit: 250ms
|
|
357
|
-
lockScroll={false} // true by default
|
|
358
|
-
/>
|
|
359
|
-
```
|
|
360
|
-
|
|
361
|
-
### Different Close Behaviors
|
|
362
|
-
```tsx
|
|
363
|
-
// Option 1: Fully closable (default)
|
|
364
|
-
<ConfirmContainer closeOnEscape={true} closeOnClickOutside={true} />
|
|
365
|
-
// Users can close via: OK, Cancel, ESC, or backdrop click
|
|
366
|
-
|
|
367
|
-
// Option 2: Force explicit choice
|
|
368
|
-
<ConfirmContainer closeOnEscape={false} closeOnClickOutside={false} />
|
|
369
|
-
// Users can only close via: OK or Cancel buttons
|
|
370
|
-
|
|
371
|
-
// Option 3: Backdrop only
|
|
372
|
-
<ConfirmContainer closeOnEscape={false} closeOnClickOutside={true} />
|
|
373
|
-
// Users can close via: OK, Cancel, or backdrop click
|
|
374
|
-
|
|
375
|
-
// Option 4: ESC only
|
|
376
|
-
<ConfirmContainer closeOnEscape={true} closeOnClickOutside={false} />
|
|
377
|
-
// Users can close via: OK, Cancel, or ESC key
|
|
378
|
-
```
|
|
379
|
-
If user will close dialog box by clicking outside or by pressing escape then it will return `null`
|
|
380
|
-
|
|
381
|
-
## 🎨 Animation Gallery
|
|
382
|
-
|
|
383
|
-
### Slide Animations
|
|
384
|
-
- `slide` - Smooth vertical slide (default)
|
|
385
|
-
- `slideRight` / `slideLeft` - Horizontal slides
|
|
386
|
-
- `slideVertical` - Vertical slide
|
|
387
|
-
- `slideDown` - Slide down
|
|
388
|
-
|
|
389
|
-
### Fade Animations
|
|
390
|
-
- `fadeScale` - Fade with scaling
|
|
391
|
-
- `fadeUp` / `fadeDown` - Directional fades
|
|
392
|
-
- `fadeBlur` - Fade with blur effect
|
|
393
|
-
- `fadeShrink` - Fade with shrink effect
|
|
394
|
-
|
|
395
|
-
### 3D Animations
|
|
396
|
-
- `flip` - Card flip effect
|
|
397
|
-
- `drop` - 3D drop animation
|
|
398
|
-
- `rotate` / `rotateRight` - Rotation effects
|
|
399
|
-
|
|
400
|
-
### Playful Animations
|
|
401
|
-
- `bounce` / `bounceSmall` - Bounce effects
|
|
402
|
-
- `zoom` / `zoomSmall` - Zoom in/out
|
|
403
|
-
|
|
404
|
-
## 🚨 Troubleshooting
|
|
405
|
-
|
|
406
|
-
### Multiple dialogs are showing?
|
|
407
|
-
- Make sure you are on version `>=1.4`
|
|
408
|
-
- Make sure you didn't pass same id to different `<ConfirmContainer />`
|
|
409
|
-
|
|
410
|
-
### Dialog not showing?
|
|
411
|
-
- Make sure `<ConfirmContainer />` is mounted
|
|
412
|
-
- Check it's not conditionally rendered
|
|
413
|
-
|
|
414
|
-
### ESC key not working?
|
|
415
|
-
- Check if `closeOnEscape={true}` (default)
|
|
416
|
-
- Ensure no other event is preventing ESC
|
|
417
|
-
- Try different browsers
|
|
418
|
-
|
|
419
|
-
### Backdrop click not working?
|
|
420
|
-
- Verify `closeOnClickOutside={true}` (default)
|
|
421
|
-
- Check if any parent element is preventing clicks
|
|
422
|
-
|
|
423
|
-
### Animation not working?
|
|
424
|
-
- Verify animation name is correct
|
|
425
|
-
- Check browser console for errors
|
|
426
|
-
|
|
427
|
-
### TypeScript errors?
|
|
428
|
-
- Ensure you have `@types/react` installed
|
|
429
|
-
- Update to latest TypeScript version
|
|
430
|
-
|
|
431
|
-
### Styling issues?
|
|
432
|
-
- Use `classes` prop to override styles
|
|
433
|
-
- Check CSS specificity
|
|
434
|
-
|
|
435
|
-
You can also use it in TanStack with react easily
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
## 📱 Next.js Support
|
|
439
|
-
|
|
440
|
-
### App Router (Next.js 15+)
|
|
441
|
-
```tsx
|
|
442
|
-
// app/layout.tsx
|
|
443
|
-
import { ConfirmContainer } from 'react-confirm-lite';
|
|
444
|
-
|
|
445
|
-
export default function RootLayout({
|
|
446
|
-
children,
|
|
447
|
-
}: {
|
|
448
|
-
children: React.ReactNode;
|
|
449
|
-
}) {
|
|
450
|
-
return (
|
|
451
|
-
<html lang="en">
|
|
452
|
-
<body>
|
|
453
|
-
{children}
|
|
454
|
-
<ConfirmContainer />
|
|
455
|
-
</body>
|
|
456
|
-
</html>
|
|
457
|
-
);
|
|
458
|
-
}
|
|
459
|
-
```
|
|
460
|
-
|
|
461
|
-
### Server Components
|
|
462
|
-
```tsx
|
|
463
|
-
// Server actions
|
|
464
|
-
'use server';
|
|
465
|
-
import { confirm } from 'react-confirm-lite';
|
|
466
|
-
|
|
467
|
-
export async function serverAction() {
|
|
468
|
-
const result = await confirm('Confirm from server?');
|
|
469
|
-
if (result) {
|
|
470
|
-
// Perform action
|
|
471
|
-
} else if (result === null) {
|
|
472
|
-
// User pressed ESC or clicked outside
|
|
473
|
-
console.log('Action cancelled');
|
|
474
|
-
}
|
|
475
|
-
}
|
|
476
|
-
```
|
|
477
|
-
|
|
478
|
-
## 🔄 Migration from Other Libraries
|
|
479
|
-
|
|
480
|
-
### From window.confirm()
|
|
481
|
-
```tsx
|
|
482
|
-
// Old way (always returns true/false)
|
|
483
|
-
if (window.confirm('Delete?')) {
|
|
484
|
-
deleteItem();
|
|
485
|
-
}
|
|
486
|
-
|
|
487
|
-
// New way (returns true/false/null)
|
|
488
|
-
const result = await confirm('Delete?');
|
|
489
|
-
if (result === true) {
|
|
490
|
-
await deleteItem();
|
|
491
|
-
} else if (result === false) {
|
|
492
|
-
console.log('User clicked Cancel');
|
|
493
|
-
} else if (result === null) {
|
|
494
|
-
console.log('User pressed ESC');
|
|
495
|
-
}
|
|
496
|
-
```
|
|
497
|
-
|
|
498
|
-
### From Other Confirm Libraries
|
|
499
|
-
- No CSS imports needed
|
|
500
|
-
- Automatic queue system
|
|
501
|
-
- Built-in animations
|
|
502
|
-
- Zero configuration
|
|
503
|
-
- Three return states (true/false/null)
|
|
504
|
-
|
|
505
|
-
# Contributing to react-confirm-lite
|
|
506
|
-
|
|
507
|
-
Thanks for your interest in contributing. This project is intentionally lightweight, so the contribution workflow is kept simple and explicit. Please read this fully before starting.
|
|
508
|
-
|
|
509
|
-
---
|
|
510
|
-
|
|
511
|
-
## 📦 Project Structure
|
|
512
|
-
|
|
513
|
-
```
|
|
514
|
-
react-confirm-lite/
|
|
515
|
-
├─ src/ # Library source code
|
|
516
|
-
├─ dist/ # Built output (generated)
|
|
517
|
-
├─ example/ # Local playground app (Vite + React)
|
|
518
|
-
├─ CONTRIBUTING.md
|
|
519
|
-
├─ README.md
|
|
520
|
-
├─ package.json
|
|
521
|
-
├─ tsup.config.ts
|
|
522
|
-
```
|
|
523
|
-
|
|
524
|
-
* **src/** → where you make changes
|
|
525
|
-
* **dist/** → auto-generated by tsup (do not edit manually)
|
|
526
|
-
* **example/** → used to test changes locally
|
|
527
|
-
|
|
528
|
-
---
|
|
529
|
-
|
|
530
|
-
## 🧰 Prerequisites
|
|
531
|
-
|
|
532
|
-
* Node.js >= 18
|
|
533
|
-
* npm >= 9
|
|
534
|
-
* Basic familiarity with React + TypeScript
|
|
535
|
-
|
|
536
|
-
---
|
|
537
|
-
|
|
538
|
-
## 🚀 Local Development Setup
|
|
539
|
-
|
|
540
|
-
### 1. Clone the repository
|
|
541
|
-
|
|
542
|
-
```bash
|
|
543
|
-
git clone https://github.com/SaadNasir-git/react-confirm-lite.git
|
|
544
|
-
cd react-confirm-lite
|
|
545
|
-
```
|
|
546
|
-
|
|
547
|
-
### 2. Install dependencies (root)
|
|
548
|
-
|
|
549
|
-
```bash
|
|
550
|
-
npm install
|
|
551
|
-
```
|
|
552
|
-
|
|
553
|
-
---
|
|
554
|
-
|
|
555
|
-
## 🔁 Development Workflow (IMPORTANT)
|
|
556
|
-
|
|
557
|
-
This project uses **tsup watch mode** for live rebuilding.
|
|
558
|
-
|
|
559
|
-
### Terminal 1 — Run library in watch mode
|
|
560
|
-
|
|
561
|
-
From the project root:
|
|
562
|
-
|
|
563
|
-
```bash
|
|
564
|
-
npm run build:watch
|
|
565
|
-
```
|
|
566
|
-
|
|
567
|
-
This will:
|
|
568
|
-
|
|
569
|
-
* Watch `src/` for changes
|
|
570
|
-
* Automatically rebuild `dist/`
|
|
571
|
-
* Re-run post-build steps when files change
|
|
572
|
-
|
|
573
|
-
⚠️ Leave this terminal running.
|
|
574
|
-
|
|
575
|
-
---
|
|
576
|
-
|
|
577
|
-
### Terminal 2 — Run example app
|
|
578
|
-
|
|
579
|
-
```bash
|
|
580
|
-
cd example
|
|
581
|
-
npm install
|
|
582
|
-
npm run dev
|
|
583
|
-
```
|
|
584
|
-
|
|
585
|
-
Open the provided local URL in your browser.
|
|
586
|
-
|
|
587
|
-
---
|
|
588
|
-
|
|
589
|
-
## 🧪 How to Test Your Changes
|
|
590
|
-
|
|
591
|
-
1. Modify files inside `src/`
|
|
592
|
-
2. tsup automatically rebuilds the library
|
|
593
|
-
3. Refresh the browser running the example app
|
|
594
|
-
4. Verify behavior visually and via console logs
|
|
595
|
-
|
|
596
|
-
You **do not** need to:
|
|
597
|
-
|
|
598
|
-
* run `npm pack`
|
|
599
|
-
* reinstall the package
|
|
600
|
-
* publish to npm
|
|
601
|
-
|
|
602
|
-
This setup mirrors real-world library development.
|
|
603
|
-
|
|
604
|
-
---
|
|
605
|
-
|
|
606
|
-
## 🧠 What to Change (and What Not to)
|
|
607
|
-
|
|
608
|
-
### ✅ You can change
|
|
609
|
-
|
|
610
|
-
* Logic in `src/`
|
|
611
|
-
* Types in `types.ts`
|
|
612
|
-
* Styles / animations
|
|
613
|
-
* README documentation
|
|
614
|
-
|
|
615
|
-
### ❌ Do not change
|
|
616
|
-
|
|
617
|
-
* `dist/` files manually
|
|
618
|
-
* Version number (maintainer handles releases)
|
|
619
|
-
* Build configuration unless discussed
|
|
620
|
-
|
|
621
|
-
---
|
|
622
|
-
|
|
623
|
-
## 🧹 Code Style
|
|
624
|
-
|
|
625
|
-
* Use TypeScript types explicitly
|
|
626
|
-
* Avoid unnecessary abstractions
|
|
627
|
-
* Prefer clarity over cleverness
|
|
628
|
-
* Keep bundle size in mind
|
|
629
|
-
|
|
630
|
-
---
|
|
631
|
-
|
|
632
|
-
## 🐞 Reporting Bugs
|
|
633
|
-
|
|
634
|
-
When opening an issue, include:
|
|
635
|
-
|
|
636
|
-
* What you expected
|
|
637
|
-
* What actually happened
|
|
638
|
-
* Steps to reproduce
|
|
639
|
-
* Browser and React version
|
|
640
|
-
|
|
641
|
-
---
|
|
642
|
-
|
|
643
|
-
## 💡 Feature Requests
|
|
644
|
-
|
|
645
|
-
Feature requests are welcome, but keep in mind:
|
|
646
|
-
|
|
647
|
-
* This library aims to stay minimal
|
|
648
|
-
* Features should not add heavy dependencies
|
|
649
|
-
* API simplicity is a priority
|
|
650
|
-
|
|
651
|
-
---
|
|
652
|
-
|
|
653
|
-
## 🛠 Development & Contributing
|
|
654
|
-
|
|
655
|
-
If you want to contribute or modify the library locally, use the built-in example app and watch mode.
|
|
656
|
-
|
|
657
|
-
### Local Development Setup
|
|
658
|
-
|
|
659
|
-
```bash
|
|
660
|
-
git clone https://github.com/SaadNasir-git/react-confirm-lite.git
|
|
661
|
-
cd react-confirm-lite
|
|
662
|
-
npm install
|
|
663
|
-
```
|
|
664
|
-
|
|
665
|
-
### Run Library in Watch Mode
|
|
666
|
-
|
|
667
|
-
In the project root:
|
|
668
|
-
|
|
669
|
-
```bash
|
|
670
|
-
npm run build:watch
|
|
671
|
-
```
|
|
672
|
-
|
|
673
|
-
This watches the `src/` directory and automatically rebuilds `dist/` on every change.
|
|
674
|
-
|
|
675
|
-
### Run Example App
|
|
676
|
-
|
|
677
|
-
In a second terminal:
|
|
678
|
-
|
|
679
|
-
```bash
|
|
680
|
-
cd example
|
|
681
|
-
npm install
|
|
682
|
-
npm run dev
|
|
72
|
+
or if you want that everytime it show the closest without passing true in api then you can do like this in root component
|
|
73
|
+
```ts
|
|
74
|
+
import { showClosest } from 'react-confirm-lite'
|
|
75
|
+
showClosest()
|
|
683
76
|
```
|
|
684
|
-
|
|
685
|
-
Open the local URL shown by Vite. Any change you make in `src/` will be reflected after a browser refresh.
|
|
686
|
-
|
|
687
|
-
### Notes
|
|
688
|
-
|
|
689
|
-
* Do **not** edit files inside `dist/` manually
|
|
690
|
-
* You do **not** need to run `npm pack` or reinstall the package
|
|
691
|
-
* Versioning and releases are handled by the maintainer
|
|
692
|
-
|
|
693
|
-
For more details, see **CONTRIBUTING.md**.
|
|
694
|
-
|
|
695
|
-
---
|
|
696
|
-
|
|
697
|
-
## 📄 License
|
|
698
|
-
|
|
699
|
-
By contributing, you agree that your contributions will be licensed under the MIT License.
|
|
700
|
-
|
|
701
|
-
---
|
|
702
|
-
|
|
703
|
-
Thanks for contributing to **react-confirm-lite** 🙌
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
## 📄 License
|
|
707
|
-
|
|
708
|
-
MIT License - free for personal and commercial use.
|
|
709
|
-
|
|
710
|
-
## 👨💻 Author
|
|
711
|
-
|
|
712
|
-
**Saad Nasir** - Creator of react-confirm-lite
|
|
713
|
-
|
|
714
|
-
---
|
|
715
|
-
|
|
716
|
-
⭐ **Found this useful? Give it a star on GitHub!** ⭐
|
|
77
|
+
For more info checkout [website](https://react-confirm-lite.github.io).
|
package/dist/index.d.ts
CHANGED
|
@@ -53,6 +53,8 @@ interface animationPairs {
|
|
|
53
53
|
fadeShrink: EnterExit;
|
|
54
54
|
}
|
|
55
55
|
|
|
56
|
+
declare function showClosest(): void;
|
|
57
|
+
|
|
56
58
|
type Props = {
|
|
57
59
|
classes?: ConfirmClasses;
|
|
58
60
|
defaultColorSchema?: ColorSchema;
|
|
@@ -77,6 +79,6 @@ type Props = {
|
|
|
77
79
|
};
|
|
78
80
|
declare const ConfirmContainer: ({ classes, animationDuration, defaultColorSchema, closeOnEscape, closeOnClickOutside, animation, animationDurationIn, animationDurationOut, lockScroll, children, id }: Props) => react_jsx_runtime.JSX.Element;
|
|
79
81
|
|
|
80
|
-
declare function confirm(input: string | ConfirmInput, closest?: boolean): Promise<boolean | null>;
|
|
82
|
+
declare function confirm(input: string | ConfirmInput, closest?: boolean | null): Promise<boolean | null>;
|
|
81
83
|
|
|
82
|
-
export { type AnimationType, type ColorSchema, type ConfirmClasses, ConfirmContainer, type ConfirmInput, type ConfirmOptions, type animationPairs, confirm };
|
|
84
|
+
export { type AnimationType, type ColorSchema, type ConfirmClasses, ConfirmContainer, type ConfirmInput, type ConfirmOptions, type animationPairs, confirm, showClosest };
|
package/dist/index.js
CHANGED
|
@@ -8,6 +8,13 @@ var confirms = [];
|
|
|
8
8
|
var listeners = /* @__PURE__ */ new Set();
|
|
9
9
|
var isActiveContainer = false;
|
|
10
10
|
var containers = document.querySelectorAll(".null-confirm-container");
|
|
11
|
+
var showClose = false;
|
|
12
|
+
function showClosest() {
|
|
13
|
+
showClose = true;
|
|
14
|
+
}
|
|
15
|
+
function isClosest() {
|
|
16
|
+
return showClose;
|
|
17
|
+
}
|
|
11
18
|
var activeContainerId = null;
|
|
12
19
|
function setIsContainerActive(value) {
|
|
13
20
|
isActiveContainer = value;
|
|
@@ -421,11 +428,13 @@ var ConfirmContainer = ({
|
|
|
421
428
|
var confirmContainer_default = ConfirmContainer;
|
|
422
429
|
|
|
423
430
|
// src/confirm.ts
|
|
424
|
-
async function confirm(input, closest) {
|
|
431
|
+
async function confirm(input, closest = null) {
|
|
425
432
|
let containerId2;
|
|
426
433
|
if (typeof input === "string") {
|
|
427
434
|
if (closest) {
|
|
428
435
|
containerId2 = await getElement();
|
|
436
|
+
} else if (closest === null && isClosest() === true) {
|
|
437
|
+
containerId2 = await getElement();
|
|
429
438
|
}
|
|
430
439
|
const result2 = await addAlert({
|
|
431
440
|
message: input,
|
|
@@ -436,6 +445,8 @@ async function confirm(input, closest) {
|
|
|
436
445
|
if (!input.id) {
|
|
437
446
|
if (closest) {
|
|
438
447
|
containerId2 = await getElement();
|
|
448
|
+
} else if (closest === null && isClosest() === true) {
|
|
449
|
+
containerId2 = await getElement();
|
|
439
450
|
}
|
|
440
451
|
const result2 = await addAlert({
|
|
441
452
|
...input,
|
|
@@ -447,6 +458,6 @@ async function confirm(input, closest) {
|
|
|
447
458
|
return result;
|
|
448
459
|
}
|
|
449
460
|
|
|
450
|
-
export { confirmContainer_default as ConfirmContainer, confirm };
|
|
461
|
+
export { confirmContainer_default as ConfirmContainer, confirm, showClosest };
|
|
451
462
|
//# sourceMappingURL=index.js.map
|
|
452
463
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/confirm_store.ts","../src/confirm.css","../src/animations.css","../src/colorSchemas.css","../src/bundle-css.ts","../src/confirmContainer.tsx","../src/confirm.ts"],"names":["containerId","result"],"mappings":"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","file":"index.js","sourcesContent":["import type { ConfirmOptions, ConfirmInput } from \"./types\";\n\ntype Listener = (alerts: ConfirmOptions[]) => void;\n\nlet containerId: string = '';\nlet confirms: ConfirmOptions[] = [];\nlet listeners = new Set<Listener>();\nlet isActiveContainer: boolean = false\nlet containers: NodeListOf<Element> = document.querySelectorAll('.null-confirm-container');\n\n// Global lock - only ONE container can show alerts at a time\nlet activeContainerId: string | null = null;\n\nexport function setIsContainerActive(value: boolean) {\n isActiveContainer = value;\n}\n\nexport function getIsContainerActive() {\n return isActiveContainer;\n}\n\nexport function setActiveContainer(id: string | null) {\n activeContainerId = id;\n}\n\nexport function getActiveContainerId(): string | null {\n return activeContainerId;\n}\n\nexport function makeId() {\n if (typeof crypto !== 'undefined' && crypto.randomUUID) {\n return crypto.randomUUID();\n } else {\n // Fallback for older environments if necessary, though this method is widely supported.\n console.error(\"crypto.randomUUID is not supported in this environment. Using less reliable fallback.\");\n return Math.random().toString(36).substring(2) + Date.now().toString(36);\n }\n}\n\nexport async function addAlert(input: ConfirmInput): Promise<boolean | null> {\n return new Promise((resolve) => {\n const alert: ConfirmOptions = {\n id: input.id || '', // Keep the ID for container targeting\n title: input.title || \"Confirm\",\n message: input.message,\n okText: input.okText,\n cancelText: input.cancelText,\n colorSchema: input.colorSchema,\n resolve\n };\n\n confirms = [...confirms, alert];\n\n // If this alert has an ID, set it as the active container\n if (input.id) {\n setActiveContainer(input.id);\n }\n // If this alert doesn't have an ID, clear any active container\n // so any container can potentially show it\n else {\n setActiveContainer(null);\n }\n\n if (confirms.length === 1) {\n emit();\n }\n });\n}\n\nexport async function closeAlert(result: boolean | null) {\n const alert = confirms[0];\n containerId = '';\n if (!alert) return;\n\n // Resolve current alert\n alert.resolve(result);\n // Remove from queue\n confirms = confirms.slice(1);\n\n // If there are no more alerts, clear the active container\n if (confirms.length === 0) {\n setActiveContainer(null);\n }\n\n emit();\n}\n\nexport function subscribe(listener: Listener) {\n listeners.add(listener);\n listener(confirms);\n return () => listeners.delete(listener);\n}\n\nexport function emit() {\n listeners.forEach((listener) => listener(confirms));\n}\n\nconst EventListener = (e: PointerEvent) => {\n if (containers.length === 0) {\n containers = document.querySelectorAll('.null-confirm-container');\n }\n if (containers.length === 0) return;\n\n let parentElement = e.view?.document.activeElement?.parentElement;\n let container = parentElement?.querySelector('.null-confirm-container');\n\n while (true) {\n if (container?.id) {\n break;\n }\n parentElement = parentElement?.parentElement;\n container = parentElement?.querySelector('.null-confirm-container');\n }\n\n if (container?.id) {\n containerId = container.id;\n }\n}\n\nexport async function getElement() {\n document.addEventListener('click', EventListener, { once: true })\n await new Promise<void>((resolve) => {\n setTimeout(() => {\n document.removeEventListener('click', EventListener)\n resolve()\n }, 0);\n })\n if (containerId === '') {\n if (containers.length === 0) return;\n containerId = containers[0].id\n return containerId\n }\n return containerId;\n}\n\n// Create a scroll lock manager\nclass ScrollLockManager {\n private static instance: ScrollLockManager;\n private scrollPosition = 0;\n private isLocked = false;\n\n private constructor() { }\n\n static getInstance(): ScrollLockManager {\n if (!ScrollLockManager.instance) {\n ScrollLockManager.instance = new ScrollLockManager();\n }\n return ScrollLockManager.instance;\n }\n\n lock() {\n if (this.isLocked) return;\n\n // Save current scroll position\n this.scrollPosition = window.scrollY;\n\n // Get scrollbar width BEFORE hiding it\n const scrollbarWidth = window.innerWidth - document.documentElement.clientWidth;\n\n // Add padding to body BEFORE hiding scrollbar (prevents layout shift)\n document.body.style.paddingRight = `${scrollbarWidth}px`;\n\n // Lock scroll on both html and body\n document.documentElement.style.overflow = 'hidden';\n document.body.style.overflow = 'hidden';\n\n // Add class for any additional CSS\n document.body.classList.add('scroll-locked');\n\n this.isLocked = true;\n }\n\n unlock() {\n if (!this.isLocked) return;\n\n // Remove overflow hidden\n document.documentElement.style.overflow = '';\n document.body.style.overflow = '';\n\n // Remove padding\n document.body.style.paddingRight = '';\n\n // Remove class\n document.body.classList.remove('scroll-locked');\n\n // Restore scroll position AFTER styles are removed\n window.scrollTo(0, this.scrollPosition);\n\n this.isLocked = false;\n }\n}\n\n// Export simple functions\nexport const lockBodyScroll = () => ScrollLockManager.getInstance().lock();\nexport const unlockBodyScroll = () => ScrollLockManager.getInstance().unlock();","/* confirm.css */\n.alert-overlay {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n z-index: 9999;\n display: flex;\n align-items: center;\n justify-content: center;\n backdrop-filter: blur(4px);\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',\n 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',\n sans-serif;\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n animation: overlayFadeIn 0.3s ease-out forwards;\n}\n\n.alert-overlay-exit {\n animation: overlayFadeOut 0.3s ease-in forwards;\n}\n\n.alert-wrapper {\n width: 90%;\n max-width: 400px;\n border-radius: 12px;\n padding: 24px;\n box-shadow: \n 0 20px 25px -5px rgba(0, 0, 0, 0.1),\n 0 10px 10px -5px rgba(0, 0, 0, 0.04),\n 0 0 0 1px rgba(0, 0, 0, 0.05);\n animation: modalSlideUp 0.4s cubic-bezier(0.34, 1.56, 0.64, 1) forwards;\n transform: translateY(20px) scale(0.98);\n}\n\n.alert-wrapper-exit {\n animation: modalSlideDown 0.3s ease-in forwards;\n}\n\n.alert-title {\n font-size: 18px;\n font-weight: 600;\n line-height: 1.4;\n margin: 0 0 12px 0;\n}\n\n.alert-message {\n font-size: 14px;\n line-height: 1.5;\n margin: 0 0 24px 0;\n}\n\n.alert-buttons {\n display: flex;\n justify-content: flex-end;\n gap: 12px;\n margin-top: 8px;\n}\n\n.alert-button {\n padding: 10px 20px;\n border-radius: 8px;\n font-size: 14px;\n font-weight: 500;\n border: none;\n cursor: pointer;\n font-family: inherit;\n transition: all 0.2s ease;\n min-width: 80px;\n text-align: center;\n}\n\n.alert-button:focus {\n outline-offset: 2px;\n}\n\n.alert-button:active {\n transform: translateY(1px);\n}\n\n/* Default animations */\n.alert-wrapper-exit {\n animation: modalSlideDown 0.3s ease-in forwards;\n}\n\n/* Entrance Animation Classes */\n.alert-animate-fadeInScale {\n animation: fadeInScale 0.4s ease-out forwards;\n}\n\n.alert-animate-bounceIn {\n animation: bounceIn 0.6s cubic-bezier(0.68, -0.55, 0.265, 1.55) forwards;\n}\n\n.alert-animate-flipIn {\n animation: flipIn 0.6s cubic-bezier(0.175, 0.885, 0.32, 1.275) forwards;\n}\n\n.alert-animate-zoomIn {\n animation: zoomIn 0.3s ease-out forwards;\n}\n\n.alert-animate-rotateIn {\n animation: rotateIn 0.5s ease-out forwards;\n}\n\n.alert-animate-fadeInUp {\n animation: fadeInUp 0.5s cubic-bezier(0.34, 1.56, 0.64, 1) forwards;\n}\n\n.alert-animate-dropIn {\n animation: dropIn 0.6s cubic-bezier(0.175, 0.885, 0.32, 1.275) forwards;\n}\n\n.alert-animate-slideInRight {\n animation: slideInRight 0.4s ease-out forwards;\n}\n\n.alert-animate-slideInLeft {\n animation: slideInLeft 0.4s ease-out forwards;\n}\n\n.alert-animate-fadeInDown {\n animation: fadeInDown 0.5s cubic-bezier(0.34, 1.56, 0.64, 1) forwards;\n}\n\n.alert-animate-slideDownIn {\n animation: slideDownIn 0.4s cubic-bezier(0.34, 1.56, 0.64, 1) forwards;\n}\n\n.alert-animate-rotateInRight {\n animation: rotateInRight 0.5s ease-out forwards;\n}\n\n.alert-animate-zoomInSmall {\n animation: zoomInSmall 0.3s ease-out forwards;\n}\n\n.alert-animate-bounceInSmall {\n animation: bounceInSmall 0.6s cubic-bezier(0.68, -0.55, 0.265, 1.55) forwards;\n}\n\n.alert-animate-fadeInBlur {\n animation: fadeInBlur 0.4s ease-out forwards;\n}\n\n.alert-animate-fadeInShrink {\n animation: fadeInShrink 0.3s ease-out forwards;\n}\n\n/* Exit Animation Classes */\n.alert-animate-fadeOutScale {\n animation: fadeOutScale 0.3s ease-in forwards;\n}\n\n.alert-animate-bounceOut {\n animation: bounceOut 0.4s ease-in forwards;\n}\n\n.alert-animate-zoomOut {\n animation: zoomOut 0.3s ease-in forwards;\n}\n\n.alert-animate-rotateOut {\n animation: rotateOut 0.3s ease-in forwards;\n}\n\n.alert-animate-fadeOutDown {\n animation: fadeOutDown 0.3s ease-in forwards;\n}\n\n.alert-animate-slideOutRight {\n animation: slideOutRight 0.3s ease-in forwards;\n}\n\n.alert-animate-slideOutLeft {\n animation: slideOutLeft 0.3s ease-in forwards;\n}\n\n.alert-animate-flipOut {\n animation: flipOut 0.6s cubic-bezier(0.175, 0.885, 0.32, 1.275) forwards;\n}\n\n.alert-animate-dropOut {\n animation: dropOut 0.6s cubic-bezier(0.175, 0.885, 0.32, 1.275) forwards;\n}\n\n.alert-animate-fadeOutUp {\n animation: fadeOutUp 0.3s ease-in forwards;\n}\n\n.alert-animate-slideUpOut {\n animation: slideUpOut 0.3s ease-in forwards;\n}\n\n.alert-animate-rotateOutLeft {\n animation: rotateOutLeft 0.3s ease-in forwards;\n}\n\n.alert-animate-zoomOutSmall {\n animation: zoomOutSmall 0.3s ease-in forwards;\n}\n\n.alert-animate-bounceOutSmall {\n animation: bounceOutSmall 0.4s ease-in forwards;\n}\n\n.alert-animate-fadeOutBlur {\n animation: fadeOutBlur 0.4s ease-in forwards;\n}\n\n.alert-animate-fadeOutShrink {\n animation: fadeOutShrink 0.3s ease-in forwards;\n}\n\n.alert-wrapper {\n width: 90%;\n max-width: 400px;\n border-radius: 12px;\n padding: 24px;\n box-shadow: \n 0 20px 25px -5px rgba(0, 0, 0, 0.1),\n 0 10px 10px -5px rgba(0, 0, 0, 0.04),\n 0 0 0 1px rgba(0, 0, 0, 0.05);\n}\n\n.null-confirm-container{\n width: 0;\n height: 0;\n opacity: 0;\n position: fixed;\n left: 0;\n top: 0;\n}\n\n/* Global CSS file */\nhtml.scroll-locked {\n overflow: hidden !important;\n position: relative !important;\n height: 100% !important;\n width: 100% !important;\n}\n\nhtml.scroll-locked body {\n overflow: hidden !important;\n height: 100% !important;\n width: 100% !important;\n position: relative !important;\n padding-right: var(--scrollbar-width, 0px) !important;\n}\n\n/* Optional: Prevent momentum scrolling on iOS */\nhtml.scroll-locked {\n -webkit-overflow-scrolling: auto !important;\n}","/* animations.css - Complete Animation Keyframes */\n\n/* Overlay Animations */\n@keyframes overlayFadeIn {\n from {\n opacity: 0;\n }\n to {\n opacity: 1;\n }\n}\n\n@keyframes overlayFadeOut {\n from {\n opacity: 1;\n }\n to {\n opacity: 0;\n }\n}\n\n/* Default Modal Animations */\n@keyframes modalSlideUp {\n from {\n opacity: 0;\n transform: translateY(20px) scale(0.98);\n }\n to {\n opacity: 1;\n transform: translateY(0) scale(1);\n }\n}\n\n@keyframes modalSlideDown {\n from {\n opacity: 1;\n transform: translateY(0) scale(1);\n }\n to {\n opacity: 0;\n transform: translateY(20px) scale(0.98);\n }\n}\n\n/* Fade In/Out with Scale */\n@keyframes fadeInScale {\n from {\n opacity: 0;\n transform: scale(0.95);\n }\n to {\n opacity: 1;\n transform: scale(1);\n }\n}\n\n@keyframes fadeOutScale {\n from {\n opacity: 1;\n transform: scale(1);\n }\n to {\n opacity: 0;\n transform: scale(0.95);\n }\n}\n\n/* Slide In/Out from Right */\n@keyframes slideInRight {\n from {\n opacity: 0;\n transform: translateX(30px);\n }\n to {\n opacity: 1;\n transform: translateX(0);\n }\n}\n\n@keyframes slideOutRight {\n from {\n opacity: 1;\n transform: translateX(0);\n }\n to {\n opacity: 0;\n transform: translateX(30px);\n }\n}\n\n/* Slide In/Out from Left */\n@keyframes slideInLeft {\n from {\n opacity: 0;\n transform: translateX(-30px);\n }\n to {\n opacity: 1;\n transform: translateX(0);\n }\n}\n\n@keyframes slideOutLeft {\n from {\n opacity: 1;\n transform: translateX(0);\n }\n to {\n opacity: 0;\n transform: translateX(-30px);\n }\n}\n\n/* Bounce In/Out */\n@keyframes bounceIn {\n 0% {\n opacity: 0;\n transform: scale(0.3);\n }\n 50% {\n opacity: 1;\n transform: scale(1.05);\n }\n 70% {\n transform: scale(0.9);\n }\n 100% {\n transform: scale(1);\n }\n}\n\n@keyframes bounceOut {\n 20% {\n transform: scale(1.1);\n }\n 100% {\n opacity: 0;\n transform: scale(0.3);\n }\n}\n\n/* Small Bounce In/Out */\n@keyframes bounceInSmall {\n 0% {\n opacity: 0;\n transform: scale(0.8);\n }\n 50% {\n opacity: 1;\n transform: scale(1.05);\n }\n 70% {\n transform: scale(0.95);\n }\n 100% {\n transform: scale(1);\n }\n}\n\n@keyframes bounceOutSmall {\n 20% {\n transform: scale(1.05);\n }\n 100% {\n opacity: 0;\n transform: scale(0.8);\n }\n}\n\n/* Flip In/Out */\n@keyframes flipIn {\n 0% {\n opacity: 0;\n transform: perspective(400px) rotateY(90deg);\n }\n 100% {\n opacity: 1;\n transform: perspective(400px) rotateY(0deg);\n }\n}\n\n@keyframes flipOut {\n 0% {\n opacity: 1;\n transform: perspective(400px) rotateY(0deg);\n }\n 100% {\n opacity: 0;\n transform: perspective(400px) rotateY(90deg);\n }\n}\n\n/* Zoom In/Out */\n@keyframes zoomIn {\n from {\n opacity: 0;\n transform: scale(0.5);\n }\n to {\n opacity: 1;\n transform: scale(1);\n }\n}\n\n@keyframes zoomOut {\n from {\n opacity: 1;\n transform: scale(1);\n }\n to {\n opacity: 0;\n transform: scale(0.5);\n }\n}\n\n/* Small Zoom In/Out */\n@keyframes zoomInSmall {\n from {\n opacity: 0;\n transform: scale(0.8);\n }\n to {\n opacity: 1;\n transform: scale(1);\n }\n}\n\n@keyframes zoomOutSmall {\n from {\n opacity: 1;\n transform: scale(1);\n }\n to {\n opacity: 0;\n transform: scale(0.8);\n }\n}\n\n/* Rotate In/Out */\n@keyframes rotateIn {\n from {\n opacity: 0;\n transform: rotate(-15deg) scale(0.95);\n }\n to {\n opacity: 1;\n transform: rotate(0deg) scale(1);\n }\n}\n\n@keyframes rotateOut {\n from {\n opacity: 1;\n transform: rotate(0deg) scale(1);\n }\n to {\n opacity: 0;\n transform: rotate(15deg) scale(0.95);\n }\n}\n\n/* Rotate Right In/Left Out */\n@keyframes rotateInRight {\n from {\n opacity: 0;\n transform: rotate(15deg) scale(0.95);\n }\n to {\n opacity: 1;\n transform: rotate(0deg) scale(1);\n }\n}\n\n@keyframes rotateOutLeft {\n from {\n opacity: 1;\n transform: rotate(0deg) scale(1);\n }\n to {\n opacity: 0;\n transform: rotate(-15deg) scale(0.95);\n }\n}\n\n/* Fade Up In/Down Out */\n@keyframes fadeInUp {\n from {\n opacity: 0;\n transform: translateY(40px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n\n@keyframes fadeOutDown {\n from {\n opacity: 1;\n transform: translateY(0);\n }\n to {\n opacity: 0;\n transform: translateY(40px);\n }\n}\n\n/* Fade Down In/Up Out */\n@keyframes fadeInDown {\n from {\n opacity: 0;\n transform: translateY(-40px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n\n@keyframes fadeOutUp {\n from {\n opacity: 1;\n transform: translateY(0);\n }\n to {\n opacity: 0;\n transform: translateY(-40px);\n }\n}\n\n/* Drop In/Out (3D) */\n@keyframes dropIn {\n 0% {\n opacity: 0;\n transform: translateY(-100px) rotateX(90deg);\n }\n 70% {\n opacity: 1;\n transform: translateY(10px) rotateX(-10deg);\n }\n 100% {\n transform: translateY(0) rotateX(0deg);\n }\n}\n\n@keyframes dropOut {\n 0% {\n opacity: 1;\n transform: translateY(0) rotateX(0deg);\n }\n 30% {\n opacity: 1;\n transform: translateY(10px) rotateX(-10deg);\n }\n 100% {\n opacity: 0;\n transform: translateY(-100px) rotateX(90deg);\n }\n}\n\n/* Slide Up Out/Down In */\n@keyframes slideUpOut {\n from {\n opacity: 1;\n transform: translateY(0) scale(1);\n }\n to {\n opacity: 0;\n transform: translateY(-20px) scale(0.98);\n }\n}\n\n@keyframes slideDownIn {\n from {\n opacity: 0;\n transform: translateY(-20px) scale(0.98);\n }\n to {\n opacity: 1;\n transform: translateY(0) scale(1);\n }\n}\n\n/* Blur In/Out Effects */\n@keyframes fadeInBlur {\n from {\n opacity: 0;\n filter: blur(10px);\n }\n to {\n opacity: 1;\n filter: blur(0px);\n }\n}\n\n@keyframes fadeOutBlur {\n from {\n opacity: 1;\n filter: blur(0px);\n }\n to {\n opacity: 0;\n filter: blur(10px);\n }\n}\n\n/* Shrink In/Out Effects */\n@keyframes fadeInShrink {\n from {\n opacity: 0;\n transform: scale(1.2) translateY(20px);\n }\n to {\n opacity: 1;\n transform: scale(1) translateY(0);\n }\n}\n\n@keyframes fadeOutShrink {\n from {\n opacity: 1;\n transform: scale(1) translateY(0);\n }\n to {\n opacity: 0;\n transform: scale(0.8) translateY(20px);\n }\n}\n\n/* Background Blur Animations */\n@keyframes blurIn {\n from {\n backdrop-filter: blur(0px);\n }\n to {\n backdrop-filter: blur(4px);\n }\n}\n\n@keyframes blurOut {\n from {\n backdrop-filter: blur(4px);\n }\n to {\n backdrop-filter: blur(0px);\n }\n}\n\n/* Special Effects Animations */\n\n/* Shake Animation (for errors) */\n@keyframes shake {\n 0%, 100% {\n transform: translateX(0);\n }\n 10%, 30%, 50%, 70%, 90% {\n transform: translateX(-5px);\n }\n 20%, 40%, 60%, 80% {\n transform: translateX(5px);\n }\n}\n\n/* Pulse Animation (for emphasis) */\n@keyframes pulse {\n 0% {\n transform: scale(1);\n }\n 50% {\n transform: scale(1.05);\n }\n 100% {\n transform: scale(1);\n }\n}\n\n/* Button Hover Effects */\n@keyframes buttonHover {\n 0% {\n transform: translateY(0);\n box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);\n }\n 50% {\n transform: translateY(-2px);\n box-shadow: 0 8px 15px rgba(0, 0, 0, 0.2);\n }\n 100% {\n transform: translateY(-1px);\n box-shadow: 0 6px 12px rgba(0, 0, 0, 0.15);\n }\n}\n\n/* Accessibility: Reduce motion */\n@media (prefers-reduced-motion: reduce) {\n .alert-overlay,\n .alert-wrapper,\n .alert-button {\n animation-duration: 0.01ms;\n animation-iteration-count: 1;\n transition-duration: 0.01ms;\n }\n \n .alert-overlay {\n animation: none;\n opacity: 1;\n }\n \n .alert-wrapper {\n animation: none;\n opacity: 1;\n transform: none;\n }\n}","/* ========== LIGHT SCHEMA (Default) ========== */\n.schema-light-overlay {\n background-color: rgba(0, 0, 0, 0.5);\n}\n\n.schema-light-wrapper {\n background-color: #ffffff;\n color: #111827;\n}\n\n.schema-light-title {\n color: #111827;\n}\n\n.schema-light-message {\n color: #6b7280;\n}\n\n.schema-light-cancel {\n background-color: #f3f4f6;\n color: #374151;\n outline-color: #9ca3af;\n}\n\n.schema-light-cancel:hover {\n background-color: #e5e7eb;\n transform: translateY(-1px);\n}\n\n.schema-light-cancel:active {\n background-color: #d1d5db;\n}\n\n.schema-light-cancel-danger {\n background-color: #fee2e2;\n color: #991b1b;\n outline-color: #f87171;\n}\n\n.schema-light-cancel-danger:hover {\n background-color: #fecaca;\n}\n\n.schema-light-ok {\n background-color: #10b981;\n color: #ffffff;\n outline-color: #34d399;\n}\n\n.schema-light-ok:hover {\n background-color: #059669;\n transform: translateY(-1px);\n}\n\n.schema-light-ok:active {\n background-color: #047857;\n}\n\n.schema-light-ok-danger {\n background-color: #ef4444;\n color: #ffffff;\n outline-color: #f87171;\n}\n\n.schema-light-ok-danger:hover {\n background-color: #dc2626;\n}\n\n/* ========== DARK SCHEMA ========== */\n.schema-dark-overlay {\n background-color: rgba(0, 0, 0, 0.7);\n}\n\n.schema-dark-wrapper {\n background-color: #18181b;\n color: #f4f4f5;\n box-shadow: \n 0 20px 25px -5px rgba(0, 0, 0, 0.3),\n 0 10px 10px -5px rgba(0, 0, 0, 0.2),\n 0 0 0 1px rgba(255, 255, 255, 0.1);\n}\n\n.schema-dark-title {\n color: #f4f4f5;\n}\n\n.schema-dark-message {\n color: #a1a1aa;\n}\n\n.schema-dark-cancel {\n background-color: #27272a;\n color: #e4e4e7;\n outline-color: #71717a;\n}\n\n.schema-dark-cancel:hover {\n background-color: #3f3f46;\n transform: translateY(-1px);\n}\n\n.schema-dark-cancel:active {\n background-color: #52525b;\n}\n\n.schema-dark-cancel-danger {\n background-color: #7f1d1d;\n color: #fecaca;\n outline-color: #ef4444;\n}\n\n.schema-dark-cancel-danger:hover {\n background-color: #991b1b;\n}\n\n.schema-dark-ok {\n background-color: #10b981;\n color: #ffffff;\n outline-color: #34d399;\n}\n\n.schema-dark-ok:hover {\n background-color: #059669;\n transform: translateY(-1px);\n}\n\n.schema-dark-ok:active {\n background-color: #047857;\n}\n\n.schema-dark-ok-danger {\n background-color: #dc2626;\n color: #ffffff;\n outline-color: #ef4444;\n}\n\n.schema-dark-ok-danger:hover {\n background-color: #b91c1c;\n}\n\n/* ========== BLUE SCHEMA ========== */\n.schema-blue-overlay {\n background-color: rgba(59, 130, 246, 0.3);\n}\n\n.schema-blue-wrapper {\n background-color: #eff6ff;\n color: #1e3a8a;\n box-shadow: \n 0 20px 25px -5px rgba(59, 130, 246, 0.15),\n 0 10px 10px -5px rgba(59, 130, 246, 0.1),\n 0 0 0 1px rgba(59, 130, 246, 0.1);\n}\n\n.schema-blue-title {\n color: #1e3a8a;\n}\n\n.schema-blue-message {\n color: #3b82f6;\n}\n\n.schema-blue-cancel {\n background-color: #dbeafe;\n color: #1e40af;\n outline-color: #60a5fa;\n}\n\n.schema-blue-cancel:hover {\n background-color: #bfdbfe;\n transform: translateY(-1px);\n}\n\n.schema-blue-cancel:active {\n background-color: #93c5fd;\n}\n\n.schema-blue-cancel-danger {\n background-color: #fee2e2;\n color: #991b1b;\n outline-color: #f87171;\n}\n\n.schema-blue-ok {\n background-color: #3b82f6;\n color: #ffffff;\n outline-color: #60a5fa;\n}\n\n.schema-blue-ok:hover {\n background-color: #2563eb;\n transform: translateY(-1px);\n}\n\n.schema-blue-ok:active {\n background-color: #1d4ed8;\n}\n\n.schema-blue-ok-danger {\n background-color: #ef4444;\n color: #ffffff;\n outline-color: #f87171;\n}\n\n/* ========== RED SCHEMA ========== */\n.schema-red-overlay {\n background-color: rgba(220, 38, 38, 0.2);\n}\n\n.schema-red-wrapper {\n background-color: #fef2f2;\n color: #7f1d1d;\n box-shadow: \n 0 20px 25px -5px rgba(220, 38, 38, 0.15),\n 0 10px 10px -5px rgba(220, 38, 38, 0.1),\n 0 0 0 1px rgba(220, 38, 38, 0.1);\n}\n\n.schema-red-title {\n color: #7f1d1d;\n}\n\n.schema-red-message {\n color: #ef4444;\n}\n\n.schema-red-cancel {\n background-color: #fecaca;\n color: #991b1b;\n outline-color: #f87171;\n}\n\n.schema-red-cancel:hover {\n background-color: #fca5a5;\n transform: translateY(-1px);\n}\n\n.schema-red-cancel:active {\n background-color: #f87171;\n}\n\n.schema-red-ok {\n background-color: #dc2626;\n color: #ffffff;\n outline-color: #ef4444;\n}\n\n.schema-red-ok:hover {\n background-color: #b91c1c;\n transform: translateY(-1px);\n}\n\n.schema-red-ok:active {\n background-color: #991b1b;\n}\n\n.schema-red-ok-danger {\n background-color: #991b1b;\n color: #ffffff;\n outline-color: #dc2626;\n}\n\n/* ========== GREEN SCHEMA ========== */\n.schema-green-overlay {\n background-color: rgba(16, 185, 129, 0.2);\n}\n\n.schema-green-wrapper {\n background-color: #ecfdf5;\n color: #064e3b;\n box-shadow: \n 0 20px 25px -5px rgba(16, 185, 129, 0.15),\n 0 10px 10px -5px rgba(16, 185, 129, 0.1),\n 0 0 0 1px rgba(16, 185, 129, 0.1);\n}\n\n.schema-green-title {\n color: #064e3b;\n}\n\n.schema-green-message {\n color: #10b981;\n}\n\n.schema-green-cancel {\n background-color: #d1fae5;\n color: #047857;\n outline-color: #34d399;\n}\n\n.schema-green-cancel:hover {\n background-color: #a7f3d0;\n transform: translateY(-1px);\n}\n\n.schema-green-cancel:active {\n background-color: #6ee7b7;\n}\n\n.schema-green-cancel-danger {\n background-color: #fee2e2;\n color: #991b1b;\n outline-color: #f87171;\n}\n\n.schema-green-ok {\n background-color: #10b981;\n color: #ffffff;\n outline-color: #34d399;\n}\n\n.schema-green-ok:hover {\n background-color: #059669;\n transform: translateY(-1px);\n}\n\n.schema-green-ok:active {\n background-color: #047857;\n}\n\n.schema-green-ok-danger {\n background-color: #ef4444;\n color: #ffffff;\n outline-color: #f87171;\n}\n\n/* ========== PURPLE SCHEMA ========== */\n.schema-purple-overlay {\n background-color: rgba(139, 92, 246, 0.2);\n}\n\n.schema-purple-wrapper {\n background-color: #f5f3ff;\n color: #5b21b6;\n box-shadow: \n 0 20px 25px -5px rgba(139, 92, 246, 0.15),\n 0 10px 10px -5px rgba(139, 92, 246, 0.1),\n 0 0 0 1px rgba(139, 92, 246, 0.1);\n}\n\n.schema-purple-title {\n color: #5b21b6;\n}\n\n.schema-purple-message {\n color: #8b5cf6;\n}\n\n.schema-purple-cancel {\n background-color: #ede9fe;\n color: #6d28d9;\n outline-color: #a78bfa;\n}\n\n.schema-purple-cancel:hover {\n background-color: #ddd6fe;\n transform: translateY(-1px);\n}\n\n.schema-purple-cancel:active {\n background-color: #c4b5fd;\n}\n\n.schema-purple-cancel-danger {\n background-color: #fee2e2;\n color: #991b1b;\n outline-color: #f87171;\n}\n\n.schema-purple-ok {\n background-color: #8b5cf6;\n color: #ffffff;\n outline-color: #a78bfa;\n}\n\n.schema-purple-ok:hover {\n background-color: #7c3aed;\n transform: translateY(-1px);\n}\n\n.schema-purple-ok:active {\n background-color: #6d28d9;\n}\n\n.schema-purple-ok-danger {\n background-color: #ef4444;\n color: #ffffff;\n outline-color: #f87171;\n}\n","import confirmCSS from './confirm.css';\nimport animationsCSS from './animations.css';\nimport colorSchemasCSS from './colorSchemas.css';\n\n// Combine all CSS\nconst ALL_CSS = `${confirmCSS}\\n${animationsCSS}\\n${colorSchemasCSS}`;\n\nlet stylesInjected = false;\n\nexport function ensureStyles() {\n if (typeof document === 'undefined') {\n return; // Server-side rendering\n }\n \n if (stylesInjected) {\n return; // Already injected\n }\n \n // Create and inject style tag\n const style = document.createElement('style');\n style.setAttribute('data-react-confirm-lite', '');\n style.textContent = ALL_CSS;\n document.head.appendChild(style);\n \n stylesInjected = true;\n}","import React, { useEffect, useState, useCallback, useRef, type ReactNode, type CSSProperties } from \"react\";\nimport { subscribe, closeAlert, setActiveContainer, setIsContainerActive, getIsContainerActive, getActiveContainerId, makeId } from \"./confirm_store\";\nimport type { ConfirmClasses, ConfirmOptions, ColorSchema, AnimationType, animationPairs } from \"./types\";\nimport { lockBodyScroll, unlockBodyScroll } from \"./confirm_store\";\nimport \"./confirm.css\";\nimport './animations.css'\nimport './colorSchemas.css'\nimport { ensureStyles } from \"./bundle-css\";\n\nfunction cx(...classes: (string | undefined)[]) {\n return classes.filter(Boolean).join(\" \");\n}\n\nconst animationPairs = {\n slide: { enter: '', exit: 'alert-wrapper-exit' },\n fadeScale: { enter: 'alert-animate-fadeInScale', exit: 'alert-animate-fadeOutScale' },\n bounce: { enter: 'alert-animate-bounceIn', exit: 'alert-animate-bounceOut' },\n flip: { enter: 'alert-animate-flipIn', exit: 'alert-animate-flipOut' },\n zoom: { enter: 'alert-animate-zoomIn', exit: 'alert-animate-zoomOut' },\n rotate: { enter: 'alert-animate-rotateIn', exit: 'alert-animate-rotateOut' },\n fadeUp: { enter: 'alert-animate-fadeInUp', exit: 'alert-animate-fadeOutDown' },\n drop: { enter: 'alert-animate-dropIn', exit: 'alert-animate-dropOut' },\n slideRight: { enter: 'alert-animate-slideInRight', exit: 'alert-animate-slideOutLeft' },\n slideLeft: { enter: 'alert-animate-slideInLeft', exit: 'alert-animate-slideOutRight' },\n fadeDown: { enter: 'alert-animate-fadeInDown', exit: 'alert-animate-fadeOutUp' },\n slideVertical: { enter: 'alert-animate-slideDownIn', exit: 'alert-animate-slideUpOut' },\n rotateRight: { enter: 'alert-animate-rotateInRight', exit: 'alert-animate-rotateOutLeft' },\n zoomSmall: { enter: 'alert-animate-zoomInSmall', exit: 'alert-animate-zoomOutSmall' },\n bounceSmall: { enter: 'alert-animate-bounceInSmall', exit: 'alert-animate-bounceOutSmall' },\n fadeBlur: { enter: 'alert-animate-fadeInBlur', exit: 'alert-animate-fadeOutBlur' },\n fadeShrink: { enter: 'alert-animate-fadeInShrink', exit: 'alert-animate-fadeOutShrink' },\n} as const;\n\ntype Props = {\n classes?: ConfirmClasses;\n defaultColorSchema?: ColorSchema;\n closeOnEscape?: boolean;\n closeOnClickOutside?: boolean;\n animation?: AnimationType;\n animationDuration?: number;\n animationDurationIn?: number;\n animationDurationOut?: number;\n lockScroll?: boolean;\n children?: (props: {\n isVisible: boolean;\n confirm: ConfirmOptions;\n handleCancel: () => void;\n handleOk: () => void;\n containerRef: React.RefObject<HTMLDivElement | null>;\n colorSchema: ColorSchema;\n animationClass: string;\n animationStyle: CSSProperties;\n }) => ReactNode;\n id?: string;\n};\n\nconst ConfirmContainer = ({\n classes = {},\n animationDuration = 300,\n defaultColorSchema = 'dark',\n closeOnEscape = true,\n closeOnClickOutside = true,\n animation = 'slide',\n animationDurationIn,\n animationDurationOut,\n lockScroll = true,\n children,\n id\n}: Props) => {\n const [alerts, setAlerts] = useState<ConfirmOptions[]>([]);\n const [isVisible, setIsVisible] = useState(false);\n const [currentAlert, setCurrentAlert] = useState<ConfirmOptions | null>(null);\n const [isExiting, setIsExiting] = useState(false);\n const [isMounted, setIsMounted] = useState(false);\n const overlayRef = useRef<HTMLDivElement>(null);\n const wrapperRef = useRef<HTMLDivElement>(null);\n const exitTimerRef = useRef<number | null>(null);\n const containerId = useRef(id || `confirm-${makeId()}`)\n const nullElement = <div id={containerId.current} className=\"null-confirm-container\"></div>\n\n useEffect(() => {\n subscribe((newAlerts) => {\n setAlerts(newAlerts);\n });\n }, []);\n\n useEffect(() => {\n ensureStyles()\n }, []);\n\n useEffect(() => {\n if (alerts.length > 0 && !currentAlert && !isExiting) {\n const nextAlert = alerts[0];\n\n // Check if we should show this alert\n const shouldShowAlert =\n !nextAlert.id ||\n nextAlert.id === containerId.current ||\n !getActiveContainerId();\n\n if (shouldShowAlert) {\n // Check if we can become active\n const currentActive = getActiveContainerId();\n\n if (!currentActive || currentActive === containerId.current) {\n if (lockScroll) {\n lockBodyScroll()\n }\n setActiveContainer(containerId.current);\n setIsContainerActive(true);\n\n // Show the alert\n setIsMounted(true);\n setCurrentAlert(nextAlert);\n setIsVisible(true);\n }\n }\n }\n else if (alerts.length === 0 && currentAlert && isVisible) {\n // No more alerts, but we're showing one - start exit\n setIsExiting(true);\n setIsVisible(false);\n\n if (exitTimerRef.current) {\n clearTimeout(exitTimerRef.current);\n }\n\n const exitDuration = animationDurationOut || animationDuration;\n exitTimerRef.current = setTimeout(() => {\n setIsContainerActive(false);\n setIsExiting(false);\n setCurrentAlert(null);\n setIsMounted(false);\n }, exitDuration);\n }\n else if (alerts.length > 0 && currentAlert && alerts[0].id !== currentAlert.id) {\n // New alert with different ID is replacing current one\n setIsExiting(true);\n setIsVisible(false);\n\n if (exitTimerRef.current) {\n clearTimeout(exitTimerRef.current);\n }\n\n const exitDuration = animationDurationOut || animationDuration;\n exitTimerRef.current = setTimeout(() => {\n setIsContainerActive(false);\n setIsExiting(false);\n setCurrentAlert(null);\n setIsMounted(false);\n // The new alert will be picked up in the next render\n }, exitDuration);\n }\n }, [alerts, currentAlert, animationDuration, animationDurationOut, isVisible]);\n\n const handleClose = useCallback(async (value: boolean | null) => {\n if (!currentAlert || isExiting) return;\n\n // Start exit animation immediately\n setIsExiting(true);\n setIsVisible(false);\n\n // Delay the actual closeAlert call until animation completes\n const exitDuration = animationDurationOut || animationDuration;\n\n if (exitTimerRef.current) {\n clearTimeout(exitTimerRef.current);\n }\n\n exitTimerRef.current = setTimeout(() => {\n // Now call closeAlert which will resolve the promise\n closeAlert(value);\n\n // Reset state\n setIsExiting(false);\n setCurrentAlert(null);\n setIsMounted(false);\n setIsContainerActive(false);\n unlockBodyScroll()\n }, exitDuration);\n }, [currentAlert, isExiting, animationDuration, animationDurationOut]);\n\n const handleCancel = useCallback(() => {\n if (currentAlert && isVisible && !isExiting) {\n handleClose(false);\n }\n }, [currentAlert, isVisible, isExiting, handleClose]);\n\n const handleOk = useCallback(() => {\n if (currentAlert && isVisible && !isExiting) {\n handleClose(true);\n }\n }, [currentAlert, isVisible, isExiting, handleClose]);\n\n const handleEscKey = useCallback((event: KeyboardEvent) => {\n if (event.key === 'Escape' && closeOnEscape && currentAlert && isVisible && !isExiting) {\n event.preventDefault();\n event.stopPropagation();\n handleClose(null);\n }\n }, [closeOnEscape, currentAlert, isVisible, isExiting, handleClose]);\n\n useEffect(() => {\n if (currentAlert && isVisible && !isExiting) {\n window.addEventListener('keydown', handleEscKey, { capture: true });\n }\n\n return () => {\n window.removeEventListener('keydown', handleEscKey, { capture: true });\n };\n }, [handleEscKey, currentAlert, isVisible, isExiting]);\n\n useEffect(() => {\n const handleClickOutside = (event: MouseEvent) => {\n if (wrapperRef.current &&\n !wrapperRef.current.contains(event.target as Node) &&\n closeOnClickOutside &&\n currentAlert &&\n isVisible &&\n !isExiting) {\n handleClose(null);\n }\n };\n\n if (currentAlert && isVisible && !isExiting) {\n document.addEventListener(\"mousedown\", handleClickOutside);\n }\n\n return () => {\n document.removeEventListener(\"mousedown\", handleClickOutside);\n };\n }, [closeOnClickOutside, currentAlert, isVisible, isExiting, handleClose]);\n\n // Replace the render conditions with:\n if (!isMounted && !isExiting) {\n return nullElement;\n }\n\n if (!currentAlert || !getIsContainerActive()) {\n return nullElement;\n }\n\n // Always render if we have a current alert\n const colorSchema = currentAlert?.colorSchema || defaultColorSchema;\n const schemaClass = `schema-${colorSchema}`;\n\n const animationStyle: CSSProperties = {};\n const currentDuration = isVisible\n ? (animationDurationIn || animationDuration)\n : (animationDurationOut || animationDuration);\n\n animationStyle.animationDuration = `${currentDuration}ms`;\n animationStyle.animationFillMode = 'forwards';\n\n const animationClass = isVisible\n ? animationPairs[animation as keyof animationPairs].enter\n : animationPairs[animation as keyof animationPairs].exit;\n\n\n // For children render\n if (children && currentAlert && getActiveContainerId() === containerId.current) {\n return (\n <>\n {nullElement}\n {children({\n isVisible: isVisible && !isExiting,\n confirm: currentAlert,\n handleCancel,\n handleOk,\n containerRef: wrapperRef,\n colorSchema,\n animationClass,\n animationStyle\n })}\n </>\n )\n }\n\n return (\n <>\n {nullElement}\n <div\n ref={overlayRef}\n className={cx(\n \"alert-overlay\",\n !isVisible ? \"alert-overlay-exit\" : '',\n `${schemaClass}-overlay`,\n classes.overlay\n )}\n style={animationStyle}\n >\n <div\n ref={wrapperRef}\n className={cx(\n \"alert-wrapper\",\n animationClass,\n `${schemaClass}-wrapper`,\n classes.wrapper\n )}\n style={animationStyle}\n >\n <h2 className={cx(\n \"alert-title\",\n `${schemaClass}-title`,\n classes.title\n )}>\n {currentAlert.title}\n </h2>\n <p className={cx(\n \"alert-message\",\n `${schemaClass}-message`,\n classes.message\n )}>\n {currentAlert.message}\n </p>\n <div className=\"alert-buttons\">\n <button\n onClick={handleCancel}\n disabled={isExiting || !isVisible}\n className={cx(\n \"alert-button alert-button-cancel\",\n `${schemaClass}-cancel`,\n classes.button,\n classes.cancel\n )}\n >\n {currentAlert.cancelText || 'Cancel'}\n </button>\n <button\n onClick={handleOk}\n disabled={isExiting || !isVisible}\n className={cx(\n 'alert-button alert-button-ok',\n `${schemaClass}-ok`,\n classes.button,\n classes.ok\n )}\n >\n {currentAlert.okText || 'OK'}\n </button>\n </div>\n </div>\n </div>\n </>\n );\n};\n\nexport default ConfirmContainer;","import { addAlert, getElement } from \"./confirm_store\";\nimport type { ConfirmInput } from \"./types\";\n\nexport async function confirm(input: string | ConfirmInput, closest?: boolean): Promise<boolean | null> {\n let containerId;\n\n if (typeof input === 'string') {\n if (closest) {\n containerId = await getElement();\n }\n const result = await addAlert({ \n message: input, \n id: containerId\n });\n return result;\n } \n \n if (!input.id) {\n if (closest) { \n containerId = await getElement();\n }\n const result = await addAlert({ \n ...input,\n id: containerId \n });\n return result;\n } \n \n const result = await addAlert(input);\n return result;\n}"]}
|
|
1
|
+
{"version":3,"sources":["../src/confirm_store.ts","../src/confirm.css","../src/animations.css","../src/colorSchemas.css","../src/bundle-css.ts","../src/confirmContainer.tsx","../src/confirm.ts"],"names":["containerId","result"],"mappings":";;;;AAIA,IAAI,WAAA,GAAsB,EAAA;AAC1B,IAAI,WAA6B,EAAC;AAClC,IAAI,SAAA,uBAAgB,GAAA,EAAc;AAClC,IAAI,iBAAA,GAA6B,KAAA;AACjC,IAAI,UAAA,GAAkC,QAAA,CAAS,gBAAA,CAAiB,yBAAyB,CAAA;AACzF,IAAI,SAAA,GAAY,KAAA;AAET,SAAS,WAAA,GAAc;AAC5B,EAAA,SAAA,GAAY,IAAA;AACd;AAEO,SAAS,SAAA,GAAY;AAC1B,EAAA,OAAO,SAAA;AACT;AAGA,IAAI,iBAAA,GAAmC,IAAA;AAEhC,SAAS,qBAAqB,KAAA,EAAgB;AACnD,EAAA,iBAAA,GAAoB,KAAA;AACtB;AAEO,SAAS,oBAAA,GAAuB;AACrC,EAAA,OAAO,iBAAA;AACT;AAEO,SAAS,mBAAmB,EAAA,EAAmB;AACpD,EAAA,iBAAA,GAAoB,EAAA;AACtB;AAEO,SAAS,oBAAA,GAAsC;AACpD,EAAA,OAAO,iBAAA;AACT;AAEO,SAAS,MAAA,GAAS;AACvB,EAAA,IAAI,OAAO,MAAA,KAAW,WAAA,IAAe,MAAA,CAAO,UAAA,EAAY;AACtD,IAAA,OAAO,OAAO,UAAA,EAAW;AAAA,EAC3B,CAAA,MAAO;AAEL,IAAA,OAAA,CAAQ,MAAM,uFAAuF,CAAA;AACrG,IAAA,OAAO,IAAA,CAAK,MAAA,EAAO,CAAE,QAAA,CAAS,EAAE,CAAA,CAAE,SAAA,CAAU,CAAC,CAAA,GAAI,IAAA,CAAK,GAAA,EAAI,CAAE,SAAS,EAAE,CAAA;AAAA,EACzE;AACF;AAEA,eAAsB,SAAS,KAAA,EAA8C;AAC3E,EAAA,OAAO,IAAI,OAAA,CAAQ,CAAC,OAAA,KAAY;AAC9B,IAAA,MAAM,KAAA,GAAwB;AAAA,MAC5B,EAAA,EAAI,MAAM,EAAA,IAAM,EAAA;AAAA;AAAA,MAChB,KAAA,EAAO,MAAM,KAAA,IAAS,SAAA;AAAA,MACtB,SAAS,KAAA,CAAM,OAAA;AAAA,MACf,QAAQ,KAAA,CAAM,MAAA;AAAA,MACd,YAAY,KAAA,CAAM,UAAA;AAAA,MAClB,aAAa,KAAA,CAAM,WAAA;AAAA,MACnB;AAAA,KACF;AAEA,IAAA,QAAA,GAAW,CAAC,GAAG,QAAA,EAAU,KAAK,CAAA;AAG9B,IAAA,IAAI,MAAM,EAAA,EAAI;AACZ,MAAA,kBAAA,CAAmB,MAAM,EAAE,CAAA;AAAA,IAC7B,CAAA,MAGK;AACH,MAAA,kBAAA,CAAmB,IAAI,CAAA;AAAA,IACzB;AAEA,IAAA,IAAI,QAAA,CAAS,WAAW,CAAA,EAAG;AACzB,MAAA,IAAA,EAAK;AAAA,IACP;AAAA,EACF,CAAC,CAAA;AACH;AAEA,eAAsB,WAAW,MAAA,EAAwB;AACvD,EAAA,MAAM,KAAA,GAAQ,SAAS,CAAC,CAAA;AACxB,EAAA,WAAA,GAAc,EAAA;AACd,EAAA,IAAI,CAAC,KAAA,EAAO;AAGZ,EAAA,KAAA,CAAM,QAAQ,MAAM,CAAA;AAEpB,EAAA,QAAA,GAAW,QAAA,CAAS,MAAM,CAAC,CAAA;AAG3B,EAAA,IAAI,QAAA,CAAS,WAAW,CAAA,EAAG;AACzB,IAAA,kBAAA,CAAmB,IAAI,CAAA;AAAA,EACzB;AAEA,EAAA,IAAA,EAAK;AACP;AAEO,SAAS,UAAU,QAAA,EAAoB;AAC5C,EAAA,SAAA,CAAU,IAAI,QAAQ,CAAA;AACtB,EAAA,QAAA,CAAS,QAAQ,CAAA;AACjB,EAAA,OAAO,MAAM,SAAA,CAAU,MAAA,CAAO,QAAQ,CAAA;AACxC;AAEO,SAAS,IAAA,GAAO;AACrB,EAAA,SAAA,CAAU,OAAA,CAAQ,CAAC,QAAA,KAAa,QAAA,CAAS,QAAQ,CAAC,CAAA;AACpD;AAEA,IAAM,aAAA,GAAgB,CAAC,CAAA,KAAoB;AACzC,EAAA,IAAI,UAAA,CAAW,WAAW,CAAA,EAAG;AAC3B,IAAA,UAAA,GAAa,QAAA,CAAS,iBAAiB,yBAAyB,CAAA;AAAA,EAClE;AACA,EAAA,IAAI,UAAA,CAAW,WAAW,CAAA,EAAG;AAE7B,EAAA,IAAI,aAAA,GAAgB,CAAA,CAAE,IAAA,EAAM,QAAA,CAAS,aAAA,EAAe,aAAA;AACpD,EAAA,IAAI,SAAA,GAAY,aAAA,EAAe,aAAA,CAAc,yBAAyB,CAAA;AAEtE,EAAA,OAAO,IAAA,EAAM;AACX,IAAA,IAAI,WAAW,EAAA,EAAI;AACjB,MAAA;AAAA,IACF;AACA,IAAA,aAAA,GAAgB,aAAA,EAAe,aAAA;AAC/B,IAAA,SAAA,GAAY,aAAA,EAAe,cAAc,yBAAyB,CAAA;AAAA,EACpE;AAEA,EAAA,IAAI,WAAW,EAAA,EAAI;AACjB,IAAA,WAAA,GAAc,SAAA,CAAU,EAAA;AAAA,EAC1B;AACF,CAAA;AAEA,eAAsB,UAAA,GAAa;AACjC,EAAA,QAAA,CAAS,iBAAiB,OAAA,EAAS,aAAA,EAAe,EAAE,IAAA,EAAM,MAAM,CAAA;AAChE,EAAA,MAAM,IAAI,OAAA,CAAc,CAAC,OAAA,KAAY;AACnC,IAAA,UAAA,CAAW,MAAM;AACf,MAAA,QAAA,CAAS,mBAAA,CAAoB,SAAS,aAAa,CAAA;AACnD,MAAA,OAAA,EAAQ;AAAA,IACV,GAAG,CAAC,CAAA;AAAA,EACN,CAAC,CAAA;AACD,EAAA,IAAI,gBAAgB,EAAA,EAAI;AACtB,IAAA,IAAI,UAAA,CAAW,WAAW,CAAA,EAAG;AAC7B,IAAA,WAAA,GAAc,UAAA,CAAW,CAAC,CAAA,CAAE,EAAA;AAC5B,IAAA,OAAO,WAAA;AAAA,EACT;AACA,EAAA,OAAO,WAAA;AACT;AAGA,IAAM,iBAAA,GAAN,MAAM,kBAAA,CAAkB;AAAA,EAKd,WAAA,GAAc;AAHtB,IAAA,IAAA,CAAQ,cAAA,GAAiB,CAAA;AACzB,IAAA,IAAA,CAAQ,QAAA,GAAW,KAAA;AAAA,EAEK;AAAA,EAExB,OAAO,WAAA,GAAiC;AACtC,IAAA,IAAI,CAAC,mBAAkB,QAAA,EAAU;AAC/B,MAAA,kBAAA,CAAkB,QAAA,GAAW,IAAI,kBAAA,EAAkB;AAAA,IACrD;AACA,IAAA,OAAO,kBAAA,CAAkB,QAAA;AAAA,EAC3B;AAAA,EAEA,IAAA,GAAO;AACL,IAAA,IAAI,KAAK,QAAA,EAAU;AAGnB,IAAA,IAAA,CAAK,iBAAiB,MAAA,CAAO,OAAA;AAG7B,IAAA,MAAM,cAAA,GAAiB,MAAA,CAAO,UAAA,GAAa,QAAA,CAAS,eAAA,CAAgB,WAAA;AAGpE,IAAA,QAAA,CAAS,IAAA,CAAK,KAAA,CAAM,YAAA,GAAe,CAAA,EAAG,cAAc,CAAA,EAAA,CAAA;AAGpD,IAAA,QAAA,CAAS,eAAA,CAAgB,MAAM,QAAA,GAAW,QAAA;AAC1C,IAAA,QAAA,CAAS,IAAA,CAAK,MAAM,QAAA,GAAW,QAAA;AAG/B,IAAA,QAAA,CAAS,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,eAAe,CAAA;AAE3C,IAAA,IAAA,CAAK,QAAA,GAAW,IAAA;AAAA,EAClB;AAAA,EAEA,MAAA,GAAS;AACP,IAAA,IAAI,CAAC,KAAK,QAAA,EAAU;AAGpB,IAAA,QAAA,CAAS,eAAA,CAAgB,MAAM,QAAA,GAAW,EAAA;AAC1C,IAAA,QAAA,CAAS,IAAA,CAAK,MAAM,QAAA,GAAW,EAAA;AAG/B,IAAA,QAAA,CAAS,IAAA,CAAK,MAAM,YAAA,GAAe,EAAA;AAGnC,IAAA,QAAA,CAAS,IAAA,CAAK,SAAA,CAAU,MAAA,CAAO,eAAe,CAAA;AAG9C,IAAA,MAAA,CAAO,QAAA,CAAS,CAAA,EAAG,IAAA,CAAK,cAAc,CAAA;AAEtC,IAAA,IAAA,CAAK,QAAA,GAAW,KAAA;AAAA,EAClB;AACF,CAAA;AAGO,IAAM,cAAA,GAAiB,MAAM,iBAAA,CAAkB,WAAA,GAAc,IAAA,EAAK;AAClE,IAAM,gBAAA,GAAmB,MAAM,iBAAA,CAAkB,WAAA,GAAc,MAAA,EAAO;;;AC3M7E,IAAA,eAAA,GAAA,ghLAAA;;;ACAA,IAAA,kBAAA,GAAA,u2PAAA;;;ACAA,IAAA,oBAAA,GAAA,o7NAAA;;;ACKA,IAAM,OAAA,GAAU,GAAG,eAAU;AAAA,EAAK,kBAAa;AAAA,EAAK,oBAAe,CAAA,CAAA;AAEnE,IAAI,cAAA,GAAiB,KAAA;AAEd,SAAS,YAAA,GAAe;AAC7B,EAAA,IAAI,OAAO,aAAa,WAAA,EAAa;AACnC,IAAA;AAAA,EACF;AAEA,EAAA,IAAI,cAAA,EAAgB;AAClB,IAAA;AAAA,EACF;AAGA,EAAA,MAAM,KAAA,GAAQ,QAAA,CAAS,aAAA,CAAc,OAAO,CAAA;AAC5C,EAAA,KAAA,CAAM,YAAA,CAAa,2BAA2B,EAAE,CAAA;AAChD,EAAA,KAAA,CAAM,WAAA,GAAc,OAAA;AACpB,EAAA,QAAA,CAAS,IAAA,CAAK,YAAY,KAAK,CAAA;AAE/B,EAAA,cAAA,GAAiB,IAAA;AACnB;AChBA,SAAS,MAAM,OAAA,EAAiC;AAC9C,EAAA,OAAO,OAAA,CAAQ,MAAA,CAAO,OAAO,CAAA,CAAE,KAAK,GAAG,CAAA;AACzC;AAEA,IAAM,cAAA,GAAiB;AAAA,EACrB,KAAA,EAAO,EAAE,KAAA,EAAO,EAAA,EAAI,MAAM,oBAAA,EAAqB;AAAA,EAC/C,SAAA,EAAW,EAAE,KAAA,EAAO,2BAAA,EAA6B,MAAM,4BAAA,EAA6B;AAAA,EACpF,MAAA,EAAQ,EAAE,KAAA,EAAO,wBAAA,EAA0B,MAAM,yBAAA,EAA0B;AAAA,EAC3E,IAAA,EAAM,EAAE,KAAA,EAAO,sBAAA,EAAwB,MAAM,uBAAA,EAAwB;AAAA,EACrE,IAAA,EAAM,EAAE,KAAA,EAAO,sBAAA,EAAwB,MAAM,uBAAA,EAAwB;AAAA,EACrE,MAAA,EAAQ,EAAE,KAAA,EAAO,wBAAA,EAA0B,MAAM,yBAAA,EAA0B;AAAA,EAC3E,MAAA,EAAQ,EAAE,KAAA,EAAO,wBAAA,EAA0B,MAAM,2BAAA,EAA4B;AAAA,EAC7E,IAAA,EAAM,EAAE,KAAA,EAAO,sBAAA,EAAwB,MAAM,uBAAA,EAAwB;AAAA,EACrE,UAAA,EAAY,EAAE,KAAA,EAAO,4BAAA,EAA8B,MAAM,4BAAA,EAA6B;AAAA,EACtF,SAAA,EAAW,EAAE,KAAA,EAAO,2BAAA,EAA6B,MAAM,6BAAA,EAA8B;AAAA,EACrF,QAAA,EAAU,EAAE,KAAA,EAAO,0BAAA,EAA4B,MAAM,yBAAA,EAA0B;AAAA,EAC/E,aAAA,EAAe,EAAE,KAAA,EAAO,2BAAA,EAA6B,MAAM,0BAAA,EAA2B;AAAA,EACtF,WAAA,EAAa,EAAE,KAAA,EAAO,6BAAA,EAA+B,MAAM,6BAAA,EAA8B;AAAA,EACzF,SAAA,EAAW,EAAE,KAAA,EAAO,2BAAA,EAA6B,MAAM,4BAAA,EAA6B;AAAA,EACpF,WAAA,EAAa,EAAE,KAAA,EAAO,6BAAA,EAA+B,MAAM,8BAAA,EAA+B;AAAA,EAC1F,QAAA,EAAU,EAAE,KAAA,EAAO,0BAAA,EAA4B,MAAM,2BAAA,EAA4B;AAAA,EACjF,UAAA,EAAY,EAAE,KAAA,EAAO,4BAAA,EAA8B,MAAM,6BAAA;AAC3D,CAAA;AAyBA,IAAM,mBAAmB,CAAC;AAAA,EACxB,UAAU,EAAC;AAAA,EACX,iBAAA,GAAoB,GAAA;AAAA,EACpB,kBAAA,GAAqB,MAAA;AAAA,EACrB,aAAA,GAAgB,IAAA;AAAA,EAChB,mBAAA,GAAsB,IAAA;AAAA,EACtB,SAAA,GAAY,OAAA;AAAA,EACZ,mBAAA;AAAA,EACA,oBAAA;AAAA,EACA,UAAA,GAAa,IAAA;AAAA,EACb,QAAA;AAAA,EACA;AACF,CAAA,KAAa;AACX,EAAA,MAAM,CAAC,MAAA,EAAQ,SAAS,CAAA,GAAI,QAAA,CAA2B,EAAE,CAAA;AACzD,EAAA,MAAM,CAAC,SAAA,EAAW,YAAY,CAAA,GAAI,SAAS,KAAK,CAAA;AAChD,EAAA,MAAM,CAAC,YAAA,EAAc,eAAe,CAAA,GAAI,SAAgC,IAAI,CAAA;AAC5E,EAAA,MAAM,CAAC,SAAA,EAAW,YAAY,CAAA,GAAI,SAAS,KAAK,CAAA;AAChD,EAAA,MAAM,CAAC,SAAA,EAAW,YAAY,CAAA,GAAI,SAAS,KAAK,CAAA;AAChD,EAAA,MAAM,UAAA,GAAa,OAAuB,IAAI,CAAA;AAC9C,EAAA,MAAM,UAAA,GAAa,OAAuB,IAAI,CAAA;AAC9C,EAAA,MAAM,YAAA,GAAe,OAAsB,IAAI,CAAA;AAC/C,EAAA,MAAMA,eAAc,MAAA,CAAO,EAAA,IAAM,CAAA,QAAA,EAAW,MAAA,EAAQ,CAAA,CAAE,CAAA;AACtD,EAAA,MAAM,8BAAc,GAAA,CAAC,KAAA,EAAA,EAAI,IAAIA,YAAAA,CAAY,OAAA,EAAS,WAAU,wBAAA,EAAyB,CAAA;AAErF,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,SAAA,CAAU,CAAC,SAAA,KAAc;AACvB,MAAA,SAAA,CAAU,SAAS,CAAA;AAAA,IACrB,CAAC,CAAA;AAAA,EACH,CAAA,EAAG,EAAE,CAAA;AAEL,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,YAAA,EAAa;AAAA,EACf,CAAA,EAAG,EAAE,CAAA;AAEL,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI,OAAO,MAAA,GAAS,CAAA,IAAK,CAAC,YAAA,IAAgB,CAAC,SAAA,EAAW;AACpD,MAAA,MAAM,SAAA,GAAY,OAAO,CAAC,CAAA;AAG1B,MAAA,MAAM,eAAA,GACJ,CAAC,SAAA,CAAU,EAAA,IACX,UAAU,EAAA,KAAOA,YAAAA,CAAY,OAAA,IAC7B,CAAC,oBAAA,EAAqB;AAExB,MAAA,IAAI,eAAA,EAAiB;AAEnB,QAAA,MAAM,gBAAgB,oBAAA,EAAqB;AAE3C,QAAA,IAAI,CAAC,aAAA,IAAiB,aAAA,KAAkBA,YAAAA,CAAY,OAAA,EAAS;AAC3D,UAAA,IAAI,UAAA,EAAY;AACd,YAAA,cAAA,EAAe;AAAA,UACjB;AACA,UAAA,kBAAA,CAAmBA,aAAY,OAAO,CAAA;AACtC,UAAA,oBAAA,CAAqB,IAAI,CAAA;AAGzB,UAAA,YAAA,CAAa,IAAI,CAAA;AACjB,UAAA,eAAA,CAAgB,SAAS,CAAA;AACzB,UAAA,YAAA,CAAa,IAAI,CAAA;AAAA,QACnB;AAAA,MACF;AAAA,IACF,CAAA,MAAA,IACS,MAAA,CAAO,MAAA,KAAW,CAAA,IAAK,gBAAgB,SAAA,EAAW;AAEzD,MAAA,YAAA,CAAa,IAAI,CAAA;AACjB,MAAA,YAAA,CAAa,KAAK,CAAA;AAElB,MAAA,IAAI,aAAa,OAAA,EAAS;AACxB,QAAA,YAAA,CAAa,aAAa,OAAO,CAAA;AAAA,MACnC;AAEA,MAAA,MAAM,eAAe,oBAAA,IAAwB,iBAAA;AAC7C,MAAA,YAAA,CAAa,OAAA,GAAU,WAAW,MAAM;AACtC,QAAA,oBAAA,CAAqB,KAAK,CAAA;AAC1B,QAAA,YAAA,CAAa,KAAK,CAAA;AAClB,QAAA,eAAA,CAAgB,IAAI,CAAA;AACpB,QAAA,YAAA,CAAa,KAAK,CAAA;AAAA,MACpB,GAAG,YAAY,CAAA;AAAA,IACjB,CAAA,MAAA,IACS,MAAA,CAAO,MAAA,GAAS,CAAA,IAAK,YAAA,IAAgB,OAAO,CAAC,CAAA,CAAE,EAAA,KAAO,YAAA,CAAa,EAAA,EAAI;AAE9E,MAAA,YAAA,CAAa,IAAI,CAAA;AACjB,MAAA,YAAA,CAAa,KAAK,CAAA;AAElB,MAAA,IAAI,aAAa,OAAA,EAAS;AACxB,QAAA,YAAA,CAAa,aAAa,OAAO,CAAA;AAAA,MACnC;AAEA,MAAA,MAAM,eAAe,oBAAA,IAAwB,iBAAA;AAC7C,MAAA,YAAA,CAAa,OAAA,GAAU,WAAW,MAAM;AACtC,QAAA,oBAAA,CAAqB,KAAK,CAAA;AAC1B,QAAA,YAAA,CAAa,KAAK,CAAA;AAClB,QAAA,eAAA,CAAgB,IAAI,CAAA;AACpB,QAAA,YAAA,CAAa,KAAK,CAAA;AAAA,MAEpB,GAAG,YAAY,CAAA;AAAA,IACjB;AAAA,EACF,GAAG,CAAC,MAAA,EAAQ,cAAc,iBAAA,EAAmB,oBAAA,EAAsB,SAAS,CAAC,CAAA;AAE7E,EAAA,MAAM,WAAA,GAAc,WAAA,CAAY,OAAO,KAAA,KAA0B;AAC/D,IAAA,IAAI,CAAC,gBAAgB,SAAA,EAAW;AAGhC,IAAA,YAAA,CAAa,IAAI,CAAA;AACjB,IAAA,YAAA,CAAa,KAAK,CAAA;AAGlB,IAAA,MAAM,eAAe,oBAAA,IAAwB,iBAAA;AAE7C,IAAA,IAAI,aAAa,OAAA,EAAS;AACxB,MAAA,YAAA,CAAa,aAAa,OAAO,CAAA;AAAA,IACnC;AAEA,IAAA,YAAA,CAAa,OAAA,GAAU,WAAW,MAAM;AAEtC,MAAA,UAAA,CAAW,KAAK,CAAA;AAGhB,MAAA,YAAA,CAAa,KAAK,CAAA;AAClB,MAAA,eAAA,CAAgB,IAAI,CAAA;AACpB,MAAA,YAAA,CAAa,KAAK,CAAA;AAClB,MAAA,oBAAA,CAAqB,KAAK,CAAA;AAC1B,MAAA,gBAAA,EAAiB;AAAA,IACnB,GAAG,YAAY,CAAA;AAAA,EACjB,GAAG,CAAC,YAAA,EAAc,SAAA,EAAW,iBAAA,EAAmB,oBAAoB,CAAC,CAAA;AAErE,EAAA,MAAM,YAAA,GAAe,YAAY,MAAM;AACrC,IAAA,IAAI,YAAA,IAAgB,SAAA,IAAa,CAAC,SAAA,EAAW;AAC3C,MAAA,WAAA,CAAY,KAAK,CAAA;AAAA,IACnB;AAAA,EACF,GAAG,CAAC,YAAA,EAAc,SAAA,EAAW,SAAA,EAAW,WAAW,CAAC,CAAA;AAEpD,EAAA,MAAM,QAAA,GAAW,YAAY,MAAM;AACjC,IAAA,IAAI,YAAA,IAAgB,SAAA,IAAa,CAAC,SAAA,EAAW;AAC3C,MAAA,WAAA,CAAY,IAAI,CAAA;AAAA,IAClB;AAAA,EACF,GAAG,CAAC,YAAA,EAAc,SAAA,EAAW,SAAA,EAAW,WAAW,CAAC,CAAA;AAEpD,EAAA,MAAM,YAAA,GAAe,WAAA,CAAY,CAAC,KAAA,KAAyB;AACzD,IAAA,IAAI,MAAM,GAAA,KAAQ,QAAA,IAAY,iBAAiB,YAAA,IAAgB,SAAA,IAAa,CAAC,SAAA,EAAW;AACtF,MAAA,KAAA,CAAM,cAAA,EAAe;AACrB,MAAA,KAAA,CAAM,eAAA,EAAgB;AACtB,MAAA,WAAA,CAAY,IAAI,CAAA;AAAA,IAClB;AAAA,EACF,GAAG,CAAC,aAAA,EAAe,cAAc,SAAA,EAAW,SAAA,EAAW,WAAW,CAAC,CAAA;AAEnE,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI,YAAA,IAAgB,SAAA,IAAa,CAAC,SAAA,EAAW;AAC3C,MAAA,MAAA,CAAO,iBAAiB,SAAA,EAAW,YAAA,EAAc,EAAE,OAAA,EAAS,MAAM,CAAA;AAAA,IACpE;AAEA,IAAA,OAAO,MAAM;AACX,MAAA,MAAA,CAAO,oBAAoB,SAAA,EAAW,YAAA,EAAc,EAAE,OAAA,EAAS,MAAM,CAAA;AAAA,IACvE,CAAA;AAAA,EACF,GAAG,CAAC,YAAA,EAAc,YAAA,EAAc,SAAA,EAAW,SAAS,CAAC,CAAA;AAErD,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,MAAM,kBAAA,GAAqB,CAAC,KAAA,KAAsB;AAChD,MAAA,IAAI,UAAA,CAAW,OAAA,IACb,CAAC,UAAA,CAAW,OAAA,CAAQ,QAAA,CAAS,KAAA,CAAM,MAAc,CAAA,IACjD,mBAAA,IACA,YAAA,IACA,SAAA,IACA,CAAC,SAAA,EAAW;AACZ,QAAA,WAAA,CAAY,IAAI,CAAA;AAAA,MAClB;AAAA,IACF,CAAA;AAEA,IAAA,IAAI,YAAA,IAAgB,SAAA,IAAa,CAAC,SAAA,EAAW;AAC3C,MAAA,QAAA,CAAS,gBAAA,CAAiB,aAAa,kBAAkB,CAAA;AAAA,IAC3D;AAEA,IAAA,OAAO,MAAM;AACX,MAAA,QAAA,CAAS,mBAAA,CAAoB,aAAa,kBAAkB,CAAA;AAAA,IAC9D,CAAA;AAAA,EACF,GAAG,CAAC,mBAAA,EAAqB,cAAc,SAAA,EAAW,SAAA,EAAW,WAAW,CAAC,CAAA;AAGzE,EAAA,IAAI,CAAC,SAAA,IAAa,CAAC,SAAA,EAAW;AAC5B,IAAA,OAAO,WAAA;AAAA,EACT;AAEA,EAAA,IAAI,CAAC,YAAA,IAAgB,CAAC,oBAAA,EAAqB,EAAG;AAC5C,IAAA,OAAO,WAAA;AAAA,EACT;AAGA,EAAA,MAAM,WAAA,GAAc,cAAc,WAAA,IAAe,kBAAA;AACjD,EAAA,MAAM,WAAA,GAAc,UAAU,WAAW,CAAA,CAAA;AAEzC,EAAA,MAAM,iBAAgC,EAAC;AACvC,EAAA,MAAM,eAAA,GAAkB,SAAA,GACnB,mBAAA,IAAuB,iBAAA,GACvB,oBAAA,IAAwB,iBAAA;AAE7B,EAAA,cAAA,CAAe,iBAAA,GAAoB,GAAG,eAAe,CAAA,EAAA,CAAA;AACrD,EAAA,cAAA,CAAe,iBAAA,GAAoB,UAAA;AAEnC,EAAA,MAAM,cAAA,GAAiB,YACnB,cAAA,CAAe,SAAiC,EAAE,KAAA,GAClD,cAAA,CAAe,SAAiC,CAAA,CAAE,IAAA;AAItD,EAAA,IAAI,QAAA,IAAY,YAAA,IAAgB,oBAAA,EAAqB,KAAMA,aAAY,OAAA,EAAS;AAC9E,IAAA,uBACE,IAAA,CAAA,QAAA,EAAA,EACG,QAAA,EAAA;AAAA,MAAA,WAAA;AAAA,MACA,QAAA,CAAS;AAAA,QACR,SAAA,EAAW,aAAa,CAAC,SAAA;AAAA,QACzB,OAAA,EAAS,YAAA;AAAA,QACT,YAAA;AAAA,QACA,QAAA;AAAA,QACA,YAAA,EAAc,UAAA;AAAA,QACd,WAAA;AAAA,QACA,cAAA;AAAA,QACA;AAAA,OACD;AAAA,KAAA,EACH,CAAA;AAAA,EAEJ;AAEA,EAAA,uBACE,IAAA,CAAA,QAAA,EAAA,EACG,QAAA,EAAA;AAAA,IAAA,WAAA;AAAA,oBACD,GAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QACC,GAAA,EAAK,UAAA;AAAA,QACL,SAAA,EAAW,EAAA;AAAA,UACT,eAAA;AAAA,UACA,CAAC,YAAY,oBAAA,GAAuB,EAAA;AAAA,UACpC,GAAG,WAAW,CAAA,QAAA,CAAA;AAAA,UACd,OAAA,CAAQ;AAAA,SACV;AAAA,QACA,KAAA,EAAO,cAAA;AAAA,QAEP,QAAA,kBAAA,IAAA;AAAA,UAAC,KAAA;AAAA,UAAA;AAAA,YACC,GAAA,EAAK,UAAA;AAAA,YACL,SAAA,EAAW,EAAA;AAAA,cACT,eAAA;AAAA,cACA,cAAA;AAAA,cACA,GAAG,WAAW,CAAA,QAAA,CAAA;AAAA,cACd,OAAA,CAAQ;AAAA,aACV;AAAA,YACA,KAAA,EAAO,cAAA;AAAA,YAEP,QAAA,EAAA;AAAA,8BAAA,GAAA,CAAC,QAAG,SAAA,EAAW,EAAA;AAAA,gBACb,aAAA;AAAA,gBACA,GAAG,WAAW,CAAA,MAAA,CAAA;AAAA,gBACd,OAAA,CAAQ;AAAA,eACV,EACG,uBAAa,KAAA,EAChB,CAAA;AAAA,8BACA,GAAA,CAAC,OAAE,SAAA,EAAW,EAAA;AAAA,gBACZ,eAAA;AAAA,gBACA,GAAG,WAAW,CAAA,QAAA,CAAA;AAAA,gBACd,OAAA,CAAQ;AAAA,eACV,EACG,uBAAa,OAAA,EAChB,CAAA;AAAA,8BACA,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,eAAA,EACb,QAAA,EAAA;AAAA,gCAAA,GAAA;AAAA,kBAAC,QAAA;AAAA,kBAAA;AAAA,oBACC,OAAA,EAAS,YAAA;AAAA,oBACT,QAAA,EAAU,aAAa,CAAC,SAAA;AAAA,oBACxB,SAAA,EAAW,EAAA;AAAA,sBACT,kCAAA;AAAA,sBACA,GAAG,WAAW,CAAA,OAAA,CAAA;AAAA,sBACd,OAAA,CAAQ,MAAA;AAAA,sBACR,OAAA,CAAQ;AAAA,qBACV;AAAA,oBAEC,uBAAa,UAAA,IAAc;AAAA;AAAA,iBAC9B;AAAA,gCACA,GAAA;AAAA,kBAAC,QAAA;AAAA,kBAAA;AAAA,oBACC,OAAA,EAAS,QAAA;AAAA,oBACT,QAAA,EAAU,aAAa,CAAC,SAAA;AAAA,oBACxB,SAAA,EAAW,EAAA;AAAA,sBACT,8BAAA;AAAA,sBACA,GAAG,WAAW,CAAA,GAAA,CAAA;AAAA,sBACd,OAAA,CAAQ,MAAA;AAAA,sBACR,OAAA,CAAQ;AAAA,qBACV;AAAA,oBAEC,uBAAa,MAAA,IAAU;AAAA;AAAA;AAC1B,eAAA,EACF;AAAA;AAAA;AAAA;AACF;AAAA;AACF,GAAA,EACF,CAAA;AAEJ,CAAA;AAEA,IAAO,wBAAA,GAAQ;;;ACvVf,eAAsB,OAAA,CAAQ,KAAA,EAA8B,OAAA,GAA0B,IAAA,EAA+B;AACnH,EAAA,IAAIA,YAAAA;AAEJ,EAAA,IAAI,OAAO,UAAU,QAAA,EAAU;AAC7B,IAAA,IAAI,OAAA,EAAS;AACX,MAAAA,YAAAA,GAAc,MAAM,UAAA,EAAW;AAAA,IACjC,CAAA,MAAA,IAAW,OAAA,KAAY,IAAA,IAAQ,SAAA,OAAgB,IAAA,EAAM;AACnD,MAAAA,YAAAA,GAAc,MAAM,UAAA,EAAW;AAAA,IACjC;AACA,IAAA,MAAMC,OAAAA,GAAS,MAAM,QAAA,CAAS;AAAA,MAC5B,OAAA,EAAS,KAAA;AAAA,MACT,EAAA,EAAID;AAAA,KACL,CAAA;AACD,IAAA,OAAOC,OAAAA;AAAA,EACT;AAEA,EAAA,IAAI,CAAC,MAAM,EAAA,EAAI;AACb,IAAA,IAAI,OAAA,EAAS;AACX,MAAAD,YAAAA,GAAc,MAAM,UAAA,EAAW;AAAA,IACjC,CAAA,MAAA,IAAW,OAAA,KAAY,IAAA,IAAQ,SAAA,OAAgB,IAAA,EAAM;AACnD,MAAAA,YAAAA,GAAc,MAAM,UAAA,EAAW;AAAA,IACjC;AACA,IAAA,MAAMC,OAAAA,GAAS,MAAM,QAAA,CAAS;AAAA,MAC5B,GAAG,KAAA;AAAA,MACH,EAAA,EAAID;AAAA,KACL,CAAA;AACD,IAAA,OAAOC,OAAAA;AAAA,EACT;AAEA,EAAA,MAAM,MAAA,GAAS,MAAM,QAAA,CAAS,KAAK,CAAA;AACnC,EAAA,OAAO,MAAA;AACT","file":"index.js","sourcesContent":["import type { ConfirmOptions, ConfirmInput } from \"./types\";\n\ntype Listener = (alerts: ConfirmOptions[]) => void;\n\nlet containerId: string = '';\nlet confirms: ConfirmOptions[] = [];\nlet listeners = new Set<Listener>();\nlet isActiveContainer: boolean = false\nlet containers: NodeListOf<Element> = document.querySelectorAll('.null-confirm-container');\nlet showClose = false\n\nexport function showClosest() {\n showClose = true\n}\n\nexport function isClosest() {\n return showClose\n}\n\n// Global lock - only ONE container can show alerts at a time\nlet activeContainerId: string | null = null;\n\nexport function setIsContainerActive(value: boolean) {\n isActiveContainer = value;\n}\n\nexport function getIsContainerActive() {\n return isActiveContainer;\n}\n\nexport function setActiveContainer(id: string | null) {\n activeContainerId = id;\n}\n\nexport function getActiveContainerId(): string | null {\n return activeContainerId;\n}\n\nexport function makeId() {\n if (typeof crypto !== 'undefined' && crypto.randomUUID) {\n return crypto.randomUUID();\n } else {\n // Fallback for older environments if necessary, though this method is widely supported.\n console.error(\"crypto.randomUUID is not supported in this environment. Using less reliable fallback.\");\n return Math.random().toString(36).substring(2) + Date.now().toString(36);\n }\n}\n\nexport async function addAlert(input: ConfirmInput): Promise<boolean | null> {\n return new Promise((resolve) => {\n const alert: ConfirmOptions = {\n id: input.id || '', // Keep the ID for container targeting\n title: input.title || \"Confirm\",\n message: input.message,\n okText: input.okText,\n cancelText: input.cancelText,\n colorSchema: input.colorSchema,\n resolve\n };\n\n confirms = [...confirms, alert];\n\n // If this alert has an ID, set it as the active container\n if (input.id) {\n setActiveContainer(input.id);\n }\n // If this alert doesn't have an ID, clear any active container\n // so any container can potentially show it\n else {\n setActiveContainer(null);\n }\n\n if (confirms.length === 1) {\n emit();\n }\n });\n}\n\nexport async function closeAlert(result: boolean | null) {\n const alert = confirms[0];\n containerId = '';\n if (!alert) return;\n\n // Resolve current alert\n alert.resolve(result);\n // Remove from queue\n confirms = confirms.slice(1);\n\n // If there are no more alerts, clear the active container\n if (confirms.length === 0) {\n setActiveContainer(null);\n }\n\n emit();\n}\n\nexport function subscribe(listener: Listener) {\n listeners.add(listener);\n listener(confirms);\n return () => listeners.delete(listener);\n}\n\nexport function emit() {\n listeners.forEach((listener) => listener(confirms));\n}\n\nconst EventListener = (e: PointerEvent) => {\n if (containers.length === 0) {\n containers = document.querySelectorAll('.null-confirm-container');\n }\n if (containers.length === 0) return;\n\n let parentElement = e.view?.document.activeElement?.parentElement;\n let container = parentElement?.querySelector('.null-confirm-container');\n\n while (true) {\n if (container?.id) {\n break;\n }\n parentElement = parentElement?.parentElement;\n container = parentElement?.querySelector('.null-confirm-container');\n }\n\n if (container?.id) {\n containerId = container.id;\n }\n}\n\nexport async function getElement() {\n document.addEventListener('click', EventListener, { once: true })\n await new Promise<void>((resolve) => {\n setTimeout(() => {\n document.removeEventListener('click', EventListener)\n resolve()\n }, 0);\n })\n if (containerId === '') {\n if (containers.length === 0) return;\n containerId = containers[0].id\n return containerId\n }\n return containerId;\n}\n\n// Create a scroll lock manager\nclass ScrollLockManager {\n private static instance: ScrollLockManager;\n private scrollPosition = 0;\n private isLocked = false;\n\n private constructor() { }\n\n static getInstance(): ScrollLockManager {\n if (!ScrollLockManager.instance) {\n ScrollLockManager.instance = new ScrollLockManager();\n }\n return ScrollLockManager.instance;\n }\n\n lock() {\n if (this.isLocked) return;\n\n // Save current scroll position\n this.scrollPosition = window.scrollY;\n\n // Get scrollbar width BEFORE hiding it\n const scrollbarWidth = window.innerWidth - document.documentElement.clientWidth;\n\n // Add padding to body BEFORE hiding scrollbar (prevents layout shift)\n document.body.style.paddingRight = `${scrollbarWidth}px`;\n\n // Lock scroll on both html and body\n document.documentElement.style.overflow = 'hidden';\n document.body.style.overflow = 'hidden';\n\n // Add class for any additional CSS\n document.body.classList.add('scroll-locked');\n\n this.isLocked = true;\n }\n\n unlock() {\n if (!this.isLocked) return;\n\n // Remove overflow hidden\n document.documentElement.style.overflow = '';\n document.body.style.overflow = '';\n\n // Remove padding\n document.body.style.paddingRight = '';\n\n // Remove class\n document.body.classList.remove('scroll-locked');\n\n // Restore scroll position AFTER styles are removed\n window.scrollTo(0, this.scrollPosition);\n\n this.isLocked = false;\n }\n}\n\n// Export simple functions\nexport const lockBodyScroll = () => ScrollLockManager.getInstance().lock();\nexport const unlockBodyScroll = () => ScrollLockManager.getInstance().unlock();","/* confirm.css */\n.alert-overlay {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n z-index: 9999;\n display: flex;\n align-items: center;\n justify-content: center;\n backdrop-filter: blur(4px);\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',\n 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',\n sans-serif;\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n animation: overlayFadeIn 0.3s ease-out forwards;\n}\n\n.alert-overlay-exit {\n animation: overlayFadeOut 0.3s ease-in forwards;\n}\n\n.alert-wrapper {\n width: 90%;\n max-width: 400px;\n border-radius: 12px;\n padding: 24px;\n box-shadow: \n 0 20px 25px -5px rgba(0, 0, 0, 0.1),\n 0 10px 10px -5px rgba(0, 0, 0, 0.04),\n 0 0 0 1px rgba(0, 0, 0, 0.05);\n animation: modalSlideUp 0.4s cubic-bezier(0.34, 1.56, 0.64, 1) forwards;\n transform: translateY(20px) scale(0.98);\n}\n\n.alert-wrapper-exit {\n animation: modalSlideDown 0.3s ease-in forwards;\n}\n\n.alert-title {\n font-size: 18px;\n font-weight: 600;\n line-height: 1.4;\n margin: 0 0 12px 0;\n}\n\n.alert-message {\n font-size: 14px;\n line-height: 1.5;\n margin: 0 0 24px 0;\n}\n\n.alert-buttons {\n display: flex;\n justify-content: flex-end;\n gap: 12px;\n margin-top: 8px;\n}\n\n.alert-button {\n padding: 10px 20px;\n border-radius: 8px;\n font-size: 14px;\n font-weight: 500;\n border: none;\n cursor: pointer;\n font-family: inherit;\n transition: all 0.2s ease;\n min-width: 80px;\n text-align: center;\n}\n\n.alert-button:focus {\n outline-offset: 2px;\n}\n\n.alert-button:active {\n transform: translateY(1px);\n}\n\n/* Default animations */\n.alert-wrapper-exit {\n animation: modalSlideDown 0.3s ease-in forwards;\n}\n\n/* Entrance Animation Classes */\n.alert-animate-fadeInScale {\n animation: fadeInScale 0.4s ease-out forwards;\n}\n\n.alert-animate-bounceIn {\n animation: bounceIn 0.6s cubic-bezier(0.68, -0.55, 0.265, 1.55) forwards;\n}\n\n.alert-animate-flipIn {\n animation: flipIn 0.6s cubic-bezier(0.175, 0.885, 0.32, 1.275) forwards;\n}\n\n.alert-animate-zoomIn {\n animation: zoomIn 0.3s ease-out forwards;\n}\n\n.alert-animate-rotateIn {\n animation: rotateIn 0.5s ease-out forwards;\n}\n\n.alert-animate-fadeInUp {\n animation: fadeInUp 0.5s cubic-bezier(0.34, 1.56, 0.64, 1) forwards;\n}\n\n.alert-animate-dropIn {\n animation: dropIn 0.6s cubic-bezier(0.175, 0.885, 0.32, 1.275) forwards;\n}\n\n.alert-animate-slideInRight {\n animation: slideInRight 0.4s ease-out forwards;\n}\n\n.alert-animate-slideInLeft {\n animation: slideInLeft 0.4s ease-out forwards;\n}\n\n.alert-animate-fadeInDown {\n animation: fadeInDown 0.5s cubic-bezier(0.34, 1.56, 0.64, 1) forwards;\n}\n\n.alert-animate-slideDownIn {\n animation: slideDownIn 0.4s cubic-bezier(0.34, 1.56, 0.64, 1) forwards;\n}\n\n.alert-animate-rotateInRight {\n animation: rotateInRight 0.5s ease-out forwards;\n}\n\n.alert-animate-zoomInSmall {\n animation: zoomInSmall 0.3s ease-out forwards;\n}\n\n.alert-animate-bounceInSmall {\n animation: bounceInSmall 0.6s cubic-bezier(0.68, -0.55, 0.265, 1.55) forwards;\n}\n\n.alert-animate-fadeInBlur {\n animation: fadeInBlur 0.4s ease-out forwards;\n}\n\n.alert-animate-fadeInShrink {\n animation: fadeInShrink 0.3s ease-out forwards;\n}\n\n/* Exit Animation Classes */\n.alert-animate-fadeOutScale {\n animation: fadeOutScale 0.3s ease-in forwards;\n}\n\n.alert-animate-bounceOut {\n animation: bounceOut 0.4s ease-in forwards;\n}\n\n.alert-animate-zoomOut {\n animation: zoomOut 0.3s ease-in forwards;\n}\n\n.alert-animate-rotateOut {\n animation: rotateOut 0.3s ease-in forwards;\n}\n\n.alert-animate-fadeOutDown {\n animation: fadeOutDown 0.3s ease-in forwards;\n}\n\n.alert-animate-slideOutRight {\n animation: slideOutRight 0.3s ease-in forwards;\n}\n\n.alert-animate-slideOutLeft {\n animation: slideOutLeft 0.3s ease-in forwards;\n}\n\n.alert-animate-flipOut {\n animation: flipOut 0.6s cubic-bezier(0.175, 0.885, 0.32, 1.275) forwards;\n}\n\n.alert-animate-dropOut {\n animation: dropOut 0.6s cubic-bezier(0.175, 0.885, 0.32, 1.275) forwards;\n}\n\n.alert-animate-fadeOutUp {\n animation: fadeOutUp 0.3s ease-in forwards;\n}\n\n.alert-animate-slideUpOut {\n animation: slideUpOut 0.3s ease-in forwards;\n}\n\n.alert-animate-rotateOutLeft {\n animation: rotateOutLeft 0.3s ease-in forwards;\n}\n\n.alert-animate-zoomOutSmall {\n animation: zoomOutSmall 0.3s ease-in forwards;\n}\n\n.alert-animate-bounceOutSmall {\n animation: bounceOutSmall 0.4s ease-in forwards;\n}\n\n.alert-animate-fadeOutBlur {\n animation: fadeOutBlur 0.4s ease-in forwards;\n}\n\n.alert-animate-fadeOutShrink {\n animation: fadeOutShrink 0.3s ease-in forwards;\n}\n\n.alert-wrapper {\n width: 90%;\n max-width: 400px;\n border-radius: 12px;\n padding: 24px;\n box-shadow: \n 0 20px 25px -5px rgba(0, 0, 0, 0.1),\n 0 10px 10px -5px rgba(0, 0, 0, 0.04),\n 0 0 0 1px rgba(0, 0, 0, 0.05);\n}\n\n.null-confirm-container{\n width: 0;\n height: 0;\n opacity: 0;\n position: fixed;\n left: 0;\n top: 0;\n}\n\n/* Global CSS file */\nhtml.scroll-locked {\n overflow: hidden !important;\n position: relative !important;\n height: 100% !important;\n width: 100% !important;\n}\n\nhtml.scroll-locked body {\n overflow: hidden !important;\n height: 100% !important;\n width: 100% !important;\n position: relative !important;\n padding-right: var(--scrollbar-width, 0px) !important;\n}\n\n/* Optional: Prevent momentum scrolling on iOS */\nhtml.scroll-locked {\n -webkit-overflow-scrolling: auto !important;\n}","/* animations.css - Complete Animation Keyframes */\n\n/* Overlay Animations */\n@keyframes overlayFadeIn {\n from {\n opacity: 0;\n }\n to {\n opacity: 1;\n }\n}\n\n@keyframes overlayFadeOut {\n from {\n opacity: 1;\n }\n to {\n opacity: 0;\n }\n}\n\n/* Default Modal Animations */\n@keyframes modalSlideUp {\n from {\n opacity: 0;\n transform: translateY(20px) scale(0.98);\n }\n to {\n opacity: 1;\n transform: translateY(0) scale(1);\n }\n}\n\n@keyframes modalSlideDown {\n from {\n opacity: 1;\n transform: translateY(0) scale(1);\n }\n to {\n opacity: 0;\n transform: translateY(20px) scale(0.98);\n }\n}\n\n/* Fade In/Out with Scale */\n@keyframes fadeInScale {\n from {\n opacity: 0;\n transform: scale(0.95);\n }\n to {\n opacity: 1;\n transform: scale(1);\n }\n}\n\n@keyframes fadeOutScale {\n from {\n opacity: 1;\n transform: scale(1);\n }\n to {\n opacity: 0;\n transform: scale(0.95);\n }\n}\n\n/* Slide In/Out from Right */\n@keyframes slideInRight {\n from {\n opacity: 0;\n transform: translateX(30px);\n }\n to {\n opacity: 1;\n transform: translateX(0);\n }\n}\n\n@keyframes slideOutRight {\n from {\n opacity: 1;\n transform: translateX(0);\n }\n to {\n opacity: 0;\n transform: translateX(30px);\n }\n}\n\n/* Slide In/Out from Left */\n@keyframes slideInLeft {\n from {\n opacity: 0;\n transform: translateX(-30px);\n }\n to {\n opacity: 1;\n transform: translateX(0);\n }\n}\n\n@keyframes slideOutLeft {\n from {\n opacity: 1;\n transform: translateX(0);\n }\n to {\n opacity: 0;\n transform: translateX(-30px);\n }\n}\n\n/* Bounce In/Out */\n@keyframes bounceIn {\n 0% {\n opacity: 0;\n transform: scale(0.3);\n }\n 50% {\n opacity: 1;\n transform: scale(1.05);\n }\n 70% {\n transform: scale(0.9);\n }\n 100% {\n transform: scale(1);\n }\n}\n\n@keyframes bounceOut {\n 20% {\n transform: scale(1.1);\n }\n 100% {\n opacity: 0;\n transform: scale(0.3);\n }\n}\n\n/* Small Bounce In/Out */\n@keyframes bounceInSmall {\n 0% {\n opacity: 0;\n transform: scale(0.8);\n }\n 50% {\n opacity: 1;\n transform: scale(1.05);\n }\n 70% {\n transform: scale(0.95);\n }\n 100% {\n transform: scale(1);\n }\n}\n\n@keyframes bounceOutSmall {\n 20% {\n transform: scale(1.05);\n }\n 100% {\n opacity: 0;\n transform: scale(0.8);\n }\n}\n\n/* Flip In/Out */\n@keyframes flipIn {\n 0% {\n opacity: 0;\n transform: perspective(400px) rotateY(90deg);\n }\n 100% {\n opacity: 1;\n transform: perspective(400px) rotateY(0deg);\n }\n}\n\n@keyframes flipOut {\n 0% {\n opacity: 1;\n transform: perspective(400px) rotateY(0deg);\n }\n 100% {\n opacity: 0;\n transform: perspective(400px) rotateY(90deg);\n }\n}\n\n/* Zoom In/Out */\n@keyframes zoomIn {\n from {\n opacity: 0;\n transform: scale(0.5);\n }\n to {\n opacity: 1;\n transform: scale(1);\n }\n}\n\n@keyframes zoomOut {\n from {\n opacity: 1;\n transform: scale(1);\n }\n to {\n opacity: 0;\n transform: scale(0.5);\n }\n}\n\n/* Small Zoom In/Out */\n@keyframes zoomInSmall {\n from {\n opacity: 0;\n transform: scale(0.8);\n }\n to {\n opacity: 1;\n transform: scale(1);\n }\n}\n\n@keyframes zoomOutSmall {\n from {\n opacity: 1;\n transform: scale(1);\n }\n to {\n opacity: 0;\n transform: scale(0.8);\n }\n}\n\n/* Rotate In/Out */\n@keyframes rotateIn {\n from {\n opacity: 0;\n transform: rotate(-15deg) scale(0.95);\n }\n to {\n opacity: 1;\n transform: rotate(0deg) scale(1);\n }\n}\n\n@keyframes rotateOut {\n from {\n opacity: 1;\n transform: rotate(0deg) scale(1);\n }\n to {\n opacity: 0;\n transform: rotate(15deg) scale(0.95);\n }\n}\n\n/* Rotate Right In/Left Out */\n@keyframes rotateInRight {\n from {\n opacity: 0;\n transform: rotate(15deg) scale(0.95);\n }\n to {\n opacity: 1;\n transform: rotate(0deg) scale(1);\n }\n}\n\n@keyframes rotateOutLeft {\n from {\n opacity: 1;\n transform: rotate(0deg) scale(1);\n }\n to {\n opacity: 0;\n transform: rotate(-15deg) scale(0.95);\n }\n}\n\n/* Fade Up In/Down Out */\n@keyframes fadeInUp {\n from {\n opacity: 0;\n transform: translateY(40px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n\n@keyframes fadeOutDown {\n from {\n opacity: 1;\n transform: translateY(0);\n }\n to {\n opacity: 0;\n transform: translateY(40px);\n }\n}\n\n/* Fade Down In/Up Out */\n@keyframes fadeInDown {\n from {\n opacity: 0;\n transform: translateY(-40px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n\n@keyframes fadeOutUp {\n from {\n opacity: 1;\n transform: translateY(0);\n }\n to {\n opacity: 0;\n transform: translateY(-40px);\n }\n}\n\n/* Drop In/Out (3D) */\n@keyframes dropIn {\n 0% {\n opacity: 0;\n transform: translateY(-100px) rotateX(90deg);\n }\n 70% {\n opacity: 1;\n transform: translateY(10px) rotateX(-10deg);\n }\n 100% {\n transform: translateY(0) rotateX(0deg);\n }\n}\n\n@keyframes dropOut {\n 0% {\n opacity: 1;\n transform: translateY(0) rotateX(0deg);\n }\n 30% {\n opacity: 1;\n transform: translateY(10px) rotateX(-10deg);\n }\n 100% {\n opacity: 0;\n transform: translateY(-100px) rotateX(90deg);\n }\n}\n\n/* Slide Up Out/Down In */\n@keyframes slideUpOut {\n from {\n opacity: 1;\n transform: translateY(0) scale(1);\n }\n to {\n opacity: 0;\n transform: translateY(-20px) scale(0.98);\n }\n}\n\n@keyframes slideDownIn {\n from {\n opacity: 0;\n transform: translateY(-20px) scale(0.98);\n }\n to {\n opacity: 1;\n transform: translateY(0) scale(1);\n }\n}\n\n/* Blur In/Out Effects */\n@keyframes fadeInBlur {\n from {\n opacity: 0;\n filter: blur(10px);\n }\n to {\n opacity: 1;\n filter: blur(0px);\n }\n}\n\n@keyframes fadeOutBlur {\n from {\n opacity: 1;\n filter: blur(0px);\n }\n to {\n opacity: 0;\n filter: blur(10px);\n }\n}\n\n/* Shrink In/Out Effects */\n@keyframes fadeInShrink {\n from {\n opacity: 0;\n transform: scale(1.2) translateY(20px);\n }\n to {\n opacity: 1;\n transform: scale(1) translateY(0);\n }\n}\n\n@keyframes fadeOutShrink {\n from {\n opacity: 1;\n transform: scale(1) translateY(0);\n }\n to {\n opacity: 0;\n transform: scale(0.8) translateY(20px);\n }\n}\n\n/* Background Blur Animations */\n@keyframes blurIn {\n from {\n backdrop-filter: blur(0px);\n }\n to {\n backdrop-filter: blur(4px);\n }\n}\n\n@keyframes blurOut {\n from {\n backdrop-filter: blur(4px);\n }\n to {\n backdrop-filter: blur(0px);\n }\n}\n\n/* Special Effects Animations */\n\n/* Shake Animation (for errors) */\n@keyframes shake {\n 0%, 100% {\n transform: translateX(0);\n }\n 10%, 30%, 50%, 70%, 90% {\n transform: translateX(-5px);\n }\n 20%, 40%, 60%, 80% {\n transform: translateX(5px);\n }\n}\n\n/* Pulse Animation (for emphasis) */\n@keyframes pulse {\n 0% {\n transform: scale(1);\n }\n 50% {\n transform: scale(1.05);\n }\n 100% {\n transform: scale(1);\n }\n}\n\n/* Button Hover Effects */\n@keyframes buttonHover {\n 0% {\n transform: translateY(0);\n box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);\n }\n 50% {\n transform: translateY(-2px);\n box-shadow: 0 8px 15px rgba(0, 0, 0, 0.2);\n }\n 100% {\n transform: translateY(-1px);\n box-shadow: 0 6px 12px rgba(0, 0, 0, 0.15);\n }\n}\n\n/* Accessibility: Reduce motion */\n@media (prefers-reduced-motion: reduce) {\n .alert-overlay,\n .alert-wrapper,\n .alert-button {\n animation-duration: 0.01ms;\n animation-iteration-count: 1;\n transition-duration: 0.01ms;\n }\n \n .alert-overlay {\n animation: none;\n opacity: 1;\n }\n \n .alert-wrapper {\n animation: none;\n opacity: 1;\n transform: none;\n }\n}","/* ========== LIGHT SCHEMA (Default) ========== */\n.schema-light-overlay {\n background-color: rgba(0, 0, 0, 0.5);\n}\n\n.schema-light-wrapper {\n background-color: #ffffff;\n color: #111827;\n}\n\n.schema-light-title {\n color: #111827;\n}\n\n.schema-light-message {\n color: #6b7280;\n}\n\n.schema-light-cancel {\n background-color: #f3f4f6;\n color: #374151;\n outline-color: #9ca3af;\n}\n\n.schema-light-cancel:hover {\n background-color: #e5e7eb;\n transform: translateY(-1px);\n}\n\n.schema-light-cancel:active {\n background-color: #d1d5db;\n}\n\n.schema-light-cancel-danger {\n background-color: #fee2e2;\n color: #991b1b;\n outline-color: #f87171;\n}\n\n.schema-light-cancel-danger:hover {\n background-color: #fecaca;\n}\n\n.schema-light-ok {\n background-color: #10b981;\n color: #ffffff;\n outline-color: #34d399;\n}\n\n.schema-light-ok:hover {\n background-color: #059669;\n transform: translateY(-1px);\n}\n\n.schema-light-ok:active {\n background-color: #047857;\n}\n\n.schema-light-ok-danger {\n background-color: #ef4444;\n color: #ffffff;\n outline-color: #f87171;\n}\n\n.schema-light-ok-danger:hover {\n background-color: #dc2626;\n}\n\n/* ========== DARK SCHEMA ========== */\n.schema-dark-overlay {\n background-color: rgba(0, 0, 0, 0.7);\n}\n\n.schema-dark-wrapper {\n background-color: #18181b;\n color: #f4f4f5;\n box-shadow: \n 0 20px 25px -5px rgba(0, 0, 0, 0.3),\n 0 10px 10px -5px rgba(0, 0, 0, 0.2),\n 0 0 0 1px rgba(255, 255, 255, 0.1);\n}\n\n.schema-dark-title {\n color: #f4f4f5;\n}\n\n.schema-dark-message {\n color: #a1a1aa;\n}\n\n.schema-dark-cancel {\n background-color: #27272a;\n color: #e4e4e7;\n outline-color: #71717a;\n}\n\n.schema-dark-cancel:hover {\n background-color: #3f3f46;\n transform: translateY(-1px);\n}\n\n.schema-dark-cancel:active {\n background-color: #52525b;\n}\n\n.schema-dark-cancel-danger {\n background-color: #7f1d1d;\n color: #fecaca;\n outline-color: #ef4444;\n}\n\n.schema-dark-cancel-danger:hover {\n background-color: #991b1b;\n}\n\n.schema-dark-ok {\n background-color: #10b981;\n color: #ffffff;\n outline-color: #34d399;\n}\n\n.schema-dark-ok:hover {\n background-color: #059669;\n transform: translateY(-1px);\n}\n\n.schema-dark-ok:active {\n background-color: #047857;\n}\n\n.schema-dark-ok-danger {\n background-color: #dc2626;\n color: #ffffff;\n outline-color: #ef4444;\n}\n\n.schema-dark-ok-danger:hover {\n background-color: #b91c1c;\n}\n\n/* ========== BLUE SCHEMA ========== */\n.schema-blue-overlay {\n background-color: rgba(59, 130, 246, 0.3);\n}\n\n.schema-blue-wrapper {\n background-color: #eff6ff;\n color: #1e3a8a;\n box-shadow: \n 0 20px 25px -5px rgba(59, 130, 246, 0.15),\n 0 10px 10px -5px rgba(59, 130, 246, 0.1),\n 0 0 0 1px rgba(59, 130, 246, 0.1);\n}\n\n.schema-blue-title {\n color: #1e3a8a;\n}\n\n.schema-blue-message {\n color: #3b82f6;\n}\n\n.schema-blue-cancel {\n background-color: #dbeafe;\n color: #1e40af;\n outline-color: #60a5fa;\n}\n\n.schema-blue-cancel:hover {\n background-color: #bfdbfe;\n transform: translateY(-1px);\n}\n\n.schema-blue-cancel:active {\n background-color: #93c5fd;\n}\n\n.schema-blue-cancel-danger {\n background-color: #fee2e2;\n color: #991b1b;\n outline-color: #f87171;\n}\n\n.schema-blue-ok {\n background-color: #3b82f6;\n color: #ffffff;\n outline-color: #60a5fa;\n}\n\n.schema-blue-ok:hover {\n background-color: #2563eb;\n transform: translateY(-1px);\n}\n\n.schema-blue-ok:active {\n background-color: #1d4ed8;\n}\n\n.schema-blue-ok-danger {\n background-color: #ef4444;\n color: #ffffff;\n outline-color: #f87171;\n}\n\n/* ========== RED SCHEMA ========== */\n.schema-red-overlay {\n background-color: rgba(220, 38, 38, 0.2);\n}\n\n.schema-red-wrapper {\n background-color: #fef2f2;\n color: #7f1d1d;\n box-shadow: \n 0 20px 25px -5px rgba(220, 38, 38, 0.15),\n 0 10px 10px -5px rgba(220, 38, 38, 0.1),\n 0 0 0 1px rgba(220, 38, 38, 0.1);\n}\n\n.schema-red-title {\n color: #7f1d1d;\n}\n\n.schema-red-message {\n color: #ef4444;\n}\n\n.schema-red-cancel {\n background-color: #fecaca;\n color: #991b1b;\n outline-color: #f87171;\n}\n\n.schema-red-cancel:hover {\n background-color: #fca5a5;\n transform: translateY(-1px);\n}\n\n.schema-red-cancel:active {\n background-color: #f87171;\n}\n\n.schema-red-ok {\n background-color: #dc2626;\n color: #ffffff;\n outline-color: #ef4444;\n}\n\n.schema-red-ok:hover {\n background-color: #b91c1c;\n transform: translateY(-1px);\n}\n\n.schema-red-ok:active {\n background-color: #991b1b;\n}\n\n.schema-red-ok-danger {\n background-color: #991b1b;\n color: #ffffff;\n outline-color: #dc2626;\n}\n\n/* ========== GREEN SCHEMA ========== */\n.schema-green-overlay {\n background-color: rgba(16, 185, 129, 0.2);\n}\n\n.schema-green-wrapper {\n background-color: #ecfdf5;\n color: #064e3b;\n box-shadow: \n 0 20px 25px -5px rgba(16, 185, 129, 0.15),\n 0 10px 10px -5px rgba(16, 185, 129, 0.1),\n 0 0 0 1px rgba(16, 185, 129, 0.1);\n}\n\n.schema-green-title {\n color: #064e3b;\n}\n\n.schema-green-message {\n color: #10b981;\n}\n\n.schema-green-cancel {\n background-color: #d1fae5;\n color: #047857;\n outline-color: #34d399;\n}\n\n.schema-green-cancel:hover {\n background-color: #a7f3d0;\n transform: translateY(-1px);\n}\n\n.schema-green-cancel:active {\n background-color: #6ee7b7;\n}\n\n.schema-green-cancel-danger {\n background-color: #fee2e2;\n color: #991b1b;\n outline-color: #f87171;\n}\n\n.schema-green-ok {\n background-color: #10b981;\n color: #ffffff;\n outline-color: #34d399;\n}\n\n.schema-green-ok:hover {\n background-color: #059669;\n transform: translateY(-1px);\n}\n\n.schema-green-ok:active {\n background-color: #047857;\n}\n\n.schema-green-ok-danger {\n background-color: #ef4444;\n color: #ffffff;\n outline-color: #f87171;\n}\n\n/* ========== PURPLE SCHEMA ========== */\n.schema-purple-overlay {\n background-color: rgba(139, 92, 246, 0.2);\n}\n\n.schema-purple-wrapper {\n background-color: #f5f3ff;\n color: #5b21b6;\n box-shadow: \n 0 20px 25px -5px rgba(139, 92, 246, 0.15),\n 0 10px 10px -5px rgba(139, 92, 246, 0.1),\n 0 0 0 1px rgba(139, 92, 246, 0.1);\n}\n\n.schema-purple-title {\n color: #5b21b6;\n}\n\n.schema-purple-message {\n color: #8b5cf6;\n}\n\n.schema-purple-cancel {\n background-color: #ede9fe;\n color: #6d28d9;\n outline-color: #a78bfa;\n}\n\n.schema-purple-cancel:hover {\n background-color: #ddd6fe;\n transform: translateY(-1px);\n}\n\n.schema-purple-cancel:active {\n background-color: #c4b5fd;\n}\n\n.schema-purple-cancel-danger {\n background-color: #fee2e2;\n color: #991b1b;\n outline-color: #f87171;\n}\n\n.schema-purple-ok {\n background-color: #8b5cf6;\n color: #ffffff;\n outline-color: #a78bfa;\n}\n\n.schema-purple-ok:hover {\n background-color: #7c3aed;\n transform: translateY(-1px);\n}\n\n.schema-purple-ok:active {\n background-color: #6d28d9;\n}\n\n.schema-purple-ok-danger {\n background-color: #ef4444;\n color: #ffffff;\n outline-color: #f87171;\n}\n","import confirmCSS from './confirm.css';\nimport animationsCSS from './animations.css';\nimport colorSchemasCSS from './colorSchemas.css';\n\n// Combine all CSS\nconst ALL_CSS = `${confirmCSS}\\n${animationsCSS}\\n${colorSchemasCSS}`;\n\nlet stylesInjected = false;\n\nexport function ensureStyles() {\n if (typeof document === 'undefined') {\n return; // Server-side rendering\n }\n \n if (stylesInjected) {\n return; // Already injected\n }\n \n // Create and inject style tag\n const style = document.createElement('style');\n style.setAttribute('data-react-confirm-lite', '');\n style.textContent = ALL_CSS;\n document.head.appendChild(style);\n \n stylesInjected = true;\n}","import React, { useEffect, useState, useCallback, useRef, type ReactNode, type CSSProperties } from \"react\";\nimport { subscribe, closeAlert, setActiveContainer, setIsContainerActive, getIsContainerActive, getActiveContainerId, makeId } from \"./confirm_store\";\nimport type { ConfirmClasses, ConfirmOptions, ColorSchema, AnimationType, animationPairs } from \"./types\";\nimport { lockBodyScroll, unlockBodyScroll } from \"./confirm_store\";\nimport \"./confirm.css\";\nimport './animations.css'\nimport './colorSchemas.css'\nimport { ensureStyles } from \"./bundle-css\";\n\nfunction cx(...classes: (string | undefined)[]) {\n return classes.filter(Boolean).join(\" \");\n}\n\nconst animationPairs = {\n slide: { enter: '', exit: 'alert-wrapper-exit' },\n fadeScale: { enter: 'alert-animate-fadeInScale', exit: 'alert-animate-fadeOutScale' },\n bounce: { enter: 'alert-animate-bounceIn', exit: 'alert-animate-bounceOut' },\n flip: { enter: 'alert-animate-flipIn', exit: 'alert-animate-flipOut' },\n zoom: { enter: 'alert-animate-zoomIn', exit: 'alert-animate-zoomOut' },\n rotate: { enter: 'alert-animate-rotateIn', exit: 'alert-animate-rotateOut' },\n fadeUp: { enter: 'alert-animate-fadeInUp', exit: 'alert-animate-fadeOutDown' },\n drop: { enter: 'alert-animate-dropIn', exit: 'alert-animate-dropOut' },\n slideRight: { enter: 'alert-animate-slideInRight', exit: 'alert-animate-slideOutLeft' },\n slideLeft: { enter: 'alert-animate-slideInLeft', exit: 'alert-animate-slideOutRight' },\n fadeDown: { enter: 'alert-animate-fadeInDown', exit: 'alert-animate-fadeOutUp' },\n slideVertical: { enter: 'alert-animate-slideDownIn', exit: 'alert-animate-slideUpOut' },\n rotateRight: { enter: 'alert-animate-rotateInRight', exit: 'alert-animate-rotateOutLeft' },\n zoomSmall: { enter: 'alert-animate-zoomInSmall', exit: 'alert-animate-zoomOutSmall' },\n bounceSmall: { enter: 'alert-animate-bounceInSmall', exit: 'alert-animate-bounceOutSmall' },\n fadeBlur: { enter: 'alert-animate-fadeInBlur', exit: 'alert-animate-fadeOutBlur' },\n fadeShrink: { enter: 'alert-animate-fadeInShrink', exit: 'alert-animate-fadeOutShrink' },\n} as const;\n\ntype Props = {\n classes?: ConfirmClasses;\n defaultColorSchema?: ColorSchema;\n closeOnEscape?: boolean;\n closeOnClickOutside?: boolean;\n animation?: AnimationType;\n animationDuration?: number;\n animationDurationIn?: number;\n animationDurationOut?: number;\n lockScroll?: boolean;\n children?: (props: {\n isVisible: boolean;\n confirm: ConfirmOptions;\n handleCancel: () => void;\n handleOk: () => void;\n containerRef: React.RefObject<HTMLDivElement | null>;\n colorSchema: ColorSchema;\n animationClass: string;\n animationStyle: CSSProperties;\n }) => ReactNode;\n id?: string;\n};\n\nconst ConfirmContainer = ({\n classes = {},\n animationDuration = 300,\n defaultColorSchema = 'dark',\n closeOnEscape = true,\n closeOnClickOutside = true,\n animation = 'slide',\n animationDurationIn,\n animationDurationOut,\n lockScroll = true,\n children,\n id\n}: Props) => {\n const [alerts, setAlerts] = useState<ConfirmOptions[]>([]);\n const [isVisible, setIsVisible] = useState(false);\n const [currentAlert, setCurrentAlert] = useState<ConfirmOptions | null>(null);\n const [isExiting, setIsExiting] = useState(false);\n const [isMounted, setIsMounted] = useState(false);\n const overlayRef = useRef<HTMLDivElement>(null);\n const wrapperRef = useRef<HTMLDivElement>(null);\n const exitTimerRef = useRef<number | null>(null);\n const containerId = useRef(id || `confirm-${makeId()}`)\n const nullElement = <div id={containerId.current} className=\"null-confirm-container\"></div>\n\n useEffect(() => {\n subscribe((newAlerts) => {\n setAlerts(newAlerts);\n });\n }, []);\n\n useEffect(() => {\n ensureStyles()\n }, []);\n\n useEffect(() => {\n if (alerts.length > 0 && !currentAlert && !isExiting) {\n const nextAlert = alerts[0];\n\n // Check if we should show this alert\n const shouldShowAlert =\n !nextAlert.id ||\n nextAlert.id === containerId.current ||\n !getActiveContainerId();\n\n if (shouldShowAlert) {\n // Check if we can become active\n const currentActive = getActiveContainerId();\n\n if (!currentActive || currentActive === containerId.current) {\n if (lockScroll) {\n lockBodyScroll()\n }\n setActiveContainer(containerId.current);\n setIsContainerActive(true);\n\n // Show the alert\n setIsMounted(true);\n setCurrentAlert(nextAlert);\n setIsVisible(true);\n }\n }\n }\n else if (alerts.length === 0 && currentAlert && isVisible) {\n // No more alerts, but we're showing one - start exit\n setIsExiting(true);\n setIsVisible(false);\n\n if (exitTimerRef.current) {\n clearTimeout(exitTimerRef.current);\n }\n\n const exitDuration = animationDurationOut || animationDuration;\n exitTimerRef.current = setTimeout(() => {\n setIsContainerActive(false);\n setIsExiting(false);\n setCurrentAlert(null);\n setIsMounted(false);\n }, exitDuration);\n }\n else if (alerts.length > 0 && currentAlert && alerts[0].id !== currentAlert.id) {\n // New alert with different ID is replacing current one\n setIsExiting(true);\n setIsVisible(false);\n\n if (exitTimerRef.current) {\n clearTimeout(exitTimerRef.current);\n }\n\n const exitDuration = animationDurationOut || animationDuration;\n exitTimerRef.current = setTimeout(() => {\n setIsContainerActive(false);\n setIsExiting(false);\n setCurrentAlert(null);\n setIsMounted(false);\n // The new alert will be picked up in the next render\n }, exitDuration);\n }\n }, [alerts, currentAlert, animationDuration, animationDurationOut, isVisible]);\n\n const handleClose = useCallback(async (value: boolean | null) => {\n if (!currentAlert || isExiting) return;\n\n // Start exit animation immediately\n setIsExiting(true);\n setIsVisible(false);\n\n // Delay the actual closeAlert call until animation completes\n const exitDuration = animationDurationOut || animationDuration;\n\n if (exitTimerRef.current) {\n clearTimeout(exitTimerRef.current);\n }\n\n exitTimerRef.current = setTimeout(() => {\n // Now call closeAlert which will resolve the promise\n closeAlert(value);\n\n // Reset state\n setIsExiting(false);\n setCurrentAlert(null);\n setIsMounted(false);\n setIsContainerActive(false);\n unlockBodyScroll()\n }, exitDuration);\n }, [currentAlert, isExiting, animationDuration, animationDurationOut]);\n\n const handleCancel = useCallback(() => {\n if (currentAlert && isVisible && !isExiting) {\n handleClose(false);\n }\n }, [currentAlert, isVisible, isExiting, handleClose]);\n\n const handleOk = useCallback(() => {\n if (currentAlert && isVisible && !isExiting) {\n handleClose(true);\n }\n }, [currentAlert, isVisible, isExiting, handleClose]);\n\n const handleEscKey = useCallback((event: KeyboardEvent) => {\n if (event.key === 'Escape' && closeOnEscape && currentAlert && isVisible && !isExiting) {\n event.preventDefault();\n event.stopPropagation();\n handleClose(null);\n }\n }, [closeOnEscape, currentAlert, isVisible, isExiting, handleClose]);\n\n useEffect(() => {\n if (currentAlert && isVisible && !isExiting) {\n window.addEventListener('keydown', handleEscKey, { capture: true });\n }\n\n return () => {\n window.removeEventListener('keydown', handleEscKey, { capture: true });\n };\n }, [handleEscKey, currentAlert, isVisible, isExiting]);\n\n useEffect(() => {\n const handleClickOutside = (event: MouseEvent) => {\n if (wrapperRef.current &&\n !wrapperRef.current.contains(event.target as Node) &&\n closeOnClickOutside &&\n currentAlert &&\n isVisible &&\n !isExiting) {\n handleClose(null);\n }\n };\n\n if (currentAlert && isVisible && !isExiting) {\n document.addEventListener(\"mousedown\", handleClickOutside);\n }\n\n return () => {\n document.removeEventListener(\"mousedown\", handleClickOutside);\n };\n }, [closeOnClickOutside, currentAlert, isVisible, isExiting, handleClose]);\n\n // Replace the render conditions with:\n if (!isMounted && !isExiting) {\n return nullElement;\n }\n\n if (!currentAlert || !getIsContainerActive()) {\n return nullElement;\n }\n\n // Always render if we have a current alert\n const colorSchema = currentAlert?.colorSchema || defaultColorSchema;\n const schemaClass = `schema-${colorSchema}`;\n\n const animationStyle: CSSProperties = {};\n const currentDuration = isVisible\n ? (animationDurationIn || animationDuration)\n : (animationDurationOut || animationDuration);\n\n animationStyle.animationDuration = `${currentDuration}ms`;\n animationStyle.animationFillMode = 'forwards';\n\n const animationClass = isVisible\n ? animationPairs[animation as keyof animationPairs].enter\n : animationPairs[animation as keyof animationPairs].exit;\n\n\n // For children render\n if (children && currentAlert && getActiveContainerId() === containerId.current) {\n return (\n <>\n {nullElement}\n {children({\n isVisible: isVisible && !isExiting,\n confirm: currentAlert,\n handleCancel,\n handleOk,\n containerRef: wrapperRef,\n colorSchema,\n animationClass,\n animationStyle\n })}\n </>\n )\n }\n\n return (\n <>\n {nullElement}\n <div\n ref={overlayRef}\n className={cx(\n \"alert-overlay\",\n !isVisible ? \"alert-overlay-exit\" : '',\n `${schemaClass}-overlay`,\n classes.overlay\n )}\n style={animationStyle}\n >\n <div\n ref={wrapperRef}\n className={cx(\n \"alert-wrapper\",\n animationClass,\n `${schemaClass}-wrapper`,\n classes.wrapper\n )}\n style={animationStyle}\n >\n <h2 className={cx(\n \"alert-title\",\n `${schemaClass}-title`,\n classes.title\n )}>\n {currentAlert.title}\n </h2>\n <p className={cx(\n \"alert-message\",\n `${schemaClass}-message`,\n classes.message\n )}>\n {currentAlert.message}\n </p>\n <div className=\"alert-buttons\">\n <button\n onClick={handleCancel}\n disabled={isExiting || !isVisible}\n className={cx(\n \"alert-button alert-button-cancel\",\n `${schemaClass}-cancel`,\n classes.button,\n classes.cancel\n )}\n >\n {currentAlert.cancelText || 'Cancel'}\n </button>\n <button\n onClick={handleOk}\n disabled={isExiting || !isVisible}\n className={cx(\n 'alert-button alert-button-ok',\n `${schemaClass}-ok`,\n classes.button,\n classes.ok\n )}\n >\n {currentAlert.okText || 'OK'}\n </button>\n </div>\n </div>\n </div>\n </>\n );\n};\n\nexport default ConfirmContainer;","import { addAlert, getElement } from \"./confirm_store\";\nimport type { ConfirmInput } from \"./types\";\nimport { isClosest } from \"./confirm_store\";\n\nexport async function confirm(input: string | ConfirmInput, closest: boolean | null = null): Promise<boolean | null> {\n let containerId;\n\n if (typeof input === 'string') {\n if (closest) {\n containerId = await getElement();\n } else if (closest === null && isClosest() === true) {\n containerId = await getElement();\n }\n const result = await addAlert({\n message: input,\n id: containerId\n });\n return result;\n }\n\n if (!input.id) {\n if (closest) {\n containerId = await getElement();\n } else if (closest === null && isClosest() === true) {\n containerId = await getElement();\n }\n const result = await addAlert({\n ...input,\n id: containerId\n });\n return result;\n }\n\n const result = await addAlert(input);\n return result;\n}"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-confirm-lite",
|
|
3
|
-
"version": "1.5.
|
|
3
|
+
"version": "1.5.6",
|
|
4
4
|
"description": "A lightweight, promise-based confirm dialog for React, designed to be as easy to use as react-toastify, while remaining fully customizable.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|