mirror of
https://github.com/cheeaun/phanpy.git
synced 2024-11-25 02:35:39 +03:00
First step in making things focusable
This commit is contained in:
parent
30c529fe02
commit
9201f7a118
8 changed files with 62 additions and 9 deletions
27
src/app.jsx
27
src/app.jsx
|
@ -298,6 +298,26 @@ export function App() {
|
|||
}, []);
|
||||
|
||||
const [currentDeck, setCurrentDeck] = useState('home');
|
||||
const focusDeck = () => {
|
||||
let timer = setTimeout(() => {
|
||||
const page = document.getElementById(`${currentDeck}-page`);
|
||||
console.log('focus', currentDeck, page);
|
||||
if (page) {
|
||||
page.focus();
|
||||
}
|
||||
}, 100);
|
||||
return () => clearTimeout(timer);
|
||||
};
|
||||
useEffect(focusDeck, [currentDeck]);
|
||||
useEffect(() => {
|
||||
if (
|
||||
!snapStates.showCompose &&
|
||||
!snapStates.showSettings &&
|
||||
!snapStates.showAccount
|
||||
) {
|
||||
focusDeck();
|
||||
}
|
||||
}, [snapStates.showCompose, snapStates.showSettings, snapStates.showAccount]);
|
||||
|
||||
useEffect(() => {
|
||||
// HACK: prevent this from running again due to HMR
|
||||
|
@ -324,7 +344,7 @@ export function App() {
|
|||
|
||||
return (
|
||||
<>
|
||||
{isLoggedIn && currentDeck && (
|
||||
{isLoggedIn && (
|
||||
<>
|
||||
<button
|
||||
type="button"
|
||||
|
@ -345,7 +365,7 @@ export function App() {
|
|||
</button>
|
||||
<div class="decks">
|
||||
{/* Home will never be unmounted */}
|
||||
<Home hidden={currentDeck !== 'home'} />
|
||||
<Home />
|
||||
{/* Notifications can be unmounted */}
|
||||
{currentDeck === 'notifications' && <Notifications />}
|
||||
</div>
|
||||
|
@ -355,6 +375,7 @@ export function App() {
|
|||
<Router
|
||||
history={createHashHistory()}
|
||||
onChange={(e) => {
|
||||
console.log('router onChange', e);
|
||||
// Special handling for Home and Notifications
|
||||
const { url } = e;
|
||||
if (/notifications/i.test(url)) {
|
||||
|
@ -362,7 +383,7 @@ export function App() {
|
|||
} else if (url === '/') {
|
||||
setCurrentDeck('home');
|
||||
document.title = `Home / ${CLIENT_NAME}`;
|
||||
} else if (url === '/login' || url === '/welcome') {
|
||||
} else {
|
||||
setCurrentDeck(null);
|
||||
}
|
||||
states.history.push(url);
|
||||
|
|
|
@ -102,7 +102,6 @@ function Account({ account }) {
|
|||
return (
|
||||
<div
|
||||
id="account-container"
|
||||
tabIndex="-1"
|
||||
class={`sheet ${uiState === 'loading' ? 'skeleton' : ''}`}
|
||||
>
|
||||
{!info || uiState === 'loading' ? (
|
||||
|
@ -129,7 +128,7 @@ function Account({ account }) {
|
|||
<Avatar url={avatar} size="xxxl" />
|
||||
<NameText account={info} showAcct external />
|
||||
</header>
|
||||
<main>
|
||||
<main tabIndex="-1">
|
||||
{bot && (
|
||||
<>
|
||||
<span class="tag">
|
||||
|
|
|
@ -1,14 +1,26 @@
|
|||
import './modal.css';
|
||||
|
||||
import { createPortal } from 'preact/compat';
|
||||
import { useEffect, useRef } from 'preact/hooks';
|
||||
|
||||
const $modalContainer = document.getElementById('modal-container');
|
||||
|
||||
function Modal({ children, onClick, class: className }) {
|
||||
if (!children) return null;
|
||||
|
||||
const modalRef = useRef();
|
||||
useEffect(() => {
|
||||
let timer = setTimeout(() => {
|
||||
const focusElement = modalRef.current?.querySelector('[tabindex="-1"]');
|
||||
if (focusElement) {
|
||||
focusElement.focus();
|
||||
}
|
||||
}, 100);
|
||||
return () => clearTimeout(timer);
|
||||
}, []);
|
||||
|
||||
const Modal = (
|
||||
<div className={className} onClick={onClick}>
|
||||
<div ref={modalRef} className={className} onClick={onClick}>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -186,8 +186,12 @@ function Status({
|
|||
});
|
||||
const readMoreText = 'Read more →';
|
||||
|
||||
const statusRef = useRef(null);
|
||||
|
||||
return (
|
||||
<article
|
||||
ref={statusRef}
|
||||
tabindex="-1"
|
||||
class={`status ${
|
||||
!withinContext && inReplyToAccount ? 'status-reply-to' : ''
|
||||
} visibility-${visibility} ${
|
||||
|
@ -653,6 +657,7 @@ function Status({
|
|||
index={showMediaModal}
|
||||
onClose={() => {
|
||||
setShowMediaModal(false);
|
||||
statusRef.current?.focus();
|
||||
}}
|
||||
/>
|
||||
</Modal>
|
||||
|
@ -662,6 +667,7 @@ function Status({
|
|||
onClick={(e) => {
|
||||
if (e.target === e.currentTarget) {
|
||||
setShowEdited(false);
|
||||
statusRef.current?.focus();
|
||||
}
|
||||
}}
|
||||
>
|
||||
|
@ -669,6 +675,7 @@ function Status({
|
|||
statusID={showEdited}
|
||||
onClose={() => {
|
||||
setShowEdited(false);
|
||||
statusRef.current?.focus();
|
||||
}}
|
||||
/>
|
||||
</Modal>
|
||||
|
@ -1153,7 +1160,7 @@ function EditedAtModal({ statusID, onClose = () => {} }) {
|
|||
const currentYear = new Date().getFullYear();
|
||||
|
||||
return (
|
||||
<div id="edit-history" class="sheet" tabIndex="-1">
|
||||
<div id="edit-history" class="sheet">
|
||||
<header>
|
||||
{/* <button type="button" class="close-button plain large" onClick={onClose}>
|
||||
<Icon icon="x" alt="Close" />
|
||||
|
@ -1166,7 +1173,7 @@ function EditedAtModal({ statusID, onClose = () => {} }) {
|
|||
</p>
|
||||
)}
|
||||
</header>
|
||||
<main>
|
||||
<main tabIndex="-1">
|
||||
{editHistory.length > 0 && (
|
||||
<ol>
|
||||
{editHistory.map((status) => {
|
||||
|
|
|
@ -242,6 +242,10 @@ code {
|
|||
}
|
||||
}
|
||||
|
||||
[tabindex='-1'] {
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
/* UTILS */
|
||||
|
||||
.ib {
|
||||
|
|
|
@ -73,6 +73,7 @@ function Home({ hidden }) {
|
|||
|
||||
return (
|
||||
<div
|
||||
id="home-page"
|
||||
class="deck-container"
|
||||
hidden={hidden}
|
||||
ref={scrollableRef}
|
||||
|
|
|
@ -290,7 +290,12 @@ function Notifications() {
|
|||
);
|
||||
// console.log(groupedNotifications);
|
||||
return (
|
||||
<div class="deck-container" ref={scrollableRef} tabIndex="-1">
|
||||
<div
|
||||
id="notifications-page"
|
||||
class="deck-container"
|
||||
ref={scrollableRef}
|
||||
tabIndex="-1"
|
||||
>
|
||||
<div class={`timeline-deck deck ${onlyMentions ? 'only-mentions' : ''}`}>
|
||||
<header
|
||||
onClick={() => {
|
||||
|
|
|
@ -33,6 +33,9 @@ function StatusPage({ id }) {
|
|||
const heroStatusRef = useRef();
|
||||
|
||||
const scrollableRef = useRef();
|
||||
useEffect(() => {
|
||||
scrollableRef.current?.focus();
|
||||
}, []);
|
||||
useEffect(() => {
|
||||
const onScroll = debounce(() => {
|
||||
// console.log('onScroll');
|
||||
|
@ -279,6 +282,7 @@ function StatusPage({ id }) {
|
|||
<div class="deck-backdrop">
|
||||
<Link href={closeLink}></Link>
|
||||
<div
|
||||
tabIndex="-1"
|
||||
ref={scrollableRef}
|
||||
class={`status-deck deck contained ${
|
||||
statuses.length > 1 ? 'padded-bottom' : ''
|
||||
|
|
Loading…
Reference in a new issue