@mezzanine-ui/react 1.0.0-beta.6 → 1.0.0-beta.7
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/Accordion/Accordion.d.ts +23 -1
- package/Accordion/Accordion.js +59 -11
- package/Accordion/AccordionActions.d.ts +13 -0
- package/Accordion/AccordionActions.js +24 -0
- package/Accordion/AccordionContent.d.ts +9 -0
- package/Accordion/{AccordionDetails.js → AccordionContent.js} +4 -6
- package/Accordion/AccordionControlContext.d.ts +2 -2
- package/Accordion/AccordionGroup.d.ts +10 -0
- package/Accordion/AccordionGroup.js +26 -0
- package/Accordion/AccordionTitle.d.ts +14 -0
- package/Accordion/AccordionTitle.js +56 -0
- package/Accordion/index.d.ts +8 -4
- package/Accordion/index.js +4 -2
- package/AutoComplete/AutoComplete.d.ts +20 -6
- package/AutoComplete/AutoComplete.js +118 -30
- package/Backdrop/Backdrop.js +15 -19
- package/Calendar/CalendarDays.js +1 -1
- package/Card/BaseCard.d.ts +11 -0
- package/Card/BaseCard.js +48 -0
- package/Card/BaseCardSkeleton.d.ts +14 -0
- package/Card/BaseCardSkeleton.js +18 -0
- package/Card/CardGroup.d.ts +47 -0
- package/Card/CardGroup.js +147 -0
- package/Card/FourThumbnailCard.d.ts +14 -0
- package/Card/FourThumbnailCard.js +73 -0
- package/Card/FourThumbnailCardSkeleton.d.ts +14 -0
- package/Card/FourThumbnailCardSkeleton.js +20 -0
- package/Card/QuickActionCard.d.ts +12 -0
- package/Card/QuickActionCard.js +23 -0
- package/Card/QuickActionCardSkeleton.d.ts +14 -0
- package/Card/QuickActionCardSkeleton.js +18 -0
- package/Card/SingleThumbnailCard.d.ts +13 -0
- package/Card/SingleThumbnailCard.js +44 -0
- package/Card/SingleThumbnailCardSkeleton.d.ts +19 -0
- package/Card/SingleThumbnailCardSkeleton.js +18 -0
- package/Card/Thumbnail.d.ts +12 -0
- package/Card/Thumbnail.js +18 -0
- package/Card/ThumbnailCardInfo.d.ts +34 -0
- package/Card/ThumbnailCardInfo.js +43 -0
- package/Card/index.d.ts +43 -4
- package/Card/index.js +19 -2
- package/Card/typings.d.ts +442 -0
- package/Checkbox/Checkbox.d.ts +8 -0
- package/Checkbox/Checkbox.js +3 -2
- package/Checkbox/CheckboxGroup.js +1 -1
- package/ContentHeader/ContentHeader.d.ts +22 -70
- package/ContentHeader/ContentHeader.js +1 -1
- package/ContentHeader/ContentHeaderResponsive.d.ts +9 -0
- package/ContentHeader/ContentHeaderResponsive.js +7 -0
- package/ContentHeader/utils.d.ts +3 -3
- package/ContentHeader/utils.js +66 -20
- package/Cropper/Cropper.d.ts +66 -0
- package/Cropper/Cropper.js +115 -0
- package/Cropper/CropperElement.d.ts +10 -0
- package/Cropper/CropperElement.js +892 -0
- package/Cropper/index.d.ts +18 -0
- package/Cropper/index.js +8 -0
- package/Cropper/tools.d.ts +90 -0
- package/Cropper/tools.js +143 -0
- package/Cropper/typings.d.ts +69 -0
- package/Cropper/utils/cropper-calculations.d.ts +39 -0
- package/Cropper/utils/cropper-calculations.js +95 -0
- package/DateTimePicker/DateTimePicker.d.ts +1 -1
- package/DateTimePicker/DateTimePicker.js +14 -1
- package/Dropdown/Dropdown.d.ts +7 -1
- package/Dropdown/Dropdown.js +31 -14
- package/Dropdown/DropdownItem.d.ts +7 -1
- package/Dropdown/DropdownItem.js +36 -6
- package/Dropdown/DropdownItemCard.js +2 -1
- package/FloatingButton/FloatingButton.d.ts +21 -0
- package/FloatingButton/FloatingButton.js +18 -0
- package/FloatingButton/index.d.ts +2 -0
- package/FloatingButton/index.js +1 -0
- package/Form/FormField.d.ts +21 -10
- package/Form/FormField.js +12 -4
- package/Input/Input.js +9 -2
- package/Message/Message.js +1 -1
- package/MultipleDatePicker/MultipleDatePicker.js +2 -2
- package/Navigation/NavigationHeader.js +1 -1
- package/Picker/FormattedInput.d.ts +1 -1
- package/Picker/FormattedInput.js +2 -1
- package/Picker/PickerTriggerWithSeparator.d.ts +10 -0
- package/Picker/PickerTriggerWithSeparator.js +2 -2
- package/Picker/useDateInputFormatter.d.ts +6 -0
- package/Picker/useDateInputFormatter.js +4 -1
- package/Select/Select.d.ts +2 -8
- package/Select/Select.js +12 -33
- package/Select/SelectTrigger.js +21 -7
- package/Select/index.d.ts +0 -4
- package/Select/index.js +0 -2
- package/Select/typings.d.ts +0 -4
- package/Select/useSelectTriggerTags.d.ts +1 -1
- package/Select/useSelectTriggerTags.js +9 -6
- package/Separator/Separator.d.ts +14 -0
- package/Separator/Separator.js +17 -0
- package/Separator/index.d.ts +2 -0
- package/Separator/index.js +1 -0
- package/Table/utils/useTableRowSelection.js +6 -0
- package/Tag/TagGroup.d.ts +4 -2
- package/Tag/TagGroup.js +7 -4
- package/TextField/TextField.d.ts +1 -1
- package/TextField/TextField.js +63 -9
- package/TimePanel/TimePanelColumn.js +19 -12
- package/index.d.ts +27 -28
- package/index.js +23 -25
- package/package.json +4 -4
- package/Accordion/AccordionDetails.d.ts +0 -9
- package/Accordion/AccordionSummary.d.ts +0 -18
- package/Accordion/AccordionSummary.js +0 -51
- package/Alert/Alert.d.ts +0 -20
- package/Alert/Alert.js +0 -18
- package/Alert/index.d.ts +0 -3
- package/Alert/index.js +0 -1
- package/Card/Card.d.ts +0 -51
- package/Card/Card.js +0 -20
- package/Card/CardActions.d.ts +0 -34
- package/Card/CardActions.js +0 -15
- package/ConfirmActions/ConfirmActions.d.ts +0 -46
- package/ConfirmActions/ConfirmActions.js +0 -15
- package/ConfirmActions/index.d.ts +0 -2
- package/ConfirmActions/index.js +0 -1
- package/Select/Option.d.ts +0 -18
- package/Select/Option.js +0 -45
- package/Select/TreeSelect.d.ts +0 -72
- package/Select/TreeSelect.js +0 -205
- package/Tree/Tree.d.ts +0 -70
- package/Tree/Tree.js +0 -139
- package/Tree/TreeNode.d.ts +0 -40
- package/Tree/TreeNode.js +0 -50
- package/Tree/TreeNodeList.d.ts +0 -24
- package/Tree/TreeNodeList.js +0 -28
- package/Tree/getTreeNodeEntities.d.ts +0 -11
- package/Tree/getTreeNodeEntities.js +0 -92
- package/Tree/index.d.ts +0 -13
- package/Tree/index.js +0 -7
- package/Tree/toggleValue.d.ts +0 -4
- package/Tree/toggleValue.js +0 -19
- package/Tree/traverseTree.d.ts +0 -2
- package/Tree/traverseTree.js +0 -11
- package/Tree/typings.d.ts +0 -16
- package/Tree/useTreeExpandedValue.d.ts +0 -14
- package/Tree/useTreeExpandedValue.js +0 -33
package/ContentHeader/utils.js
CHANGED
|
@@ -1,17 +1,22 @@
|
|
|
1
1
|
import { jsx } from 'react/jsx-runtime';
|
|
2
|
-
import { isValidElement, cloneElement, Children } from 'react';
|
|
2
|
+
import { createElement, isValidElement, cloneElement, Children } from 'react';
|
|
3
3
|
import Button from '../Button/Button.js';
|
|
4
4
|
import { flattenChildren } from '../utils/flatten-children.js';
|
|
5
5
|
import { ChevronLeftIcon } from '@mezzanine-ui/icons';
|
|
6
|
+
import ContentHeaderResponsive from './ContentHeaderResponsive.js';
|
|
7
|
+
import { contentHeaderClasses } from '@mezzanine-ui/core/content-header';
|
|
6
8
|
import Input from '../Input/Input.js';
|
|
7
9
|
import Select from '../Select/Select.js';
|
|
10
|
+
import Toggle from '../Toggle/Toggle.js';
|
|
11
|
+
import Checkbox from '../Checkbox/Checkbox.js';
|
|
8
12
|
import Dropdown from '../Dropdown/Dropdown.js';
|
|
13
|
+
import cx from 'clsx';
|
|
9
14
|
|
|
10
15
|
/**
|
|
11
16
|
* Renders a button from either ButtonProps or a React element.
|
|
12
17
|
* Applies the specified size and variant to the button.
|
|
13
18
|
*/
|
|
14
|
-
const renderButton = (button, size) => {
|
|
19
|
+
const renderButton = (button, size, key) => {
|
|
15
20
|
if (!button) {
|
|
16
21
|
return null;
|
|
17
22
|
}
|
|
@@ -19,31 +24,41 @@ const renderButton = (button, size) => {
|
|
|
19
24
|
return cloneElement(button, {
|
|
20
25
|
size,
|
|
21
26
|
type: 'button',
|
|
27
|
+
key: button.key || key,
|
|
22
28
|
});
|
|
23
29
|
}
|
|
24
|
-
return
|
|
30
|
+
return (createElement(Button, { ...button, size: size, type: "button", key: key || button.title }));
|
|
25
31
|
};
|
|
26
32
|
const withSize = (target, size) => {
|
|
27
33
|
return cloneElement(target, { size });
|
|
28
34
|
};
|
|
29
|
-
const renderFilterProp = (
|
|
30
|
-
if (!
|
|
35
|
+
const renderFilterProp = (props, size) => {
|
|
36
|
+
if (!props) {
|
|
31
37
|
return null;
|
|
32
38
|
}
|
|
33
|
-
const { variant } =
|
|
39
|
+
const { variant } = props;
|
|
40
|
+
if ('size' in props) {
|
|
41
|
+
console.warn('[Mezzanine][ContentHeader]: size in ContentHeader filter is forced to match ContentHeader size.');
|
|
42
|
+
}
|
|
34
43
|
if (variant === 'search') {
|
|
35
|
-
return (jsx(Input, { ...
|
|
44
|
+
return (jsx(Input, { ...props, size: size, variant: "search" }));
|
|
36
45
|
}
|
|
37
46
|
if (variant === 'select') {
|
|
38
|
-
return jsx(Select, { ...
|
|
47
|
+
return jsx(Select, { ...props, size: size });
|
|
39
48
|
}
|
|
40
49
|
if (variant === 'segmentedControl') {
|
|
41
50
|
console.warn('SegmentedControl component is not implemented yet.');
|
|
42
51
|
return null;
|
|
43
52
|
}
|
|
53
|
+
if (variant === 'toggle') {
|
|
54
|
+
return jsx(Toggle, { ...props, size: size });
|
|
55
|
+
}
|
|
56
|
+
if (variant === 'checkbox') {
|
|
57
|
+
return jsx(Checkbox, { ...props });
|
|
58
|
+
}
|
|
44
59
|
return null;
|
|
45
60
|
};
|
|
46
|
-
const renderIconButtonWithProps = (child, size) => {
|
|
61
|
+
const renderIconButtonWithProps = (child, size, key) => {
|
|
47
62
|
const { icon } = child.props;
|
|
48
63
|
return cloneElement(child, {
|
|
49
64
|
icon,
|
|
@@ -51,13 +66,14 @@ const renderIconButtonWithProps = (child, size) => {
|
|
|
51
66
|
size,
|
|
52
67
|
variant: 'base-secondary',
|
|
53
68
|
type: 'button',
|
|
69
|
+
key: child.key || key,
|
|
54
70
|
});
|
|
55
71
|
};
|
|
56
72
|
const renderIconButtonsProp = (utilities, size) => {
|
|
57
73
|
const result = [];
|
|
58
|
-
utilities === null || utilities === void 0 ? void 0 : utilities.forEach((props) => {
|
|
74
|
+
utilities === null || utilities === void 0 ? void 0 : utilities.forEach((props, index) => {
|
|
59
75
|
if (props instanceof Object && 'icon' in props) {
|
|
60
|
-
result.push(
|
|
76
|
+
result.push(createElement(Button, { ...props, type: "button", size: size, iconType: "icon-only", variant: "base-secondary", key: props.id || props['aria-label'] || `utility-${index}` }));
|
|
61
77
|
}
|
|
62
78
|
if (props instanceof Object && 'options' in props) {
|
|
63
79
|
if (!isValidElement(props.children) ||
|
|
@@ -65,12 +81,12 @@ const renderIconButtonsProp = (utilities, size) => {
|
|
|
65
81
|
console.warn('[Mezzanine][ContentHeader]: Dropdown in utilities should have Button with icon as its children.');
|
|
66
82
|
return;
|
|
67
83
|
}
|
|
68
|
-
result.push(
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
84
|
+
result.push(createElement(Dropdown, { ...props, key: props.id || `utility-dropdown-${index}` }, cloneElement(props.children, {
|
|
85
|
+
type: 'button',
|
|
86
|
+
size: size,
|
|
87
|
+
iconType: 'icon-only',
|
|
88
|
+
variant: 'base-secondary',
|
|
89
|
+
})));
|
|
74
90
|
}
|
|
75
91
|
});
|
|
76
92
|
return result;
|
|
@@ -111,7 +127,7 @@ const renderActionsProp = (actions, size) => {
|
|
|
111
127
|
})
|
|
112
128
|
.sort((a, b) => variantOrder[a.variant || 'base-primary'] -
|
|
113
129
|
variantOrder[b.variant || 'base-primary'])
|
|
114
|
-
.map((v) => renderButton(v, size));
|
|
130
|
+
.map((v, index) => renderButton(v, size, `action-${index}`));
|
|
115
131
|
}
|
|
116
132
|
return null;
|
|
117
133
|
};
|
|
@@ -123,7 +139,29 @@ const resolveContentHeaderChild = (children, size) => {
|
|
|
123
139
|
let backButton = null;
|
|
124
140
|
if (children) {
|
|
125
141
|
const flatChildren = flattenChildren(children);
|
|
142
|
+
const responsiveChildren = [];
|
|
126
143
|
Children.forEach(flatChildren, (child) => {
|
|
144
|
+
if (isValidElement(child) && child.type === ContentHeaderResponsive) {
|
|
145
|
+
const props = child.props;
|
|
146
|
+
const breakpointClass = contentHeaderClasses.breakpoint(props.breakpoint);
|
|
147
|
+
Children.forEach(flattenChildren(props.children), (rwdChild) => {
|
|
148
|
+
if (isValidElement(rwdChild)) {
|
|
149
|
+
const rwdProps = rwdChild.props;
|
|
150
|
+
responsiveChildren.push(cloneElement(rwdChild, {
|
|
151
|
+
...rwdProps,
|
|
152
|
+
className: cx(breakpointClass, rwdProps === null || rwdProps === void 0 ? void 0 : rwdProps.className),
|
|
153
|
+
}));
|
|
154
|
+
}
|
|
155
|
+
else {
|
|
156
|
+
responsiveChildren.push(jsx("span", { className: breakpointClass, children: rwdChild }));
|
|
157
|
+
}
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
else {
|
|
161
|
+
responsiveChildren.push(child);
|
|
162
|
+
}
|
|
163
|
+
});
|
|
164
|
+
Children.forEach(responsiveChildren, (child) => {
|
|
127
165
|
if (!isValidElement(child)) {
|
|
128
166
|
return;
|
|
129
167
|
}
|
|
@@ -140,7 +178,8 @@ const resolveContentHeaderChild = (children, size) => {
|
|
|
140
178
|
}
|
|
141
179
|
// is filter
|
|
142
180
|
if ((type === Input && props.variant === 'search') ||
|
|
143
|
-
type === Select
|
|
181
|
+
type === Select ||
|
|
182
|
+
type === Toggle) {
|
|
144
183
|
if (filter) {
|
|
145
184
|
console.warn('[Mezzanine][ContentHeader]: ContentHeader only accepts one filter component.');
|
|
146
185
|
}
|
|
@@ -149,8 +188,15 @@ const resolveContentHeaderChild = (children, size) => {
|
|
|
149
188
|
else if (type.toString() === 'SegmentedControl') {
|
|
150
189
|
console.warn('SegmentedControl component is not implemented yet.');
|
|
151
190
|
}
|
|
191
|
+
else if (type === Checkbox) {
|
|
192
|
+
if (filter) {
|
|
193
|
+
console.warn('[Mezzanine][ContentHeader]: ContentHeader only accepts one filter component.');
|
|
194
|
+
}
|
|
195
|
+
filter = child;
|
|
196
|
+
}
|
|
197
|
+
else if (
|
|
152
198
|
// is utilities (icon button)
|
|
153
|
-
|
|
199
|
+
(type === Button && props.iconType === 'icon-only') ||
|
|
154
200
|
(type === Button &&
|
|
155
201
|
props.icon &&
|
|
156
202
|
!props.children)) {
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import type { ReactElement } from 'react';
|
|
2
|
+
import type { ModalProps } from '../Modal';
|
|
3
|
+
import { ComponentOverridableForwardRefComponentPropsFactory } from '../utils/jsx-types';
|
|
4
|
+
import { CropArea, CropperComponent, CropperPropsBase } from './typings';
|
|
5
|
+
export type CropperModalProps = Omit<ModalProps, 'children' | 'modalType' | 'extendedSplitLeftSideContent' | 'extendedSplitRightSideContent' | 'onCancel' | 'onConfirm' | 'showCancelButton' | 'showModalFooter' | 'showModalHeader' | 'confirmText' | 'title'> & {
|
|
6
|
+
/**
|
|
7
|
+
* The text for the cancel button.
|
|
8
|
+
*/
|
|
9
|
+
cancelText?: ModalProps['cancelText'];
|
|
10
|
+
/**
|
|
11
|
+
* The text for the confirm button.
|
|
12
|
+
* @default '確認'
|
|
13
|
+
*/
|
|
14
|
+
confirmText?: string;
|
|
15
|
+
/**
|
|
16
|
+
* Additional className for the cropper content wrapper.
|
|
17
|
+
*/
|
|
18
|
+
cropperContentClassName?: string;
|
|
19
|
+
/**
|
|
20
|
+
* Props for the CropperElement component.
|
|
21
|
+
*/
|
|
22
|
+
cropperProps?: CropperPropsBase;
|
|
23
|
+
/**
|
|
24
|
+
* Callback fired when the cancel button is clicked.
|
|
25
|
+
*/
|
|
26
|
+
onCancel?: () => void;
|
|
27
|
+
/**
|
|
28
|
+
* Callback fired when the confirm button is clicked.
|
|
29
|
+
* Receives the cropping context with canvas, cropArea, and imageSrc.
|
|
30
|
+
*/
|
|
31
|
+
onConfirm?: (context: CropperModalConfirmContext) => void | Promise<void>;
|
|
32
|
+
/**
|
|
33
|
+
* Whether to show the modal footer with confirm and cancel buttons.
|
|
34
|
+
* @default true
|
|
35
|
+
*/
|
|
36
|
+
showModalFooter?: boolean;
|
|
37
|
+
/**
|
|
38
|
+
* Whether to show the modal header.
|
|
39
|
+
* @default true
|
|
40
|
+
*/
|
|
41
|
+
showModalHeader?: boolean;
|
|
42
|
+
/**
|
|
43
|
+
* The title of the modal header.
|
|
44
|
+
* @default '圖片裁切'
|
|
45
|
+
*/
|
|
46
|
+
title?: string;
|
|
47
|
+
};
|
|
48
|
+
export interface CropperModalConfirmContext {
|
|
49
|
+
canvas: HTMLCanvasElement | null;
|
|
50
|
+
cropArea: CropArea | null;
|
|
51
|
+
imageSrc?: string | File | Blob;
|
|
52
|
+
}
|
|
53
|
+
export type CropperModalResult = CropperModalConfirmContext;
|
|
54
|
+
export type CropperModalOpenOptions = Omit<CropperModalProps, 'open'>;
|
|
55
|
+
export type CropperProps<C extends CropperComponent = 'div'> = ComponentOverridableForwardRefComponentPropsFactory<CropperComponent, C, CropperPropsBase>;
|
|
56
|
+
/**
|
|
57
|
+
* The react component for `mezzanine` cropper.
|
|
58
|
+
*/
|
|
59
|
+
declare const Cropper: import("react").ForwardRefExoticComponent<Omit<Omit<import("../utils/jsx-types").ComponentPropsWithoutKeyAndRef<"div">, keyof CropperPropsBase> & CropperPropsBase, "component"> & {
|
|
60
|
+
component?: CropperComponent | undefined;
|
|
61
|
+
} & import("react").RefAttributes<HTMLDivElement>>;
|
|
62
|
+
export type CropperModalType = ((props: CropperModalProps) => ReactElement | null) & {
|
|
63
|
+
open: (options: CropperModalOpenOptions) => Promise<CropperModalResult | null>;
|
|
64
|
+
};
|
|
65
|
+
export declare const CropperModal: CropperModalType;
|
|
66
|
+
export default Cropper;
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx } from 'react/jsx-runtime';
|
|
3
|
+
import { cropperClasses } from '@mezzanine-ui/core/cropper';
|
|
4
|
+
import { forwardRef, useState, useRef, useCallback } from 'react';
|
|
5
|
+
import CropperElement from './CropperElement.js';
|
|
6
|
+
import Modal from '../Modal/Modal.js';
|
|
7
|
+
import { createNotifier } from '../Notifier/createNotifier.js';
|
|
8
|
+
import cx from 'clsx';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* The react component for `mezzanine` cropper.
|
|
12
|
+
*/
|
|
13
|
+
const Cropper = forwardRef(function Cropper(props, ref) {
|
|
14
|
+
const { children, className, component: Component = 'div', size = 'main', ...rest } = props;
|
|
15
|
+
return (jsx(Component, { ...rest, ref: ref, className: cx(cropperClasses.host, cropperClasses.size(size), className), children: children }));
|
|
16
|
+
});
|
|
17
|
+
/**
|
|
18
|
+
* The react component for `mezzanine` cropper with modal wrapper.
|
|
19
|
+
*/
|
|
20
|
+
const CropperModalComponent = forwardRef(function CropperModal(props, ref) {
|
|
21
|
+
const { cropperProps, onConfirm, onClose, showModalFooter = true, showModalHeader = true, title = '圖片裁切', size = 'wide', confirmText = '確認', cancelText = '取消', onCancel, open = false, cropperContentClassName, ...restModalProps } = props;
|
|
22
|
+
const { aspectRatio, imageSrc, initialCropArea, minHeight, minWidth, onCropChange, onCropDragEnd, onImageDragEnd, onScaleChange, onImageLoad, onImageError, size: cropperSize = 'main', } = cropperProps !== null && cropperProps !== void 0 ? cropperProps : {};
|
|
23
|
+
const [currentCropArea, setCurrentCropArea] = useState(initialCropArea !== null && initialCropArea !== void 0 ? initialCropArea : null);
|
|
24
|
+
const canvasRef = useRef(null);
|
|
25
|
+
const handleCropChange = useCallback((area) => {
|
|
26
|
+
setCurrentCropArea(area);
|
|
27
|
+
onCropChange === null || onCropChange === void 0 ? void 0 : onCropChange(area);
|
|
28
|
+
}, [onCropChange]);
|
|
29
|
+
const handleCancel = useCallback(() => {
|
|
30
|
+
onCancel === null || onCancel === void 0 ? void 0 : onCancel();
|
|
31
|
+
onClose === null || onClose === void 0 ? void 0 : onClose();
|
|
32
|
+
}, [onCancel, onClose]);
|
|
33
|
+
const handleConfirm = useCallback(async () => {
|
|
34
|
+
try {
|
|
35
|
+
await (onConfirm === null || onConfirm === void 0 ? void 0 : onConfirm({
|
|
36
|
+
canvas: canvasRef.current,
|
|
37
|
+
cropArea: currentCropArea,
|
|
38
|
+
imageSrc,
|
|
39
|
+
}));
|
|
40
|
+
onClose === null || onClose === void 0 ? void 0 : onClose();
|
|
41
|
+
}
|
|
42
|
+
catch (error) {
|
|
43
|
+
console.error('CropperModal onConfirm failed:', error);
|
|
44
|
+
}
|
|
45
|
+
}, [currentCropArea, imageSrc, onClose, onConfirm]);
|
|
46
|
+
const modalFooterProps = showModalFooter
|
|
47
|
+
? {
|
|
48
|
+
showModalFooter: true,
|
|
49
|
+
confirmText,
|
|
50
|
+
showCancelButton: true,
|
|
51
|
+
cancelText,
|
|
52
|
+
onCancel: handleCancel,
|
|
53
|
+
onConfirm: handleConfirm,
|
|
54
|
+
}
|
|
55
|
+
: {
|
|
56
|
+
showModalFooter: false,
|
|
57
|
+
};
|
|
58
|
+
const modalHeaderProps = showModalHeader
|
|
59
|
+
? {
|
|
60
|
+
showModalHeader: true,
|
|
61
|
+
title,
|
|
62
|
+
}
|
|
63
|
+
: {
|
|
64
|
+
showModalHeader: false,
|
|
65
|
+
};
|
|
66
|
+
return (jsx(Modal, { modalType: "standard", onClose: onClose, open: open, ref: ref, size: size, ...restModalProps, ...modalHeaderProps, ...modalFooterProps, children: jsx(CropperElement, { className: cx(cropperClasses.content, cropperContentClassName), aspectRatio: aspectRatio, imageSrc: imageSrc, initialCropArea: initialCropArea, minHeight: minHeight, minWidth: minWidth, onCropChange: handleCropChange, onCropDragEnd: onCropDragEnd, onImageDragEnd: onImageDragEnd, onScaleChange: onScaleChange, onImageLoad: onImageLoad, onImageError: onImageError, ref: canvasRef, size: cropperSize }) }));
|
|
67
|
+
});
|
|
68
|
+
const CropperModal = CropperModalComponent;
|
|
69
|
+
const CropperModalNotifier = (props) => {
|
|
70
|
+
const { instanceKey, notifierKey, onCancel, onClose, onConfirm, resolve, maxCount: _maxCount, duration: _duration, ...rest } = props;
|
|
71
|
+
const resolvedRef = useRef(false);
|
|
72
|
+
const resolveOnce = useCallback((result) => {
|
|
73
|
+
if (resolvedRef.current)
|
|
74
|
+
return;
|
|
75
|
+
resolvedRef.current = true;
|
|
76
|
+
resolve(result);
|
|
77
|
+
cropperModalNotifier.remove(instanceKey !== null && instanceKey !== void 0 ? instanceKey : notifierKey);
|
|
78
|
+
}, [instanceKey, notifierKey, resolve]);
|
|
79
|
+
const handleClose = useCallback(() => {
|
|
80
|
+
onClose === null || onClose === void 0 ? void 0 : onClose();
|
|
81
|
+
resolveOnce(null);
|
|
82
|
+
}, [onClose, resolveOnce]);
|
|
83
|
+
const handleConfirm = useCallback(async (context) => {
|
|
84
|
+
try {
|
|
85
|
+
await (onConfirm === null || onConfirm === void 0 ? void 0 : onConfirm(context));
|
|
86
|
+
resolveOnce(context);
|
|
87
|
+
}
|
|
88
|
+
catch (error) {
|
|
89
|
+
console.error('CropperModalNotifier onConfirm failed:', error);
|
|
90
|
+
resolveOnce(null);
|
|
91
|
+
}
|
|
92
|
+
}, [onConfirm, resolveOnce]);
|
|
93
|
+
const mergedModalProps = {
|
|
94
|
+
...rest,
|
|
95
|
+
onCancel,
|
|
96
|
+
onClose: handleClose,
|
|
97
|
+
onConfirm: handleConfirm,
|
|
98
|
+
open: true,
|
|
99
|
+
};
|
|
100
|
+
return (jsx(CropperModal, { ...mergedModalProps }));
|
|
101
|
+
};
|
|
102
|
+
const cropperModalNotifier = createNotifier({
|
|
103
|
+
render: (notifierProps) => {
|
|
104
|
+
const { key, ...restProps } = notifierProps;
|
|
105
|
+
return (jsx(CropperModalNotifier, { ...restProps, notifierKey: key }));
|
|
106
|
+
},
|
|
107
|
+
});
|
|
108
|
+
CropperModal.open = (options) => new Promise((resolve) => {
|
|
109
|
+
cropperModalNotifier.add({
|
|
110
|
+
...options,
|
|
111
|
+
resolve,
|
|
112
|
+
});
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
export { CropperModal, Cropper as default };
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { ComponentOverridableForwardRefComponentPropsFactory } from '../utils/jsx-types';
|
|
2
|
+
import { CropperElementComponent, CropperPropsBase } from './typings';
|
|
3
|
+
export type CropperElementProps<C extends CropperElementComponent = 'canvas'> = ComponentOverridableForwardRefComponentPropsFactory<CropperElementComponent, C, CropperPropsBase>;
|
|
4
|
+
/**
|
|
5
|
+
* The react component for `mezzanine` cropper element (canvas).
|
|
6
|
+
*/
|
|
7
|
+
declare const CropperElement: import("react").ForwardRefExoticComponent<Omit<Omit<import("../utils/jsx-types").ComponentPropsWithoutKeyAndRef<"canvas">, keyof CropperPropsBase> & CropperPropsBase, "component"> & {
|
|
8
|
+
component?: "canvas" | undefined;
|
|
9
|
+
} & import("react").RefAttributes<HTMLCanvasElement>>;
|
|
10
|
+
export default CropperElement;
|