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..ddad01a1946 100644
--- a/packages/ra-ui-materialui/src/input/InPlaceEditor/InPlaceEditor.tsx
+++ b/packages/ra-ui-materialui/src/input/InPlaceEditor/InPlaceEditor.tsx
@@ -196,16 +196,19 @@ export const InPlaceEditor = <
};
const handleBlur = (event: React.FocusEvent) => {
- if (event.relatedTarget) {
+ if (
+ event.relatedTarget &&
+ event.currentTarget.contains(event.relatedTarget as Node)
+ ) {
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();
}
};