Files
bible/rules/patterns/modal-workflows/contract.md
2026-03-01 17:16:50 +03:00

2.5 KiB

Contract: Modal Workflows

Version: 1.0

State Machine

Every modal has exactly these states:

closed → open → submitting → success | error
                           ↓
                        cancel → closed
  • open: form visible, submit enabled.
  • submitting: form disabled, spinner on submit button, no double-submit possible.
  • success: close modal, show toast, refresh affected data.
  • error: stay open, show error message inline, re-enable form.
  • cancel: close without changes, no confirmation needed unless form is dirty.

Rules

  • Destructive actions (delete, archive, bulk remove) require a separate confirmation modal — not just a disabled button. Confirmation modal must name the target: "Delete component ABC-123?"
  • Never close a modal automatically on error — keep it open so the user can retry or copy the error.
  • Submit button text must describe the action: "Save", "Delete", "Archive" — not "OK" or "Confirm".
  • Modal title must match the action: "Edit Component", "Delete Asset" — not generic "Modal".
  • Escape key and clicking the backdrop close the modal (unless in submitting state).

Validation

  • Validate on submit server-side. Client-side validation is optional progressive enhancement only.
  • Show field-level errors inline below each field.
  • Show a form-level error summary at the top if multiple fields fail.
  • Error messages must be human-readable and action-oriented: "Serial number is required" — not "serial_number: cannot be null".

htmx Pattern (server-rendered modals)

POST /api/entity        → 200 OK + HX-Trigger: "entitySaved"   (success)
                        → 422 Unprocessable + partial HTML      (validation error, re-render form)
                        → 500 + error message                   (server error)
  • On success: server sends HX-Trigger header, JS listener closes modal and refreshes list.
  • On validation error: server re-renders the form partial with inline errors (422).
  • On server error: show generic error toast, log full error server-side.
  • Do not use 200 OK for validation errors — use 422 so htmx can differentiate.

Multi-Step Modals

Use only when the workflow genuinely requires staged input (e.g. import preview → confirm).

  • Show a step indicator (Step 1 of 3).
  • Back button must restore previous step values.
  • Final confirm step must summarise what will happen before the destructive/irreversible action.
  • Single-step edits must NOT be split into multi-step without good reason.