176 lines
4.4 KiB
TypeScript
176 lines
4.4 KiB
TypeScript
import {
|
|
DragEventHandler,
|
|
RefObject,
|
|
} from 'react';
|
|
|
|
import {
|
|
Box,
|
|
BoxProps,
|
|
Center,
|
|
Flex,
|
|
HStack,
|
|
Image,
|
|
} from '@chakra-ui/react';
|
|
import {
|
|
MdHighlightOff,
|
|
MdUploadFile,
|
|
} from 'react-icons/md';
|
|
|
|
import { FormGroup } from '@/components/form/FormGroup';
|
|
import { UseFormidableReturn } from '@/components/form/Formidable';
|
|
import { DataUrlAccess } from '@/utils/data-url-access';
|
|
|
|
export type DragNdropProps = {
|
|
onFilesSelected?: (file: File[]) => void;
|
|
onUriSelected?: (uri: string) => void;
|
|
width?: string;
|
|
height?: string;
|
|
};
|
|
|
|
export const DragNdrop = ({
|
|
onFilesSelected = () => { },
|
|
onUriSelected = () => { },
|
|
width = '100px',
|
|
height = '100px',
|
|
}: DragNdropProps) => {
|
|
const handleFileChange = (event) => {
|
|
const selectedFiles = event.target.files;
|
|
if (selectedFiles && selectedFiles.length > 0) {
|
|
const newFiles: File[] = Array.from(selectedFiles);
|
|
onFilesSelected(newFiles);
|
|
}
|
|
};
|
|
const handleDrop = (eventInput: any) => {
|
|
const event = eventInput as DragEvent;
|
|
event.preventDefault();
|
|
const droppedFiles = event.dataTransfer?.files;
|
|
console.log('drop ...' + droppedFiles?.length);
|
|
if (droppedFiles && droppedFiles?.length > 0) {
|
|
const newFiles: File[] = Array.from(droppedFiles);
|
|
onFilesSelected(newFiles);
|
|
} else {
|
|
console.log(`drop types: ${event.dataTransfer?.types}`);
|
|
const listUri = event.dataTransfer?.getData('text/uri-list');
|
|
console.log(`listUri: ${listUri}`);
|
|
if (!listUri) {
|
|
return;
|
|
}
|
|
onUriSelected(listUri);
|
|
}
|
|
};
|
|
|
|
return (
|
|
<Box
|
|
width={width}
|
|
height={height}
|
|
border="2px"
|
|
borderRadius="5px"
|
|
borderStyle="dashed"
|
|
onDrop={handleDrop}
|
|
onDragOver={(event) => event.preventDefault()}
|
|
>
|
|
<label htmlFor="browse">
|
|
<Box paddingY="15%" height="100%" cursor="pointer">
|
|
<Center>
|
|
<MdUploadFile size="50%" />
|
|
</Center>
|
|
<Center>
|
|
<input
|
|
type="file"
|
|
hidden
|
|
id="browse"
|
|
onChange={handleFileChange}
|
|
//accept=".pdf,.docx,.pptx,.txt,.xlsx"
|
|
multiple
|
|
/>
|
|
Browse files
|
|
</Center>
|
|
</Box>
|
|
</label>
|
|
</Box>
|
|
);
|
|
};
|
|
|
|
export type CenterIconProps = BoxProps & {
|
|
children: any;
|
|
sizeIcon?: string;
|
|
};
|
|
|
|
export const CenterIcon = ({
|
|
children,
|
|
sizeIcon = '15px',
|
|
...rest
|
|
}: CenterIconProps) => {
|
|
return (
|
|
<Box position="relative" w={sizeIcon} h={sizeIcon} flex="none" {...rest}>
|
|
<Box
|
|
w={sizeIcon}
|
|
h={sizeIcon}
|
|
position="absolute"
|
|
top="50%"
|
|
left="50%"
|
|
transform="translate(-50%, -50%)"
|
|
>{children}</Box>
|
|
</Box>
|
|
);
|
|
};
|
|
|
|
export type FormCoversProps = {
|
|
form: UseFormidableReturn;
|
|
variableName: string;
|
|
ref?: RefObject<any>;
|
|
label?: string;
|
|
isRequired?: boolean;
|
|
onFilesSelected?: (files: File[]) => void;
|
|
onUriSelected?: (uri: string) => void;
|
|
onRemove?: (index: number) => void;
|
|
};
|
|
|
|
export const FormCovers = ({
|
|
form,
|
|
variableName,
|
|
ref,
|
|
onFilesSelected = () => { },
|
|
onUriSelected = () => { },
|
|
onRemove = () => { },
|
|
...rest
|
|
}: FormCoversProps) => {
|
|
const urls =
|
|
DataUrlAccess.getListThumbnailUrl(form.values[variableName]) ?? [];
|
|
return (
|
|
<FormGroup
|
|
isModify={form.isModify[variableName]}
|
|
onRestore={() => form.restoreValue({ [variableName]: true })}
|
|
{...rest}
|
|
>
|
|
<HStack wrap="wrap" width="full">
|
|
{urls.map((data, index) => (
|
|
<Flex align="flex-start" key={data}>
|
|
<Box width="125px" height="125px" position="relative">
|
|
<Box width="125px" height="125px" position="absolute">
|
|
<CenterIcon
|
|
width="125px"
|
|
sizeIcon="100%"
|
|
zIndex="+1"
|
|
color="#00000020"
|
|
_hover={{ color: 'red' }}
|
|
onClick={() => onRemove && onRemove(index)}
|
|
><MdHighlightOff /></CenterIcon>
|
|
</Box>
|
|
<Image loading="lazy" src={data} boxSize="full" />
|
|
</Box>
|
|
</Flex>
|
|
))}
|
|
<Flex align="flex-start" key="data">
|
|
<DragNdrop
|
|
height="125px"
|
|
width="125px"
|
|
onFilesSelected={onFilesSelected}
|
|
onUriSelected={onUriSelected}
|
|
/>
|
|
</Flex>
|
|
</HStack>
|
|
</FormGroup>
|
|
);
|
|
};
|