feat: keyboard shortcuts on Senders email list

Wires the shared useListKeyboardNav hook into SenderEmails so j/k/e/#
work there too, matching FolderView and SearchResults.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
cesnimda
2026-06-30 21:58:40 +02:00
parent 7710d49c77
commit c7ead8caae
+5 -2
View File
@@ -2,6 +2,7 @@ import { useEffect, useCallback, useRef, useState } from 'react';
import { AnalyticsApi, SearchApi, EmailApi } from '../api/client.js'; import { AnalyticsApi, SearchApi, EmailApi } from '../api/client.js';
import BulkToolbar from '../components/BulkToolbar.jsx'; import BulkToolbar from '../components/BulkToolbar.jsx';
import useSelection from '../hooks/useSelection.js'; import useSelection from '../hooks/useSelection.js';
import useListKeyboardNav from '../hooks/useListKeyboardNav.js';
// ── helpers ────────────────────────────────────────────────────────────────── // ── helpers ──────────────────────────────────────────────────────────────────
@@ -125,7 +126,7 @@ function EmailDetail({ email: summary, onBack }) {
// ── EmailListRow (row inside sender email list) ─────────────────────────────── // ── EmailListRow (row inside sender email list) ───────────────────────────────
function EmailListRow({ email: initial, onRemove, onOpen, selected, onToggleSelect }) { function EmailListRow({ email: initial, onRemove, onOpen, selected, onToggleSelect, focused }) {
const [email, setEmail] = useState(initial); const [email, setEmail] = useState(initial);
const [acting, setActing] = useState(false); const [acting, setActing] = useState(false);
@@ -147,7 +148,7 @@ function EmailListRow({ email: initial, onRemove, onOpen, selected, onToggleSele
return ( return (
<tr <tr
className={`email-row${email.isUnread ? ' email-row--unread' : ''}${acting ? ' email-row--acting' : ''}`} className={`email-row${email.isUnread ? ' email-row--unread' : ''}${acting ? ' email-row--acting' : ''}${focused ? ' email-row--focused' : ''}`}
onClick={() => onOpen(email)} onClick={() => onOpen(email)}
title="View email" title="View email"
style={{ cursor: 'pointer' }} style={{ cursor: 'pointer' }}
@@ -201,6 +202,7 @@ function SenderEmails({ sender }) {
const [openEmail, setOpenEmail] = useState(null); const [openEmail, setOpenEmail] = useState(null);
const sentinelRef = useRef(null); const sentinelRef = useRef(null);
const { selected, toggle, clear, removeIds, selectedIds } = useSelection(); const { selected, toggle, clear, removeIds, selectedIds } = useSelection();
const focusedId = useListKeyboardNav(emails, (id) => setEmails((prev) => prev.filter((x) => x.id !== id)));
// Reset when sender changes // Reset when sender changes
useEffect(() => { useEffect(() => {
@@ -272,6 +274,7 @@ function SenderEmails({ sender }) {
email={e} email={e}
selected={selected.has(e.id)} selected={selected.has(e.id)}
onToggleSelect={toggle} onToggleSelect={toggle}
focused={focusedId === e.id}
onOpen={setOpenEmail} onOpen={setOpenEmail}
onRemove={(id) => setEmails((prev) => prev.filter((x) => x.id !== id))} onRemove={(id) => setEmails((prev) => prev.filter((x) => x.id !== id))}
/> />