@rovula/ui 0.1.26 → 0.1.28
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/cjs/bundle.css +12 -0
- package/dist/cjs/bundle.js +3 -3
- package/dist/cjs/bundle.js.map +1 -1
- package/dist/cjs/types/components/Avatar/Avatar.d.ts +1 -1
- package/dist/cjs/types/components/Avatar/Avatar.stories.d.ts +1 -1
- package/dist/cjs/types/components/Avatar/Avatar.styles.d.ts +1 -0
- package/dist/cjs/types/patterns/confirm-dialog/ConfirmDialog.d.ts +2 -0
- package/dist/cjs/types/patterns/confirm-dialog/ConfirmDialog.stories.d.ts +3 -0
- package/dist/components/Avatar/Avatar.js +2 -1
- package/dist/components/Avatar/Avatar.styles.js +3 -0
- package/dist/components/Avatar/AvatarBase.js +1 -1
- package/dist/esm/bundle.css +12 -0
- package/dist/esm/bundle.js +2 -2
- package/dist/esm/bundle.js.map +1 -1
- package/dist/esm/types/components/Avatar/Avatar.d.ts +1 -1
- package/dist/esm/types/components/Avatar/Avatar.stories.d.ts +1 -1
- package/dist/esm/types/components/Avatar/Avatar.styles.d.ts +1 -0
- package/dist/esm/types/patterns/confirm-dialog/ConfirmDialog.d.ts +2 -0
- package/dist/esm/types/patterns/confirm-dialog/ConfirmDialog.stories.d.ts +3 -0
- package/dist/index.d.ts +3 -1
- package/dist/patterns/confirm-dialog/ConfirmDialog.js +18 -7
- package/dist/patterns/confirm-dialog/ConfirmDialog.stories.js +33 -0
- package/dist/src/theme/global.css +15 -0
- package/package.json +1 -1
- package/src/components/Avatar/Avatar.styles.ts +4 -1
- package/src/components/Avatar/Avatar.tsx +3 -2
- package/src/components/Avatar/AvatarBase.tsx +3 -3
- package/src/patterns/confirm-dialog/ConfirmDialog.stories.tsx +71 -0
- package/src/patterns/confirm-dialog/ConfirmDialog.tsx +24 -9
|
@@ -22,7 +22,7 @@ type AvatarImageProps = {
|
|
|
22
22
|
type: "image";
|
|
23
23
|
} & BaseAvatarProps;
|
|
24
24
|
type AvatarIconProps = {
|
|
25
|
-
icon:
|
|
25
|
+
icon: React.ReactNode;
|
|
26
26
|
type: "icon";
|
|
27
27
|
} & BaseAvatarProps;
|
|
28
28
|
export type AvatarProps = AvatarTextProps | AvatarImageProps | AvatarIconProps;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export declare const avatarVariants: (props?: ({
|
|
2
2
|
size?: "sm" | "md" | "lg" | "xxs" | "xs" | null | undefined;
|
|
3
3
|
rounded?: "none" | "normal" | "full" | null | undefined;
|
|
4
|
+
hasImage?: boolean | null | undefined;
|
|
4
5
|
} & import("class-variance-authority/dist/types").ClassProp) | undefined) => string;
|
|
@@ -21,6 +21,8 @@ export type ConfirmDialogProps = {
|
|
|
21
21
|
* When true, hides the cancel button — useful for info/error alerts that only need one action.
|
|
22
22
|
*/
|
|
23
23
|
hideCancelButton?: boolean;
|
|
24
|
+
/** When true, shows a loading spinner on the confirm button and disables all interactive controls. */
|
|
25
|
+
isLoading?: boolean;
|
|
24
26
|
testId?: string;
|
|
25
27
|
cancelClassName?: string;
|
|
26
28
|
confirmClassName?: string;
|
|
@@ -22,6 +22,7 @@ declare const meta: {
|
|
|
22
22
|
trigger?: React.ReactNode;
|
|
23
23
|
typeToConfirm?: string | undefined;
|
|
24
24
|
hideCancelButton?: boolean | undefined;
|
|
25
|
+
isLoading?: boolean | undefined;
|
|
25
26
|
testId?: string | undefined;
|
|
26
27
|
cancelClassName?: string | undefined;
|
|
27
28
|
confirmClassName?: string | undefined;
|
|
@@ -55,3 +56,5 @@ export declare const WithoutCancelButton: Story;
|
|
|
55
56
|
export declare const RequireConfirmText: Story;
|
|
56
57
|
export declare const FigmaDefaultOpen: Story;
|
|
57
58
|
export declare const FigmaRequirePasswordDefaultOpen: Story;
|
|
59
|
+
export declare const WithLoading: Story;
|
|
60
|
+
export declare const WithLoadingAndTypeToConfirm: Story;
|
package/dist/index.d.ts
CHANGED
|
@@ -542,7 +542,7 @@ type AvatarImageProps = {
|
|
|
542
542
|
type: "image";
|
|
543
543
|
} & BaseAvatarProps;
|
|
544
544
|
type AvatarIconProps = {
|
|
545
|
-
icon:
|
|
545
|
+
icon: React.ReactNode;
|
|
546
546
|
type: "icon";
|
|
547
547
|
} & BaseAvatarProps;
|
|
548
548
|
type AvatarProps = AvatarTextProps | AvatarImageProps | AvatarIconProps;
|
|
@@ -1318,6 +1318,8 @@ type ConfirmDialogProps = {
|
|
|
1318
1318
|
* When true, hides the cancel button — useful for info/error alerts that only need one action.
|
|
1319
1319
|
*/
|
|
1320
1320
|
hideCancelButton?: boolean;
|
|
1321
|
+
/** When true, shows a loading spinner on the confirm button and disables all interactive controls. */
|
|
1322
|
+
isLoading?: boolean;
|
|
1321
1323
|
testId?: string;
|
|
1322
1324
|
cancelClassName?: string;
|
|
1323
1325
|
confirmClassName?: string;
|
|
@@ -5,7 +5,8 @@ import * as yup from "yup";
|
|
|
5
5
|
import { AlertDialog, AlertDialogContent, AlertDialogHeader, AlertDialogTitle, AlertDialogDescription, AlertDialogFooter, AlertDialogAction, AlertDialogCancel, AlertDialogTrigger, } from "@/components/AlertDialog/AlertDialog";
|
|
6
6
|
import { useControlledForm, Field } from "@/components/Form";
|
|
7
7
|
import { TextInput } from "@/components/TextInput/TextInput";
|
|
8
|
-
|
|
8
|
+
import Loading from "@/components/Loading/Loading";
|
|
9
|
+
export const ConfirmDialog = ({ open, onOpenChange, title, description, children, confirmLabel = "Confirm", cancelLabel = "Cancel", onConfirm, onCancel, onClose, trigger, typeToConfirm, hideCancelButton = false, isLoading = false, testId, cancelClassName, confirmClassName, }) => {
|
|
9
10
|
const requiresInput = !!typeToConfirm;
|
|
10
11
|
const validationSchema = React.useMemo(() => yup.object({
|
|
11
12
|
confirmInput: yup
|
|
@@ -20,20 +21,24 @@ export const ConfirmDialog = ({ open, onOpenChange, title, description, children
|
|
|
20
21
|
reValidateMode: "onChange",
|
|
21
22
|
});
|
|
22
23
|
const isFormValid = methods.formState.isValid;
|
|
24
|
+
React.useEffect(() => {
|
|
25
|
+
if (!open) {
|
|
26
|
+
methods.reset();
|
|
27
|
+
}
|
|
28
|
+
}, [open]);
|
|
23
29
|
const handleOpenChange = (nextOpen) => {
|
|
30
|
+
if (isLoading)
|
|
31
|
+
return;
|
|
24
32
|
if (!nextOpen) {
|
|
25
|
-
methods.reset();
|
|
26
33
|
onClose === null || onClose === void 0 ? void 0 : onClose();
|
|
27
34
|
}
|
|
28
35
|
onOpenChange === null || onOpenChange === void 0 ? void 0 : onOpenChange(nextOpen);
|
|
29
36
|
};
|
|
30
37
|
const handleCancel = () => {
|
|
31
|
-
methods.reset();
|
|
32
38
|
onCancel === null || onCancel === void 0 ? void 0 : onCancel();
|
|
33
39
|
onClose === null || onClose === void 0 ? void 0 : onClose();
|
|
34
40
|
};
|
|
35
41
|
const handleSubmit = () => {
|
|
36
|
-
methods.reset();
|
|
37
42
|
onConfirm === null || onConfirm === void 0 ? void 0 : onConfirm();
|
|
38
43
|
};
|
|
39
44
|
return (_jsxs(AlertDialog, { open: open, onOpenChange: handleOpenChange, children: [trigger && _jsx(AlertDialogTrigger, { asChild: true, children: trigger }), _jsxs(AlertDialogContent, { "data-testid": testId, children: [_jsxs(AlertDialogHeader, { children: [_jsx(AlertDialogTitle, { "data-testid": testId && `${testId}-title`, children: title }), description && (_jsx(AlertDialogDescription, { "data-testid": testId && `${testId}-description`, children: description }))] }), children, requiresInput && (_jsxs(FormRoot, { className: "flex flex-col gap-4 w-full", onSubmit: handleSubmit, children: [_jsxs("p", { className: "typography-small1 text-text-contrast-max", children: ["Type \u201C", typeToConfirm, "\u201D to proceed."] }), _jsx(Field, { name: "confirmInput", component: TextInput, componentProps: {
|
|
@@ -43,8 +48,14 @@ export const ConfirmDialog = ({ open, onOpenChange, title, description, children
|
|
|
43
48
|
keepFooterSpace: true,
|
|
44
49
|
fullwidth: true,
|
|
45
50
|
testId: testId && `${testId}-type-to-confirm-input`,
|
|
46
|
-
} })] })), _jsxs(AlertDialogFooter, { children: [!hideCancelButton && (_jsx(AlertDialogCancel, { className: cancelClassName, "data-testid": testId && `${testId}-cancel-button`, onClick: handleCancel, children: cancelLabel })),
|
|
47
|
-
|
|
48
|
-
|
|
51
|
+
}, disabled: isLoading })] })), _jsxs(AlertDialogFooter, { children: [!hideCancelButton && (_jsx(AlertDialogCancel, { className: cancelClassName, "data-testid": testId && `${testId}-cancel-button`, onClick: handleCancel, disabled: isLoading, children: cancelLabel })), _jsxs(AlertDialogAction, { type: "button", disabled: isLoading || (requiresInput && !isFormValid), onClick: (e) => {
|
|
52
|
+
e.preventDefault();
|
|
53
|
+
if (requiresInput) {
|
|
54
|
+
methods.handleSubmit(handleSubmit)();
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
onConfirm === null || onConfirm === void 0 ? void 0 : onConfirm();
|
|
58
|
+
}
|
|
59
|
+
}, className: confirmClassName, "data-testid": testId && `${testId}-confirm-button`, children: [isLoading && _jsx(Loading, {}), confirmLabel] })] })] })] }));
|
|
49
60
|
};
|
|
50
61
|
ConfirmDialog.displayName = "ConfirmDialog";
|
|
@@ -101,3 +101,36 @@ export const FigmaRequirePasswordDefaultOpen = {
|
|
|
101
101
|
return (_jsx(ConfirmDialog, Object.assign({}, args, { open: open, onOpenChange: (next) => updateArgs({ open: next }), onConfirm: () => updateArgs({ open: false }), onCancel: () => updateArgs({ open: false }) })));
|
|
102
102
|
},
|
|
103
103
|
};
|
|
104
|
+
export const WithLoading = {
|
|
105
|
+
args: {
|
|
106
|
+
open: false,
|
|
107
|
+
title: "Delete project?",
|
|
108
|
+
description: "This action cannot be undone.",
|
|
109
|
+
confirmLabel: "Delete",
|
|
110
|
+
cancelLabel: "Cancel",
|
|
111
|
+
},
|
|
112
|
+
render: (args) => {
|
|
113
|
+
const [{ open, isLoading }, updateArgs] = useArgs();
|
|
114
|
+
return (_jsx(ConfirmDialog, Object.assign({}, args, { open: open, isLoading: isLoading, onOpenChange: (next) => updateArgs({ open: next }), onConfirm: () => {
|
|
115
|
+
updateArgs({ isLoading: true });
|
|
116
|
+
setTimeout(() => updateArgs({ isLoading: false, open: false }), 2000);
|
|
117
|
+
}, onCancel: () => updateArgs({ open: false }), trigger: _jsx(Button, { fullwidth: false, color: "error", onClick: () => updateArgs({ open: true, isLoading: false }), children: "Delete" }) })));
|
|
118
|
+
},
|
|
119
|
+
};
|
|
120
|
+
export const WithLoadingAndTypeToConfirm = {
|
|
121
|
+
args: {
|
|
122
|
+
open: false,
|
|
123
|
+
title: "Delete project?",
|
|
124
|
+
description: "This action cannot be undone.",
|
|
125
|
+
confirmLabel: "Delete",
|
|
126
|
+
cancelLabel: "Cancel",
|
|
127
|
+
typeToConfirm: "delete",
|
|
128
|
+
},
|
|
129
|
+
render: (args) => {
|
|
130
|
+
const [{ open, isLoading }, updateArgs] = useArgs();
|
|
131
|
+
return (_jsx(ConfirmDialog, Object.assign({}, args, { open: open, isLoading: isLoading, onOpenChange: (next) => updateArgs({ open: next }), onConfirm: () => {
|
|
132
|
+
updateArgs({ isLoading: true });
|
|
133
|
+
setTimeout(() => updateArgs({ isLoading: false, open: false }), 5000);
|
|
134
|
+
}, onCancel: () => updateArgs({ open: false }), trigger: _jsx(Button, { fullwidth: false, color: "error", onClick: () => updateArgs({ open: true, isLoading: false }), children: "Delete (type to confirm)" }) })));
|
|
135
|
+
},
|
|
136
|
+
};
|
|
@@ -7055,6 +7055,11 @@ input[type=number] {
|
|
|
7055
7055
|
background-color: color-mix(in srgb, var(--transparent-warning-8) calc(100% * var(--tw-bg-opacity, 1)), transparent);
|
|
7056
7056
|
}
|
|
7057
7057
|
|
|
7058
|
+
.bg-white {
|
|
7059
|
+
--tw-bg-opacity: 1;
|
|
7060
|
+
background-color: rgb(255 255 255 / var(--tw-bg-opacity, 1));
|
|
7061
|
+
}
|
|
7062
|
+
|
|
7058
7063
|
.bg-white-transparent-12 {
|
|
7059
7064
|
--tw-bg-opacity: 1;
|
|
7060
7065
|
background-color: color-mix(in srgb, var(--transparent-white-12) calc(100% * var(--tw-bg-opacity, 1)), transparent);
|
|
@@ -7325,6 +7330,16 @@ input[type=number] {
|
|
|
7325
7330
|
stroke: color-mix(in srgb, var(--state-primary-default) calc(100% * 1), transparent);
|
|
7326
7331
|
}
|
|
7327
7332
|
|
|
7333
|
+
.object-cover {
|
|
7334
|
+
-o-object-fit: cover;
|
|
7335
|
+
object-fit: cover;
|
|
7336
|
+
}
|
|
7337
|
+
|
|
7338
|
+
.object-top {
|
|
7339
|
+
-o-object-position: top;
|
|
7340
|
+
object-position: top;
|
|
7341
|
+
}
|
|
7342
|
+
|
|
7328
7343
|
.\!p-0 {
|
|
7329
7344
|
padding: 0px !important;
|
|
7330
7345
|
}
|
package/package.json
CHANGED
|
@@ -31,7 +31,7 @@ type AvatarImageProps = {
|
|
|
31
31
|
} & BaseAvatarProps;
|
|
32
32
|
|
|
33
33
|
type AvatarIconProps = {
|
|
34
|
-
icon:
|
|
34
|
+
icon: React.ReactNode;
|
|
35
35
|
type: "icon";
|
|
36
36
|
} & BaseAvatarProps;
|
|
37
37
|
|
|
@@ -61,7 +61,8 @@ const Avatar: React.FC<AvatarProps> = ({
|
|
|
61
61
|
children,
|
|
62
62
|
style,
|
|
63
63
|
}) => {
|
|
64
|
-
const
|
|
64
|
+
const hasImage = !!imageUrl;
|
|
65
|
+
const avatarClassname = avatarVariants({ size, rounded, hasImage });
|
|
65
66
|
|
|
66
67
|
return (
|
|
67
68
|
<AvatarBase className={cn(avatarClassname, className)} style={style}>
|
|
@@ -13,7 +13,7 @@ const AvatarBase = React.forwardRef<
|
|
|
13
13
|
ref={ref}
|
|
14
14
|
className={cn(
|
|
15
15
|
"relative flex h-10 w-10 shrink-0 overflow-hidden rounded-full",
|
|
16
|
-
className
|
|
16
|
+
className,
|
|
17
17
|
)}
|
|
18
18
|
{...props}
|
|
19
19
|
/>
|
|
@@ -26,7 +26,7 @@ const AvatarImage = React.forwardRef<
|
|
|
26
26
|
>(({ className, ...props }, ref) => (
|
|
27
27
|
<AvatarPrimitive.Image
|
|
28
28
|
ref={ref}
|
|
29
|
-
className={cn("
|
|
29
|
+
className={cn("object-cover object-top h-full w-full", className)}
|
|
30
30
|
{...props}
|
|
31
31
|
/>
|
|
32
32
|
));
|
|
@@ -40,7 +40,7 @@ const AvatarFallback = React.forwardRef<
|
|
|
40
40
|
ref={ref}
|
|
41
41
|
className={cn(
|
|
42
42
|
"flex h-full w-full items-center justify-center rounded-full bg-inherit text-inherit",
|
|
43
|
-
className
|
|
43
|
+
className,
|
|
44
44
|
)}
|
|
45
45
|
{...props}
|
|
46
46
|
/>
|
|
@@ -191,3 +191,74 @@ export const FigmaRequirePasswordDefaultOpen: Story = {
|
|
|
191
191
|
);
|
|
192
192
|
},
|
|
193
193
|
};
|
|
194
|
+
|
|
195
|
+
export const WithLoading: Story = {
|
|
196
|
+
args: {
|
|
197
|
+
open: false,
|
|
198
|
+
title: "Delete project?",
|
|
199
|
+
description: "This action cannot be undone.",
|
|
200
|
+
confirmLabel: "Delete",
|
|
201
|
+
cancelLabel: "Cancel",
|
|
202
|
+
},
|
|
203
|
+
render: (args) => {
|
|
204
|
+
const [{ open, isLoading }, updateArgs] = useArgs();
|
|
205
|
+
return (
|
|
206
|
+
<ConfirmDialog
|
|
207
|
+
{...args}
|
|
208
|
+
open={open}
|
|
209
|
+
isLoading={isLoading}
|
|
210
|
+
onOpenChange={(next) => updateArgs({ open: next })}
|
|
211
|
+
onConfirm={() => {
|
|
212
|
+
updateArgs({ isLoading: true });
|
|
213
|
+
setTimeout(() => updateArgs({ isLoading: false, open: false }), 2000);
|
|
214
|
+
}}
|
|
215
|
+
onCancel={() => updateArgs({ open: false })}
|
|
216
|
+
trigger={
|
|
217
|
+
<Button
|
|
218
|
+
fullwidth={false}
|
|
219
|
+
color="error"
|
|
220
|
+
onClick={() => updateArgs({ open: true, isLoading: false })}
|
|
221
|
+
>
|
|
222
|
+
Delete
|
|
223
|
+
</Button>
|
|
224
|
+
}
|
|
225
|
+
/>
|
|
226
|
+
);
|
|
227
|
+
},
|
|
228
|
+
};
|
|
229
|
+
|
|
230
|
+
export const WithLoadingAndTypeToConfirm: Story = {
|
|
231
|
+
args: {
|
|
232
|
+
open: false,
|
|
233
|
+
title: "Delete project?",
|
|
234
|
+
description: "This action cannot be undone.",
|
|
235
|
+
confirmLabel: "Delete",
|
|
236
|
+
cancelLabel: "Cancel",
|
|
237
|
+
typeToConfirm: "delete",
|
|
238
|
+
},
|
|
239
|
+
render: (args) => {
|
|
240
|
+
const [{ open, isLoading }, updateArgs] = useArgs();
|
|
241
|
+
return (
|
|
242
|
+
<ConfirmDialog
|
|
243
|
+
{...args}
|
|
244
|
+
open={open}
|
|
245
|
+
isLoading={isLoading}
|
|
246
|
+
onOpenChange={(next) => updateArgs({ open: next })}
|
|
247
|
+
onConfirm={() => {
|
|
248
|
+
updateArgs({ isLoading: true });
|
|
249
|
+
setTimeout(() => updateArgs({ isLoading: false, open: false }), 5000);
|
|
250
|
+
}}
|
|
251
|
+
onCancel={() => updateArgs({ open: false })}
|
|
252
|
+
trigger={
|
|
253
|
+
<Button
|
|
254
|
+
fullwidth={false}
|
|
255
|
+
color="error"
|
|
256
|
+
onClick={() => updateArgs({ open: true, isLoading: false })}
|
|
257
|
+
>
|
|
258
|
+
Delete (type to confirm)
|
|
259
|
+
</Button>
|
|
260
|
+
}
|
|
261
|
+
/>
|
|
262
|
+
);
|
|
263
|
+
},
|
|
264
|
+
};
|
|
@@ -15,6 +15,7 @@ import {
|
|
|
15
15
|
} from "@/components/AlertDialog/AlertDialog";
|
|
16
16
|
import { useControlledForm, Field } from "@/components/Form";
|
|
17
17
|
import { TextInput } from "@/components/TextInput/TextInput";
|
|
18
|
+
import Loading from "@/components/Loading/Loading";
|
|
18
19
|
|
|
19
20
|
export type ConfirmDialogProps = {
|
|
20
21
|
open?: boolean;
|
|
@@ -38,6 +39,8 @@ export type ConfirmDialogProps = {
|
|
|
38
39
|
* When true, hides the cancel button — useful for info/error alerts that only need one action.
|
|
39
40
|
*/
|
|
40
41
|
hideCancelButton?: boolean;
|
|
42
|
+
/** When true, shows a loading spinner on the confirm button and disables all interactive controls. */
|
|
43
|
+
isLoading?: boolean;
|
|
41
44
|
testId?: string;
|
|
42
45
|
cancelClassName?: string;
|
|
43
46
|
confirmClassName?: string;
|
|
@@ -59,6 +62,7 @@ export const ConfirmDialog: React.FC<ConfirmDialogProps> = ({
|
|
|
59
62
|
trigger,
|
|
60
63
|
typeToConfirm,
|
|
61
64
|
hideCancelButton = false,
|
|
65
|
+
isLoading = false,
|
|
62
66
|
testId,
|
|
63
67
|
cancelClassName,
|
|
64
68
|
confirmClassName,
|
|
@@ -89,22 +93,26 @@ export const ConfirmDialog: React.FC<ConfirmDialogProps> = ({
|
|
|
89
93
|
|
|
90
94
|
const isFormValid = methods.formState.isValid;
|
|
91
95
|
|
|
96
|
+
React.useEffect(() => {
|
|
97
|
+
if (!open) {
|
|
98
|
+
methods.reset();
|
|
99
|
+
}
|
|
100
|
+
}, [open]);
|
|
101
|
+
|
|
92
102
|
const handleOpenChange = (nextOpen: boolean) => {
|
|
103
|
+
if (isLoading) return;
|
|
93
104
|
if (!nextOpen) {
|
|
94
|
-
methods.reset();
|
|
95
105
|
onClose?.();
|
|
96
106
|
}
|
|
97
107
|
onOpenChange?.(nextOpen);
|
|
98
108
|
};
|
|
99
109
|
|
|
100
110
|
const handleCancel = () => {
|
|
101
|
-
methods.reset();
|
|
102
111
|
onCancel?.();
|
|
103
112
|
onClose?.();
|
|
104
113
|
};
|
|
105
114
|
|
|
106
115
|
const handleSubmit = () => {
|
|
107
|
-
methods.reset();
|
|
108
116
|
onConfirm?.();
|
|
109
117
|
};
|
|
110
118
|
|
|
@@ -146,6 +154,7 @@ export const ConfirmDialog: React.FC<ConfirmDialogProps> = ({
|
|
|
146
154
|
fullwidth: true,
|
|
147
155
|
testId: testId && `${testId}-type-to-confirm-input`,
|
|
148
156
|
}}
|
|
157
|
+
disabled={isLoading}
|
|
149
158
|
/>
|
|
150
159
|
</FormRoot>
|
|
151
160
|
)}
|
|
@@ -156,21 +165,27 @@ export const ConfirmDialog: React.FC<ConfirmDialogProps> = ({
|
|
|
156
165
|
className={cancelClassName}
|
|
157
166
|
data-testid={testId && `${testId}-cancel-button`}
|
|
158
167
|
onClick={handleCancel}
|
|
168
|
+
disabled={isLoading}
|
|
159
169
|
>
|
|
160
170
|
{cancelLabel}
|
|
161
171
|
</AlertDialogCancel>
|
|
162
172
|
)}
|
|
163
173
|
<AlertDialogAction
|
|
164
174
|
type="button"
|
|
165
|
-
disabled={requiresInput && !isFormValid}
|
|
166
|
-
onClick={
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
175
|
+
disabled={isLoading || (requiresInput && !isFormValid)}
|
|
176
|
+
onClick={(e) => {
|
|
177
|
+
e.preventDefault();
|
|
178
|
+
|
|
179
|
+
if (requiresInput) {
|
|
180
|
+
methods.handleSubmit(handleSubmit)();
|
|
181
|
+
} else {
|
|
182
|
+
onConfirm?.();
|
|
183
|
+
}
|
|
184
|
+
}}
|
|
171
185
|
className={confirmClassName}
|
|
172
186
|
data-testid={testId && `${testId}-confirm-button`}
|
|
173
187
|
>
|
|
188
|
+
{isLoading && <Loading />}
|
|
174
189
|
{confirmLabel}
|
|
175
190
|
</AlertDialogAction>
|
|
176
191
|
</AlertDialogFooter>
|