Specialized inputs

AppFilePicker

A tall drag-and-drop dropzone that swaps to a large image preview once a file is chosen.

<app-file-picker label="Structure photo" name="structurePhoto" />

<app-file-picker> is the image upload field for a single, visually-important picture — a structure photo, a cover image, a document scan. It shows a tall dropzone that accepts a click or a drag & drop, then swaps to a large preview once a file is chosen (hover to change, × to remove).

Its look comes entirely from the shared @webority/theme, so the Razor <app-file-picker> and the React <AppFilePicker> render identically — the same dropzone on every Webority surface. Never hand-roll a raw <input type="file">.

Playground

Every attribute, live. Each change re-renders the real tag helper on the server, so the dropzone below is what that combination actually emits — drag or pick a real file onto it and validation runs for real (type + size).

<app-file-picker label="Structure photo" name="playgroundFile" />
File selection isn't a query-string valueDrag or pick a real file onto the dropzone above — the client-side script wired into <app-file-picker> validates and previews it for real. The playground controls only round-trip the configuration attributes (label, accept, multiple, …), the same way React's value/onPick always stay local state.

The dropzone

Empty, the field is a tall target that accepts a click OR a file dragged onto it. Pick a file to watch it swap to a preview.

Click or drag & drop
The field is controlled — the parent owns the chosen file. Type and size are validated automatically; a file that fails never reaches the handler.
Show code
<app-file-picker label="Structure photo" name="structurePhoto" />
Validation is built inThe picker checks type (JPG / JPEG / PNG) and size (up to 5 MB) before it reports the choice. A file that fails never reaches the handler — the user sees a toast explaining why. You don't write the validation.

Preview & remove

Once a file is picked the dropzone becomes a large preview. Hovering reveals a “Change image” overlay; the × removes it and returns to the empty dropzone.

The chosen image, in place
Clearing the selection returns the field to the empty dropzone; the preview’s object URL is created and released for you.
Show code
<app-file-picker label="Structure photo" name="structurePhoto" />

Multiple files

Add multiple="true" and the dropzone stays put while picked files stack in a list below it — image thumbnail or file-type icon + name + size, each with its own × to remove. Widen accept beyond images for PDFs and other files; cap the count with max-files.

Multiple, mixed types
Each pick appends to the list (duplicates by name+size are ignored). Images render a thumbnail; PDFs and other files render a file-type icon. Single mode still swaps to the full-width preview.
Show code
<app-file-picker label="Attachments" name="attachments" multiple="true" max-files="5" accept="image/png,image/jpeg,application/pdf" />

Required, hint & errors

Mark the field required to render the asterisk. A hint sits below the zone in the same slot every field uses for helper text; an error (yours, or the reason a pick was rejected) takes that slot while it shows.

With a hint
A clear photo of the whole structure, taken in daylight.
Show code
<app-file-picker label="Structure photo" name="structurePhoto" hint="A clear photo of the whole structure, taken in daylight." />
Required, with an error
Logo is required
Show code
<app-file-picker label="Company logo" name="logo" required="true" error="Logo is required" />

Loading

Set loading="true" while the chosen file uploads. A spinner covers the control and picking is blocked: no click and no drop. To switch it from script, for an upload that runs in the page, call WUI.filePicker.setLoading(field, true) and false when it settles; field is the picker's wrapper or any element inside it. The spinner then covers the picked preview too.

Uploading
Show code
<app-file-picker label="Structure photo" name="structurePhoto" loading="true" />

Width

The dropzone fills its column by default. Cap it to a fixed width with a file-w-* class (file-w-sm, file-w-md, file-w-lg, file-w-full), or set the --wui-file-width variable to any value.

Fixed-width dropzone
file-w-md caps the zone; the default (no class) stays full-width to line up with other form fields.
Show code
<app-file-picker label="Small (file-w-sm)" name="width" class="file-w-sm" />
<app-file-picker label="Medium (file-w-md)" name="width" class="file-w-md" />

When to use

Use it when

  • A single, visually-important image is being uploaded — a photo, a cover, a scan.
  • The preview matters: the user should see the picture they chose, large.
  • You want drag & drop plus a click target in one field, with type/size validation handled.

Reach for something else when

  • You are attaching a file where the name/size matters more than a big preview. → AppFileAttachment
  • The upload is a round avatar or a company logo in a header. → AppLogoPicker
  • It is a plain, non-image file input with no preview. → a labelled AppInput
  • You hand-roll a raw <input type="file"> with custom styling. → AppFilePicker

Best practices

Do
Give the field a specific label — "Structure photo", not "Upload" — so the user knows what image belongs here.
Don't
A vague "File" label leaves the user guessing what to drop, and mixes with the format hint already in the zone.
Do
Logo is required
Surface validation with a message below the zone, in the field’s own error style — the eye lands on it next to the control.
Don't
A required field with no message on submit leaves the user unsure why the form won’t save.

Every option

The whole surface of the component, one cell per value — accept presets, multiple/max-files, required/error, and every width class.

accept — every preset

accept=".jpg,.jpeg,.png"
accept="image/*"
accept="image/*,application/pdf"
accept="application/pdf"
accept=".csv,.xlsx"

multiple / max-files

multiple="false" (default)
multiple="true"
multiple, populated (image + pdf) — needs a real pick, see the value gap below
multiple="true" max-files="1" — caps total files accepted

required / error

(default)
required="true"
error="…"
This field is required.
required="true" error="…"
Logo is required
hint="…"
PNG or JPG, up to 5 MB.
hint + error (the error takes the slot)
This field is required.

loading

loading, empty dropzone
loading, with a preview
Not renderable server-sideA preview only exists after a real client-side pick. Pick a file, then call WUI.filePicker.setLoading(field, true) and the spinner covers the preview.

value — every preview state (React-only; Razor has no value attribute, see below)

(default) — empty dropzone
image preview — no value attribute
Not renderable server-sideThere's no value attribute to pre-seed an image — drag or pick a file onto any dropzone on this page to see the thumbnail preview render client-side.
existing { url } — no value attribute
Not renderable server-sideReact's value={ url } shape has no Razor equivalent — the tag helper can't pre-render an already-uploaded image from the server.
non-image file-type icon — no value attribute
Not renderable server-sidePick a non-image file (a PDF, say) on any dropzone above to see the file-type icon + name variant.
The preview only exists after a real pick<app-file-picker> has no value attribute — there is no way to hand the tag helper an existing File or { url } at render time, unlike React's value prop. Drag or pick a file onto any dropzone on this page to see the preview shell (thumbnail for an image, file-type icon + name otherwise) — the same client-side script every <app-file-picker> on this page shares.

class — width presets

class="file-w-sm"
class="file-w-md"
class="file-w-lg"
class="file-w-full"

Attributes

AttributeTypeDefaultDescription
labelstring—Field label shown above the dropzone.
namestring—Form field name for the posted file input.
acceptstring.jpg,.jpeg,.pngAccepted file types. Widen (e.g. image/*,application/pdf) for non-image files.
multipleboolfalseAccept several files — they stack in a list below the dropzone, each removable.
max-filesint—Cap on total files in multiple mode.
requiredboolfalseRenders the required asterisk beside the label.
errorstring—Validation message shown below the zone; also styles the zone as errored.
hintstring—Helper text below the zone, in the field hint slot. An error, yours or a rejected pick's, replaces it while it shows.
loadingboolfalseCovers the dropzone with a spinner and blocks picking (click and drop), e.g. while the file uploads.
max-size-mbint5Maximum accepted file size in MB (React maxSizeMb). Unset means 5. 0 or less means no size limit, and the hint then names no size.
classstring—Extra class on the field wrapper — e.g. a file-w-* width preset (see the matrix above).
input-classstring—Extra classes on the control itself (the dropzone) — the React className counterpart. The plain class attribute merges onto the .field wrapper instead.