diff --git a/packages/ra-ui-materialui/src/input/InPlaceEditor/InPlaceEditor.spec.tsx b/packages/ra-ui-materialui/src/input/InPlaceEditor/InPlaceEditor.spec.tsx
index b9bc471acdc..e49dc563406 100644
--- a/packages/ra-ui-materialui/src/input/InPlaceEditor/InPlaceEditor.spec.tsx
+++ b/packages/ra-ui-materialui/src/input/InPlaceEditor/InPlaceEditor.spec.tsx
@@ -23,6 +23,24 @@ describe('InPlaceEditor', () => {
fireEvent.blur(input);
await screen.findByText('Jane Doe');
});
+
+ it('should save when focus moves to an element outside the editor', async () => {
+ const { container } = render();
+
+ const value = await screen.findByText('John Doe');
+ value.click();
+
+ const input = await screen.findByDisplayValue('John Doe');
+ fireEvent.change(input, { target: { value: 'Jane Doe' } });
+
+ const outsideButton = document.createElement('button');
+ outsideButton.textContent = 'Next';
+ container.appendChild(outsideButton);
+
+ fireEvent.blur(input, { relatedTarget: outsideButton });
+
+ await screen.findByText('Jane Doe');
+ });
it('should revert to the previous version on error', async () => {
jest.spyOn(console, 'error').mockImplementation(() => {});
render();
diff --git a/packages/ra-ui-materialui/src/input/InPlaceEditor/InPlaceEditor.tsx b/packages/ra-ui-materialui/src/input/InPlaceEditor/InPlaceEditor.tsx
index d8756b61b12..6ebbf056fdd 100644
--- a/packages/ra-ui-materialui/src/input/InPlaceEditor/InPlaceEditor.tsx
+++ b/packages/ra-ui-materialui/src/input/InPlaceEditor/InPlaceEditor.tsx
@@ -197,16 +197,27 @@ export const InPlaceEditor = <
const handleBlur = (event: React.FocusEvent) => {
if (event.relatedTarget) {
- return;
+ // Focus moved to an element inside the editor — ignore
+ if (event.currentTarget.contains(event.relatedTarget as Node)) {
+ return;
+ }
+ // Focus moved to a MUI portal (e.g. Select dropdown) — ignore
+ if (
+ (event.relatedTarget as HTMLElement).closest?.(
+ '.MuiPopover-root, .MuiModal-root, .MuiMenu-root'
+ )
+ ) {
+ return;
+ }
}
+
if (cancelOnBlur) {
dispatch({ type: 'cancel' });
return;
}
+
if (state.state === 'editing') {
- // trigger the parent form submit
- // to save the changes
- (submitButtonRef.current as HTMLButtonElement).click();
+ (submitButtonRef.current as HTMLButtonElement)?.click();
}
};