Add invalid/close events to <dialog> element (#19439)
Support dialog Fix
Dominic Gannaway committed
Jul 24, 2020 at 20:36 UTC
ef22aecfc52cdf0d7cedc723c590719c009c2a64
2 files changed
+44
packages/react-dom/src/__tests__/ReactDOMEventListener-test.js
+33
@@ -502,6 +502,39 @@ describe('ReactDOMEventListener', () => {
502
}
503
});
504
505
+ it('should delegate dialog events even without a direct listener', () => {
506
+ const container = document.createElement('div');
507
+ const ref = React.createRef();
508
+ const onCancel = jest.fn();
509
+ const onClose = jest.fn();
510
+ document.body.appendChild(container);
511
+ try {
512
+ ReactDOM.render(
513
+ <div onCancel={onCancel} onClose={onClose}>
514
+ {/* Intentionally no handler on the target: */}
515
+ <dialog ref={ref} />
516
+ </div>,
517
+ container,
518
+ );
519
+ ref.current.dispatchEvent(
520
+ new Event('close', {
521
+ bubbles: false,
522
+ }),
523
+ );
524
+ ref.current.dispatchEvent(
525
+ new Event('cancel', {
526
+ bubbles: false,
527
+ }),
528
+ );
529
+ // Regression test: ensure React tree delegation still works
530
+ // even if the actual DOM element did not have a handler.
531
+ expect(onCancel).toHaveBeenCalledTimes(1);
532
+ expect(onClose).toHaveBeenCalledTimes(1);
533
+ } finally {
534
+ document.body.removeChild(container);
535
+ }
536
+ });
537
+
538
it('should bubble non-native bubbling events', () => {
539
const container = document.createElement('div');
540
const ref = React.createRef();
packages/react-dom/src/client/ReactDOMComponent.js
+11
@@ -96,6 +96,8 @@ import {
96
TOP_ERROR,
97
TOP_TOGGLE,
98
TOP_INVALID,
99
+ TOP_CANCEL,
100
+ TOP_CLOSE,
101
} from '../events/DOMTopLevelEventTypes';
102
103
let didWarnInvalidHydration = false;
@@ -539,6 +541,11 @@ export function setInitialProperties(
541
// TODO: Make sure that we check isMounted before firing any of these events.
542
let props: Object;
543
switch (tag) {
544
+ case 'dialog':
545
+ listenToNonDelegatedEvent(TOP_CANCEL, domElement);
546
+ listenToNonDelegatedEvent(TOP_CLOSE, domElement);
547
+ props = rawProps;
548
+ break;
549
case 'iframe':
550
case 'object':
551
case 'embed':
@@ -939,6 +946,10 @@ export function diffHydratedProperties(
946
947
// TODO: Make sure that we check isMounted before firing any of these events.
948
switch (tag) {
949
+ case 'dialog':
950
+ listenToNonDelegatedEvent(TOP_CANCEL, domElement);
951
+ listenToNonDelegatedEvent(TOP_CLOSE, domElement);
952
+ break;
953
case 'iframe':
954
case 'object':
955
case 'embed':