Skip to content

Commit

Permalink
wip: refactor(file-upload): with react-hook-form
Browse files Browse the repository at this point in the history
  • Loading branch information
ntatoud committed May 13, 2024
1 parent 212ef85 commit 48a85ea
Show file tree
Hide file tree
Showing 10 changed files with 1,037 additions and 441 deletions.
759 changes: 597 additions & 162 deletions pnpm-lock.yaml

Large diffs are not rendered by default.

213 changes: 107 additions & 106 deletions src/components/FieldUpload/FieldUploadPreview.tsx
Original file line number Diff line number Diff line change
@@ -1,120 +1,121 @@
import React, { FC, useCallback, useEffect, useState } from 'react';
// TODO : Delete file once migration is done
// import React, { FC, useCallback, useEffect, useState } from 'react';

import { Box, Flex, FlexProps, IconButton } from '@chakra-ui/react';
import { useFormContext, useFormFields } from '@formiz/core';
import { LuX } from 'react-icons/lu';
// import { Box, Flex, FlexProps, IconButton } from '@chakra-ui/react';
// import { useFormContext, useFormFields } from '@formiz/core';
// import { LuX } from 'react-icons/lu';

import { FieldUploadValue } from '@/components/FieldUpload';
// import { FieldUploadValue } from '@/components/FieldUpload';

const ImagePreview = ({
image,
onClick,
}: {
image: string;
onClick: React.MouseEventHandler<HTMLButtonElement>;
}) => {
return (
<Box
position="relative"
bg="gray.200"
height="100%"
aspectRatio="1"
overflow="hidden"
rounded="md"
>
<Box as="img" width="100%" height="100%" objectFit="cover" src={image} />
<IconButton
position="absolute"
top="1"
right="1"
icon={<LuX fontSize="sm" />}
aria-label="Remove"
rounded="full"
minWidth="6"
minHeight="6"
width="6"
height="6"
onClick={onClick}
/>
</Box>
);
};
// const ImagePreview = ({
// image,
// onClick,
// }: {
// image: string;
// onClick: React.MouseEventHandler<HTMLButtonElement>;
// }) => {
// return (
// <Box
// position="relative"
// bg="gray.200"
// height="100%"
// aspectRatio="1"
// overflow="hidden"
// rounded="md"
// >
// <Box as="img" width="100%" height="100%" objectFit="cover" src={image} />
// <IconButton
// position="absolute"
// top="1"
// right="1"
// icon={<LuX fontSize="sm" />}
// aria-label="Remove"
// rounded="full"
// minWidth="6"
// minHeight="6"
// width="6"
// height="6"
// onClick={onClick}
// />
// </Box>
// );
// };

export type FieldUploadPreviewProps = FlexProps & {
uploaderName: string;
};
// export type FieldUploadPreviewProps = FlexProps & {
// uploaderName: string;
// };

export const FieldUploadPreview: FC<
React.PropsWithChildren<FieldUploadPreviewProps>
> = ({ uploaderName, ...rest }) => {
const fields = useFormFields({
fields: [uploaderName] as const, // To get the uploader values
});
const form = useFormContext();
// export const FieldUploadPreview: FC<
// React.PropsWithChildren<FieldUploadPreviewProps>
// > = ({ uploaderName, ...rest }) => {
// const fields = useFormFields({
// fields: [uploaderName] as const, // To get the uploader values
// });
// const form = useFormContext();

const [fileToPreview, setFileToPreview] = useState<string>();
// const [fileToPreview, setFileToPreview] = useState<string>();

const previewFile = useCallback(async () => {
const uploaderFieldValue = fields?.[uploaderName]
?.value as FieldUploadValue;
// const previewFile = useCallback(async () => {
// const uploaderFieldValue = fields?.[uploaderName]
// ?.value as FieldUploadValue;

if (
!uploaderFieldValue ||
(!uploaderFieldValue.fileUrl && !uploaderFieldValue.file)
) {
setFileToPreview(undefined);
return;
}
// if (
// !uploaderFieldValue ||
// (!uploaderFieldValue.fileUrl && !uploaderFieldValue.file)
// ) {
// setFileToPreview(undefined);
// return;
// }

const hasUserUploadedAFile = uploaderFieldValue.file;
const hasDefaultFileSet =
uploaderFieldValue.fileUrl && !hasUserUploadedAFile;
// const hasUserUploadedAFile = uploaderFieldValue.file;
// const hasDefaultFileSet =
// uploaderFieldValue.fileUrl && !hasUserUploadedAFile;

if (hasDefaultFileSet) {
setFileToPreview(uploaderFieldValue.fileUrl);
return;
}
// if (hasDefaultFileSet) {
// setFileToPreview(uploaderFieldValue.fileUrl);
// return;
// }

const uploadedFileToPreview = await new Promise<string>(
(resolve, reject) => {
const reader = new FileReader();
reader.onloadend = () => resolve(reader.result?.toString() ?? '');
reader.onerror = reject;
if (uploaderFieldValue.file) {
reader.readAsDataURL(uploaderFieldValue.file);
}
}
);
// const uploadedFileToPreview = await new Promise<string>(
// (resolve, reject) => {
// const reader = new FileReader();
// reader.onloadend = () => resolve(reader.result?.toString() ?? '');
// reader.onerror = reject;
// if (uploaderFieldValue.file) {
// reader.readAsDataURL(uploaderFieldValue.file);
// }
// }
// );

setFileToPreview(uploadedFileToPreview);
}, [fields, uploaderName]);
// setFileToPreview(uploadedFileToPreview);
// }, [fields, uploaderName]);

useEffect(() => {
previewFile();
}, [previewFile]);
// useEffect(() => {
// previewFile();
// }, [previewFile]);

return (
fileToPreview && (
<Flex
mt={2}
background="white"
height="32"
width="full"
rounded="md"
boxShadow="sm"
border="1px solid"
borderColor="gray.200"
alignItems="center"
p={4}
{...rest}
>
<ImagePreview
image={fileToPreview}
onClick={() => {
form.setValues({ [uploaderName]: null });
}}
/>
</Flex>
)
);
};
// return (
// fileToPreview && (
// <Flex
// mt={2}
// background="white"
// height="32"
// width="full"
// rounded="md"
// boxShadow="sm"
// border="1px solid"
// borderColor="gray.200"
// alignItems="center"
// p={4}
// {...rest}
// >
// <ImagePreview
// image={fileToPreview}
// onClick={() => {
// form.setValues({ [uploaderName]: null });
// }}
// />
// </Flex>
// )
// );
// };
134 changes: 69 additions & 65 deletions src/components/FieldUpload/docs.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,80 +1,84 @@
import React from 'react';

import { Box, Button, Stack } from '@chakra-ui/react';
import { Formiz, useForm } from '@formiz/core';
// TODO : Delete file once migration is done
import { Meta } from '@storybook/react';

import { FieldUploadPreview } from '@/components/FieldUpload/FieldUploadPreview';
import { useFieldUploadFileFromUrl } from '@/components/FieldUpload/utils';
// import React from 'react';

// import { Box, Button, Stack } from '@chakra-ui/react';
// import { Formiz, useForm } from '@formiz/core';

// import { FieldUploadPreview } from '@/components/FieldUpload/FieldUploadPreview';
// import { useFieldUploadFileFromUrl } from '@/components/FieldUpload/utils';

import { FieldUpload, FieldUploadValue } from '.';
// import { FieldUpload, FieldUploadValue } from '.';

export default {
title: 'Fields/FieldUpload',
} satisfies Meta;

export const Default = () => {
const form = useForm({ onSubmit: console.log });
return (
<Formiz connect={form} autoForm>
<Stack spacing={4}>
<FieldUpload name="file" label="File" />
<Box>
<Button type="submit">Submit</Button>
</Box>
</Stack>
</Formiz>
);
return <></>;
};
// export const Default = () => {
// const form = useForm({ onSubmit: console.log });
// return (
// <Formiz connect={form} autoForm>
// <Stack spacing={4}>
// <FieldUpload name="file" label="File" />
// <Box>
// <Button type="submit">Submit</Button>
// </Box>
// </Stack>
// </Formiz>
// );
// };

export const DefaultValue = () => {
const initialFiles = useFieldUploadFileFromUrl(
'https://plus.unsplash.com/premium_photo-1674593231084-d8b27596b134?auto=format&fit=crop&q=60&w=800&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxlZGl0b3JpYWwtZmVlZHwyfHx8ZW58MHx8fHx8'
);
// export const DefaultValue = () => {
// const initialFiles = useFieldUploadFileFromUrl(
// 'https://plus.unsplash.com/premium_photo-1674593231084-d8b27596b134?auto=format&fit=crop&q=60&w=800&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxlZGl0b3JpYWwtZmVlZHwyfHx8ZW58MHx8fHx8'
// );

const form = useForm({
ready: initialFiles.isSuccess,
initialValues: {
file: initialFiles.data,
},
onSubmit: console.log,
});
// const form = useForm({
// ready: initialFiles.isSuccess,
// initialValues: {
// file: initialFiles.data,
// },
// onSubmit: console.log,
// });

return (
<Formiz connect={form} autoForm>
<Stack spacing={4}>
<FieldUpload name="file" label="File" />
<Box>
<Button type="submit">Submit</Button>
</Box>
</Stack>
</Formiz>
);
};
// return (
// <Formiz connect={form} autoForm>
// <Stack spacing={4}>
// <FieldUpload name="file" label="File" />
// <Box>
// <Button type="submit">Submit</Button>
// </Box>
// </Stack>
// </Formiz>
// );
// };

export const WithPreview = () => {
const file: FieldUploadValue = {
fileUrl:
'https://plus.unsplash.com/premium_photo-1674593231084-d8b27596b134?auto=format&fit=crop&q=60&w=800&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxlZGl0b3JpYWwtZmVlZHwyfHx8ZW58MHx8fHx8',
name: 'mon-image',
};
// export const WithPreview = () => {
// const file: FieldUploadValue = {
// fileUrl:
// 'https://plus.unsplash.com/premium_photo-1674593231084-d8b27596b134?auto=format&fit=crop&q=60&w=800&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxlZGl0b3JpYWwtZmVlZHwyfHx8ZW58MHx8fHx8',
// name: 'mon-image',
// };

const form = useForm({
initialValues: {
file: file,
},
onSubmit: console.log,
});
// const form = useForm({
// initialValues: {
// file: file,
// },
// onSubmit: console.log,
// });

return (
<Formiz connect={form} autoForm>
<Stack spacing={4}>
<FieldUpload name="file" label="File" />
<FieldUploadPreview uploaderName="file" />
<Box>
<Button type="submit">Submit</Button>
</Box>
</Stack>
</Formiz>
);
};
// return (
// <Formiz connect={form} autoForm>
// <Stack spacing={4}>
// <FieldUpload name="file" label="File" />
// <FieldUploadPreview uploaderName="file" />
// <Box>
// <Button type="submit">Submit</Button>
// </Box>
// </Stack>
// </Formiz>
// );
// };

0 comments on commit 48a85ea

Please sign in to comment.