diff --git a/src/hooks/useActive.ts b/src/hooks/useActive.ts index dd0d6005..d992fea6 100644 --- a/src/hooks/useActive.ts +++ b/src/hooks/useActive.ts @@ -25,23 +25,28 @@ export default function useActive( active: activeKey === eventKey, }; - // Skip when disabled - if (!disabled) { - ret.onMouseEnter = domEvent => { - onMouseEnter?.({ - key: eventKey, - domEvent, - }); + // Disabled item never becomes active, but still notifies the hover callbacks + // so that users can attach tooltips or other hover behaviors to it. + ret.onMouseEnter = domEvent => { + onMouseEnter?.({ + key: eventKey, + domEvent, + }); + + if (!disabled) { onActive(eventKey); - }; - ret.onMouseLeave = domEvent => { - onMouseLeave?.({ - key: eventKey, - domEvent, - }); + } + }; + ret.onMouseLeave = domEvent => { + onMouseLeave?.({ + key: eventKey, + domEvent, + }); + + if (!disabled) { onInactive(eventKey); - }; - } + } + }; return ret; } diff --git a/tests/MenuItem.spec.tsx b/tests/MenuItem.spec.tsx index 87966ef1..612b6550 100644 --- a/tests/MenuItem.spec.tsx +++ b/tests/MenuItem.spec.tsx @@ -108,6 +108,32 @@ describe('MenuItem', () => { }); }); + describe('disabled hover', () => { + it('still triggers onMouseEnter/onMouseLeave without activating', () => { + const onMouseEnter = jest.fn(); + const onMouseLeave = jest.fn(); + const { container } = render( +
, + ); + const item = container.querySelector('.rc-menu-item'); + + fireEvent.mouseEnter(item); + expect(onMouseEnter).toHaveBeenCalledWith( + expect.objectContaining({ key: '1', domEvent: expect.anything() }), + ); + expect(item).not.toHaveClass('rc-menu-item-active'); + + fireEvent.mouseLeave(item); + expect(onMouseLeave).toHaveBeenCalledWith( + expect.objectContaining({ key: '1', domEvent: expect.anything() }), + ); + }); + }); + describe('rest props', () => { it('onClick event should only trigger 1 time along the component hierarchy', () => { const onClick = jest.fn();