From a8f1ce1f1eb59e94c2ca4758c4b7f739f5429b6d Mon Sep 17 00:00:00 2001 From: hrb-hub <181954414+hrb-hub@users.noreply.github.com> Date: Tue, 17 Dec 2024 11:33:52 +0100 Subject: [PATCH] Trap focus in topmost modal on screen readers Close #7998 Co-authored-by: ivk --- src/RootView.ts | 2 +- src/common/gui/base/Modal.ts | 11 ++++------- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/src/RootView.ts b/src/RootView.ts index a0317cdd4eaa..dfb73e1003d5 100644 --- a/src/RootView.ts +++ b/src/RootView.ts @@ -76,7 +76,7 @@ export class RootView implements ClassComponent { height: "100%", }, }, - [m(overlay), m(modal), vnode.children], + [m(overlay), m(modal), m(".main-view", { inert: modal.visible }, vnode.children)], ) } diff --git a/src/common/gui/base/Modal.ts b/src/common/gui/base/Modal.ts index a5780018828c..793fbdd7d5ea 100644 --- a/src/common/gui/base/Modal.ts +++ b/src/common/gui/base/Modal.ts @@ -4,7 +4,7 @@ import { theme } from "../theme" import type { Shortcut } from "../../misc/KeyManager" import { keyManager } from "../../misc/KeyManager" import { windowFacade } from "../../misc/WindowFacade" -import { insideRect, remove } from "@tutao/tutanota-utils" +import { insideRect, lastIndex, remove } from "@tutao/tutanota-utils" import { LayerType } from "../../../RootView" import { assertMainOrNodeBoot } from "../../api/common/Env" @@ -36,12 +36,8 @@ class Modal implements Component { return m( "#modal.fill-absolute", { - oncreate: (_) => { - // const lastComponent = last(this.components) - // if (lastComponent) { - // lastComponent.component.backgroundClick(e) - // } - }, + "aria-modal": true, + inert: !this.visible, style: { "z-index": LayerType.Modal, display: this.visible ? "" : "none", @@ -52,6 +48,7 @@ class Modal implements Component { ".fill-absolute", { key: wrapper.key, + inert: i !== lastIndex(array), oncreate: (vnode) => { // do not set visible=true already in display() because it leads to modal staying open in a second window in Chrome // because onbeforeremove is not called in that case to set visible=false. this is probably an optimization in Chrome to reduce