diff --git a/README.md b/README.md index 03f9b55842..b84505f541 100755 --- a/README.md +++ b/README.md @@ -1,5 +1,6 @@ # ASU Unity Design System (UDS) + ## Table of Contents - [ASU Unity Design System (UDS)](#asu-unity-design-system-uds) @@ -441,3 +442,4 @@ Read contribution guide here: [CONTRIBUTING.md](./CONTRIBUTING.md) ### See [here](https://docs.github.com/en/actions/guides/publishing-nodejs-packages) for more information about publishing packages ### See [the top answer on this stackoverflow question](https://stackoverflow.com/questions/62819489/github-actions-why-build-with-different-node-versions) for why you may want to build against multiple node versions. Probably unnecessary for this workflow. + diff --git a/packages/unity-bootstrap-theme/src/js/modals.js b/packages/unity-bootstrap-theme/src/js/modals.js index 50b9b6c816..324335d3bb 100644 --- a/packages/unity-bootstrap-theme/src/js/modals.js +++ b/packages/unity-bootstrap-theme/src/js/modals.js @@ -5,6 +5,7 @@ function initModals() { .getElementById("openModalButton") ?.addEventListener("click", function () { 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-react-core/src/components/AnchorMenu/AnchorMenu.styles.js b/packages/unity-react-core/src/components/AnchorMenu/AnchorMenu.styles.js index 5f40893108..6f6e82b5eb 100644 --- a/packages/unity-react-core/src/components/AnchorMenu/AnchorMenu.styles.js +++ b/packages/unity-react-core/src/components/AnchorMenu/AnchorMenu.styles.js @@ -10,13 +10,11 @@ const AnchorMenuWrapper = styled.div` .mobile-menu-toggler { background-color: transparent; border: none; - padding: 0; - cursor: pointer; - display: flex; - justify-content: space-between; - align-items: center; - width: 100%; - text-align: inherit; + cursor: default; + h4, + h2 { + align-items: center; + } i { transition: all 0.3s; } diff --git a/packages/unity-react-core/src/components/Modal/Modal.tsx b/packages/unity-react-core/src/components/Modal/Modal.tsx index cf043a551d..173f6b2bce 100644 --- a/packages/unity-react-core/src/components/Modal/Modal.tsx +++ b/packages/unity-react-core/src/components/Modal/Modal.tsx @@ -36,14 +36,62 @@ export const Modal: React.FC = ({ open, gaData }) => { const { isReact, isBootstrap } = useBaseSpecificFramework(); const [openState, setOpen] = React.useState(open); + const focusOnModalInput = () => { + //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; + + if (lastFocusableElement && firstFocusableElement) { + document.addEventListener('keydown', function (e) { + 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(); + } + } + }); + (firstFocusableElement as HTMLElement)?.focus(); + } + } + const handleOpen = () => { setOpen(true); + focusOnModalInput(); }; const handleClose = () => { setOpen(false); }; + useEffect(() => { + const handleKeyDown = (event) => { + if (event.key === 'Escape') setOpen(false); // Close on Esc key + }; + + if (openState) { + document.addEventListener('keydown', handleKeyDown); + } + + return () => document.removeEventListener('keydown', handleKeyDown); + }, [openState, setOpen]); + + const modalTitle = "Content"; + return (
); -}; + } +); + +TabHeader.displayName = "TabHeader"; export { TabHeader }; export type { TabHeaderProps };