marmelab / marmelab/react-admin
InPlaceEditor ignores blur when focus moves outside the editor
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 26.9k
- Forks
- 5.5k
- Avg merge
- 2d 3h
- Merged PRs (30d)
- 19
Description
**What you were expecting:**
When an `` 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:**
1. Render an `InPlaceEditor` followed by a focusable control.
2. Click the field to enter edit mode.
3. Change its value.
4. Press Tab to move to the next control, or click that control.
5. Observe that the editor remains in edit mode and no update occurs.
```tsx
<>
Next
```
A focused test also reproduces the issue:
```tsx
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`:
```tsx
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
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start at the InPlaceEditor handleBlur handler and reproduce the issue with the focused test scenario using a relatedTarget outside the editor. Check focus transitions to the editor’s Save/Cancel controls versus external focusable elements. Done means moving focus outside saves the edited value, while cancelOnBlur restores the initial value, without breaking internal editor focus.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- react, typescript
- Domain
- frontend
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 78/100