mirror of
https://github.com/cheeaun/phanpy.git
synced 2025-02-02 14:16:39 +01:00
Rework the modal close + focus logic
- 'Esc' a modal will focus on "behind" nested modal - All modals will have 'esc'
This commit is contained in:
parent
fce5e45bc9
commit
27274eeab1
4 changed files with 46 additions and 28 deletions
|
@ -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;
|
||||
|
|
|
@ -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>
|
||||
);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue