Editable
Forms
Smart auto-detect
Introduction
An inline text field that displays as plain text until activated (by focus, click, or double-click), then swaps to an editable input with submit/cancel controls.
Usage
Artefact UI Suite
Add a description…
import { Editable } from "../components/ui";
export default function MyPage() {
return (
<Editable label="Project name" defaultValue="Artefact UI Suite" />
);
}
Custom Composition
Pass children for full control over the preview/input/controls layout:
import { Editable } from "../components/ui";
export default function MyPage() {
return (
<Editable defaultValue="Untitled" activationMode="dblclick">
<Editable.Label>Title</Editable.Label>
<Editable.Area>
<Editable.Preview />
<Editable.Input />
</Editable.Area>
<Editable.Control>
<Editable.EditTrigger>Edit</Editable.EditTrigger>
<Editable.SubmitTrigger>Save</Editable.SubmitTrigger>
<Editable.CancelTrigger>Cancel</Editable.CancelTrigger>
</Editable.Control>
</Editable>
);
}
CMS Page Builder
This component is available as an editable block in the
Page Builder (content/pages/*.json):
{
"type": "editable",
"label": "Project name",
"defaultValue": "Artefact UI Suite",
"placeholder": "Untitled",
"size": "md",
"activationMode": "focus",
"submitMode": "both"
}
It always renders interactive in the Page Builder.
Props
Root
| Prop | Type | Description |
|---|---|---|
value | string | The current value (controlled). |
defaultValue | string | The initial value (uncontrolled). |
edit | boolean | Whether edit mode is active (controlled). |
defaultEdit | boolean | The initial edit-mode state (uncontrolled). |
activationMode | "focus" | "dblclick" | "click" | "none" | How the preview enters edit mode. Default "focus". |
submitMode | "enter" | "blur" | "both" | "none" | Which interactions commit the value. Default "both". |
selectOnFocus | boolean | Whether the input's text is selected when it's focused. Default true. |
autoResize | boolean | Keep the preview visible (sized to content) while editing instead of hiding it. |
disabled | boolean | Disables all interaction. |
readOnly | boolean | Prevents entering edit mode while still allowing focus. |
required | boolean | Marks the underlying input required. |
invalid | boolean | Marks the field invalid. |
placeholder | string | { edit: string; preview: string } | Placeholder text, optionally different between the input and the preview. |
maxLength | number | Maximum input length. |
name | string | Name of the underlying input, for native form submission. |
form | string | Associates the input with a <form> by id. |
translations | Partial<EditableTranslations> | Overrides for the edit/submit/cancel/input ARIA strings. |
size | "2xs" | "xs" | "sm" | "md" | "lg" | Visual size. Default "md". |
onValueChange | (details: { value: string }) => void | Called as the input value changes. |
onValueCommit | (details: { value: string }) => void | Called when the value is submitted. |
onValueRevert | (details: { value: string }) => void | Called when editing is cancelled. |
onEditChange | (details: { edit: boolean }) => void | Called when edit mode toggles. |
interactive | boolean | Forces (or suppresses) hydration as an island. |
class | string | Custom CSS classes for the root element. |
Default composition
| Prop | Type | Description |
|---|---|---|
label | JSX.Element | string | Label rendered above the field. |
children | JSX.Element | Extra content appended after the default preview/input/controls. |
Sub-components
| Part | Description |
|---|---|
Editable.Label | <label> bound to the input; clicking it focuses the preview. |
Editable.Area | Wraps Preview and Input in the same layout slot. |
Editable.Preview | The read-only display shown when not editing; role="button", keyboard-activatable per activationMode. |
Editable.Input | The <input> shown while editing; handles Escape-to-cancel and Enter/blur-to-submit per submitMode. |
Editable.Control | Wraps the edit/submit/cancel triggers. |
Editable.EditTrigger | Enters edit mode. Hidden while already editing. |
Editable.SubmitTrigger | Commits the value and exits edit mode. Hidden while not editing. |
Editable.CancelTrigger | Discards changes and exits edit mode. Hidden while not editing. |
Editable.Context | Render-prop access to the editable context: <Editable.Context>{(ctx) => ...}</Editable.Context>. |
Accessibility
Previewis keyboard-operable (tabIndex={0}, Enter/Space) wheneveractivationModeis"click"or"dblclick"; with"focus"mode, simply tabbing to it opens edit mode.EditTrigger/SubmitTrigger/CancelTriggergetaria-labels fromtranslations, and are hidden (not just visually, via thehiddenattribute) when not applicable to the current mode.Inputcarriesaria-invalidwheninvalidis set andaria-labelfromtranslations.input.