FileField
<caos-file-field>
attach files to a record, with each one’s own progress and its own failure
May be placed on a record page, a page inside an app and a step of a guided flow.
Inputs
Section titled “Inputs”| Name | Attribute | Description | Type | Default | Required |
|---|---|---|---|---|---|
label |
label, markup only |
The field name above the drop target. It also names the target for a screen reader, so leaving it off leaves an unnamed control. | text | none declared | Optional |
accept |
accept, markup only |
What may be attached, in the same grammar a native file input takes — .pdf, image/png, image/*, comma-separated. It is enforced on drop and paste as well as on the picker, and a file that does not match is named as refused rather than quietly ignored. Absent means anything is accepted. |
text | none declared | Optional |
multiple |
multiple, markup only |
More than one file may be attached. Without it the field holds one: a second pick REPLACES the first rather than being ignored, because a pick that appears to do nothing reads as a broken control. | boolean | false | Optional |
maxBytes |
max-bytes, markup only |
The largest file this will take, in bytes. A file over it is refused by name with both sizes in the message, so the person can see how far over it is. Absent or 0 means no limit here. | number | none declared | Optional |
required |
required, markup only |
Something has to be attached. Draws the asterisk after the label and marks the drop target required. | boolean | false | Optional |
disabled |
disabled, markup only |
The field may not be used. Refuses the picker, drop and paste, and takes the drop target out of the tab order. This is NOT how progress is shown — a file in flight leaves the field usable. | boolean | false | Optional |
invalid |
invalid, markup only |
The answer is wrong — usually a required field with nothing attached. Turns the drop target red and marks it invalid. | boolean | false | Optional |
message |
message, markup only |
The line under the field. Setting it writes the line; the field also writes it itself to name a refused file, so a page that sets it on every render will overwrite what the field is trying to say. | text | none declared | Optional |
Events
Section titled “Events”| Name | When it fires | What it carries |
|---|---|---|
caos-file-change |
Whenever what is attached changes — a file finishes, fails, is removed, or a whole batch is refused. Not while a file is merely in flight: an upload that has not finished is not a value yet. | { value, busy } — the attached files, and whether anything is still in flight. |
Nothing goes inside this piece.
Styling hooks
Section titled “Styling hooks”| Design token | What it controls |
|---|---|
--caos-color-border |
The dashed outline of the drop target, and the outline of a settled row. |
--caos-color-accent |
The outline and wash while a file is dragged over it, and the moving part of the spinner. |
--caos-color-surface-2 |
The fill of the drop target. |
--caos-color-surface |
The fill of an attached row. |
--caos-color-danger |
The required asterisk, the outline of a failed row, and the refusal message. |
--caos-color-danger-bg |
The fill of a failed row. |
--caos-color-danger-text |
The reason under the name on a failed row. |
--caos-radius |
The corners of the drop target. |
--caos-radius-sm |
The corners of a row, its thumbnail and its buttons. |
--caos-font |
The typeface throughout. |
--caos-text-body |
The size of the label and the drop target text. |
--caos-text-row |
The size of an attached file name. |
--caos-text-label |
The size of the size/status line and the message. |
Methods
Section titled “Methods”| Name | Description | Arguments |
|---|---|---|
clear() |
Forget everything attached — for a form that has just been submitted and is being reused. An upload still in flight is abandoned rather than allowed to reappear when it lands. | takes none |
focus() |
Move keyboard focus to the drop target, so Enter or Space opens the picker. | options: FocusOptions |
Readable state
Section titled “Readable state”| Name | Type | What it tells you |
|---|---|---|
value |
a list of { name, url, size, type } |
The attached files. Only the ones that finished — a file in flight and a file that failed are both absent, so reading this never reports a file the far end does not have. |
busy |
boolean | Whether any file is still in flight. Read it to decide whether a form may be submitted yet; the field does not disable itself to say so. |
Styling parts
Section titled “Styling parts”| Part | Which piece of it | When it is there |
|---|---|---|
::part(control) |
the label, drop target, list and message together | Always |
::part(dropzone) |
the drop target that also opens the picker | Always |
::part(label) |
the field name above the drop target | Always |
::part(list) |
the list of attached files | Always |
::part(item) |
one attached file — carries data-state of uploading, done or failed |
Always |
::part(spinner) |
the busy indicator on a row that is uploading | Always |
::part(message) |
the line under the field | Always |
When to use it
Section titled “When to use it”Somebody needs to hand the system a file — a screenshot with a report, a document on a record. If what you want is a picture already stored somewhere, this is not it: this takes a file IN.
What to use instead
Section titled “What to use instead”- FieldRenderer — The type is not known until the record is read — hand it the field metadata and it draws this one for a File field.
- ProgressBar — You are reporting how far along a long task is, rather than taking a file.
- ValidationSummary — Several fields are wrong at once and the page needs to say so in one place.
Accessibility
Section titled “Accessibility”The drop target is a real focusable control with role="button", reached by Tab and opened with Enter or Space, and it is named from label so it is not announced as an unlabelled button. aria-required and aria-invalid follow their attributes, and a disabled field reports aria-disabled and leaves the tab order rather than staying focusable and inert. A file in flight sets aria-busy on its own row, so what is announced as busy is the file rather than the whole field. Refusals are written into a role="status" live region, so a file rejected on drop is announced rather than only drawn — the case where a person never sees the message because they were not looking at that line. What is left to the author is the label, and a max-bytes and accept that match what the far end will actually take.
Examples
Section titled “Examples”Waiting for a file
Section titled “Waiting for a file”The resting state: a drop target that is also the picker, and says all three ways a file can arrive.
{ "id": "example", "section": "Waiting for a file", "columns": 1, "items": [ { "id": "file_field_1", "type": "component", "key": "file_field", "inputs": { "label": "Screenshots", "accept": "image/*", "multiple": true } } ]}<caos-file-field label="Screenshots" accept="image/*" multiple></caos-file-field>With a limit
Section titled “With a limit”A single-file field that takes one PDF up to 5MB. A file over the limit is named in the message with both sizes, rather than being dropped in silence.
{ "id": "example", "section": "With a limit", "columns": 1, "items": [ { "id": "file_field_1", "type": "component", "key": "file_field", "inputs": { "label": "Signed order", "accept": ".pdf", "max_bytes": 5242880 } } ]}<caos-file-field label="Signed order" accept=".pdf" max-bytes="5242880"></caos-file-field>Required and refused
Section titled “Required and refused”A required field with nothing attached, and the reason underneath.
{ "id": "example", "section": "Required and refused", "columns": 1, "items": [ { "id": "file_field_1", "type": "component", "key": "file_field", "inputs": { "label": "Proof of delivery", "required": true, "invalid": true, "message": "A photo of the delivery is required before this can be closed." } } ]}<caos-file-field label="Proof of delivery" required invalid message="A photo of the delivery is required before this can be closed."></caos-file-field>