Rule
Match the edit surface to the scope of the change.
Why
Inline editing with many fields creates race conditions, false saves, and missing validation. Full forms on single-word edits waste time.
Inline Edit: Must
- Apply to one field at a time.
- Confirm on Enter or blur.
- Cancel on Esc and restore original value.
- Show a clear edit trigger (pencil icon or click-to-edit region).
Dedicated Form: Must
- Pre-populate all current values.
- Validate on submit, not on blur unless field is touched.
- Confirm discard when the user navigates away with unsaved changes.
Should
- Optimistically update inline edits when low-risk.
- Auto-save drafts for long-form fields.
Anti-patterns
- Inline editing a complex nested object.
- Navigation away from a form with unsaved data without warning.
Test Cases
- Esc during inline edit restores original value without save.
- Form unsaved-changes guard fires on browser back.
Telemetry
- inline_edit_saved
- inline_edit_cancelled
- form_unsaved_discard_confirmed
Code Examples
Svelte
<script lang="ts">
let name = 'Morgan Lee';
let draftName = name;
let editingInline = false;
function saveInlineEdit() {
name = draftName.trim() || name;
editingInline = false;
}
</script>
{#if editingInline}
<form on:submit|preventDefault={saveInlineEdit}>
<label>
<span class="sr-only">Display name</span>
<input bind:value={draftName} />
</label>
<button type="submit">Save</button>
<button type="button" on:click={() => (editingInline = false)}>Cancel</button>
</form>
{:else}
<p>{name}</p>
<button type="button" on:click={() => (editingInline = true)}>Edit name</button>
{/if}
<a href="/profile/edit">Edit full profile</a>Use inline editing for a single low-risk field. Switch to a dedicated form when the edit affects multiple fields, validation rules, or confirmation steps.