• CMSnpm version

    • Overview
    • ContentBuilder
    • InviteUserForm
    • LoginForm
    • RenewPasswordForm
  • UInpm version

    • Overview
    • Accordion
    • AlertBubble
    • AnnouncementBar
    • Avatar
    • AvatarFileInput
    • Badge
    • Button
    • ButtonGroup
    • ButtonList
    • Calendar
    • Checkbox
    • CheckboxButton
    • CheckboxInput
    • CheckboxList
    • Chip
    • ColorRadio
    • ColorRadioGroup
    • Combobox
    • DatePicker
    • DatePickerInput
    • DateRangePicker
    • DateRangePickerInput
    • DatetimePicker
    • DatetimePickerInput
    • Dialog
    • Dropdown
    • Dropzone
    • ErrorMessage
    • FileInput
    • FlashMessages
    • FormComponent
    • Icon
    • IconButton
    • ImageGallery
    • InfoBox
    • Input
    • Label
    • Layout
    • Lightbox
    • ListItem
    • Loader
    • Lozenge
    • Menu
    • Message
    • Modal
    • ✅ ModalDialog
    • ✅ ModalHeader
    • MultiCombobox
    • MultiSelect
    • Pagination
    • Paper
    • Popover
    • Radio
    • RadioGroup
    • RasterImage
    • Select
    • ✅ Tabs
    • TextInput
    • TextLink
    • Textarea
    • TimePicker
    • TimePickerInput
    • Toggle
    • Tooltip
    • Typography
  • Formnpm version

    • Overview
    • AvatarFileInput
    • CheckboxButton
    • CheckboxInput
    • CheckboxList
    • ColorRadioGroup
    • Combobox
    • DatePickerInput
    • DateRangePickerInput
    • DatetimePickerInput
    • Dropzone
    • FileInput
    • Form
    • FormRenderer
    • GpsInput
    • MoneyInput
    • MultiCombobox
    • MultiSelect
    • NumberInput
    • PasswordInput
    • RadioGroup
    • Select
    • TextInput
    • Textarea
    • TimePickerInput
    • Toggle
  • DataGridnpm version

    • Overview
    • DataGrid
    • DataGridCustomExample
    • ExportButton
    • FilterList
    • Filters
    • FiltersButton
    • FulltextInput
    • HiddenColumns
    • HiddenColumnsButton
    • Pagination
    • RowCounts
    • RowsPerPageSelect
    • SelectedRowsToolbar
    • TableV2
    • ToolbarControl
    • ToolbarCustoms
    • ToolbarTabs
  • Wysiwygnpm version

    • Overview
  • Resizernpm version

    • Overview
  • Routernpm version

    • Overview
  • Corenpm version

    • Overview
  • Core-Reactnpm version

    • Overview
  • Stylesnpm version

    • Overview
  • Localizenpm version

    • Overview
  • Analyticsnpm version

    • Overview
  • Datepickernpm version

    • Overview
  • Icons-generatornpm version

    • Overview
  • Smart-addressnpm version

    • Overview
  • E2Enpm version

    • Overview
  • E2E-Playwrightnpm version

    • Overview
View source on GitLab

Dropzone

react-hook-form-bound multi-file drag-and-drop upload field. Compound component: Dropzone is the drop area and Dropzone.List renders the uploaded files. Both wrap the @uxf/ui/dropzone primitive and manage its value, isInvalid, and helperText from form state.

When to use

Use @uxf/form/dropzone for uploading one or more files via drag-and-drop or a click-to-browse area inside a @uxf/form form — it registers the field with react-hook-form via control/name, adds file-count validation (minFilesCount / maxFilesCount), and renders errors automatically. For a standalone, manually-controlled dropzone (outside a form), use the @uxf/ui/dropzone twin directly. For a single-file field use @uxf/form/file-input; for an avatar/image preview use @uxf/form/avatar-file-input.

Usage

Render Dropzone (the drop area) and Dropzone.List (the file list) against the same control and name so they share the field value:

import { Form } from "@uxf/form/form";
import { Dropzone, DropzoneValue } from "@uxf/form/dropzone";
import { FileResponse } from "@uxf/core/types";
import { getDropzoneState } from "@uxf/ui/utils/get-dropzone-state";
import { handleRejectedFiles } from "@uxf/ui/dropzone/handle-rejected-files";
import { useForm } from "react-hook-form";

// your uploader: send the file to storage, resolve with the stored file
declare function uploadFile(file: File): Promise<FileResponse>;

interface FormData {
    attachments: DropzoneValue;
}

function Example() {
    const formApi = useForm<FormData>({ defaultValues: { attachments: undefined } });
    const { status } = getDropzoneState(formApi.watch("attachments"));

    return (
        <Form formApi={formApi} id="example" onSubmit={(values) => console.log(values)}>
            <Dropzone
                accept={{ "image/png": [".png"] }}
                control={formApi.control}
                isDisabled={status === "UPLOADING"}
                isRequired
                label="Use drag and drop or click to upload"
                maxFileSize={1024 * 1024}
                name="attachments"
                onDropRejected={handleRejectedFiles}
                onUploadFile={uploadFile}
            />
            <Dropzone.List control={formApi.control} name="attachments" />
        </Form>
    );
}

Value is DropzoneValue = DropzoneFile[] | undefined (DropzoneFile from @uxf/ui/dropzone/types, which extends FileResponse with upload bookkeeping such as progress and originalFile).

Imports

  • import { Dropzone } from "@uxf/form/dropzone" — the compound component (Dropzone = drop area, Dropzone.List = list). Also exports types DropzoneProps, DropzoneListProps, DropzoneValue.
  • The two parts also resolve as deep imports if you need the named components separately: import { DropzoneInput } from "@uxf/form/dropzone/dropzone-input" and import { DropzoneList } from "@uxf/form/dropzone/dropzone-list". Prefer the compound Dropzone / Dropzone.List form (used in the stories).

Props

Dropzone (drop area) — DropzoneProps<FormData>

ControlProps<FormData> + the visual props of the @uxf/ui/dropzone twin (minus the ones this field manages: isFocused, isInvalid, onChange, value) + the field-specific props below.

Prop Type Default Description
control Control<FormData> — Required. The control from useForm.
name FieldPath<FormData> — Required. Field path in the form values.
onUploadFile (file: File, options?) => Promise<FileResponse> — Required (from the twin). Uploads a dropped file; resolves to the stored file.
rules RegisterOptions — Extra react-hook-form rules; merged with the built-in count validation (a validate function is kept and run alongside as custom).
shouldUnregister boolean — Unregister the field (drop its value) on unmount.
isRequired boolean false Requires at least minFilesCount ?? 1 file(s).
minFilesCount number — Minimum number of files. Also drives the required check (set to 0 to disable requiring a file even with isRequired).
requiredMessage string localized Message for the required check (defaults to uxf-form-dropzone:validation.required).
onChange (value: DropzoneFile[] | undefined, event?) => void — Called after the field value updates.

maxFilesCount is a twin prop (forwarded) that additionally drives the max-files validation. All other props (accept, maxFileSize, minFileSize, icon, label, helperText, isNotClickable, isNotDraggable, onDropRejected, onUploadComplete, onUploadError, style, className, id, …) are forwarded to the twin — see @uxf/ui/dropzone.

Dropzone.List (file list) — DropzoneListProps<FormData>

Reads the same field (control + name) and renders the uploaded files. It does not take rules, shouldUnregister, or any validation props.

Prop Type Default Description
control Control<FormData> — Required. Same control as the drop area.
name FieldPath<FormData> — Required. Same field path as the drop area.
onChange (value: DropzoneFile[] | undefined, event?) => void — Called after a removal updates the field value.
errorText string (twin default) Text under a file that failed to upload.
isDownloadableOnClick boolean false Render the file link with download instead of opening in a new tab.
onRemoveConfirm (file: DropzoneFile) => Promise<boolean> — Confirm before removing; remove only if it resolves true.
renderItem (file, onRemove, isUploading) => ReactNode — Custom renderer for each list item.
className / style string / CSSProperties — List styling.

See @uxf/ui/dropzone for the visual behaviour of both parts.

Validation

Built-in validate on the drop area field, ordered:

  • required — when isRequired and minFilesCount !== 0 and there are fewer than minFilesCount ?? 1 files → requiredMessage / uxf-form-dropzone:validation.required.
  • max-files-count — when maxFilesCount is set and the value exceeds it → uxf-form-dropzone:validation.max-files-count (interpolates {{maxFilesCount}}).
  • min-files-count — when minFilesCount is set and the value is below it → uxf-form-dropzone:validation.min-files-count (interpolates {{minFilesCount}}).

Additional rules are merged; a rules.validate function runs alongside as custom, a rules.validate object is spread in. The field-level error is shown as the twin's helperText and sets isInvalid.

Requirements

  • Must be rendered inside a Form — it reads the form context (formId, and inherits isDisabled / isReadOnly) and needs a react-hook-form control. The drop-area id defaults to ${formId}__${name}.
  • Dropzone and Dropzone.List must use the same control and name to stay in sync.
  • Ships no CSS of its own; it renders @uxf/ui/dropzone, so include that component's stylesheet(s) and the @uxf/ui token layer — see @uxf/ui/dropzone.

Links

  • Visual/primitive twin: @uxf/ui/dropzone
Default
Open in new tab