(
+ 'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'
+ );
+ if (focusable.length === 0) return;
+
+ const first = focusable[0];
+ const last = focusable[focusable.length - 1];
+
+ if (e.shiftKey) {
+ if (document.activeElement === first) {
+ e.preventDefault();
+ last.focus();
+ }
+ } else {
+ if (document.activeElement === last) {
+ e.preventDefault();
+ first.focus();
+ }
+ }
}
};
document.addEventListener("keydown", handleKeyDown);
modalRef.current?.focus();
- return () => document.removeEventListener("keydown", handleKeyDown);
+ return () => {
+ document.removeEventListener("keydown", handleKeyDown);
+ triggerElement?.focus();
+ };
}, [isOpen]);
// Body scroll lock
@@ -426,6 +454,7 @@ export default function MultisigApprovalModal({
tabIndex={-1}
role="dialog"
aria-modal="true"
+ aria-busy={isLoading}
aria-labelledby="multisig-modal-title"
aria-describedby="multisig-modal-description"
>
@@ -453,6 +482,21 @@ export default function MultisigApprovalModal({
+ {/* Screen reader announcements */}
+
+ {currentStep === "processing"
+ ? "Processing your transaction. Please wait."
+ : currentStep === "confirm"
+ ? "Transaction approved successfully."
+ : currentStep === "error"
+ ? "Transaction failed. See error details below."
+ : ""}
+
+
{/* Content */}