Files
spsays-training/app/books/bg/[chapter]/verse-index.tsx
T
2026-04-04 13:29:23 +05:30

62 lines
1.7 KiB
TypeScript

"use client";
import { useEffect, useState } from "react";
type VerseEntry = {
verse: number;
reference: string;
};
export function VerseIndex({
verses,
chapter,
}: {
verses: VerseEntry[];
chapter: string;
}) {
const [activeVerse, setActiveVerse] = useState<number | null>(null);
useEffect(() => {
const observer = new IntersectionObserver(
(entries) => {
for (const entry of entries) {
if (entry.isIntersecting) {
const id = entry.target.id;
const num = parseInt(id.replace("verse-", ""));
if (!isNaN(num)) setActiveVerse(num);
}
}
},
{ rootMargin: "-20% 0px -60% 0px" }
);
const articles = document.querySelectorAll("article[id^='verse-']");
articles.forEach((el) => observer.observe(el));
return () => observer.disconnect();
}, []);
return (
<aside className="hidden lg:block w-48 shrink-0 sticky top-[89px] self-start max-h-[calc(100vh-89px)] overflow-y-auto py-8 pr-4">
<h2 className="text-xs font-bold uppercase tracking-wider text-amber-600 dark:text-amber-500 mb-3 px-2">
Verses
</h2>
<nav className="grid grid-cols-3 gap-0.5">
{verses.map((v) => (
<a
key={v.verse}
href={`#verse-${v.verse}`}
className={`px-2 py-1 rounded text-sm text-center transition-colors ${
activeVerse === v.verse
? "bg-amber-200 dark:bg-amber-900/40 text-amber-900 dark:text-amber-300 font-medium"
: "text-zinc-600 dark:text-zinc-400 hover:bg-amber-100 dark:hover:bg-zinc-800 hover:text-zinc-900 dark:hover:text-zinc-200"
}`}
>
{v.verse}
</a>
))}
</nav>
</aside>
);
}