ObjectUIObjectUI
Fields

File Field

File upload with multiple file support and metadata display

The File Field component provides a file upload interface with support for multiple files, file type filtering, and file metadata display.

Basic Usage

Basic File Upload

Drag & drop files here

or click to browse

Multiple Files

Multiple File Upload

Drag & drop files here

or click to browse

File Type Restrictions

Pdf Files Only

Drag & drop files here

or click to browse

Field Schema

A file field is authored as FileFieldMetadata (@object-ui/types), which is the source of truth for the key set: it extends BaseFieldMetadata with multiple, accept and maxSize. maxSize is the largest file the widget accepts, in bytes, and it is the spec's FieldSchema.maxSize: a larger pick is refused before any upload starts. There is no key for a file count, because the spec declares none and no widget enforces one.

The field's stored value is the bare sys_file id the upload adapter minted — a string, or string[] when multiple — the reference form the platform's stored contract admits. An upload whose adapter surfaces no id is refused in the widget with "did not complete" and nothing is submitted (objectui#7699); mount an UploadProvider whose adapter registers the file with the platform (createObjectStackUploadAdapter). UploadedFileMetadata, exported from the same package, is the legacy inline shape a record written before file-as-reference may still hold: the widgets still render it, and never write a new one.

Restricted files. When the reader may read the record but not a file's sys_file metadata, the platform sends that file as { id, metadataRefused: true } (FileRefusedValueSchema in @objectstack/spec/data). readFileValue flags it as metadataRefused: true on the FileValueView, and every file, image and avatar renderer shows a lock with a translated "Restricted file" label (fields.file.restricted) instead of a name or a thumbnail. The open link still points to the id-derived download endpoint, which decides access itself. An editable widget that re-submits the field's values sends such a file back as its bare id.

import type { FileFieldMetadata, UploadedFileMetadata } from '@object-ui/types';

const attachments: FileFieldMetadata = {
  type: 'file',
  name: 'attachments',
  label: 'Attachments',
  inlineHelpText: 'PDF or Word, up to 10 MB each.',
  multiple: true,
  accept: ['application/pdf', 'application/msword'],
  maxSize: 10 * 1024 * 1024,
};

// The LEGACY inline shape a pre-reference record may still hold as its VALUE —
// rendered by the widgets, never written by them (a new upload stores the id).
const legacyStoredFile: UploadedFileMetadata = {
  name: 'contract.pdf',
  original_name: 'Contract (signed).pdf',
  size: 248_310,
  mime_type: 'application/pdf',
  url: 'https://files.example.com/contract.pdf',
};

The value being edited, and the className / disabled a host supplies, are not metadata keys — they are runtime widget props. See Field Widget Props.

Accepted File Types

Common MIME type examples:

// Documents
accept: ['application/pdf', 'application/msword']

// Images
accept: ['image/png', 'image/jpeg', 'image/gif']

// Archives
accept: ['application/zip', 'application/x-rar']

// Spreadsheets
accept: ['application/vnd.ms-excel', 'text/csv']

// Wildcards
accept: ['image/*']  // All images

Features

  • File List Display: Shows uploaded files with names and sizes
  • Remove Files: Individual file removal with X button
  • Size Display: File sizes shown in KB/MB
  • Upload Button: Clear upload interface
  • Multiple Selection: Support for batch file uploads

Cell Renderer

In tables/grids, displays file count:

import { FileCellRenderer } from '@object-ui/fields';

// Renders: "3 files" or "document.pdf"

Integration Notes

The widget uploads through the ambient UploadProvider from @object-ui/providers and stores the sys_file id its adapter returns in meta.fileId; createObjectStackUploadAdapter (ObjectStack's presigned flow) returns one. With no provider mounted, useUpload() falls back to an object-URL adapter that persists nothing and returns no id, so every pick is refused with "did not complete" and the field is not changed.

Use Cases

  • Document Management: PDF uploads, contracts
  • File Attachments: Email attachments, support tickets
  • Media Libraries: Asset uploads, resources
  • Data Import: CSV files, batch uploads

On this page