@windrun-huaiin/third-ui 29.0.4 → 29.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/fuma/base/custom-header.js +6 -3
- package/dist/fuma/base/custom-header.mjs +6 -3
- package/dist/main/alert-dialog/confirm-dialog.d.ts +7 -3
- package/dist/main/alert-dialog/confirm-dialog.js +11 -6
- package/dist/main/alert-dialog/confirm-dialog.mjs +13 -8
- package/dist/main/alert-dialog/dialog-loading-action.d.ts +12 -0
- package/dist/main/alert-dialog/dialog-loading-action.js +42 -0
- package/dist/main/alert-dialog/dialog-loading-action.mjs +40 -0
- package/dist/main/alert-dialog/high-priority-confirm-dialog.d.ts +6 -3
- package/dist/main/alert-dialog/high-priority-confirm-dialog.js +13 -4
- package/dist/main/alert-dialog/high-priority-confirm-dialog.mjs +14 -5
- package/dist/main/alert-dialog/index.d.ts +1 -0
- package/dist/main/alert-dialog/info-dialog.d.ts +4 -2
- package/dist/main/alert-dialog/info-dialog.js +6 -5
- package/dist/main/alert-dialog/info-dialog.mjs +7 -6
- package/dist/main/alert-dialog/undoable-confirm-dialog.d.ts +8 -4
- package/dist/main/alert-dialog/undoable-confirm-dialog.js +23 -16
- package/dist/main/alert-dialog/undoable-confirm-dialog.mjs +24 -17
- package/dist/main/buttons/gradient-button.d.ts +3 -1
- package/dist/main/buttons/gradient-button.js +29 -3
- package/dist/main/buttons/gradient-button.mjs +29 -3
- package/dist/main/buttons/index.d.ts +1 -0
- package/dist/main/buttons/index.js +3 -0
- package/dist/main/buttons/index.mjs +1 -0
- package/dist/main/buttons/use-press-feedback.d.ts +18 -0
- package/dist/main/buttons/use-press-feedback.js +42 -0
- package/dist/main/buttons/use-press-feedback.mjs +39 -0
- package/dist/main/buttons/x-button.d.ts +3 -0
- package/dist/main/buttons/x-button.js +36 -6
- package/dist/main/buttons/x-button.mjs +36 -6
- package/dist/main/calendar/calendar-date-range-input.d.ts +17 -0
- package/dist/main/calendar/calendar-date-range-input.js +81 -0
- package/dist/main/calendar/calendar-date-range-input.mjs +79 -0
- package/dist/main/calendar/calendar-status-view.d.ts +23 -0
- package/dist/main/calendar/calendar-status-view.js +155 -0
- package/dist/main/calendar/calendar-status-view.mjs +153 -0
- package/dist/main/calendar/index.d.ts +3 -0
- package/dist/main/calendar/index.js +12 -0
- package/dist/main/calendar/index.mjs +4 -0
- package/dist/main/calendar/random-date-range-dialog.d.ts +15 -0
- package/dist/main/calendar/random-date-range-dialog.js +447 -0
- package/dist/main/calendar/random-date-range-dialog.mjs +445 -0
- package/dist/main/features.js +2 -2
- package/dist/main/features.mjs +1 -1
- package/dist/main/usage.js +2 -2
- package/dist/main/usage.mjs +1 -1
- package/package.json +9 -4
- package/src/fuma/base/custom-header.tsx +6 -3
- package/src/main/alert-dialog/confirm-dialog.tsx +59 -46
- package/src/main/alert-dialog/dialog-loading-action.tsx +63 -0
- package/src/main/alert-dialog/high-priority-confirm-dialog.tsx +67 -48
- package/src/main/alert-dialog/index.ts +1 -0
- package/src/main/alert-dialog/info-dialog.tsx +50 -44
- package/src/main/alert-dialog/undoable-confirm-dialog.tsx +96 -81
- package/src/main/buttons/gradient-button.tsx +36 -3
- package/src/main/buttons/index.ts +1 -0
- package/src/main/buttons/use-press-feedback.ts +58 -0
- package/src/main/buttons/x-button.tsx +53 -11
- package/src/main/calendar/calendar-date-range-input.tsx +173 -0
- package/src/main/calendar/calendar-status-view.tsx +365 -0
- package/src/main/calendar/index.ts +5 -0
- package/src/main/calendar/random-date-range-dialog.tsx +741 -0
- package/src/main/features.tsx +1 -1
- package/src/main/usage.tsx +1 -1
|
@@ -24,8 +24,10 @@ import {
|
|
|
24
24
|
primaryButtonClass,
|
|
25
25
|
secondaryButtonClass,
|
|
26
26
|
} from './dialog-styles';
|
|
27
|
+
import { DialogLoadingAction, DialogActionHandler, useDialogLoadingAction } from './dialog-loading-action';
|
|
27
28
|
|
|
28
29
|
export type ConfirmDialogType = 'normal' | 'danger';
|
|
30
|
+
export type ConfirmDialogEmphasis = 'confirm' | 'cancel';
|
|
29
31
|
|
|
30
32
|
interface ConfirmDialogProps {
|
|
31
33
|
open: boolean;
|
|
@@ -35,8 +37,10 @@ interface ConfirmDialogProps {
|
|
|
35
37
|
description: React.ReactNode;
|
|
36
38
|
cancelText?: string;
|
|
37
39
|
confirmText?: string;
|
|
38
|
-
|
|
39
|
-
|
|
40
|
+
emphasis?: ConfirmDialogEmphasis;
|
|
41
|
+
loadingActions?: readonly DialogLoadingAction[];
|
|
42
|
+
onCancel?: DialogActionHandler;
|
|
43
|
+
onConfirm?: DialogActionHandler;
|
|
40
44
|
}
|
|
41
45
|
|
|
42
46
|
const confirmTypeClassMap: Record<ConfirmDialogType, {
|
|
@@ -70,62 +74,71 @@ export function ConfirmDialog({
|
|
|
70
74
|
description,
|
|
71
75
|
cancelText = 'Cancel',
|
|
72
76
|
confirmText = 'Confirm',
|
|
77
|
+
emphasis = 'confirm',
|
|
78
|
+
loadingActions,
|
|
73
79
|
onCancel,
|
|
74
80
|
onConfirm,
|
|
75
81
|
}: ConfirmDialogProps) {
|
|
76
82
|
const typeClass = confirmTypeClassMap[type];
|
|
77
83
|
const Icon = typeClass.Icon;
|
|
84
|
+
const cancelButtonClass = emphasis === 'cancel' ? typeClass.action : secondaryButtonClass;
|
|
85
|
+
const confirmButtonClass = emphasis === 'cancel' ? secondaryButtonClass : typeClass.action;
|
|
86
|
+
const { dialogLoading, runDialogAction } = useDialogLoadingAction({ loadingActions, onOpenChange });
|
|
78
87
|
|
|
79
88
|
const handleCancel = () => {
|
|
89
|
+
void runDialogAction('cancel', onCancel);
|
|
90
|
+
};
|
|
91
|
+
const handleClose = () => {
|
|
80
92
|
onOpenChange(false);
|
|
81
|
-
onCancel?.();
|
|
82
93
|
};
|
|
83
94
|
|
|
84
95
|
return (
|
|
85
|
-
|
|
86
|
-
<
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
<
|
|
93
|
-
<
|
|
94
|
-
<
|
|
95
|
-
<
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
96
|
+
<>
|
|
97
|
+
<AlertDialog open={open} onOpenChange={onOpenChange}>
|
|
98
|
+
<AlertDialogContent
|
|
99
|
+
className={cn(dialogContentClass, typeClass.content)}
|
|
100
|
+
overlayClassName={dialogThemedOverlayClass}
|
|
101
|
+
onOverlayClick={handleClose}
|
|
102
|
+
>
|
|
103
|
+
<div className={dialogHeaderClass}>
|
|
104
|
+
<AlertDialogTitle asChild>
|
|
105
|
+
<div className={dialogTitleClass}>
|
|
106
|
+
<span className={cn('inline-flex size-9 shrink-0 items-center justify-center rounded-full ring-1', typeClass.iconWrap)}>
|
|
107
|
+
<Icon className={cn('size-5', typeClass.icon)} />
|
|
108
|
+
</span>
|
|
109
|
+
<span className="min-w-0 truncate">{title}</span>
|
|
110
|
+
</div>
|
|
111
|
+
</AlertDialogTitle>
|
|
112
|
+
<button
|
|
113
|
+
type="button"
|
|
114
|
+
className={closeButtonClass}
|
|
115
|
+
onClick={handleClose}
|
|
116
|
+
aria-label="Close"
|
|
117
|
+
>
|
|
118
|
+
<XIcon className="size-4" />
|
|
119
|
+
</button>
|
|
120
|
+
</div>
|
|
109
121
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
122
|
+
<AlertDialogDescription className={dialogDescriptionClass}>
|
|
123
|
+
{description}
|
|
124
|
+
</AlertDialogDescription>
|
|
113
125
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
</
|
|
127
|
-
</
|
|
128
|
-
</
|
|
129
|
-
|
|
126
|
+
<div className={dialogFooterClass}>
|
|
127
|
+
<AlertDialogCancel className={cancelButtonClass} onClick={handleCancel}>
|
|
128
|
+
{cancelText}
|
|
129
|
+
</AlertDialogCancel>
|
|
130
|
+
<AlertDialogAction
|
|
131
|
+
className={confirmButtonClass}
|
|
132
|
+
onClick={() => {
|
|
133
|
+
void runDialogAction('confirm', onConfirm);
|
|
134
|
+
}}
|
|
135
|
+
>
|
|
136
|
+
{confirmText}
|
|
137
|
+
</AlertDialogAction>
|
|
138
|
+
</div>
|
|
139
|
+
</AlertDialogContent>
|
|
140
|
+
</AlertDialog>
|
|
141
|
+
{dialogLoading}
|
|
142
|
+
</>
|
|
130
143
|
);
|
|
131
144
|
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import React from 'react';
|
|
4
|
+
import { createPortal } from 'react-dom';
|
|
5
|
+
import { Loading } from '../loading';
|
|
6
|
+
|
|
7
|
+
export type DialogLoadingAction = 'cancel' | 'confirm' | 'undo';
|
|
8
|
+
export type DialogActionHandler = () => void | Promise<void>;
|
|
9
|
+
|
|
10
|
+
interface UseDialogLoadingActionOptions {
|
|
11
|
+
loadingActions?: readonly DialogLoadingAction[];
|
|
12
|
+
onOpenChange: (open: boolean) => void;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export function useDialogLoadingAction({
|
|
16
|
+
loadingActions,
|
|
17
|
+
onOpenChange,
|
|
18
|
+
}: UseDialogLoadingActionOptions) {
|
|
19
|
+
const [mounted, setMounted] = React.useState(false);
|
|
20
|
+
const [loading, setLoading] = React.useState(false);
|
|
21
|
+
|
|
22
|
+
React.useEffect(() => {
|
|
23
|
+
setMounted(true);
|
|
24
|
+
}, []);
|
|
25
|
+
|
|
26
|
+
const runDialogAction = React.useCallback(async (
|
|
27
|
+
action: DialogLoadingAction,
|
|
28
|
+
handler?: DialogActionHandler
|
|
29
|
+
) => {
|
|
30
|
+
onOpenChange(false);
|
|
31
|
+
|
|
32
|
+
if (!handler) {
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
if (!loadingActions?.includes(action)) {
|
|
37
|
+
await handler();
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
setLoading(true);
|
|
42
|
+
|
|
43
|
+
try {
|
|
44
|
+
await handler();
|
|
45
|
+
} finally {
|
|
46
|
+
setLoading(false);
|
|
47
|
+
}
|
|
48
|
+
}, [loadingActions, onOpenChange]);
|
|
49
|
+
|
|
50
|
+
const dialogLoading = mounted && loading
|
|
51
|
+
? createPortal(
|
|
52
|
+
<div className="fixed inset-0 z-10000">
|
|
53
|
+
<Loading className="h-full w-full" />
|
|
54
|
+
</div>,
|
|
55
|
+
document.body
|
|
56
|
+
)
|
|
57
|
+
: null;
|
|
58
|
+
|
|
59
|
+
return {
|
|
60
|
+
dialogLoading,
|
|
61
|
+
runDialogAction,
|
|
62
|
+
};
|
|
63
|
+
}
|
|
@@ -15,80 +15,99 @@ import {
|
|
|
15
15
|
secondaryButtonClass,
|
|
16
16
|
} from "./dialog-styles";
|
|
17
17
|
import { themeBgColor, themeBorderColor, themeIconColor } from "@windrun-huaiin/base-ui/lib";
|
|
18
|
+
import { DialogLoadingAction, DialogActionHandler, useDialogLoadingAction } from "./dialog-loading-action";
|
|
18
19
|
|
|
19
20
|
interface HighPriorityConfirmDialogProps {
|
|
20
21
|
open: boolean;
|
|
21
|
-
|
|
22
|
-
|
|
22
|
+
onOpenChange: (open: boolean) => void;
|
|
23
|
+
onCancel: DialogActionHandler;
|
|
24
|
+
onConfirm: DialogActionHandler;
|
|
23
25
|
title: string;
|
|
24
26
|
description: React.ReactNode;
|
|
25
27
|
confirmText?: string;
|
|
26
28
|
cancelText?: string;
|
|
29
|
+
loadingActions?: readonly DialogLoadingAction[];
|
|
27
30
|
}
|
|
28
31
|
|
|
29
32
|
export function HighPriorityConfirmDialog({
|
|
30
33
|
open,
|
|
34
|
+
onOpenChange,
|
|
31
35
|
onCancel,
|
|
32
36
|
onConfirm,
|
|
33
37
|
title,
|
|
34
38
|
description,
|
|
35
39
|
confirmText = "Confirm",
|
|
36
40
|
cancelText = "Cancel",
|
|
41
|
+
loadingActions,
|
|
37
42
|
}: HighPriorityConfirmDialogProps) {
|
|
38
43
|
const [mounted, setMounted] = useState(false);
|
|
44
|
+
const { dialogLoading, runDialogAction } = useDialogLoadingAction({ loadingActions, onOpenChange });
|
|
39
45
|
|
|
40
46
|
useEffect(() => {
|
|
41
47
|
// Ensure portal target exists and prevent hydration mismatch
|
|
42
48
|
setTimeout(() => setMounted(true), 0);
|
|
43
49
|
}, []);
|
|
44
50
|
|
|
45
|
-
if (!
|
|
51
|
+
if (!mounted) return dialogLoading;
|
|
46
52
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
<span className="min-w-0 truncate">{title}</span>
|
|
61
|
-
</h3>
|
|
62
|
-
<button
|
|
63
|
-
type="button"
|
|
64
|
-
className={closeButtonClass}
|
|
65
|
-
onClick={onCancel}
|
|
66
|
-
aria-label="Close"
|
|
67
|
-
>
|
|
68
|
-
<XIcon className="size-4" />
|
|
69
|
-
</button>
|
|
70
|
-
</div>
|
|
71
|
-
<div className={dialogDescriptionClass}>
|
|
72
|
-
{description}
|
|
73
|
-
</div>
|
|
74
|
-
<div className={dialogFooterClass}>
|
|
75
|
-
<button
|
|
76
|
-
type="button"
|
|
77
|
-
onClick={onCancel}
|
|
78
|
-
className={secondaryButtonClass}
|
|
79
|
-
>
|
|
80
|
-
{cancelText}
|
|
81
|
-
</button>
|
|
82
|
-
<button
|
|
83
|
-
type="button"
|
|
84
|
-
onClick={onConfirm}
|
|
85
|
-
className={cn(primaryButtonClass, "hover:scale-105 active:scale-95")}
|
|
53
|
+
const handleClose = () => {
|
|
54
|
+
onOpenChange(false);
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
return (
|
|
58
|
+
<>
|
|
59
|
+
{open && createPortal(
|
|
60
|
+
<div className="fixed inset-0 z-10000 flex items-center justify-center bg-black/60 backdrop-blur-sm animate-in fade-in duration-300">
|
|
61
|
+
<div
|
|
62
|
+
className={cn(highPrioritySurfaceClass, "scale-100")}
|
|
63
|
+
role="dialog"
|
|
64
|
+
aria-modal="true"
|
|
65
|
+
onClick={(e) => e.stopPropagation()}
|
|
86
66
|
>
|
|
87
|
-
{
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
67
|
+
<div className={dialogHeaderClass}>
|
|
68
|
+
<h3 className={highPriorityTitleClass}>
|
|
69
|
+
<span className={cn('inline-flex size-9 shrink-0 items-center justify-center rounded-full ring-1', themeBgColor, themeBorderColor)}>
|
|
70
|
+
<FAQSIcon className={cn('size-5', themeIconColor)} />
|
|
71
|
+
</span>
|
|
72
|
+
<span className="min-w-0 truncate">{title}</span>
|
|
73
|
+
</h3>
|
|
74
|
+
<button
|
|
75
|
+
type="button"
|
|
76
|
+
className={closeButtonClass}
|
|
77
|
+
onClick={handleClose}
|
|
78
|
+
aria-label="Close"
|
|
79
|
+
>
|
|
80
|
+
<XIcon className="size-4" />
|
|
81
|
+
</button>
|
|
82
|
+
</div>
|
|
83
|
+
<div className={dialogDescriptionClass}>
|
|
84
|
+
{description}
|
|
85
|
+
</div>
|
|
86
|
+
<div className={dialogFooterClass}>
|
|
87
|
+
<button
|
|
88
|
+
type="button"
|
|
89
|
+
onClick={() => {
|
|
90
|
+
void runDialogAction('cancel', onCancel);
|
|
91
|
+
}}
|
|
92
|
+
className={secondaryButtonClass}
|
|
93
|
+
>
|
|
94
|
+
{cancelText}
|
|
95
|
+
</button>
|
|
96
|
+
<button
|
|
97
|
+
type="button"
|
|
98
|
+
onClick={() => {
|
|
99
|
+
void runDialogAction('confirm', onConfirm);
|
|
100
|
+
}}
|
|
101
|
+
className={cn(primaryButtonClass, "hover:scale-105 active:scale-95")}
|
|
102
|
+
>
|
|
103
|
+
{confirmText}
|
|
104
|
+
</button>
|
|
105
|
+
</div>
|
|
106
|
+
</div>
|
|
107
|
+
</div>,
|
|
108
|
+
document.body
|
|
109
|
+
)}
|
|
110
|
+
{dialogLoading}
|
|
111
|
+
</>
|
|
93
112
|
);
|
|
94
113
|
}
|
|
@@ -25,6 +25,7 @@ import {
|
|
|
25
25
|
dialogThemedOverlayClass,
|
|
26
26
|
dialogTitleClass,
|
|
27
27
|
} from './dialog-styles';
|
|
28
|
+
import { DialogLoadingAction, DialogActionHandler, useDialogLoadingAction } from './dialog-loading-action';
|
|
28
29
|
|
|
29
30
|
export type InfoDialogType = 'info' | 'warn' | 'success' | 'error';
|
|
30
31
|
type InfoDialogIcon = typeof BadgeInfoIcon;
|
|
@@ -36,7 +37,8 @@ interface InfoDialogProps {
|
|
|
36
37
|
title: React.ReactNode;
|
|
37
38
|
description: React.ReactNode;
|
|
38
39
|
confirmText?: string;
|
|
39
|
-
|
|
40
|
+
loadingActions?: readonly DialogLoadingAction[];
|
|
41
|
+
onConfirm?: DialogActionHandler;
|
|
40
42
|
}
|
|
41
43
|
|
|
42
44
|
const infoTypeClassMap: Record<InfoDialogType, {
|
|
@@ -83,57 +85,61 @@ export function InfoDialog({
|
|
|
83
85
|
title,
|
|
84
86
|
description,
|
|
85
87
|
confirmText = 'OK',
|
|
88
|
+
loadingActions,
|
|
86
89
|
onConfirm,
|
|
87
90
|
}: InfoDialogProps) {
|
|
88
91
|
const typeClass = infoTypeClassMap[type];
|
|
89
92
|
const Icon = typeClass.Icon;
|
|
90
93
|
const handleClose = () => onOpenChange(false);
|
|
94
|
+
const { dialogLoading, runDialogAction } = useDialogLoadingAction({ loadingActions, onOpenChange });
|
|
91
95
|
|
|
92
96
|
return (
|
|
93
|
-
|
|
94
|
-
<
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
<
|
|
101
|
-
<
|
|
102
|
-
<
|
|
103
|
-
<
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
97
|
+
<>
|
|
98
|
+
<AlertDialog open={open} onOpenChange={onOpenChange}>
|
|
99
|
+
<AlertDialogContent
|
|
100
|
+
className={cn(dialogContentClass, typeClass.content)}
|
|
101
|
+
overlayClassName={dialogThemedOverlayClass}
|
|
102
|
+
onOverlayClick={handleClose}
|
|
103
|
+
>
|
|
104
|
+
<div className={dialogHeaderClass}>
|
|
105
|
+
<AlertDialogTitle asChild>
|
|
106
|
+
<div className={dialogTitleClass}>
|
|
107
|
+
<span className={cn('inline-flex size-9 shrink-0 items-center justify-center rounded-full ring-1', typeClass.iconWrap)}>
|
|
108
|
+
<Icon className={cn('size-5', typeClass.icon)} />
|
|
109
|
+
</span>
|
|
110
|
+
<span className="min-w-0 truncate">{title}</span>
|
|
111
|
+
</div>
|
|
112
|
+
</AlertDialogTitle>
|
|
113
|
+
<button
|
|
114
|
+
type="button"
|
|
115
|
+
className={closeButtonClass}
|
|
116
|
+
onClick={handleClose}
|
|
117
|
+
aria-label="Close"
|
|
118
|
+
>
|
|
119
|
+
<XIcon className="size-4" />
|
|
120
|
+
</button>
|
|
121
|
+
</div>
|
|
117
122
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
123
|
+
<AlertDialogDescription className={dialogDescriptionClass}>
|
|
124
|
+
{description}
|
|
125
|
+
</AlertDialogDescription>
|
|
121
126
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
</
|
|
135
|
-
</
|
|
136
|
-
</
|
|
137
|
-
|
|
127
|
+
<div className={dialogFooterClass}>
|
|
128
|
+
<AlertDialogAction
|
|
129
|
+
className={cn(
|
|
130
|
+
'inline-flex min-h-10 items-center justify-center rounded-full px-5 py-2 text-sm font-bold transition focus-visible:outline-none focus-visible:ring-2 disabled:pointer-events-none disabled:opacity-60',
|
|
131
|
+
typeClass.action
|
|
132
|
+
)}
|
|
133
|
+
onClick={() => {
|
|
134
|
+
void runDialogAction('confirm', onConfirm);
|
|
135
|
+
}}
|
|
136
|
+
>
|
|
137
|
+
{confirmText}
|
|
138
|
+
</AlertDialogAction>
|
|
139
|
+
</div>
|
|
140
|
+
</AlertDialogContent>
|
|
141
|
+
</AlertDialog>
|
|
142
|
+
{dialogLoading}
|
|
143
|
+
</>
|
|
138
144
|
);
|
|
139
145
|
}
|