@chayns-components/core
Version:
A set of beautiful React components for developing your own applications with chayns.
176 lines • 5.97 kB
JavaScript
import React, { forwardRef, useCallback, useImperativeHandle, useMemo, useState } from 'react';
import { filterDuplicateFile, filterDuplicateFileUrls, isValidFileType } from '../../utils/file';
import { StyledFileInput } from './FileInput.styles';
import FileList from '../file-list/FileList';
import FileSelect from '../file-select/FileSelect';
export const TSIMG_FILE_TYPES = 'image/png, image/jpg, image/jpeg, image/gif, image/webp, image/svg+xml, image/avif';
export const STREAMINGSERVICE_FILE_TYPES = 'video/mp4, video/webm, video/avi, video/flv, video/wmv, video/mpg, video/quicktime';
const FileInput = /*#__PURE__*/forwardRef(({
fileSelectionIcons = ['fa fa-upload'],
imageSelectIcons = ['ts-image'],
fileTypes,
onMaxFilesReached,
maxFiles,
onRemove,
files,
isDisabled,
maxFileSizeInMB,
onAdd,
fileSelectionPlaceholder = 'Dateien hochladen',
imageSelectPlaceholder,
shouldPreventImageUpload = false,
shouldAllowDownload,
shouldEnableKeyboardHighlighting
}, ref) => {
const [internalFiles, setInternalFiles] = useState([]);
const [internalImages, setInternalImages] = useState([]);
const handleInputClear = () => {
setInternalFiles([]);
setInternalImages([]);
};
useImperativeHandle(ref, () => ({
clear: handleInputClear
}), []);
const handleAddImages = useCallback(images => {
const newImages = [];
images.forEach(image => {
if (!filterDuplicateFileUrls({
files: internalImages,
newFile: image
})) {
newImages.push(image);
}
});
let tmp = newImages;
if (maxFiles) {
tmp = newImages.slice(0, maxFiles - (internalFiles.length + internalImages.length + (files?.length ?? 0)));
}
if (tmp.length > 0 && typeof onAdd === 'function') {
onAdd(tmp);
}
setInternalImages(prevState => [...prevState, ...tmp]);
}, [files?.length, internalFiles.length, internalImages, maxFiles, onAdd]);
const handleAddFiles = useCallback(newFiles => {
const newFileItems = [];
newFiles.forEach(file => {
if (fileTypes && !isValidFileType({
file,
types: fileTypes
})) {
return;
}
if (file && !filterDuplicateFile({
files: internalFiles,
newFile: file
})) {
newFileItems.push(file);
}
});
let tmp = newFileItems;
if (maxFiles) {
tmp = newFileItems.slice(0, maxFiles - (internalFiles.length + (files?.length ?? 0)));
}
if (tmp.length > 0 && typeof onAdd === 'function') {
onAdd(tmp);
}
setInternalFiles(prevState => [...prevState, ...tmp]);
}, [fileTypes, files?.length, internalFiles, maxFiles, onAdd]);
const handleAdd = useCallback(newFiles => {
if (Array.isArray(newFiles) && newFiles.length > 0) {
if (newFiles[0] && 'url' in newFiles[0]) {
handleAddImages(newFiles);
} else {
handleAddFiles(newFiles);
}
}
}, [handleAddFiles, handleAddImages]);
const handleDeleteFile = useCallback(id => {
let fileToDelete;
const filteredFiles = internalFiles.filter(file => {
const {
name
} = file;
if (name === id) {
fileToDelete = file;
}
return name !== id;
});
setInternalFiles(filteredFiles);
if (!fileToDelete) {
const filteredImages = internalImages.filter(image => {
if (image.name === id) {
fileToDelete = image;
}
return image.name !== id;
});
setInternalImages(filteredImages);
}
if (!fileToDelete) {
files?.forEach(file => {
if (file.id === id || file.name === id) {
fileToDelete = file;
}
});
}
if (!fileToDelete || typeof onRemove !== 'function') {
return;
}
onRemove(fileToDelete);
}, [files, internalFiles, internalImages, onRemove]);
const internalIsDisabled = useMemo(() => {
if (isDisabled) {
return true;
}
if (maxFiles) {
if (internalFiles.length + internalImages.length >= maxFiles) {
if (typeof onMaxFilesReached === 'function') {
onMaxFilesReached();
}
return true;
}
}
return false;
}, [internalFiles.length, internalImages.length, isDisabled, maxFiles, onMaxFilesReached]);
const filesToDisplay = useMemo(() => {
const items = internalFiles.map(file => ({
id: file.name,
name: file.name,
size: file.size,
mimeType: file.type,
source: file
}));
internalImages.forEach(image => {
items.push({
id: image.name ?? image.url,
name: image.name ?? image.url,
size: image.size ?? 0,
mimeType: 'image/png',
source: image.url
});
});
files?.forEach(file => {
items.push(file);
});
return items;
}, [files, internalFiles, internalImages]);
return useMemo(() => /*#__PURE__*/React.createElement(StyledFileInput, null, /*#__PURE__*/React.createElement(FileSelect, {
shouldPreventImageUpload: shouldPreventImageUpload,
shouldEnableKeyboardHighlighting: shouldEnableKeyboardHighlighting,
maxFiles: maxFiles,
fileTypes: fileTypes,
fileSelectionIcons: fileSelectionIcons,
fileSelectionPlaceholder: fileSelectionPlaceholder,
imageSelectIcons: imageSelectIcons,
imageSelectPlaceholder: imageSelectPlaceholder,
maxFileSizeInMB: maxFileSizeInMB,
isDisabled: internalIsDisabled,
onAdd: handleAdd
}), /*#__PURE__*/React.createElement(FileList, {
files: filesToDisplay,
onRemove: handleDeleteFile,
shouldAllowDownload: shouldAllowDownload
})), [shouldPreventImageUpload, shouldEnableKeyboardHighlighting, maxFiles, fileTypes, fileSelectionIcons, fileSelectionPlaceholder, imageSelectIcons, imageSelectPlaceholder, maxFileSizeInMB, internalIsDisabled, handleAdd, filesToDisplay, handleDeleteFile, shouldAllowDownload]);
});
FileInput.displayName = 'FileInput';
export default FileInput;
//# sourceMappingURL=FileInput.js.map