What you were expecting:
When an <InPlaceEditor> loses focus, it should save the edited value. When cancelOnBlur is set, it should cancel the edit instead.
This matches the documented behavior: the field is saved automatically when the user clicks outside it, and the cancelOnBlur prop changes that behavior to cancel.
What happened instead:
If focus moves to another focusable element (for example, a neighboring button, link, or input), the editor stays open and the value is neither saved nor canceled.
The current blur handler returns whenever event.relatedTarget is non-null. Browsers set relatedTarget to the element receiving focus, so the save/cancel logic is skipped for normal Tab navigation and clicks on focusable controls.
Steps to reproduce:
- Render an
InPlaceEditor followed by a focusable control.
- Click the field to enter edit mode.
- Change its value.
- Press Tab to move to the next control, or click that control.
- Observe that the editor remains in edit mode and no update occurs.
<>
<InPlaceEditor source="name" />
<button>Next</button>
</>
A focused test also reproduces the issue:
const input = await screen.findByDisplayValue('John Doe');
fireEvent.change(input, { target: { value: 'Jane Doe' } });
const nextButton = screen.getByRole('button', { name: 'Next' });
fireEvent.blur(input, { relatedTarget: nextButton });
await screen.findByText('Jane Doe'); // times out; the input remains open
Related code:
handleBlur currently exits for every non-null relatedTarget:
if (event.relatedTarget) {
return;
}
The guard likely needs to distinguish focus moving within the editor (for example, to its Save/Cancel buttons) from focus moving outside the editor.
Documentation: https://marmelab.com/react-admin/InPlaceEditor.html
Other information:
The same problem affects cancelOnBlur: moving focus to another focusable element does not restore the initial value.
Environment
- React-admin version: 5.15.1 / current
master
- Last version that did not exhibit the issue: N/A (the guard is present in the initial
InPlaceEditor implementation)
- React version: 18.3.1
- Browser: Reproduced at the React event level with standard browser
FocusEvent.relatedTarget behavior
- Stack trace: N/A
What you were expecting:
When an
<InPlaceEditor>loses focus, it should save the edited value. WhencancelOnBluris set, it should cancel the edit instead.This matches the documented behavior: the field is saved automatically when the user clicks outside it, and the
cancelOnBlurprop changes that behavior to cancel.What happened instead:
If focus moves to another focusable element (for example, a neighboring button, link, or input), the editor stays open and the value is neither saved nor canceled.
The current blur handler returns whenever
event.relatedTargetis non-null. Browsers setrelatedTargetto the element receiving focus, so the save/cancel logic is skipped for normal Tab navigation and clicks on focusable controls.Steps to reproduce:
InPlaceEditorfollowed by a focusable control.A focused test also reproduces the issue:
Related code:
handleBlurcurrently exits for every non-nullrelatedTarget:The guard likely needs to distinguish focus moving within the editor (for example, to its Save/Cancel buttons) from focus moving outside the editor.
Documentation: https://marmelab.com/react-admin/InPlaceEditor.html
Other information:
The same problem affects
cancelOnBlur: moving focus to another focusable element does not restore the initial value.Environment
masterInPlaceEditorimplementation)FocusEvent.relatedTargetbehavior