import { UploadField } from '@megafon/ui-core';
Компонент для выбора файлов. Пользователь может перетащить в него файлы или загрузить по кнопке.
<UploadField required onChange={handleChange} description="Дополнительная информация" /> <UploadField disabled onChange={handleChange} description="Дополнительная информация" />
import { UploadFileItem } from '@megafon/ui-core';
Компонент используется для отображения загружаемого файла.
<UploadFileItem fileName='Файл 1.pdf' fileSize={2621440} loadingProgress={5} /> <UploadFileItem fileName='Файл 1.xls' fileSize={2621440} loadingProgress={20} /> <UploadFileItem fileName='Файл 1.doc' fileSize={2621440} loadingProgress={40} /> <UploadFileItem fileName='Файл 1.ppt' fileSize={2621440} loadingProgress={60} /> <UploadFileItem fileName='Файл 1.jpg' fileSize={2621440} loadingProgress={80} /> <UploadFileItem fileName='Файл 1.xxx' fileSize={2621440} loadingProgress={100} />
<UploadFileItem fileName='Файл 1.fig' fileSize={2621440} errorText="Неправильный формат файла" />
<UploadFileItem fileName='Файл 1.doc' fileSize={2621440} isChecking />
import { Notification, UploadField, UploadFileItem } from '@megafon/ui-core';
Пример формы с использованием компонентов UploadField, UploadFileItem и Notification.
Обработка загруженных файлов должна быть реализована в компоненте-обертке.
<UploadFormDemo maxFiles={2} maxFileSizeMb={1} allowedExtensions={['doc', 'pdf']} />
Код UploadFormDemoimport React from 'react';import { Notification, UploadField, UploadFileItem } from '@megafon/ui-core';import AttentionIcon from '@megafon/ui-icons/system-24-attention_invert_24.svg';const filesMock = [fileMockPdf, fileMockDoc, fileMockJpeg];type PropsType = {maxFiles?: number;maxFileSizeMb?: number;allowedExtensions?: string[];};type FormErrorsType = { [param: string]: string[] };const generateUniqueID = (file: File) => `${file.name}-${file.lastModified}-${file.size}`;const getExtension = (fileName: string) => fileName.toLowerCase().split('.').pop();const megabytesToBytes = (megabytes: number) => megabytes * 1024 * 1024;const UploadFormDemo: React.FC<PropsType> = ({ maxFiles, maxFileSizeMb, allowedExtensions = [] }) => {const [attachedFiles, setAttachedFiles] = React.useState<File[]>(filesMock);const [validationErrors, setValidationErrors] = React.useState<FormErrorsType>({});const [warningText, setWarningText] = React.useState('');const validateFiles = React.useCallback((files: File[]): { warning: string; errors: FormErrorsType } => {let warning = '';const errors: FormErrorsType = {};if (maxFiles && files.length > maxFiles) {warning = `Максимальное количество файлов: ${maxFiles}`;}files.forEach(file => {const fileExtension = getExtension(file.name);const fileSize = file.size;const fileErrors: string[] = [];if (allowedExtensions.length > 0 && fileExtension && !allowedExtensions.includes(fileExtension)) {fileErrors.push('Неправильный формат файла');}if (maxFileSizeMb && fileSize > megabytesToBytes(maxFileSizeMb)) {fileErrors.push(`Размер загружаемого файла не должен превышать ${maxFileSizeMb} Мб`);}if (fileErrors.length > 0) {errors[generateUniqueID(file)] = fileErrors;}});return {warning,errors,};},[maxFiles, allowedExtensions, maxFileSizeMb],);const handleChange = (uploadFiles: File[]) => {const files = [...attachedFiles, ...uploadFiles];setAttachedFiles(files);};const handleFileDelete = (index: number) => () => {const filesCopy = [...attachedFiles];filesCopy.splice(index, 1);setAttachedFiles(filesCopy);};const hideWarning = () => {setWarningText('');};React.useEffect(() => {const { warning, errors } = validateFiles(attachedFiles);setValidationErrors(errors);setWarningText(warning);}, [validateFiles, attachedFiles]);return (<div style={{ display: 'flex', flexDirection: 'column', gap: '16px', maxWidth: '455px' }}><UploadFieldonChange={handleChange}description={`Максимум ${maxFiles} файла не более ${maxFileSizeMb} MB каждый`}disabled={maxFiles ? attachedFiles.length >= maxFiles : false}/>{attachedFiles.map((file, index) => {const id = generateUniqueID(file);return (<UploadFileItemkey={id}fileName={file.name}fileSize={file.size}loadingProgress={validationErrors[id] ? 0 : 100}onDelete={handleFileDelete(index)}errorText={validationErrors[id] ? validationErrors[id].join(', ') : undefined}/>);})}{!!warningText && (<Notificationtype="warning"title={warningText}hasCloseButtonicon={<AttentionIcon />}onClose={hideWarning}/>)}</div>);};