Skip to content

Commit ef22aec

Browse files
authored
Add invalid/close events to <dialog> element (facebook#19439)
Support dialog Fix
1 parent b55f75d commit ef22aec

File tree

2 files changed

+44
-0
lines changed

2 files changed

+44
-0
lines changed

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

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -502,6 +502,39 @@ describe('ReactDOMEventListener', () => {
502502
}
503503
});
504504

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+
505538
it('should bubble non-native bubbling events', () => {
506539
const container = document.createElement('div');
507540
const ref = React.createRef();

packages/react-dom/src/client/ReactDOMComponent.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,8 @@ import {
9696
TOP_ERROR,
9797
TOP_TOGGLE,
9898
TOP_INVALID,
99+
TOP_CANCEL,
100+
TOP_CLOSE,
99101
} from '../events/DOMTopLevelEventTypes';
100102

101103
let didWarnInvalidHydration = false;
@@ -539,6 +541,11 @@ export function setInitialProperties(
539541
// TODO: Make sure that we check isMounted before firing any of these events.
540542
let props: Object;
541543
switch (tag) {
544+
case 'dialog':
545+
listenToNonDelegatedEvent(TOP_CANCEL, domElement);
546+
listenToNonDelegatedEvent(TOP_CLOSE, domElement);
547+
props = rawProps;
548+
break;
542549
case 'iframe':
543550
case 'object':
544551
case 'embed':
@@ -939,6 +946,10 @@ export function diffHydratedProperties(
939946

940947
// TODO: Make sure that we check isMounted before firing any of these events.
941948
switch (tag) {
949+
case 'dialog':
950+
listenToNonDelegatedEvent(TOP_CANCEL, domElement);
951+
listenToNonDelegatedEvent(TOP_CLOSE, domElement);
952+
break;
942953
case 'iframe':
943954
case 'object':
944955
case 'embed':

0 commit comments

Comments
 (0)