Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import * as React from 'react';
import { render, screen, fireEvent } from '@testing-library/react';

import { Basic } from './InPlaceEditor.stories';
import { Basic, WithSiblingControl } from './InPlaceEditor.stories';

describe('InPlaceEditor', () => {
it('should render the field value on mount', async () => {
Expand Down Expand Up @@ -54,4 +54,37 @@ describe('InPlaceEditor', () => {
await screen.findByLabelText('Cancel');
});
});
describe('blur', () => {
it('should save when focus moves to a control outside the editor', async () => {
render(<WithSiblingControl />);
const value = await screen.findByText('John Doe');
value.click();
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');
});
it('should cancel when focus moves to a control outside the editor and cancelOnBlur is set', async () => {
render(<WithSiblingControl cancelOnBlur />);
const value = await screen.findByText('John Doe');
value.click();
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('John Doe');
expect(screen.queryByDisplayValue('Jane Doe')).toBeNull();
});
it('should keep editing when focus moves to a button inside the editor', async () => {
render(<Basic delay={0} showButtons />);
const value = await screen.findByText('John Doe');
value.click();
const input = await screen.findByDisplayValue('John Doe');
fireEvent.change(input, { target: { value: 'Jane Doe' } });
const saveButton = screen.getByLabelText('Save');
fireEvent.blur(input, { relatedTarget: saveButton });
expect(screen.getByDisplayValue('Jane Doe')).not.toBeNull();
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,21 @@ export const CancelOnBlur = () => (
</Wrapper>
);

export const WithSiblingControl = ({
cancelOnBlur,
}: {
cancelOnBlur?: boolean;
}) => (
<Wrapper
dataProvider={fakeRestDataProvider({
users: [{ id: 1, name: 'John Doe', age: 25, type: 'customer' }],
})}
>
<InPlaceEditor source="name" cancelOnBlur={cancelOnBlur} />
<button type="button">Next</button>
</Wrapper>
);

export const MutationMode = () => (
<Wrapper>
<InPlaceEditor source="name" mutationMode="optimistic" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,13 @@ export const InPlaceEditor = <
};

const handleBlur = (event: React.FocusEvent) => {
if (event.relatedTarget) {
// Keep editing when focus moves to another element inside the editor
// (e.g. the Save and Cancel buttons). Only save or cancel when focus
// leaves the editor entirely.
if (
event.relatedTarget &&
event.currentTarget.contains(event.relatedTarget as Node)
) {
return;
}
if (cancelOnBlur) {
Expand Down
Loading