modalio 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,567 @@
1
+ import type {
2
+ ModalHandler,
3
+ RadixDialogContentProps,
4
+ RadixDialogProps,
5
+ ShadcnDialogProps,
6
+ } from "./types";
7
+
8
+ /**
9
+ * Options for adapter behavior
10
+ */
11
+ export interface AdapterOptions {
12
+ /** Prevent closing via escape key or clicking outside */
13
+ disableClose?: boolean;
14
+ }
15
+
16
+ // ============================================
17
+ // Radix UI adapters
18
+ // ============================================
19
+
20
+ /**
21
+ * Adapter for Radix UI Dialog root component
22
+ */
23
+ export const radixUiDialog = (
24
+ modal: ModalHandler,
25
+ options?: AdapterOptions,
26
+ ): RadixDialogProps => ({
27
+ open: modal.isOpen,
28
+ onOpenChange: (open: boolean) => {
29
+ if (!(open || options?.disableClose)) {
30
+ modal.dismiss();
31
+ }
32
+ },
33
+ });
34
+
35
+ /**
36
+ * Adapter for Radix UI Dialog.Content component
37
+ */
38
+ export const radixUiDialogContent = (
39
+ modal: ModalHandler,
40
+ options?: AdapterOptions,
41
+ ): RadixDialogContentProps => ({
42
+ onAnimationEndCapture: () => {
43
+ modal.onAnimationEnd();
44
+ },
45
+ onEscapeKeyDown: (e?: Event) => {
46
+ if (options?.disableClose) {
47
+ e?.preventDefault();
48
+ } else {
49
+ modal.dismiss();
50
+ }
51
+ },
52
+ onPointerDownOutside: (e?: Event) => {
53
+ if (options?.disableClose) {
54
+ e?.preventDefault();
55
+ } else {
56
+ modal.dismiss();
57
+ }
58
+ },
59
+ });
60
+
61
+ /**
62
+ * Adapter for Radix UI AlertDialog root component
63
+ */
64
+ export const radixUiAlertDialog = (
65
+ modal: ModalHandler,
66
+ options?: AdapterOptions,
67
+ ): RadixDialogProps => ({
68
+ open: modal.isOpen,
69
+ onOpenChange: (open: boolean) => {
70
+ if (!(open || options?.disableClose)) {
71
+ modal.dismiss();
72
+ }
73
+ },
74
+ });
75
+
76
+ /**
77
+ * Adapter for Radix UI AlertDialog.Content component
78
+ */
79
+ export const radixUiAlertDialogContent = (
80
+ modal: ModalHandler,
81
+ options?: AdapterOptions,
82
+ ): RadixDialogContentProps => ({
83
+ onAnimationEndCapture: () => {
84
+ modal.onAnimationEnd();
85
+ },
86
+ onEscapeKeyDown: (e?: Event) => {
87
+ if (options?.disableClose) {
88
+ e?.preventDefault();
89
+ } else {
90
+ modal.dismiss();
91
+ }
92
+ },
93
+ onPointerDownOutside: (e?: Event) => {
94
+ if (options?.disableClose) {
95
+ e?.preventDefault();
96
+ } else {
97
+ modal.dismiss();
98
+ }
99
+ },
100
+ });
101
+
102
+ // ============================================
103
+ // Shadcn UI adapters
104
+ // ============================================
105
+
106
+ /**
107
+ * Adapter for Shadcn UI Dialog
108
+ */
109
+ export const shadcnUiDialog = (
110
+ modal: ModalHandler,
111
+ options?: AdapterOptions,
112
+ ): ShadcnDialogProps => ({
113
+ open: modal.isOpen,
114
+ onOpenChange: (open: boolean) => {
115
+ if (!(open || options?.disableClose)) {
116
+ modal.dismiss();
117
+ }
118
+ },
119
+ onClose: () => {
120
+ if (!options?.disableClose) {
121
+ modal.dismiss();
122
+ }
123
+ },
124
+ onAnimationEndCapture: () => {
125
+ modal.onAnimationEnd();
126
+ },
127
+ });
128
+
129
+ /**
130
+ * Adapter for Shadcn UI DialogContent
131
+ */
132
+ export const shadcnUiDialogContent = (
133
+ modal: ModalHandler,
134
+ options?: AdapterOptions,
135
+ ): RadixDialogContentProps => ({
136
+ onAnimationEndCapture: () => {
137
+ modal.onAnimationEnd();
138
+ },
139
+ onEscapeKeyDown: (e?: Event) => {
140
+ if (options?.disableClose) {
141
+ e?.preventDefault();
142
+ } else {
143
+ modal.dismiss();
144
+ }
145
+ },
146
+ onPointerDownOutside: (e?: Event) => {
147
+ if (options?.disableClose) {
148
+ e?.preventDefault();
149
+ } else {
150
+ modal.dismiss();
151
+ }
152
+ },
153
+ });
154
+
155
+ /**
156
+ * Adapter for Shadcn UI AlertDialog
157
+ */
158
+ export const shadcnUiAlertDialog = (
159
+ modal: ModalHandler,
160
+ options?: AdapterOptions,
161
+ ): ShadcnDialogProps => ({
162
+ open: modal.isOpen,
163
+ onOpenChange: (open: boolean) => {
164
+ if (!(open || options?.disableClose)) {
165
+ modal.dismiss();
166
+ }
167
+ },
168
+ onClose: () => {
169
+ if (!options?.disableClose) {
170
+ modal.dismiss();
171
+ }
172
+ },
173
+ onAnimationEndCapture: () => {
174
+ modal.onAnimationEnd();
175
+ },
176
+ });
177
+
178
+ /**
179
+ * Adapter for Shadcn UI AlertDialogContent
180
+ */
181
+ export const shadcnUiAlertDialogContent = (
182
+ modal: ModalHandler,
183
+ options?: AdapterOptions,
184
+ ): RadixDialogContentProps => ({
185
+ onAnimationEndCapture: () => {
186
+ modal.onAnimationEnd();
187
+ },
188
+ onEscapeKeyDown: (e?: Event) => {
189
+ if (options?.disableClose) {
190
+ e?.preventDefault();
191
+ } else {
192
+ modal.dismiss();
193
+ }
194
+ },
195
+ onPointerDownOutside: (e?: Event) => {
196
+ if (options?.disableClose) {
197
+ e?.preventDefault();
198
+ } else {
199
+ modal.dismiss();
200
+ }
201
+ },
202
+ });
203
+
204
+ /**
205
+ * Adapter for Shadcn UI Sheet
206
+ */
207
+ export const shadcnUiSheet = (
208
+ modal: ModalHandler,
209
+ options?: AdapterOptions,
210
+ ): ShadcnDialogProps => ({
211
+ open: modal.isOpen,
212
+ onOpenChange: (open: boolean) => {
213
+ if (!(open || options?.disableClose)) {
214
+ modal.dismiss();
215
+ }
216
+ },
217
+ onClose: () => {
218
+ if (!options?.disableClose) {
219
+ modal.dismiss();
220
+ }
221
+ },
222
+ onAnimationEndCapture: () => {
223
+ modal.onAnimationEnd();
224
+ },
225
+ });
226
+
227
+ /**
228
+ * Adapter for Shadcn UI SheetContent
229
+ */
230
+ export const shadcnUiSheetContent = (
231
+ modal: ModalHandler,
232
+ options?: AdapterOptions,
233
+ ): RadixDialogContentProps => ({
234
+ onAnimationEndCapture: () => {
235
+ modal.onAnimationEnd();
236
+ },
237
+ onEscapeKeyDown: (e?: Event) => {
238
+ if (options?.disableClose) {
239
+ e?.preventDefault();
240
+ } else {
241
+ modal.dismiss();
242
+ }
243
+ },
244
+ onPointerDownOutside: (e?: Event) => {
245
+ if (options?.disableClose) {
246
+ e?.preventDefault();
247
+ } else {
248
+ modal.dismiss();
249
+ }
250
+ },
251
+ });
252
+
253
+ /**
254
+ * Adapter for Shadcn UI Popover
255
+ */
256
+ export const shadcnUiPopover = (
257
+ modal: ModalHandler,
258
+ options?: AdapterOptions,
259
+ ): { open: boolean; onOpenChange: (open: boolean) => void } => ({
260
+ open: modal.isOpen,
261
+ onOpenChange: (open: boolean) => {
262
+ if (!(open || options?.disableClose)) {
263
+ modal.dismiss();
264
+ modal.onAnimationEnd();
265
+ }
266
+ },
267
+ });
268
+
269
+ /**
270
+ * Props returned by Shadcn UI Drawer adapters
271
+ */
272
+ export interface ShadcnUiDrawerRootProps {
273
+ open: boolean;
274
+ onOpenChange: (open: boolean) => void;
275
+ dismissible?: boolean;
276
+ }
277
+
278
+ /**
279
+ * Props for Shadcn UI DrawerContent component
280
+ */
281
+ export interface ShadcnUiDrawerContentProps {
282
+ onAnimationEnd: () => void;
283
+ }
284
+
285
+ /**
286
+ * Adapter for Shadcn UI Drawer
287
+ */
288
+ export const shadcnUiDrawer = (
289
+ modal: ModalHandler,
290
+ options?: AdapterOptions,
291
+ ): ShadcnUiDrawerRootProps => ({
292
+ open: modal.isOpen,
293
+ onOpenChange: (open: boolean) => {
294
+ if (!(open || options?.disableClose)) {
295
+ modal.dismiss();
296
+ }
297
+ },
298
+ dismissible: !options?.disableClose,
299
+ });
300
+
301
+ /**
302
+ * Adapter for Shadcn UI DrawerContent component
303
+ */
304
+ export const shadcnUiDrawerContent = (
305
+ modal: ModalHandler,
306
+ ): ShadcnUiDrawerContentProps => ({
307
+ onAnimationEnd: () => {
308
+ modal.onAnimationEnd();
309
+ },
310
+ });
311
+
312
+ // ============================================
313
+ // Radix UI Sheet adapters
314
+ // ============================================
315
+
316
+ /**
317
+ * Adapter for Radix UI Sheet root component
318
+ */
319
+ export const radixUiSheet = (
320
+ modal: ModalHandler,
321
+ options?: AdapterOptions,
322
+ ): { open: boolean; onOpenChange: (open: boolean) => void } => ({
323
+ open: modal.isOpen,
324
+ onOpenChange: (open: boolean) => {
325
+ if (!(open || options?.disableClose)) {
326
+ modal.dismiss();
327
+ }
328
+ },
329
+ });
330
+
331
+ /**
332
+ * Adapter for Radix UI Sheet.Content component
333
+ */
334
+ export const radixUiSheetContent = (
335
+ modal: ModalHandler,
336
+ options?: AdapterOptions,
337
+ ): RadixDialogContentProps => ({
338
+ onAnimationEndCapture: () => {
339
+ modal.onAnimationEnd();
340
+ },
341
+ onEscapeKeyDown: (e?: Event) => {
342
+ if (options?.disableClose) {
343
+ e?.preventDefault();
344
+ } else {
345
+ modal.dismiss();
346
+ }
347
+ },
348
+ onPointerDownOutside: (e?: Event) => {
349
+ if (options?.disableClose) {
350
+ e?.preventDefault();
351
+ } else {
352
+ modal.dismiss();
353
+ }
354
+ },
355
+ });
356
+
357
+ // ============================================
358
+ // Radix UI Popover adapter
359
+ // ============================================
360
+
361
+ /**
362
+ * Adapter for Radix UI Popover
363
+ */
364
+ export const radixUiPopover = (
365
+ modal: ModalHandler,
366
+ options?: AdapterOptions,
367
+ ): { open: boolean; onOpenChange: (open: boolean) => void } => ({
368
+ open: modal.isOpen,
369
+ onOpenChange: (open: boolean) => {
370
+ if (!(open || options?.disableClose)) {
371
+ modal.dismiss();
372
+ modal.onAnimationEnd();
373
+ }
374
+ },
375
+ });
376
+
377
+ // ============================================
378
+ // Base UI adapters (v1+)
379
+ // ============================================
380
+
381
+ /**
382
+ * Props returned by Base UI dialog adapters
383
+ */
384
+ export interface BaseUiDialogRootProps {
385
+ open: boolean;
386
+ onOpenChange: (open: boolean) => void;
387
+ dismissible?: boolean;
388
+ }
389
+
390
+ /**
391
+ * Props for Base UI Dialog.Portal component
392
+ */
393
+ export interface BaseUiDialogPortalProps {
394
+ keepMounted?: boolean;
395
+ }
396
+
397
+ /**
398
+ * Props for Base UI Dialog.Popup component
399
+ */
400
+ export interface BaseUiDialogPopupProps {
401
+ onAnimationEnd: () => void;
402
+ }
403
+
404
+ /**
405
+ * Adapter for Base UI Dialog.Root component
406
+ */
407
+ export const baseUiDialog = (
408
+ modal: ModalHandler,
409
+ options?: AdapterOptions,
410
+ ): BaseUiDialogRootProps => ({
411
+ open: modal.isOpen,
412
+ onOpenChange: (open: boolean) => {
413
+ if (!(open || options?.disableClose)) {
414
+ modal.dismiss();
415
+ }
416
+ },
417
+ dismissible: !options?.disableClose,
418
+ });
419
+
420
+ /**
421
+ * Adapter for Base UI Dialog.Portal component
422
+ */
423
+ export const baseUiDialogPortal = (
424
+ modal: ModalHandler,
425
+ ): BaseUiDialogPortalProps => ({
426
+ keepMounted: modal.keepMounted,
427
+ });
428
+
429
+ /**
430
+ * Adapter for Base UI Dialog.Popup component
431
+ */
432
+ export const baseUiDialogPopup = (
433
+ modal: ModalHandler,
434
+ ): BaseUiDialogPopupProps => ({
435
+ onAnimationEnd: () => {
436
+ modal.onAnimationEnd();
437
+ },
438
+ });
439
+
440
+ /**
441
+ * Adapter for Base UI AlertDialog root component
442
+ */
443
+ export const baseUiAlertDialog = (
444
+ modal: ModalHandler,
445
+ options?: AdapterOptions,
446
+ ): BaseUiDialogRootProps => ({
447
+ open: modal.isOpen,
448
+ onOpenChange: (open: boolean) => {
449
+ if (!(open || options?.disableClose)) {
450
+ modal.dismiss();
451
+ }
452
+ },
453
+ dismissible: !options?.disableClose,
454
+ });
455
+
456
+ /**
457
+ * Adapter for Base UI AlertDialog.Portal component
458
+ */
459
+ export const baseUiAlertDialogPortal = (
460
+ modal: ModalHandler,
461
+ ): BaseUiDialogPortalProps => ({
462
+ keepMounted: modal.keepMounted,
463
+ });
464
+
465
+ /**
466
+ * Adapter for Base UI AlertDialog.Popup component
467
+ */
468
+ export const baseUiAlertDialogPopup = (
469
+ modal: ModalHandler,
470
+ ): BaseUiDialogPopupProps => ({
471
+ onAnimationEnd: () => {
472
+ modal.onAnimationEnd();
473
+ },
474
+ });
475
+
476
+ /**
477
+ * Props returned by Base UI popover adapters
478
+ */
479
+ export interface BaseUiPopoverRootProps {
480
+ open: boolean;
481
+ onOpenChange: (open: boolean) => void;
482
+ }
483
+
484
+ /**
485
+ * Props for Base UI Popover.Portal component
486
+ */
487
+ export interface BaseUiPopoverPortalProps {
488
+ keepMounted?: boolean;
489
+ }
490
+
491
+ /**
492
+ * Props for Base UI Popover.Popup component
493
+ */
494
+ export interface BaseUiPopoverPopupProps {
495
+ onAnimationEnd: () => void;
496
+ }
497
+
498
+ /**
499
+ * Adapter for Base UI Popover.Root component
500
+ */
501
+ export const baseUiPopover = (
502
+ modal: ModalHandler,
503
+ options?: AdapterOptions,
504
+ ): BaseUiPopoverRootProps => ({
505
+ open: modal.isOpen,
506
+ onOpenChange: (open: boolean) => {
507
+ if (!(open || options?.disableClose)) {
508
+ modal.dismiss();
509
+ }
510
+ },
511
+ });
512
+
513
+ /**
514
+ * Adapter for Base UI Popover.Portal component
515
+ */
516
+ export const baseUiPopoverPortal = (
517
+ modal: ModalHandler,
518
+ ): BaseUiPopoverPortalProps => ({
519
+ keepMounted: modal.keepMounted,
520
+ });
521
+
522
+ /**
523
+ * Adapter for Base UI Popover.Popup component
524
+ */
525
+ export const baseUiPopoverPopup = (
526
+ modal: ModalHandler,
527
+ ): BaseUiPopoverPopupProps => ({
528
+ onAnimationEnd: () => {
529
+ modal.onAnimationEnd();
530
+ },
531
+ });
532
+
533
+ /**
534
+ * Adapter for Base UI Sheet root component
535
+ */
536
+ export const baseUiSheet = (
537
+ modal: ModalHandler,
538
+ options?: AdapterOptions,
539
+ ): BaseUiDialogRootProps => ({
540
+ open: modal.isOpen,
541
+ onOpenChange: (open: boolean) => {
542
+ if (!(open || options?.disableClose)) {
543
+ modal.dismiss();
544
+ }
545
+ },
546
+ dismissible: !options?.disableClose,
547
+ });
548
+
549
+ /**
550
+ * Adapter for Base UI Sheet.Portal component
551
+ */
552
+ export const baseUiSheetPortal = (
553
+ modal: ModalHandler,
554
+ ): BaseUiDialogPortalProps => ({
555
+ keepMounted: modal.keepMounted,
556
+ });
557
+
558
+ /**
559
+ * Adapter for Base UI Sheet.Popup component
560
+ */
561
+ export const baseUiSheetPopup = (
562
+ modal: ModalHandler,
563
+ ): BaseUiDialogPopupProps => ({
564
+ onAnimationEnd: () => {
565
+ modal.onAnimationEnd();
566
+ },
567
+ });