3. Detail & Editing

Edit records with inputs that validate against the resource's Zod schema.

The edit view lets users update a record. Chelone's <Edit> fetches the record and publishes a form context; each input binds to a source and validates against the resource's Zod schema — no per-input validate props.

A single input

An input renders a labelled control bound to one field:

Loading preview…
import { TextInput } from "@chelone/react";
 
<TextInput source="title" />;

The full edit form

Compose inputs directly as <Edit> children — Chelone has no <SimpleForm> wrapper; the view IS the form. Keep PostList and merge the new imported names into the existing @chelone/react import in src/posts.tsx:

Loading preview…
src/posts.tsx
import {
  BooleanInput,
  Edit,
  NumberInput,
  ReferenceInput,
  SelectInput,
  TextInput,
  Toolbar,
} from "@chelone/react";
 
export function PostEdit() {
  return (
    <Edit>
      <TextInput source="title" />
      <TextInput source="body" multiline />
      <ReferenceInput source="author_id" reference="authors">
        <SelectInput optionText="name" />
      </ReferenceInput>
      <NumberInput source="views" min={0} />
      <BooleanInput source="published" />
      <Toolbar />
    </Edit>
  );
}

Validation comes from the schema

Because posts was registered with postSchema, the form validates against it on submit. Clear the Title in the preview above and save — the schema's .min(1, "Title is required") rule blocks the submit and surfaces the message. That is the "point at a Zod schema" payoff: typed records and zero-boilerplate validation, from one source of truth.

Create and show views

Add these exports to src/posts.tsx, alongside PostList and PostEdit. Merge Create, SaveButton, and Show into the existing @chelone/react import; keep TextField from the list and the inputs from the edit form. The create form includes all required fields from postSchema and a <SaveButton>:

src/posts.tsx
import { Create, SaveButton, Show } from "@chelone/react";
// Keep TextField, ReferenceInput, SelectInput and TextInput already imported.
 
export function PostCreate() {
  return (
    <Create>
      <TextInput source="title" />
      <TextInput source="body" multiline />
      <ReferenceInput source="author_id" reference="authors">
        <SelectInput optionText="name" />
      </ReferenceInput>
      <SaveButton />
    </Create>
  );
}
 
export function PostShow() {
  return (
    <Show>
      <TextField source="title" />
      <TextField source="body" />
    </Show>
  );
}

In the App from Setup, merge the new view names into the existing imports and replace the posts <Resource> inside <Admin>:

src/App.tsx
import { Resource } from "@chelone/react";
import { PostCreate, PostEdit, PostList, PostShow } from "./posts";
 
<Resource name="posts" list={PostList} edit={PostEdit} create={PostCreate} show={PostShow} />