FileUpload

FileUpload — составной загрузчик файлов на Ark FileUpload. FileUpload.Root держит набор выбранных и отклонённых файлов, скрытый инпут формы добавляет сам. Файлы попадают в него тремя путями: через кнопку (FileUpload.Trigger), перетаскиванием (FileUpload.Dropzone) и вставкой из буфера — Ctrl+V, пока фокус внутри Root.

Готового вида у выбранных файлов нет — он собирается из частей. FileUpload.ItemGroup рендерит список, внутри FileUpload.Item свободно комбинируются превью, имя, размер, кнопка удаления, прогресс и ошибка. Где стоит список — над зоной, под ней или вместо неё — решает порядок частей в Root, а строками или плитками показывать файлы — layout группы.

Компонент только выбирает файлы: наружу он отдаёт File[] (onFileChange, onFileAccept), а отправку на сервер ведёт потребитель и возвращает её ход пропсами status и progress у FileUpload.Item. По умолчанию выбирается один файл — множественный выбор включает maxFiles.

Перетащите файлы сюда, нажмите для выбора или вставьте из буфера

Анатомия

FileUpload.Root
FileUpload.Label
FileUpload.Dropzone
FileUpload.Trigger
FileUpload.ItemGroup (ul)
FileUpload.Item (li)
FileUpload.ItemPreview
FileUpload.ItemName
FileUpload.ItemSize
FileUpload.ItemStatus
FileUpload.ItemDelete
FileUpload.ItemProgress
FileUpload.ItemError
HiddenInput

Примеры

Через кнопку

FileUpload.Trigger превращает переданную кнопку в триггер диалога выбора — зона для перетаскивания при этом не обязательна. Внутрь кладётся Button.Root или ButtonIcon с любыми визуальными пропсами. Вставка из буфера работает и здесь: достаточно, чтобы фокус стоял на кнопке.

Плитки над зоной

layout="cards" показывает файлы плитками с превью: кнопка удаления ложится в угол миниатюры, имя — под ней. Список стоит над зоной просто потому, что FileUpload.ItemGroup записан в Root первым.

Перетащите фотографии или нажмите для выбора — до 6 штук

Превью вместо зоны

Одиночная картинка (обложка, аватар): после выбора зона уступает место превью. FileUpload.Context отдаёт состояние загрузчика рендер-функции — по acceptedFiles решается, показывать ли зону. Габариты плитки и превью меняются обычными className / style на FileUpload.Item и FileUpload.ItemPreview.

Перетащите изображение или нажмите для выбора

Вставка из соседнего поля

Внутри Root вставка из буфера работает сама — в том числе из вложенного поля ввода: текст вставляется в поле, файлы уходят в загрузчик. Если поле стоит снаружи, состояние поднимается хуком useFileUpload и передаётся в FileUpload.RootProvider вместо Root, а поле в своём onPaste зовёт setClipboardFiles: метод возвращает true, когда в буфере были файлы.

Статус отправки

Загрузчик сам ничего не отправляет: потребитель начинает отправку в onFileAccept и возвращает её ход в FileUpload.Item — status (uploading / success / error) и progress в процентах. FileUpload.ItemProgress рисует полосу, пока файл отправляется (без progress — бегущую), FileUpload.ItemStatus — значок статуса, FileUpload.ItemError с текстом — причину неудачи.

Файлы до 1 МБ отправятся успешно, крупнее — с ошибкой

Ограничения и отклонённые файлы

accept, maxFiles, maxFileSize / minFileSize и validate отсеивают файлы при выборе. Не прошедшие проверку в набор не попадают — их показывает отдельная группа type="rejected", а FileUpload.ItemError без текста сам подставляет причину: тип, размер, лимит или повтор. Список отклонённых живёт до следующего выбора.

Только изображения, не больше двух, каждое до 1 МБ

Ошибка и отключённый

invalid красит рамку зоны — сам текст ошибки поля выводит потребитель. disabled отключает загрузчик целиком: выбор, перетаскивание, вставка и удаление не работают.

Приложите хотя бы один файл
Загрузка недоступна

API

PropTypeDefault
children*

Части загрузчика в любом порядке и наборе: Label, Dropzone, Trigger, ItemGroup, Context

ReactNode-
classNamestring-
styleCSSProperties-
name

Имя скрытого <input type="file"> — под ним файлы уходят при нативной отправке формы

string-
accept

Допустимые типы файлов: MIME-тип ("image/*"), массив типов или карта «тип → расширения» ({ "image/*": [".png", ".jpg"] }). Не подошедшие файлы попадают в отклонённые

ArkFileUploadProps["accept"]-
maxFiles

Сколько файлов можно выбрать. Больше одного — выбор становится множественным, новые файлы добавляются к уже выбранным

number1
maxFileSize

Максимальный размер файла в байтах

number-
minFileSize

Минимальный размер файла в байтах

number-
validate

Своя проверка файла: возвращает коды или тексты ошибок (файл уходит в отклонённые, текст показывает FileUpload.ItemError) либо null

( file: File, details: FileUploadFileValidateDetails, ) => FileUploadFileError[] | null-
acceptedFiles

Выбранные файлы — контролируемый режим. Пара с onFileChange

File[]-
defaultAcceptedFiles

Начальный набор файлов для неконтролируемого режима

File[]-
onFileChange

Любое изменение набора: получает { acceptedFiles, rejectedFiles } после выбора, перетаскивания, вставки и удаления

(details: FileUploadFileChangeDetails) => void-
onFileAccept

Набор принятых файлов изменился: получает { files } — весь текущий набор, а не только добавленные. Отсюда обычно начинают отправку новых

(details: FileUploadFileAcceptDetails) => void-
onFileReject

Файлы отклонены: получает { files }, у каждого — файл и коды причин

(details: FileUploadFileRejectDetails) => void-
disabled

Отключает загрузчик: выбор, перетаскивание, вставка и удаление не работают

boolean-
invalid

Состояние ошибки — дроп-зона получает красную рамку

boolean-
required

Обязательное поле формы

boolean-

FileUpload.RootProvider

Тот же Root, но состояние приходит снаружи — из хука useFileUpload (он принимает те же пропсы, что Root). Нужен, когда с файлами работают соседи загрузчика: поле вне Root добавляет вставленные файлы, кнопка формы читает acceptedFiles.

PropTypeDefault
value*

Состояние загрузчика из хука useFileUpload

UseFileUploadReturn-
children*

Части загрузчика — те же, что у FileUpload.Root

ReactNode-
classNamestring-
styleCSSProperties-

FileUpload.Label

Подпись загрузчика в стиле Field.Label.

PropTypeDefault
children*

Подпись загрузчика — привязана к скрытому инпуту

ReactNode-

FileUpload.Dropzone

Область для перетаскивания. По клику и Enter открывает диалог выбора, пока файл несут над ней — подсвечивается.

PropTypeDefault
children*

Содержимое зоны: иконка, подсказка, FileUpload.Trigger

ReactNode-
disableClick

Зона только принимает перетаскивание: клик и Enter диалог выбора не открывают. Для зоны-обёртки вокруг другого содержимого (поле комментария, уже выбранное фото)

boolean-
classNamestring-
styleCSSProperties-

FileUpload.Trigger

Делает переданную кнопку триггером диалога выбора. Работает и отдельно, и внутри FileUpload.Dropzone.

PropTypeDefault
children*

Кнопка, открывающая диалог выбора файлов, — Button.Root или ButtonIcon (элемент должен принимать проброшенные пропсы и ref)

ReactElement-

FileUpload.Context

Рендер-функция от состояния загрузчика — когда разметка зависит от выбранных файлов.

PropTypeDefault
children*

Рендер-функция от состояния загрузчика: acceptedFiles, rejectedFiles, dragging, openFilePicker(), clearFiles(), setClipboardFiles() и остальной API Ark FileUpload

(fileUpload: UseFileUploadReturn) => ReactNode-

FileUpload.ItemGroup

Список файлов — принятых или отклонённых. Пока файлов нет, не рендерится вовсе.

PropTypeDefault
children*

Рендер одного файла — возвращает FileUpload.Item с нужным набором частей

(file: File) => ReactNode-
type

Какие файлы показывает группа: принятые или отклонённые (не тот тип, размер, сверх лимита)

"accepted" | "rejected""accepted"
layout

Раскладка файлов: list — строки во всю ширину (превью, имя, размер), cards — плитки с превью в ряд

"list" | "cards""list"
classNamestring-
styleCSSProperties-

FileUpload.Item

Один файл списка. Набор частей внутри свободный; сюда же приходит статус отправки.

PropTypeDefault
file*

Файл, который показывает элемент, — аргумент рендер-функции ItemGroup

File-
children*

Части элемента в любом наборе: ItemPreview, ItemName, ItemSize, ItemStatus, ItemDelete, ItemProgress, ItemError

ReactNode-
status

Статус отправки файла на сервер. Загрузчик сам ничего не отправляет — статус ведёт потребитель: uploading показывает ItemProgress и приглушает превью, error красит рамку, значок статуса рисует ItemStatus. Без статуса файл просто выбран

FileUploadStatus-
progress

Прогресс отправки в процентах (0–100) для ItemProgress. Без значения полоса бежит без конца — когда прогресс неизвестен

number-
classNamestring-
styleCSSProperties-

FileUpload.ItemPreview

Превью файла: у изображения — миниатюра из самого файла, у остальных — иконка.

PropTypeDefault
children

Иконка для файла без превью (не изображение). По умолчанию — значок файла

ReactNode-
classNamestring-
styleCSSProperties-

FileUpload.ItemName

Имя файла в одну строку, длинное обрезается многоточием.

Компонент не принимает пропсов.

FileUpload.ItemSize

Размер файла в читаемом виде — «340 КБ», «1,2 МБ».

Компонент не принимает пропсов.

FileUpload.ItemDelete

Кнопка-крестик: убирает файл из набора. Об удалении потребитель узнаёт из onFileChange.

Компонент не принимает пропсов.

FileUpload.ItemProgress

Полоса прогресса. Видна, только пока у Item status="uploading"; заполнение берёт из его progress.

Компонент не принимает пропсов.

FileUpload.ItemStatus

Значок статуса отправки: индикатор, галочка или знак ошибки. Без статуса не рендерится.

Компонент не принимает пропсов.

FileUpload.ItemError

Текст ошибки файла: свой (children) или причины отклонения. Не рендерится, когда показывать нечего.

PropTypeDefault
children

Свой текст ошибки — обычно причина неудачной отправки. Без него у отклонённого файла показываются причины отклонения (тип, размер, лимит)

ReactNode-