Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/five-mayflies-flash.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@primer/react": patch
---

fix(TooltipV2): delay tooltip opening time by ms
2 changes: 1 addition & 1 deletion packages/react/src/Overlay/Overlay.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ describe('Overlay', () => {
expect(container.getByText('Add to list')).toBeInTheDocument()

// open second menu
await user.click(container.getByText('Create list'))
fireEvent.click(container.getByText('Create list'))
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried for minute to get this to work with user.click, I replicated this test manually in storybook and it works as expected. I noticed userEvent was triggering different events than manual testing did 🤷🏽‍♀️

expect(container.getByPlaceholderText('Name this list')).toBeInTheDocument()

// hitting escape on input should close the second menu but not the first
Expand Down
19 changes: 17 additions & 2 deletions packages/react/src/TooltipV2/Tooltip.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import classes from './Tooltip.module.css'
import {useFeatureFlag} from '../FeatureFlags'
import {KeybindingHint, type KeybindingHintProps} from '../KeybindingHint'
import VisuallyHidden from '../_VisuallyHidden'
import useSafeTimeout from '../hooks/useSafeTimeout'

const CSS_MODULE_FEATURE_FLAG = 'primer_react_css_modules_team'

Expand Down Expand Up @@ -213,6 +214,10 @@ export const Tooltip = React.forwardRef(

const [isPopoverOpen, setIsPopoverOpen] = useState(false)

const timeoutRef = React.useRef<number | null>(null)

const {safeSetTimeout, safeClearTimeout} = useSafeTimeout()

const openTooltip = () => {
try {
if (
Expand Down Expand Up @@ -265,6 +270,8 @@ export const Tooltip = React.forwardRef(
) {
tooltipElRef.current.hidePopover()
setIsPopoverOpen(false)
} else {
setIsPopoverOpen(false)
Comment on lines +273 to +274
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixes bug where overlay would stay "stuck" and not able to close via keyboard due to popOver state being open but it not actually being in the DOM

}
} catch (error) {
// older browsers don't support the :popover-open selector and will throw, even though we use a polyfill
Expand Down Expand Up @@ -362,10 +369,18 @@ export const Tooltip = React.forwardRef(
child.props.onFocus?.(event)
},
onMouseEnter: (event: React.MouseEvent) => {
openTooltip()
child.props.onMouseEnter?.(event)
// show tooltip after mosue has been hovering for at least 50ms
// (prevent showing tooltip when mouse is just passing through)
timeoutRef.current = safeSetTimeout(() => {
openTooltip()
child.props.onMouseEnter?.(event)
}, 50)
},
onMouseLeave: (event: React.MouseEvent) => {
if (timeoutRef.current) {
safeClearTimeout(timeoutRef.current)
timeoutRef.current = null
}
closeTooltip()
child.props.onMouseLeave?.(event)
},
Expand Down
Loading