react-data-form
Field controllers
The full catalogue — forty-odd controllers, each one running.
Every field is rendered by a controller. Name one on a field and that is the whole wiring — there is no registration step, and a controller is an ordinary component you could have written yourself.
How to use one#
import { PriceInputController } from "react-data-form"
inputs: {
amount: { label: "Amount", controller: PriceInputController },
}They all come from the main entry point
Every controller on this page is exported from react-data-form. Only the image editor lives elsewhere, in react-data-form/media, because it pulls a cropping library in.
Text#
DefaultInputController is what a field falls back to, driven by its type. The others add behaviour a bare input has not got — masking, a text area, a rich editor.
Text controllers
| Name | Type | Default | Description |
|---|---|---|---|
DefaultInputController | string | — | An HTML input driven by the field's type. Used when no controller is named. |
TextAreaInputController | string | — | A multi-line text area. |
EmailInputController | string | — | An email input with the matching keyboard on mobile. |
PasswordInputController | string | — | A masked input with a reveal toggle. |
WebsiteInputController | string | — | A URL input, normalising what is typed. |
PhoneInputController | string | — | A telephone input. |
ArrayInputController | string[] | — | Free-form tags. min and max bound how many. |
WysiwygInputController | string (HTML) | — | A rich text editor built on TipTap. The HTML is sanitised on the way out. |
SearchInputController | string | — | A text input styled as a search box, with a clear button. |
Numbers#
Two of these do not store what they show, which is the point of using them: a price is held in the smallest currency unit and a duration in seconds, so neither ever loses a rounding.
Number controllers
Submit the form above
€12.50 arrives as 1250, and “1 h 30” as 5400. The reader sees an amount and a duration; your API receives integers.
Dates and time#
The date fields format and parse through the dateLocale port, so a single call at startup localises all of them — see Configuration.
Date and time controllers
| Name | Type | Default | Description |
|---|---|---|---|
DatePickerInputController | string (ISO date) | — | A calendar in a popover. The everyday choice. |
DateInputController | string (ISO date) | — | A native date input — faster to fill when the reader knows the date. |
DateRangeInputController | { start, end } | — | A period. Build the field with createDateRangeFormInput, which names both ends. |
TimeInputController | string (HH:mm) | — | A time of day. |
SelectTimeInputController | number (seconds) | — | Preset durations from 15 minutes upwards. |
MomentInputController | string (ISO datetime) | — | A date and a time together, in one control. |
Choices#
All of these read the same valueOptions. They differ only in how much room they take and how many values they hold — which means changing your mind later is a one-word edit.
Single choice, four presentations
Booleans and multiple choice
Searching a large set#
A dropdown stops working somewhere around fifty options. Past that, the field should ask the server instead: onSearch is called on every keystroke and returns the options to show.
Type a name — the options are fetched per keystroke
| Name | Type | Default | Description |
|---|---|---|---|
SelectSearchInputController | Primitive | — | One value, chosen from a searched, remote set. |
MultiSelectSearchInputController | Primitive[] | — | The same, holding several values. |
AutocompleteInputController | string | — | Suggests from the options but accepts anything typed — a free field with hints. |
MultiSelectInputController | Primitive[] | — | Several values from a set already in memory. |
Showing an IRI as a name
When an option's value is an IRI, the label shown once it is chosen comes from the iriLabel port. Configure it once and every dropdown in the application reads resource names instead of /api/authors/4.
Composite#
Three controllers hold structure rather than a scalar. They have a page of their own, since what they submit is nested.
| Name | Type | Default | Description |
|---|---|---|---|
FormInputController | object | — | Renders the field's form inline as a sub-form, and submits it as a nested object. |
FormArrayInputController | object[] | — | A page builder: the reader adds blocks from a palette, each block being a registered form. |
BlockOrderInput | object[] | — | Reorders the blocks of the field above. |
Files and media#
| Name | Type | Default | Description |
|---|---|---|---|
FileInputController | string | — | A file input. Uploading is yours to do — the controller stores whatever reference you give back. |
IaImageInputController | string | — | An image field with a generation affordance, for backends that offer one. |
ImageEditor | component | — | Cropping and rotation, from react-data-form/media. Not a controller: a component to plug into the upload flow your API needs. |
No upload endpoint is assumed
The library never issues a request. FileInputController hands you the file and stores the reference you put back on the field, so it works the same against S3, an API Platform media object, or a data URL.