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:
parent
793b69e592
commit
c0047269c1
@ -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}
|
||||
|
@ -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 (
|
||||
<>
|
||||
|
@ -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")}>
|
||||
|
@ -671,10 +671,6 @@ const LayerUI = ({
|
||||
{appState.showHelpDialog && (
|
||||
<HelpDialog
|
||||
onClose={() => {
|
||||
const helpIcon = document.querySelector(
|
||||
".help-icon",
|
||||
)! as HTMLElement;
|
||||
helpIcon.focus();
|
||||
setAppState({ showHelpDialog: false });
|
||||
}}
|
||||
/>
|
||||
|
@ -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) => {
|
||||
|
Loading…
x
Reference in New Issue
Block a user