Rework the modal close + focus logic

- 'Esc' a modal will focus on "behind" nested modal
- All modals will have 'esc'
pull/228/head
Lim Chee Aun 2023-09-14 20:39:23 +08:00
rodzic fce5e45bc9
commit 27274eeab1
4 zmienionych plików z 46 dodań i 28 usunięć

Wyświetl plik

@ -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;

Wyświetl plik

@ -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>
);

Wyświetl plik

@ -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

Wyświetl plik

@ -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