Skip to content

Commit

Permalink
fix(tooltip): hide tooltip when touched outside of a component
Browse files Browse the repository at this point in the history
Fixes: #276
  • Loading branch information
HitomiWin committed Sep 25, 2023
1 parent 2f0de3f commit 8b3b641
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 37 deletions.
16 changes: 12 additions & 4 deletions packages/core/src/Tooltip/__snapshots__/index.test.tsx.snap
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,9 @@ exports[`Tooltip Default 1`] = `
className="c1"
id="layer-1"
>
<span>
<span
onPointerDown={[Function]}
>
Test
</span>
</div>
Expand Down Expand Up @@ -84,7 +86,9 @@ exports[`Tooltip Expanded 1`] = `
className="c1"
id="layer-3"
>
<span>
<span
onPointerDown={[Function]}
>
Test
</span>
</div>
Expand Down Expand Up @@ -135,7 +139,9 @@ exports[`Tooltip Expanded 2`] = `
className="c1"
id="layer-5"
>
<span>
<span
onPointerDown={[Function]}
>
Test
</span>
</div>
Expand Down Expand Up @@ -186,7 +192,9 @@ exports[`Tooltip Expanded 3`] = `
className="c1"
id="layer-7"
>
<span>
<span
onPointerDown={[Function]}
>
Test
</span>
</div>
Expand Down
28 changes: 8 additions & 20 deletions packages/core/src/Tooltip/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,12 @@ import {
FC,
} from 'react'
import styled, { css } from 'styled-components'
import { useBoolean } from 'react-hooks-shareable'
import { useBoolean, useClickOutside } from 'react-hooks-shareable'

import { Typography, TypographyProps } from '../Typography'
import { PopOver, PopOverProps } from '../PopOver'
import { shape, spacing, componentSize } from '../designparams'
import { font } from '../theme'
import { useTouchScrollDistance } from './utils'

/**
* Tooltip
Expand Down Expand Up @@ -254,7 +253,8 @@ export const Tooltip: FC<TooltipProps | ExpandedTooltipProps> = ({
const child = Children.only(children) as ReactElement
const [anchorEl, setAnchorEl] = useState<HTMLElement | null>(null)
// State for click
const [visibleByClick, showByClick] = useState(false)
const [visibleByClick, _showByClick, hideByClick, toggleByClick] =
useBoolean(false)
// Delayed state for pointer
const [visibleDelayed, showDelayed, hideDelayed] = useBoolean(false)
// State for pointer
Expand All @@ -265,8 +265,6 @@ export const Tooltip: FC<TooltipProps | ExpandedTooltipProps> = ({
// If tooltip should be shown
const visible = visibleByClick || debouncedVisible

const touchScrollDistance = useTouchScrollDistance()

const toggle = useCallback(
(event: PointerEvent) => {
// When using touch instead of mouse, we have to toggle the tooltip
Expand All @@ -275,24 +273,12 @@ export const Tooltip: FC<TooltipProps | ExpandedTooltipProps> = ({
return
}

showByClick(v => !v)
toggleByClick()
},
[showByClick]
[toggleByClick]
)

/**
* If the delta for any axis is larger than 150 pixels,
* remove the tooltip from the screen.
*/
useLayoutEffect(() => {
if (!visible) {
return
}
const { x, y } = touchScrollDistance
if (Math.max(Math.abs(x), Math.abs(y)) > 150) {
showByClick(false)
}
}, [touchScrollDistance])
const handlePointerDown = useClickOutside(hideByClick)

useEffect(() => {
const delayVisible = () => setDebouncedVisible(visibleDelayed)
Expand Down Expand Up @@ -374,6 +360,7 @@ export const Tooltip: FC<TooltipProps | ExpandedTooltipProps> = ({
<>
{cloneElement(child, {
ref: setAnchorEl,
onPointerDown: handlePointerDown,
})}
{visible ? (
<PopOver anchorEl={anchorEl} {...alignments[layout]} {...props}>
Expand All @@ -392,6 +379,7 @@ export const Tooltip: FC<TooltipProps | ExpandedTooltipProps> = ({
<>
{cloneElement(child, {
ref: setAnchorEl,
onPointerDown: handlePointerDown,
})}
{visible ? (
<>
Expand Down
16 changes: 3 additions & 13 deletions packages/ui-tests/src/coreComponents/Tooltip.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,25 +85,15 @@ context('Tooltip mobile device', () => {
cy.get(`[data-cy=${data.tooltipDataCy}]`).should('not.exist')
})

it(`Tooltip ${data.tooltipDataCy} should hide when client touch move more than 150 pixels`, () => {
it(`Tooltip ${data.tooltipDataCy} should hide when client touch the screen again`, () => {
// Touch to show tooltip
cy.get(`[data-cy=${data.textDataCy}]`).trigger('pointerdown')
cy.get(`[data-cy=${data.tooltipDataCy}]`)
.should('exist')
.should('be.visible')

// Touch move 151 pixels and hide tooltip
cy.get(`[data-cy=${data.textDataCy}]`)
.parent()
.trigger('touchstart', {
touches: [{ clientX: 0, clientY: 0, identifier: 0 }],
})

cy.get(`[data-cy=${data.textDataCy}]`)
.parent()
.trigger('touchmove', {
changedTouches: [{ clientX: 151, clientY: 151, identifier: 0 }],
})
// Touch the swcreen again
cy.get(`[data-cy=${data.textDataCy}]`).parent().trigger('pointerdown')

// Tooltip is not shown
cy.get(`[data-cy=${data.tooltipDataCy}]`).should('not.exist')
Expand Down

0 comments on commit 8b3b641

Please sign in to comment.