@samitouri / QOS-React / commits / 7b023d7073

[react-dom] Include `submitter` in `submit` events (#35590)

Sebastian "Sebbie" Silbermann committed Feb 2, 2026 at 21:17 UTC 7b023d7073aa700b48674ae1985235b8c4755880
4 files changed +49 -1
packages/react-dom-bindings/src/events/SyntheticEvent.js
+11
@@ -522,6 +522,17 @@ export const SyntheticPointerEvent: $FlowFixMe = createSyntheticEvent(
522 PointerEventInterface,
523 );
524
525 +/**
526 + * @interface SubmitEvent
527 + * @see https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#the-submitevent-interface
528 + */
529 +const SubmitEventInterface: EventInterfaceType = {
530 + ...EventInterface,
531 + submitter: 0,
532 +};
533 +export const SyntheticSubmitEvent: $FlowFixMe =
534 + createSyntheticEvent(SubmitEventInterface);
535 +
536 /**
537 * @interface TouchEvent
538 * @see http://www.w3.org/TR/touch-events/
packages/react-dom-bindings/src/events/plugins/SimpleEventPlugin.js
+4
@@ -27,6 +27,7 @@ import {
27 SyntheticWheelEvent,
28 SyntheticClipboardEvent,
29 SyntheticPointerEvent,
30 + SyntheticSubmitEvent,
31 SyntheticToggleEvent,
32 } from '../../events/SyntheticEvent';
33
@@ -162,6 +163,9 @@ function extractEvents(
163 case 'pointerup':
164 SyntheticEventCtor = SyntheticPointerEvent;
165 break;
166 + case 'submit':
167 + SyntheticEventCtor = SyntheticSubmitEvent;
168 + break;
169 case 'toggle':
170 case 'beforetoggle':
171 // MDN claims <details> should not receive ToggleEvent contradicting the spec: https://html.spec.whatwg.org/multipage/indices.html#event-toggle
packages/react-dom/src/__tests__/ReactDOMEventPropagation-test.js
+2 -1
@@ -672,9 +672,10 @@ describe('ReactDOMEventListener', () => {
672 reactEventType: 'submit',
673 nativeEvent: 'submit',
674 dispatch(node) {
675 - const e = new Event('submit', {
675 + const e = new SubmitEvent('submit', {
676 bubbles: true,
677 cancelable: true,
678 + submitter: null,
679 });
680 node.dispatchEvent(e);
681 },
packages/react-dom/src/events/plugins/__tests__/SimpleEventPlugin-test.js
+32
@@ -591,4 +591,36 @@ describe('SimpleEventPlugin', function () {
591 );
592 });
593 });
594 +
595 + it('includes the submitter in submit events', async function () {
596 + container = document.createElement('div');
597 +
598 + const onSubmit = jest.fn(event => {
599 + event.preventDefault();
600 + });
601 + const root = ReactDOMClient.createRoot(container);
602 + await act(() => {
603 + root.render(
604 + <form onSubmit={onSubmit}>
605 + <button type="submit" id="submitter">
606 + Submit
607 + </button>
608 + </form>,
609 + );
610 + });
611 +
612 + const submitter = container.querySelector('#submitter');
613 + const submitEvent = new SubmitEvent('submit', {
614 + bubbles: true,
615 + cancelable: true,
616 + submitter: submitter,
617 + });
618 + await act(() => {
619 + submitter.dispatchEvent(submitEvent);
620 + });
621 +
622 + expect(onSubmit).toHaveBeenCalledTimes(1);
623 + const event = onSubmit.mock.calls[0][0];
624 + expect(event.submitter).toBe(submitter);
625 + });
626 });