Files
study-bible-project/src/components/study/SuggestWordsSheet.jsx
T
nmemmertandClaude Sonnet 5.5 31abee0695
Build and Push Docker Image / build-and-push (push) Successful in 4m15s
Redesign the study side: Outline, Study, Script and Export stages
Studies now move through a stage bar in the reader's themes. Outline splits
chunks by clicking between verses (join merges notes) and suggests chunks from
section headings. Study is three panes: outline, passage with an Observe /
Interpret / Apply accordion, and commentary / word study / cross-refs / people
& places for the chunk; original words are added by clicking them in the
interlinear. Script drafts an outline from notes; Export holds files and the
share link. Home, Import and the Pronunciation guide are restyled. Study
projects are BSB only.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-09-29 10:13:46 -04:00

51 lines
3.4 KiB
React

// Picker for "suggest words from this passage": checkbox list of candidate words.
import DOMPurify from 'dompurify';
import Sheet from '../reader/Sheet.jsx';
import { buildGreekDefinitionHtml } from '../../utils/wordStudy.js';
export default function SuggestWordsSheet({ wordStudy }) {
const { suggestModal, setSuggestModal, suggestSelection, setSuggestSelection, confirmSuggestWords } = wordStudy;
if (!suggestModal) return null;
const close = () => { setSuggestModal(null); setSuggestSelection(new Set()); };
const n = suggestSelection.size;
return (
<Sheet open onClose={close} title={`Select ${suggestModal.language === 'hebrew' ? 'Hebrew' : 'Greek'} words to add`}>
<p className="mb-2 text-xs text-[var(--r-sub)]">{suggestModal.helperText || "Content words are pre-checked. Uncheck any you don't need."}</p>
<div className="mb-2 flex items-center gap-3 text-xs">
<button type="button" onClick={() => setSuggestSelection(new Set(suggestModal.words.map((w) => w.strongKey)))} className="text-[var(--r-accent)] hover:underline">Select all</button>
<button type="button" onClick={() => setSuggestSelection(new Set())} className="text-[var(--r-accent)] hover:underline">Select none</button>
<span className="ml-auto text-[var(--r-sub)]">{n} selected</span>
</div>
<ul className="max-h-[40vh] divide-y divide-[var(--r-line)] overflow-y-auto rounded-xl border border-[var(--r-line)] px-3">
{suggestModal.words.map((w) => (
<li key={w.strongKey}>
<label className="flex cursor-pointer items-center gap-3 py-2.5">
<input type="checkbox" checked={suggestSelection.has(w.strongKey)} className="h-4 w-4 shrink-0 accent-[var(--r-accent)]"
onChange={(e) => setSuggestSelection((prev) => { const next = new Set(prev); if (e.target.checked) next.add(w.strongKey); else next.delete(w.strongKey); return next; })} />
<div className="min-w-0 flex-1">
<div className="flex flex-wrap items-baseline gap-2">
<span className="text-sm font-medium">{w.def || w.strongKey}</span>
<span className="text-sm text-[var(--r-sub)]">{w.lexeme}</span>
{w.translit && <span className="text-xs italic text-[var(--r-sub)]">{w.translit}</span>}
<span className="font-mono text-[10px] text-[var(--r-sub)]">{w.strongKey}</span>
</div>
{w.entry && (w.entry.strongs_def || w.entry.kjv_def || w.entry.derivation) && (
<details className="mt-1">
<summary className="cursor-pointer text-xs text-[var(--r-accent)]" onClick={(e) => e.stopPropagation()}>Definition</summary>
<div className="mt-1 text-xs leading-5" dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(buildGreekDefinitionHtml(w.strongKey, w.entry)) }} />
</details>
)}
</div>
</label>
</li>
))}
</ul>
<div className="mt-3 flex gap-2">
<button type="button" onClick={close} className="flex-1 rounded-xl border border-[var(--r-line)] py-2 text-sm hover:bg-black/5">Cancel</button>
<button type="button" onClick={confirmSuggestWords} disabled={n === 0}
className="flex-1 rounded-xl bg-[var(--r-accent)] py-2 text-sm font-medium text-[var(--r-on)] disabled:opacity-40">Add {n > 0 ? `${n} word${n > 1 ? 's' : ''}` : 'words'}</button>
</div>
</Sheet>
);
}