@expcat/tigercat-react 0.3.69 → 0.3.70

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 (39) hide show
  1. package/dist/chunk-2EOXY2LP.mjs +353 -0
  2. package/dist/chunk-5CLXOFRZ.mjs +248 -0
  3. package/dist/chunk-6W6CRBBG.mjs +169 -0
  4. package/dist/chunk-EHYSER2Z.js +144 -0
  5. package/dist/chunk-GNMOOYHG.js +250 -0
  6. package/dist/chunk-NV3JUZ3N.js +57 -0
  7. package/dist/chunk-QFYS5QIZ.mjs +142 -0
  8. package/dist/chunk-QIJG42YQ.mjs +54 -0
  9. package/dist/chunk-U3JOBIDU.js +355 -0
  10. package/dist/chunk-Z7SXK2KO.js +171 -0
  11. package/dist/components/ActivityFeed.js +4 -4
  12. package/dist/components/ActivityFeed.mjs +2 -2
  13. package/dist/components/CropUpload.d.mts +52 -0
  14. package/dist/components/CropUpload.d.ts +52 -0
  15. package/dist/components/CropUpload.js +14 -0
  16. package/dist/components/CropUpload.mjs +5 -0
  17. package/dist/components/Image.d.mts +20 -0
  18. package/dist/components/Image.d.ts +20 -0
  19. package/dist/components/Image.js +13 -0
  20. package/dist/components/Image.mjs +4 -0
  21. package/dist/components/ImageCropper.d.mts +21 -0
  22. package/dist/components/ImageCropper.d.ts +21 -0
  23. package/dist/components/ImageCropper.js +10 -0
  24. package/dist/components/ImageCropper.mjs +1 -0
  25. package/dist/components/ImageGroup.d.mts +30 -0
  26. package/dist/components/ImageGroup.d.ts +30 -0
  27. package/dist/components/ImageGroup.js +16 -0
  28. package/dist/components/ImageGroup.mjs +3 -0
  29. package/dist/components/ImagePreview.d.mts +20 -0
  30. package/dist/components/ImagePreview.d.ts +20 -0
  31. package/dist/components/ImagePreview.js +11 -0
  32. package/dist/components/ImagePreview.mjs +2 -0
  33. package/dist/index.d.mts +5 -0
  34. package/dist/index.d.ts +5 -0
  35. package/dist/index.js +105 -76
  36. package/dist/index.mjs +22 -17
  37. package/package.json +2 -2
  38. package/dist/{chunk-MTL2QUM3.mjs → chunk-FTY2W4L2.mjs} +1 -1
  39. package/dist/{chunk-J3HKED4B.js → chunk-IOM7DWWQ.js} +1 -1
@@ -0,0 +1,142 @@
1
+ import { Modal } from './chunk-JNLX47UL.mjs';
2
+ import { ImageCropper } from './chunk-2EOXY2LP.mjs';
3
+ import { Button } from './chunk-ENSLMM3L.mjs';
4
+ import { useRef, useState, useCallback, useMemo } from 'react';
5
+ import { classNames, cropUploadTriggerDisabledClasses, cropUploadTriggerClasses, uploadPlusIconPath } from '@expcat/tigercat-core';
6
+ import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
7
+
8
+ var CropUpload = ({
9
+ accept = "image/*",
10
+ disabled = false,
11
+ maxSize,
12
+ cropperProps,
13
+ modalTitle = "\u88C1\u526A\u56FE\u7247",
14
+ modalWidth = 520,
15
+ className,
16
+ children,
17
+ onCropComplete,
18
+ onError
19
+ }) => {
20
+ const fileInputRef = useRef(null);
21
+ const cropperRef = useRef(null);
22
+ const [modalVisible, setModalVisible] = useState(false);
23
+ const [imageSrc, setImageSrc] = useState("");
24
+ const [cropping, setCropping] = useState(false);
25
+ const handleTriggerClick = useCallback(() => {
26
+ if (disabled) return;
27
+ fileInputRef.current?.click();
28
+ }, [disabled]);
29
+ const handleFileChange = useCallback(
30
+ (e) => {
31
+ const file = e.target.files?.[0];
32
+ if (!file) return;
33
+ if (maxSize && file.size > maxSize) {
34
+ onError?.(new Error(`File size exceeds maximum of ${maxSize} bytes`));
35
+ e.target.value = "";
36
+ return;
37
+ }
38
+ const reader = new FileReader();
39
+ reader.onload = (ev) => {
40
+ setImageSrc(ev.target?.result);
41
+ setModalVisible(true);
42
+ };
43
+ reader.readAsDataURL(file);
44
+ e.target.value = "";
45
+ },
46
+ [maxSize, onError]
47
+ );
48
+ const handleConfirm = useCallback(async () => {
49
+ if (!cropperRef.current) return;
50
+ setCropping(true);
51
+ try {
52
+ const result = await cropperRef.current.getCropResult();
53
+ onCropComplete?.(result);
54
+ setModalVisible(false);
55
+ } catch (err) {
56
+ onError?.(err);
57
+ } finally {
58
+ setCropping(false);
59
+ }
60
+ }, [onCropComplete, onError]);
61
+ const handleCancel = useCallback(() => {
62
+ setModalVisible(false);
63
+ setImageSrc("");
64
+ }, []);
65
+ const triggerClasses = useMemo(
66
+ () => classNames(disabled ? cropUploadTriggerDisabledClasses : cropUploadTriggerClasses, className),
67
+ [disabled, className]
68
+ );
69
+ const handleKeyDown = useCallback(
70
+ (e) => {
71
+ if (e.key === "Enter" || e.key === " ") {
72
+ e.preventDefault();
73
+ handleTriggerClick();
74
+ }
75
+ },
76
+ [handleTriggerClick]
77
+ );
78
+ return /* @__PURE__ */ jsxs("div", { className: "tiger-crop-upload inline-block", children: [
79
+ /* @__PURE__ */ jsx(
80
+ "input",
81
+ {
82
+ ref: fileInputRef,
83
+ type: "file",
84
+ accept,
85
+ style: { display: "none" },
86
+ onChange: handleFileChange
87
+ }
88
+ ),
89
+ /* @__PURE__ */ jsx(
90
+ "div",
91
+ {
92
+ className: triggerClasses,
93
+ onClick: handleTriggerClick,
94
+ role: "button",
95
+ tabIndex: disabled ? -1 : 0,
96
+ "aria-label": "Select image to crop and upload",
97
+ "aria-disabled": disabled ? "true" : void 0,
98
+ onKeyDown: handleKeyDown,
99
+ children: children || /* @__PURE__ */ jsxs(Fragment, { children: [
100
+ /* @__PURE__ */ jsx(
101
+ "svg",
102
+ {
103
+ className: "w-5 h-5",
104
+ xmlns: "http://www.w3.org/2000/svg",
105
+ fill: "none",
106
+ viewBox: "0 0 24 24",
107
+ stroke: "currentColor",
108
+ children: /* @__PURE__ */ jsx(
109
+ "path",
110
+ {
111
+ strokeLinecap: "round",
112
+ strokeLinejoin: "round",
113
+ strokeWidth: "2",
114
+ d: uploadPlusIconPath
115
+ }
116
+ )
117
+ }
118
+ ),
119
+ /* @__PURE__ */ jsx("span", { children: "\u9009\u62E9\u56FE\u7247" })
120
+ ] })
121
+ }
122
+ ),
123
+ /* @__PURE__ */ jsx(
124
+ Modal,
125
+ {
126
+ visible: modalVisible,
127
+ size: "lg",
128
+ title: modalTitle,
129
+ closable: true,
130
+ maskClosable: false,
131
+ onClose: handleCancel,
132
+ footer: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-end gap-3", children: [
133
+ /* @__PURE__ */ jsx(Button, { variant: "secondary", onClick: handleCancel, children: "\u53D6\u6D88" }),
134
+ /* @__PURE__ */ jsx(Button, { onClick: handleConfirm, loading: cropping, children: "\u786E\u8BA4\u88C1\u526A" })
135
+ ] }),
136
+ children: imageSrc && /* @__PURE__ */ jsx(ImageCropper, { ref: cropperRef, src: imageSrc, ...cropperProps })
137
+ }
138
+ )
139
+ ] });
140
+ };
141
+
142
+ export { CropUpload };
@@ -0,0 +1,54 @@
1
+ import { ImagePreview } from './chunk-5CLXOFRZ.mjs';
2
+ import { createContext, useState, useRef, useCallback, useMemo } from 'react';
3
+ import { jsx, jsxs } from 'react/jsx-runtime';
4
+
5
+ var ImageGroupContext = createContext(null);
6
+ var ImageGroup = ({
7
+ preview = true,
8
+ onPreviewVisibleChange,
9
+ children,
10
+ className
11
+ }) => {
12
+ const [previewVisible, setPreviewVisible] = useState(false);
13
+ const [previewIndex, setPreviewIndex] = useState(0);
14
+ const imagesRef = useRef([]);
15
+ const register = useCallback((src) => {
16
+ const idx = imagesRef.current.length;
17
+ imagesRef.current = [...imagesRef.current, src];
18
+ return idx;
19
+ }, []);
20
+ const unregister = useCallback((src) => {
21
+ imagesRef.current = imagesRef.current.filter((s) => s !== src);
22
+ }, []);
23
+ const openPreview = useCallback(
24
+ (index) => {
25
+ if (!preview) return;
26
+ setPreviewIndex(index);
27
+ setPreviewVisible(true);
28
+ onPreviewVisibleChange?.(true);
29
+ },
30
+ [preview, onPreviewVisibleChange]
31
+ );
32
+ const contextValue = useMemo(
33
+ () => ({ register, unregister, openPreview }),
34
+ [register, unregister, openPreview]
35
+ );
36
+ return /* @__PURE__ */ jsx(ImageGroupContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsxs("div", { className: className || "tiger-image-group", role: "group", children: [
37
+ children,
38
+ preview && /* @__PURE__ */ jsx(
39
+ ImagePreview,
40
+ {
41
+ visible: previewVisible,
42
+ images: imagesRef.current,
43
+ currentIndex: previewIndex,
44
+ onVisibleChange: (val) => {
45
+ setPreviewVisible(val);
46
+ if (!val) onPreviewVisibleChange?.(false);
47
+ },
48
+ onCurrentIndexChange: setPreviewIndex
49
+ }
50
+ )
51
+ ] }) });
52
+ };
53
+
54
+ export { ImageGroup, ImageGroupContext };
@@ -0,0 +1,355 @@
1
+ 'use strict';
2
+
3
+ var react = require('react');
4
+ var tigercatCore = require('@expcat/tigercat-core');
5
+ var jsxRuntime = require('react/jsx-runtime');
6
+
7
+ // src/components/ImageCropper.tsx
8
+ var ImageCropper = react.forwardRef(
9
+ ({
10
+ src,
11
+ aspectRatio,
12
+ minWidth = 20,
13
+ minHeight = 20,
14
+ outputType = "image/png",
15
+ quality = 0.92,
16
+ guides = true,
17
+ className,
18
+ style,
19
+ onCropChange,
20
+ onReady
21
+ }, ref) => {
22
+ const containerRef = react.useRef(null);
23
+ const imageRef = react.useRef(null);
24
+ const [imageLoaded, setImageLoaded] = react.useState(false);
25
+ const [displayWidth, setDisplayWidth] = react.useState(0);
26
+ const [displayHeight, setDisplayHeight] = react.useState(0);
27
+ const [cropRect, setCropRect] = react.useState({ x: 0, y: 0, width: 0, height: 0 });
28
+ const dragModeRef = react.useRef("none");
29
+ const activeHandleRef = react.useRef(null);
30
+ const dragStartPosRef = react.useRef({ x: 0, y: 0 });
31
+ const dragStartRectRef = react.useRef({ x: 0, y: 0, width: 0, height: 0 });
32
+ const displayDimsRef = react.useRef({ w: 0, h: 0 });
33
+ react.useEffect(() => {
34
+ displayDimsRef.current = { w: displayWidth, h: displayHeight };
35
+ }, [displayWidth, displayHeight]);
36
+ react.useEffect(() => {
37
+ setImageLoaded(false);
38
+ const img = new window.Image();
39
+ img.crossOrigin = "anonymous";
40
+ img.onload = () => {
41
+ imageRef.current = img;
42
+ const container = containerRef.current;
43
+ const containerW = container ? container.clientWidth : img.naturalWidth;
44
+ const containerH = container ? container.clientHeight || 400 : img.naturalHeight;
45
+ const ratio = Math.min(containerW / img.naturalWidth, containerH / img.naturalHeight, 1);
46
+ const dw = img.naturalWidth * ratio;
47
+ const dh = img.naturalHeight * ratio;
48
+ setDisplayWidth(dw);
49
+ setDisplayHeight(dh);
50
+ displayDimsRef.current = { w: dw, h: dh };
51
+ const initial = tigercatCore.getInitialCropRect(dw, dh, aspectRatio);
52
+ setCropRect(initial);
53
+ setImageLoaded(true);
54
+ onReady?.();
55
+ };
56
+ img.src = src;
57
+ }, [src, aspectRatio, onReady]);
58
+ react.useImperativeHandle(
59
+ ref,
60
+ () => ({
61
+ getCropResult: () => {
62
+ return new Promise((resolve, reject) => {
63
+ if (!imageRef.current) {
64
+ reject(new Error("Image not loaded"));
65
+ return;
66
+ }
67
+ const { canvas, dataUrl } = tigercatCore.cropCanvas(
68
+ imageRef.current,
69
+ cropRect,
70
+ displayWidth,
71
+ displayHeight,
72
+ outputType,
73
+ quality
74
+ );
75
+ canvas.toBlob(
76
+ (blob) => {
77
+ if (blob) {
78
+ resolve({ canvas, blob, dataUrl, cropRect: { ...cropRect } });
79
+ } else {
80
+ reject(new Error("Failed to create blob"));
81
+ }
82
+ },
83
+ outputType,
84
+ quality
85
+ );
86
+ });
87
+ }
88
+ }),
89
+ [cropRect, displayWidth, displayHeight, outputType, quality]
90
+ );
91
+ const handleMouseDown = react.useCallback(
92
+ (e, mode, handle) => {
93
+ e.preventDefault();
94
+ e.stopPropagation();
95
+ dragModeRef.current = mode;
96
+ activeHandleRef.current = handle || null;
97
+ dragStartPosRef.current = { x: e.clientX, y: e.clientY };
98
+ dragStartRectRef.current = { ...cropRect };
99
+ const onMouseMove = (ev) => {
100
+ const dx = ev.clientX - dragStartPosRef.current.x;
101
+ const dy = ev.clientY - dragStartPosRef.current.y;
102
+ const dims = displayDimsRef.current;
103
+ let newRect;
104
+ if (dragModeRef.current === "move") {
105
+ newRect = tigercatCore.moveCropRect(dragStartRectRef.current, dx, dy, dims.w, dims.h);
106
+ } else {
107
+ newRect = tigercatCore.resizeCropRect(
108
+ dragStartRectRef.current,
109
+ activeHandleRef.current,
110
+ dx,
111
+ dy,
112
+ dims.w,
113
+ dims.h,
114
+ aspectRatio,
115
+ minWidth,
116
+ minHeight
117
+ );
118
+ }
119
+ setCropRect(newRect);
120
+ onCropChange?.(newRect);
121
+ };
122
+ const onMouseUp = () => {
123
+ dragModeRef.current = "none";
124
+ activeHandleRef.current = null;
125
+ document.removeEventListener("mousemove", onMouseMove);
126
+ document.removeEventListener("mouseup", onMouseUp);
127
+ };
128
+ document.addEventListener("mousemove", onMouseMove);
129
+ document.addEventListener("mouseup", onMouseUp);
130
+ },
131
+ [cropRect, aspectRatio, minWidth, minHeight, onCropChange]
132
+ );
133
+ const handleTouchStart = react.useCallback(
134
+ (e, mode, handle) => {
135
+ if (e.touches.length !== 1) return;
136
+ e.preventDefault();
137
+ e.stopPropagation();
138
+ const touch = e.touches[0];
139
+ dragModeRef.current = mode;
140
+ activeHandleRef.current = handle || null;
141
+ dragStartPosRef.current = { x: touch.clientX, y: touch.clientY };
142
+ dragStartRectRef.current = { ...cropRect };
143
+ const onTouchMove = (ev) => {
144
+ if (ev.touches.length !== 1) return;
145
+ const t = ev.touches[0];
146
+ const dx = t.clientX - dragStartPosRef.current.x;
147
+ const dy = t.clientY - dragStartPosRef.current.y;
148
+ const dims = displayDimsRef.current;
149
+ let newRect;
150
+ if (dragModeRef.current === "move") {
151
+ newRect = tigercatCore.moveCropRect(dragStartRectRef.current, dx, dy, dims.w, dims.h);
152
+ } else {
153
+ newRect = tigercatCore.resizeCropRect(
154
+ dragStartRectRef.current,
155
+ activeHandleRef.current,
156
+ dx,
157
+ dy,
158
+ dims.w,
159
+ dims.h,
160
+ aspectRatio,
161
+ minWidth,
162
+ minHeight
163
+ );
164
+ }
165
+ setCropRect(newRect);
166
+ onCropChange?.(newRect);
167
+ };
168
+ const onTouchEnd = () => {
169
+ dragModeRef.current = "none";
170
+ activeHandleRef.current = null;
171
+ document.removeEventListener("touchmove", onTouchMove);
172
+ document.removeEventListener("touchend", onTouchEnd);
173
+ };
174
+ document.addEventListener("touchmove", onTouchMove, { passive: false });
175
+ document.addEventListener("touchend", onTouchEnd);
176
+ },
177
+ [cropRect, aspectRatio, minWidth, minHeight, onCropChange]
178
+ );
179
+ const containerClasses = react.useMemo(
180
+ () => tigercatCore.classNames(tigercatCore.imageCropperContainerClasses, className),
181
+ [className]
182
+ );
183
+ const cr = cropRect;
184
+ if (!imageLoaded) {
185
+ return /* @__PURE__ */ jsxRuntime.jsx(
186
+ "div",
187
+ {
188
+ ref: containerRef,
189
+ className: tigercatCore.classNames(containerClasses, "flex items-center justify-center"),
190
+ style: { ...style, minHeight: "200px" },
191
+ role: "img",
192
+ "aria-label": "Loading image for cropping",
193
+ children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-8 h-8 border-2 border-white/30 border-t-white rounded-full animate-spin" })
194
+ }
195
+ );
196
+ }
197
+ return /* @__PURE__ */ jsxRuntime.jsxs(
198
+ "div",
199
+ {
200
+ ref: containerRef,
201
+ className: containerClasses,
202
+ style: {
203
+ ...style,
204
+ width: `${displayWidth}px`,
205
+ height: `${displayHeight}px`
206
+ },
207
+ role: "application",
208
+ "aria-label": "Image cropper",
209
+ "aria-roledescription": "image cropper",
210
+ children: [
211
+ /* @__PURE__ */ jsxRuntime.jsx(
212
+ "img",
213
+ {
214
+ src,
215
+ className: tigercatCore.imageCropperImgClasses,
216
+ style: { width: `${displayWidth}px`, height: `${displayHeight}px` },
217
+ draggable: false,
218
+ alt: "Image to crop"
219
+ }
220
+ ),
221
+ /* @__PURE__ */ jsxRuntime.jsxs(
222
+ "svg",
223
+ {
224
+ className: tigercatCore.imageCropperMaskClasses,
225
+ width: displayWidth,
226
+ height: displayHeight,
227
+ xmlns: "http://www.w3.org/2000/svg",
228
+ children: [
229
+ /* @__PURE__ */ jsxRuntime.jsx("defs", { children: /* @__PURE__ */ jsxRuntime.jsxs("mask", { id: "crop-mask", children: [
230
+ /* @__PURE__ */ jsxRuntime.jsx("rect", { width: displayWidth, height: displayHeight, fill: "white" }),
231
+ /* @__PURE__ */ jsxRuntime.jsx("rect", { x: cr.x, y: cr.y, width: cr.width, height: cr.height, fill: "black" })
232
+ ] }) }),
233
+ /* @__PURE__ */ jsxRuntime.jsx(
234
+ "rect",
235
+ {
236
+ width: displayWidth,
237
+ height: displayHeight,
238
+ fill: "var(--tiger-image-cropper-mask, rgba(0,0,0,0.55))",
239
+ mask: "url(#crop-mask)"
240
+ }
241
+ )
242
+ ]
243
+ }
244
+ ),
245
+ /* @__PURE__ */ jsxRuntime.jsx(
246
+ "div",
247
+ {
248
+ className: tigercatCore.imageCropperSelectionClasses,
249
+ style: {
250
+ left: `${cr.x}px`,
251
+ top: `${cr.y}px`,
252
+ width: `${cr.width}px`,
253
+ height: `${cr.height}px`
254
+ }
255
+ }
256
+ ),
257
+ /* @__PURE__ */ jsxRuntime.jsx(
258
+ "div",
259
+ {
260
+ className: tigercatCore.imageCropperDragAreaClasses,
261
+ style: {
262
+ left: `${cr.x}px`,
263
+ top: `${cr.y}px`,
264
+ width: `${cr.width}px`,
265
+ height: `${cr.height}px`
266
+ },
267
+ onMouseDown: (e) => handleMouseDown(e, "move"),
268
+ onTouchStart: (e) => handleTouchStart(e, "move")
269
+ }
270
+ ),
271
+ guides && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
272
+ /* @__PURE__ */ jsxRuntime.jsx(
273
+ "div",
274
+ {
275
+ className: tigercatCore.imageCropperGuideClasses,
276
+ style: {
277
+ left: `${cr.x}px`,
278
+ top: `${cr.y + cr.height / 3}px`,
279
+ width: `${cr.width}px`,
280
+ height: 0,
281
+ borderTopWidth: "1px",
282
+ borderTopStyle: "dashed"
283
+ }
284
+ }
285
+ ),
286
+ /* @__PURE__ */ jsxRuntime.jsx(
287
+ "div",
288
+ {
289
+ className: tigercatCore.imageCropperGuideClasses,
290
+ style: {
291
+ left: `${cr.x}px`,
292
+ top: `${cr.y + cr.height * 2 / 3}px`,
293
+ width: `${cr.width}px`,
294
+ height: 0,
295
+ borderTopWidth: "1px",
296
+ borderTopStyle: "dashed"
297
+ }
298
+ }
299
+ ),
300
+ /* @__PURE__ */ jsxRuntime.jsx(
301
+ "div",
302
+ {
303
+ className: tigercatCore.imageCropperGuideClasses,
304
+ style: {
305
+ left: `${cr.x + cr.width / 3}px`,
306
+ top: `${cr.y}px`,
307
+ width: 0,
308
+ height: `${cr.height}px`,
309
+ borderLeftWidth: "1px",
310
+ borderLeftStyle: "dashed"
311
+ }
312
+ }
313
+ ),
314
+ /* @__PURE__ */ jsxRuntime.jsx(
315
+ "div",
316
+ {
317
+ className: tigercatCore.imageCropperGuideClasses,
318
+ style: {
319
+ left: `${cr.x + cr.width * 2 / 3}px`,
320
+ top: `${cr.y}px`,
321
+ width: 0,
322
+ height: `${cr.height}px`,
323
+ borderLeftWidth: "1px",
324
+ borderLeftStyle: "dashed"
325
+ }
326
+ }
327
+ )
328
+ ] }),
329
+ tigercatCore.CROP_HANDLES.map((handle) => {
330
+ const pos = {};
331
+ if (handle.includes("n")) pos.top = `${cr.y}px`;
332
+ if (handle.includes("s")) pos.top = `${cr.y + cr.height}px`;
333
+ if (handle === "e" || handle === "w") pos.top = `${cr.y + cr.height / 2}px`;
334
+ if (handle.includes("w")) pos.left = `${cr.x}px`;
335
+ if (handle.includes("e")) pos.left = `${cr.x + cr.width}px`;
336
+ if (handle === "n" || handle === "s") pos.left = `${cr.x + cr.width / 2}px`;
337
+ return /* @__PURE__ */ jsxRuntime.jsx(
338
+ "div",
339
+ {
340
+ className: tigercatCore.getCropperHandleClasses(handle),
341
+ style: pos,
342
+ onMouseDown: (e) => handleMouseDown(e, "resize", handle),
343
+ onTouchStart: (e) => handleTouchStart(e, "resize", handle)
344
+ },
345
+ handle
346
+ );
347
+ })
348
+ ]
349
+ }
350
+ );
351
+ }
352
+ );
353
+ ImageCropper.displayName = "ImageCropper";
354
+
355
+ exports.ImageCropper = ImageCropper;