Editable
Inline edit: a focusable preview that swaps to an input, submitting on Enter/blur and cancelling on Escape.
|
|
| Package |
@vizejs/ui/editable |
| Maturity |
stable |
| Own the source |
vize lib pull editable |
| Requires |
context, controllable-state, id |
| Aliases |
inline edit, click to edit, editable text, in-place editor |
| Covers |
Chakra Editable, Ark UI Editable, Reka UI Editable |
Usage
import { Editable, EditablePreview, EditableInput, EditableTrigger } from "@vizejs/ui/editable";
Or copy the source into your project with vize lib pull editable (see Source Distribution).
API
Editable
Source: src/families/form/editable/editable.vue
Props
| Prop |
Type |
Default |
Description |
id |
string | null |
undefined |
Id of the edit input. null and undefined select a deterministic fallback. |
name |
string |
undefined |
Native form field name; a hidden input submits the committed value. |
modelValue |
string |
undefined |
Controlled committed value. undefined selects uncontrolled behavior. |
defaultValue |
string |
"" |
Initial uncontrolled value. |
editing |
boolean |
undefined |
Controlled edit mode (v-model:editing). undefined selects uncontrolled behavior. |
defaultEditing |
boolean |
false |
Initial uncontrolled edit mode. |
activationMode |
EditableActivationMode |
"focus" |
How the preview enters edit mode. Enter and F2 on a focused preview always do. |
submitMode |
EditableSubmitMode |
"both" |
Which interactions commit the draft: Enter, blur, both, or only an explicit submit. |
selectOnFocus |
boolean |
true |
Select the input text when edit mode starts. |
placeholder |
string |
undefined |
Text shown by the preview and input while empty. |
maxLength |
number |
undefined |
Native maximum length of the input. |
disabled |
boolean |
false |
Prevent editing and remove the preview from the tab order. |
readOnly |
boolean |
false |
Show the value without allowing edit mode. |
ariaLabel |
string |
undefined |
Accessible name of the input when no label or aria-labelledby supplies one. |
ariaLabelledby |
string |
undefined |
Space-separated ids that label the input and preview. |
ariaDescribedby |
string |
undefined |
Space-separated ids that describe the input. |
ariaErrormessage |
string |
undefined |
Id of the validation error message used while invalid. |
ariaInvalid |
EditableAriaInvalid |
false |
Invalid state announced on the input. |
Events
| Event |
Payload |
Description |
update:modelValue |
[value: string] |
Fired when a submit requests a new committed value. |
update:editing |
[editing: boolean] |
Fired when edit mode requests to open or close (v-model:editing). |
edit |
[] |
Fired when edit mode starts. |
submit |
[value: string, previous: string] |
Fired after a submit with the committed value and the previous value. |
cancel |
[value: string, discarded: string] |
Fired after a cancel with the restored value and the discarded draft. |
Slots
| Slot |
Slot props |
Description |
default |
EditableSlotState |
Renders the preview, input, and triggers with the editing state. |
Exposed
| Member |
Type |
Description |
value |
string |
Committed value. |
draft |
string |
Text in the input while editing (equals value otherwise). |
editing |
boolean |
Whether the input is shown. |
empty |
boolean |
Whether the committed value is empty (the preview shows the placeholder). |
disabled |
boolean |
Whether editing is disabled. |
readOnly |
boolean |
Whether the value can be read but not edited. |
state |
EditableState |
Stable state token. |
root |
HTMLDivElement | null |
Rendered root element. |
edit |
() => boolean |
Enter edit mode (no-op while disabled or read-only); returns whether it started. |
submit |
() => boolean |
Commit the draft and leave edit mode; returns whether the value changed. |
cancel |
() => void |
Discard the draft and leave edit mode. |
setValue |
(value: string) => boolean |
Replace the committed value; returns whether it changed. |
EditablePreview
Source: src/families/form/editable/editable-preview.vue
Slots
| Slot |
Slot props |
Description |
default |
{ readonly value: string; readonly empty: boolean } |
Preview contents; defaults to the value or the placeholder. |
Source: src/families/form/editable/editable-input.vue
EditableTrigger
Source: src/families/form/editable/editable-trigger.vue
Props
| Prop |
Type |
Default |
Description |
action (required) |
EditableTriggerAction |
required |
What activation does: enter edit mode, submit the draft, or cancel it. |
ariaLabel |
string |
undefined |
Accessible name when the contents are icon-only. |
Slots
| Slot |
Slot props |
Description |
default |
{ readonly editing: boolean } |
Trigger contents with the current editing state. |
Behavior
Normative state x input -> outcome table for editable.vue,
editable-preview.vue, editable-input.vue, and editable-trigger.vue
(@vizejs/ui/editable). Every row is proven by the named test in
editable.test.ts or editable-ssr.test.ts; compile-only assertions live in
editable.types.test-d.ts.
| # |
State |
Input |
Outcome |
Proven by |
| E1 |
preview, named |
render |
focusable role="button" preview with the value; input and submit/cancel triggers are hidden; hidden form value |
renders a focusable preview with the input and editing triggers hidden |
| E2 |
preview, focus mode |
focus preview |
enters edit mode, emits update:editing then edit, focuses the input and selects its text |
focusing the preview enters edit mode and focuses the selected input |
| E3 |
editing |
Enter / Escape |
Enter commits (submit(value, previous)), Escape discards (cancel(value, discarded)); focus returns to the preview without reopening |
Enter submits, Escape cancels, and focus returns to the preview without reopening |
| E4 |
editing, submitMode |
blur / Enter |
both (default) submits on blur and Enter; enter ignores blur; none requires an explicit submit |
blur submits by default and submitMode controls Enter and blur |
| E5 |
activationMode="none" |
triggers |
focus and clicks no longer activate (Enter/F2 still do); edit/submit/cancel triggers act, and pointer presses keep focus in the input |
triggers edit, submit, and cancel while keeping focus in the input |
| E6 |
click / dblclick modes |
click / dblclick / F2 |
the preview activates only on its mode; Enter and F2 always activate a focused preview |
click and double-click activation modes |
| E7 |
controlled |
focus / submit |
controlled editing and modelValue win until the parent accepts them |
controlled value and editing win until the parent accepts them |
| E8 |
empty / disabled / read-only |
render / activation |
placeholder shows when empty; disabled and read-only previews stay focusable with aria-disabled, triggers are disabled, and nothing is emitted |
placeholder, disabled, and read-only states |
| E9 |
in a form / imperative |
submit / expose |
the hidden input submits the committed value; edit, submit, cancel, setValue, and state are exposed |
submits the committed value with a form and exposes edit, submit, cancel, setValue |
| E10 |
part without provider |
setup |
throws the stable VIZE_UI_CONTEXT_MISSING: Editable diagnostic |
parts require an Editable provider |
| E11 |
SSR / hydration |
isolated requests |
byte-identical markup with hidden parts, hydration without diagnostics, and interactive preview |
renders byte-identical inline-edit markup and hydrates without mismatches |
Public extension contract
| Surface |
Contract |
| Parts |
root, preview, input, and edit-trigger / submit-trigger / cancel-trigger. |
| Data attributes |
data-vize-ui, data-state (preview/editing/readonly/disabled), data-empty, trigger data-action. |
| Visibility |
Parts toggle the native hidden attribute, so SSR markup and hydration never swap nodes. |
The subpath is tree-shakable and ships no CSS; those package contracts are
pinned by distribution.test.ts, check:size, and check:tree-shaking.