Fix suggest modal: portal to body + English word first
- Render modal via createPortal(…, document.body) so it's never clipped or offset by parent overflow/transform CSS — appears as a true centered overlay regardless of page scroll position - Reorder word rows: English definition leads (bold), then Greek lexeme, transliteration, and Strong's number — makes it easy to recognise words without reading the Greek Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
+14
-10
@@ -1,4 +1,5 @@
|
|||||||
import { useEffect, useRef, useState } from 'react';
|
import { useEffect, useRef, useState } from 'react';
|
||||||
|
import { createPortal } from 'react-dom';
|
||||||
import {
|
import {
|
||||||
Document,
|
Document,
|
||||||
HeadingLevel,
|
HeadingLevel,
|
||||||
@@ -2111,8 +2112,8 @@ const restoreRemoteProject = async (id) => {
|
|||||||
</section>
|
</section>
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
{/* Greek word picker modal */}
|
{/* Greek word picker modal — portalled to document.body so it's never clipped by parent CSS */}
|
||||||
{suggestModal && (
|
{suggestModal && createPortal(
|
||||||
<div
|
<div
|
||||||
className="fixed inset-0 z-50 flex items-center justify-center bg-black/40 p-4"
|
className="fixed inset-0 z-50 flex items-center justify-center bg-black/40 p-4"
|
||||||
onClick={(e) => { if (e.target === e.currentTarget) { setSuggestModal(null); setSuggestSelection(new Set()); } }}
|
onClick={(e) => { if (e.target === e.currentTarget) { setSuggestModal(null); setSuggestSelection(new Set()); } }}
|
||||||
@@ -2143,7 +2144,7 @@ const restoreRemoteProject = async (id) => {
|
|||||||
<ul className="flex-1 overflow-y-auto divide-y divide-slate-100 px-4 py-2">
|
<ul className="flex-1 overflow-y-auto divide-y divide-slate-100 px-4 py-2">
|
||||||
{suggestModal.words.map((w) => (
|
{suggestModal.words.map((w) => (
|
||||||
<li key={w.strongKey}>
|
<li key={w.strongKey}>
|
||||||
<label className="flex cursor-pointer items-start gap-3 py-2.5">
|
<label className="flex cursor-pointer items-center gap-3 py-2.5">
|
||||||
<input
|
<input
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
checked={suggestSelection.has(w.strongKey)}
|
checked={suggestSelection.has(w.strongKey)}
|
||||||
@@ -2154,13 +2155,15 @@ const restoreRemoteProject = async (id) => {
|
|||||||
return next;
|
return next;
|
||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
className="mt-0.5 h-4 w-4 rounded border-slate-300 accent-slate-900"
|
className="h-4 w-4 shrink-0 rounded border-slate-300 accent-slate-900"
|
||||||
/>
|
/>
|
||||||
<div className="min-w-0">
|
<div className="min-w-0 flex-1">
|
||||||
<span className="font-medium text-slate-900">{w.lexeme || w.strongKey}</span>
|
<div className="flex items-baseline gap-2">
|
||||||
{w.translit && <span className="ml-1.5 text-xs text-slate-400 italic">{w.translit}</span>}
|
<span className="font-semibold text-slate-900">{w.def || w.strongKey}</span>
|
||||||
<span className="ml-1.5 text-xs font-mono text-slate-400">{w.strongKey}</span>
|
<span className="text-sm text-slate-500">{w.lexeme}</span>
|
||||||
<p className="text-xs text-slate-500 mt-0.5 truncate">{w.def}</p>
|
{w.translit && <span className="text-xs text-slate-400 italic">{w.translit}</span>}
|
||||||
|
<span className="text-xs font-mono text-slate-300">{w.strongKey}</span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</label>
|
</label>
|
||||||
</li>
|
</li>
|
||||||
@@ -2178,7 +2181,8 @@ const restoreRemoteProject = async (id) => {
|
|||||||
>Add {suggestSelection.size > 0 ? `${suggestSelection.size} word${suggestSelection.size > 1 ? 's' : ''}` : 'words'}</button>
|
>Add {suggestSelection.size > 0 ? `${suggestSelection.size} word${suggestSelection.size > 1 ? 's' : ''}` : 'words'}</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>,
|
||||||
|
document.body
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user