UNPKG

@chayns-components/core

Version:

A set of beautiful React components for developing your own applications with chayns.

176 lines 5.97 kB
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