From 7585adef570a1d0efab5f843d6e0e7ca0fa86c0b Mon Sep 17 00:00:00 2001 From: Philipp S Date: Thu, 5 Dec 2024 15:33:56 -0500 Subject: [PATCH] Switch to `React.MouseEvent` and `React.TouchEvent` to ensure cross browser compatibility https://stackoverflow.com/questions/27313488/touchevent-not-working-in-firefox-and-other-website-browser --- .../TooltipWrapper/TooltipWrapper.tsx | 11 ++++++----- .../src/components/TooltipWrapper/types.ts | 2 +- .../TooltipWrapper/utilities/eventPoint.ts | 18 +++++++++++------- .../utilities/shouldBlockTooltipEvents.ts | 6 ++++-- 4 files changed, 22 insertions(+), 15 deletions(-) diff --git a/packages/polaris-viz/src/components/TooltipWrapper/TooltipWrapper.tsx b/packages/polaris-viz/src/components/TooltipWrapper/TooltipWrapper.tsx index 90ca84268..49344719e 100644 --- a/packages/polaris-viz/src/components/TooltipWrapper/TooltipWrapper.tsx +++ b/packages/polaris-viz/src/components/TooltipWrapper/TooltipWrapper.tsx @@ -22,6 +22,7 @@ import {shouldBlockTooltipEvents} from './utilities/shouldBlockTooltipEvents'; import type {TooltipPosition} from './types'; import {DEFAULT_TOOLTIP_POSITION} from './constants'; import {TooltipAnimatedContainer} from './components/TooltipAnimatedContainer'; +import {isTouchEvent} from './utilities/eventPoint'; const TOUCH_START_DELAY = 300; @@ -89,7 +90,7 @@ function TooltipWrapperRaw(props: BaseProps) { index, }: { eventType: 'mouse' | 'focus'; - event?: MouseEvent | TouchEvent; + event?: React.MouseEvent | React.TouchEvent; index?: number; }) => { const scrollY = scrollContainer == null ? 0 : scrollContainer.scrollTop; @@ -148,7 +149,7 @@ function TooltipWrapperRaw(props: BaseProps) { ); const showAndPositionTooltip = useCallback( - (event: MouseEvent | TouchEvent) => { + (event: React.MouseEvent | React.TouchEvent) => { const newPosition = getPosition({event, eventType: 'mouse'}); const scrollContainerTop = Number(scrollContainer?.scrollTop ?? 0); @@ -185,10 +186,10 @@ function TooltipWrapperRaw(props: BaseProps) { ); const onMouseMove = useCallback( - (event: MouseEvent | TouchEvent) => { + (event: React.MouseEvent | React.TouchEvent) => { window.clearTimeout(touchStartTimer.current); - if (event instanceof TouchEvent) { + if (isTouchEvent(event)) { if (isLongTouch.current === true) { // prevents scrolling after long touch (since it is supposed to move the tooltip/datapoint vs scroll) event?.preventDefault(); @@ -212,7 +213,7 @@ function TooltipWrapperRaw(props: BaseProps) { }, [onIndexChange]); const onTouchStart = useCallback( - (event: TouchEvent) => { + (event: React.TouchEvent) => { touchStartTimer.current = window.setTimeout(() => { event.preventDefault(); diff --git a/packages/polaris-viz/src/components/TooltipWrapper/types.ts b/packages/polaris-viz/src/components/TooltipWrapper/types.ts index 96aaee3ca..18b3e1472 100644 --- a/packages/polaris-viz/src/components/TooltipWrapper/types.ts +++ b/packages/polaris-viz/src/components/TooltipWrapper/types.ts @@ -39,7 +39,7 @@ export interface TooltipPositionParams { eventType: 'mouse' | 'focus'; longestSeriesIndex: number; xScale: ScaleBand | ScaleLinear; - event?: MouseEvent | TouchEvent; + event?: React.MouseEvent | React.TouchEvent; index?: number; type?: ChartType; yScale?: ScaleLinear; diff --git a/packages/polaris-viz/src/components/TooltipWrapper/utilities/eventPoint.ts b/packages/polaris-viz/src/components/TooltipWrapper/utilities/eventPoint.ts index 7811d1476..d3289fcf0 100644 --- a/packages/polaris-viz/src/components/TooltipWrapper/utilities/eventPoint.ts +++ b/packages/polaris-viz/src/components/TooltipWrapper/utilities/eventPoint.ts @@ -36,7 +36,7 @@ export function eventPoint( }; } -export function eventPointNative(event: MouseEvent | TouchEvent) { +export function eventPointNative(event: React.MouseEvent | React.TouchEvent) { const svgNode = getSVGNodeFromTarget(event); if (svgNode == null) { @@ -62,7 +62,7 @@ export function eventPointNative(event: MouseEvent | TouchEvent) { svgY: transformedSVGPoint.y, }; - function getSVGNodeFromTarget(event: MouseEvent | TouchEvent) { + function getSVGNodeFromTarget(event: React.MouseEvent | React.TouchEvent) { if (event.currentTarget == null) { return (event.target as SVGElement)?.closest('svg'); } @@ -71,10 +71,12 @@ export function eventPointNative(event: MouseEvent | TouchEvent) { } } -export function getXYFromEventType(event: MouseEvent | TouchEvent): Position { - return event instanceof TouchEvent - ? {x: event.touches[0].pageX, y: event.touches[0].pageY} - : {x: event.pageX, y: event.pageY}; +export function getXYFromEventType( + event: React.MouseEvent | React.TouchEvent, +): Position { + return 'touches' in event + ? {x: event.touches[0].clientX, y: event.touches[0].clientY} + : {x: event.clientX, y: event.clientY}; } export function isMouseEvent( @@ -86,5 +88,7 @@ export function isMouseEvent( export function isTouchEvent( event: React.SyntheticEvent, ): event is React.TouchEvent { - return event.nativeEvent instanceof TouchEvent; + return ( + typeof TouchEvent !== 'undefined' && event.nativeEvent instanceof TouchEvent + ); } diff --git a/packages/polaris-viz/src/components/TooltipWrapper/utilities/shouldBlockTooltipEvents.ts b/packages/polaris-viz/src/components/TooltipWrapper/utilities/shouldBlockTooltipEvents.ts index ac5098304..10b57fbb1 100644 --- a/packages/polaris-viz/src/components/TooltipWrapper/utilities/shouldBlockTooltipEvents.ts +++ b/packages/polaris-viz/src/components/TooltipWrapper/utilities/shouldBlockTooltipEvents.ts @@ -1,5 +1,7 @@ -export function shouldBlockTooltipEvents(event: MouseEvent | TouchEvent) { - return event.composedPath().some((path) => { +export function shouldBlockTooltipEvents( + event: React.MouseEvent | React.TouchEvent, +) { + return event.nativeEvent.composedPath().some((path) => { const dataset = (path as HTMLElement).dataset; return dataset != null && dataset.blockTooltipEvents === 'true'; });