diff --git a/src/components/App/SideBar/AiSummary/AiAnswer/index.tsx b/src/components/App/SideBar/AiSummary/AiAnswer/index.tsx index 27f117d93..39f52be5b 100644 --- a/src/components/App/SideBar/AiSummary/AiAnswer/index.tsx +++ b/src/components/App/SideBar/AiSummary/AiAnswer/index.tsx @@ -32,7 +32,8 @@ export const AiAnswer = ({ answer, entities, handleLoaded, hasBeenRendered }: Pr const { setBudget } = useUserStore((s) => s) const [displayedText, setDisplayedText] = useState('') const [highlightedEntities, setHighlightedEntities] = useState(entities) - const [isDescriptionComplete, setIsDescriptionComplete] = useState(false) + const [mousePosition, setMousePosition] = useState(0) + const [isDescriptionComplete, setIsDescriptionComplete] = useState(true) useEffect(() => { let timeoutId: NodeJS.Timeout @@ -50,8 +51,8 @@ export const AiAnswer = ({ answer, entities, handleLoaded, hasBeenRendered }: Pr return () => clearTimeout(timeoutId) } - handleLoaded() setIsDescriptionComplete(true) + handleLoaded() }, [answer, displayedText, handleLoaded, hasBeenRendered]) useEffect(() => { @@ -74,15 +75,21 @@ export const AiAnswer = ({ answer, entities, handleLoaded, hasBeenRendered }: Pr } }, [entities, highlightedEntities]) + const handleMouseMove = (event: React.MouseEvent) => { + setIsDescriptionComplete(false) + setMousePosition(event.clientX) + } + const responseTextDisplay = highlightAiSummary( displayedText, handleSubmit, + mousePosition, highlightedEntities, isDescriptionComplete, ) return ( - + {responseTextDisplay} ) diff --git a/src/components/App/SideBar/AiSummary/utils/AiSummaryHighlight/index.tsx b/src/components/App/SideBar/AiSummary/utils/AiSummaryHighlight/index.tsx index 23a609dda..cbb8d82f2 100644 --- a/src/components/App/SideBar/AiSummary/utils/AiSummaryHighlight/index.tsx +++ b/src/components/App/SideBar/AiSummary/utils/AiSummaryHighlight/index.tsx @@ -1,7 +1,7 @@ -import styled, { css, keyframes } from 'styled-components' -import { Tooltip } from '~/components/common/ToolTip' -import { ExtractedEntity } from '~/types' +import styled, { keyframes } from 'styled-components' import { colors } from '~/utils' +import { ExtractedEntity } from '~/types' +import { Tooltip } from '~/components/common/ToolTip' // Define a keyframe animation for highlighting from top-left to bottom-right const highlightAnimation = keyframes` @@ -17,27 +17,25 @@ const highlightAnimation = keyframes` } ` -const Highlight = styled.span<{ isDescriptionComplete?: boolean }>` +const Highlight = styled.span<{ animate: boolean }>` padding: 0; margin: 0; color: ${colors.SECONDARY_BLUE}; background-color: transparent; - animation: ${(props) => - props.isDescriptionComplete - ? css` - ${highlightAnimation} 0.5s ease-in-out forwards - ` - : 'none'}; + animation: ${({ animate }) => (animate ? highlightAnimation : 'none')} 0.5s ease-in-out forwards; + animation-play-state: ${({ animate }) => (animate ? 'running' : 'paused')}; &:hover { text-decoration: underline; cursor: pointer; + animation: none; } ` export function highlightAiSummary( sDescription: string, handleSubmit: (search: string) => void, + mousePosition: number, entities?: ExtractedEntity[], isDescriptionComplete?: boolean, ) { @@ -55,17 +53,27 @@ export function highlightAiSummary( const parts = sDescription.split(regex) + let positionLeft: string + + if (mousePosition <= 180) { + positionLeft = '145%' + } else if (mousePosition >= 250) { + positionLeft = '10%' + } else { + positionLeft = '50%' + } + return ( <> - {parts.map((part) => { + {parts.map((part, index) => { const entity = entities.find((e) => e.entity.toLowerCase() === part.toLowerCase()) if (entity) { - const uniqueKey = `${entity.entity}-${entities.indexOf(entity)}` + const uniqueKey = `${entity.entity}-${index}` return ( - - handleSubmit(part)}> + + handleSubmit(part)}> {part} @@ -82,7 +90,7 @@ function escapeRegExp(string: string) { return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&') } -const StyledTooltip = styled(({ className, ...props }) => ( +const StyledTooltip = styled(({ className, positionLeft, ...props }) => ( ( fontSize="12px" fontWeight="500" minWidth="160px" + mrLeft={positionLeft} padding="10px" textAlign="start" whiteSpace="normal" diff --git a/src/components/common/ToolTip/index.tsx b/src/components/common/ToolTip/index.tsx index 6510de760..5829fe448 100644 --- a/src/components/common/ToolTip/index.tsx +++ b/src/components/common/ToolTip/index.tsx @@ -14,6 +14,7 @@ interface TooltipProps { minWidth?: string whiteSpace?: string textAlign?: string + mrLeft?: string } const TooltipContainer = styled.div` @@ -34,6 +35,7 @@ const TooltipText = styled.div<{ minWidth?: string whiteSpace?: string textAlign?: string + mrLeft?: string }>` visibility: hidden; width: auto; @@ -46,7 +48,7 @@ const TooltipText = styled.div<{ position: absolute; z-index: 1; ${({ position }) => (position === 'top' ? 'bottom: 100%;' : 'top: 100%;')} - left: 50%; + left: ${({ mrLeft }) => mrLeft || '50%'}; transform: translateX(-50%); margin-top: ${({ margin }) => margin || '0px'}; opacity: 0; @@ -77,6 +79,7 @@ export const Tooltip = ({ whiteSpace, position, textAlign, + mrLeft, }: TooltipProps) => ( {children} @@ -88,6 +91,7 @@ export const Tooltip = ({ fontWeight={fontWeight} margin={margin} minWidth={minWidth} + mrLeft={mrLeft} padding={padding} position={position} textAlign={textAlign}