Editable
An edit-in-place text field that swaps a preview for an input.
Usage
import {
Editable,
EditableArea,
EditableCancelTrigger,
EditableControl,
EditableEditTrigger,
EditableInput,
EditablePreview,
EditableSubmitTrigger,
} from "@kanzo-tech/ui";EditableInput and the triggers render bare — compose them over a styled
Input (or Textarea) and Button with asChild, and wrap the field in a
Field for its label.
Anatomy
<Field>
<FieldLabel>Contract title</FieldLabel>
<Editable defaultValue="A wyrm under the granary">
<EditableArea>
<EditableInput asChild>
<Input className="w-full" />
</EditableInput>
<EditablePreview />
</EditableArea>
<EditableControl>
<EditableEditTrigger asChild>
<Button size="icon-md" variant="ghost">
<PencilIcon />
</Button>
</EditableEditTrigger>
<EditableSubmitTrigger asChild>
<Button size="icon-md" variant="outline">
<CheckIcon />
</Button>
</EditableSubmitTrigger>
<EditableCancelTrigger asChild>
<Button size="icon-md" variant="ghost">
<XIcon />
</Button>
</EditableCancelTrigger>
</EditableControl>
</Editable>
</Field>Ark shows the edit trigger while idle and the submit/cancel pair while editing — no conditional needed.
API Reference
Editable
| Prop | Type | Default |
|---|---|---|
orientation | "horizontal" | "vertical" | "horizontal" |
activationMode | "focus" | "dblclick" | "click" | "focus" |
submitMode | "blur" | "enter" | "both" | "none" | "both" |
selectOnFocus | boolean | true |
orientation is ours — it is mirrored to data-orientation, which is what stacks
EditableControl under the area instead of beside it. The rest is Ark's.
Extends React.ComponentProps<typeof ArkEditable.Root>, so value / defaultValue,
onValueChange / onValueCommit / onValueRevert, edit / defaultEdit / onEditChange,
placeholder, maxLength, autoResize, disabled, invalid, readOnly, required, name,
form and ref pass through.
EditablePreview
| Prop | Type | Default |
|---|---|---|
variant | ButtonProps["variant"] | "outline" |
size | ButtonProps["size"] | "md" |
The idle state is styled with buttonVariants at clickEffect: false, so it already looks like
the control it is about to become.
Other parts
EditableArea and EditableControl take their Ark part's props. EditableInput and the three
triggers render bare — pass a styled Input / Textarea or Button with asChild;
EditableInput omits the native size attribute, the way Input does.
useEditable re-exports Ark's useEditableContext.
Every part's props are exported as an interface — EditableInputProps and EditableProps — so a
wrapper can take the same props without restating them.