Editing

Forms and inputs for creating and updating records.

Inputs are the editable counterparts of fields. Each one binds a single record property — named by its source — into the ambient form, rendering a labelled control that reads and writes the form store. Place inputs inside a <Create> or <Edit> view (Chelone has no <SimpleForm> wrapper — the view is the form) and they register, display the current value, and surface validation errors automatically.

How an input binds

An input calls useInput under the hood: it registers source with the form, subscribes to that field's value and error, and renders a shadcn control wired to both. Type in the preview and the form store updates; the resource's Zod schema validates it on submit.

Loading preview…
import { BooleanInput, NumberInput, TextInput } from "@chelone/react";
 
<TextInput source="title" />
<TextInput source="body" multiline />
<NumberInput source="views" min={0} />
<BooleanInput source="published" />

Validation comes from the schema

When a resource is registered with a Zod schema, the form validates against it on submit, so most inputs need no validate prop. The schema is the single source of truth for both the record type and the form rules. Pass a per-input validate for a one-off rule on top.

Shared props

Most inputs accept the props of InputProps, on top of their own:

PropEffect
sourceThe record property to bind, relative to the ambient source scope. Required.
label, helperTextA string is translated and a node renders as is. label={false} renders no label.
validateOne validator or an array, such as required() from @chelone/core. They run in order and the first error wins.
formatTurns the stored value into the value the control shows.
parseTurns the control's value into the value written to the form.
defaultValueSeeds the input when the record has no value for source.
alwaysOnIn a <FilterForm> or <FilterButton>, keeps the filter shown instead of putting it in the add-filter menu. Do not combine it with defaultValue: seed the filter with the filterDefaultValues option of useListController (see Advanced List).
readOnlyThe control shows its value and takes no edits.
disabledDisables the control.
isRequiredForces the required marker. A required() validator sets it by itself.
onChange, onBlurCalled after the value is written or the blur is recorded.

Some inputs differ. <ReferenceInput> takes no validate: set it on the child input. <BooleanInput> omits type, onChange and onBlur. <ReferenceArrayInput>, <ArrayInput>, <DatagridInput>, <ApiKeyInput> and <SubscriptionPlanPicker> declare their own props instead. The component's page lists exactly what it takes.

format and parse run in opposite directions, so pass them as a pair:

import { required } from "@chelone/core";
import { TextInput } from "@chelone/react";
 
<TextInput
  source="slug"
  validate={required()}
  format={(value) => String(value ?? "").replace(/-/g, " ")}
  parse={(value) => String(value).replace(/\s+/g, "-")}
  defaultValue="untitled"
/>;

The input families

  • Text & numbers: <TextInput>, <NumberInput>, <PasswordInput>, <ResettableTextInput>, <SearchInput>, <CurrencyInput>, <DateInput>, <DateTimeInput>, <TimeInput>, <DurationInput>, <PhoneInput>, <ColorInput>, <CronInput>, <RatingInput>.
  • Choices: <SelectInput>, <AutocompleteInput>, <RadioButtonGroupInput>, <CheckboxGroupInput>, <BooleanInput>, <NullableBooleanInput>.
  • References: <ReferenceInput> (pick one related record), <ReferenceArrayInput> / <SelectArrayInput> / <AutocompleteArrayInput> (pick many).
  • Files & arrays: <FileInput>, <ImageInput>, <ArrayInput>, <TextArrayInput>, <DatagridInput>.
  • JSON: <MonacoJsonInput> edits a JSON value in a Monaco editor, with JSON Schema checks. It is an add-on installed from the registry, not part of the @chelone/react barrel.
  • Markdown: <MdxInput> edits a markdown string in a rich-text editor. It is an add-on installed from the registry, not part of the @chelone/react barrel.
  • SaaS: <ApiKeyInput>, <SubscriptionPlanPicker>, <WebhookEndpointInput>.
  • Forms and buttons: <TabbedForm> and <WizardForm> lay inputs out in tabs or steps, and <FilterForm> holds a list's filter inputs. The buttons act on the form or the record: <SaveButton>, <CancelButton>, <DeleteButton>, <CreateButton>, <EditButton>, <ShowButton>, and <BulkDeleteButton>, <BulkExportButton>, <BulkUpdateButton> for a list's selection. Two buttons move a record through a workflow: <DualApprovalButton> collects approvals and <StatusTransitionButton> moves it between states.

Each page in the sidebar is a props reference for one component: its props, with the types read from the source.

Inputs vs fields

Inputs edit; fields display. They pair by source: <TextInput source="title" /> in an <Edit>, <TextField source="title" /> in a <Show>.