Skip to content

Commit 9c07beb

Browse files
committed
Add more non-React events to the priority list
1 parent 212b1c7 commit 9c07beb

File tree

3 files changed

+57
-0
lines changed

3 files changed

+57
-0
lines changed

packages/react-dom/src/__tests__/ReactDOMNativeEventHeuristic-test.js

+33
Original file line numberDiff line numberDiff line change
@@ -258,4 +258,37 @@ describe('ReactDOMNativeEventHeuristic-test', () => {
258258
expect(container.textContent).toEqual('hovered');
259259
});
260260
});
261+
262+
// @gate experimental
263+
// @gate enableDiscreteEventMicroTasks && enableNativeEventPriorityInference
264+
it('mouse enter should be user-blocking but not discrete', async () => {
265+
const root = ReactDOM.unstable_createRoot(container);
266+
267+
const target = React.createRef(null);
268+
function Foo() {
269+
const [isHover, setHover] = React.useState(false);
270+
React.useLayoutEffect(() => {
271+
target.current.onmouseenter = () => setHover(true);
272+
});
273+
return <div ref={target}>{isHover ? 'hovered' : 'not hovered'}</div>;
274+
}
275+
276+
await act(async () => {
277+
root.render(<Foo />);
278+
});
279+
expect(container.textContent).toEqual('not hovered');
280+
281+
await act(async () => {
282+
// Note: React does not use native mouseenter/mouseleave events
283+
// but we should still correctly determine their priority.
284+
const mouseEnterEvent = document.createEvent('MouseEvents');
285+
mouseEnterEvent.initEvent('mouseenter', true, true);
286+
dispatchAndSetCurrentEvent(target.current, mouseEnterEvent);
287+
288+
// 3s should be enough to expire the updates
289+
Scheduler.unstable_advanceTime(3000);
290+
expect(Scheduler).toFlushExpired([]);
291+
expect(container.textContent).toEqual('hovered');
292+
});
293+
});
261294
});

packages/react-dom/src/events/DOMEventNames.js

+10
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ export type DOMEventName =
1717
// 'animationend |
1818
// 'animationstart' |
1919
| 'beforeblur' // Not a real event. This is used by event experiments.
20+
| 'beforeinput'
21+
| 'blur'
2022
| 'canplay'
2123
| 'canplaythrough'
2224
| 'cancel'
@@ -44,9 +46,12 @@ export type DOMEventName =
4446
| 'encrypted'
4547
| 'ended'
4648
| 'error'
49+
| 'focus'
4750
| 'focusin'
4851
| 'focusout'
52+
| 'fullscreenchange'
4953
| 'gotpointercapture'
54+
| 'hashchange'
5055
| 'input'
5156
| 'invalid'
5257
| 'keydown'
@@ -58,6 +63,8 @@ export type DOMEventName =
5863
| 'loadedmetadata'
5964
| 'lostpointercapture'
6065
| 'mousedown'
66+
| 'mouseenter'
67+
| 'mouseleave'
6168
| 'mousemove'
6269
| 'mouseout'
6370
| 'mouseover'
@@ -74,12 +81,15 @@ export type DOMEventName =
7481
| 'pointerout'
7582
| 'pointerover'
7683
| 'pointerup'
84+
| 'popstate'
7785
| 'progress'
7886
| 'ratechange'
7987
| 'reset'
8088
| 'scroll'
8189
| 'seeked'
8290
| 'seeking'
91+
| 'select'
92+
| 'selectstart'
8393
| 'selectionchange'
8494
| 'stalled'
8595
| 'submit'

packages/react-dom/src/events/ReactDOMEventListener.js

+14
Original file line numberDiff line numberDiff line change
@@ -397,6 +397,16 @@ export function getEventPriority(domEventName: DOMEventName): * {
397397
// eslint-disable-next-line no-fallthrough
398398
case 'beforeblur':
399399
case 'afterblur':
400+
// Not used by React but could be by user code:
401+
// eslint-disable-next-line no-fallthrough
402+
case 'beforeinput':
403+
case 'blur':
404+
case 'fullscreenchange':
405+
case 'focus':
406+
case 'hashchange':
407+
case 'popstate':
408+
case 'select':
409+
case 'selectstart':
400410
return InputDiscreteLanePriority;
401411
case 'drag':
402412
case 'dragenter':
@@ -413,6 +423,10 @@ export function getEventPriority(domEventName: DOMEventName): * {
413423
case 'toggle':
414424
case 'touchmove':
415425
case 'wheel':
426+
// Not used by React but could be by user code:
427+
// eslint-disable-next-line no-fallthrough
428+
case 'mouseenter':
429+
case 'mouseleave':
416430
return InputContinuousLanePriority;
417431
default:
418432
return DefaultLanePriority;

0 commit comments

Comments
 (0)