Context
Found during the 2026 Axim-commissioned accessibility audit of Paragon, while documenting ModalDialog against the APG modal dialog pattern.
Current behavior
ModalDialog renders the dialog container with role="dialog" and aria-label={title} (ModalDialog.tsx), and ModalLayer enforces focus containment behaviorally via react-focus-on. However, aria-modal="true" is not set.
Impact
Some screen readers use aria-modal to scope reading/browse commands to the dialog and treat background content as inert. Without it, users may be able to read (though not focus) background content while the dialog is open, contrary to the modal's intent. WCAG mapping: 4.1.2 Name, Role, Value (state not fully exposed).
Suggested fix
Add aria-modal="true" to the role="dialog" element in ModalDialog.tsx. Verify the derived modals (AlertModal, FullscreenModal, MarketingModal) inherit it, and confirm no double-inert conflict with the react-focus-on aria-hidden handling.
References
Context
Found during the 2026 Axim-commissioned accessibility audit of Paragon, while documenting
ModalDialogagainst the APG modal dialog pattern.Current behavior
ModalDialogrenders the dialog container withrole="dialog"andaria-label={title}(ModalDialog.tsx), andModalLayerenforces focus containment behaviorally viareact-focus-on. However,aria-modal="true"is not set.Impact
Some screen readers use
aria-modalto scope reading/browse commands to the dialog and treat background content as inert. Without it, users may be able to read (though not focus) background content while the dialog is open, contrary to the modal's intent. WCAG mapping: 4.1.2 Name, Role, Value (state not fully exposed).Suggested fix
Add
aria-modal="true"to therole="dialog"element inModalDialog.tsx. Verify the derived modals (AlertModal,FullscreenModal,MarketingModal) inherit it, and confirm no double-inert conflict with thereact-focus-onaria-hidden handling.References