diff --git a/packages/unity-bootstrap-theme/src/js/modals.js b/packages/unity-bootstrap-theme/src/js/modals.js index 50b9b6c816..622eb6d204 100644 --- a/packages/unity-bootstrap-theme/src/js/modals.js +++ b/packages/unity-bootstrap-theme/src/js/modals.js @@ -4,7 +4,8 @@ function initModals() { document .getElementById("openModalButton") ?.addEventListener("click", function () { - document.getElementById("uds-modal").classList.add("open"); + document.getElementById("uds-modal")?.classList.add("open"); + document.getElementById("closeModalButton")?.focus(); }); document @@ -12,6 +13,11 @@ function initModals() { ?.addEventListener("click", function () { document.getElementById("uds-modal").classList.remove("open"); }); + + document?.addEventListener("keydown", function (event) { + event.key === "Escape" && + document.getElementById("uds-modal")?.classList.remove("open"); + }); } EventHandler.on(window, "load.uds.modals", initModals); diff --git a/packages/unity-bootstrap-theme/src/scss/extends/_modals.scss b/packages/unity-bootstrap-theme/src/scss/extends/_modals.scss index a3e6eba659..6bcace67f7 100644 --- a/packages/unity-bootstrap-theme/src/scss/extends/_modals.scss +++ b/packages/unity-bootstrap-theme/src/scss/extends/_modals.scss @@ -53,6 +53,11 @@ background-color: $uds-color-background-white; opacity: .7; } + + &:focus, + &:focus-visible { + background-color: $uds-color-background-white; + } } } diff --git a/packages/unity-react-core/src/components/Modal/Modal.tsx b/packages/unity-react-core/src/components/Modal/Modal.tsx index cf043a551d..8c945d703d 100644 --- a/packages/unity-react-core/src/components/Modal/Modal.tsx +++ b/packages/unity-react-core/src/components/Modal/Modal.tsx @@ -44,13 +44,70 @@ export const Modal: React.FC = ({ open, gaData }) => { setOpen(false); }; + useEffect(() => { + const handleKeyDown = (event: any) => { + if (event.key === "Escape") setOpen(false); // Close on Esc key + }; + + if (openState) { + document.addEventListener("keydown", handleKeyDown); + } + + return () => document.removeEventListener("keydown", handleKeyDown); + }, [openState, setOpen]); + + useEffect(() => { + if (!openState) return; + + //source: https://stackoverflow.com/questions/4195616/how-to-set-the-focus-on-a-javascript-modal-window + const focusableElements = + 'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'; + const modal = document.getElementsByClassName("uds-modal-container")[0]; + const firstFocusableElement = modal?.querySelectorAll(focusableElements)[0]; + const focusableContent = modal?.querySelectorAll(focusableElements); + const lastFocusableElement = focusableContent + ? focusableContent[focusableContent?.length - 1] + : undefined; + + const handleTabKey = (e: KeyboardEvent) => { + let isTabPressed = e.key === "Tab"; // || e.keyCode === 9; + + if (!isTabPressed) { + return; + } + + if (e.shiftKey) { + // if shift key pressed for shift + tab combination + if (document.activeElement === firstFocusableElement) { + (lastFocusableElement as HTMLElement)?.focus(); // add focus for the last focusable element + e.preventDefault(); + } + } else { + // if tab key is pressed + if (document.activeElement === lastFocusableElement) { + // if focused has reached to last focusable element then focus first focusable element after pressing tab + (firstFocusableElement as HTMLElement)?.focus(); // add focus for the first focusable element + e.preventDefault(); + } + } + }; + + if (lastFocusableElement && firstFocusableElement) { + document.addEventListener("keydown", handleTabKey); + (firstFocusableElement as HTMLElement)?.focus(); + return () => document.removeEventListener("keydown", handleTabKey); + } + }, [openState]); + + const modalTitle = "Content"; + return (