Wire Strong's dictionary concordance UI

This commit is contained in:
2026-07-12 07:56:26 -05:00
parent 6877fa78f2
commit 81ba163207
11 changed files with 364 additions and 31 deletions
+48 -2
View File
@@ -14,6 +14,7 @@ function App() {
const [verses, setVerses] = useState<Verse[]>([])
const [tags, setTags] = useState<Tag[]>([])
const [selectedId, setSelectedId] = useState<number | null>(null)
const [selectedStrong, setSelectedStrong] = useState<string | null>(null)
const [tagInput, setTagInput] = useState('')
const [loading, setLoading] = useState(true)
const [error, setError] = useState<string | null>(null)
@@ -60,6 +61,19 @@ function App() {
() => verses.find((verse) => verse.id === selectedId) ?? verses[0],
[selectedId, verses],
)
const selectedStrongEntry = useMemo(() => {
if (!selectedVerse?.strongs.length) return null
return (
selectedVerse.strongs.find((entry) => entry.strong === selectedStrong) ??
selectedVerse.strongs[0]
)
}, [selectedStrong, selectedVerse])
function searchStrong(strong: string) {
setQuery(strong)
setSelectedStrong(strong)
runSearch(strong).catch((reason) => setError(String(reason)))
}
return (
<main className="app-shell">
@@ -154,6 +168,20 @@ function App() {
<article className="verse-card">
<p>{selectedVerse.text}</p>
<div className="linked-word-list" aria-label="Linked Strong's words">
{selectedVerse.strongs.map((entry) => (
<button
key={`${entry.strong}-${entry.position}`}
className={entry.strong === selectedStrongEntry?.strong ? 'word-link active' : 'word-link'}
type="button"
title={`${entry.surface}: ${entry.strong}`}
onClick={() => setSelectedStrong(entry.strong)}
>
<span>{entry.surface}</span>
<small>{entry.strong}</small>
</button>
))}
</div>
</article>
<div className="study-grid">
@@ -162,12 +190,30 @@ function App() {
<h3>Strong's Links</h3>
<span>{selectedVerse.strongs.length}</span>
</div>
{selectedStrongEntry ? (
<article className="strong-focus">
<div>
<strong>{selectedStrongEntry.strong}</strong>
<span>{selectedStrongEntry.language}</span>
</div>
<h4>{selectedStrongEntry.lemma}</h4>
<p className="translit">{selectedStrongEntry.transliteration}</p>
<p>{selectedStrongEntry.definition}</p>
<button type="button" onClick={() => searchStrong(selectedStrongEntry.strong)}>
Show matching verses
</button>
</article>
) : null}
<div className="strong-list">
{selectedVerse.strongs.map((entry) => (
<article key={entry.strong} className="strong-entry">
<article
key={`${entry.strong}-${entry.position}`}
className={entry.strong === selectedStrongEntry?.strong ? 'strong-entry active' : 'strong-entry'}
onClick={() => setSelectedStrong(entry.strong)}
>
<div>
<strong>{entry.strong}</strong>
<span>{entry.language}</span>
<span>{entry.surface}</span>
</div>
<h4>{entry.lemma}</h4>
<p className="translit">{entry.transliteration}</p>