@edux-design/modals 0.1.3 → 0.2.1
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/CHANGELOG.md +19 -2
- package/README.md +19 -0
- package/dist/index.d.mts +78 -0
- package/dist/index.d.ts +78 -0
- package/dist/index.js +196 -43
- package/dist/index.mjs +195 -43
- package/docs/confirmation.md +117 -0
- package/package.json +10 -19
- package/src/demos/Modal.stories.jsx +0 -304
- package/src/elements/Modal.jsx +0 -228
- package/src/elements/Modal.test.jsx +0 -139
- package/src/index.js +0 -13
package/CHANGELOG.md
CHANGED
|
@@ -1,16 +1,33 @@
|
|
|
1
1
|
# @edux-design/modals
|
|
2
2
|
|
|
3
|
+
## 0.2.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Align the exact Radix Dialog peer to 1.1.19 so dialog and Tooltip 1.2.12 share dismissal-layer ownership. Preserve the existing Modal UI runtime and public composition.
|
|
8
|
+
|
|
9
|
+
## 0.2.0
|
|
10
|
+
|
|
11
|
+
### Minor Changes
|
|
12
|
+
|
|
13
|
+
- Add controlled confirmation dialog and anchored popover compositions with pending dismissal policy, error/retry content and safe focus handling. Generate declared public types for both packages.
|
|
14
|
+
|
|
15
|
+
### Patch Changes
|
|
16
|
+
|
|
17
|
+
- Updated dependencies
|
|
18
|
+
- @edux-design/buttons@0.3.0
|
|
19
|
+
|
|
3
20
|
## 0.1.3
|
|
4
21
|
|
|
5
22
|
### Patch Changes
|
|
6
23
|
|
|
7
|
-
- Rebuilt
|
|
24
|
+
- Rebuilt distribution artifacts.
|
|
8
25
|
|
|
9
26
|
## 0.1.2
|
|
10
27
|
|
|
11
28
|
### Patch Changes
|
|
12
29
|
|
|
13
|
-
- Updated design tokens
|
|
30
|
+
- Updated design tokens.
|
|
14
31
|
|
|
15
32
|
## 0.1.1
|
|
16
33
|
|
package/README.md
CHANGED
|
@@ -2,6 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
Centered modal primitives built on top of Radix Dialog and Edux design tokens.
|
|
4
4
|
|
|
5
|
+
This release requires `@radix-ui/react-dialog@1.1.19`. It shares the dismissal
|
|
6
|
+
layer used by `@radix-ui/react-tooltip@1.2.12`, the exact dependency of the new
|
|
7
|
+
Edux Tooltips release. Keep direct Dialog dependencies and any Tooltip overrides
|
|
8
|
+
aligned with this pair so Escape dismisses a nested tooltip before its modal.
|
|
9
|
+
|
|
5
10
|
Exports:
|
|
6
11
|
|
|
7
12
|
- `Modal`
|
|
@@ -63,3 +68,17 @@ export function PublishModal() {
|
|
|
63
68
|
Passing `onClose` to `Modal` also enables the default close icon inside `ModalHeader`.
|
|
64
69
|
|
|
65
70
|
`ModalContent` accepts `size`, `backdropProps`, the legacy alias `backDropProps`, `className`, and `contentProps`. Storybook examples live in `src/demos/Modal.stories.jsx`.
|
|
71
|
+
|
|
72
|
+
### Size contracts
|
|
73
|
+
|
|
74
|
+
The `small`, `medium`, `large`, and `full` values are named component-owned width
|
|
75
|
+
contracts. They intentionally use responsive `min()` and viewport constraints so
|
|
76
|
+
the modal keeps its current geometry across screen sizes. These values are not
|
|
77
|
+
global width tokens: the design-token standards keep calculated, component-specific
|
|
78
|
+
surface dimensions local until multiple unrelated components share the same role.
|
|
79
|
+
|
|
80
|
+
Unknown `size` values fall back to `medium` for compatibility.
|
|
81
|
+
|
|
82
|
+
## Additional components
|
|
83
|
+
|
|
84
|
+
[Confirmation dialogs](./docs/confirmation.md).
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import * as _radix_ui_react_dialog from '@radix-ui/react-dialog';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
|
|
4
|
+
/** @type {React.FC<ModalProps>} */
|
|
5
|
+
declare const Modal: React.FC<ModalProps>;
|
|
6
|
+
declare const ModalTrigger: React.ForwardRefExoticComponent<_radix_ui_react_dialog.DialogTriggerProps & React.RefAttributes<HTMLButtonElement>>;
|
|
7
|
+
declare const ModalClose: React.ForwardRefExoticComponent<_radix_ui_react_dialog.DialogCloseProps & React.RefAttributes<HTMLButtonElement>>;
|
|
8
|
+
declare const ModalPortal: React.FC<_radix_ui_react_dialog.DialogPortalProps>;
|
|
9
|
+
/** @type {React.ForwardRefExoticComponent<ModalOverlayProps & React.RefAttributes<HTMLDivElement>>} */
|
|
10
|
+
declare const ModalOverlay: React.ForwardRefExoticComponent<ModalOverlayProps & React.RefAttributes<HTMLDivElement>>;
|
|
11
|
+
/** @type {React.ForwardRefExoticComponent<ModalContentProps & React.RefAttributes<HTMLDivElement>>} */
|
|
12
|
+
declare const ModalContent: React.ForwardRefExoticComponent<ModalContentProps & React.RefAttributes<HTMLDivElement>>;
|
|
13
|
+
/** @type {React.ForwardRefExoticComponent<ModalHeaderProps & React.RefAttributes<HTMLDivElement>>} */
|
|
14
|
+
declare const ModalHeader: React.ForwardRefExoticComponent<ModalHeaderProps & React.RefAttributes<HTMLDivElement>>;
|
|
15
|
+
/** @type {React.ForwardRefExoticComponent<ModalBodyProps & React.RefAttributes<HTMLDivElement>>} */
|
|
16
|
+
declare const ModalBody: React.ForwardRefExoticComponent<ModalBodyProps & React.RefAttributes<HTMLDivElement>>;
|
|
17
|
+
/** @type {React.ForwardRefExoticComponent<ModalFooterProps & React.RefAttributes<HTMLDivElement>>} */
|
|
18
|
+
declare const ModalFooter: React.ForwardRefExoticComponent<ModalFooterProps & React.RefAttributes<HTMLDivElement>>;
|
|
19
|
+
/** @type {React.ForwardRefExoticComponent<ModalTitleProps & React.RefAttributes<HTMLHeadingElement>>} */
|
|
20
|
+
declare const ModalTitle: React.ForwardRefExoticComponent<ModalTitleProps & React.RefAttributes<HTMLHeadingElement>>;
|
|
21
|
+
/** @type {React.ForwardRefExoticComponent<ModalDescriptionProps & React.RefAttributes<HTMLParagraphElement>>} */
|
|
22
|
+
declare const ModalDescription: React.ForwardRefExoticComponent<ModalDescriptionProps & React.RefAttributes<HTMLParagraphElement>>;
|
|
23
|
+
type ModalProps = _radix_ui_react_dialog.DialogProps & {
|
|
24
|
+
onOpen?: () => void;
|
|
25
|
+
onClose?: () => void;
|
|
26
|
+
};
|
|
27
|
+
type ModalContentProps = _radix_ui_react_dialog.DialogContentProps & {
|
|
28
|
+
size?: "small" | "medium" | "large" | "full";
|
|
29
|
+
backdropProps?: _radix_ui_react_dialog.DialogOverlayProps;
|
|
30
|
+
backDropProps?: _radix_ui_react_dialog.DialogOverlayProps;
|
|
31
|
+
contentProps?: _radix_ui_react_dialog.DialogContentProps;
|
|
32
|
+
portalProps?: _radix_ui_react_dialog.DialogPortalProps;
|
|
33
|
+
};
|
|
34
|
+
type ModalOverlayProps = _radix_ui_react_dialog.DialogOverlayProps;
|
|
35
|
+
type ModalHeaderProps = React.HTMLAttributes<HTMLDivElement>;
|
|
36
|
+
type ModalBodyProps = React.HTMLAttributes<HTMLDivElement>;
|
|
37
|
+
type ModalFooterProps = React.HTMLAttributes<HTMLDivElement>;
|
|
38
|
+
type ModalTitleProps = _radix_ui_react_dialog.DialogTitleProps;
|
|
39
|
+
type ModalDescriptionProps = _radix_ui_react_dialog.DialogDescriptionProps;
|
|
40
|
+
|
|
41
|
+
type ConfirmationDialogActionProps = Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, "children" | "disabled"> & React.RefAttributes<HTMLButtonElement>;
|
|
42
|
+
interface ConfirmationDialogProps {
|
|
43
|
+
open?: boolean;
|
|
44
|
+
defaultOpen?: boolean;
|
|
45
|
+
onOpenChange?: (open: boolean) => void;
|
|
46
|
+
modal?: boolean;
|
|
47
|
+
title: React.ReactNode;
|
|
48
|
+
description?: React.ReactNode;
|
|
49
|
+
children?: React.ReactNode;
|
|
50
|
+
/** A single ref-forwarding button. Omit for an externally opened dialog. */
|
|
51
|
+
trigger?: React.ReactElement;
|
|
52
|
+
onConfirm: React.MouseEventHandler<HTMLButtonElement>;
|
|
53
|
+
onCancel?: React.MouseEventHandler<HTMLButtonElement>;
|
|
54
|
+
confirmLabel?: React.ReactNode;
|
|
55
|
+
cancelLabel?: React.ReactNode;
|
|
56
|
+
pendingLabel?: React.ReactNode;
|
|
57
|
+
pending?: boolean;
|
|
58
|
+
error?: React.ReactNode;
|
|
59
|
+
confirmDisabled?: boolean;
|
|
60
|
+
cancelDisabled?: boolean;
|
|
61
|
+
/** Locks user dismissal. The controlled host may still close explicitly. */
|
|
62
|
+
dismissible?: boolean;
|
|
63
|
+
/** Explicit return target, useful when confirmation removes its own trigger. */
|
|
64
|
+
returnFocusRef?: React.RefObject<HTMLElement | null>;
|
|
65
|
+
isDanger?: boolean;
|
|
66
|
+
/** Pending confirmations block every user dismissal unless explicitly enabled. */
|
|
67
|
+
allowDismissWhilePending?: boolean;
|
|
68
|
+
size?: "small" | "medium" | "large" | "full";
|
|
69
|
+
contentProps?: Omit<_radix_ui_react_dialog.DialogContentProps, "children" | "asChild">;
|
|
70
|
+
backdropProps?: _radix_ui_react_dialog.DialogOverlayProps;
|
|
71
|
+
portalProps?: _radix_ui_react_dialog.DialogPortalProps;
|
|
72
|
+
confirmButtonProps?: ConfirmationDialogActionProps;
|
|
73
|
+
cancelButtonProps?: ConfirmationDialogActionProps;
|
|
74
|
+
}
|
|
75
|
+
/** Controlled confirmation. The host owns mutations, pending/error state and success closure. */
|
|
76
|
+
declare const ConfirmationDialog: React.ForwardRefExoticComponent<ConfirmationDialogProps & React.RefAttributes<HTMLDivElement>>;
|
|
77
|
+
|
|
78
|
+
export { ConfirmationDialog, type ConfirmationDialogActionProps, type ConfirmationDialogProps, Modal, ModalBody, type ModalBodyProps, ModalClose, ModalContent, type ModalContentProps, ModalDescription, type ModalDescriptionProps, ModalFooter, type ModalFooterProps, ModalHeader, type ModalHeaderProps, ModalOverlay, type ModalOverlayProps, ModalPortal, type ModalProps, ModalTitle, type ModalTitleProps, ModalTrigger };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import * as _radix_ui_react_dialog from '@radix-ui/react-dialog';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
|
|
4
|
+
/** @type {React.FC<ModalProps>} */
|
|
5
|
+
declare const Modal: React.FC<ModalProps>;
|
|
6
|
+
declare const ModalTrigger: React.ForwardRefExoticComponent<_radix_ui_react_dialog.DialogTriggerProps & React.RefAttributes<HTMLButtonElement>>;
|
|
7
|
+
declare const ModalClose: React.ForwardRefExoticComponent<_radix_ui_react_dialog.DialogCloseProps & React.RefAttributes<HTMLButtonElement>>;
|
|
8
|
+
declare const ModalPortal: React.FC<_radix_ui_react_dialog.DialogPortalProps>;
|
|
9
|
+
/** @type {React.ForwardRefExoticComponent<ModalOverlayProps & React.RefAttributes<HTMLDivElement>>} */
|
|
10
|
+
declare const ModalOverlay: React.ForwardRefExoticComponent<ModalOverlayProps & React.RefAttributes<HTMLDivElement>>;
|
|
11
|
+
/** @type {React.ForwardRefExoticComponent<ModalContentProps & React.RefAttributes<HTMLDivElement>>} */
|
|
12
|
+
declare const ModalContent: React.ForwardRefExoticComponent<ModalContentProps & React.RefAttributes<HTMLDivElement>>;
|
|
13
|
+
/** @type {React.ForwardRefExoticComponent<ModalHeaderProps & React.RefAttributes<HTMLDivElement>>} */
|
|
14
|
+
declare const ModalHeader: React.ForwardRefExoticComponent<ModalHeaderProps & React.RefAttributes<HTMLDivElement>>;
|
|
15
|
+
/** @type {React.ForwardRefExoticComponent<ModalBodyProps & React.RefAttributes<HTMLDivElement>>} */
|
|
16
|
+
declare const ModalBody: React.ForwardRefExoticComponent<ModalBodyProps & React.RefAttributes<HTMLDivElement>>;
|
|
17
|
+
/** @type {React.ForwardRefExoticComponent<ModalFooterProps & React.RefAttributes<HTMLDivElement>>} */
|
|
18
|
+
declare const ModalFooter: React.ForwardRefExoticComponent<ModalFooterProps & React.RefAttributes<HTMLDivElement>>;
|
|
19
|
+
/** @type {React.ForwardRefExoticComponent<ModalTitleProps & React.RefAttributes<HTMLHeadingElement>>} */
|
|
20
|
+
declare const ModalTitle: React.ForwardRefExoticComponent<ModalTitleProps & React.RefAttributes<HTMLHeadingElement>>;
|
|
21
|
+
/** @type {React.ForwardRefExoticComponent<ModalDescriptionProps & React.RefAttributes<HTMLParagraphElement>>} */
|
|
22
|
+
declare const ModalDescription: React.ForwardRefExoticComponent<ModalDescriptionProps & React.RefAttributes<HTMLParagraphElement>>;
|
|
23
|
+
type ModalProps = _radix_ui_react_dialog.DialogProps & {
|
|
24
|
+
onOpen?: () => void;
|
|
25
|
+
onClose?: () => void;
|
|
26
|
+
};
|
|
27
|
+
type ModalContentProps = _radix_ui_react_dialog.DialogContentProps & {
|
|
28
|
+
size?: "small" | "medium" | "large" | "full";
|
|
29
|
+
backdropProps?: _radix_ui_react_dialog.DialogOverlayProps;
|
|
30
|
+
backDropProps?: _radix_ui_react_dialog.DialogOverlayProps;
|
|
31
|
+
contentProps?: _radix_ui_react_dialog.DialogContentProps;
|
|
32
|
+
portalProps?: _radix_ui_react_dialog.DialogPortalProps;
|
|
33
|
+
};
|
|
34
|
+
type ModalOverlayProps = _radix_ui_react_dialog.DialogOverlayProps;
|
|
35
|
+
type ModalHeaderProps = React.HTMLAttributes<HTMLDivElement>;
|
|
36
|
+
type ModalBodyProps = React.HTMLAttributes<HTMLDivElement>;
|
|
37
|
+
type ModalFooterProps = React.HTMLAttributes<HTMLDivElement>;
|
|
38
|
+
type ModalTitleProps = _radix_ui_react_dialog.DialogTitleProps;
|
|
39
|
+
type ModalDescriptionProps = _radix_ui_react_dialog.DialogDescriptionProps;
|
|
40
|
+
|
|
41
|
+
type ConfirmationDialogActionProps = Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, "children" | "disabled"> & React.RefAttributes<HTMLButtonElement>;
|
|
42
|
+
interface ConfirmationDialogProps {
|
|
43
|
+
open?: boolean;
|
|
44
|
+
defaultOpen?: boolean;
|
|
45
|
+
onOpenChange?: (open: boolean) => void;
|
|
46
|
+
modal?: boolean;
|
|
47
|
+
title: React.ReactNode;
|
|
48
|
+
description?: React.ReactNode;
|
|
49
|
+
children?: React.ReactNode;
|
|
50
|
+
/** A single ref-forwarding button. Omit for an externally opened dialog. */
|
|
51
|
+
trigger?: React.ReactElement;
|
|
52
|
+
onConfirm: React.MouseEventHandler<HTMLButtonElement>;
|
|
53
|
+
onCancel?: React.MouseEventHandler<HTMLButtonElement>;
|
|
54
|
+
confirmLabel?: React.ReactNode;
|
|
55
|
+
cancelLabel?: React.ReactNode;
|
|
56
|
+
pendingLabel?: React.ReactNode;
|
|
57
|
+
pending?: boolean;
|
|
58
|
+
error?: React.ReactNode;
|
|
59
|
+
confirmDisabled?: boolean;
|
|
60
|
+
cancelDisabled?: boolean;
|
|
61
|
+
/** Locks user dismissal. The controlled host may still close explicitly. */
|
|
62
|
+
dismissible?: boolean;
|
|
63
|
+
/** Explicit return target, useful when confirmation removes its own trigger. */
|
|
64
|
+
returnFocusRef?: React.RefObject<HTMLElement | null>;
|
|
65
|
+
isDanger?: boolean;
|
|
66
|
+
/** Pending confirmations block every user dismissal unless explicitly enabled. */
|
|
67
|
+
allowDismissWhilePending?: boolean;
|
|
68
|
+
size?: "small" | "medium" | "large" | "full";
|
|
69
|
+
contentProps?: Omit<_radix_ui_react_dialog.DialogContentProps, "children" | "asChild">;
|
|
70
|
+
backdropProps?: _radix_ui_react_dialog.DialogOverlayProps;
|
|
71
|
+
portalProps?: _radix_ui_react_dialog.DialogPortalProps;
|
|
72
|
+
confirmButtonProps?: ConfirmationDialogActionProps;
|
|
73
|
+
cancelButtonProps?: ConfirmationDialogActionProps;
|
|
74
|
+
}
|
|
75
|
+
/** Controlled confirmation. The host owns mutations, pending/error state and success closure. */
|
|
76
|
+
declare const ConfirmationDialog: React.ForwardRefExoticComponent<ConfirmationDialogProps & React.RefAttributes<HTMLDivElement>>;
|
|
77
|
+
|
|
78
|
+
export { ConfirmationDialog, type ConfirmationDialogActionProps, type ConfirmationDialogProps, Modal, ModalBody, type ModalBodyProps, ModalClose, ModalContent, type ModalContentProps, ModalDescription, type ModalDescriptionProps, ModalFooter, type ModalFooterProps, ModalHeader, type ModalHeaderProps, ModalOverlay, type ModalOverlayProps, ModalPortal, type ModalProps, ModalTitle, type ModalTitleProps, ModalTrigger };
|
package/dist/index.js
CHANGED
|
@@ -29,6 +29,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
29
29
|
// src/index.js
|
|
30
30
|
var index_exports = {};
|
|
31
31
|
__export(index_exports, {
|
|
32
|
+
ConfirmationDialog: () => ConfirmationDialog,
|
|
32
33
|
Modal: () => Modal,
|
|
33
34
|
ModalBody: () => ModalBody,
|
|
34
35
|
ModalClose: () => ModalClose,
|
|
@@ -49,6 +50,7 @@ var DialogPrimitive = __toESM(require("@radix-ui/react-dialog"));
|
|
|
49
50
|
var import_utils = require("@edux-design/utils");
|
|
50
51
|
var import_buttons = require("@edux-design/buttons");
|
|
51
52
|
var import_icons = require("@edux-design/icons");
|
|
53
|
+
var import_jsx_runtime = require("react/jsx-runtime");
|
|
52
54
|
var MODAL_OVERLAY_Z_INDEX = 2147483645;
|
|
53
55
|
var MODAL_CONTENT_Z_INDEX = 2147483646;
|
|
54
56
|
var ModalContext = (0, import_react.createContext)({ hasOnClose: false });
|
|
@@ -105,40 +107,40 @@ var Modal = ({
|
|
|
105
107
|
);
|
|
106
108
|
const handleOpenChange = (0, import_react.useCallback)(
|
|
107
109
|
(nextOpen) => {
|
|
108
|
-
onOpenChange
|
|
110
|
+
onOpenChange?.(nextOpen);
|
|
109
111
|
if (nextOpen) {
|
|
110
|
-
onOpen
|
|
112
|
+
onOpen?.();
|
|
111
113
|
return;
|
|
112
114
|
}
|
|
113
|
-
onClose
|
|
115
|
+
onClose?.();
|
|
114
116
|
},
|
|
115
117
|
[onClose, onOpen, onOpenChange]
|
|
116
118
|
);
|
|
117
|
-
return /* @__PURE__ */
|
|
119
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ModalContext.Provider, { value: contextValue, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
118
120
|
DialogPrimitive.Root,
|
|
119
121
|
{
|
|
120
122
|
open,
|
|
121
123
|
defaultOpen,
|
|
122
124
|
onOpenChange: handleOpenChange,
|
|
123
|
-
...props
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
));
|
|
125
|
+
...props,
|
|
126
|
+
children
|
|
127
|
+
}
|
|
128
|
+
) });
|
|
127
129
|
};
|
|
128
130
|
var ModalTrigger = DialogPrimitive.Trigger;
|
|
129
131
|
var ModalClose = DialogPrimitive.Close;
|
|
130
132
|
var ModalPortal = DialogPrimitive.Portal;
|
|
131
|
-
var ModalHeaderCloseButton = () => /* @__PURE__ */
|
|
133
|
+
var ModalHeaderCloseButton = () => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ModalClose, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
132
134
|
import_buttons.IconButton,
|
|
133
135
|
{
|
|
134
136
|
size: "small",
|
|
135
137
|
isBare: true,
|
|
136
|
-
icon: /* @__PURE__ */
|
|
138
|
+
icon: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_icons.Close, { "aria-hidden": "true" }),
|
|
137
139
|
"aria-label": MODAL_CLOSE_LABEL
|
|
138
140
|
}
|
|
139
|
-
));
|
|
141
|
+
) });
|
|
140
142
|
var ModalOverlay = (0, import_react.forwardRef)(
|
|
141
|
-
({ className, style, ...props }, ref) => /* @__PURE__ */
|
|
143
|
+
({ className, style, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
142
144
|
DialogPrimitive.Overlay,
|
|
143
145
|
{
|
|
144
146
|
ref,
|
|
@@ -162,50 +164,56 @@ var ModalContent = (0, import_react.forwardRef)(
|
|
|
162
164
|
backdropProps,
|
|
163
165
|
backDropProps,
|
|
164
166
|
contentProps = {},
|
|
167
|
+
portalProps = {},
|
|
165
168
|
...restProps
|
|
166
169
|
}, ref) => {
|
|
167
170
|
const resolvedBackdropProps = backdropProps ?? backDropProps ?? {};
|
|
168
171
|
const { className: backdropClassName, style: backdropStyle, ...overlayProps } = resolvedBackdropProps;
|
|
169
|
-
return /* @__PURE__ */
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
172
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(ModalPortal, { ...portalProps, children: [
|
|
173
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
174
|
+
ModalOverlay,
|
|
175
|
+
{
|
|
176
|
+
...overlayProps,
|
|
177
|
+
className: (0, import_utils.cx)(backdropClassName),
|
|
178
|
+
style: { ...backdropStyle }
|
|
179
|
+
}
|
|
180
|
+
),
|
|
181
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
182
|
+
DialogPrimitive.Content,
|
|
183
|
+
{
|
|
184
|
+
ref,
|
|
185
|
+
className: (0, import_utils.cx)(
|
|
186
|
+
MODAL_SURFACE_CLASSES,
|
|
187
|
+
getSizeClasses(size),
|
|
188
|
+
className
|
|
189
|
+
),
|
|
190
|
+
style: { zIndex: MODAL_CONTENT_Z_INDEX, ...style },
|
|
191
|
+
...contentProps,
|
|
192
|
+
...restProps,
|
|
193
|
+
children
|
|
194
|
+
}
|
|
195
|
+
)
|
|
196
|
+
] });
|
|
191
197
|
}
|
|
192
198
|
);
|
|
193
199
|
ModalContent.displayName = "ModalContent";
|
|
194
200
|
var ModalHeader = (0, import_react.forwardRef)(({ className, children, ...props }, ref) => {
|
|
195
201
|
const { hasOnClose } = (0, import_react.useContext)(ModalContext);
|
|
196
|
-
return /* @__PURE__ */
|
|
202
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
197
203
|
"div",
|
|
198
204
|
{
|
|
199
205
|
ref,
|
|
200
206
|
className: (0, import_utils.cx)(MODAL_HEADER_CLASSES, className),
|
|
201
|
-
...props
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
207
|
+
...props,
|
|
208
|
+
children: [
|
|
209
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: MODAL_HEADER_CONTENT_CLASSES, children }),
|
|
210
|
+
hasOnClose ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ModalHeaderCloseButton, {}) : null
|
|
211
|
+
]
|
|
212
|
+
}
|
|
205
213
|
);
|
|
206
214
|
});
|
|
207
215
|
ModalHeader.displayName = "ModalHeader";
|
|
208
|
-
var ModalBody = (0, import_react.forwardRef)(({ className, ...props }, ref) => /* @__PURE__ */
|
|
216
|
+
var ModalBody = (0, import_react.forwardRef)(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
209
217
|
"div",
|
|
210
218
|
{
|
|
211
219
|
ref,
|
|
@@ -214,7 +222,7 @@ var ModalBody = (0, import_react.forwardRef)(({ className, ...props }, ref) => /
|
|
|
214
222
|
}
|
|
215
223
|
));
|
|
216
224
|
ModalBody.displayName = "ModalBody";
|
|
217
|
-
var ModalFooter = (0, import_react.forwardRef)(({ className, ...props }, ref) => /* @__PURE__ */
|
|
225
|
+
var ModalFooter = (0, import_react.forwardRef)(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
218
226
|
"div",
|
|
219
227
|
{
|
|
220
228
|
ref,
|
|
@@ -223,7 +231,7 @@ var ModalFooter = (0, import_react.forwardRef)(({ className, ...props }, ref) =>
|
|
|
223
231
|
}
|
|
224
232
|
));
|
|
225
233
|
ModalFooter.displayName = "ModalFooter";
|
|
226
|
-
var ModalTitle = (0, import_react.forwardRef)(({ className, ...props }, ref) => /* @__PURE__ */
|
|
234
|
+
var ModalTitle = (0, import_react.forwardRef)(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
227
235
|
DialogPrimitive.Title,
|
|
228
236
|
{
|
|
229
237
|
ref,
|
|
@@ -232,7 +240,7 @@ var ModalTitle = (0, import_react.forwardRef)(({ className, ...props }, ref) =>
|
|
|
232
240
|
}
|
|
233
241
|
));
|
|
234
242
|
ModalTitle.displayName = "ModalTitle";
|
|
235
|
-
var ModalDescription = (0, import_react.forwardRef)(({ className, ...props }, ref) => /* @__PURE__ */
|
|
243
|
+
var ModalDescription = (0, import_react.forwardRef)(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
236
244
|
DialogPrimitive.Description,
|
|
237
245
|
{
|
|
238
246
|
ref,
|
|
@@ -241,8 +249,153 @@ var ModalDescription = (0, import_react.forwardRef)(({ className, ...props }, re
|
|
|
241
249
|
}
|
|
242
250
|
));
|
|
243
251
|
ModalDescription.displayName = "ModalDescription";
|
|
252
|
+
|
|
253
|
+
// src/elements/ConfirmationDialog.tsx
|
|
254
|
+
var import_react2 = require("react");
|
|
255
|
+
var import_buttons2 = require("@edux-design/buttons");
|
|
256
|
+
var import_utils2 = require("@edux-design/utils");
|
|
257
|
+
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
258
|
+
var ConfirmationDialog = (0, import_react2.forwardRef)(function ConfirmationDialog2({
|
|
259
|
+
open,
|
|
260
|
+
defaultOpen = false,
|
|
261
|
+
onOpenChange,
|
|
262
|
+
modal = true,
|
|
263
|
+
title,
|
|
264
|
+
description,
|
|
265
|
+
children,
|
|
266
|
+
trigger,
|
|
267
|
+
onConfirm,
|
|
268
|
+
onCancel,
|
|
269
|
+
confirmLabel = "Confirm",
|
|
270
|
+
cancelLabel = "Cancel",
|
|
271
|
+
pendingLabel = "Working\u2026",
|
|
272
|
+
pending = false,
|
|
273
|
+
error,
|
|
274
|
+
confirmDisabled = false,
|
|
275
|
+
cancelDisabled = false,
|
|
276
|
+
dismissible = true,
|
|
277
|
+
returnFocusRef,
|
|
278
|
+
isDanger = false,
|
|
279
|
+
allowDismissWhilePending = false,
|
|
280
|
+
size = "small",
|
|
281
|
+
contentProps = {},
|
|
282
|
+
backdropProps,
|
|
283
|
+
portalProps,
|
|
284
|
+
confirmButtonProps = {},
|
|
285
|
+
cancelButtonProps = {}
|
|
286
|
+
}, ref) {
|
|
287
|
+
const [uncontrolledOpen, setUncontrolledOpen] = (0, import_react2.useState)(defaultOpen);
|
|
288
|
+
const resolvedOpen = open ?? uncontrolledOpen;
|
|
289
|
+
const cancelRef = (0, import_react2.useRef)(null);
|
|
290
|
+
const previousFocusRef = (0, import_react2.useRef)(null);
|
|
291
|
+
const statusId = (0, import_react2.useId)();
|
|
292
|
+
const locked = !dismissible || pending && !allowDismissWhilePending;
|
|
293
|
+
const hasBody = children != null || Boolean(error) || pending;
|
|
294
|
+
const {
|
|
295
|
+
onClick: onCancelClick,
|
|
296
|
+
ref: actionRef,
|
|
297
|
+
...cancelProps
|
|
298
|
+
} = cancelButtonProps;
|
|
299
|
+
const { onClick: onConfirmClick, ...confirmProps } = confirmButtonProps;
|
|
300
|
+
const requestOpen = (next) => {
|
|
301
|
+
if (!next && locked) return;
|
|
302
|
+
if (open === void 0) setUncontrolledOpen(next);
|
|
303
|
+
onOpenChange?.(next);
|
|
304
|
+
};
|
|
305
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(Modal, { open: resolvedOpen, onOpenChange: requestOpen, modal, children: [
|
|
306
|
+
trigger && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ModalTrigger, { asChild: true, children: trigger }),
|
|
307
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
308
|
+
ModalContent,
|
|
309
|
+
{
|
|
310
|
+
...contentProps,
|
|
311
|
+
ref,
|
|
312
|
+
size,
|
|
313
|
+
backdropProps,
|
|
314
|
+
portalProps,
|
|
315
|
+
...!description && !contentProps["aria-describedby"] ? { "aria-describedby": void 0 } : {},
|
|
316
|
+
"aria-busy": pending || void 0,
|
|
317
|
+
className: (0, import_utils2.cx)("motion-reduce:animate-none", contentProps.className),
|
|
318
|
+
onOpenAutoFocus: (event) => {
|
|
319
|
+
previousFocusRef.current = document.activeElement instanceof HTMLElement ? document.activeElement : null;
|
|
320
|
+
contentProps.onOpenAutoFocus?.(event);
|
|
321
|
+
if (!event.defaultPrevented) {
|
|
322
|
+
event.preventDefault();
|
|
323
|
+
if (!locked && !cancelDisabled) cancelRef.current?.focus();
|
|
324
|
+
else if (event.target instanceof HTMLElement) event.target.focus();
|
|
325
|
+
}
|
|
326
|
+
},
|
|
327
|
+
onCloseAutoFocus: (event) => {
|
|
328
|
+
contentProps.onCloseAutoFocus?.(event);
|
|
329
|
+
const target = returnFocusRef?.current ?? (!trigger ? previousFocusRef.current : null);
|
|
330
|
+
if (!event.defaultPrevented && target?.isConnected) {
|
|
331
|
+
event.preventDefault();
|
|
332
|
+
target.focus();
|
|
333
|
+
}
|
|
334
|
+
},
|
|
335
|
+
onEscapeKeyDown: (event) => {
|
|
336
|
+
contentProps.onEscapeKeyDown?.(event);
|
|
337
|
+
if (locked) event.preventDefault();
|
|
338
|
+
},
|
|
339
|
+
onInteractOutside: (event) => {
|
|
340
|
+
contentProps.onInteractOutside?.(event);
|
|
341
|
+
if (locked) event.preventDefault();
|
|
342
|
+
},
|
|
343
|
+
children: [
|
|
344
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(ModalHeader, { className: !hasBody ? "border-b-0" : void 0, children: [
|
|
345
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ModalTitle, { children: title }),
|
|
346
|
+
description && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ModalDescription, { children: description })
|
|
347
|
+
] }),
|
|
348
|
+
hasBody && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(ModalBody, { className: "min-h-0 text-sm text-fg-base", children: [
|
|
349
|
+
children,
|
|
350
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { role: "alert", className: "mt-8 text-fg-danger-emphasis", children: error }),
|
|
351
|
+
pending && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { id: statusId, role: "status", className: "sr-only", children: pendingLabel })
|
|
352
|
+
] }),
|
|
353
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(ModalFooter, { className: "flex-wrap", children: [
|
|
354
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
355
|
+
import_buttons2.Button,
|
|
356
|
+
{
|
|
357
|
+
...cancelProps,
|
|
358
|
+
ref: (node) => {
|
|
359
|
+
cancelRef.current = node;
|
|
360
|
+
if (typeof actionRef === "function") actionRef(node);
|
|
361
|
+
else if (actionRef) actionRef.current = node;
|
|
362
|
+
},
|
|
363
|
+
type: "button",
|
|
364
|
+
size: "small",
|
|
365
|
+
isSecondary: true,
|
|
366
|
+
disabled: locked || cancelDisabled,
|
|
367
|
+
onClick: (event) => {
|
|
368
|
+
onCancelClick?.(event);
|
|
369
|
+
if (!event.defaultPrevented) onCancel?.(event);
|
|
370
|
+
if (!event.defaultPrevented) requestOpen(false);
|
|
371
|
+
},
|
|
372
|
+
children: cancelLabel
|
|
373
|
+
}
|
|
374
|
+
),
|
|
375
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
376
|
+
import_buttons2.Button,
|
|
377
|
+
{
|
|
378
|
+
...confirmProps,
|
|
379
|
+
type: "button",
|
|
380
|
+
size: "small",
|
|
381
|
+
isDanger,
|
|
382
|
+
disabled: pending || confirmDisabled,
|
|
383
|
+
onClick: (event) => {
|
|
384
|
+
onConfirmClick?.(event);
|
|
385
|
+
if (!event.defaultPrevented) onConfirm(event);
|
|
386
|
+
},
|
|
387
|
+
children: pending ? pendingLabel : confirmLabel
|
|
388
|
+
}
|
|
389
|
+
)
|
|
390
|
+
] })
|
|
391
|
+
]
|
|
392
|
+
}
|
|
393
|
+
)
|
|
394
|
+
] });
|
|
395
|
+
});
|
|
244
396
|
// Annotate the CommonJS export names for ESM import in node:
|
|
245
397
|
0 && (module.exports = {
|
|
398
|
+
ConfirmationDialog,
|
|
246
399
|
Modal,
|
|
247
400
|
ModalBody,
|
|
248
401
|
ModalClose,
|