diff --git a/src/components/account-sheet.jsx b/src/components/account-sheet.jsx index cf7ccc30..37d4a903 100644 --- a/src/components/account-sheet.jsx +++ b/src/components/account-sheet.jsx @@ -11,8 +11,6 @@ function AccountSheet({ account, instance: propInstance, onClose }) { const { masto, instance, authenticated } = api({ instance: propInstance }); const isString = typeof account === 'string'; - const escRef = useHotkeys('esc', onClose, [onClose]); - useEffect(() => { if (!isString) { states.accounts[`${account.id}@${instance}`] = account; diff --git a/src/components/modal.jsx b/src/components/modal.jsx index a70aad57..34b0a58b 100644 --- a/src/components/modal.jsx +++ b/src/components/modal.jsx @@ -2,10 +2,11 @@ import './modal.css'; import { createPortal } from 'preact/compat'; import { useEffect, useRef } from 'preact/hooks'; +import { useHotkeys } from 'react-hotkeys-hook'; const $modalContainer = document.getElementById('modal-container'); -function Modal({ children, onClick, class: className }) { +function Modal({ children, onClose, onClick, class: className }) { if (!children) return null; const modalRef = useRef(); @@ -19,8 +20,28 @@ function Modal({ children, onClick, class: className }) { return () => clearTimeout(timer); }, []); + const escRef = useHotkeys('esc', onClose, [onClose], { + enabled: !!onClose, + }); + const Modal = ( - <div ref={modalRef} className={className} onClick={onClick}> + <div + ref={(node) => { + modalRef.current = node; + escRef.current = node?.querySelector?.('[tabindex="-1"]') || node; + }} + className={className} + onClick={(e) => { + onClick?.(e); + if (e.target === e.currentTarget) { + onClose?.(e); + } + }} + tabIndex="-1" + onFocus={(e) => { + modalRef.current?.querySelector?.('[tabindex="-1"]')?.focus?.(); + }} + > {children} </div> ); diff --git a/src/components/modals.jsx b/src/components/modals.jsx index aa5420b7..47c5871c 100644 --- a/src/components/modals.jsx +++ b/src/components/modals.jsx @@ -76,10 +76,8 @@ export default function Modals() { )} {!!snapStates.showSettings && ( <Modal - onClick={(e) => { - if (e.target === e.currentTarget) { - states.showSettings = false; - } + onClose={() => { + states.showSettings = false; }} > <Settings @@ -91,10 +89,8 @@ export default function Modals() { )} {!!snapStates.showAccounts && ( <Modal - onClick={(e) => { - if (e.target === e.currentTarget) { - states.showAccounts = false; - } + onClose={() => { + states.showAccounts = false; }} > <Accounts @@ -107,10 +103,8 @@ export default function Modals() { {!!snapStates.showAccount && ( <Modal class="light" - onClick={(e) => { - if (e.target === e.currentTarget) { - states.showAccount = false; - } + onClose={() => { + states.showAccount = false; }} > <AccountSheet @@ -127,10 +121,8 @@ export default function Modals() { )} {!!snapStates.showDrafts && ( <Modal - onClick={(e) => { - if (e.target === e.currentTarget) { - states.showDrafts = false; - } + onClose={() => { + states.showDrafts = false; }} > <Drafts onClose={() => (states.showDrafts = false)} /> @@ -161,10 +153,8 @@ export default function Modals() { {!!snapStates.showShortcutsSettings && ( <Modal class="light" - onClick={(e) => { - if (e.target === e.currentTarget) { - states.showShortcutsSettings = false; - } + onClose={() => { + states.showShortcutsSettings = false; }} > <ShortcutsSettings @@ -175,10 +165,8 @@ export default function Modals() { {!!snapStates.showGenericAccounts && ( <Modal class="light" - onClick={(e) => { - if (e.target === e.currentTarget) { - states.showGenericAccounts = false; - } + onClose={() => { + states.showGenericAccounts = false; }} > <GenericAccounts diff --git a/src/utils/focus-deck.jsx b/src/utils/focus-deck.jsx index 3f5c3fc0..16a8fded 100644 --- a/src/utils/focus-deck.jsx +++ b/src/utils/focus-deck.jsx @@ -5,6 +5,17 @@ const focusDeck = () => { // Focus first column // columns.querySelector('.deck-container')?.focus?.(); } else { + const modals = document.querySelectorAll('#modal-container > *'); + if (modals?.length) { + // Focus last modal + const modal = modals[modals.length - 1]; // last one + const modalFocusElement = + modal.querySelector('[tabindex="-1"]') || modal; + if (modalFocusElement) { + modalFocusElement.focus(); + return; + } + } const backDrop = document.querySelector('.deck-backdrop'); if (backDrop) return; // Focus last deck