From fb4c045a46670c07ef4b510a32ce5a885cc300ca Mon Sep 17 00:00:00 2001 From: Muhammad Ahmad Date: Tue, 5 Nov 2024 18:12:53 +0500 Subject: [PATCH] fix: ensure Ask OpenCanvas input only shows within code/markdown renderer --- src/components/artifacts/ArtifactRenderer.tsx | 62 +++++++++++++------ 1 file changed, 42 insertions(+), 20 deletions(-) diff --git a/src/components/artifacts/ArtifactRenderer.tsx b/src/components/artifacts/ArtifactRenderer.tsx index 5d4e5e87..7430c0d2 100644 --- a/src/components/artifacts/ArtifactRenderer.tsx +++ b/src/components/artifacts/ArtifactRenderer.tsx @@ -144,6 +144,7 @@ function ArtifactRendererComponent(props: ArtifactRendererProps) { const [isSelectionActive, setIsSelectionActive] = useState(false); const [inputValue, setInputValue] = useState(""); const [isHoveringOverArtifact, setIsHoveringOverArtifact] = useState(false); + const [isValidSelectionOrigin, setIsValidSelectionOrigin] = useState(false); const handleMouseUp = useCallback(() => { const selection = window.getSelection(); @@ -151,27 +152,47 @@ function ArtifactRendererComponent(props: ArtifactRendererProps) { const range = selection.getRangeAt(0); const selectedText = range.toString().trim(); - if (selectedText) { - const rects = range.getClientRects(); - const firstRect = rects[0]; - const lastRect = rects[rects.length - 1]; - const contentRect = contentRef.current.getBoundingClientRect(); - - const boxWidth = 400; // Approximate width of the selection box - let left = lastRect.right - contentRect.left - boxWidth; + // Check if the selection originated from within the artifact content + if (selectedText && artifactContentRef.current) { + const isWithinArtifact = (node: Node | null): boolean => { + if (!node) return false; + if (node === artifactContentRef.current) return true; + return isWithinArtifact(node.parentNode); + }; + + // Check both start and end containers + const startInArtifact = isWithinArtifact(range.startContainer); + const endInArtifact = isWithinArtifact(range.endContainer); + + if (startInArtifact && endInArtifact) { + setIsValidSelectionOrigin(true); + const rects = range.getClientRects(); + const firstRect = rects[0]; + const lastRect = rects[rects.length - 1]; + const contentRect = contentRef.current.getBoundingClientRect(); + + const boxWidth = 400; // Approximate width of the selection box + let left = lastRect.right - contentRect.left - boxWidth; + + if (left < 0) { + left = Math.min(0, firstRect.left - contentRect.left); + } + // Ensure the box doesn't go beyond the left edge + if (left < 0) { + left = Math.min(0, firstRect.left - contentRect.left); + } - // Ensure the box doesn't go beyond the left edge - if (left < 0) { - left = Math.min(0, firstRect.left - contentRect.left); + setSelectionBox({ + top: lastRect.bottom - contentRect.top, + left: left, + text: selectedText, + }); + setIsInputVisible(false); + setIsSelectionActive(true); + } else { + setIsValidSelectionOrigin(false); + handleCleanupState(); } - - setSelectionBox({ - top: lastRect.bottom - contentRect.top, - left: left, - text: selectedText, - }); - setIsInputVisible(false); - setIsSelectionActive(true); } } }, []); @@ -181,6 +202,7 @@ function ArtifactRendererComponent(props: ArtifactRendererProps) { setSelectionBox(undefined); setSelectionIndexes(undefined); setIsSelectionActive(false); + setIsValidSelectionOrigin(false); setInputValue(""); }; @@ -395,7 +417,7 @@ function ArtifactRendererComponent(props: ArtifactRendererProps) { className="absolute top-0 left-0 w-full h-full pointer-events-none" /> - {selectionBox && isSelectionActive && ( + {selectionBox && isSelectionActive && isValidSelectionOrigin && (