Design accessible form success states: status, navigation, Undo, and confirmation

2026-11-15来源 dev.to UXEnglish

Successful submission is a distinct UI state

A completed form needs to answer two questions: did the action finish, and can the user recover if it was accidental? Treating success as an error-summary variant or relying on a visual toast makes those answers harder to discover.

Start by choosing the announcement channel from the page transition.

If submission navigates to a new page or a clearly different view, put the result in the new document context: update the page title and expose a clear main heading such as “Task submitted.” This makes the destination state explicit rather than leaving the user to infer success from a changed screen.

If submission remains on the same page, keep the user in context and return a concise status message. The message should say what completed, not repeat a long explanation. The inserted example models this as a dedicated status result, separate from validation output.

Keep recovery and validation honest

Validation failures need a correction path: field errors identify what must change before submission can continue. They are not success feedback, and a successful result should not be inferred merely because an error summary is absent. Model these as separate states so the rendering layer cannot accidentally present success through an error pattern.

Next, choose the safeguard based on reversibility. For reversible work, return an Undo control after success and restore the prior item when the user activates it. Once restoration has happened, Undo should no longer be available. For permanent or otherwise critical work, do not offer a recovery promise that the system cannot keep. Require confirmation before committing the action instead.

Expected behavior is straightforward: a valid reversible submission produces a completion announcement and Undo; a page-style completion produces a title and heading instead of an in-place status; invalid input produces validation feedback; irreversible work pauses for confirmation and exposes no Undo control.

One important limitation remains: this flow can model the semantic contract, but it cannot prove the exact announcement order or behavior of every browser and assistive-technology combination. Verify the rendered markup and interaction in the environments you support.

Working example

export const proofBoundary = 'This model verifies the flow’s presentation contract. It does not prove how a particular browser or assistive technology announces a live region, title, or heading.'; function successPresentation(presentation, task) { const message = `Task “${task}” submitted successfully.`; if (presentation === 'page') { return { title: `Task submitted – Task manager`, heading: 'Task submitted', status: null, message, }; } return { title: null, heading: null, status: { role: 'status', text: message }, message, }; } /** * Models a form submission UI. A real page can render `title` and `heading` * after navigation, or render the `status` live region after an in-page submit. */ export function createTaskFormFlow({ presentation = 'status', reversible = true } = {}) { if (!['status', 'page'].includes(presentation)) { throw new RangeError('presentation must be "status" or "page"'); } let pendingSubmission = null; return { submit({ task, confirmed = false } = {}) { const normalizedTask = typeof task === 'string' ? task.trim() : ''; if (!normalizedTask) { return { ok: false, kind: 'validation', fieldErrors: { task: 'Enter a task.' }, // Success is not represented as a server-style error summary. errorSummary: null, }; } if (!reversible && !confirmed) { return { ok: false, kind: 'confirmation-required', message: 'Confirm this permanent submission before continuing.', }; } pendingSubmission = { task: normalizedTask }; const feedback = successPresentation(presentation, normalizedTask); return { ok: true, kind: 'submitted', ...feedback, undoControl: reversible ? { action: 'undo', label: 'Undo submission', accessibleName: 'Undo submission' } : null, }; }, undo() { if (!reversible || pendingSubmission === null) { return { ok: false, kind: 'undo-unavailable', status: null, }; } const { task } = pendingSubmission; pendingSubmission = null; return { ok: true, kind: 'undone', restoredTask: task, status: { role: 'status', text: `Submission of “${task}” was undone.` }, }; }, }; } 

Read the full article: https://chriseugenerodriguez.com/blog/successful-form-submission-undo-accessibly

原文:https://www.a8q9.cn/en/article/design-accessible-form-success-states-status-navigation-undo-and-confirmation-75f18f.html

相关文章