// Bible tab — King James 1611, served entirely from the local CSV (offline, instant). // Floating navigator (BIBLE App Labs style): book search + book/chapter/verse pickers + All/OT/NT + GO. function BibleTab(){ const meta = window.BIBLE_BOOKS; const testOf = React.useMemo(()=>{ const m={}; meta.forEach(b=>m[b.name]=b.testament); return m; }, [meta]); const [bible, setBible] = React.useState(null); // { data, order, chapterCount } const [loadErr, setLoadErr] = React.useState(''); const [ref, setRef] = React.useState({ book:'Genesis', chapter:1, verse:1 }); const [open, setOpen] = React.useState(false); const scrollRef = React.useRef(null); // panel working selection const [test, setTest] = React.useState('All'); const [selBook, setSelBook] = React.useState('Genesis'); const [selCh, setSelCh] = React.useState(1); const [selV, setSelV] = React.useState(1); const [query, setQuery] = React.useState(''); const [fontScale, setFontScale] = React.useState(()=> parseFloat(localStorage.getItem('cwa-biblefont')||'1') || 1); React.useEffect(()=>{ localStorage.setItem('cwa-biblefont', String(fontScale)); }, [fontScale]); const bump = (d)=> setFontScale(s=> Math.min(1.9, Math.max(0.8, Math.round((s+d)*10)/10))); React.useEffect(()=>{ let alive = true; window.loadBible().then(b=>{ if(alive){ setBible(b); } }) .catch(()=>{ if(alive) setLoadErr('Could not load the Bible file (uploads/kjv1611_full.csv).'); }); return ()=>{ alive=false; }; }, []); const verses = bible && bible.data[ref.book] && bible.data[ref.book][ref.chapter] ? bible.data[ref.book][ref.chapter] : []; const chCount = bible ? bible.chapterCount(selBook) : 1; const chapters = Array.from({length: Math.max(chCount,1)}, (_,n)=>n+1); const vCount = bible && bible.data[selBook] && bible.data[selBook][selCh] ? bible.data[selBook][selCh].length : 1; const verseList = Array.from({length: Math.max(vCount,1)}, (_,n)=>n+1); const order = bible ? bible.order : meta.map(b=>b.name); const filtered = order.filter(name => (test==='All' || testOf[name]===test) && name.toLowerCase().includes(query.toLowerCase())); function go(book, chapter, verse){ setRef({ book, chapter, verse }); setOpen(false); requestAnimationFrame(()=>{ const el = scrollRef.current; if(!el) return; el.scrollTop = 0; if(verse>1){ const t = el.querySelector(`[data-v="${verse}"]`); if(t) el.scrollTop = t.offsetTop - 30; } }); } function openPanel(){ setSelBook(ref.book); setSelCh(ref.chapter); setSelV(ref.verse); setQuery(''); setOpen(o=>!o); } return (

{ref.book} {ref.chapter}

{!bible && !loadErr &&
Loading the King James 1611…
} {loadErr &&
{loadErr}
} {bible && verses.map(v=>(

{v.verse}{v.text}

))} {bible && !verses.length && !loadErr &&
Passage not found.
}
{open && (
{selBook} {selCh}:{selV}
setQuery(e.target.value)} />
{filtered.map(name=>(
{ setSelBook(name); setSelCh(1); setSelV(1); }}>{name}
))} {!filtered.length &&
No match
}
{chapters.map(c=>(
{ setSelCh(c); setSelV(1); }}>{c}
))}
{verseList.map(v=>(
setSelV(v)}>{v}
))}
{['All','OT','NT'].map(t=>( ))}
)}
); } window.BibleTab = BibleTab;