Skip to content

Commit

Permalink
Merge pull request #1932 from Shoaibdev7/Make-tool-tip-scrollable
Browse files Browse the repository at this point in the history
Fixed(Graph-Tooltip): Make the Tooltip scrollable and improve the UX
  • Loading branch information
Rassl authored Aug 8, 2024
2 parents e2e801e + 039cdc5 commit abaa174
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,11 @@ import { formatDescription } from '~/utils/formatDescription'
import { TwitData } from './Tweet'

const Wrapper = styled(Flex)(({ theme }) => ({
position: 'absolute',
top: '65px',
right: '55px',
width: '300px',
pointerEvents: 'auto',
background: colors.dashboardHeader,
boxShadow: '0px 1px 6px rgba(0, 0, 0, 0.1)',
color: colors.primaryText1,
zIndex: 100,
maxHeight: '400px',
overflowY: 'auto',
transition: 'opacity 0.6s',
Expand Down
10 changes: 6 additions & 4 deletions src/components/Universe/Graph/Cubes/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ const POINTER_IN_DELAY = 200
export const Cubes = memo(() => {
const selectedNode = useSelectedNode()
const relativeIds = useSelectedNodeRelativeIds()
const { selectionGraphData, showSelectionGraph, setHoveredNode } = useGraphStore((s) => s)
const { selectionGraphData, showSelectionGraph, setHoveredNode, setIsHovering } = useGraphStore((s) => s)

const data = useDataStore((s) => s.dataInitial)
const setTranscriptOpen = useAppStore((s) => s.setTranscriptOpen)
Expand Down Expand Up @@ -56,6 +56,7 @@ export const Cubes = memo(() => {
const onPointerOut = useCallback(
(e: ThreeEvent<PointerEvent>) => {
e.stopPropagation()
setIsHovering(false)

if (hoverTimeoutRef.current) {
clearTimeout(hoverTimeoutRef.current)
Expand All @@ -64,7 +65,7 @@ export const Cubes = memo(() => {

setHoveredNode(null)
},
[setHoveredNode],
[setHoveredNode, setIsHovering],
)

const onPointerIn = useCallback(
Expand All @@ -77,14 +78,15 @@ export const Cubes = memo(() => {

if (!ignoreNodeEvent(node)) {
e.stopPropagation()
setIsHovering(true)

hoverTimeoutRef.current = setTimeout(() => {
setHoveredNode(node)
}, POINTER_IN_DELAY)
}
}
},
[setHoveredNode, ignoreNodeEvent],
[setHoveredNode, ignoreNodeEvent, setIsHovering],
)

const hideUniverse = showSelectionGraph && !!selectedNode
Expand Down Expand Up @@ -119,4 +121,4 @@ export const Cubes = memo(() => {
)
})

Cubes.displayName = 'Cubes'
Cubes.displayName = 'Cubes'
42 changes: 38 additions & 4 deletions src/components/Universe/Overlay/index.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,44 @@
import { useCallback, useEffect, useState } from 'react'
import styled from 'styled-components'
import { ActionsToolbar } from '~/components/App/ActionsToolbar'
import { useGraphStore } from '~/stores/useGraphStore'
import { Tooltip } from '../Graph/Cubes/Cube/components/Tooltip'

export const Overlay = () => {
const [hoveredNode] = useGraphStore((s) => [s.hoveredNode])
const [hoveredNode, isHovering] = useGraphStore((s) => [s.hoveredNode, s.isHovering])
const [isVisible, setIsVisible] = useState(false)
const [isTooltipHovered, setIsTooltipHovered] = useState(false)

useEffect(() => {
let timer: NodeJS.Timeout | null = null

if (isHovering || isTooltipHovered) {
setIsVisible(true)
} else {
timer = setTimeout(() => setIsVisible(false), 300)
}

return () => {
if (timer) {
clearTimeout(timer)
}
}
}, [isHovering, isTooltipHovered])

const handleTooltipMouseEnter = useCallback(() => {
setIsTooltipHovered(true)
}, [])

const handleTooltipMouseLeave = useCallback(() => {
setIsTooltipHovered(false)
}, [])

return (
<OverlayWrap>
{hoveredNode && (
<div id="tooltip-portal">
{hoveredNode && isVisible && (
<TooltipWrapper onMouseEnter={handleTooltipMouseEnter} onMouseLeave={handleTooltipMouseLeave}>
<Tooltip node={hoveredNode} />
</div>
</TooltipWrapper>
)}
<ActionsToolbar />
</OverlayWrap>
Expand All @@ -37,3 +64,10 @@ const OverlayWrap = styled('div')(({ theme }) => ({
top: 50,
},
}))

const TooltipWrapper = styled.div`
position: absolute;
top: 65px;
right: 55px;
z-index: 100;
`
5 changes: 5 additions & 0 deletions src/stores/useGraphStore/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ export type GraphStore = {
scrollEventsDisabled: boolean
simulation: ForceSimulation | null
simulationHelpers: SimulationHelpers
isHovering: boolean

setDisableCameraRotation: (rotation: boolean) => void
setScrollEventsDisabled: (rotation: boolean) => void
Expand All @@ -92,6 +93,7 @@ export type GraphStore = {
setShowSelectionGraph: (_: boolean) => void
setSelectionData: (data: GraphData) => void
simulationCreate: (nodes: Node[], links: Link[]) => void
setIsHovering: (isHovering: boolean) => void
}

const defaultData: Omit<
Expand All @@ -110,6 +112,7 @@ const defaultData: Omit<
| 'setSelectionData'
| 'setHideNodeDetails'
| 'simulationCreate'
| 'setIsHovering'
> = {
data: null,
simulation: null,
Expand All @@ -124,6 +127,7 @@ const defaultData: Omit<
nearbyNodeIds: [],
showSelectionGraph: false,
simulationHelpers: defaultSimulationHelpers,
isHovering: false,
}

export const useGraphStore = create<GraphStore>()((set, get) => ({
Expand All @@ -134,6 +138,7 @@ export const useGraphStore = create<GraphStore>()((set, get) => ({
setSelectionData: (selectionGraphData) => set({ selectionGraphData }),
setScrollEventsDisabled: (scrollEventsDisabled) => set({ scrollEventsDisabled }),
setDisableCameraRotation: (rotation) => set({ disableCameraRotation: rotation }),
setIsHovering: (isHovering) => set({ isHovering }),
setGraphRadius: (graphRadius) => set({ graphRadius }),
setGraphStyle: (graphStyle) => set({ graphStyle }),
setHoveredNode: (hoveredNode) => {
Expand Down

0 comments on commit abaa174

Please sign in to comment.