diff --git a/packages/@react-aria/tooltip/src/useTooltip.ts b/packages/@react-aria/tooltip/src/useTooltip.ts index a900c741503..460e7bc0267 100644 --- a/packages/@react-aria/tooltip/src/useTooltip.ts +++ b/packages/@react-aria/tooltip/src/useTooltip.ts @@ -14,7 +14,7 @@ import {AriaTooltipProps} from '@react-types/tooltip'; import {DOMAttributes} from '@react-types/shared'; import {filterDOMProps, mergeProps} from '@react-aria/utils'; import {TooltipTriggerState} from '@react-stately/tooltip'; -import {useHover} from '@react-aria/interactions'; +import {useHover, usePress} from '@react-aria/interactions'; export interface TooltipAria { /** @@ -28,6 +28,7 @@ export interface TooltipAria { */ export function useTooltip(props: AriaTooltipProps, state?: TooltipTriggerState): TooltipAria { let domProps = filterDOMProps(props, {labelable: true}); + let {pressProps} = usePress({}); let {hoverProps} = useHover({ onHoverStart: () => state?.open(true), @@ -35,7 +36,7 @@ export function useTooltip(props: AriaTooltipProps, state?: TooltipTriggerState) }); return { - tooltipProps: mergeProps(domProps, hoverProps, { + tooltipProps: mergeProps(domProps, hoverProps, pressProps, { role: 'tooltip' }) }; diff --git a/packages/@react-spectrum/tooltip/stories/TooltipTrigger.stories.tsx b/packages/@react-spectrum/tooltip/stories/TooltipTrigger.stories.tsx index a4c64854058..5991af85baa 100644 --- a/packages/@react-spectrum/tooltip/stories/TooltipTrigger.stories.tsx +++ b/packages/@react-spectrum/tooltip/stories/TooltipTrigger.stories.tsx @@ -17,7 +17,7 @@ import Delete from '@spectrum-icons/workflow/Delete'; import Edit from '@spectrum-icons/workflow/Edit'; import {Flex} from '@react-spectrum/layout'; import {Link} from '@react-spectrum/link'; -import React, {useState} from 'react'; +import React, {CSSProperties, useState} from 'react'; import SaveTo from '@spectrum-icons/workflow/SaveTo'; import {SpectrumTooltipTriggerProps} from '@react-types/tooltip'; import {Tooltip, TooltipTrigger} from '../src'; @@ -176,6 +176,25 @@ export const TooltripTriggerInsideActionGroup: TooltipTriggerStory = { ) }; +const TooltipDivRender = (props) => { + const [isDisabled, setIsDisabled] = useState(false); + const wrapperStyle: CSSProperties = {width: '400px', height: '400px', backgroundColor: 'red', position: 'absolute'}; + return ( + // eslint-disable-next-line jsx-a11y/click-events-have-key-events,jsx-a11y/no-static-element-interactions +
setIsDisabled(!isDisabled)} style={wrapperStyle}> + + click red to disable + Click on tooltip doesn't propagate to parent + +
+ ); +}; +export const TooltripTriggerInsideDiv: TooltipTriggerStory = { + args: {delay: 0}, + render: (args) => , + parameters: {description: {data: 'Event handlers are attached to the parent of the tooltip trigger. They should not be called when the tooltip itself is clicked.'}} +}; + export const ArrowPositioningAtEdge: TooltipTriggerStory = { args: { children: [ diff --git a/packages/@react-spectrum/tooltip/test/Tooltip.test.js b/packages/@react-spectrum/tooltip/test/Tooltip.test.js index b80cc957f0a..4bb7aade44a 100644 --- a/packages/@react-spectrum/tooltip/test/Tooltip.test.js +++ b/packages/@react-spectrum/tooltip/test/Tooltip.test.js @@ -11,7 +11,7 @@ */ import React from 'react'; -import {render} from '@react-spectrum/test-utils'; +import {render, triggerPress} from '@react-spectrum/test-utils'; import {Tooltip} from '../'; describe('Tooltip', function () { @@ -40,4 +40,13 @@ describe('Tooltip', function () { let tooltip = getByRole('tooltip'); expect(ref.current.UNSAFE_getDOMNode()).toBe(tooltip); }); + + it('click does not propagate to parent', () => { + let mockClick = jest.fn(); + // eslint-disable-next-line jsx-a11y/click-events-have-key-events,jsx-a11y/no-static-element-interactions + let {getByRole} = render(
This is a tooltip
); + let tooltip = getByRole('tooltip'); + triggerPress(tooltip); + expect(mockClick).not.toHaveBeenCalled(); + }); }); diff --git a/packages/@react-spectrum/tooltip/test/TooltipTrigger.test.js b/packages/@react-spectrum/tooltip/test/TooltipTrigger.test.js index d86ce599905..62da6676542 100644 --- a/packages/@react-spectrum/tooltip/test/TooltipTrigger.test.js +++ b/packages/@react-spectrum/tooltip/test/TooltipTrigger.test.js @@ -976,4 +976,33 @@ describe('TooltipTrigger', function () { expect(queryByRole('tooltip')).toBeNull(); }); }); + + it('does not propagate pointer or click through the portal', () => { + let onPointerDown = jest.fn(); + let onPointerUp = jest.fn(); + let onClick = jest.fn(); + + let {getByRole} = render( + + {/* eslint-disable-next-line jsx-a11y/click-events-have-key-events,jsx-a11y/no-static-element-interactions */} +
+ + Trigger + Helpful information. + +
+
+ ); + + let button = getByRole('button'); + act(() => { + button.focus(); + }); + + let tooltip = getByRole('tooltip'); + triggerPress(tooltip); + expect(onPointerDown).not.toHaveBeenCalled(); + expect(onPointerUp).not.toHaveBeenCalled(); + expect(onClick).not.toHaveBeenCalled(); + }); });