@rovula/ui 0.1.36 → 0.1.38

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.
@@ -24,6 +24,11 @@ export type ConfirmDialogProps = {
24
24
  /** When true, shows a loading spinner on the confirm button and disables all interactive controls. */
25
25
  isLoading?: boolean;
26
26
  testId?: string;
27
+ contentClassName?: string;
28
+ headerClassName?: string;
29
+ titleClassName?: string;
30
+ descriptionClassName?: string;
31
+ footerClassName?: string;
27
32
  cancelClassName?: string;
28
33
  confirmClassName?: string;
29
34
  };
@@ -24,6 +24,11 @@ declare const meta: {
24
24
  hideCancelButton?: boolean | undefined;
25
25
  isLoading?: boolean | undefined;
26
26
  testId?: string | undefined;
27
+ contentClassName?: string | undefined;
28
+ headerClassName?: string | undefined;
29
+ titleClassName?: string | undefined;
30
+ descriptionClassName?: string | undefined;
31
+ footerClassName?: string | undefined;
27
32
  cancelClassName?: string | undefined;
28
33
  confirmClassName?: string | undefined;
29
34
  }>) => import("react/jsx-runtime").JSX.Element)[];
package/dist/index.d.ts CHANGED
@@ -1699,6 +1699,11 @@ type ConfirmDialogProps = {
1699
1699
  /** When true, shows a loading spinner on the confirm button and disables all interactive controls. */
1700
1700
  isLoading?: boolean;
1701
1701
  testId?: string;
1702
+ contentClassName?: string;
1703
+ headerClassName?: string;
1704
+ titleClassName?: string;
1705
+ descriptionClassName?: string;
1706
+ footerClassName?: string;
1702
1707
  cancelClassName?: string;
1703
1708
  confirmClassName?: string;
1704
1709
  };
@@ -6,7 +6,7 @@ import { AlertDialog, AlertDialogContent, AlertDialogHeader, AlertDialogTitle, A
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
+ export const ConfirmDialog = ({ open, onOpenChange, title, description, children, confirmLabel = "Confirm", cancelLabel = "Cancel", onConfirm, onCancel, onClose, trigger, typeToConfirm, hideCancelButton = false, isLoading = false, testId, contentClassName, headerClassName, titleClassName, descriptionClassName, footerClassName, cancelClassName, confirmClassName, }) => {
10
10
  const requiresInput = !!typeToConfirm;
11
11
  const validationSchema = React.useMemo(() => yup.object({
12
12
  confirmInput: yup
@@ -41,14 +41,14 @@ export const ConfirmDialog = ({ open, onOpenChange, title, description, children
41
41
  const handleSubmit = () => {
42
42
  onConfirm === null || onConfirm === void 0 ? void 0 : onConfirm();
43
43
  };
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: {
44
+ return (_jsxs(AlertDialog, { open: open, onOpenChange: handleOpenChange, children: [trigger && _jsx(AlertDialogTrigger, { asChild: true, children: trigger }), _jsxs(AlertDialogContent, { className: contentClassName, "data-testid": testId, children: [_jsxs(AlertDialogHeader, { className: headerClassName, children: [_jsx(AlertDialogTitle, { className: titleClassName, "data-testid": testId && `${testId}-title`, children: title }), description && (_jsx(AlertDialogDescription, { className: descriptionClassName, "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: {
45
45
  label: "Type to confirm",
46
46
  required: true,
47
47
  hasClearIcon: true,
48
48
  keepFooterSpace: true,
49
49
  fullwidth: true,
50
50
  testId: testId && `${testId}-type-to-confirm-input`,
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) => {
51
+ }, disabled: isLoading })] })), _jsxs(AlertDialogFooter, { className: footerClassName, 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
52
  e.preventDefault();
53
53
  if (requiresInput) {
54
54
  methods.handleSubmit(handleSubmit)();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rovula/ui",
3
- "version": "0.1.36",
3
+ "version": "0.1.38",
4
4
  "main": "dist/cjs/bundle.js",
5
5
  "module": "dist/esm/bundle.js",
6
6
  "types": "dist/index.d.ts",
@@ -1,4 +1,4 @@
1
- import React from "react";
1
+ import React, { useState } from "react";
2
2
  import type { Meta, StoryObj } from "@storybook/react";
3
3
  import * as yup from "yup";
4
4
  import {
@@ -16,6 +16,7 @@ import { Label } from "../Label/Label";
16
16
  import { Input } from "../Input/Input";
17
17
  import { Field, Form, ValidationHintList, ValidationHintRule } from "../Form";
18
18
  import PasswordInput from "../PasswordInput";
19
+ import { Menu } from "@/patterns/menu/Menu";
19
20
 
20
21
  const meta = {
21
22
  title: "Components/Dialog",
@@ -219,36 +220,75 @@ export const FigmaFunctionForm = {
219
220
  } satisfies StoryObj;
220
221
 
221
222
  export const FigmaFunctionFormWithAction = {
222
- render: () => (
223
- <div className="flex w-full">
224
- <Dialog defaultOpen>
225
- <DialogContent>
226
- <DialogHeader>
227
- <DialogTitle>Title</DialogTitle>
228
- <DialogDescription>Subtitle description</DialogDescription>
229
- </DialogHeader>
230
- <DialogBody>
231
- <div className="flex items-center justify-center bg-ramps-secondary-150 h-[200px] w-full rounded-sm">
232
- <p className="typography-body3 text-text-contrast-max">
233
- Content - Form Area
234
- </p>
235
- </div>
236
- </DialogBody>
237
- <DialogFooter className="justify-between">
238
- <Button variant="outline" color="secondary" fullwidth={false}>
239
- Medium
240
- </Button>
241
- <div className="flex items-center gap-4">
242
- <Button variant="outline" color="primary" fullwidth={false}>
243
- Cancel
244
- </Button>
245
- <Button disabled fullwidth={false}>
246
- Confirm
223
+ render: () => {
224
+ const [open, setOpen] = useState(false);
225
+ const handleOpenChange = (open: boolean) => {
226
+ setOpen(open);
227
+ };
228
+ const handleCancel = () => {
229
+ setOpen(false);
230
+ };
231
+ const handleConfirm = () => {
232
+ setOpen(false);
233
+ };
234
+
235
+ return (
236
+ <div className="flex w-full">
237
+ <Menu
238
+ items={[
239
+ {
240
+ type: "item",
241
+ item: {
242
+ value: "edit",
243
+ label: "Edit",
244
+ onClick: () => handleOpenChange(true),
245
+ },
246
+ },
247
+ {
248
+ type: "item",
249
+ item: {
250
+ value: "delete",
251
+ label: "Delete",
252
+ onClick: () => handleOpenChange(true),
253
+ },
254
+ },
255
+ ]}
256
+ trigger={<Button variant="outline">Open</Button>}
257
+ />
258
+ <Dialog open={open} onOpenChange={handleOpenChange}>
259
+ <DialogContent>
260
+ <DialogHeader>
261
+ <DialogTitle>Title</DialogTitle>
262
+ <DialogDescription>Subtitle description</DialogDescription>
263
+ </DialogHeader>
264
+ <DialogBody>
265
+ <div className="flex items-center justify-center bg-ramps-secondary-150 h-[200px] w-full rounded-sm">
266
+ <p className="typography-body3 text-text-contrast-max">
267
+ Content - Form Area
268
+ </p>
269
+ </div>
270
+ </DialogBody>
271
+ <DialogFooter className="justify-between">
272
+ <Button variant="outline" color="secondary" fullwidth={false}>
273
+ Medium
247
274
  </Button>
248
- </div>
249
- </DialogFooter>
250
- </DialogContent>
251
- </Dialog>
252
- </div>
253
- ),
275
+ <div className="flex items-center gap-4">
276
+ <Button
277
+ variant="outline"
278
+ color="primary"
279
+ fullwidth={false}
280
+ onClick={handleCancel}
281
+ >
282
+ Cancel
283
+ </Button>
284
+ <Button disabled fullwidth={false} onClick={handleConfirm}>
285
+ Confirm
286
+ </Button>
287
+ </div>
288
+ </DialogFooter>
289
+ </DialogContent>
290
+ </Dialog>
291
+ </div>
292
+ );
293
+ },
254
294
  } satisfies StoryObj;
@@ -55,6 +55,12 @@ const DialogContent = React.forwardRef<
55
55
  className,
56
56
  )}
57
57
  {...props}
58
+ onCloseAutoFocus={(event) => {
59
+ event.preventDefault();
60
+ document.body.style.pointerEvents = "auto";
61
+
62
+ props?.onCloseAutoFocus?.(event);
63
+ }}
58
64
  >
59
65
  {children}
60
66
  {showCloseButton && (
@@ -42,6 +42,11 @@ export type ConfirmDialogProps = {
42
42
  /** When true, shows a loading spinner on the confirm button and disables all interactive controls. */
43
43
  isLoading?: boolean;
44
44
  testId?: string;
45
+ contentClassName?: string;
46
+ headerClassName?: string;
47
+ titleClassName?: string;
48
+ descriptionClassName?: string;
49
+ footerClassName?: string;
45
50
  cancelClassName?: string;
46
51
  confirmClassName?: string;
47
52
  };
@@ -64,6 +69,11 @@ export const ConfirmDialog: React.FC<ConfirmDialogProps> = ({
64
69
  hideCancelButton = false,
65
70
  isLoading = false,
66
71
  testId,
72
+ contentClassName,
73
+ headerClassName,
74
+ titleClassName,
75
+ descriptionClassName,
76
+ footerClassName,
67
77
  cancelClassName,
68
78
  confirmClassName,
69
79
  }) => {
@@ -119,13 +129,17 @@ export const ConfirmDialog: React.FC<ConfirmDialogProps> = ({
119
129
  return (
120
130
  <AlertDialog open={open} onOpenChange={handleOpenChange}>
121
131
  {trigger && <AlertDialogTrigger asChild>{trigger}</AlertDialogTrigger>}
122
- <AlertDialogContent data-testid={testId}>
123
- <AlertDialogHeader>
124
- <AlertDialogTitle data-testid={testId && `${testId}-title`}>
132
+ <AlertDialogContent className={contentClassName} data-testid={testId}>
133
+ <AlertDialogHeader className={headerClassName}>
134
+ <AlertDialogTitle
135
+ className={titleClassName}
136
+ data-testid={testId && `${testId}-title`}
137
+ >
125
138
  {title}
126
139
  </AlertDialogTitle>
127
140
  {description && (
128
141
  <AlertDialogDescription
142
+ className={descriptionClassName}
129
143
  data-testid={testId && `${testId}-description`}
130
144
  >
131
145
  {description}
@@ -159,7 +173,7 @@ export const ConfirmDialog: React.FC<ConfirmDialogProps> = ({
159
173
  </FormRoot>
160
174
  )}
161
175
 
162
- <AlertDialogFooter>
176
+ <AlertDialogFooter className={footerClassName}>
163
177
  {!hideCancelButton && (
164
178
  <AlertDialogCancel
165
179
  className={cancelClassName}