@mittwald/flow-react-components 0.2.0-alpha.872 → 0.2.0-alpha.874

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.
@@ -210,6 +210,7 @@ import './packages/components/src/components/IllustratedMessage/IllustratedMessa
210
210
  import './packages/components/src/components/Image/Image.mjs';
211
211
  import 'react-easy-crop';
212
212
  import './packages/components/src/components/Slider/Slider.mjs';
213
+ import 'use-debounce';
213
214
  import './packages/components/src/components/Initials/Initials.mjs';
214
215
  export { IntlProvider } from './packages/components/src/components/IntlProvider/IntlProvider.mjs';
215
216
  import './packages/components/src/components/LayoutCard/LayoutCard.mjs';
@@ -1 +1 @@
1
- {"version":3,"file":"flr-universal.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"flr-universal.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -1,7 +1,7 @@
1
1
  "use client"
2
2
  /* */
3
3
  import { jsxs, jsx } from 'react/jsx-runtime';
4
- import { useState, useEffectEvent, useEffect } from 'react';
4
+ import { useState, useEffect } from 'react';
5
5
  import Cropper from 'react-easy-crop';
6
6
  import clsx from 'clsx';
7
7
  import styles from './ImageCropper.module.scss.mjs';
@@ -10,6 +10,7 @@ import { getCroppedImageFile } from './lib/getCroppedImageFile.mjs';
10
10
  import { useLocalizedStringFormatter } from '../TranslationProvider/useLocalizedStringFormatter.mjs';
11
11
  import locales from '../../../../../_virtual/_.locale.json@849e6f494125ee27df10a461562fa893.mjs';
12
12
  import { useImageSrc } from '../../lib/hooks/useImageSrc.mjs';
13
+ import { useDebouncedCallback } from 'use-debounce';
13
14
 
14
15
  const ImageCropper = (props) => {
15
16
  const {
@@ -22,25 +23,31 @@ const ImageCropper = (props) => {
22
23
  ...rest
23
24
  } = props;
24
25
  const imageSrc = useImageSrc(image);
26
+ const [mediaLoaded, setMediaLoaded] = useState(false);
25
27
  const [crop, setCrop] = useState({ x: 0, y: 0 });
26
28
  const [zoom, setZoom] = useState(1);
27
- const [croppedAreaPixels, setCroppedAreaPixels] = useState();
28
- const rootClassName = clsx(styles.imageCropper, className);
29
29
  const stringFormatter = useLocalizedStringFormatter(locales, "ImageCropper");
30
- const onCropAreaPixelsChange = useEffectEvent(async () => {
31
- if (croppedAreaPixels) {
30
+ const rootClassName = clsx(styles.imageCropper, className);
31
+ const debouncedCropComplete = useDebouncedCallback(
32
+ async (croppedAreaPixels) => {
33
+ if (!croppedAreaPixels) {
34
+ return;
35
+ }
32
36
  const croppedImageFile = await getCroppedImageFile(
33
37
  imageSrc,
38
+ image ?? "",
34
39
  croppedAreaPixels
35
40
  );
36
- if (onCropComplete) {
37
- onCropComplete(croppedImageFile);
38
- }
41
+ onCropComplete?.(croppedImageFile);
42
+ },
43
+ 500,
44
+ {
45
+ leading: true
39
46
  }
40
- });
47
+ );
41
48
  useEffect(() => {
42
- void onCropAreaPixelsChange();
43
- }, [croppedAreaPixels]);
49
+ setMediaLoaded(false);
50
+ }, [imageSrc]);
44
51
  return /* @__PURE__ */ jsxs("div", { className: rootClassName, style: { width }, children: [
45
52
  /* @__PURE__ */ jsx("div", { className: styles.cropperContainer, style: { height }, children: /* @__PURE__ */ jsx(
46
53
  Cropper,
@@ -56,7 +63,12 @@ const ImageCropper = (props) => {
56
63
  onCropChange: setCrop,
57
64
  zoom,
58
65
  onZoomChange: setZoom,
59
- onCropComplete: (_, croppedAreaPixels2) => setCroppedAreaPixels(croppedAreaPixels2),
66
+ onMediaLoaded: () => setMediaLoaded(true),
67
+ onCropComplete: (_, croppedAreaPixels) => {
68
+ if (mediaLoaded) {
69
+ debouncedCropComplete(croppedAreaPixels);
70
+ }
71
+ },
60
72
  ...rest
61
73
  }
62
74
  ) }),
@@ -1 +1 @@
1
- {"version":3,"file":"ImageCropper.mjs","sources":["../../../../../../../src/components/ImageCropper/ImageCropper.tsx"],"sourcesContent":["import {\n type CSSProperties,\n type FC,\n useEffect,\n useEffectEvent,\n useState,\n} from \"react\";\nimport Cropper, { type Area, type CropperProps } from \"react-easy-crop\";\nimport type { PropsWithClassName } from \"@/lib/types/props\";\nimport clsx from \"clsx\";\nimport styles from \"./ImageCropper.module.scss\";\nimport { Slider } from \"@/components/Slider\";\nimport { getCroppedImageFile } from \"@/components/ImageCropper/lib/getCroppedImageFile\";\nimport { useLocalizedStringFormatter } from \"@/components/TranslationProvider/useLocalizedStringFormatter\";\nimport locales from \"./locales/*.locale.json\";\nimport { useImageSrc } from \"@/lib/hooks/useImageSrc\";\n\nexport interface ImageCropperProps\n extends PropsWithClassName, Partial<Pick<CropperProps, \"cropShape\">> {\n /** The image file to crop. */\n image?: File | string;\n /** Callback on crop complete. */\n onCropComplete?: (croppedImage: File) => void;\n /** The width of the component. @default 300 */\n width?: CSSProperties[\"width\"];\n /** The height of the component. @default 300 */\n height?: CSSProperties[\"height\"];\n /** The aspect ratio of the crop shape. */\n aspectRatio?: number;\n}\n\n/** @flr-generate all */\nexport const ImageCropper: FC<ImageCropperProps> = (props) => {\n const {\n image,\n className,\n onCropComplete,\n width = 300,\n height = 300,\n aspectRatio,\n ...rest\n } = props;\n\n const imageSrc = useImageSrc(image);\n\n const [crop, setCrop] = useState({ x: 0, y: 0 });\n const [zoom, setZoom] = useState(1);\n const [croppedAreaPixels, setCroppedAreaPixels] = useState<Area>();\n\n const rootClassName = clsx(styles.imageCropper, className);\n\n const stringFormatter = useLocalizedStringFormatter(locales, \"ImageCropper\");\n\n const onCropAreaPixelsChange = useEffectEvent(async () => {\n if (croppedAreaPixels) {\n const croppedImageFile = await getCroppedImageFile(\n imageSrc,\n croppedAreaPixels,\n );\n if (onCropComplete) {\n onCropComplete(croppedImageFile);\n }\n }\n });\n\n useEffect(() => {\n void onCropAreaPixelsChange();\n }, [croppedAreaPixels]);\n\n return (\n <div className={rootClassName} style={{ width }}>\n <div className={styles.cropperContainer} style={{ height }}>\n <Cropper\n style={{\n containerStyle: {\n borderRadius: \"calc(var(--image-cropper--corner-radius) - 1px)\",\n },\n }}\n aspect={aspectRatio}\n crop={crop}\n image={imageSrc}\n onCropChange={setCrop}\n zoom={zoom}\n onZoomChange={setZoom}\n onCropComplete={(_, croppedAreaPixels) =>\n setCroppedAreaPixels(croppedAreaPixels)\n }\n {...rest}\n />\n </div>\n <Slider\n minValue={1}\n maxValue={3}\n step={0.01}\n value={zoom}\n sliderOnly\n onChange={(zoom) => setZoom(zoom as number)}\n aria-label={stringFormatter.format(\"zoom\")}\n />\n </div>\n );\n};\n\nexport default ImageCropper;\n"],"names":["croppedAreaPixels","zoom"],"mappings":";;;;;;;;;;;AAgCO,MAAM,YAAA,GAAsC,CAAC,KAAA,KAAU;AAC5D,EAAA,MAAM;AAAA,IACJ,KAAA;AAAA,IACA,SAAA;AAAA,IACA,cAAA;AAAA,IACA,KAAA,GAAQ,GAAA;AAAA,IACR,MAAA,GAAS,GAAA;AAAA,IACT,WAAA;AAAA,IACA,GAAG;AAAA,GACL,GAAI,KAAA;AAEJ,EAAA,MAAM,QAAA,GAAW,YAAY,KAAK,CAAA;AAElC,EAAA,MAAM,CAAC,IAAA,EAAM,OAAO,CAAA,GAAI,QAAA,CAAS,EAAE,CAAA,EAAG,CAAA,EAAG,CAAA,EAAG,CAAA,EAAG,CAAA;AAC/C,EAAA,MAAM,CAAC,IAAA,EAAM,OAAO,CAAA,GAAI,SAAS,CAAC,CAAA;AAClC,EAAA,MAAM,CAAC,iBAAA,EAAmB,oBAAoB,CAAA,GAAI,QAAA,EAAe;AAEjE,EAAA,MAAM,aAAA,GAAgB,IAAA,CAAK,MAAA,CAAO,YAAA,EAAc,SAAS,CAAA;AAEzD,EAAA,MAAM,eAAA,GAAkB,2BAAA,CAA4B,OAAA,EAAS,cAAc,CAAA;AAE3E,EAAA,MAAM,sBAAA,GAAyB,eAAe,YAAY;AACxD,IAAA,IAAI,iBAAA,EAAmB;AACrB,MAAA,MAAM,mBAAmB,MAAM,mBAAA;AAAA,QAC7B,QAAA;AAAA,QACA;AAAA,OACF;AACA,MAAA,IAAI,cAAA,EAAgB;AAClB,QAAA,cAAA,CAAe,gBAAgB,CAAA;AAAA,MACjC;AAAA,IACF;AAAA,EACF,CAAC,CAAA;AAED,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,KAAK,sBAAA,EAAuB;AAAA,EAC9B,CAAA,EAAG,CAAC,iBAAiB,CAAC,CAAA;AAEtB,EAAA,4BACG,KAAA,EAAA,EAAI,SAAA,EAAW,eAAe,KAAA,EAAO,EAAE,OAAM,EAC5C,QAAA,EAAA;AAAA,oBAAA,GAAA,CAAC,SAAI,SAAA,EAAW,MAAA,CAAO,kBAAkB,KAAA,EAAO,EAAE,QAAO,EACvD,QAAA,kBAAA,GAAA;AAAA,MAAC,OAAA;AAAA,MAAA;AAAA,QACC,KAAA,EAAO;AAAA,UACL,cAAA,EAAgB;AAAA,YACd,YAAA,EAAc;AAAA;AAChB,SACF;AAAA,QACA,MAAA,EAAQ,WAAA;AAAA,QACR,IAAA;AAAA,QACA,KAAA,EAAO,QAAA;AAAA,QACP,YAAA,EAAc,OAAA;AAAA,QACd,IAAA;AAAA,QACA,YAAA,EAAc,OAAA;AAAA,QACd,cAAA,EAAgB,CAAC,CAAA,EAAGA,kBAAAA,KAClB,qBAAqBA,kBAAiB,CAAA;AAAA,QAEvC,GAAG;AAAA;AAAA,KACN,EACF,CAAA;AAAA,oBACA,GAAA;AAAA,MAAC,MAAA;AAAA,MAAA;AAAA,QACC,QAAA,EAAU,CAAA;AAAA,QACV,QAAA,EAAU,CAAA;AAAA,QACV,IAAA,EAAM,IAAA;AAAA,QACN,KAAA,EAAO,IAAA;AAAA,QACP,UAAA,EAAU,IAAA;AAAA,QACV,QAAA,EAAU,CAACC,KAAAA,KAAS,OAAA,CAAQA,KAAc,CAAA;AAAA,QAC1C,YAAA,EAAY,eAAA,CAAgB,MAAA,CAAO,MAAM;AAAA;AAAA;AAC3C,GAAA,EACF,CAAA;AAEJ;;;;"}
1
+ {"version":3,"file":"ImageCropper.mjs","sources":["../../../../../../../src/components/ImageCropper/ImageCropper.tsx"],"sourcesContent":["import { type CSSProperties, type FC, useEffect, useState } from \"react\";\nimport Cropper, { type Area, type CropperProps } from \"react-easy-crop\";\nimport type { PropsWithClassName } from \"@/lib/types/props\";\nimport clsx from \"clsx\";\nimport styles from \"./ImageCropper.module.scss\";\nimport { Slider } from \"@/components/Slider\";\nimport { getCroppedImageFile } from \"@/components/ImageCropper/lib/getCroppedImageFile\";\nimport { useLocalizedStringFormatter } from \"@/components/TranslationProvider/useLocalizedStringFormatter\";\nimport locales from \"./locales/*.locale.json\";\nimport { useImageSrc } from \"@/lib/hooks/useImageSrc\";\nimport { useDebouncedCallback } from \"use-debounce\";\n\nexport interface ImageCropperProps\n extends PropsWithClassName, Partial<Pick<CropperProps, \"cropShape\">> {\n /** The image file to crop. */\n image?: File | string;\n /** Callback on crop complete. */\n onCropComplete?: (croppedImage: File) => void;\n /** The width of the component. @default 300 */\n width?: CSSProperties[\"width\"];\n /** The height of the component. @default 300 */\n height?: CSSProperties[\"height\"];\n /** The aspect ratio of the crop shape. */\n aspectRatio?: number;\n}\n\n/** @flr-generate all */\nexport const ImageCropper: FC<ImageCropperProps> = (props) => {\n const {\n image,\n className,\n onCropComplete,\n width = 300,\n height = 300,\n aspectRatio,\n ...rest\n } = props;\n\n const imageSrc = useImageSrc(image);\n\n const [mediaLoaded, setMediaLoaded] = useState(false);\n const [crop, setCrop] = useState({ x: 0, y: 0 });\n const [zoom, setZoom] = useState(1);\n\n const stringFormatter = useLocalizedStringFormatter(locales, \"ImageCropper\");\n const rootClassName = clsx(styles.imageCropper, className);\n\n const debouncedCropComplete = useDebouncedCallback(\n async (croppedAreaPixels: Area) => {\n if (!croppedAreaPixels) {\n return;\n }\n\n const croppedImageFile = await getCroppedImageFile(\n imageSrc,\n image ?? \"\",\n croppedAreaPixels,\n );\n\n onCropComplete?.(croppedImageFile);\n },\n 500,\n {\n leading: true,\n },\n );\n\n useEffect(() => {\n setMediaLoaded(false);\n }, [imageSrc]);\n\n return (\n <div className={rootClassName} style={{ width }}>\n <div className={styles.cropperContainer} style={{ height }}>\n <Cropper\n style={{\n containerStyle: {\n borderRadius: \"calc(var(--image-cropper--corner-radius) - 1px)\",\n },\n }}\n aspect={aspectRatio}\n crop={crop}\n image={imageSrc}\n onCropChange={setCrop}\n zoom={zoom}\n onZoomChange={setZoom}\n onMediaLoaded={() => setMediaLoaded(true)}\n onCropComplete={(_, croppedAreaPixels) => {\n if (mediaLoaded) {\n debouncedCropComplete(croppedAreaPixels);\n }\n }}\n {...rest}\n />\n </div>\n <Slider\n minValue={1}\n maxValue={3}\n step={0.01}\n value={zoom}\n sliderOnly\n onChange={(zoom) => setZoom(zoom as number)}\n aria-label={stringFormatter.format(\"zoom\")}\n />\n </div>\n );\n};\n\nexport default ImageCropper;\n"],"names":["zoom"],"mappings":";;;;;;;;;;;;AA2BO,MAAM,YAAA,GAAsC,CAAC,KAAA,KAAU;AAC5D,EAAA,MAAM;AAAA,IACJ,KAAA;AAAA,IACA,SAAA;AAAA,IACA,cAAA;AAAA,IACA,KAAA,GAAQ,GAAA;AAAA,IACR,MAAA,GAAS,GAAA;AAAA,IACT,WAAA;AAAA,IACA,GAAG;AAAA,GACL,GAAI,KAAA;AAEJ,EAAA,MAAM,QAAA,GAAW,YAAY,KAAK,CAAA;AAElC,EAAA,MAAM,CAAC,WAAA,EAAa,cAAc,CAAA,GAAI,SAAS,KAAK,CAAA;AACpD,EAAA,MAAM,CAAC,IAAA,EAAM,OAAO,CAAA,GAAI,QAAA,CAAS,EAAE,CAAA,EAAG,CAAA,EAAG,CAAA,EAAG,CAAA,EAAG,CAAA;AAC/C,EAAA,MAAM,CAAC,IAAA,EAAM,OAAO,CAAA,GAAI,SAAS,CAAC,CAAA;AAElC,EAAA,MAAM,eAAA,GAAkB,2BAAA,CAA4B,OAAA,EAAS,cAAc,CAAA;AAC3E,EAAA,MAAM,aAAA,GAAgB,IAAA,CAAK,MAAA,CAAO,YAAA,EAAc,SAAS,CAAA;AAEzD,EAAA,MAAM,qBAAA,GAAwB,oBAAA;AAAA,IAC5B,OAAO,iBAAA,KAA4B;AACjC,MAAA,IAAI,CAAC,iBAAA,EAAmB;AACtB,QAAA;AAAA,MACF;AAEA,MAAA,MAAM,mBAAmB,MAAM,mBAAA;AAAA,QAC7B,QAAA;AAAA,QACA,KAAA,IAAS,EAAA;AAAA,QACT;AAAA,OACF;AAEA,MAAA,cAAA,GAAiB,gBAAgB,CAAA;AAAA,IACnC,CAAA;AAAA,IACA,GAAA;AAAA,IACA;AAAA,MACE,OAAA,EAAS;AAAA;AACX,GACF;AAEA,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,cAAA,CAAe,KAAK,CAAA;AAAA,EACtB,CAAA,EAAG,CAAC,QAAQ,CAAC,CAAA;AAEb,EAAA,4BACG,KAAA,EAAA,EAAI,SAAA,EAAW,eAAe,KAAA,EAAO,EAAE,OAAM,EAC5C,QAAA,EAAA;AAAA,oBAAA,GAAA,CAAC,SAAI,SAAA,EAAW,MAAA,CAAO,kBAAkB,KAAA,EAAO,EAAE,QAAO,EACvD,QAAA,kBAAA,GAAA;AAAA,MAAC,OAAA;AAAA,MAAA;AAAA,QACC,KAAA,EAAO;AAAA,UACL,cAAA,EAAgB;AAAA,YACd,YAAA,EAAc;AAAA;AAChB,SACF;AAAA,QACA,MAAA,EAAQ,WAAA;AAAA,QACR,IAAA;AAAA,QACA,KAAA,EAAO,QAAA;AAAA,QACP,YAAA,EAAc,OAAA;AAAA,QACd,IAAA;AAAA,QACA,YAAA,EAAc,OAAA;AAAA,QACd,aAAA,EAAe,MAAM,cAAA,CAAe,IAAI,CAAA;AAAA,QACxC,cAAA,EAAgB,CAAC,CAAA,EAAG,iBAAA,KAAsB;AACxC,UAAA,IAAI,WAAA,EAAa;AACf,YAAA,qBAAA,CAAsB,iBAAiB,CAAA;AAAA,UACzC;AAAA,QACF,CAAA;AAAA,QACC,GAAG;AAAA;AAAA,KACN,EACF,CAAA;AAAA,oBACA,GAAA;AAAA,MAAC,MAAA;AAAA,MAAA;AAAA,QACC,QAAA,EAAU,CAAA;AAAA,QACV,QAAA,EAAU,CAAA;AAAA,QACV,IAAA,EAAM,IAAA;AAAA,QACN,KAAA,EAAO,IAAA;AAAA,QACP,UAAA,EAAU,IAAA;AAAA,QACV,QAAA,EAAU,CAACA,KAAAA,KAAS,OAAA,CAAQA,KAAc,CAAA;AAAA,QAC1C,YAAA,EAAY,eAAA,CAAgB,MAAA,CAAO,MAAM;AAAA;AAAA;AAC3C,GAAA,EACF,CAAA;AAEJ;;;;"}
@@ -1,15 +1,17 @@
1
1
  "use client"
2
2
  /* */
3
- function getCroppedImageFile(imageSrc, pixelCrop) {
3
+ import { addAwaitedArrayBuffer } from '../../../../../core/src/file.mjs';
4
+
5
+ function getCroppedImageFile(imageSrc, sourceImage, pixelCrop) {
4
6
  return new Promise((resolve, reject) => {
5
7
  const image = new Image();
6
8
  image.crossOrigin = "anonymous";
7
9
  image.src = imageSrc;
8
10
  image.onload = () => {
9
11
  const canvas = document.createElement("canvas");
12
+ const ctx = canvas.getContext("2d");
10
13
  canvas.width = pixelCrop.width;
11
14
  canvas.height = pixelCrop.height;
12
- const ctx = canvas.getContext("2d");
13
15
  if (!ctx) {
14
16
  reject(new Error("Failed to get canvas context"));
15
17
  return;
@@ -25,18 +27,24 @@ function getCroppedImageFile(imageSrc, pixelCrop) {
25
27
  pixelCrop.width,
26
28
  pixelCrop.height
27
29
  );
30
+ const isSourceImageJsFile = sourceImage instanceof File;
31
+ const sourceImageName = isSourceImageJsFile ? sourceImage.name : "cropped-image.png";
32
+ const sourceImageType = isSourceImageJsFile ? sourceImage.type : "image/png";
33
+ const quality = sourceImageType === "image/jpeg" ? 0.86 : sourceImageType === "image/webp" ? 0.82 : void 0;
28
34
  canvas.toBlob(
29
35
  (blob) => {
30
36
  if (!blob) {
31
37
  return;
32
38
  }
33
- const file = new File([blob], "cropped-image.png", {
34
- type: "image/png"
39
+ const file = new File([blob], sourceImageName, {
40
+ type: sourceImageType
41
+ });
42
+ addAwaitedArrayBuffer(file).then((fileWithArrayBuffer) => {
43
+ resolve(fileWithArrayBuffer);
35
44
  });
36
- resolve(file);
37
45
  },
38
- "image/png",
39
- 85
46
+ sourceImageType,
47
+ quality
40
48
  );
41
49
  };
42
50
  image.onerror = () => {
@@ -1 +1 @@
1
- {"version":3,"file":"getCroppedImageFile.mjs","sources":["../../../../../../../../src/components/ImageCropper/lib/getCroppedImageFile.ts"],"sourcesContent":["import type { Area } from \"react-easy-crop\";\n\nexport function getCroppedImageFile(\n imageSrc: string,\n pixelCrop: Area,\n): Promise<File> {\n return new Promise((resolve, reject) => {\n const image = new Image();\n image.crossOrigin = \"anonymous\";\n image.src = imageSrc;\n\n image.onload = () => {\n const canvas = document.createElement(\"canvas\");\n canvas.width = pixelCrop.width;\n canvas.height = pixelCrop.height;\n const ctx = canvas.getContext(\"2d\");\n\n if (!ctx) {\n reject(new Error(\"Failed to get canvas context\"));\n return;\n }\n\n ctx.drawImage(\n image,\n pixelCrop.x,\n pixelCrop.y,\n pixelCrop.width,\n pixelCrop.height,\n 0,\n 0,\n pixelCrop.width,\n pixelCrop.height,\n );\n\n canvas.toBlob(\n (blob) => {\n if (!blob) {\n return;\n }\n\n const file = new File([blob], \"cropped-image.png\", {\n type: \"image/png\",\n });\n resolve(file);\n },\n \"image/png\",\n 85,\n );\n };\n\n image.onerror = () => {\n reject(new Error(\"Failed to load image\"));\n };\n });\n}\n"],"names":[],"mappings":"AAEO,SAAS,mBAAA,CACd,UACA,SAAA,EACe;AACf,EAAA,OAAO,IAAI,OAAA,CAAQ,CAAC,OAAA,EAAS,MAAA,KAAW;AACtC,IAAA,MAAM,KAAA,GAAQ,IAAI,KAAA,EAAM;AACxB,IAAA,KAAA,CAAM,WAAA,GAAc,WAAA;AACpB,IAAA,KAAA,CAAM,GAAA,GAAM,QAAA;AAEZ,IAAA,KAAA,CAAM,SAAS,MAAM;AACnB,MAAA,MAAM,MAAA,GAAS,QAAA,CAAS,aAAA,CAAc,QAAQ,CAAA;AAC9C,MAAA,MAAA,CAAO,QAAQ,SAAA,CAAU,KAAA;AACzB,MAAA,MAAA,CAAO,SAAS,SAAA,CAAU,MAAA;AAC1B,MAAA,MAAM,GAAA,GAAM,MAAA,CAAO,UAAA,CAAW,IAAI,CAAA;AAElC,MAAA,IAAI,CAAC,GAAA,EAAK;AACR,QAAA,MAAA,CAAO,IAAI,KAAA,CAAM,8BAA8B,CAAC,CAAA;AAChD,QAAA;AAAA,MACF;AAEA,MAAA,GAAA,CAAI,SAAA;AAAA,QACF,KAAA;AAAA,QACA,SAAA,CAAU,CAAA;AAAA,QACV,SAAA,CAAU,CAAA;AAAA,QACV,SAAA,CAAU,KAAA;AAAA,QACV,SAAA,CAAU,MAAA;AAAA,QACV,CAAA;AAAA,QACA,CAAA;AAAA,QACA,SAAA,CAAU,KAAA;AAAA,QACV,SAAA,CAAU;AAAA,OACZ;AAEA,MAAA,MAAA,CAAO,MAAA;AAAA,QACL,CAAC,IAAA,KAAS;AACR,UAAA,IAAI,CAAC,IAAA,EAAM;AACT,YAAA;AAAA,UACF;AAEA,UAAA,MAAM,OAAO,IAAI,IAAA,CAAK,CAAC,IAAI,GAAG,mBAAA,EAAqB;AAAA,YACjD,IAAA,EAAM;AAAA,WACP,CAAA;AACD,UAAA,OAAA,CAAQ,IAAI,CAAA;AAAA,QACd,CAAA;AAAA,QACA,WAAA;AAAA,QACA;AAAA,OACF;AAAA,IACF,CAAA;AAEA,IAAA,KAAA,CAAM,UAAU,MAAM;AACpB,MAAA,MAAA,CAAO,IAAI,KAAA,CAAM,sBAAsB,CAAC,CAAA;AAAA,IAC1C,CAAA;AAAA,EACF,CAAC,CAAA;AACH;;;;"}
1
+ {"version":3,"file":"getCroppedImageFile.mjs","sources":["../../../../../../../../src/components/ImageCropper/lib/getCroppedImageFile.ts"],"sourcesContent":["import type { Area } from \"react-easy-crop\";\nimport { addAwaitedArrayBuffer } from \"@mittwald/flow-core\";\n\nexport function getCroppedImageFile(\n imageSrc: string,\n sourceImage: File | string,\n pixelCrop: Area,\n): Promise<File> {\n return new Promise((resolve, reject) => {\n const image = new Image();\n image.crossOrigin = \"anonymous\";\n image.src = imageSrc;\n\n image.onload = () => {\n const canvas = document.createElement(\"canvas\");\n const ctx = canvas.getContext(\"2d\");\n\n canvas.width = pixelCrop.width;\n canvas.height = pixelCrop.height;\n\n if (!ctx) {\n reject(new Error(\"Failed to get canvas context\"));\n return;\n }\n\n ctx.drawImage(\n image,\n pixelCrop.x,\n pixelCrop.y,\n pixelCrop.width,\n pixelCrop.height,\n 0,\n 0,\n pixelCrop.width,\n pixelCrop.height,\n );\n\n const isSourceImageJsFile = sourceImage instanceof File;\n const sourceImageName = isSourceImageJsFile\n ? sourceImage.name\n : \"cropped-image.png\";\n const sourceImageType = isSourceImageJsFile\n ? sourceImage.type\n : \"image/png\";\n\n const quality =\n sourceImageType === \"image/jpeg\"\n ? 0.86\n : sourceImageType === \"image/webp\"\n ? 0.82\n : undefined;\n\n canvas.toBlob(\n (blob) => {\n if (!blob) {\n return;\n }\n\n const file = new File([blob], sourceImageName, {\n type: sourceImageType,\n });\n addAwaitedArrayBuffer(file).then((fileWithArrayBuffer) => {\n resolve(fileWithArrayBuffer);\n });\n },\n sourceImageType,\n quality,\n );\n };\n\n image.onerror = () => {\n reject(new Error(\"Failed to load image\"));\n };\n });\n}\n"],"names":[],"mappings":";;AAGO,SAAS,mBAAA,CACd,QAAA,EACA,WAAA,EACA,SAAA,EACe;AACf,EAAA,OAAO,IAAI,OAAA,CAAQ,CAAC,OAAA,EAAS,MAAA,KAAW;AACtC,IAAA,MAAM,KAAA,GAAQ,IAAI,KAAA,EAAM;AACxB,IAAA,KAAA,CAAM,WAAA,GAAc,WAAA;AACpB,IAAA,KAAA,CAAM,GAAA,GAAM,QAAA;AAEZ,IAAA,KAAA,CAAM,SAAS,MAAM;AACnB,MAAA,MAAM,MAAA,GAAS,QAAA,CAAS,aAAA,CAAc,QAAQ,CAAA;AAC9C,MAAA,MAAM,GAAA,GAAM,MAAA,CAAO,UAAA,CAAW,IAAI,CAAA;AAElC,MAAA,MAAA,CAAO,QAAQ,SAAA,CAAU,KAAA;AACzB,MAAA,MAAA,CAAO,SAAS,SAAA,CAAU,MAAA;AAE1B,MAAA,IAAI,CAAC,GAAA,EAAK;AACR,QAAA,MAAA,CAAO,IAAI,KAAA,CAAM,8BAA8B,CAAC,CAAA;AAChD,QAAA;AAAA,MACF;AAEA,MAAA,GAAA,CAAI,SAAA;AAAA,QACF,KAAA;AAAA,QACA,SAAA,CAAU,CAAA;AAAA,QACV,SAAA,CAAU,CAAA;AAAA,QACV,SAAA,CAAU,KAAA;AAAA,QACV,SAAA,CAAU,MAAA;AAAA,QACV,CAAA;AAAA,QACA,CAAA;AAAA,QACA,SAAA,CAAU,KAAA;AAAA,QACV,SAAA,CAAU;AAAA,OACZ;AAEA,MAAA,MAAM,sBAAsB,WAAA,YAAuB,IAAA;AACnD,MAAA,MAAM,eAAA,GAAkB,mBAAA,GACpB,WAAA,CAAY,IAAA,GACZ,mBAAA;AACJ,MAAA,MAAM,eAAA,GAAkB,mBAAA,GACpB,WAAA,CAAY,IAAA,GACZ,WAAA;AAEJ,MAAA,MAAM,UACJ,eAAA,KAAoB,YAAA,GAChB,IAAA,GACA,eAAA,KAAoB,eAClB,IAAA,GACA,MAAA;AAER,MAAA,MAAA,CAAO,MAAA;AAAA,QACL,CAAC,IAAA,KAAS;AACR,UAAA,IAAI,CAAC,IAAA,EAAM;AACT,YAAA;AAAA,UACF;AAEA,UAAA,MAAM,OAAO,IAAI,IAAA,CAAK,CAAC,IAAI,GAAG,eAAA,EAAiB;AAAA,YAC7C,IAAA,EAAM;AAAA,WACP,CAAA;AACD,UAAA,qBAAA,CAAsB,IAAI,CAAA,CAAE,IAAA,CAAK,CAAC,mBAAA,KAAwB;AACxD,YAAA,OAAA,CAAQ,mBAAmB,CAAA;AAAA,UAC7B,CAAC,CAAA;AAAA,QACH,CAAA;AAAA,QACA,eAAA;AAAA,QACA;AAAA,OACF;AAAA,IACF,CAAA;AAEA,IAAA,KAAA,CAAM,UAAU,MAAM;AACpB,MAAA,MAAA,CAAO,IAAI,KAAA,CAAM,sBAAsB,CAAC,CAAA;AAAA,IAC1C,CAAA;AAAA,EACF,CAAC,CAAA;AACH;;;;"}
@@ -12,7 +12,13 @@ import { flowComponent } from '../../../../lib/componentFactory/flowComponent.mj
12
12
  import { LinkListTunnelExit } from '../LinkListTunnelExit/LinkListTunnelExit.mjs';
13
13
 
14
14
  const NavigationGroup = flowComponent("NavigationGroup", (props) => {
15
- const { children, className, collapsable, ...rest } = props;
15
+ const {
16
+ children,
17
+ className,
18
+ collapsable,
19
+ "aria-label": ariaLabel,
20
+ ...rest
21
+ } = props;
16
22
  const rootClassName = clsx(
17
23
  styles.navigationGroup,
18
24
  collapsable && styles.collapsable,
@@ -21,7 +27,7 @@ const NavigationGroup = flowComponent("NavigationGroup", (props) => {
21
27
  const generatedId = useId();
22
28
  const propsContext = {
23
29
  Label: {
24
- id: generatedId,
30
+ id: ariaLabel ? void 0 : generatedId,
25
31
  className: styles.label
26
32
  },
27
33
  Link: {
@@ -35,10 +41,19 @@ const NavigationGroup = flowComponent("NavigationGroup", (props) => {
35
41
  children,
36
42
  /* @__PURE__ */ jsx(Content, { children: /* @__PURE__ */ jsx(LinkListTunnelExit, { id: "groupLinks", component: "NavigationGroup" }) })
37
43
  ] });
38
- const defaultUi = /* @__PURE__ */ jsxs("section", { "aria-labelledby": generatedId, className: rootClassName, ...rest, children: [
39
- children,
40
- /* @__PURE__ */ jsx(LinkListTunnelExit, { id: "groupLinks", component: "NavigationGroup" })
41
- ] });
44
+ const defaultUi = /* @__PURE__ */ jsxs(
45
+ "section",
46
+ {
47
+ "aria-labelledby": ariaLabel ? void 0 : generatedId,
48
+ "aria-label": ariaLabel,
49
+ className: rootClassName,
50
+ ...rest,
51
+ children: [
52
+ children,
53
+ /* @__PURE__ */ jsx(LinkListTunnelExit, { id: "groupLinks", component: "NavigationGroup" })
54
+ ]
55
+ }
56
+ );
42
57
  return /* @__PURE__ */ jsx(PropsContextProvider, { props: propsContext, dependencies: [generatedId], children: collapsable ? collapsableUi : defaultUi });
43
58
  });
44
59
 
@@ -1 +1 @@
1
- {"version":3,"file":"NavigationGroup.mjs","sources":["../../../../../../../../../src/components/Navigation/components/NavigationGroup/NavigationGroup.tsx"],"sourcesContent":["import { type ComponentProps, type PropsWithChildren } from \"react\";\nimport { useId } from \"react\";\nimport clsx from \"clsx\";\nimport styles from \"./NavigationGroup.module.scss\";\nimport { type PropsContext, PropsContextProvider } from \"@/lib/propsContext\";\nimport { Accordion } from \"@/components/Accordion\";\nimport { Content } from \"@/components/Content\";\nimport {\n flowComponent,\n type FlowComponentProps,\n} from \"@/lib/componentFactory/flowComponent\";\nimport { LinkListTunnelExit } from \"@/components/Navigation/components/LinkListTunnelExit/LinkListTunnelExit\";\n\nexport interface NavigationGroupProps\n extends\n PropsWithChildren<ComponentProps<\"section\">>,\n FlowComponentProps<HTMLElement> {\n collapsable?: boolean;\n}\n\n/** @flr-generate all */\nexport const NavigationGroup = flowComponent(\"NavigationGroup\", (props) => {\n const { children, className, collapsable, ...rest } = props;\n\n const rootClassName = clsx(\n styles.navigationGroup,\n collapsable && styles.collapsable,\n className,\n );\n\n const generatedId = useId();\n\n const propsContext: PropsContext = {\n Label: {\n id: generatedId,\n className: styles.label,\n },\n Link: {\n tunnel: {\n id: \"groupLinks\",\n component: \"NavigationGroup\",\n },\n },\n };\n\n const collapsableUi = (\n <Accordion defaultExpanded className={rootClassName}>\n {children}\n <Content>\n <LinkListTunnelExit id=\"groupLinks\" component=\"NavigationGroup\" />\n </Content>\n </Accordion>\n );\n\n const defaultUi = (\n <section aria-labelledby={generatedId} className={rootClassName} {...rest}>\n {children}\n <LinkListTunnelExit id=\"groupLinks\" component=\"NavigationGroup\" />\n </section>\n );\n\n return (\n <PropsContextProvider props={propsContext} dependencies={[generatedId]}>\n {collapsable ? collapsableUi : defaultUi}\n </PropsContextProvider>\n );\n});\n\nexport default NavigationGroup;\n"],"names":[],"mappings":";;;;;;;;;;;AAqBO,MAAM,eAAA,GAAkB,aAAA,CAAc,iBAAA,EAAmB,CAAC,KAAA,KAAU;AACzE,EAAA,MAAM,EAAE,QAAA,EAAU,SAAA,EAAW,WAAA,EAAa,GAAG,MAAK,GAAI,KAAA;AAEtD,EAAA,MAAM,aAAA,GAAgB,IAAA;AAAA,IACpB,MAAA,CAAO,eAAA;AAAA,IACP,eAAe,MAAA,CAAO,WAAA;AAAA,IACtB;AAAA,GACF;AAEA,EAAA,MAAM,cAAc,KAAA,EAAM;AAE1B,EAAA,MAAM,YAAA,GAA6B;AAAA,IACjC,KAAA,EAAO;AAAA,MACL,EAAA,EAAI,WAAA;AAAA,MACJ,WAAW,MAAA,CAAO;AAAA,KACpB;AAAA,IACA,IAAA,EAAM;AAAA,MACJ,MAAA,EAAQ;AAAA,QACN,EAAA,EAAI,YAAA;AAAA,QACJ,SAAA,EAAW;AAAA;AACb;AACF,GACF;AAEA,EAAA,MAAM,gCACJ,IAAA,CAAC,SAAA,EAAA,EAAU,eAAA,EAAe,IAAA,EAAC,WAAW,aAAA,EACnC,QAAA,EAAA;AAAA,IAAA,QAAA;AAAA,oBACD,GAAA,CAAC,WACC,QAAA,kBAAA,GAAA,CAAC,kBAAA,EAAA,EAAmB,IAAG,YAAA,EAAa,SAAA,EAAU,mBAAkB,CAAA,EAClE;AAAA,GAAA,EACF,CAAA;AAGF,EAAA,MAAM,SAAA,wBACH,SAAA,EAAA,EAAQ,iBAAA,EAAiB,aAAa,SAAA,EAAW,aAAA,EAAgB,GAAG,IAAA,EAClE,QAAA,EAAA;AAAA,IAAA,QAAA;AAAA,oBACD,GAAA,CAAC,kBAAA,EAAA,EAAmB,EAAA,EAAG,YAAA,EAAa,WAAU,iBAAA,EAAkB;AAAA,GAAA,EAClE,CAAA;AAGF,EAAA,uBACE,GAAA,CAAC,oBAAA,EAAA,EAAqB,KAAA,EAAO,YAAA,EAAc,YAAA,EAAc,CAAC,WAAW,CAAA,EAClE,QAAA,EAAA,WAAA,GAAc,aAAA,GAAgB,SAAA,EACjC,CAAA;AAEJ,CAAC;;;;"}
1
+ {"version":3,"file":"NavigationGroup.mjs","sources":["../../../../../../../../../src/components/Navigation/components/NavigationGroup/NavigationGroup.tsx"],"sourcesContent":["import { type ComponentProps, type PropsWithChildren } from \"react\";\nimport { useId } from \"react\";\nimport clsx from \"clsx\";\nimport styles from \"./NavigationGroup.module.scss\";\nimport { type PropsContext, PropsContextProvider } from \"@/lib/propsContext\";\nimport { Accordion } from \"@/components/Accordion\";\nimport { Content } from \"@/components/Content\";\nimport {\n flowComponent,\n type FlowComponentProps,\n} from \"@/lib/componentFactory/flowComponent\";\nimport { LinkListTunnelExit } from \"@/components/Navigation/components/LinkListTunnelExit/LinkListTunnelExit\";\n\nexport interface NavigationGroupProps\n extends\n PropsWithChildren<ComponentProps<\"section\">>,\n FlowComponentProps<HTMLElement> {\n collapsable?: boolean;\n}\n\n/** @flr-generate all */\nexport const NavigationGroup = flowComponent(\"NavigationGroup\", (props) => {\n const {\n children,\n className,\n collapsable,\n \"aria-label\": ariaLabel,\n ...rest\n } = props;\n\n const rootClassName = clsx(\n styles.navigationGroup,\n collapsable && styles.collapsable,\n className,\n );\n\n const generatedId = useId();\n\n const propsContext: PropsContext = {\n Label: {\n id: ariaLabel ? undefined : generatedId,\n className: styles.label,\n },\n Link: {\n tunnel: {\n id: \"groupLinks\",\n component: \"NavigationGroup\",\n },\n },\n };\n\n const collapsableUi = (\n <Accordion defaultExpanded className={rootClassName}>\n {children}\n <Content>\n <LinkListTunnelExit id=\"groupLinks\" component=\"NavigationGroup\" />\n </Content>\n </Accordion>\n );\n\n const defaultUi = (\n <section\n aria-labelledby={ariaLabel ? undefined : generatedId}\n aria-label={ariaLabel}\n className={rootClassName}\n {...rest}\n >\n {children}\n <LinkListTunnelExit id=\"groupLinks\" component=\"NavigationGroup\" />\n </section>\n );\n\n return (\n <PropsContextProvider props={propsContext} dependencies={[generatedId]}>\n {collapsable ? collapsableUi : defaultUi}\n </PropsContextProvider>\n );\n});\n\nexport default NavigationGroup;\n"],"names":[],"mappings":";;;;;;;;;;;AAqBO,MAAM,eAAA,GAAkB,aAAA,CAAc,iBAAA,EAAmB,CAAC,KAAA,KAAU;AACzE,EAAA,MAAM;AAAA,IACJ,QAAA;AAAA,IACA,SAAA;AAAA,IACA,WAAA;AAAA,IACA,YAAA,EAAc,SAAA;AAAA,IACd,GAAG;AAAA,GACL,GAAI,KAAA;AAEJ,EAAA,MAAM,aAAA,GAAgB,IAAA;AAAA,IACpB,MAAA,CAAO,eAAA;AAAA,IACP,eAAe,MAAA,CAAO,WAAA;AAAA,IACtB;AAAA,GACF;AAEA,EAAA,MAAM,cAAc,KAAA,EAAM;AAE1B,EAAA,MAAM,YAAA,GAA6B;AAAA,IACjC,KAAA,EAAO;AAAA,MACL,EAAA,EAAI,YAAY,MAAA,GAAY,WAAA;AAAA,MAC5B,WAAW,MAAA,CAAO;AAAA,KACpB;AAAA,IACA,IAAA,EAAM;AAAA,MACJ,MAAA,EAAQ;AAAA,QACN,EAAA,EAAI,YAAA;AAAA,QACJ,SAAA,EAAW;AAAA;AACb;AACF,GACF;AAEA,EAAA,MAAM,gCACJ,IAAA,CAAC,SAAA,EAAA,EAAU,eAAA,EAAe,IAAA,EAAC,WAAW,aAAA,EACnC,QAAA,EAAA;AAAA,IAAA,QAAA;AAAA,oBACD,GAAA,CAAC,WACC,QAAA,kBAAA,GAAA,CAAC,kBAAA,EAAA,EAAmB,IAAG,YAAA,EAAa,SAAA,EAAU,mBAAkB,CAAA,EAClE;AAAA,GAAA,EACF,CAAA;AAGF,EAAA,MAAM,SAAA,mBACJ,IAAA;AAAA,IAAC,SAAA;AAAA,IAAA;AAAA,MACC,iBAAA,EAAiB,YAAY,MAAA,GAAY,WAAA;AAAA,MACzC,YAAA,EAAY,SAAA;AAAA,MACZ,SAAA,EAAW,aAAA;AAAA,MACV,GAAG,IAAA;AAAA,MAEH,QAAA,EAAA;AAAA,QAAA,QAAA;AAAA,wBACD,GAAA,CAAC,kBAAA,EAAA,EAAmB,EAAA,EAAG,YAAA,EAAa,WAAU,iBAAA,EAAkB;AAAA;AAAA;AAAA,GAClE;AAGF,EAAA,uBACE,GAAA,CAAC,oBAAA,EAAA,EAAqB,KAAA,EAAO,YAAA,EAAc,YAAA,EAAc,CAAC,WAAW,CAAA,EAClE,QAAA,EAAA,WAAA,GAAc,aAAA,GAAgB,SAAA,EACjC,CAAA;AAEJ,CAAC;;;;"}
@@ -1,28 +1,18 @@
1
1
  "use client"
2
2
  /* */
3
- import { useState, useEffectEvent, useEffect } from 'react';
3
+ import { useState, useEffect } from 'react';
4
4
 
5
5
  const useImageSrc = (image) => {
6
- const [imageSrc, setImageSrc] = useState("");
7
- const onImageChange = useEffectEvent(() => {
8
- if (image) {
9
- if (typeof image === "string") {
10
- setImageSrc(image);
11
- } else {
12
- const reader = new FileReader();
13
- reader.onload = () => {
14
- if (typeof reader.result === "string") {
15
- setImageSrc(reader.result);
16
- }
17
- };
18
- reader.readAsDataURL(image);
19
- }
20
- }
21
- });
6
+ const [src, setSrc] = useState(typeof image === "string" ? image : "");
22
7
  useEffect(() => {
23
- onImageChange();
8
+ if (!image || typeof image === "string") {
9
+ return;
10
+ }
11
+ const url = URL.createObjectURL(image);
12
+ setSrc(url);
13
+ return () => URL.revokeObjectURL(url);
24
14
  }, [image]);
25
- return imageSrc;
15
+ return src;
26
16
  };
27
17
 
28
18
  export { useImageSrc };
@@ -1 +1 @@
1
- {"version":3,"file":"useImageSrc.mjs","sources":["../../../../../../../src/lib/hooks/useImageSrc.tsx"],"sourcesContent":["import { useEffect, useEffectEvent, useState } from \"react\";\n\nexport const useImageSrc = (image?: string | File) => {\n const [imageSrc, setImageSrc] = useState<string>(\"\");\n\n const onImageChange = useEffectEvent(() => {\n if (image) {\n if (typeof image === \"string\") {\n setImageSrc(image);\n } else {\n const reader = new FileReader();\n reader.onload = () => {\n if (typeof reader.result === \"string\") {\n setImageSrc(reader.result);\n }\n };\n reader.readAsDataURL(image);\n }\n }\n });\n\n useEffect(() => {\n onImageChange();\n }, [image]);\n\n return imageSrc;\n};\n"],"names":[],"mappings":";;AAEO,MAAM,WAAA,GAAc,CAAC,KAAA,KAA0B;AACpD,EAAA,MAAM,CAAC,QAAA,EAAU,WAAW,CAAA,GAAI,SAAiB,EAAE,CAAA;AAEnD,EAAA,MAAM,aAAA,GAAgB,eAAe,MAAM;AACzC,IAAA,IAAI,KAAA,EAAO;AACT,MAAA,IAAI,OAAO,UAAU,QAAA,EAAU;AAC7B,QAAA,WAAA,CAAY,KAAK,CAAA;AAAA,MACnB,CAAA,MAAO;AACL,QAAA,MAAM,MAAA,GAAS,IAAI,UAAA,EAAW;AAC9B,QAAA,MAAA,CAAO,SAAS,MAAM;AACpB,UAAA,IAAI,OAAO,MAAA,CAAO,MAAA,KAAW,QAAA,EAAU;AACrC,YAAA,WAAA,CAAY,OAAO,MAAM,CAAA;AAAA,UAC3B;AAAA,QACF,CAAA;AACA,QAAA,MAAA,CAAO,cAAc,KAAK,CAAA;AAAA,MAC5B;AAAA,IACF;AAAA,EACF,CAAC,CAAA;AAED,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,aAAA,EAAc;AAAA,EAChB,CAAA,EAAG,CAAC,KAAK,CAAC,CAAA;AAEV,EAAA,OAAO,QAAA;AACT;;;;"}
1
+ {"version":3,"file":"useImageSrc.mjs","sources":["../../../../../../../src/lib/hooks/useImageSrc.tsx"],"sourcesContent":["import { useEffect, useState } from \"react\";\n\nexport const useImageSrc = (image?: string | File) => {\n const [src, setSrc] = useState(typeof image === \"string\" ? image : \"\");\n\n useEffect(() => {\n if (!image || typeof image === \"string\") {\n return;\n }\n\n const url = URL.createObjectURL(image);\n setSrc(url);\n\n return () => URL.revokeObjectURL(url);\n }, [image]);\n\n return src;\n};\n"],"names":[],"mappings":";;AAEO,MAAM,WAAA,GAAc,CAAC,KAAA,KAA0B;AACpD,EAAA,MAAM,CAAC,KAAK,MAAM,CAAA,GAAI,SAAS,OAAO,KAAA,KAAU,QAAA,GAAW,KAAA,GAAQ,EAAE,CAAA;AAErE,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI,CAAC,KAAA,IAAS,OAAO,KAAA,KAAU,QAAA,EAAU;AACvC,MAAA;AAAA,IACF;AAEA,IAAA,MAAM,GAAA,GAAM,GAAA,CAAI,eAAA,CAAgB,KAAK,CAAA;AACrC,IAAA,MAAA,CAAO,GAAG,CAAA;AAEV,IAAA,OAAO,MAAM,GAAA,CAAI,eAAA,CAAgB,GAAG,CAAA;AAAA,EACtC,CAAA,EAAG,CAAC,KAAK,CAAC,CAAA;AAEV,EAAA,OAAO,GAAA;AACT;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"ImageCropper.d.ts","sourceRoot":"","sources":["../../../../src/components/ImageCropper/ImageCropper.tsx"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,aAAa,EAClB,KAAK,EAAE,EAIR,MAAM,OAAO,CAAC;AACf,OAAgB,EAAa,KAAK,YAAY,EAAE,MAAM,iBAAiB,CAAC;AACxE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAS5D,MAAM,WAAW,iBACf,SAAQ,kBAAkB,EAAE,OAAO,CAAC,IAAI,CAAC,YAAY,EAAE,WAAW,CAAC,CAAC;IACpE,8BAA8B;IAC9B,KAAK,CAAC,EAAE,IAAI,GAAG,MAAM,CAAC;IACtB,iCAAiC;IACjC,cAAc,CAAC,EAAE,CAAC,YAAY,EAAE,IAAI,KAAK,IAAI,CAAC;IAC9C,+CAA+C;IAC/C,KAAK,CAAC,EAAE,aAAa,CAAC,OAAO,CAAC,CAAC;IAC/B,gDAAgD;IAChD,MAAM,CAAC,EAAE,aAAa,CAAC,QAAQ,CAAC,CAAC;IACjC,0CAA0C;IAC1C,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,wBAAwB;AACxB,eAAO,MAAM,YAAY,EAAE,EAAE,CAAC,iBAAiB,CAqE9C,CAAC;AAEF,eAAe,YAAY,CAAC"}
1
+ {"version":3,"file":"ImageCropper.d.ts","sourceRoot":"","sources":["../../../../src/components/ImageCropper/ImageCropper.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,aAAa,EAAE,KAAK,EAAE,EAAuB,MAAM,OAAO,CAAC;AACzE,OAAgB,EAAa,KAAK,YAAY,EAAE,MAAM,iBAAiB,CAAC;AACxE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAU5D,MAAM,WAAW,iBACf,SAAQ,kBAAkB,EAAE,OAAO,CAAC,IAAI,CAAC,YAAY,EAAE,WAAW,CAAC,CAAC;IACpE,8BAA8B;IAC9B,KAAK,CAAC,EAAE,IAAI,GAAG,MAAM,CAAC;IACtB,iCAAiC;IACjC,cAAc,CAAC,EAAE,CAAC,YAAY,EAAE,IAAI,KAAK,IAAI,CAAC;IAC9C,+CAA+C;IAC/C,KAAK,CAAC,EAAE,aAAa,CAAC,OAAO,CAAC,CAAC;IAC/B,gDAAgD;IAChD,MAAM,CAAC,EAAE,aAAa,CAAC,QAAQ,CAAC,CAAC;IACjC,0CAA0C;IAC1C,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,wBAAwB;AACxB,eAAO,MAAM,YAAY,EAAE,EAAE,CAAC,iBAAiB,CA+E9C,CAAC;AAEF,eAAe,YAAY,CAAC"}
@@ -1,3 +1,3 @@
1
1
  import { Area } from 'react-easy-crop';
2
- export declare function getCroppedImageFile(imageSrc: string, pixelCrop: Area): Promise<File>;
2
+ export declare function getCroppedImageFile(imageSrc: string, sourceImage: File | string, pixelCrop: Area): Promise<File>;
3
3
  //# sourceMappingURL=getCroppedImageFile.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"getCroppedImageFile.d.ts","sourceRoot":"","sources":["../../../../../src/components/ImageCropper/lib/getCroppedImageFile.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAE5C,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,IAAI,GACd,OAAO,CAAC,IAAI,CAAC,CAiDf"}
1
+ {"version":3,"file":"getCroppedImageFile.d.ts","sourceRoot":"","sources":["../../../../../src/components/ImageCropper/lib/getCroppedImageFile.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAG5C,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,IAAI,GAAG,MAAM,EAC1B,SAAS,EAAE,IAAI,GACd,OAAO,CAAC,IAAI,CAAC,CAmEf"}
@@ -1 +1 @@
1
- {"version":3,"file":"Default.stories.d.ts","sourceRoot":"","sources":["../../../../../src/components/ImageCropper/stories/Default.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAEvD,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAQzD,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,OAAO,YAAY,CAWnC,CAAC;AACF,eAAe,IAAI,CAAC;AAEpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,YAAY,CAAC,CAAC;AAE3C,eAAO,MAAM,OAAO,EAAE,KAAU,CAAC;AAEjC,eAAO,MAAM,YAAY,EAAE,KAyC1B,CAAC;AAEF,eAAO,MAAM,QAAQ,EAAE,KAoCtB,CAAC"}
1
+ {"version":3,"file":"Default.stories.d.ts","sourceRoot":"","sources":["../../../../../src/components/ImageCropper/stories/Default.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAEvD,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AASzD,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,OAAO,YAAY,CA+BnC,CAAC;AACF,eAAe,IAAI,CAAC;AAEpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,YAAY,CAAC,CAAC;AAE3C,eAAO,MAAM,OAAO,EAAE,KAAU,CAAC;AAEjC,eAAO,MAAM,YAAY,EAAE,KAmD1B,CAAC;AAEF,eAAO,MAAM,QAAQ,EAAE,KAoCtB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"NavigationGroup.d.ts","sourceRoot":"","sources":["../../../../../../src/components/Navigation/components/NavigationGroup/NavigationGroup.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,cAAc,EAAE,KAAK,iBAAiB,EAAE,MAAM,OAAO,CAAC;AAOpE,OAAO,EAEL,KAAK,kBAAkB,EACxB,MAAM,sCAAsC,CAAC;AAG9C,MAAM,WAAW,oBACf,SACE,iBAAiB,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC,EAC5C,kBAAkB,CAAC,WAAW,CAAC;IACjC,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,wBAAwB;AACxB,eAAO,MAAM,eAAe,sGA6C1B,CAAC;AAEH,eAAe,eAAe,CAAC"}
1
+ {"version":3,"file":"NavigationGroup.d.ts","sourceRoot":"","sources":["../../../../../../src/components/Navigation/components/NavigationGroup/NavigationGroup.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,cAAc,EAAE,KAAK,iBAAiB,EAAE,MAAM,OAAO,CAAC;AAOpE,OAAO,EAEL,KAAK,kBAAkB,EACxB,MAAM,sCAAsC,CAAC;AAG9C,MAAM,WAAW,oBACf,SACE,iBAAiB,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC,EAC5C,kBAAkB,CAAC,WAAW,CAAC;IACjC,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,wBAAwB;AACxB,eAAO,MAAM,eAAe,sGAwD1B,CAAC;AAEH,eAAe,eAAe,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"useImageSrc.d.ts","sourceRoot":"","sources":["../../../../src/lib/hooks/useImageSrc.tsx"],"names":[],"mappings":"AAEA,eAAO,MAAM,WAAW,GAAI,QAAQ,MAAM,GAAG,IAAI,WAwBhD,CAAC"}
1
+ {"version":3,"file":"useImageSrc.d.ts","sourceRoot":"","sources":["../../../../src/lib/hooks/useImageSrc.tsx"],"names":[],"mappings":"AAEA,eAAO,MAAM,WAAW,GAAI,QAAQ,MAAM,GAAG,IAAI,WAehD,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mittwald/flow-react-components",
3
- "version": "0.2.0-alpha.872",
3
+ "version": "0.2.0-alpha.874",
4
4
  "type": "module",
5
5
  "description": "A React implementation of Flow, mittwald’s design system",
6
6
  "homepage": "https://mittwald.github.io/flow",
@@ -63,9 +63,9 @@
63
63
  "@internationalized/string": "^3.2.9",
64
64
  "@internationalized/string-compiler": "^3.4.1",
65
65
  "@lezer/highlight": "^1.2.3",
66
- "@mittwald/flow-icons": "0.2.0-alpha.872",
66
+ "@mittwald/flow-icons": "0.2.0-alpha.874",
67
67
  "@mittwald/password-tools-js": "3.0.0-alpha.30",
68
- "@mittwald/react-tunnel": "0.2.0-alpha.872",
68
+ "@mittwald/react-tunnel": "0.2.0-alpha.874",
69
69
  "@mittwald/react-use-promise": "^4.2.2",
70
70
  "@react-aria/form": "^3.2.1",
71
71
  "@react-aria/i18n": "^3.13.1",
@@ -110,6 +110,7 @@
110
110
  "remeda": "^2.39.0",
111
111
  "type-fest": "^5.7.0",
112
112
  "use-callback-ref": "^1.3.3",
113
+ "use-debounce": "^10.1.1",
113
114
  "usehooks-ts": "^3.1.1",
114
115
  "zod": "^4.4.3"
115
116
  },
@@ -119,7 +120,7 @@
119
120
  "@lezer/generator": "^1.8.0",
120
121
  "@lezer/lr": "^1.4.10",
121
122
  "@mittwald/flow-core": "",
122
- "@mittwald/flow-design-tokens": "0.2.0-alpha.872",
123
+ "@mittwald/flow-design-tokens": "0.2.0-alpha.874",
123
124
  "@mittwald/flow-icons-base": "",
124
125
  "@mittwald/react-use-promise": "^4.2.2",
125
126
  "@mittwald/remote-dom-react": "1.2.2-mittwald.10",
@@ -174,7 +175,7 @@
174
175
  },
175
176
  "peerDependencies": {
176
177
  "@internationalized/date": "^3.12.2",
177
- "@mittwald/flow-icons-pro": "0.2.0-alpha.871",
178
+ "@mittwald/flow-icons-pro": "0.2.0-alpha.873",
178
179
  "@mittwald/react-use-promise": "^4.2.2",
179
180
  "next": "^16.2.3",
180
181
  "react": "^19.2.0",
@@ -195,5 +196,5 @@
195
196
  "optional": true
196
197
  }
197
198
  },
198
- "gitHead": "54bbd789099cdc5be2fdf9169be1221f2e6f0cf3"
199
+ "gitHead": "8d4b04c6cd6641cbacfd647aae90abeac04a85ef"
199
200
  }