This commit is contained in:
Anthony Stirling 2025-11-10 18:18:21 +00:00
parent 559ba3ccab
commit 5fadb92f51

View File

@ -756,6 +756,7 @@ const PdfJsonEditorView = ({ data }: PdfJsonEditorViewProps) => {
isChanged: boolean, isChanged: boolean,
content: React.ReactNode, content: React.ReactNode,
onActivate?: (event: React.MouseEvent) => void, onActivate?: (event: React.MouseEvent) => void,
onClick?: (event: React.MouseEvent) => void,
) => ( ) => (
<Box <Box
component="div" component="div"
@ -783,17 +784,15 @@ const PdfJsonEditorView = ({ data }: PdfJsonEditorViewProps) => {
}} }}
onClick={(event) => { onClick={(event) => {
event.stopPropagation(); event.stopPropagation();
onActivate?.(event); if (onClick) {
}} onClick(event);
onMouseEnter={() => setActiveGroupId(groupId)} } else {
onMouseLeave={() => { onActivate?.(event);
if (editingGroupId !== groupId) {
setActiveGroupId((current) => (current === groupId ? null : current));
} }
}} }}
> >
{content} {content}
{isActive && editingGroupId !== groupId && ( {activeGroupId === groupId && editingGroupId !== groupId && (
<ActionIcon <ActionIcon
size="xs" size="xs"
variant="filled" variant="filled"
@ -1502,52 +1501,59 @@ const PdfJsonEditorView = ({ data }: PdfJsonEditorViewProps) => {
{group.text || '\u00A0'} {group.text || '\u00A0'}
</span> </span>
</div>, </div>,
undefined,
(event: React.MouseEvent) => { (event: React.MouseEvent) => {
// Capture click position BEFORE switching to edit mode // Double-click to edit
const clickX = event.clientX; if (event.detail === 2) {
const clickY = event.clientY; // Capture click position BEFORE switching to edit mode
const clickX = event.clientX;
const clickY = event.clientY;
setEditingGroupId(group.id); setEditingGroupId(group.id);
setActiveGroupId(group.id); setActiveGroupId(group.id);
// Clear any stored offset to prevent interference // Clear any stored offset to prevent interference
caretOffsetsRef.current.delete(group.id); caretOffsetsRef.current.delete(group.id);
// Wait for editor to render, then position cursor at click location // Wait for editor to render, then position cursor at click location
requestAnimationFrame(() => { requestAnimationFrame(() => {
const editor = document.querySelector<HTMLElement>(`[data-editor-group="${group.id}"]`); const editor = document.querySelector<HTMLElement>(`[data-editor-group="${group.id}"]`);
if (!editor) return; if (!editor) return;
// Focus the editor first // Focus the editor first
editor.focus(); editor.focus();
// Use caretRangeFromPoint to position cursor at click coordinates // Use caretRangeFromPoint to position cursor at click coordinates
setTimeout(() => { setTimeout(() => {
if (document.caretRangeFromPoint) { if (document.caretRangeFromPoint) {
const range = document.caretRangeFromPoint(clickX, clickY); const range = document.caretRangeFromPoint(clickX, clickY);
if (range) { if (range) {
const selection = window.getSelection(); const selection = window.getSelection();
if (selection) { if (selection) {
selection.removeAllRanges(); selection.removeAllRanges();
selection.addRange(range); selection.addRange(range);
}
}
} else if ((document as any).caretPositionFromPoint) {
// Firefox fallback
const pos = (document as any).caretPositionFromPoint(clickX, clickY);
if (pos) {
const range = document.createRange();
range.setStart(pos.offsetNode, pos.offset);
range.collapse(true);
const selection = window.getSelection();
if (selection) {
selection.removeAllRanges();
selection.addRange(range);
}
} }
} }
} else if ((document as any).caretPositionFromPoint) { }, 10);
// Firefox fallback });
const pos = (document as any).caretPositionFromPoint(clickX, clickY); } else {
if (pos) { // Single click just selects
const range = document.createRange(); setActiveGroupId(group.id);
range.setStart(pos.offsetNode, pos.offset); }
range.collapse(true);
const selection = window.getSelection();
if (selection) {
selection.removeAllRanges();
selection.addRange(range);
}
}
}
}, 10);
});
}, },
)} )}
</Box> </Box>