Dialog Patterns¶
Consistent modal and dialog patterns across the application.
Overview¶
flowchart TB
subgraph Dialogs
A[ConfirmDialog]
B[FormDialog]
C[EntityDialog]
end
subgraph System
D[UnsavedChangesDialog]
E[PrivacyNoticeDialog]
F[PwaUpdateDialog]
end
subgraph Hooks
G[useModal]
H[useEntityModal]
I[useFormModal]
end
G --> A
H --> C
I --> B
I --> D Confirmation Dialog¶
For destructive actions requiring user confirmation.
<ConfirmDeleteDialog
open={isOpen}
title={t("deleteMarker")}
message={t("deleteMarkerConfirm")}
onConfirm={handleDelete}
onCancel={close}
isLoading={isDeleting}
/>
Pattern: - Clear title stating the action - Message explaining consequences - Cancel as default/safe option - Loading state during async action
Form Dialog¶
Dialog containing a form with validation.
<FormDialog
open={isOpen}
title={entity ? t("editMarker") : t("createMarker")}
onClose={handleClose}
>
<MarkerForm
defaultValues={entity}
onSubmit={handleSubmit}
onCancel={close}
/>
</FormDialog>
Features: - Dirty state tracking - Unsaved changes warning on close - Form reset on close - Loading state during submission
Entity Dialog¶
Full CRUD dialog for entity management.
const { isOpen, entity, openCreate, openEdit, close } = useEntityModal<Category>();
<EntityDialog
open={isOpen}
entity={entity}
onSave={handleSave}
onDelete={handleDelete}
onClose={close}
/>
Unsaved Changes Dialog¶
Warns users before discarding form changes.
<UnsavedChangesDialog
open={showWarning}
onDiscard={() => {
resetForm();
close();
}}
onCancel={() => setShowWarning(false)}
/>
Triggered by: - Closing form with dirty state - Navigating away with unsaved changes - Browser back button
Privacy Notice Dialog¶
First-run privacy consent.
const { hasAccepted, accept } = usePrivacyNoticeStore();
{!hasAccepted && (
<PrivacyNoticeDialog
open={true}
onAccept={accept}
/>
)}
Persisted in localStorage.
PWA Update Dialog¶
Notifies users of available updates.
const { needsUpdate, update } = usePwaUpdate();
<PwaUpdateDialog
open={needsUpdate}
onUpdate={update}
onDismiss={dismiss}
/>
Dialog Best Practices¶
| Do | Don't |
|---|---|
| Use clear action verbs | Use vague "OK/Cancel" |
| Show loading states | Allow double-submission |
| Trap focus inside dialog | Allow background interaction |
| Support Escape to close | Require mouse to close |
| Animate open/close | Instant show/hide |
Accessibility¶
Dialogs must: - Trap focus within the dialog - Return focus on close - Support Escape key - Have proper ARIA attributes
MUI Dialog handles this automatically:
<Dialog
open={open}
onClose={onClose}
aria-labelledby="dialog-title"
>
<DialogTitle id="dialog-title">Title</DialogTitle>
...
</Dialog>
Related¶
- Hooks — Modal hooks
- Forms — Form patterns
- State Management — Dialog state