Skip to content

Commit 291c5d2

Browse files
committed
feat: Enhance ImageDialog with FormData support and crop options
1 parent 8f4b4a0 commit 291c5d2

File tree

7 files changed

+63
-16
lines changed

7 files changed

+63
-16
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@programmer_network/yail",
3-
"version": "1.0.206",
3+
"version": "1.0.207",
44
"description": "Programmer Network's official UI library for React",
55
"author": "Aleksandar Grbic - (https://programmer.network)",
66
"publishConfig": {

src/Components/ImageDialog/ImageDialog.stories.tsx

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { createRef } from "react";
22

33
import ImageDialog from ".";
4+
import { IImageDialogOnSaveArgs } from "./types";
45

56
export default {
67
title: "Components / ImageDialog",
@@ -21,10 +22,12 @@ export const Default = () => {
2122
dialogRef.current?.close();
2223
};
2324

24-
const handleSave = async ({ base64 }: { base64: string }) => {
25+
const handleSave = async (args: IImageDialogOnSaveArgs) => {
26+
console.log(args);
27+
2528
return new Promise(resolve => {
2629
setTimeout(() => {
27-
resolve(base64);
30+
resolve(args.formData);
2831
}, 0);
2932
});
3033
};
@@ -37,6 +40,10 @@ export const Default = () => {
3740
onClose={handleClose}
3841
onOpen={handleOpen}
3942
onSave={handleSave}
43+
cropOptions={{
44+
aspect: 1,
45+
circularCrop: true
46+
}}
4047
/>
4148
);
4249
};

src/Components/ImageDialog/index.tsx

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,18 @@ import { IImageDialogProps } from "./types";
1919

2020
const ImageDialog = forwardRef<HTMLDialogElement, IImageDialogProps>(
2121
(
22-
{ className, isOpen, onClose, onOpen, onSave, aspect = 1, buttonText },
22+
{
23+
className,
24+
isOpen,
25+
onClose,
26+
onOpen,
27+
onSave,
28+
cropOptions = {
29+
aspect: 1,
30+
circularCrop: false
31+
},
32+
buttonText
33+
},
2334
forwardedRef
2435
) => {
2536
const [validationError, setValidationError] =
@@ -38,8 +49,14 @@ const ImageDialog = forwardRef<HTMLDialogElement, IImageDialogProps>(
3849
setIsSaving(true);
3950
await onSave?.({
4051
blob: croppedImage,
41-
base64: await ImageUtils.blobToBase64(croppedImage)
52+
base64: await ImageUtils.blobToBase64(croppedImage),
53+
formData: ImageUtils.blobToFormData(
54+
croppedImage,
55+
imageInputSelection?.file.fileName ?? "",
56+
imageInputSelection?.file.mimeType ?? ""
57+
)
4258
});
59+
4360
setImageInputSelection(null);
4461
setCroppedImage(null);
4562

@@ -69,7 +86,8 @@ const ImageDialog = forwardRef<HTMLDialogElement, IImageDialogProps>(
6986
<div>
7087
<div className='yl:relative yl:w-full yl:overflow-hidden'>
7188
<ImageCrop
72-
aspect={aspect}
89+
aspect={cropOptions.aspect}
90+
circularCrop={cropOptions.circularCrop}
7391
src={imageInputSelection?.file.blob ?? null}
7492
onComplete={blob => {
7593
setCroppedImage(blob);
Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,19 @@
11
import { IDialogProps } from "Components/Dialog/types";
22

3+
export interface IImageDialogOnSaveArgs {
4+
blob: Blob;
5+
base64: string;
6+
formData: FormData;
7+
}
8+
9+
export interface IImageDialogCropOptions {
10+
aspect?: number;
11+
circularCrop?: boolean;
12+
}
13+
314
export interface IImageDialogProps extends IDialogProps {
415
onComplete?: (blob: Blob) => void;
5-
onSave?: ({
6-
blob,
7-
base64
8-
}: {
9-
blob: Blob;
10-
base64: string;
11-
}) => Promise<unknown>;
12-
aspect?: number;
16+
onSave?: (args: IImageDialogOnSaveArgs) => Promise<unknown>;
17+
cropOptions?: IImageDialogCropOptions;
1318
buttonText: string;
1419
}

src/Utils/Image/index.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,20 @@ class ImageUtils {
128128
});
129129
};
130130

131+
public static blobToFormData = (
132+
blob: Blob,
133+
fileName: string,
134+
mimeType: string
135+
): FormData => {
136+
const formData = new FormData();
137+
138+
formData.append("fileName", fileName);
139+
formData.append("mimeType", mimeType);
140+
formData.append("file", blob);
141+
142+
return formData;
143+
};
144+
131145
public static base64ToBlob = (base64: string, mimeType: string): Blob => {
132146
const parts = base64.split(",");
133147
if (parts.length < 2) {

src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ export { default as Dropdown } from "Components/Dropdown";
2020
export { default as Error } from "Components/Error";
2121
export { default as Icon } from "Components/Icon";
2222
export { default as ImageCrop } from "Components/ImageCrop";
23+
export { default as ImageDialog } from "Components/ImageDialog";
2324
export { default as ImageSelector } from "Components/ImageSelector";
2425
export { default as ItemActions } from "Components/ItemActions";
2526
export { default as Pagination } from "Components/Pagination";

src/types.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import * as DropdownTypes from "./Components/Dropdown/types";
1818
import * as ErrorTypes from "./Components/Error/types";
1919
import * as IconTypes from "./Components/Icon/types";
2020
import * as ImageCropTypes from "./Components/ImageCrop/types";
21+
import * as ImageDialogTypes from "./Components/ImageDialog/types";
2122
import * as ImageSelectorTypes from "./Components/ImageSelector/types";
2223
import * as ImageInputTypes from "./Components/Inputs/ImageInput/types";
2324
import * as InputTypes from "./Components/Inputs/types";
@@ -42,18 +43,19 @@ export {
4243
BadgeTypes,
4344
BookmarkTypes,
4445
ButtonTypes,
45-
CTATypes,
46-
CardTypes,
4746
CardsTypes,
47+
CardTypes,
4848
CharacterCounterTypes,
4949
ContentWidgetTypes,
50+
CTATypes,
5051
DialogTypes,
5152
DividerTypes,
5253
DraggableListTypes,
5354
DropdownTypes,
5455
ErrorTypes,
5556
IconTypes,
5657
ImageCropTypes,
58+
ImageDialogTypes,
5759
ImageInputTypes,
5860
ImageSelectorTypes,
5961
InputTypes,

0 commit comments

Comments
 (0)