Editable table cell.
Make a small change in place, with validation and a way back.
Install the source
npx shadcn@latest add https://ui.bld8.dev/r/editable-cell.jsonUsage
<EditableCell label="Project name" value={project.name}
validate={value => value.trim().length < 3 ? "Use at least three characters." : undefined}
onSave={(value, {signal}) => saveName(project.id, value, signal)} />In the workspace or ZIP starter, import components from @bld8/ui and include @bld8/ui/styles.css once. Registry installations use your local bld8/ source path. Wrap overlays in UIProvider.
API & behaviour
An explicit Edit action opens a text/date input or select. Enter saves; Escape cancels. Pending saves prevent repeats and disable the input. Validation and service errors retain the draft and link to the field. onSave receives an AbortSignal; unmount aborts and stale completions are ignored. The application owns the committed value and must refresh its dataset after success.
EditableCell
| Prop | Type | Default |
|---|---|---|
labelRequired | string | — |
onSaveRequired | (value: string, context: { signal: AbortSignal; originalValue: string; revision?: string | number; }) => Promise<void> | — |
valueRequired | string | — |
disabled | boolean | undefined | — |
display | ReactNode | — |
options | { value: string; label: string; }[] | undefined | — |
revision | string | number | undefined | — |
type | "text" | "date" | undefined | 'text' |
validate | ((value: string) => string | undefined) | undefined | — |
Tables come from the public TypeScript declarations. Related types are shown alongside their component. A dash means no default is declared at the public function boundary.
Notes to self
Test this component with real content, keyboard input and both themes. The example is a starting point; labels, error handling and behaviour still need to fit the application.