fix: focus on last active element when dialog closes (#3447)

* fix: focus on last active element when dialog closes

* useState instead of ref
This commit is contained in:
Aakansha Doshi 2021-04-15 20:29:00 +05:30 committed by GitHub
parent 793b69e592
commit c0047269c1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 15 additions and 14 deletions

View File

@ -1,5 +1,5 @@
import clsx from "clsx";
import React, { useEffect } from "react";
import React, { useEffect, useState } from "react";
import { useCallbackRefState } from "../hooks/useCallbackRefState";
import { t } from "../i18n";
import { useIsMobile } from "../components/App";
@ -20,6 +20,8 @@ export const Dialog = (props: {
theme?: AppState["theme"];
}) => {
const [islandNode, setIslandNode] = useCallbackRefState<HTMLDivElement>();
const [lastActiveElement] = useState(document.activeElement);
useEffect(() => {
if (!islandNode) {
return;
@ -66,12 +68,17 @@ export const Dialog = (props: {
return focusableElements ? Array.from(focusableElements) : [];
};
const onClose = () => {
(lastActiveElement as HTMLElement).focus();
props.onCloseRequest();
};
return (
<Modal
className={clsx("Dialog", props.className)}
labelledBy="dialog-title"
maxWidth={props.small ? 550 : 800}
onCloseRequest={props.onCloseRequest}
onCloseRequest={onClose}
theme={props.theme}
>
<Island ref={setIslandNode}>
@ -79,7 +86,7 @@ export const Dialog = (props: {
<span className="Dialog__titleContent">{props.title}</span>
<button
className="Modal__close"
onClick={props.onCloseRequest}
onClick={onClose}
aria-label={t("buttons.close")}
>
{useIsMobile() ? back : close}

View File

@ -2,6 +2,7 @@ import React, { useState } from "react";
import { t } from "../i18n";
import { Dialog } from "./Dialog";
import { useExcalidrawContainer } from "./App";
export const ErrorDialog = ({
message,
@ -11,6 +12,7 @@ export const ErrorDialog = ({
onClose?: () => void;
}) => {
const [modalIsShown, setModalIsShown] = useState(!!message);
const excalidrawContainer = useExcalidrawContainer();
const handleClose = React.useCallback(() => {
setModalIsShown(false);
@ -18,8 +20,9 @@ export const ErrorDialog = ({
if (onClose) {
onClose();
}
document.querySelector<HTMLElement>(".excalidraw-container")?.focus();
}, [onClose]);
// TODO: Fix the A11y issues so this is never needed since we should always focus on last active element
excalidrawContainer?.focus();
}, [onClose, excalidrawContainer]);
return (
<>

View File

@ -244,11 +244,9 @@ export const ExportDialog = ({
onExportToBackend?: ExportCB;
}) => {
const [modalIsShown, setModalIsShown] = useState(false);
const triggerButton = useRef<HTMLButtonElement>(null);
const handleClose = React.useCallback(() => {
setModalIsShown(false);
triggerButton.current?.focus();
}, []);
return (
@ -263,7 +261,6 @@ export const ExportDialog = ({
aria-label={t("buttons.export")}
showAriaLabel={useIsMobile()}
title={t("buttons.export")}
ref={triggerButton}
/>
{modalIsShown && (
<Dialog onCloseRequest={handleClose} title={t("buttons.export")}>

View File

@ -671,10 +671,6 @@ const LayerUI = ({
{appState.showHelpDialog && (
<HelpDialog
onClose={() => {
const helpIcon = document.querySelector(
".help-icon",
)! as HTMLElement;
helpIcon.focus();
setAppState({ showHelpDialog: false });
}}
/>

View File

@ -591,8 +591,6 @@ class CollabWrapper extends PureComponent<Props, CollabState> {
handleClose = () => {
this.setState({ modalIsShown: false });
const collabIcon = document.querySelector(".CollabButton") as HTMLElement;
collabIcon.focus();
};
onUsernameChange = (username: string) => {