Skip to content
This repository was archived by the owner on Mar 25, 2025. It is now read-only.

Commit 69f9a12

Browse files
riktegTigge
authored andcommitted
fix(tooltip): handle tooltip with touch
For devices using touchscreen, it is not possible to see a tooltip since pointerover and pointerout never fires.
1 parent 211e309 commit 69f9a12

File tree

1 file changed

+29
-11
lines changed

1 file changed

+29
-11
lines changed

packages/core/src/Tooltip/index.tsx

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import {
2+
useCallback,
23
useState,
34
useEffect,
45
useLayoutEffect,
@@ -252,30 +253,47 @@ export const Tooltip: FC<TooltipProps | ExpandedTooltipProps> = ({
252253
const child = Children.only(children) as ReactElement
253254
const [anchorEl, setAnchorEl] = useState<HTMLElement | null>(null)
254255

255-
const [visible, show, hide] = useBoolean(false)
256-
const [debouncedVisible, setDebouncedVisible] = useState(visible)
256+
// State for click
257+
const [visibleByClick, showByClick] = useState(false)
258+
// Delayed state for pointer
259+
const [visibleDelayed, showDelayed, hideDelayed] = useBoolean(false)
260+
// State for pointer
261+
const [debouncedVisible, setDebouncedVisible] = useState(false)
257262
const [layout, setLayout] = useState<Placement>('down')
258263
const [tooltipEl, setTooltipEl] = useState<HTMLDivElement | null>(null)
259264

265+
// If tooltip should be shown
266+
const visible = visibleByClick || debouncedVisible
267+
268+
const toggle = useCallback(() => {
269+
// When using touch instead of mouse, we have to toggle the tooltip
270+
// on "click" instead of "pointerover" and "pointerout"
271+
showByClick(v => !v)
272+
}, [showByClick])
273+
260274
useEffect(() => {
261-
const delayVisible = () => setDebouncedVisible(visible)
275+
const delayVisible = () => setDebouncedVisible(visibleDelayed)
262276
const delayed = setTimeout(delayVisible, TOOLTIP_DELAY_MS)
263277
return () => {
264278
clearTimeout(delayed)
265279
}
266-
}, [visible])
280+
}, [visibleDelayed])
267281

268282
useLayoutEffect(() => {
269283
if (anchorEl === null) {
270284
return
271285
}
272-
anchorEl.addEventListener('pointerover', show)
273-
anchorEl.addEventListener('pointerout', hide)
286+
// Events when using a pointer
287+
anchorEl.addEventListener('pointerover', showDelayed)
288+
anchorEl.addEventListener('pointerout', hideDelayed)
289+
// Event when using touch
290+
anchorEl.addEventListener('click', toggle)
274291
return () => {
275-
anchorEl.removeEventListener('pointerover', show)
276-
anchorEl.removeEventListener('pointerout', hide)
292+
anchorEl.removeEventListener('pointerover', showDelayed)
293+
anchorEl.removeEventListener('pointerout', hideDelayed)
294+
anchorEl.removeEventListener('click', toggle)
277295
}
278-
}, [anchorEl, hide, show])
296+
}, [anchorEl, hideDelayed, showDelayed, toggle])
279297

280298
useLayoutEffect(() => {
281299
if (tooltipEl === null || anchorEl === null) {
@@ -334,7 +352,7 @@ export const Tooltip: FC<TooltipProps | ExpandedTooltipProps> = ({
334352
{cloneElement(child, {
335353
ref: setAnchorEl,
336354
})}
337-
{debouncedVisible ? (
355+
{visible ? (
338356
<PopOver anchorEl={anchorEl} {...alignments[layout]} {...props}>
339357
<TooltipWrapper ref={setTooltipEl}>
340358
<Typography variant="chip-tag-text">{props.text}</Typography>
@@ -352,7 +370,7 @@ export const Tooltip: FC<TooltipProps | ExpandedTooltipProps> = ({
352370
{cloneElement(child, {
353371
ref: setAnchorEl,
354372
})}
355-
{debouncedVisible ? (
373+
{visible ? (
356374
<>
357375
<PopOver anchorEl={anchorEl} {...alignments[layout]} {...props}>
358376
<ExpandedTooltipWrapper ref={setTooltipEl}>

0 commit comments

Comments
 (0)