Skip to content

InPlaceEditor ignores blur when focus moves outside the editor #11303

Description

@ClarenceChoo

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:

  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.
<>
    <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

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions