@wallarm-org/design-system 4.4.0 → 4.5.0

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 (26) hide show
  1. package/dist/components/ImageCropper/ImageCropper.d.ts +16 -0
  2. package/dist/components/ImageCropper/ImageCropper.js +360 -0
  3. package/dist/components/ImageCropper/ImageCropperContext.d.ts +7 -0
  4. package/dist/components/ImageCropper/ImageCropperContext.js +17 -0
  5. package/dist/components/ImageCropper/ImageCropperGrid.d.ts +7 -0
  6. package/dist/components/ImageCropper/ImageCropperGrid.js +83 -0
  7. package/dist/components/ImageCropper/ImageCropperImage.d.ts +6 -0
  8. package/dist/components/ImageCropper/ImageCropperImage.js +150 -0
  9. package/dist/components/ImageCropper/ImageCropperProvider.d.ts +37 -0
  10. package/dist/components/ImageCropper/ImageCropperProvider.js +46 -0
  11. package/dist/components/ImageCropper/ImageCropperSelection.d.ts +7 -0
  12. package/dist/components/ImageCropper/ImageCropperSelection.js +91 -0
  13. package/dist/components/ImageCropper/ImageCropperViewport.d.ts +9 -0
  14. package/dist/components/ImageCropper/ImageCropperViewport.js +135 -0
  15. package/dist/components/ImageCropper/index.d.ts +9 -0
  16. package/dist/components/ImageCropper/index.js +6 -0
  17. package/dist/components/ImageCropper/lib/exportCrop.d.ts +9 -0
  18. package/dist/components/ImageCropper/lib/exportCrop.js +20 -0
  19. package/dist/components/ImageCropper/lib/geometry.d.ts +23 -0
  20. package/dist/components/ImageCropper/lib/geometry.js +19 -0
  21. package/dist/components/ImageCropper/useCropperMachine.d.ts +9 -0
  22. package/dist/components/ImageCropper/useCropperMachine.js +60 -0
  23. package/dist/index.d.ts +1 -0
  24. package/dist/index.js +1 -0
  25. package/dist/metadata/components.json +1544 -2
  26. package/package.json +2 -1
@@ -0,0 +1,16 @@
1
+ import { type FC, type HTMLAttributes, type Ref } from 'react';
2
+ import { type TestableProps } from '../../utils/testId.js';
3
+ import { type ImageCropperSize } from './lib/geometry.js';
4
+ export interface ImageCropperProps extends HTMLAttributes<HTMLDivElement>, TestableProps {
5
+ /** Exact exported pixel dimensions; also determines the visible frame's aspect ratio. */
6
+ outputSize: ImageCropperSize;
7
+ zoom?: number;
8
+ defaultZoom?: number;
9
+ /** The minimum scale, relative to the image covering the frame. Must be at least 1. */
10
+ minZoom?: number;
11
+ maxZoom?: number;
12
+ onZoomChange?: (zoom: number) => void;
13
+ ref?: Ref<HTMLDivElement>;
14
+ }
15
+ /** Client-side image crop and resize. Compose a viewport, image, selection and external controls. */
16
+ export declare const ImageCropper: FC<ImageCropperProps>;
@@ -0,0 +1,360 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { c } from "react/compiler-runtime";
3
+ import { useLayoutEffect, useRef, useState } from "react";
4
+ import { ImageCropper } from "@ark-ui/react/image-cropper";
5
+ import { cn } from "../../utils/cn.js";
6
+ import { TestIdProvider } from "../../utils/testId.js";
7
+ import { ImageCropperProvider } from "./ImageCropperProvider.js";
8
+ import { exportCrop } from "./lib/exportCrop.js";
9
+ import { getCropperGeometry, validateOutputSize } from "./lib/geometry.js";
10
+ import { useCropperMachine } from "./useCropperMachine.js";
11
+ const ImageCropper_ImageCropper = (t0)=>{
12
+ const $ = c(101);
13
+ let children;
14
+ let className;
15
+ let id;
16
+ let onZoomChange;
17
+ let outputSize;
18
+ let props;
19
+ let ref;
20
+ let t1;
21
+ let t2;
22
+ let t3;
23
+ let testId;
24
+ let zoom;
25
+ if ($[0] !== t0) {
26
+ ({ outputSize, zoom, defaultZoom: t1, minZoom: t2, maxZoom: t3, onZoomChange, ref, id, className, children, "data-testid": testId, ...props } = t0);
27
+ $[0] = t0;
28
+ $[1] = children;
29
+ $[2] = className;
30
+ $[3] = id;
31
+ $[4] = onZoomChange;
32
+ $[5] = outputSize;
33
+ $[6] = props;
34
+ $[7] = ref;
35
+ $[8] = t1;
36
+ $[9] = t2;
37
+ $[10] = t3;
38
+ $[11] = testId;
39
+ $[12] = zoom;
40
+ } else {
41
+ children = $[1];
42
+ className = $[2];
43
+ id = $[3];
44
+ onZoomChange = $[4];
45
+ outputSize = $[5];
46
+ props = $[6];
47
+ ref = $[7];
48
+ t1 = $[8];
49
+ t2 = $[9];
50
+ t3 = $[10];
51
+ testId = $[11];
52
+ zoom = $[12];
53
+ }
54
+ const defaultZoom = void 0 === t1 ? 1 : t1;
55
+ const minZoom = void 0 === t2 ? 1 : t2;
56
+ const maxZoom = void 0 === t3 ? 5 : t3;
57
+ validateOutputSize(outputSize);
58
+ if (!Number.isFinite(minZoom) || !Number.isFinite(maxZoom) || minZoom < 1 || maxZoom < minZoom) throw new RangeError("ImageCropper requires 1 <= minZoom <= maxZoom.");
59
+ let t4;
60
+ if ($[13] === Symbol.for("react.memo_cache_sentinel")) {
61
+ t4 = {
62
+ width: 0,
63
+ height: 0
64
+ };
65
+ $[13] = t4;
66
+ } else t4 = $[13];
67
+ const [frameSize, setFrameSize] = useState(t4);
68
+ const [source, setSource] = useState(null);
69
+ const [image, setImage] = useState(null);
70
+ let t5;
71
+ if ($[14] === Symbol.for("react.memo_cache_sentinel")) {
72
+ t5 = {};
73
+ $[14] = t5;
74
+ } else t5 = $[14];
75
+ const [partIds, setPartIds] = useState(t5);
76
+ const sourceSize = source?.width && source.height ? source : outputSize;
77
+ let t6;
78
+ if ($[15] !== frameSize || $[16] !== sourceSize) {
79
+ t6 = getCropperGeometry(sourceSize, frameSize);
80
+ $[15] = frameSize;
81
+ $[16] = sourceSize;
82
+ $[17] = t6;
83
+ } else t6 = $[17];
84
+ const geometry = t6;
85
+ const controlledZoom = void 0 === zoom ? void 0 : Math.min(maxZoom, Math.max(minZoom, zoom));
86
+ if (void 0 !== controlledZoom && !Number.isFinite(controlledZoom)) throw new RangeError("ImageCropper zoom must be finite.");
87
+ let t7;
88
+ if ($[18] !== id || $[19] !== partIds) {
89
+ t7 = {
90
+ ...partIds,
91
+ root: id
92
+ };
93
+ $[18] = id;
94
+ $[19] = partIds;
95
+ $[20] = t7;
96
+ } else t7 = $[20];
97
+ const t8 = outputSize.width / outputSize.height;
98
+ const t9 = frameSize.width;
99
+ const t10 = frameSize.width;
100
+ const t11 = frameSize.height;
101
+ const t12 = frameSize.height;
102
+ const t13 = Math.min(maxZoom, Math.max(minZoom, defaultZoom));
103
+ let t14;
104
+ if ($[21] !== onZoomChange) {
105
+ t14 = (details)=>onZoomChange?.(details.zoom);
106
+ $[21] = onZoomChange;
107
+ $[22] = t14;
108
+ } else t14 = $[22];
109
+ let t15;
110
+ if ($[23] === Symbol.for("react.memo_cache_sentinel")) {
111
+ t15 = {
112
+ selectionInstructions: "Use arrow keys to position the image. Hold Shift for larger steps. Press plus or minus to zoom."
113
+ };
114
+ $[23] = t15;
115
+ } else t15 = $[23];
116
+ let t16;
117
+ if ($[24] !== controlledZoom || $[25] !== frameSize.height || $[26] !== frameSize.width || $[27] !== maxZoom || $[28] !== minZoom || $[29] !== t13 || $[30] !== t14 || $[31] !== t7 || $[32] !== t8) {
118
+ t16 = {
119
+ ids: t7,
120
+ fixedCropArea: true,
121
+ aspectRatio: t8,
122
+ minWidth: t9,
123
+ maxWidth: t10,
124
+ minHeight: t11,
125
+ maxHeight: t12,
126
+ minZoom,
127
+ maxZoom,
128
+ zoom: controlledZoom,
129
+ defaultZoom: t13,
130
+ onZoomChange: t14,
131
+ translations: t15
132
+ };
133
+ $[24] = controlledZoom;
134
+ $[25] = frameSize.height;
135
+ $[26] = frameSize.width;
136
+ $[27] = maxZoom;
137
+ $[28] = minZoom;
138
+ $[29] = t13;
139
+ $[30] = t14;
140
+ $[31] = t7;
141
+ $[32] = t8;
142
+ $[33] = t16;
143
+ } else t16 = $[33];
144
+ const ark = useCropperMachine(t16);
145
+ const measured = frameSize.width > 0 && frameSize.height > 0 && Math.abs(ark.viewportRect.width - geometry.viewport.width) < 0.5 && Math.abs(ark.viewportRect.height - geometry.viewport.height) < 0.5;
146
+ const resetKey = `${source?.src}:${source?.width}:${source?.height}:${frameSize.width}:${frameSize.height}:${outputSize.width / outputSize.height}`;
147
+ const lastReset = useRef("");
148
+ const lastSource = useRef(void 0);
149
+ let t17;
150
+ if ($[34] !== ark || $[35] !== measured || $[36] !== resetKey || $[37] !== source?.src) {
151
+ t17 = ()=>{
152
+ const sourceChanged = lastSource.current !== source?.src;
153
+ lastSource.current = source?.src;
154
+ if (!sourceChanged && (!measured || lastReset.current === resetKey)) return;
155
+ lastReset.current = measured ? resetKey : "";
156
+ ark.reset();
157
+ };
158
+ $[34] = ark;
159
+ $[35] = measured;
160
+ $[36] = resetKey;
161
+ $[37] = source?.src;
162
+ $[38] = t17;
163
+ } else t17 = $[38];
164
+ const t18 = source?.src;
165
+ let t19;
166
+ if ($[39] !== ark || $[40] !== measured || $[41] !== resetKey || $[42] !== t18) {
167
+ t19 = [
168
+ ark,
169
+ measured,
170
+ resetKey,
171
+ t18
172
+ ];
173
+ $[39] = ark;
174
+ $[40] = measured;
175
+ $[41] = resetKey;
176
+ $[42] = t18;
177
+ $[43] = t19;
178
+ } else t19 = $[43];
179
+ useLayoutEffect(t17, t19);
180
+ const ready = source?.status === "loaded" && source.width > 0 && source.height > 0 && ark.naturalSize.width === source.width && ark.naturalSize.height === source.height && measured && Math.abs(ark.crop.x - geometry.crop.x) < 0.5 && Math.abs(ark.crop.y - geometry.crop.y) < 0.5 && Math.abs(ark.crop.width - frameSize.width) < 0.5 && Math.abs(ark.crop.height - frameSize.height) < 0.5;
181
+ const sourceScale = geometry.viewport.width > 0 ? sourceSize.width / geometry.viewport.width : 1;
182
+ const cropWidth = frameSize.width * sourceScale / ark.zoom;
183
+ const cropHeight = frameSize.height * sourceScale / ark.zoom;
184
+ const sourceX = ((ark.crop.x - ark.offset.x - geometry.viewport.width / 2) / ark.zoom + geometry.viewport.width / 2) * sourceScale;
185
+ const sourceY = ((ark.crop.y - ark.offset.y - geometry.viewport.height / 2) / ark.zoom + geometry.viewport.height / 2) * sourceScale;
186
+ const horizontalRange = Math.max(0, sourceSize.width - cropWidth);
187
+ const verticalRange = Math.max(0, sourceSize.height - cropHeight);
188
+ const t20 = !ready || void 0;
189
+ const t21 = source?.status ?? "loading";
190
+ let t22;
191
+ if ($[44] !== className) {
192
+ t22 = cn("flex min-w-0 flex-col items-center gap-24", className);
193
+ $[44] = className;
194
+ $[45] = t22;
195
+ } else t22 = $[45];
196
+ const t23 = geometry.viewport;
197
+ let t24;
198
+ if ($[46] !== horizontalRange || $[47] !== sourceX || $[48] !== sourceY || $[49] !== verticalRange) {
199
+ t24 = Math.round(horizontalRange >= verticalRange ? sourceX : sourceY);
200
+ $[46] = horizontalRange;
201
+ $[47] = sourceX;
202
+ $[48] = sourceY;
203
+ $[49] = verticalRange;
204
+ $[50] = t24;
205
+ } else t24 = $[50];
206
+ const t25 = Math.max(0, t24);
207
+ let t26;
208
+ if ($[51] !== horizontalRange || $[52] !== verticalRange) {
209
+ t26 = Math.round(Math.max(horizontalRange, verticalRange));
210
+ $[51] = horizontalRange;
211
+ $[52] = verticalRange;
212
+ $[53] = t26;
213
+ } else t26 = $[53];
214
+ let t27;
215
+ if ($[54] !== sourceX) {
216
+ t27 = Math.round(sourceX);
217
+ $[54] = sourceX;
218
+ $[55] = t27;
219
+ } else t27 = $[55];
220
+ const t28 = Math.max(0, t27);
221
+ let t29;
222
+ if ($[56] !== sourceY) {
223
+ t29 = Math.round(sourceY);
224
+ $[56] = sourceY;
225
+ $[57] = t29;
226
+ } else t29 = $[57];
227
+ const t30 = Math.max(0, t29);
228
+ let t31;
229
+ if ($[58] !== ark.zoom) {
230
+ t31 = Math.round(100 * ark.zoom);
231
+ $[58] = ark.zoom;
232
+ $[59] = t31;
233
+ } else t31 = $[59];
234
+ const t32 = `Image position X ${t28}, Y ${t30} pixels. Zoom ${t31}%.`;
235
+ let t33;
236
+ if ($[60] !== t25 || $[61] !== t26 || $[62] !== t32) {
237
+ t33 = {
238
+ value: t25,
239
+ max: t26,
240
+ text: t32
241
+ };
242
+ $[60] = t25;
243
+ $[61] = t26;
244
+ $[62] = t32;
245
+ $[63] = t33;
246
+ } else t33 = $[63];
247
+ let t34;
248
+ if ($[64] !== ark || $[65] !== maxZoom || $[66] !== minZoom) {
249
+ t34 = (value)=>{
250
+ if (Number.isFinite(value)) ark.setZoom(Math.min(maxZoom, Math.max(minZoom, value)));
251
+ };
252
+ $[64] = ark;
253
+ $[65] = maxZoom;
254
+ $[66] = minZoom;
255
+ $[67] = t34;
256
+ } else t34 = $[67];
257
+ let t35;
258
+ if ($[68] !== ark || $[69] !== image || $[70] !== outputSize || $[71] !== ready || $[72] !== source?.src) {
259
+ t35 = async (options)=>{
260
+ if (!ready || !image || image.getAttribute("src") !== source?.src) return null;
261
+ const src = image.currentSrc || image.src;
262
+ const { topLeft, topRight, bottomLeft } = ark.getCropData().corners;
263
+ const blob = await exportCrop(image, {
264
+ x: topLeft.x,
265
+ y: topLeft.y,
266
+ width: topRight.x - topLeft.x,
267
+ height: bottomLeft.y - topLeft.y
268
+ }, outputSize, options);
269
+ return image.isConnected && (image.currentSrc || image.src) === src ? blob : null;
270
+ };
271
+ $[68] = ark;
272
+ $[69] = image;
273
+ $[70] = outputSize;
274
+ $[71] = ready;
275
+ $[72] = source?.src;
276
+ $[73] = t35;
277
+ } else t35 = $[73];
278
+ let t36;
279
+ if ($[74] !== ark.reset || $[75] !== ark.zoom || $[76] !== ready || $[77] !== t34 || $[78] !== t35) {
280
+ t36 = {
281
+ ready,
282
+ zoom: ark.zoom,
283
+ setZoom: t34,
284
+ reset: ark.reset,
285
+ getCroppedImage: t35
286
+ };
287
+ $[74] = ark.reset;
288
+ $[75] = ark.zoom;
289
+ $[76] = ready;
290
+ $[77] = t34;
291
+ $[78] = t35;
292
+ $[79] = t36;
293
+ } else t36 = $[79];
294
+ let t37;
295
+ if ($[80] !== geometry.viewport || $[81] !== outputSize || $[82] !== source || $[83] !== t33 || $[84] !== t36) {
296
+ t37 = {
297
+ outputSize,
298
+ viewportSize: t23,
299
+ source,
300
+ setSource,
301
+ setFrameSize,
302
+ setImage,
303
+ setPartIds,
304
+ selection: t33,
305
+ api: t36
306
+ };
307
+ $[80] = geometry.viewport;
308
+ $[81] = outputSize;
309
+ $[82] = source;
310
+ $[83] = t33;
311
+ $[84] = t36;
312
+ $[85] = t37;
313
+ } else t37 = $[85];
314
+ let t38;
315
+ if ($[86] !== children || $[87] !== t37) {
316
+ t38 = /*#__PURE__*/ jsx(ImageCropperProvider, {
317
+ value: t37,
318
+ children: children
319
+ });
320
+ $[86] = children;
321
+ $[87] = t37;
322
+ $[88] = t38;
323
+ } else t38 = $[88];
324
+ let t39;
325
+ if ($[89] !== t38 || $[90] !== testId) {
326
+ t39 = /*#__PURE__*/ jsx(TestIdProvider, {
327
+ value: testId,
328
+ children: t38
329
+ });
330
+ $[89] = t38;
331
+ $[90] = testId;
332
+ $[91] = t39;
333
+ } else t39 = $[91];
334
+ let t40;
335
+ if ($[92] !== ark || $[93] !== props || $[94] !== ref || $[95] !== t20 || $[96] !== t21 || $[97] !== t22 || $[98] !== t39 || $[99] !== testId) {
336
+ t40 = /*#__PURE__*/ jsx(ImageCropper.RootProvider, {
337
+ ...props,
338
+ value: ark,
339
+ ref: ref,
340
+ "aria-busy": t20,
341
+ "data-slot": "image-cropper",
342
+ "data-testid": testId,
343
+ "data-state": t21,
344
+ className: t22,
345
+ children: t39
346
+ });
347
+ $[92] = ark;
348
+ $[93] = props;
349
+ $[94] = ref;
350
+ $[95] = t20;
351
+ $[96] = t21;
352
+ $[97] = t22;
353
+ $[98] = t39;
354
+ $[99] = testId;
355
+ $[100] = t40;
356
+ } else t40 = $[100];
357
+ return t40;
358
+ };
359
+ ImageCropper_ImageCropper.displayName = "ImageCropper";
360
+ export { ImageCropper_ImageCropper as ImageCropper };
@@ -0,0 +1,7 @@
1
+ import type { FC, ReactNode } from 'react';
2
+ import { type ImageCropperApi } from './ImageCropperProvider.js';
3
+ export interface ImageCropperContextProps {
4
+ children: (api: ImageCropperApi) => ReactNode;
5
+ }
6
+ /** Compose Slider/FileUpload/Button controls using the current cropper state. */
7
+ export declare const ImageCropperContext: FC<ImageCropperContextProps>;
@@ -0,0 +1,17 @@
1
+ import { c } from "react/compiler-runtime";
2
+ import { useImageCropperInternal } from "./ImageCropperProvider.js";
3
+ const ImageCropperContext = (t0)=>{
4
+ const $ = c(3);
5
+ const { children } = t0;
6
+ const t1 = useImageCropperInternal();
7
+ let t2;
8
+ if ($[0] !== children || $[1] !== t1.api) {
9
+ t2 = children(t1.api);
10
+ $[0] = children;
11
+ $[1] = t1.api;
12
+ $[2] = t2;
13
+ } else t2 = $[2];
14
+ return t2;
15
+ };
16
+ ImageCropperContext.displayName = "ImageCropperContext";
17
+ export { ImageCropperContext };
@@ -0,0 +1,7 @@
1
+ import type { FC, HTMLAttributes, Ref } from 'react';
2
+ import { type TestableProps } from '../../utils/testId.js';
3
+ export interface ImageCropperGridProps extends HTMLAttributes<HTMLDivElement>, TestableProps {
4
+ ref?: Ref<HTMLDivElement>;
5
+ }
6
+ /** Optional rule-of-thirds guide, clipped by the viewport. */
7
+ export declare const ImageCropperGrid: FC<ImageCropperGridProps>;
@@ -0,0 +1,83 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { c } from "react/compiler-runtime";
3
+ import { cn } from "../../utils/cn.js";
4
+ import { useTestId } from "../../utils/testId.js";
5
+ const ImageCropperGrid = (t0)=>{
6
+ const $ = c(16);
7
+ let className;
8
+ let props;
9
+ let ref;
10
+ let testIdProp;
11
+ if ($[0] !== t0) {
12
+ ({ ref, className, "data-testid": testIdProp, ...props } = t0);
13
+ $[0] = t0;
14
+ $[1] = className;
15
+ $[2] = props;
16
+ $[3] = ref;
17
+ $[4] = testIdProp;
18
+ } else {
19
+ className = $[1];
20
+ props = $[2];
21
+ ref = $[3];
22
+ testIdProp = $[4];
23
+ }
24
+ const testId = useTestId("grid", testIdProp);
25
+ let t1;
26
+ if ($[5] !== className) {
27
+ t1 = cn("pointer-events-none absolute inset-0", className);
28
+ $[5] = className;
29
+ $[6] = t1;
30
+ } else t1 = $[6];
31
+ let t2;
32
+ let t3;
33
+ let t4;
34
+ let t5;
35
+ if ($[7] === Symbol.for("react.memo_cache_sentinel")) {
36
+ t2 = /*#__PURE__*/ jsx("span", {
37
+ className: "absolute inset-y-0 left-1/3 border-l border-border-primary/60"
38
+ });
39
+ t3 = /*#__PURE__*/ jsx("span", {
40
+ className: "absolute inset-y-0 left-2/3 border-l border-border-primary/60"
41
+ });
42
+ t4 = /*#__PURE__*/ jsx("span", {
43
+ className: "absolute inset-x-0 top-1/3 border-t border-border-primary/60"
44
+ });
45
+ t5 = /*#__PURE__*/ jsx("span", {
46
+ className: "absolute inset-x-0 top-2/3 border-t border-border-primary/60"
47
+ });
48
+ $[7] = t2;
49
+ $[8] = t3;
50
+ $[9] = t4;
51
+ $[10] = t5;
52
+ } else {
53
+ t2 = $[7];
54
+ t3 = $[8];
55
+ t4 = $[9];
56
+ t5 = $[10];
57
+ }
58
+ let t6;
59
+ if ($[11] !== props || $[12] !== ref || $[13] !== t1 || $[14] !== testId) {
60
+ t6 = /*#__PURE__*/ jsxs("div", {
61
+ ...props,
62
+ ref: ref,
63
+ "aria-hidden": "true",
64
+ "data-slot": "image-cropper-grid",
65
+ "data-testid": testId,
66
+ className: t1,
67
+ children: [
68
+ t2,
69
+ t3,
70
+ t4,
71
+ t5
72
+ ]
73
+ });
74
+ $[11] = props;
75
+ $[12] = ref;
76
+ $[13] = t1;
77
+ $[14] = testId;
78
+ $[15] = t6;
79
+ } else t6 = $[15];
80
+ return t6;
81
+ };
82
+ ImageCropperGrid.displayName = "ImageCropperGrid";
83
+ export { ImageCropperGrid };
@@ -0,0 +1,6 @@
1
+ import { type FC, type ImgHTMLAttributes, type Ref } from 'react';
2
+ import { type TestableProps } from '../../utils/testId.js';
3
+ export interface ImageCropperImageProps extends ImgHTMLAttributes<HTMLImageElement>, TestableProps {
4
+ ref?: Ref<HTMLImageElement>;
5
+ }
6
+ export declare const ImageCropperImage: FC<ImageCropperImageProps>;
@@ -0,0 +1,150 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { c } from "react/compiler-runtime";
3
+ import { useLayoutEffect, useState } from "react";
4
+ import { ImageCropper } from "@ark-ui/react/image-cropper";
5
+ import { useComposedRefs } from "@radix-ui/react-compose-refs";
6
+ import { cn } from "../../utils/cn.js";
7
+ import { useTestId } from "../../utils/testId.js";
8
+ import { useImageCropperInternal, useImageCropperPartId } from "./ImageCropperProvider.js";
9
+ const ImageCropperImage = (t0)=>{
10
+ const $ = c(35);
11
+ let className;
12
+ let id;
13
+ let onError;
14
+ let onLoad;
15
+ let props;
16
+ let ref;
17
+ let src;
18
+ let t1;
19
+ let testIdProp;
20
+ if ($[0] !== t0) {
21
+ ({ ref, id, src, alt: t1, className, onLoad, onError, "data-testid": testIdProp, ...props } = t0);
22
+ $[0] = t0;
23
+ $[1] = className;
24
+ $[2] = id;
25
+ $[3] = onError;
26
+ $[4] = onLoad;
27
+ $[5] = props;
28
+ $[6] = ref;
29
+ $[7] = src;
30
+ $[8] = t1;
31
+ $[9] = testIdProp;
32
+ } else {
33
+ className = $[1];
34
+ id = $[2];
35
+ onError = $[3];
36
+ onLoad = $[4];
37
+ props = $[5];
38
+ ref = $[6];
39
+ src = $[7];
40
+ t1 = $[8];
41
+ testIdProp = $[9];
42
+ }
43
+ const alt = void 0 === t1 ? "" : t1;
44
+ const { source, setSource, setImage } = useImageCropperInternal();
45
+ const [node, setNode] = useState(null);
46
+ const composedRef = useComposedRefs(ref, setNode, setImage);
47
+ const testId = useTestId("image", testIdProp);
48
+ useImageCropperPartId("image", id);
49
+ let t2;
50
+ let t3;
51
+ if ($[10] !== node || $[11] !== setSource || $[12] !== src) {
52
+ t2 = ()=>{
53
+ setSource({
54
+ src: src ?? "",
55
+ status: "loading",
56
+ width: 0,
57
+ height: 0
58
+ });
59
+ if (node?.complete && node.naturalWidth && node.naturalHeight && node.currentSrc && node.currentSrc === node.src) setSource({
60
+ src: src ?? "",
61
+ status: "loaded",
62
+ width: node.naturalWidth,
63
+ height: node.naturalHeight
64
+ });
65
+ return ()=>setSource(null);
66
+ };
67
+ t3 = [
68
+ src,
69
+ node,
70
+ setSource
71
+ ];
72
+ $[10] = node;
73
+ $[11] = setSource;
74
+ $[12] = src;
75
+ $[13] = t2;
76
+ $[14] = t3;
77
+ } else {
78
+ t2 = $[13];
79
+ t3 = $[14];
80
+ }
81
+ useLayoutEffect(t2, t3);
82
+ const state = source && source.src === src ? source.status : "loading";
83
+ let t4;
84
+ if ($[15] !== className) {
85
+ t4 = cn("block size-full select-none data-[state=loading]:invisible data-[state=error]:invisible", className);
86
+ $[15] = className;
87
+ $[16] = t4;
88
+ } else t4 = $[16];
89
+ let t5;
90
+ if ($[17] !== onLoad || $[18] !== setSource || $[19] !== src) {
91
+ t5 = (event)=>{
92
+ const image = event.currentTarget;
93
+ setSource({
94
+ src: src ?? "",
95
+ status: "loaded",
96
+ width: image.naturalWidth,
97
+ height: image.naturalHeight
98
+ });
99
+ onLoad?.(event);
100
+ };
101
+ $[17] = onLoad;
102
+ $[18] = setSource;
103
+ $[19] = src;
104
+ $[20] = t5;
105
+ } else t5 = $[20];
106
+ let t6;
107
+ if ($[21] !== onError || $[22] !== setSource || $[23] !== src) {
108
+ t6 = (event_0)=>{
109
+ setSource({
110
+ src: src ?? "",
111
+ status: "error",
112
+ width: 0,
113
+ height: 0
114
+ });
115
+ onError?.(event_0);
116
+ };
117
+ $[21] = onError;
118
+ $[22] = setSource;
119
+ $[23] = src;
120
+ $[24] = t6;
121
+ } else t6 = $[24];
122
+ let t7;
123
+ if ($[25] !== alt || $[26] !== composedRef || $[27] !== props || $[28] !== src || $[29] !== state || $[30] !== t4 || $[31] !== t5 || $[32] !== t6 || $[33] !== testId) {
124
+ t7 = /*#__PURE__*/ jsx(ImageCropper.Image, {
125
+ ...props,
126
+ ref: composedRef,
127
+ src: src,
128
+ alt: alt,
129
+ "data-slot": "image-cropper-image",
130
+ "data-testid": testId,
131
+ "data-state": state,
132
+ className: t4,
133
+ onLoad: t5,
134
+ onError: t6
135
+ });
136
+ $[25] = alt;
137
+ $[26] = composedRef;
138
+ $[27] = props;
139
+ $[28] = src;
140
+ $[29] = state;
141
+ $[30] = t4;
142
+ $[31] = t5;
143
+ $[32] = t6;
144
+ $[33] = testId;
145
+ $[34] = t7;
146
+ } else t7 = $[34];
147
+ return t7;
148
+ };
149
+ ImageCropperImage.displayName = "ImageCropperImage";
150
+ export { ImageCropperImage };
@@ -0,0 +1,37 @@
1
+ import { type Dispatch, type SetStateAction } from 'react';
2
+ import type { ImageCropperExportOptions } from './lib/exportCrop.js';
3
+ import type { ImageCropperSize } from './lib/geometry.js';
4
+ export interface ImageCropperApi {
5
+ /** True once the current image has loaded and the crop has been measured. */
6
+ ready: boolean;
7
+ zoom: number;
8
+ setZoom: (zoom: number) => void;
9
+ reset: () => void;
10
+ /** Returns a rectangular bitmap at outputSize, or null when unavailable or canvas export fails. */
11
+ getCroppedImage: (options?: ImageCropperExportOptions) => Promise<Blob | null>;
12
+ }
13
+ export interface CropperSource extends ImageCropperSize {
14
+ src: string;
15
+ status: 'loading' | 'loaded' | 'error';
16
+ }
17
+ type Part = 'viewport' | 'image' | 'selection';
18
+ export interface ImageCropperInternalContext {
19
+ api: ImageCropperApi;
20
+ selection: {
21
+ value: number;
22
+ max: number;
23
+ text: string;
24
+ };
25
+ outputSize: ImageCropperSize;
26
+ viewportSize: ImageCropperSize;
27
+ source: CropperSource | null;
28
+ setSource: Dispatch<SetStateAction<CropperSource | null>>;
29
+ setFrameSize: Dispatch<SetStateAction<ImageCropperSize>>;
30
+ setImage: Dispatch<SetStateAction<HTMLImageElement | null>>;
31
+ setPartIds: Dispatch<SetStateAction<Partial<Record<Part, string>>>>;
32
+ }
33
+ export declare const ImageCropperProvider: import("react").Context<ImageCropperInternalContext | null>;
34
+ export declare const useImageCropperInternal: () => ImageCropperInternalContext;
35
+ /** Ark locates elements by id. Publish custom ids into its configuration before paint. */
36
+ export declare const useImageCropperPartId: (part: Part, id?: string) => void;
37
+ export {};