Hover tooltips, clickable cross-references, easier highlighting

- Tooltips on hover and keyboard focus across the app: icon-only buttons show
  their label, existing titles show in the app's style without the browser's
  delay, and the reader's main buttons show shortcut hints ("Search (/)").
  Touch screens are unaffected.
- Reader: cross-references (under verses and in the Cross-refs tab) open the
  passage's text in the side panel without leaving the chapter; "Open chapter"
  goes there when wanted
- Reader: the verse panel now has a Highlight row of colours for one-tap
  whole-verse highlighting (tap again to remove, Clear for all, with Undo);
  selecting words still highlights just those
- Fix: a cross-reference preview was cleared when React ran the panel's
  effect twice (development builds)

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
nmemmertandClaude Sonnet 5.5 committed 2026-10-01 16:31:27 -04:00
1 parent bb80623c45
commit 7f0256be06
9 files changed
+394 -28

No files matched your search

+12 -12
View File
@@ -9,9 +9,9 @@ export function TopBar({ title, onBack, onOpenNavigator, onSearch, onBookmarks,
return (
<div className="safe-top sticky top-0 z-30 border-b border-[var(--r-line)] bg-[var(--r-bar)] font-sans">
<div className="mx-auto flex h-12 max-w-4xl items-center gap-1 px-2">
<button type="button" onClick={onBack} className="flex h-9 items-center gap-0.5 rounded-lg pl-1 pr-2 text-[var(--r-sub)] transition hover:bg-black/5" aria-label="Back to home"><ChevronLeft /><span className="hidden text-xs sm:inline">Home</span></button>
<button type="button" onClick={onBack} className="flex h-9 items-center gap-0.5 rounded-lg pl-1 pr-2 text-[var(--r-sub)] transition hover:bg-black/5" aria-label="Back to home" data-tip="Back to home"><ChevronLeft /><span className="hidden text-xs sm:inline">Home</span></button>
<button type="button" onClick={onOpenNavigator}
className="mx-auto flex min-w-0 items-center gap-1.5 rounded-lg px-3 py-1.5 text-sm font-medium text-[var(--r-text)] hover:bg-black/5">
className="mx-auto flex min-w-0 items-center gap-1.5 rounded-lg px-3 py-1.5 text-sm font-medium text-[var(--r-text)] hover:bg-black/5" data-tip="Go to a book and chapter (G)">
<span className="truncate">{title}</span><ChevronDown />
</button>
{onDoneDrawing ? (
@@ -21,12 +21,12 @@ export function TopBar({ title, onBack, onOpenNavigator, onSearch, onBookmarks,
</button>
) : (
<>
<button type="button" onClick={onSearch} className={iconBtn} aria-label="Search"><SearchIcon /></button>
<button type="button" onClick={onBookmarks} className={`${iconBtn} relative ${bookmarkCount ? 'text-[var(--r-accent)]' : ''}`} aria-label="Bookmarks">
<button type="button" onClick={onSearch} className={iconBtn} aria-label="Search" data-tip="Search (/)"><SearchIcon /></button>
<button type="button" onClick={onBookmarks} className={`${iconBtn} relative ${bookmarkCount ? 'text-[var(--r-accent)]' : ''}`} aria-label="Bookmarks" data-tip="Bookmarks and highlights">
<BookmarkIcon filled={bookmarkCount > 0} />
</button>
<button type="button" onClick={onCompare} className={`${iconBtn} ${compareActive ? 'text-[var(--r-accent)]' : ''}`} aria-label="Compare translations" aria-pressed={!!compareActive} title="Compare translations"><CompareIcon /></button>
<button type="button" onClick={onSettings} className={`${iconBtn} w-10 text-sm font-medium`} aria-label="Reading settings">Aa</button>
<button type="button" onClick={onCompare} className={`${iconBtn} ${compareActive ? 'text-[var(--r-accent)]' : ''}`} aria-label="Compare translations" aria-pressed={!!compareActive} data-tip="Compare translations (C)"><CompareIcon /></button>
<button type="button" onClick={onSettings} className={`${iconBtn} w-10 text-sm font-medium`} aria-label="Reading settings" data-tip="Text size, typeface and theme (,)">Aa</button>
</>
)}
</div>
@@ -42,11 +42,11 @@ export function BottomBar({
return (
<div className="fixed inset-x-0 bottom-0 z-30 border-t border-[var(--r-line)] bg-[var(--r-bar)] pb-[env(safe-area-inset-bottom)] font-sans">
<div className="mx-auto flex h-14 max-w-4xl items-center gap-0.5 px-2">
<button type="button" onClick={onPrev} disabled={prevDisabled} className={iconBtn} aria-label="Previous chapter"><ChevronLeft /></button>
<button type="button" onClick={onAudio} className={`${iconBtn} ${audioActive ? active : ''}`} aria-label="Listen"><HeadphonesIcon /></button>
<button type="button" onClick={onPen} className={iconBtn} aria-label="Draw notes"><PenIcon /></button>
<button type="button" onClick={onCrossRefs} className={`${iconBtn} ${crossRefsOn ? active : ''}`} aria-label="Show cross-references under verses"><LinkIcon /></button>
<button type="button" onClick={onFocus} className={iconBtn} aria-label="Hide controls"><FocusIcon /></button>
<button type="button" onClick={onPrev} disabled={prevDisabled} className={iconBtn} aria-label="Previous chapter" data-tip="Previous chapter (←)"><ChevronLeft /></button>
<button type="button" onClick={onAudio} className={`${iconBtn} ${audioActive ? active : ''}`} aria-label="Listen" data-tip="Listen to this chapter"><HeadphonesIcon /></button>
<button type="button" onClick={onPen} className={iconBtn} aria-label="Draw notes" data-tip="Draw notes on this page"><PenIcon /></button>
<button type="button" onClick={onCrossRefs} className={`${iconBtn} ${crossRefsOn ? active : ''}`} aria-label="Show cross-references under verses" data-tip="Show cross-references under each verse"><LinkIcon /></button>
<button type="button" onClick={onFocus} className={iconBtn} aria-label="Hide controls" data-tip="Hide the controls (F)"><FocusIcon /></button>
<div className="mx-auto" />
{primary && (
<button type="button" onClick={primary.onClick}
@@ -54,7 +54,7 @@ export function BottomBar({
{primary.done ? null : <CheckIcon />}{primary.label}
</button>
)}
<button type="button" onClick={onNext} disabled={nextDisabled} className={iconBtn} aria-label="Next chapter"><ChevronRight /></button>
<button type="button" onClick={onNext} disabled={nextDisabled} className={iconBtn} aria-label="Next chapter" data-tip="Next chapter (→)"><ChevronRight /></button>
</div>
</div>
);