This commit is contained in:
nm1 2026-11-04 00:33:23 +05:30
commit 74ae93a96e
2 changed files with 94691 additions and 0 deletions

View file

@ -0,0 +1,384 @@
Drag and Drop File Upload
[react-drop-file-input-main.zip](../../../../_resources/react-drop-file-input-main.zip)
- JSX
```JSX
import React, { useRef, useState } from 'react';
import PropTypes from 'prop-types';
import './drop-file-input.css';
import { ImageConfig } from '../../config/ImageConfig';
import uploadImg from '../../assets/cloud-upload-regular-240.png';
const DropFileInput = props => {
const wrapperRef = useRef(null);
const [fileList, setFileList] = useState([]);
const onDragEnter = () => wrapperRef.current.classList.add('dragover');
const onDragLeave = () => wrapperRef.current.classList.remove('dragover');
const onDrop = () => wrapperRef.current.classList.remove('dragover');
const onFileDrop = (e) => {
const newFile = e.target.files[0];
if (newFile) {
const updatedList = [...fileList, newFile];
setFileList(updatedList);
props.onFileChange(updatedList);
}
}
const fileRemove = (file) => {
const updatedList = [...fileList];
updatedList.splice(fileList.indexOf(file), 1);
setFileList(updatedList);
props.onFileChange(updatedList);
}
return (
<>
<div
ref={wrapperRef}
className="drop-file-input"
onDragEnter={onDragEnter}
onDragLeave={onDragLeave}
onDrop={onDrop}
>
<div className="drop-file-input__label">
<img src={uploadImg} alt="" />
<p>Drag & Drop your files here</p>
</div>
<input type="file" value="" onChange={onFileDrop}/>
</div>
{
fileList.length > 0 ? (
<div className="drop-file-preview">
<p className="drop-file-preview__title">
Ready to upload
</p>
{
fileList.map((item, index) => (
<div key={index} className="drop-file-preview__item">
<img src={ImageConfig[item.type.split('/')[1]] || ImageConfig['default']} alt="" />
<div className="drop-file-preview__item__info">
<p>{item.name}</p>
<p>{item.size}B</p>
</div>
<span className="drop-file-preview__item__del" onClick={() => fileRemove(item)}>x</span>
</div>
))
}
</div>
) : null
}
</>
);
}
DropFileInput.propTypes = {
onFileChange: PropTypes.func
}
export default DropFileInput;
```
&nbsp;
CSS
```css
.drop-file-input {
position: relative;
width: 400px;
height: 200px;
border: 2px dashed var(--border-color);
border-radius: 20px;
display: flex;
align-items: center;
justify-content: center;
background-color: var(--input-bg);
}
.drop-file-input input {
opacity: 0;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
cursor: pointer;
}
.drop-file-input:hover,
.drop-file-input.dragover {
opacity: 0.6;
}
.drop-file-input__label {
text-align: center;
color: var(--txt-second-color);
font-weight: 600;
padding: 10px;
}
.drop-file-input__label img {
width: 100px;
}
.drop-file-preview {
margin-top: 30px;
}
.drop-file-preview p {
font-weight: 500;
}
.drop-file-preview__title {
margin-bottom: 20px;
}
.drop-file-preview__item {
position: relative;
display: flex;
margin-bottom: 10px;
background-color: var(--input-bg);
padding: 15px;
border-radius: 20px;
}
.drop-file-preview__item img {
width: 50px;
margin-right: 20px;
}
.drop-file-preview__item__info {
display: flex;
flex-direction: column;
justify-content: space-between;
}
.drop-file-preview__item__del {
background-color: var(--box-bg);
width: 40px;
height: 40px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
position: absolute;
right: 10px;
top: 50%;
transform: translateY(-50%);
box-shadow: var(--box-shadow);
cursor: pointer;
opacity: 0;
transition: opacity 0.3s ease;
}
.drop-file-preview__item:hover .drop-file-preview__item__del {
opacity: 1;
}
```
---
&nbsp;
- For multiple file uploading use this and to limit the height of preview file list:
```jsx
import React, { useRef, useState } from "react";
import PropTypes from "prop-types";
import "./drop-file-input.css";
import { ImageConfig } from "../../config/ImageConfig";
import uploadImg from "../../assets/cloud-upload-regular-240.png";
const DropFileInput = (props) => {
const wrapperRef = useRef(null);
const [fileList, setFileList] = useState([]);
const onDragEnter = () => wrapperRef.current.classList.add("dragover");
const onDragLeave = () => wrapperRef.current.classList.remove("dragover");
const onDrop = () => wrapperRef.current.classList.remove("dragover");
const onFileDrop = (e) => {
const newFiles = e.target.files;
if (newFiles.length !== 0) {
const updatedList = [...fileList, ...newFiles];
setFileList(updatedList);
props.onFileChange(updatedList);
}
};
const fileRemove = (file) => {
const updatedList = [...fileList];
updatedList.splice(fileList.indexOf(file), 1);
setFileList(updatedList);
props.onFileChange(updatedList);
};
return (
<>
<div
ref={wrapperRef}
className="drop-file-input"
onDragEnter={onDragEnter}
onDragLeave={onDragLeave}
onDrop={onDrop}
>
<div className="drop-file-input__label">
<img src={uploadImg} alt="" />
<p>Drag & Drop your files here</p>
</div>
<input type="file" value="" multiple onChange={onFileDrop} />
</div>
{fileList.length > 0 ? (
<div className="drop-file-preview">
<p className="drop-file-preview__title">Ready to upload</p>
{fileList.map((item, index) => (
<div key={index} className="drop-file-preview__item">
<img
src={
ImageConfig[item.type.split("/")[1]] || ImageConfig["default"]
}
alt=""
/>
<div className="drop-file-preview__item__info">
<p>{item.name}</p>
<p>{item.size}B</p>
</div>
<span
className="drop-file-preview__item__del"
onClick={() => fileRemove(item)}
>
x
</span>
</div>
))}
</div>
) : null}
</>
);
};
DropFileInput.propTypes = {
onFileChange: PropTypes.func,
};
export default DropFileInput;
```
&nbsp;
CSS
```css
.drop-file-input {
position: relative;
width: 400px;
height: 200px;
border: 2px dashed var(--border-color);
border-radius: 20px;
display: flex;
align-items: center;
justify-content: center;
background-color: var(--input-bg);
}
.drop-file-input input {
opacity: 0;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
cursor: pointer;
}
.drop-file-input:hover,
.drop-file-input.dragover {
opacity: 0.6;
}
.drop-file-input__label {
text-align: center;
color: var(--txt-second-color);
font-weight: 600;
padding: 10px;
}
.drop-file-input__label img {
width: 100px;
}
.drop-file-preview {
margin-top: 30px;
max-height: 70%;
overflow-y: auto;
}
.drop-file-preview p {
font-weight: 500;
}
.drop-file-preview__title {
margin-bottom: 20px;
}
.drop-file-preview__item {
position: relative;
display: flex;
margin-bottom: 10px;
background-color: var(--input-bg);
padding: 15px;
border-radius: 20px;
}
.drop-file-preview__item img {
width: 50px;
margin-right: 20px;
}
.drop-file-preview__item__info {
display: flex;
flex-direction: column;
justify-content: space-between;
}
.drop-file-preview__item__del {
background-color: var(--box-bg);
width: 40px;
height: 40px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
position: absolute;
right: 10px;
top: 50%;
transform: translateY(-50%);
box-shadow: var(--box-shadow);
cursor: pointer;
opacity: 0;
transition: opacity 0.3s ease;
}
.drop-file-preview__item:hover .drop-file-preview__item__del {
opacity: 1;
}
```
---

View file

@ -0,0 +1,66 @@
Toast
https://primereact.org/toast/
Here package `primereact` is used so use `npm i primereact` to install it
In Toast.jsx
```jsx
import { useEffect, useRef, useState } from "react";
import { Toast } from "primereact/toast";
// import { Button } from "primereact/button";
const ToastEle = (props) => {
const toast = useRef(null);
const { errorMessage, errorVisibility, setErrorVisibility } = props;
const showError = () => {
toast.current.show({ severity: "error", detail: errorMessage, life: 3000 });
};
useEffect(() => {
if (errorVisibility === true) {
showError();
setErrorVisibility(false);
}
}, [errorVisibility]);
return <Toast ref={toast} position="top-left" />;
};
export default ToastEle;
```
&nbsp;
In App.jsx
```jsx
import { PrimeReactProvider } from "primereact/api";
import "primereact/resources/themes/lara-light-indigo/theme.css"; // theme
// import "primeflex/primeflex.css"; // css utility
// import "primeicons/primeicons.css";
import "primereact/resources/primereact.css"; //
import ToastEle from "./Components/Toast";
function App() {
// for error message at top
const [errorVisibility, setErrorVisibility] = useState(false);
const [errorMessage, setErrorMessage] = useState("");
return(
<PrimeReactProvider>
<ToastEle
errorVisibility={errorVisibility}
errorMessage={errorMessage}
setErrorVisibility={setErrorVisibility}
/>
</PrimeReactProvider>
)
```