Skip to content

Fix <Notification> causes undoable notifications to be commited twice in MUI v6 - #11345

Merged
fzaninotto merged 2 commits into
marmelab:masterfrom
dawNotPoi:fix/11334-notification-exit-callback
Sep 1, 2026
Merged

Fix <Notification> causes undoable notifications to be commited twice in MUI v6#11345
fzaninotto merged 2 commits into
marmelab:masterfrom
dawNotPoi:fix/11334-notification-exit-callback

Conversation

@dawNotPoi

@dawNotPoi dawNotPoi commented Aug 22, 2026

Copy link
Copy Markdown
Contributor

Problem

With MUI 6 and later, Notification passes the same onExited callback through both the legacy TransitionProps API and slotProps.transition. MUI invokes both callbacks, causing an undoable mutation to be committed twice.

Fixes #11334

Solution

Use TransitionProps and ContentProps only with MUI 5. For MUI 6 and later, use the slot props API exclusively while preserving the existing user prop override order.

How To Test

The notification regression suite must pass with the development dependencies installed against both MUI 5 and MUI 6. With MUI 5, the MUI 6+ regression is expected to be skipped; with MUI 6, it runs against the real Snackbar implementation.

  • yarn jest packages/ra-ui-materialui/src/layout/Notification.spec.tsx --runInBand
  • yarn jest packages/ra-core/src/notification/useNotify.spec.tsx --runInBand
  • yarn workspace ra-core build
  • yarn workspace ra-ui-materialui build
  • yarn tsc --noEmit -p packages/ra-ui-materialui/tsconfig.json

Additional Checks

  • The PR targets master for a bug fix
  • The PR includes unit tests
  • No new story is required because this is internal transition wiring covered by the regression test
  • No documentation change is required because the public API is unchanged

@dawNotPoi
dawNotPoi marked this pull request as ready for review August 22, 2026 12:23
Comment on lines +9 to +40
const Mui6Snackbar = ReactModule.forwardRef<any, any>((props, ref) => {
const wasOpen = ReactModule.useRef(props.open);

ReactModule.useEffect(() => {
if (wasOpen.current && !props.open) {
props.slotProps?.transition?.onExited?.(null);
props.TransitionProps?.onExited?.(null);
}
wasOpen.current = props.open;
}, [props.open, props.slotProps, props.TransitionProps]);

ReactModule.useEffect(() => {
if (!props.open) return;

document.addEventListener('click', props.onClose);
return () => document.removeEventListener('click', props.onClose);
}, [props.open, props.onClose]);

if (!props.open) return null;

return ReactModule.createElement(
'div',
{ ref },
props.children ?? props.message,
props.action,
ReactModule.createElement(
'button',
{ onClick: props.onClose },
'Close notification'
)
);
});

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I really don't understand why you need to reimplement the Snackbar to test mui v6. Can you explain?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right; reimplementing Snackbar was unnecessary. Removed the module mock in 3eaa674. The regression now exercises the real MUI Snackbar and triggers its click-away exit path.

mockMuiMajor = 5;
});

it.each([6, 7, 9])(

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think that it makes much sense to test all versions. I'd prefer that you create a test that only runs if the MUI major it >=6, with no mock. And then explain in the PR description that, in order to test you change, te tests must pass with devdeps using mui V5 and mui V6.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated in 3eaa674. The regression now runs only when the installed MUI major is 6 or newer, with no MUI mock. I verified the file against MUI 5.16.14 (3 passed, 1 expected skip) and MUI 6.4.10 (4 passed), and updated the PR description with the two-version test requirement.

@fzaninotto
fzaninotto merged commit 062f3fd into marmelab:master Sep 1, 2026
14 checks passed
@fzaninotto

Copy link
Copy Markdown
Member

Thanks!

@fzaninotto fzaninotto added this to the 5.15.3 milestone Sep 1, 2026
@fzaninotto fzaninotto changed the title Fix duplicate undoable mutation commits on notification exit Fix <Notification> causes undoable notifications to be commited twice in MUI v6 Sep 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants