diff --git a/.Jules/palette.md b/.Jules/palette.md index 0a19f42a..c975fe97 100644 --- a/.Jules/palette.md +++ b/.Jules/palette.md @@ -26,3 +26,6 @@ ## 2026-04-09 - Standardize Modal Accessibility for Cloud Library **Learning:** The `CloudLibrary` component functioned as a modal visually but lacked standard ARIA modal attributes (`role="dialog"`, `aria-modal="true"`, `aria-labelledby`), causing screen readers to announce it incorrectly or not at all. **Action:** When implementing custom modals, always include `role="dialog"`, `aria-modal="true"`, an explicit `aria-labelledby` referencing a visually hidden or visible title element, and an `aria-hidden="true"` on the clickable background overlay. +## 2024-11-20 - Standardize Backdrop Overlay Accessibility +**Learning:** Components using `fixed inset-0` with a click handler to close a modal will cause screen readers to announce the entire background as a clickable element. This violates accessibility conventions. +**Action:** When implementing clickable background overlays for custom modals, always separate the clickable backdrop into its own `
` sibling of the dialog element, and explicitly mark it with `aria-hidden="true"`. diff --git a/src/components/AISongModal.tsx b/src/components/AISongModal.tsx index 8fa0fdc2..1b5b26fa 100644 --- a/src/components/AISongModal.tsx +++ b/src/components/AISongModal.tsx @@ -655,10 +655,17 @@ export function AISongModal({ isOpen, onClose, onImport, onShowToast, audioEngin
e.target === e.currentTarget && handleClose()} > + diff --git a/src/components/RbsImportModal.tsx b/src/components/RbsImportModal.tsx index 68cf6789..5a4311fd 100644 --- a/src/components/RbsImportModal.tsx +++ b/src/components/RbsImportModal.tsx @@ -384,9 +384,13 @@ export function RbsImportModal({ isOpen, onClose, onImport, onShowToast }: RbsIm return (
e.target === e.currentTarget && onClose()} > -
+