diff --git a/packages/ui/src/components/message-timeline.tsx b/packages/ui/src/components/message-timeline.tsx index 7faaca97..c0e1d9d7 100644 --- a/packages/ui/src/components/message-timeline.tsx +++ b/packages/ui/src/components/message-timeline.tsx @@ -276,6 +276,7 @@ const MessageTimeline: Component = (props) => { const [tooltipSize, setTooltipSize] = createSignal<{ width: number; height: number }>({ width: 360, height: 420 }) const [tooltipElement, setTooltipElement] = createSignal(null) let hoverTimer: number | null = null + let closeTimer: number | null = null const showTools = () => props.showToolSegments ?? true const registerButtonRef = (segmentId: string, element: HTMLButtonElement | null) => { @@ -292,10 +293,30 @@ const MessageTimeline: Component = (props) => { hoverTimer = null } } + + const clearCloseTimer = () => { + if (closeTimer !== null && typeof window !== "undefined") { + window.clearTimeout(closeTimer) + closeTimer = null + } + } + + const scheduleClose = () => { + if (typeof window === "undefined") return + clearHoverTimer() + clearCloseTimer() + // Small delay so the pointer can travel from the segment to the tooltip. + closeTimer = window.setTimeout(() => { + closeTimer = null + setHoveredSegment(null) + setHoverAnchorRect(null) + }, 160) + } const handleMouseEnter = (segment: TimelineSegment, event: MouseEvent) => { if (typeof window === "undefined") return clearHoverTimer() + clearCloseTimer() const target = event.currentTarget as HTMLButtonElement hoverTimer = window.setTimeout(() => { const rect = target.getBoundingClientRect() @@ -305,9 +326,7 @@ const MessageTimeline: Component = (props) => { } const handleMouseLeave = () => { - clearHoverTimer() - setHoveredSegment(null) - setHoverAnchorRect(null) + scheduleClose() } createEffect(() => { @@ -326,7 +345,10 @@ const MessageTimeline: Component = (props) => { setTooltipCoords({ top: clampedTop, left: clampedLeft }) }) - onCleanup(() => clearHoverTimer()) + onCleanup(() => { + clearHoverTimer() + clearCloseTimer() + }) createEffect(() => { const activeId = props.activeMessageId @@ -432,6 +454,8 @@ const MessageTimeline: Component = (props) => { ref={(element) => setTooltipElement(element)} class="message-timeline-tooltip" style={{ top: `${tooltipCoords().top}px`, left: `${tooltipCoords().left}px` }} + onMouseEnter={() => clearCloseTimer()} + onMouseLeave={() => scheduleClose()} >