diff --git a/packages/react/src/select/item/useSelectItem.ts b/packages/react/src/select/item/useSelectItem.ts index 80c5f23182..3499ed8509 100644 --- a/packages/react/src/select/item/useSelectItem.ts +++ b/packages/react/src/select/item/useSelectItem.ts @@ -64,12 +64,28 @@ export function useSelectItem(params: useSelectItem.Parameters): useSelectItem.R prevPopupHeightRef.current = popupRef.current.offsetHeight; } }, - onMouseLeave() { + onMouseLeave(event) { const popup = popupRef.current; if (!popup || !open) { return; } + const targetRect = event.currentTarget.getBoundingClientRect(); + + // Safari randomly fires `mouseleave` incorrectly when the item is + // aligned to the trigger. This is a workaround to prevent the highlight + // from being removed while the cursor is still within the bounds of the item. + // https://github.com/mui/base-ui/issues/869 + const isWithinBounds = + targetRect.top + 1 <= event.clientY && + event.clientY <= targetRect.bottom - 1 && + targetRect.left + 1 <= event.clientX && + event.clientX <= targetRect.right - 1; + + if (isWithinBounds) { + return; + } + // With `alignItemToTrigger`, avoid re-rendering the root due to `onMouseLeave` // firing and causing a performance issue when expanding the popup. if (popup.offsetHeight === prevPopupHeightRef.current) {