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,43 +1,52 @@
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;
text?: string; handleDrop?: (event: DragEvent<HTMLDivElement>) => void;
ref?: any; text?: string;
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
ref={ref} onDragOver={(event: DragEvent<HTMLDivElement>) => event.preventDefault()}
sx={{ onDrop={handleDrop}
width: "100%", ref={ref}
height: "120px", sx={{
position: "relative", width: "100%",
display: "flex", height: "120px",
justifyContent: "center", position: "relative",
alignItems: "center", display: "flex",
backgroundColor: theme.palette.background.default, justifyContent: "center",
border: `1px solid ${theme.palette.grey2.main}`, alignItems: "center",
borderRadius: "8px", backgroundColor: theme.palette.background.default,
...sx, border: `1px solid ${theme.palette.grey2.main}`,
}}> borderRadius: "8px",
{icon} ...sx,
}}
>
{icon}
<Typography sx={{ <Typography
position: "absolute", sx={{
right: "10px", position: "absolute",
bottom: "10px", right: "10px",
color: theme.palette.orange.main, bottom: "10px",
fontSize: "16px", color: theme.palette.orange.main,
lineHeight: "19px", fontSize: "16px",
textDecoration: "underline", lineHeight: "19px",
}}>{text}</Typography> textDecoration: "underline",
</Box> }}
); >
} {text}
</Typography>
</Box>
);
}