@mezzanine-ui/react 1.0.0-beta.2 → 1.0.0-beta.4

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.
Files changed (193) hide show
  1. package/Anchor/Anchor.d.ts +51 -18
  2. package/Anchor/Anchor.js +15 -15
  3. package/Anchor/AnchorGroup.d.ts +34 -0
  4. package/Anchor/AnchorGroup.js +37 -0
  5. package/Anchor/AnchorItem.d.ts +30 -0
  6. package/Anchor/AnchorItem.js +65 -0
  7. package/Anchor/index.d.ts +2 -0
  8. package/Anchor/index.js +1 -0
  9. package/Anchor/utils.d.ts +13 -0
  10. package/Anchor/utils.js +95 -0
  11. package/AutoComplete/AutoComplete.d.ts +217 -0
  12. package/AutoComplete/AutoComplete.js +433 -0
  13. package/AutoComplete/index.d.ts +2 -0
  14. package/AutoComplete/index.js +1 -0
  15. package/AutoComplete/useAutoCompleteCreation.d.ts +33 -0
  16. package/AutoComplete/useAutoCompleteCreation.js +201 -0
  17. package/AutoComplete/useAutoCompleteKeyboard.d.ts +31 -0
  18. package/AutoComplete/useAutoCompleteKeyboard.js +149 -0
  19. package/AutoComplete/useAutoCompleteSearch.d.ts +16 -0
  20. package/AutoComplete/useAutoCompleteSearch.js +69 -0
  21. package/AutoComplete/useCreationTracker.d.ts +17 -0
  22. package/AutoComplete/useCreationTracker.js +47 -0
  23. package/Breadcrumb/Breadcrumb.js +16 -21
  24. package/Breadcrumb/BreadcrumbDropdown.d.ts +11 -0
  25. package/Breadcrumb/BreadcrumbDropdown.js +22 -0
  26. package/Breadcrumb/BreadcrumbItem.d.ts +2 -3
  27. package/Breadcrumb/BreadcrumbItem.js +13 -31
  28. package/Breadcrumb/BreadcrumbOverflowMenu.d.ts +7 -0
  29. package/Breadcrumb/BreadcrumbOverflowMenu.js +77 -0
  30. package/Breadcrumb/BreadcrumbOverflowMenuDropdown.d.ts +11 -0
  31. package/Breadcrumb/BreadcrumbOverflowMenuDropdown.js +21 -0
  32. package/Breadcrumb/BreadcrumbOverflowMenuItem.d.ts +3 -0
  33. package/Breadcrumb/BreadcrumbOverflowMenuItem.js +27 -0
  34. package/Breadcrumb/typings.d.ts +21 -39
  35. package/Button/Button.js +13 -11
  36. package/Button/index.d.ts +1 -1
  37. package/Button/typings.d.ts +27 -4
  38. package/Checkbox/index.d.ts +4 -5
  39. package/Checkbox/index.js +1 -5
  40. package/ContentHeader/ContentHeader.d.ts +160 -0
  41. package/ContentHeader/ContentHeader.js +54 -0
  42. package/ContentHeader/index.d.ts +2 -0
  43. package/ContentHeader/index.js +1 -0
  44. package/ContentHeader/utils.d.ts +23 -0
  45. package/ContentHeader/utils.js +215 -0
  46. package/Description/Description.d.ts +12 -22
  47. package/Description/Description.js +4 -24
  48. package/Dropdown/Dropdown.d.ts +46 -1
  49. package/Dropdown/Dropdown.js +99 -14
  50. package/Dropdown/DropdownAction.d.ts +1 -1
  51. package/Dropdown/DropdownAction.js +1 -4
  52. package/Dropdown/DropdownItem.d.ts +28 -1
  53. package/Dropdown/DropdownItem.js +56 -14
  54. package/Dropdown/DropdownItemCard.d.ts +2 -2
  55. package/Dropdown/DropdownItemCard.js +20 -16
  56. package/Dropdown/DropdownStatus.js +29 -0
  57. package/Dropdown/dropdownKeydownHandler.d.ts +2 -1
  58. package/Dropdown/dropdownKeydownHandler.js +73 -0
  59. package/Dropdown/highlightText.js +5 -1
  60. package/Dropdown/shortcutTextHandler.d.ts +24 -0
  61. package/Dropdown/shortcutTextHandler.js +171 -0
  62. package/Empty/Empty.js +2 -1
  63. package/Empty/icons/EmptyMainNotificationIcon.d.ts +4 -0
  64. package/Empty/icons/EmptyMainNotificationIcon.js +9 -0
  65. package/Empty/typings.d.ts +2 -2
  66. package/FilterArea/Filter.d.ts +32 -0
  67. package/FilterArea/Filter.js +23 -0
  68. package/FilterArea/FilterArea.d.ts +58 -0
  69. package/FilterArea/FilterArea.js +31 -0
  70. package/FilterArea/FilterLine.d.ts +11 -0
  71. package/FilterArea/FilterLine.js +13 -0
  72. package/FilterArea/index.d.ts +6 -0
  73. package/FilterArea/index.js +3 -0
  74. package/Form/FormField.js +3 -1
  75. package/Input/Input.d.ts +35 -7
  76. package/Input/Input.js +48 -14
  77. package/Input/index.d.ts +1 -1
  78. package/Modal/MediaPreviewModal.d.ts +54 -0
  79. package/Modal/MediaPreviewModal.js +158 -0
  80. package/Modal/Modal.d.ts +103 -11
  81. package/Modal/Modal.js +14 -9
  82. package/Modal/ModalBodyForVerification.d.ts +59 -0
  83. package/Modal/ModalBodyForVerification.js +99 -0
  84. package/Modal/ModalControl.d.ts +2 -2
  85. package/Modal/ModalControl.js +1 -1
  86. package/Modal/ModalFooter.d.ts +119 -1
  87. package/Modal/ModalFooter.js +15 -3
  88. package/Modal/ModalHeader.d.ts +26 -7
  89. package/Modal/ModalHeader.js +33 -7
  90. package/Modal/index.d.ts +6 -5
  91. package/Modal/index.js +2 -2
  92. package/Modal/useModalContainer.d.ts +12 -3
  93. package/Modal/useModalContainer.js +28 -6
  94. package/Navigation/Navigation.d.ts +7 -2
  95. package/Navigation/Navigation.js +36 -35
  96. package/Navigation/NavigationHeader.d.ts +4 -0
  97. package/Navigation/NavigationHeader.js +3 -2
  98. package/Navigation/NavigationOption.d.ts +8 -3
  99. package/Navigation/NavigationOption.js +46 -11
  100. package/Navigation/NavigationOptionCategory.js +1 -0
  101. package/Navigation/NavigationOverflowMenu.d.ts +6 -0
  102. package/Navigation/NavigationOverflowMenu.js +90 -0
  103. package/Navigation/NavigationOverflowMenuOption.d.ts +7 -0
  104. package/Navigation/NavigationOverflowMenuOption.js +68 -0
  105. package/Navigation/NavigationUserMenu.d.ts +4 -2
  106. package/Navigation/NavigationUserMenu.js +13 -5
  107. package/Navigation/context.d.ts +3 -2
  108. package/Navigation/useVisibleItems.d.ts +5 -0
  109. package/Navigation/useVisibleItems.js +54 -0
  110. package/NotificationCenter/NotificationCenter.d.ts +124 -0
  111. package/NotificationCenter/NotificationCenter.js +279 -0
  112. package/NotificationCenter/NotificationCenterDrawer.d.ts +109 -0
  113. package/NotificationCenter/index.d.ts +3 -0
  114. package/NotificationCenter/index.js +1 -0
  115. package/PageFooter/PageFooter.d.ts +19 -9
  116. package/PageFooter/PageFooter.js +10 -10
  117. package/PageHeader/PageHeader.d.ts +32 -25
  118. package/PageHeader/PageHeader.js +49 -43
  119. package/ResultState/ResultState.d.ts +9 -0
  120. package/ResultState/ResultState.js +36 -4
  121. package/Scrollbar/Scrollbar.d.ts +9 -0
  122. package/Scrollbar/Scrollbar.js +78 -0
  123. package/Scrollbar/index.d.ts +2 -0
  124. package/Scrollbar/index.js +1 -0
  125. package/Scrollbar/typings.d.ts +47 -0
  126. package/Select/SelectTrigger.js +5 -4
  127. package/Select/index.d.ts +0 -2
  128. package/Select/index.js +0 -1
  129. package/Select/typings.d.ts +6 -1
  130. package/Selection/Selection.js +1 -1
  131. package/Selection/SelectionGroup.d.ts +28 -0
  132. package/Slider/useSlider.js +1 -1
  133. package/Table/Table.d.ts +2 -120
  134. package/Table/Table.js +148 -53
  135. package/Table/TableContext.d.ts +11 -12
  136. package/Table/components/TableActionsCell.js +12 -4
  137. package/Table/components/TableBody.js +2 -1
  138. package/Table/components/TableBulkActions.js +1 -19
  139. package/Table/components/TableColGroup.d.ts +1 -4
  140. package/Table/components/TableColGroup.js +15 -16
  141. package/Table/components/TableCollectableCell.d.ts +17 -0
  142. package/Table/components/TableCollectableCell.js +54 -0
  143. package/Table/components/TableDragOrPinHandleCell.d.ts +20 -0
  144. package/Table/components/TableDragOrPinHandleCell.js +58 -0
  145. package/Table/components/TableExpandedRow.js +11 -2
  146. package/Table/components/TableHeader.js +12 -10
  147. package/Table/components/TableRow.js +38 -13
  148. package/Table/components/TableSelectionCell.js +1 -1
  149. package/Table/components/TableToggleableCell.d.ts +16 -0
  150. package/Table/components/TableToggleableCell.js +51 -0
  151. package/Table/components/index.d.ts +4 -1
  152. package/Table/components/index.js +3 -0
  153. package/Table/hooks/typings.d.ts +18 -4
  154. package/Table/hooks/useTableExpansion.d.ts +2 -2
  155. package/Table/hooks/useTableExpansion.js +5 -5
  156. package/Table/hooks/useTableFixedOffsets.d.ts +6 -2
  157. package/Table/hooks/useTableFixedOffsets.js +60 -26
  158. package/Table/hooks/useTableScroll.d.ts +9 -3
  159. package/Table/hooks/useTableScroll.js +34 -7
  160. package/Table/hooks/useTableVirtualization.d.ts +2 -1
  161. package/Table/hooks/useTableVirtualization.js +2 -8
  162. package/Table/index.d.ts +4 -3
  163. package/Table/index.js +3 -0
  164. package/Table/typings.d.ts +172 -0
  165. package/Table/utils/useTableRowSelection.js +13 -5
  166. package/Tag/TagGroup.d.ts +3 -0
  167. package/Tag/index.d.ts +2 -0
  168. package/Tag/index.js +1 -0
  169. package/Transition/Slide.d.ts +9 -2
  170. package/Transition/Slide.js +7 -4
  171. package/Tree/TreeNode.js +1 -1
  172. package/Upload/UploadPictureCard.js +1 -1
  173. package/index.d.ts +37 -21
  174. package/index.js +25 -11
  175. package/package.json +6 -4
  176. package/Modal/ModalActions.d.ts +0 -9
  177. package/Modal/ModalActions.js +0 -20
  178. package/Modal/ModalBody.d.ts +0 -7
  179. package/Modal/ModalBody.js +0 -14
  180. package/Notification/Notification.d.ts +0 -54
  181. package/Notification/Notification.js +0 -76
  182. package/Notification/index.d.ts +0 -3
  183. package/Notification/index.js +0 -1
  184. package/PageToolbar/PageToolbar.d.ts +0 -114
  185. package/PageToolbar/PageToolbar.js +0 -23
  186. package/PageToolbar/index.d.ts +0 -2
  187. package/PageToolbar/index.js +0 -1
  188. package/PageToolbar/utils.d.ts +0 -23
  189. package/PageToolbar/utils.js +0 -165
  190. package/Select/AutoComplete.d.ts +0 -107
  191. package/Select/AutoComplete.js +0 -114
  192. package/Table/components/TableDragHandleCell.d.ts +0 -11
  193. package/Table/components/TableDragHandleCell.js +0 -44
package/Modal/Modal.d.ts CHANGED
@@ -1,34 +1,126 @@
1
- import { ModalSeverity, ModalSize } from '@mezzanine-ui/core/modal';
2
- import { SlideFadeOverlayProps } from '../_internal/SlideFadeOverlay';
1
+ import { ModalSize, ModalStatusType } from '@mezzanine-ui/core/modal';
2
+ import { ModalContainerProps } from './useModalContainer';
3
3
  import { NativeElementPropsWithoutKeyAndRef } from '../utils/jsx-types';
4
- export interface ModalProps extends Omit<SlideFadeOverlayProps, 'children'>, Pick<NativeElementPropsWithoutKeyAndRef<'div'>, 'children'> {
4
+ import { ModalHeaderProps } from './ModalHeader';
5
+ import { ModalFooterProps } from './ModalFooter';
6
+ interface CommonModalProps extends Omit<ModalContainerProps, 'children'>, Pick<NativeElementPropsWithoutKeyAndRef<'div'>, 'children'>, Partial<Omit<ModalHeaderProps, 'children' | 'className' | 'title'>>, Partial<Omit<ModalFooterProps, 'children' | 'className' | 'confirmText'>> {
5
7
  /**
6
8
  * Whether to force full screen on any breakpoint.
7
9
  * @default false
8
10
  */
9
11
  fullScreen?: boolean;
10
- /**
11
- * Controls whether or not to hide close button at top-end.
12
- * @default false
13
- */
14
- hideCloseIcon?: boolean;
15
12
  /**
16
13
  * Whether the modal is loading.
17
14
  * Controls the loading prop of confirm button in modal actions.
18
15
  */
19
16
  loading?: boolean;
20
17
  /**
21
- * Controlls whether or not to display status icon before title. <br />
18
+ * Controls whether or not to display status icon before title.
22
19
  * Notice that giving a status will only display the regular title.
23
20
  * @default 'info'
24
21
  */
25
- severity?: ModalSeverity;
22
+ modalStatusType?: ModalStatusType;
23
+ /**
24
+ * Controls whether or not to show dismiss button at top-end.
25
+ * @default false
26
+ */
27
+ showDismissButton?: boolean;
28
+ }
29
+ interface ExtendedSplitModalProps extends CommonModalProps {
30
+ /**
31
+ * Content for the left side in extendedSplit layout.
32
+ * Required when modalType is 'extendedSplit'.
33
+ */
34
+ extendedSplitLeftSideContent: React.ReactNode;
35
+ /**
36
+ * Content for the right side in extendedSplit layout.
37
+ * Required when modalType is 'extendedSplit'.
38
+ */
39
+ extendedSplitRightSideContent: React.ReactNode;
40
+ /**
41
+ * Controls the type/layout of the modal.
42
+ * - 'extendedSplit': Modal with split layout (footer inside left content)
43
+ */
44
+ modalType: 'extendedSplit';
26
45
  /**
27
46
  * Controls the size of the modal.
28
- * @default "medium"
47
+ * For extendedSplit type, only 'wide' is allowed.
48
+ * @default 'wide'
49
+ */
50
+ size?: 'wide';
51
+ }
52
+ interface OtherModalProps extends CommonModalProps {
53
+ /**
54
+ * Content for the left side in extendedSplit layout.
55
+ * Cannot be provided when modalType is not 'extendedSplit'.
56
+ */
57
+ extendedSplitLeftSideContent?: never;
58
+ /**
59
+ * Content for the right side in extendedSplit layout.
60
+ * Cannot be provided when modalType is not 'extendedSplit'.
61
+ */
62
+ extendedSplitRightSideContent?: never;
63
+ /**
64
+ * Controls the type/layout of the modal.
65
+ * - 'standard': Default modal with body container
66
+ * - 'extended': Modal with left and right content areas
67
+ * - 'mediaPreview': Modal for media preview
68
+ * - 'verification': Modal for verification flows
69
+ * @default 'standard'
70
+ */
71
+ modalType: 'extended' | 'standard' | 'mediaPreview' | 'verification';
72
+ /**
73
+ * Controls the size of the modal.
74
+ * @default 'regular'
29
75
  */
30
76
  size?: ModalSize;
31
77
  }
78
+ type BaseModalProps = ExtendedSplitModalProps | OtherModalProps;
79
+ type ModalHeaderPropsWithHeader = {
80
+ /**
81
+ * Whether to show modal header.
82
+ */
83
+ showModalHeader: true;
84
+ /**
85
+ * The title of the modal header (required when showModalHeader is true).
86
+ */
87
+ title: string;
88
+ };
89
+ type ModalHeaderPropsWithoutHeader = {
90
+ /**
91
+ * Whether to show modal header.
92
+ * @default false
93
+ */
94
+ showModalHeader?: false;
95
+ /**
96
+ * The title of the modal header.
97
+ * Cannot be provided when showModalHeader is false.
98
+ */
99
+ title?: never;
100
+ };
101
+ type ModalFooterPropsWithFooter = {
102
+ /**
103
+ * Whether to show modal footer.
104
+ */
105
+ showModalFooter: true;
106
+ /**
107
+ * The confirm button text of the modal footer (required when showModalFooter is true).
108
+ */
109
+ confirmText: string;
110
+ };
111
+ type ModalFooterPropsWithoutFooter = {
112
+ /**
113
+ * Whether to show modal footer.
114
+ * @default false
115
+ */
116
+ showModalFooter?: false;
117
+ /**
118
+ * The confirm button text of the modal footer.
119
+ * Cannot be provided when showModalFooter is false.
120
+ */
121
+ confirmText?: never;
122
+ };
123
+ export type ModalProps = BaseModalProps & ((ModalHeaderPropsWithHeader & ModalFooterPropsWithFooter) | (ModalHeaderPropsWithHeader & ModalFooterPropsWithoutFooter) | (ModalHeaderPropsWithoutHeader & ModalFooterPropsWithFooter) | (ModalHeaderPropsWithoutHeader & ModalFooterPropsWithoutFooter));
32
124
  /**
33
125
  * The react component for `mezzanine` modal.
34
126
  */
package/Modal/Modal.js CHANGED
@@ -1,26 +1,31 @@
1
- import { jsx, jsxs } from 'react/jsx-runtime';
1
+ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
2
2
  import { modalClasses } from '@mezzanine-ui/core/modal';
3
- import { TimesIcon } from '@mezzanine-ui/icons';
4
3
  import { forwardRef, useMemo } from 'react';
5
4
  import { ModalControlContext } from './ModalControl.js';
6
5
  import useModalContainer from './useModalContainer.js';
7
- import Icon from '../Icon/Icon.js';
6
+ import ModalHeader from './ModalHeader.js';
7
+ import ModalFooter from './ModalFooter.js';
8
+ import ClearActions from '../ClearActions/ClearActions.js';
8
9
  import cx from 'clsx';
9
10
 
10
11
  /**
11
12
  * The react component for `mezzanine` modal.
12
13
  */
13
14
  const Modal = forwardRef(function Modal(props, ref) {
14
- const { children, className, container, direction = 'down', disableCloseOnBackdropClick = false, disableCloseOnEscapeKeyDown = false, disablePortal = false, fullScreen = false, hideCloseIcon = false, loading = false, onBackdropClick, onClose, open, severity = 'info', size = 'medium', ...rest } = props;
15
+ const { actionsButtonLayout, annotation, auxiliaryContentButtonProps, auxiliaryContentButtonText, auxiliaryContentChecked, auxiliaryContentLabel, auxiliaryContentOnChange, auxiliaryContentOnClick, auxiliaryContentType, cancelButtonProps, cancelText, children, className, confirmButtonProps, confirmText, container, disableCloseOnBackdropClick = false, disableCloseOnEscapeKeyDown = false, disablePortal = false, extendedSplitLeftSideContent, extendedSplitRightSideContent, fullScreen = false, loading = false, modalStatusType = 'info', modalType = 'standard', onBackdropClick, onCancel, onClose, onConfirm, open, passwordButtonProps, passwordButtonText, passwordChecked, passwordCheckedLabel, passwordCheckedOnChange, passwordOnClick, showCancelButton, showDismissButton = false, showModalFooter = false, showModalHeader, showStatusTypeIcon, size = 'regular', statusTypeIconLayout, supportingText, supportingTextAlign, title, titleAlign, ...rest } = props;
15
16
  const modalControl = useMemo(() => ({
16
17
  loading,
17
- severity,
18
- }), [loading, severity]);
18
+ modalStatusType: modalStatusType,
19
+ }), [loading, modalStatusType]);
19
20
  const { Container: ModalContainer } = useModalContainer();
20
- return (jsx(ModalControlContext.Provider, { value: modalControl, children: jsx(ModalContainer, { className: modalClasses.overlay, container: container, direction: direction, disableCloseOnBackdropClick: disableCloseOnBackdropClick, disableCloseOnEscapeKeyDown: disableCloseOnEscapeKeyDown, disablePortal: disablePortal, onBackdropClick: onBackdropClick, onClose: onClose, open: open, ref: ref, children: jsxs("div", { ...rest, className: cx(modalClasses.host, modalClasses.severity(severity), modalClasses.size(size), {
21
+ const renderModalFooter = () => (jsx(ModalFooter, { actionsButtonLayout: actionsButtonLayout, annotation: annotation, auxiliaryContentButtonProps: auxiliaryContentButtonProps, auxiliaryContentButtonText: auxiliaryContentButtonText, auxiliaryContentChecked: auxiliaryContentChecked, auxiliaryContentLabel: auxiliaryContentLabel, auxiliaryContentOnChange: auxiliaryContentOnChange, auxiliaryContentOnClick: auxiliaryContentOnClick, auxiliaryContentType: auxiliaryContentType, cancelButtonProps: cancelButtonProps, cancelText: cancelText, confirmButtonProps: confirmButtonProps, confirmText: confirmText, loading: loading, onCancel: onCancel, onConfirm: onConfirm, passwordButtonProps: passwordButtonProps, passwordButtonText: passwordButtonText, passwordChecked: passwordChecked, passwordCheckedLabel: passwordCheckedLabel, passwordCheckedOnChange: passwordCheckedOnChange, passwordOnClick: passwordOnClick, showCancelButton: showCancelButton }));
22
+ return (jsx(ModalControlContext.Provider, { value: modalControl, children: jsx(ModalContainer, { className: modalClasses.overlay, container: container, disableCloseOnBackdropClick: disableCloseOnBackdropClick, disableCloseOnEscapeKeyDown: disableCloseOnEscapeKeyDown, disablePortal: disablePortal, onBackdropClick: onBackdropClick, onClose: onClose, open: open, ref: ref, children: jsxs("div", { ...rest, className: cx(modalClasses.host, modalClasses.modalStatusType(modalStatusType), modalClasses.size(size), {
21
23
  [modalClasses.fullScreen]: fullScreen,
22
- [modalClasses.withCloseIcon]: !hideCloseIcon,
23
- }, className), role: "dialog", children: [children, !hideCloseIcon && (jsx(Icon, { className: modalClasses.closeIcon, icon: TimesIcon, onClick: onClose }))] }) }) }));
24
+ [modalClasses.withCloseIcon]: showDismissButton,
25
+ }, className), role: "dialog", children: [showModalHeader && (jsx(ModalHeader, { showStatusTypeIcon: showStatusTypeIcon, statusTypeIconLayout: statusTypeIconLayout, supportingText: supportingText, supportingTextAlign: supportingTextAlign, title: title, titleAlign: titleAlign })), modalType === 'extendedSplit' && (jsxs("div", { className: modalClasses.modalBodyContainerExtendedSplit, children: [jsx("div", { className: modalClasses.modalBodyContainerExtendedSplitRight, children: extendedSplitRightSideContent }), jsxs("div", { className: modalClasses.modalBodyContainerExtendedSplitLeft, children: [jsx("div", { className: modalClasses.modalBodyContainerExtendedSplitLeftSideContent, children: extendedSplitLeftSideContent }), showModalFooter && renderModalFooter()] })] })), (modalType === 'standard' ||
26
+ modalType === 'verification' ||
27
+ modalType === 'extended' ||
28
+ modalType === 'mediaPreview') && (jsxs(Fragment, { children: [children && (jsx("div", { className: modalClasses.modalBodyContainer, children: children })), showModalFooter && renderModalFooter()] })), showDismissButton && (jsx(ClearActions, { onClick: onClose, className: modalClasses.closeIcon, variant: "base" }))] }) }) }));
24
29
  });
25
30
 
26
31
  export { Modal as default };
@@ -0,0 +1,59 @@
1
+ import { NativeElementPropsWithoutKeyAndRef } from '../utils/jsx-types';
2
+ export interface ModalBodyForVerificationProps extends Omit<NativeElementPropsWithoutKeyAndRef<'div'>, 'onChange'> {
3
+ /**
4
+ * Whether to auto focus the first input when mounted.
5
+ * @default true
6
+ */
7
+ autoFocus?: boolean;
8
+ /**
9
+ * Whether the inputs are disabled.
10
+ * @default false
11
+ */
12
+ disabled?: boolean;
13
+ /**
14
+ * Whether the inputs are in error state.
15
+ * @default false
16
+ */
17
+ error?: boolean;
18
+ /**
19
+ * Number of verification code digits.
20
+ * @default 4
21
+ */
22
+ length?: number;
23
+ /**
24
+ * Called when verification code changes.
25
+ */
26
+ onChange?: (value: string) => void;
27
+ /**
28
+ * Called when all digits are filled.
29
+ */
30
+ onComplete?: (value: string) => void;
31
+ /**
32
+ * Called when resend link is clicked.
33
+ */
34
+ onResend?: () => void;
35
+ /**
36
+ * Whether the inputs are readonly.
37
+ * @default false
38
+ */
39
+ readOnly?: boolean;
40
+ /**
41
+ * Prompt text before resend link.
42
+ * @default "收不到驗證碼?"
43
+ */
44
+ resendPrompt?: string;
45
+ /**
46
+ * Resend link text.
47
+ * @default "點此重新寄送"
48
+ */
49
+ resendText?: string;
50
+ /**
51
+ * Current verification code value.
52
+ */
53
+ value?: string;
54
+ }
55
+ /**
56
+ * The react component for verification code input in modal.
57
+ */
58
+ declare const ModalBodyForVerification: import("react").ForwardRefExoticComponent<ModalBodyForVerificationProps & import("react").RefAttributes<HTMLDivElement>>;
59
+ export default ModalBodyForVerification;
@@ -0,0 +1,99 @@
1
+ 'use client';
2
+ import { jsxs, jsx } from 'react/jsx-runtime';
3
+ import { forwardRef, useState, useRef, useEffect } from 'react';
4
+ import { modalClasses } from '@mezzanine-ui/core/modal';
5
+ import Typography from '../Typography/Typography.js';
6
+ import cx from 'clsx';
7
+
8
+ /**
9
+ * The react component for verification code input in modal.
10
+ */
11
+ const ModalBodyForVerification = forwardRef(function ModalBodyForVerification(props, ref) {
12
+ const { autoFocus = true, className, disabled = false, error = false, length = 4, onChange, onComplete, onResend, readOnly = false, resendPrompt = '收不到驗證碼?', resendText = '點此重新寄送', value = '', ...rest } = props;
13
+ const [codes, setCodes] = useState(value
14
+ .split('')
15
+ .slice(0, length)
16
+ .concat(Array(length - value.length).fill('')));
17
+ const inputRefs = useRef([]);
18
+ // Auto focus first input when mounted
19
+ useEffect(() => {
20
+ var _a;
21
+ if (autoFocus && !disabled && !readOnly) {
22
+ (_a = inputRefs.current[0]) === null || _a === void 0 ? void 0 : _a.focus();
23
+ }
24
+ }, [autoFocus, disabled, readOnly]);
25
+ const handleChange = (index, newValue) => {
26
+ var _a;
27
+ if (disabled || readOnly)
28
+ return;
29
+ // Only allow single digit/letter
30
+ const sanitized = newValue.slice(-1);
31
+ const newCodes = [...codes];
32
+ newCodes[index] = sanitized;
33
+ setCodes(newCodes);
34
+ const fullValue = newCodes.join('');
35
+ onChange === null || onChange === void 0 ? void 0 : onChange(fullValue);
36
+ // Auto focus next input
37
+ if (sanitized && index < length - 1) {
38
+ (_a = inputRefs.current[index + 1]) === null || _a === void 0 ? void 0 : _a.focus();
39
+ }
40
+ // Call onComplete when all filled
41
+ if (fullValue.length === length) {
42
+ onComplete === null || onComplete === void 0 ? void 0 : onComplete(fullValue);
43
+ }
44
+ };
45
+ const handleKeyDown = (index, e) => {
46
+ var _a, _b, _c;
47
+ // Handle backspace
48
+ if (e.key === 'Backspace') {
49
+ if (disabled || readOnly)
50
+ return;
51
+ if (!codes[index] && index > 0) {
52
+ // If current is empty, focus previous
53
+ (_a = inputRefs.current[index - 1]) === null || _a === void 0 ? void 0 : _a.focus();
54
+ }
55
+ else {
56
+ // Clear current
57
+ const newCodes = [...codes];
58
+ newCodes[index] = '';
59
+ setCodes(newCodes);
60
+ onChange === null || onChange === void 0 ? void 0 : onChange(newCodes.join(''));
61
+ }
62
+ }
63
+ // Handle arrow keys
64
+ else if (e.key === 'ArrowLeft' && index > 0) {
65
+ (_b = inputRefs.current[index - 1]) === null || _b === void 0 ? void 0 : _b.focus();
66
+ }
67
+ else if (e.key === 'ArrowRight' && index < length - 1) {
68
+ (_c = inputRefs.current[index + 1]) === null || _c === void 0 ? void 0 : _c.focus();
69
+ }
70
+ };
71
+ const handlePaste = (e) => {
72
+ var _a;
73
+ if (disabled || readOnly)
74
+ return;
75
+ e.preventDefault();
76
+ const pastedData = e.clipboardData.getData('text').slice(0, length);
77
+ const newCodes = pastedData
78
+ .split('')
79
+ .concat(Array(length - pastedData.length).fill(''));
80
+ setCodes(newCodes);
81
+ onChange === null || onChange === void 0 ? void 0 : onChange(pastedData);
82
+ // Focus the next empty input or the last input
83
+ const nextEmptyIndex = Math.min(pastedData.length, length - 1);
84
+ (_a = inputRefs.current[nextEmptyIndex]) === null || _a === void 0 ? void 0 : _a.focus();
85
+ if (pastedData.length === length) {
86
+ onComplete === null || onComplete === void 0 ? void 0 : onComplete(pastedData);
87
+ }
88
+ };
89
+ const handleInputChange = (index, e) => {
90
+ handleChange(index, e.target.value);
91
+ };
92
+ return (jsxs("div", { ...rest, ref: ref, className: cx(modalClasses.modalBodyVerification, className), children: [jsx("div", { className: modalClasses.modalBodyVerificationInputs, children: Array.from({ length }).map((_, index) => (jsx("input", { ref: (el) => {
93
+ inputRefs.current[index] = el;
94
+ }, type: "text", inputMode: "numeric", maxLength: 1, value: codes[index] || '', onChange: (e) => handleInputChange(index, e), onKeyDown: (e) => handleKeyDown(index, e), onPaste: handlePaste, className: cx(modalClasses.modalBodyVerificationInput, {
95
+ [modalClasses.modalBodyVerificationInputError]: error,
96
+ }), autoComplete: "off", disabled: disabled, readOnly: readOnly }, index))) }), onResend && (jsxs("div", { className: modalClasses.modalBodyVerificationResend, children: [jsx(Typography, { variant: "caption", color: "text-neutral", children: resendPrompt }), jsx(Typography, { variant: "caption", color: "text-neutral", className: modalClasses.modalBodyVerificationResendLink, onClick: onResend, component: "span", style: { cursor: 'pointer', textDecoration: 'underline' }, children: resendText })] }))] }));
97
+ });
98
+
99
+ export { ModalBodyForVerification as default };
@@ -1,6 +1,6 @@
1
- import { ModalSeverity } from '@mezzanine-ui/core/modal';
1
+ import { ModalStatusType } from '@mezzanine-ui/core/modal';
2
2
  export interface ModalControl {
3
3
  loading: boolean;
4
- severity: ModalSeverity;
4
+ modalStatusType: ModalStatusType;
5
5
  }
6
6
  export declare const ModalControlContext: import("react").Context<ModalControl>;
@@ -3,7 +3,7 @@ import { createContext } from 'react';
3
3
 
4
4
  const ModalControlContext = createContext({
5
5
  loading: false,
6
- severity: 'info',
6
+ modalStatusType: 'info',
7
7
  });
8
8
 
9
9
  export { ModalControlContext };
@@ -1,5 +1,123 @@
1
+ import { ReactNode } from 'react';
1
2
  import { NativeElementPropsWithoutKeyAndRef } from '../utils/jsx-types';
2
- export type ModalFooterProps = NativeElementPropsWithoutKeyAndRef<'div'>;
3
+ import { ButtonProps } from '../Button/Button';
4
+ export interface ModalFooterProps extends NativeElementPropsWithoutKeyAndRef<'div'> {
5
+ /**
6
+ * Layout of action buttons.
7
+ * - 'fixed': Buttons maintain fixed width
8
+ * - 'fill': Buttons expand to fill available space equally
9
+ * @default 'fixed'
10
+ */
11
+ actionsButtonLayout?: 'fill' | 'fixed';
12
+ /**
13
+ * Text to display as annotation on the left side.
14
+ * Only used when auxiliaryContentType is 'annotation'.
15
+ */
16
+ annotation?: ReactNode;
17
+ /**
18
+ * Props for the auxiliary content button.
19
+ * Only used when auxiliaryContentType is 'button'.
20
+ */
21
+ auxiliaryContentButtonProps?: ButtonProps;
22
+ /**
23
+ * Text for the auxiliary content button.
24
+ * Only used when auxiliaryContentType is 'button'.
25
+ */
26
+ auxiliaryContentButtonText?: ReactNode;
27
+ /**
28
+ * Whether the auxiliary content control (checkbox/toggle) is checked.
29
+ * Only used when auxiliaryContentType is 'checkbox' or 'toggle'.
30
+ */
31
+ auxiliaryContentChecked?: boolean;
32
+ /**
33
+ * Label text for the auxiliary content control (checkbox/toggle).
34
+ * Only used when auxiliaryContentType is 'checkbox' or 'toggle'.
35
+ */
36
+ auxiliaryContentLabel?: string;
37
+ /**
38
+ * Change handler for auxiliary content control (checkbox/toggle).
39
+ * Only used when auxiliaryContentType is 'checkbox' or 'toggle'.
40
+ */
41
+ auxiliaryContentOnChange?: (checked: boolean) => void;
42
+ /**
43
+ * Click handler for the auxiliary content button.
44
+ * Only used when auxiliaryContentType is 'button'.
45
+ */
46
+ auxiliaryContentOnClick?: ButtonProps['onClick'];
47
+ /**
48
+ * Type of auxiliary content to show on the left side of the footer.
49
+ * - 'annotation': Display text annotation
50
+ * - 'button': Display a button
51
+ * - 'checkbox': Display a checkbox control
52
+ * - 'toggle': Display a toggle control
53
+ * - 'password': Display password-specific controls (remember me + forgot password)
54
+ * @default undefined (no auxiliary content)
55
+ */
56
+ auxiliaryContentType?: 'annotation' | 'button' | 'checkbox' | 'toggle' | 'password';
57
+ /**
58
+ * Additional props for the cancel button.
59
+ */
60
+ cancelButtonProps?: ButtonProps;
61
+ /**
62
+ * Text content of the cancel button.
63
+ */
64
+ cancelText?: ReactNode;
65
+ /**
66
+ * Additional props for the confirm button.
67
+ */
68
+ confirmButtonProps?: ButtonProps;
69
+ /**
70
+ * Text content of the confirm button.
71
+ */
72
+ confirmText?: ReactNode;
73
+ /**
74
+ * Whether confirm button is loading and cancel button is disabled.
75
+ */
76
+ loading?: boolean;
77
+ /**
78
+ * Click handler for the cancel button.
79
+ */
80
+ onCancel?: ButtonProps['onClick'];
81
+ /**
82
+ * Click handler for the confirm button.
83
+ */
84
+ onConfirm?: ButtonProps['onClick'];
85
+ /**
86
+ * Props for the password auxiliary button.
87
+ * Only used when auxiliaryContentType is 'password'.
88
+ */
89
+ passwordButtonProps?: ButtonProps;
90
+ /**
91
+ * Text for the password auxiliary button (e.g., "Forgot password?").
92
+ * Only used when auxiliaryContentType is 'password'.
93
+ */
94
+ passwordButtonText?: ReactNode;
95
+ /**
96
+ * Whether the password checkbox is checked (e.g., "Remember me").
97
+ * Only used when auxiliaryContentType is 'password'.
98
+ */
99
+ passwordChecked?: boolean;
100
+ /**
101
+ * Label for the password checkbox (e.g., "Remember me").
102
+ * Only used when auxiliaryContentType is 'password'.
103
+ */
104
+ passwordCheckedLabel?: string;
105
+ /**
106
+ * Change handler for the password checkbox.
107
+ * Only used when auxiliaryContentType is 'password'.
108
+ */
109
+ passwordCheckedOnChange?: (checked: boolean) => void;
110
+ /**
111
+ * Click handler for the password auxiliary button.
112
+ * Only used when auxiliaryContentType is 'password'.
113
+ */
114
+ passwordOnClick?: ButtonProps['onClick'];
115
+ /**
116
+ * Whether to show the cancel button.
117
+ * @default true
118
+ */
119
+ showCancelButton?: boolean;
120
+ }
3
121
  /**
4
122
  * The react component for `mezzanine` modal footer.
5
123
  */
@@ -1,14 +1,26 @@
1
- import { jsx } from 'react/jsx-runtime';
1
+ import { jsxs, jsx } from 'react/jsx-runtime';
2
2
  import { forwardRef } from 'react';
3
3
  import { modalClasses } from '@mezzanine-ui/core/modal';
4
+ import Button from '../Button/Button.js';
5
+ import ButtonGroup from '../Button/ButtonGroup.js';
6
+ import Checkbox from '../Checkbox/Checkbox.js';
7
+ import Toggle from '../Toggle/Toggle.js';
8
+ import Typography from '../Typography/Typography.js';
4
9
  import cx from 'clsx';
5
10
 
6
11
  /**
7
12
  * The react component for `mezzanine` modal footer.
8
13
  */
9
14
  const ModalFooter = forwardRef(function ModalFooter(props, ref) {
10
- const { children, className, ...rest } = props;
11
- return (jsx("div", { ...rest, ref: ref, className: cx(modalClasses.footer, className), children: children }));
15
+ const { children, className, actionsButtonLayout = 'fixed', annotation, auxiliaryContentButtonProps, auxiliaryContentButtonText, auxiliaryContentChecked, auxiliaryContentLabel, auxiliaryContentOnChange, auxiliaryContentOnClick, auxiliaryContentType, cancelButtonProps, cancelText, confirmButtonProps, confirmText, loading, onCancel, onConfirm, passwordButtonProps, passwordButtonText, passwordChecked, passwordCheckedLabel, passwordCheckedOnChange, passwordOnClick, showCancelButton = true, ...rest } = props;
16
+ const { disabled: cancelButtonDisabled = loading } = cancelButtonProps || {};
17
+ const isActionsButtonFillLayout = actionsButtonLayout === 'fill' && !auxiliaryContentType;
18
+ return (jsxs("div", { ...rest, ref: ref, className: cx(modalClasses.modalFooter, {
19
+ [modalClasses.modalFooter + '--password-mode']: auxiliaryContentType === 'password',
20
+ [modalClasses.modalFooter + '--with-auxiliary-content']: !!auxiliaryContentType && auxiliaryContentType !== 'password',
21
+ }, className), children: [auxiliaryContentType === 'password' && (jsxs("div", { className: modalClasses.modalFooterPasswordContainer, children: [jsx(Checkbox, { checked: passwordChecked, label: passwordCheckedLabel, onChange: (e) => passwordCheckedOnChange === null || passwordCheckedOnChange === void 0 ? void 0 : passwordCheckedOnChange(e.target.checked) }), jsx(Button, { variant: "base-text-link", ...passwordButtonProps, onClick: passwordOnClick, children: passwordButtonText })] })), auxiliaryContentType && auxiliaryContentType !== 'password' && (jsxs("div", { className: modalClasses.modalFooterAuxiliaryContentContainer, children: [auxiliaryContentType === 'annotation' && (jsx(Typography, { variant: "caption", color: "text-neutral", children: annotation })), auxiliaryContentType === 'button' && (jsx(Button, { variant: "base-text-link", ...auxiliaryContentButtonProps, onClick: auxiliaryContentOnClick, children: auxiliaryContentButtonText })), auxiliaryContentType === 'checkbox' && (jsx(Checkbox, { checked: auxiliaryContentChecked, label: auxiliaryContentLabel, onChange: (e) => auxiliaryContentOnChange === null || auxiliaryContentOnChange === void 0 ? void 0 : auxiliaryContentOnChange(e.target.checked) })), auxiliaryContentType === 'toggle' && (jsx(Toggle, { checked: auxiliaryContentChecked, label: auxiliaryContentLabel, onChange: (e) => auxiliaryContentOnChange === null || auxiliaryContentOnChange === void 0 ? void 0 : auxiliaryContentOnChange(e.target.checked) }))] })), jsxs(ButtonGroup, { className: cx(modalClasses.modalFooterActionsButtonContainer, {
22
+ [modalClasses.modalFooterActionsButtonContainer + '--fill-layout']: isActionsButtonFillLayout,
23
+ }), children: [showCancelButton && (jsx(Button, { variant: "base-secondary", ...cancelButtonProps, disabled: cancelButtonDisabled, onClick: onCancel, className: modalClasses.modalFooterActionsButton, children: cancelText })), jsx(Button, { variant: "base-primary", ...confirmButtonProps, loading: loading, onClick: onConfirm, className: modalClasses.modalFooterActionsButton, children: confirmText })] }), children] }));
12
24
  });
13
25
 
14
26
  export { ModalFooter as default };
@@ -1,19 +1,38 @@
1
1
  import { NativeElementPropsWithoutKeyAndRef } from '../utils/jsx-types';
2
2
  export interface ModalHeaderProps extends NativeElementPropsWithoutKeyAndRef<'div'> {
3
3
  /**
4
- * Whether to show severity icon.
4
+ * Whether to show status type icon.
5
5
  * @default false
6
6
  */
7
- showSeverityIcon?: boolean;
7
+ showStatusTypeIcon?: boolean;
8
8
  /**
9
- * Controlls the title styles.
10
- * Use large title if the modal body has section/block titles.
11
- * @default false
9
+ * Layout of the status type icon relative to title.
10
+ * - 'vertical': Icon above title
11
+ * - 'horizontal': Icon to the left of title
12
+ * @default 'vertical'
13
+ */
14
+ statusTypeIconLayout?: 'vertical' | 'horizontal';
15
+ /**
16
+ * Supporting text displayed below the title.
17
+ */
18
+ supportingText?: string;
19
+ /**
20
+ * Alignment of the supporting text.
21
+ * @default 'left'
22
+ */
23
+ supportingTextAlign?: 'left' | 'center';
24
+ /**
25
+ * The title text of the modal header.
26
+ */
27
+ title: string;
28
+ /**
29
+ * Alignment of the title.
30
+ * @default 'left'
12
31
  */
13
- titleLarge?: boolean;
32
+ titleAlign?: 'left' | 'center';
14
33
  }
15
34
  /**
16
- * The react component for `mezzanine` modal header.
35
+ * The React component for `mezzanine` modal header.
17
36
  */
18
37
  declare const ModalHeader: import("react").ForwardRefExoticComponent<ModalHeaderProps & import("react").RefAttributes<HTMLDivElement>>;
19
38
  export default ModalHeader;
@@ -1,20 +1,46 @@
1
1
  'use client';
2
2
  import { jsxs, jsx } from 'react/jsx-runtime';
3
3
  import { forwardRef, useContext } from 'react';
4
- import { modalSeverityIcons, modalClasses } from '@mezzanine-ui/core/modal';
4
+ import { modalStatusTypeIcons, modalClasses } from '@mezzanine-ui/core/modal';
5
5
  import { ModalControlContext } from './ModalControl.js';
6
+ import Typography from '../Typography/Typography.js';
6
7
  import Icon from '../Icon/Icon.js';
7
8
  import cx from 'clsx';
8
9
 
9
10
  /**
10
- * The react component for `mezzanine` modal header.
11
+ * The React component for `mezzanine` modal header.
11
12
  */
12
13
  const ModalHeader = forwardRef(function ModalHeader(props, ref) {
13
- const { children, className, showSeverityIcon = false, titleLarge = false, ...rest } = props;
14
- const { severity } = useContext(ModalControlContext);
15
- return (jsxs("div", { ...rest, ref: ref, className: cx(modalClasses.header, className), children: [showSeverityIcon && (jsx(Icon, { className: modalClasses.severityIcon, icon: modalSeverityIcons[severity] })), jsx("h3", { className: cx(modalClasses.title, {
16
- [modalClasses.titleLarge]: titleLarge,
17
- }), title: typeof children === 'string' ? children : undefined, children: children })] }));
14
+ const { className, showStatusTypeIcon = false, statusTypeIconLayout = 'vertical', supportingText, supportingTextAlign = 'left', title, titleAlign = 'left', ...rest } = props;
15
+ const { modalStatusType } = useContext(ModalControlContext);
16
+ const iconColor = (type) => {
17
+ switch (type) {
18
+ case 'success':
19
+ return 'success-strong';
20
+ case 'warning':
21
+ return 'warning';
22
+ case 'error':
23
+ return 'error-solid';
24
+ case 'info':
25
+ return 'info-strong';
26
+ case 'email':
27
+ return 'info-strong';
28
+ case 'delete':
29
+ return 'error-solid';
30
+ default:
31
+ return 'neutral';
32
+ }
33
+ };
34
+ return (jsxs("div", { ...rest, ref: ref, className: cx(modalClasses.modalHeader, {
35
+ [modalClasses.modalHeader + '--horizontal']: statusTypeIconLayout === 'horizontal',
36
+ [modalClasses.modalHeader + '--vertical']: statusTypeIconLayout === 'vertical',
37
+ [modalClasses.modalHeader + '--title-align-left']: titleAlign === 'left',
38
+ [modalClasses.modalHeader + '--title-align-center']: titleAlign === 'center',
39
+ [modalClasses.modalHeader + '--show-modal-status-type-icon']: showStatusTypeIcon,
40
+ }, className), children: [showStatusTypeIcon && (jsx("div", { className: cx(modalClasses.modalHeaderStatusTypeIcon), children: jsx(Icon, { icon: modalStatusTypeIcons[modalStatusType], color: iconColor(modalStatusType), size: 20 }) })), jsxs("div", { className: cx(modalClasses.modalHeaderTitleAndSupportingTextContainer), children: [jsx(Typography, { variant: "h3", color: "text-neutral-solid", className: cx(modalClasses.modalHeaderTitle), title: typeof title === 'string' ? title : undefined, children: title }), jsx(Typography, { variant: "body", color: "text-neutral-strong", className: cx(modalClasses.modalHeaderSupportingText, {
41
+ [modalClasses.modalHeaderSupportingText + '--align-left']: supportingTextAlign === 'left',
42
+ [modalClasses.modalHeaderSupportingText + '--align-center']: supportingTextAlign === 'center',
43
+ }), children: supportingText })] })] }));
18
44
  });
19
45
 
20
46
  export { ModalHeader as default };
package/Modal/index.d.ts CHANGED
@@ -1,12 +1,13 @@
1
- export type { ModalSeverity, ModalSize } from '@mezzanine-ui/core/modal';
2
- export type { ModalActionsProps } from './ModalActions';
3
- export { default as ModalActions } from './ModalActions';
4
- export type { ModalBodyProps } from './ModalBody';
5
- export { default as ModalBody } from './ModalBody';
1
+ export type { ModalStatusType, ModalSize } from '@mezzanine-ui/core/modal';
2
+ export type { ModalBodyForVerificationProps } from './ModalBodyForVerification';
3
+ export { default as ModalBodyForVerification } from './ModalBodyForVerification';
6
4
  export type { ModalFooterProps } from './ModalFooter';
7
5
  export { default as ModalFooter } from './ModalFooter';
8
6
  export type { ModalHeaderProps } from './ModalHeader';
9
7
  export { default as ModalHeader } from './ModalHeader';
8
+ export type { MediaPreviewModalProps } from './MediaPreviewModal';
9
+ export { default as MediaPreviewModal } from './MediaPreviewModal';
10
10
  export { default as useModalContainer } from './useModalContainer';
11
+ export type { ModalContainerProps } from './useModalContainer';
11
12
  export type { ModalProps } from './Modal';
12
13
  export { default } from './Modal';
package/Modal/index.js CHANGED
@@ -1,6 +1,6 @@
1
- export { default as ModalActions } from './ModalActions.js';
2
- export { default as ModalBody } from './ModalBody.js';
1
+ export { default as ModalBodyForVerification } from './ModalBodyForVerification.js';
3
2
  export { default as ModalFooter } from './ModalFooter.js';
4
3
  export { default as ModalHeader } from './ModalHeader.js';
4
+ export { default as MediaPreviewModal } from './MediaPreviewModal.js';
5
5
  export { default as useModalContainer } from './useModalContainer.js';
6
6
  export { default } from './Modal.js';