this repo has no description
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Rework the modal close + focus logic

- 'Esc' a modal will focus on "behind" nested modal
- All modals will have 'esc'

+46 -28
-2
src/components/account-sheet.jsx
··· 11 11 const { masto, instance, authenticated } = api({ instance: propInstance }); 12 12 const isString = typeof account === 'string'; 13 13 14 - const escRef = useHotkeys('esc', onClose, [onClose]); 15 - 16 14 useEffect(() => { 17 15 if (!isString) { 18 16 states.accounts[`${account.id}@${instance}`] = account;
+23 -2
src/components/modal.jsx
··· 2 2 3 3 import { createPortal } from 'preact/compat'; 4 4 import { useEffect, useRef } from 'preact/hooks'; 5 + import { useHotkeys } from 'react-hotkeys-hook'; 5 6 6 7 const $modalContainer = document.getElementById('modal-container'); 7 8 8 - function Modal({ children, onClick, class: className }) { 9 + function Modal({ children, onClose, onClick, class: className }) { 9 10 if (!children) return null; 10 11 11 12 const modalRef = useRef(); ··· 18 19 }, 100); 19 20 return () => clearTimeout(timer); 20 21 }, []); 22 + 23 + const escRef = useHotkeys('esc', onClose, [onClose], { 24 + enabled: !!onClose, 25 + }); 21 26 22 27 const Modal = ( 23 - <div ref={modalRef} className={className} onClick={onClick}> 28 + <div 29 + ref={(node) => { 30 + modalRef.current = node; 31 + escRef.current = node?.querySelector?.('[tabindex="-1"]') || node; 32 + }} 33 + className={className} 34 + onClick={(e) => { 35 + onClick?.(e); 36 + if (e.target === e.currentTarget) { 37 + onClose?.(e); 38 + } 39 + }} 40 + tabIndex="-1" 41 + onFocus={(e) => { 42 + modalRef.current?.querySelector?.('[tabindex="-1"]')?.focus?.(); 43 + }} 44 + > 24 45 {children} 25 46 </div> 26 47 );
+12 -24
src/components/modals.jsx
··· 76 76 )} 77 77 {!!snapStates.showSettings && ( 78 78 <Modal 79 - onClick={(e) => { 80 - if (e.target === e.currentTarget) { 81 - states.showSettings = false; 82 - } 79 + onClose={() => { 80 + states.showSettings = false; 83 81 }} 84 82 > 85 83 <Settings ··· 91 89 )} 92 90 {!!snapStates.showAccounts && ( 93 91 <Modal 94 - onClick={(e) => { 95 - if (e.target === e.currentTarget) { 96 - states.showAccounts = false; 97 - } 92 + onClose={() => { 93 + states.showAccounts = false; 98 94 }} 99 95 > 100 96 <Accounts ··· 107 103 {!!snapStates.showAccount && ( 108 104 <Modal 109 105 class="light" 110 - onClick={(e) => { 111 - if (e.target === e.currentTarget) { 112 - states.showAccount = false; 113 - } 106 + onClose={() => { 107 + states.showAccount = false; 114 108 }} 115 109 > 116 110 <AccountSheet ··· 127 121 )} 128 122 {!!snapStates.showDrafts && ( 129 123 <Modal 130 - onClick={(e) => { 131 - if (e.target === e.currentTarget) { 132 - states.showDrafts = false; 133 - } 124 + onClose={() => { 125 + states.showDrafts = false; 134 126 }} 135 127 > 136 128 <Drafts onClose={() => (states.showDrafts = false)} /> ··· 161 153 {!!snapStates.showShortcutsSettings && ( 162 154 <Modal 163 155 class="light" 164 - onClick={(e) => { 165 - if (e.target === e.currentTarget) { 166 - states.showShortcutsSettings = false; 167 - } 156 + onClose={() => { 157 + states.showShortcutsSettings = false; 168 158 }} 169 159 > 170 160 <ShortcutsSettings ··· 175 165 {!!snapStates.showGenericAccounts && ( 176 166 <Modal 177 167 class="light" 178 - onClick={(e) => { 179 - if (e.target === e.currentTarget) { 180 - states.showGenericAccounts = false; 181 - } 168 + onClose={() => { 169 + states.showGenericAccounts = false; 182 170 }} 183 171 > 184 172 <GenericAccounts
+11
src/utils/focus-deck.jsx
··· 5 5 // Focus first column 6 6 // columns.querySelector('.deck-container')?.focus?.(); 7 7 } else { 8 + const modals = document.querySelectorAll('#modal-container > *'); 9 + if (modals?.length) { 10 + // Focus last modal 11 + const modal = modals[modals.length - 1]; // last one 12 + const modalFocusElement = 13 + modal.querySelector('[tabindex="-1"]') || modal; 14 + if (modalFocusElement) { 15 + modalFocusElement.focus(); 16 + return; 17 + } 18 + } 8 19 const backDrop = document.querySelector('.deck-backdrop'); 9 20 if (backDrop) return; 10 21 // Focus last deck