Skip to main content

Attachments

A file-list control with add, upload, and delete. It is not registered by default, Attachments is exported but you must register it yourself with registerEditorItem under a comp name of your choice (examples use "files"). Once registered, value and onChange are supplied by the field binding; the component can also be used standalone. Unlisted props are forwarded to the internal file list.

Usage

import { Attachments, registerEditorItem } from "@svar-ui/react-editor";

// pick any comp name; "files" is the convention used across the docs
registerEditorItem("files", Attachments);

Props

PropTypeDefaultDescription
valueTFilesValueundefinedCurrent files array, or a master-record id resolved through ondata.
ondata(value: TFilesValue) => Promise<IUploadedFile[]> | IUploadedFile[]undefinedResolves the display list when value is a record id.
uploadURLstring | ((file: IUploadedFile) => Promise<Record<string, any>>)""REST endpoint that receives a multipart POST, or a custom uploader returning the stored file metadata.
acceptstring""HTML file-input accept filter.
multiplebooleantrueAllows selecting and holding more than one file. Set false for a single-file slot that replaces on each upload.
disabledbooleanfalseDisables the add-file button and input.
readonlybooleanfalseHides add/delete controls and renders the list only.
onChangeTFilesChangeHandlerundefinedFires when a file is committed (added) or deleted.
onAction(ev) => voidundefinedCoarse add/delete signal.

onChange payload: { value: IUploadedFile[], action: "add" \| "delete", file: IUploadedFile, originalValue: TFilesValue }.

onAction payload: { action: "add-file" \| "delete-file", file: IUploadedFile, value: IUploadedFile[] }.

Types

type TFilesValue = IUploadedFile[] | TID;

interface IUploadedFile {
id: TID;
name: string;
url?: string;
size?: number;
status?: "client" | "server" | "error";
file?: File;
[key: string]: any;
}

Only committed file metadata enters the stored value. In-flight and failed uploads stay in local state and are never reported through onChange. The default uploader POSTs multipart/form-data under the field name upload and expects a JSON response containing at least the permanent id.

Example

import { Editor, Willow, Attachments, registerEditorItem } from "@svar-ui/react-editor";

registerEditorItem("files", Attachments);

const items = [
{ comp: "files", key: "docs", label: "Documents", uploadURL: "/api/upload" },
];
const values = { docs: [] };

<Willow>
<Editor items={items} values={values} />
</Willow>

Editor with an attachments list, one upload in progress