fix(17): WR-01 trap focus in modal dialogs via useFocusTrap

This commit is contained in:
Lucas Berger
2026-06-18 13:41:33 -04:00
parent a4a7438641
commit fb30800e9a
3 changed files with 28 additions and 0 deletions
+6
View File
@@ -39,6 +39,7 @@ import {
} from '../api/client.js';
import { CredentialSheet, type CredentialSheetMode } from '../components/CredentialSheet.js';
import { useIsPhone } from '../hooks/useIsPhone.js';
import { useFocusTrap } from '../hooks/useFocusTrap.js';
// ── Styles ─────────────────────────────────────────────────────────────────
@@ -1352,6 +1353,9 @@ function ResetPasswordSheet({ isOpen, onClose, onSuccess, member }: ResetPasswor
const [confirmPassword, setConfirmPassword] = useState('');
const [error, setError] = useState<string | null>(null);
const headingRef = useRef<HTMLHeadingElement>(null);
// WR-01: trap Tab/Shift+Tab inside the dialog (matches aria-modal="true").
const dialogRef = useRef<HTMLDivElement>(null);
const handleDialogKeyDown = useFocusTrap(dialogRef);
// Escape closes the sheet
useEffect(() => {
@@ -1417,9 +1421,11 @@ function ResetPasswordSheet({ isOpen, onClose, onSuccess, member }: ResetPasswor
{/* Sheet — phone: bottom-sheet / desktop: centered modal (D-09) */}
<div
ref={dialogRef}
role="dialog"
aria-modal="true"
aria-label="Reset password"
onKeyDown={handleDialogKeyDown}
style={
sheetPhone
? {