@rovula/ui 0.1.15 → 0.1.16
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.js +1545 -1545
- package/dist/cjs/bundle.js.map +1 -1
- package/dist/cjs/types/index.d.ts +2 -0
- package/dist/cjs/types/patterns/confirm-dialog/ConfirmDialog.d.ts +1 -0
- package/dist/cjs/types/patterns/confirm-dialog/ConfirmDialog.stories.d.ts +1 -0
- package/dist/cjs/types/patterns/form-dialog/FormDialog.d.ts +1 -0
- package/dist/cjs/types/patterns/form-dialog/FormDialog.stories.d.ts +1 -0
- package/dist/esm/bundle.js +1545 -1545
- package/dist/esm/bundle.js.map +1 -1
- package/dist/esm/types/index.d.ts +2 -0
- package/dist/esm/types/patterns/confirm-dialog/ConfirmDialog.d.ts +1 -0
- package/dist/esm/types/patterns/confirm-dialog/ConfirmDialog.stories.d.ts +1 -0
- package/dist/esm/types/patterns/form-dialog/FormDialog.d.ts +1 -0
- package/dist/esm/types/patterns/form-dialog/FormDialog.stories.d.ts +1 -0
- package/dist/index.d.ts +66 -1
- package/dist/index.js +3 -0
- package/dist/patterns/confirm-dialog/ConfirmDialog.js +4 -3
- package/dist/patterns/form-dialog/FormDialog.js +2 -2
- package/package.json +1 -1
- package/src/index.ts +4 -0
- package/src/patterns/confirm-dialog/ConfirmDialog.tsx +15 -4
- package/src/patterns/form-dialog/FormDialog.tsx +11 -4
|
@@ -44,6 +44,8 @@ export * from "./components/Tree";
|
|
|
44
44
|
export * from "./components/FocusedScrollView/FocusedScrollView";
|
|
45
45
|
export * from "./components/RadioGroup/RadioGroup";
|
|
46
46
|
export * from "./components/Form";
|
|
47
|
+
export * from "./patterns/confirm-dialog/ConfirmDialog";
|
|
48
|
+
export * from "./patterns/form-dialog/FormDialog";
|
|
47
49
|
export type { ButtonProps } from "./components/Button/Button";
|
|
48
50
|
export type { InputProps } from "./components/TextInput/TextInput";
|
|
49
51
|
export type { PasswordInputProps } from "./components/PasswordInput/PasswordInput";
|
package/dist/index.d.ts
CHANGED
|
@@ -19,6 +19,7 @@ import { ToastProviderProps } from '@radix-ui/react-toast';
|
|
|
19
19
|
import * as RadioGroupPrimitive from '@radix-ui/react-radio-group';
|
|
20
20
|
import { FieldValues, UseFormReturn, DefaultValues, SubmitHandler, SubmitErrorHandler, Resolver, Mode, FieldPath, RegisterOptions, FieldPathValue } from 'react-hook-form';
|
|
21
21
|
import * as yup from 'yup';
|
|
22
|
+
import Button$1 from '@/components/Button/Button';
|
|
22
23
|
import { ClassValue } from 'clsx';
|
|
23
24
|
|
|
24
25
|
type ButtonProps = {
|
|
@@ -1281,6 +1282,70 @@ declare const useOptionBridge: <TValue extends OptionValue = string, TOption ext
|
|
|
1281
1282
|
optionsByValue: Map<TValue, TOption>;
|
|
1282
1283
|
};
|
|
1283
1284
|
|
|
1285
|
+
type ConfirmDialogProps = {
|
|
1286
|
+
open?: boolean;
|
|
1287
|
+
onOpenChange?: (open: boolean) => void;
|
|
1288
|
+
title: string;
|
|
1289
|
+
description?: string;
|
|
1290
|
+
confirmLabel?: string;
|
|
1291
|
+
cancelLabel?: string;
|
|
1292
|
+
onConfirm?: () => void;
|
|
1293
|
+
onCancel?: () => void;
|
|
1294
|
+
/** Fires whenever the dialog closes, regardless of how (cancel button, overlay, Escape). */
|
|
1295
|
+
onClose?: () => void;
|
|
1296
|
+
trigger?: React.ReactNode;
|
|
1297
|
+
/**
|
|
1298
|
+
* When provided, the user must type this exact text before the confirm button is enabled.
|
|
1299
|
+
* e.g. typeToConfirm="confirm" or typeToConfirm="delete"
|
|
1300
|
+
*/
|
|
1301
|
+
typeToConfirm?: string;
|
|
1302
|
+
/**
|
|
1303
|
+
* When true, hides the cancel button — useful for info/error alerts that only need one action.
|
|
1304
|
+
*/
|
|
1305
|
+
hideCancelButton?: boolean;
|
|
1306
|
+
testId?: string;
|
|
1307
|
+
};
|
|
1308
|
+
declare const ConfirmDialog: React.FC<ConfirmDialogProps>;
|
|
1309
|
+
|
|
1310
|
+
type FormDialogAction = {
|
|
1311
|
+
label: string;
|
|
1312
|
+
onClick?: () => void;
|
|
1313
|
+
variant?: React.ComponentProps<typeof Button$1>["variant"];
|
|
1314
|
+
color?: React.ComponentProps<typeof Button$1>["color"];
|
|
1315
|
+
disabled?: boolean;
|
|
1316
|
+
isLoading?: boolean;
|
|
1317
|
+
type?: "button" | "submit" | "reset";
|
|
1318
|
+
};
|
|
1319
|
+
type FormDialogProps = {
|
|
1320
|
+
open?: boolean;
|
|
1321
|
+
onOpenChange?: (open: boolean) => void;
|
|
1322
|
+
title: string;
|
|
1323
|
+
description?: string;
|
|
1324
|
+
children?: React.ReactNode;
|
|
1325
|
+
trigger?: React.ReactNode;
|
|
1326
|
+
/**
|
|
1327
|
+
* Primary action (right side of footer).
|
|
1328
|
+
*/
|
|
1329
|
+
confirmAction?: FormDialogAction;
|
|
1330
|
+
/**
|
|
1331
|
+
* Secondary cancel action (right side of footer, outline style).
|
|
1332
|
+
*/
|
|
1333
|
+
cancelAction?: FormDialogAction;
|
|
1334
|
+
/**
|
|
1335
|
+
* Optional extra action placed on the left side of the footer.
|
|
1336
|
+
*/
|
|
1337
|
+
extraAction?: FormDialogAction;
|
|
1338
|
+
scrollable?: boolean;
|
|
1339
|
+
className?: string;
|
|
1340
|
+
/**
|
|
1341
|
+
* When provided, the confirm button becomes type="submit" and is linked to this form id.
|
|
1342
|
+
* Use together with a <Form id={formId} .../> inside children.
|
|
1343
|
+
*/
|
|
1344
|
+
formId?: string;
|
|
1345
|
+
testId?: string;
|
|
1346
|
+
};
|
|
1347
|
+
declare const FormDialog: React.FC<FormDialogProps>;
|
|
1348
|
+
|
|
1284
1349
|
declare const resloveTimestamp: (timestamp: number) => number;
|
|
1285
1350
|
declare const getStartDateOfDay: (date: Date) => Date;
|
|
1286
1351
|
declare const getEndDateOfDay: (date: Date) => Date;
|
|
@@ -1720,4 +1785,4 @@ declare const srgbToHex: (color: string) => string;
|
|
|
1720
1785
|
*/
|
|
1721
1786
|
declare function getLucideIconNames(): Promise<string[]>;
|
|
1722
1787
|
|
|
1723
|
-
export { ActionButton, AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, Avatar, AvatarGroup, type AvatarGroupProps, type AvatarProps, Button, type ButtonProps, Calendar, Checkbox, Collapsible, type ControlledFormFactoryOptions, type CustomSliderProps, DataTable, type DataTableProps, DatePicker, Dialog, DialogBody, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, Dropdown, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, type DropdownProps, Field, FieldMessage, type FieldMessageProps, type FieldProps, FocusedScrollView, Footer, type FooterProps, type FooterVariant, Form, type FormController, type FormProps, Icon, Input, InputFilter, type InputFilterProps, type InputProps, Label, Loading, type MaskRule, MaskedTextInput, type MaskedTextInputProps, Menu, MenuItem, type MenuItemType, MenuLabel, type MenuOption, type MenuProps, MenuSeparator, Navbar, type NavbarProps, type NavbarVariant, NumberInput, type NumberInputProps, type OptionLike, type Options$1 as Options, OtpInput, OtpInputGroup, type OtpInputGroupProps, type OtpInputProps, PasswordInput, type PasswordInputProps, Popover, PopoverContent, PopoverTrigger, ProgressBar, RadioGroup, RadioGroupItem, Search, type SearchProps, Slider, type SliderProps, Switch, THEME_COLOR_KEYS, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow, Tabs, Text, TextArea, type TextAreaProps, TextInput, type ThemeColorKey, Toast$1 as Toast, ToastAction, type ToastActionElement, ToastClose, ToastDescription, type ToastProps, ToastProvider, ToastTitle, ToastViewport, Toaster, Tooltip, TooltipArrow, TooltipContent, TooltipProvider, TooltipSimple, TooltipTrigger, Tree, type TreeData, TreeItem, type TreeItemProps, type TreeProps, type UseControlledFormOptions, type UseOptionBridgeOptions, ValidationHintList, type ValidationHintListProps, type ValidationHintMode, type ValidationHintRule, type ValidationHintState, cn, createControlledForm, createYupResolver, getEndDateOfDay, getLucideIconNames, getStartDateOfDay, getStartEndTimestampOfDay, getThemeColor, getThemeColors, getTimestampUTC, reducer, resloveTimestamp, srgbToHex, toast, useControlledForm, useOptionBridge, usePrevious, useToast };
|
|
1788
|
+
export { ActionButton, AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, Avatar, AvatarGroup, type AvatarGroupProps, type AvatarProps, Button, type ButtonProps, Calendar, Checkbox, Collapsible, ConfirmDialog, type ConfirmDialogProps, type ControlledFormFactoryOptions, type CustomSliderProps, DataTable, type DataTableProps, DatePicker, Dialog, DialogBody, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, Dropdown, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, type DropdownProps, Field, FieldMessage, type FieldMessageProps, type FieldProps, FocusedScrollView, Footer, type FooterProps, type FooterVariant, Form, type FormController, FormDialog, type FormDialogAction, type FormDialogProps, type FormProps, Icon, Input, InputFilter, type InputFilterProps, type InputProps, Label, Loading, type MaskRule, MaskedTextInput, type MaskedTextInputProps, Menu, MenuItem, type MenuItemType, MenuLabel, type MenuOption, type MenuProps, MenuSeparator, Navbar, type NavbarProps, type NavbarVariant, NumberInput, type NumberInputProps, type OptionLike, type Options$1 as Options, OtpInput, OtpInputGroup, type OtpInputGroupProps, type OtpInputProps, PasswordInput, type PasswordInputProps, Popover, PopoverContent, PopoverTrigger, ProgressBar, RadioGroup, RadioGroupItem, Search, type SearchProps, Slider, type SliderProps, Switch, THEME_COLOR_KEYS, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow, Tabs, Text, TextArea, type TextAreaProps, TextInput, type ThemeColorKey, Toast$1 as Toast, ToastAction, type ToastActionElement, ToastClose, ToastDescription, type ToastProps, ToastProvider, ToastTitle, ToastViewport, Toaster, Tooltip, TooltipArrow, TooltipContent, TooltipProvider, TooltipSimple, TooltipTrigger, Tree, type TreeData, TreeItem, type TreeItemProps, type TreeProps, type UseControlledFormOptions, type UseOptionBridgeOptions, ValidationHintList, type ValidationHintListProps, type ValidationHintMode, type ValidationHintRule, type ValidationHintState, cn, createControlledForm, createYupResolver, getEndDateOfDay, getLucideIconNames, getStartDateOfDay, getStartEndTimestampOfDay, getThemeColor, getThemeColors, getTimestampUTC, reducer, resloveTimestamp, srgbToHex, toast, useControlledForm, useOptionBridge, usePrevious, useToast };
|
package/dist/index.js
CHANGED
|
@@ -46,6 +46,9 @@ export * from "./components/Tree";
|
|
|
46
46
|
export * from "./components/FocusedScrollView/FocusedScrollView";
|
|
47
47
|
export * from "./components/RadioGroup/RadioGroup";
|
|
48
48
|
export * from "./components/Form";
|
|
49
|
+
// Patterns
|
|
50
|
+
export * from "./patterns/confirm-dialog/ConfirmDialog";
|
|
51
|
+
export * from "./patterns/form-dialog/FormDialog";
|
|
49
52
|
// UTILS
|
|
50
53
|
export { resloveTimestamp, getStartDateOfDay, getEndDateOfDay, getStartEndTimestampOfDay, getTimestampUTC, } from "./utils/datetime";
|
|
51
54
|
// Hooks
|
|
@@ -5,7 +5,7 @@ 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
|
-
export const ConfirmDialog = ({ open, onOpenChange, title, description, confirmLabel = "Confirm", cancelLabel = "Cancel", onConfirm, onCancel, onClose, trigger, typeToConfirm, hideCancelButton = false, }) => {
|
|
8
|
+
export const ConfirmDialog = ({ open, onOpenChange, title, description, confirmLabel = "Confirm", cancelLabel = "Cancel", onConfirm, onCancel, onClose, trigger, typeToConfirm, hideCancelButton = false, testId, }) => {
|
|
9
9
|
const formId = React.useId();
|
|
10
10
|
const requiresInput = !!typeToConfirm;
|
|
11
11
|
const validationSchema = React.useMemo(() => yup.object({
|
|
@@ -33,12 +33,13 @@ export const ConfirmDialog = ({ open, onOpenChange, title, description, confirmL
|
|
|
33
33
|
onCancel === null || onCancel === void 0 ? void 0 : onCancel();
|
|
34
34
|
onClose === null || onClose === void 0 ? void 0 : onClose();
|
|
35
35
|
};
|
|
36
|
-
return (_jsxs(AlertDialog, { open: open, onOpenChange: handleOpenChange, children: [trigger && _jsx(AlertDialogTrigger, { asChild: true, children: trigger }), _jsxs(AlertDialogContent, { children: [_jsxs(AlertDialogHeader, { children: [_jsx(AlertDialogTitle, { children: title }), description && (_jsx(AlertDialogDescription, { children: description }))] }), requiresInput && (_jsxs(FormRoot, { id: formId, className: "flex flex-col gap-4 w-full", onSubmit: () => onConfirm === null || onConfirm === void 0 ? void 0 : onConfirm(), children: [_jsxs("p", { className: "typography-small1 text-text-contrast-max", children: ["Type \u201C", typeToConfirm, "\u201D to proceed."] }), _jsx(Field, { name: "confirmInput", component: TextInput, componentProps: {
|
|
36
|
+
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 }))] }), requiresInput && (_jsxs(FormRoot, { id: formId, className: "flex flex-col gap-4 w-full", onSubmit: () => onConfirm === null || onConfirm === void 0 ? void 0 : onConfirm(), children: [_jsxs("p", { className: "typography-small1 text-text-contrast-max", children: ["Type \u201C", typeToConfirm, "\u201D to proceed."] }), _jsx(Field, { name: "confirmInput", component: TextInput, componentProps: {
|
|
37
37
|
label: "Type to confirm",
|
|
38
38
|
required: true,
|
|
39
39
|
hasClearIcon: true,
|
|
40
40
|
keepFooterSpace: true,
|
|
41
41
|
fullwidth: true,
|
|
42
|
-
|
|
42
|
+
testId: testId && `${testId}-type-to-confirm-input`,
|
|
43
|
+
} })] })), _jsxs(AlertDialogFooter, { children: [!hideCancelButton && (_jsx(AlertDialogCancel, { "data-testid": testId && `${testId}-cancel-button`, onClick: handleCancel, children: cancelLabel })), _jsx(AlertDialogAction, { type: "submit", form: requiresInput ? formId : undefined, disabled: requiresInput && !isFormValid, onClick: requiresInput ? undefined : () => onConfirm === null || onConfirm === void 0 ? void 0 : onConfirm(), "data-testid": testId && `${testId}-confirm-button`, children: confirmLabel })] })] })] }));
|
|
43
44
|
};
|
|
44
45
|
ConfirmDialog.displayName = "ConfirmDialog";
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription, DialogBody, DialogFooter, DialogTrigger, } from "@/components/Dialog/Dialog";
|
|
4
4
|
import Button from "@/components/Button/Button";
|
|
5
|
-
export const FormDialog = ({ open, onOpenChange, title, description, children, trigger, confirmAction, cancelAction, extraAction, scrollable = false, className, formId, }) => {
|
|
5
|
+
export const FormDialog = ({ open, onOpenChange, title, description, children, trigger, confirmAction, cancelAction, extraAction, scrollable = false, className, formId, testId, }) => {
|
|
6
6
|
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
|
|
7
7
|
const hasFooter = confirmAction || cancelAction || extraAction;
|
|
8
|
-
return (_jsxs(Dialog, { open: open, onOpenChange: onOpenChange, children: [trigger && _jsx(DialogTrigger, { asChild: true, children: trigger }), _jsxs(DialogContent, { className: className, children: [_jsxs(DialogHeader, { children: [_jsx(DialogTitle, { children: title }), description && (_jsx(DialogDescription, { children: description }))] }), children && (_jsx(DialogBody, { scrollable: scrollable, children: children })), hasFooter && (_jsxs(DialogFooter, { className: extraAction ? "justify-between" : undefined, children: [extraAction && (_jsx(Button, { type: (_a = extraAction.type) !== null && _a !== void 0 ? _a : "button", variant: (_b = extraAction.variant) !== null && _b !== void 0 ? _b : "outline", color: (_c = extraAction.color) !== null && _c !== void 0 ? _c : "secondary", fullwidth: false, disabled: extraAction.disabled, isLoading: extraAction.isLoading, onClick: extraAction.onClick, children: extraAction.label })), _jsxs("div", { className: "flex items-center gap-4", children: [cancelAction && (_jsx(Button, { type: (_d = cancelAction.type) !== null && _d !== void 0 ? _d : "button", variant: (_e = cancelAction.variant) !== null && _e !== void 0 ? _e : "outline", color: (_f = cancelAction.color) !== null && _f !== void 0 ? _f : "primary", fullwidth: false, disabled: cancelAction.disabled, isLoading: cancelAction.isLoading, onClick: cancelAction.onClick, children: cancelAction.label })), confirmAction && (_jsx(Button, { type: formId ? "submit" : (
|
|
8
|
+
return (_jsxs(Dialog, { open: open, onOpenChange: onOpenChange, children: [trigger && _jsx(DialogTrigger, { asChild: true, children: trigger }), _jsxs(DialogContent, { className: className, "data-testid": testId, children: [_jsxs(DialogHeader, { children: [_jsx(DialogTitle, { "data-testid": testId && `${testId}-title`, children: title }), description && (_jsx(DialogDescription, { "data-testid": testId && `${testId}-description`, children: description }))] }), children && (_jsx(DialogBody, { scrollable: scrollable, children: children })), hasFooter && (_jsxs(DialogFooter, { className: extraAction ? "justify-between" : undefined, children: [extraAction && (_jsx(Button, { type: (_a = extraAction.type) !== null && _a !== void 0 ? _a : "button", variant: (_b = extraAction.variant) !== null && _b !== void 0 ? _b : "outline", color: (_c = extraAction.color) !== null && _c !== void 0 ? _c : "secondary", fullwidth: false, disabled: extraAction.disabled, isLoading: extraAction.isLoading, onClick: extraAction.onClick, "data-testid": testId && `${testId}-extra-button`, children: extraAction.label })), _jsxs("div", { className: "flex items-center gap-4", children: [cancelAction && (_jsx(Button, { type: (_d = cancelAction.type) !== null && _d !== void 0 ? _d : "button", variant: (_e = cancelAction.variant) !== null && _e !== void 0 ? _e : "outline", color: (_f = cancelAction.color) !== null && _f !== void 0 ? _f : "primary", fullwidth: false, disabled: cancelAction.disabled, isLoading: cancelAction.isLoading, onClick: cancelAction.onClick, "data-testid": testId && `${testId}-cancel-button`, children: cancelAction.label })), confirmAction && (_jsx(Button, { type: formId ? "submit" : (_g = confirmAction.type) !== null && _g !== void 0 ? _g : "button", form: formId, variant: (_h = confirmAction.variant) !== null && _h !== void 0 ? _h : "solid", color: (_j = confirmAction.color) !== null && _j !== void 0 ? _j : "primary", fullwidth: false, disabled: confirmAction.disabled, isLoading: confirmAction.isLoading, onClick: confirmAction.onClick, "data-testid": testId && `${testId}-confirm-button`, children: confirmAction.label }))] })] }))] })] }));
|
|
9
9
|
};
|
|
10
10
|
FormDialog.displayName = "FormDialog";
|
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -52,6 +52,10 @@ export * from "./components/FocusedScrollView/FocusedScrollView";
|
|
|
52
52
|
export * from "./components/RadioGroup/RadioGroup";
|
|
53
53
|
export * from "./components/Form";
|
|
54
54
|
|
|
55
|
+
// Patterns
|
|
56
|
+
export * from "./patterns/confirm-dialog/ConfirmDialog";
|
|
57
|
+
export * from "./patterns/form-dialog/FormDialog";
|
|
58
|
+
|
|
55
59
|
// Export component types
|
|
56
60
|
export type { ButtonProps } from "./components/Button/Button";
|
|
57
61
|
export type { InputProps } from "./components/TextInput/TextInput";
|
|
@@ -37,6 +37,7 @@ export type ConfirmDialogProps = {
|
|
|
37
37
|
* When true, hides the cancel button — useful for info/error alerts that only need one action.
|
|
38
38
|
*/
|
|
39
39
|
hideCancelButton?: boolean;
|
|
40
|
+
testId?: string;
|
|
40
41
|
};
|
|
41
42
|
|
|
42
43
|
type ConfirmFormValues = { confirmInput: string };
|
|
@@ -54,6 +55,7 @@ export const ConfirmDialog: React.FC<ConfirmDialogProps> = ({
|
|
|
54
55
|
trigger,
|
|
55
56
|
typeToConfirm,
|
|
56
57
|
hideCancelButton = false,
|
|
58
|
+
testId,
|
|
57
59
|
}) => {
|
|
58
60
|
const formId = React.useId();
|
|
59
61
|
const requiresInput = !!typeToConfirm;
|
|
@@ -99,11 +101,15 @@ export const ConfirmDialog: React.FC<ConfirmDialogProps> = ({
|
|
|
99
101
|
return (
|
|
100
102
|
<AlertDialog open={open} onOpenChange={handleOpenChange}>
|
|
101
103
|
{trigger && <AlertDialogTrigger asChild>{trigger}</AlertDialogTrigger>}
|
|
102
|
-
<AlertDialogContent>
|
|
104
|
+
<AlertDialogContent data-testid={testId}>
|
|
103
105
|
<AlertDialogHeader>
|
|
104
|
-
<AlertDialogTitle
|
|
106
|
+
<AlertDialogTitle data-testid={testId && `${testId}-title`}>
|
|
107
|
+
{title}
|
|
108
|
+
</AlertDialogTitle>
|
|
105
109
|
{description && (
|
|
106
|
-
<AlertDialogDescription
|
|
110
|
+
<AlertDialogDescription data-testid={testId && `${testId}-description`}>
|
|
111
|
+
{description}
|
|
112
|
+
</AlertDialogDescription>
|
|
107
113
|
)}
|
|
108
114
|
</AlertDialogHeader>
|
|
109
115
|
|
|
@@ -125,6 +131,7 @@ export const ConfirmDialog: React.FC<ConfirmDialogProps> = ({
|
|
|
125
131
|
hasClearIcon: true,
|
|
126
132
|
keepFooterSpace: true,
|
|
127
133
|
fullwidth: true,
|
|
134
|
+
testId: testId && `${testId}-type-to-confirm-input`,
|
|
128
135
|
}}
|
|
129
136
|
/>
|
|
130
137
|
</FormRoot>
|
|
@@ -132,7 +139,10 @@ export const ConfirmDialog: React.FC<ConfirmDialogProps> = ({
|
|
|
132
139
|
|
|
133
140
|
<AlertDialogFooter>
|
|
134
141
|
{!hideCancelButton && (
|
|
135
|
-
<AlertDialogCancel
|
|
142
|
+
<AlertDialogCancel
|
|
143
|
+
data-testid={testId && `${testId}-cancel-button`}
|
|
144
|
+
onClick={handleCancel}
|
|
145
|
+
>
|
|
136
146
|
{cancelLabel}
|
|
137
147
|
</AlertDialogCancel>
|
|
138
148
|
)}
|
|
@@ -141,6 +151,7 @@ export const ConfirmDialog: React.FC<ConfirmDialogProps> = ({
|
|
|
141
151
|
form={requiresInput ? formId : undefined}
|
|
142
152
|
disabled={requiresInput && !isFormValid}
|
|
143
153
|
onClick={requiresInput ? undefined : () => onConfirm?.()}
|
|
154
|
+
data-testid={testId && `${testId}-confirm-button`}
|
|
144
155
|
>
|
|
145
156
|
{confirmLabel}
|
|
146
157
|
</AlertDialogAction>
|
|
@@ -50,6 +50,7 @@ export type FormDialogProps = {
|
|
|
50
50
|
* Use together with a <Form id={formId} .../> inside children.
|
|
51
51
|
*/
|
|
52
52
|
formId?: string;
|
|
53
|
+
testId?: string;
|
|
53
54
|
};
|
|
54
55
|
|
|
55
56
|
export const FormDialog: React.FC<FormDialogProps> = ({
|
|
@@ -65,17 +66,20 @@ export const FormDialog: React.FC<FormDialogProps> = ({
|
|
|
65
66
|
scrollable = false,
|
|
66
67
|
className,
|
|
67
68
|
formId,
|
|
69
|
+
testId,
|
|
68
70
|
}) => {
|
|
69
71
|
const hasFooter = confirmAction || cancelAction || extraAction;
|
|
70
72
|
|
|
71
73
|
return (
|
|
72
74
|
<Dialog open={open} onOpenChange={onOpenChange}>
|
|
73
75
|
{trigger && <DialogTrigger asChild>{trigger}</DialogTrigger>}
|
|
74
|
-
<DialogContent className={className}>
|
|
76
|
+
<DialogContent className={className} data-testid={testId}>
|
|
75
77
|
<DialogHeader>
|
|
76
|
-
<DialogTitle>{title}</DialogTitle>
|
|
78
|
+
<DialogTitle data-testid={testId && `${testId}-title`}>{title}</DialogTitle>
|
|
77
79
|
{description && (
|
|
78
|
-
<DialogDescription
|
|
80
|
+
<DialogDescription data-testid={testId && `${testId}-description`}>
|
|
81
|
+
{description}
|
|
82
|
+
</DialogDescription>
|
|
79
83
|
)}
|
|
80
84
|
</DialogHeader>
|
|
81
85
|
|
|
@@ -94,6 +98,7 @@ export const FormDialog: React.FC<FormDialogProps> = ({
|
|
|
94
98
|
disabled={extraAction.disabled}
|
|
95
99
|
isLoading={extraAction.isLoading}
|
|
96
100
|
onClick={extraAction.onClick}
|
|
101
|
+
data-testid={testId && `${testId}-extra-button`}
|
|
97
102
|
>
|
|
98
103
|
{extraAction.label}
|
|
99
104
|
</Button>
|
|
@@ -108,13 +113,14 @@ export const FormDialog: React.FC<FormDialogProps> = ({
|
|
|
108
113
|
disabled={cancelAction.disabled}
|
|
109
114
|
isLoading={cancelAction.isLoading}
|
|
110
115
|
onClick={cancelAction.onClick}
|
|
116
|
+
data-testid={testId && `${testId}-cancel-button`}
|
|
111
117
|
>
|
|
112
118
|
{cancelAction.label}
|
|
113
119
|
</Button>
|
|
114
120
|
)}
|
|
115
121
|
{confirmAction && (
|
|
116
122
|
<Button
|
|
117
|
-
type={formId ? "submit" :
|
|
123
|
+
type={formId ? "submit" : confirmAction.type ?? "button"}
|
|
118
124
|
form={formId}
|
|
119
125
|
variant={confirmAction.variant ?? "solid"}
|
|
120
126
|
color={confirmAction.color ?? "primary"}
|
|
@@ -122,6 +128,7 @@ export const FormDialog: React.FC<FormDialogProps> = ({
|
|
|
122
128
|
disabled={confirmAction.disabled}
|
|
123
129
|
isLoading={confirmAction.isLoading}
|
|
124
130
|
onClick={confirmAction.onClick}
|
|
131
|
+
data-testid={testId && `${testId}-confirm-button`}
|
|
125
132
|
>
|
|
126
133
|
{confirmAction.label}
|
|
127
134
|
</Button>
|