feat: "Modalka" drag&drop

This commit is contained in:
IlyaDoronin 2023-08-16 17:01:29 +03:00
parent 04a3719224
commit ba13661795
2 changed files with 75 additions and 41 deletions

@ -14,8 +14,10 @@ import * as React from "react";
import UnsplashIcon from "../../assets/icons/Unsplash.svg"; import UnsplashIcon from "../../assets/icons/Unsplash.svg";
import type { DragEvent } from "react";
interface ModalkaProps { interface ModalkaProps {
imgHC: (imgInp: HTMLInputElement) => void; imgHC: (imgInp: FileList | null) => void;
} }
const Modalka: React.FC<ModalkaProps> = ({ imgHC }) => { const Modalka: React.FC<ModalkaProps> = ({ imgHC }) => {
@ -29,6 +31,13 @@ const Modalka: React.FC<ModalkaProps> = ({ imgHC }) => {
setReady(true); setReady(true);
}; };
const handleDrop = (event: DragEvent<HTMLDivElement>) => {
event.preventDefault();
event.stopPropagation();
imgHC(event.dataTransfer.files);
};
return ( return (
<Box <Box
sx={{ sx={{
@ -58,13 +67,17 @@ const Modalka: React.FC<ModalkaProps> = ({ imgHC }) => {
</Typography> </Typography>
<ButtonBase component="label" sx={{ justifyContent: "flex-start" }}> <ButtonBase component="label" sx={{ justifyContent: "flex-start" }}>
<input <input
onChange={(event) => imgHC(event.target)} onChange={(event) => imgHC(event.target.files)}
hidden hidden
accept="image/*" accept="image/*"
multiple multiple
type="file" type="file"
/> />
<Box <Box
onDragOver={(event: DragEvent<HTMLDivElement>) =>
event.preventDefault()
}
onDrop={handleDrop}
ref={dropZone} ref={dropZone}
sx={{ sx={{
width: "580px", width: "580px",
@ -149,9 +162,9 @@ export default function UploadImage() {
const [open, setOpen] = React.useState(false); const [open, setOpen] = React.useState(false);
const handleOpen = () => setOpen(true); const handleOpen = () => setOpen(true);
const handleClose = () => setOpen(false); const handleClose = () => setOpen(false);
const imgHC = (imgInp: HTMLInputElement) => { const imgHC = (files: FileList | null) => {
if (imgInp.files) { if (files) {
const fileArray = Array.from(imgInp.files); const fileArray = Array.from(files);
const [file] = fileArray; const [file] = fileArray;
setImg(URL.createObjectURL(file)); setImg(URL.createObjectURL(file));
handleClose(); handleClose();
@ -159,6 +172,13 @@ export default function UploadImage() {
}; };
const [img, setImg] = React.useState(""); const [img, setImg] = React.useState("");
const handleDrop = (event: DragEvent<HTMLDivElement>) => {
event.preventDefault();
event.stopPropagation();
imgHC(event.dataTransfer.files);
};
return ( return (
<Box sx={{ padding: "20px" }}> <Box sx={{ padding: "20px" }}>
<Typography <Typography
@ -176,9 +196,14 @@ export default function UploadImage() {
sx={{ width: "100%", maxWidth: "260px" }} sx={{ width: "100%", maxWidth: "260px" }}
> >
{img ? ( {img ? (
<img width="400" src={img} /> <img
src={img}
alt="img"
style={{ width: "100%", maxWidth: "400px" }}
/>
) : ( ) : (
<UploadBox <UploadBox
handleDrop={handleDrop}
sx={{ maxWidth: "260px" }} sx={{ maxWidth: "260px" }}
icon={<UploadIcon />} icon={<UploadIcon />}
text="5 MB максимум" text="5 MB максимум"

@ -1,19 +1,23 @@
import {Box, IconButton, Typography, useTheme} from "@mui/material"; import { Box, Typography, useTheme } from "@mui/material";
import { SxProps, Theme } from "@mui/material/styles"; import { SxProps, Theme } from "@mui/material/styles";
import type { DragEvent } from "react";
interface Props { interface Props {
sx?: SxProps<Theme>; sx?: SxProps<Theme>;
icon: React.ReactNode; icon: React.ReactNode;
handleDrop?: (event: DragEvent<HTMLDivElement>) => void;
text?: string; text?: string;
ref?: any; ref?: any;
} }
export default function UploadBox({ sx, icon, text, ref }: Props) { export default function UploadBox({ sx, icon, text, ref, handleDrop }: Props) {
const theme = useTheme(); const theme = useTheme();
return ( return (
<Box <Box
onDragOver={(event: DragEvent<HTMLDivElement>) => event.preventDefault()}
onDrop={handleDrop}
ref={ref} ref={ref}
sx={{ sx={{
width: "100%", width: "100%",
@ -26,10 +30,12 @@ export default function UploadBox({ sx, icon, text, ref }: Props) {
border: `1px solid ${theme.palette.grey2.main}`, border: `1px solid ${theme.palette.grey2.main}`,
borderRadius: "8px", borderRadius: "8px",
...sx, ...sx,
}}> }}
>
{icon} {icon}
<Typography sx={{ <Typography
sx={{
position: "absolute", position: "absolute",
right: "10px", right: "10px",
bottom: "10px", bottom: "10px",
@ -37,7 +43,10 @@ export default function UploadBox({ sx, icon, text, ref }: Props) {
fontSize: "16px", fontSize: "16px",
lineHeight: "19px", lineHeight: "19px",
textDecoration: "underline", textDecoration: "underline",
}}>{text}</Typography> }}
>
{text}
</Typography>
</Box> </Box>
); );
} }