Skip to content

Commit b921443

Browse files
authored
Merge pull request marmelab#10288 from marmelab/fix-AutocompleteInput-create-option-with-createLabel
Fix `<AutocompleteInput>` displays 'Create' option for choices that already exist when `createLabel` is provided
2 parents f5294e7 + 7ddda78 commit b921443

File tree

2 files changed

+37
-38
lines changed

2 files changed

+37
-38
lines changed

packages/ra-ui-materialui/src/input/AutocompleteInput.spec.tsx

Lines changed: 36 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import {
2727
WithInputProps,
2828
OnCreate,
2929
OnCreateSlow,
30+
CreateLabel,
3031
} from './AutocompleteInput.stories';
3132
import { ReferenceArrayInput } from './ReferenceArrayInput';
3233
import { AutocompleteArrayInput } from './AutocompleteArrayInput';
@@ -1168,7 +1169,7 @@ describe('<AutocompleteInput />', () => {
11681169
});
11691170

11701171
describe('onCreate', () => {
1171-
it("shouldn't include an option with the createLabel when the input is empty", async () => {
1172+
it("shouldn't include an option with the create label when the input is empty", async () => {
11721173
const choices = [
11731174
{ id: 'ang', name: 'Angular' },
11741175
{ id: 'rea', name: 'React' },
@@ -1213,41 +1214,11 @@ describe('<AutocompleteInput />', () => {
12131214
expect(screen.queryByText('ra.action.create_item')).toBeNull();
12141215
});
12151216
it('should include an option with the custom createLabel when the input is empty', async () => {
1216-
const choices = [
1217-
{ id: 'ang', name: 'Angular' },
1218-
{ id: 'rea', name: 'React' },
1219-
];
1220-
const handleCreate = filter => {
1221-
const newChoice = {
1222-
id: 'js_fatigue',
1223-
name: filter,
1224-
};
1225-
choices.push(newChoice);
1226-
return newChoice;
1227-
};
1217+
render(<CreateLabel />);
12281218

1229-
render(
1230-
<AdminContext dataProvider={testDataProvider()}>
1231-
<ResourceContextProvider value="posts">
1232-
<SimpleForm
1233-
mode="onBlur"
1234-
onSubmit={jest.fn()}
1235-
defaultValues={{ language: 'ang' }}
1236-
>
1237-
<AutocompleteInput
1238-
source="language"
1239-
choices={choices}
1240-
onCreate={handleCreate}
1241-
createLabel="Start typing to create a new item"
1242-
/>
1243-
</SimpleForm>
1244-
</ResourceContextProvider>
1245-
</AdminContext>
1246-
);
1247-
1248-
const input = screen.getByLabelText(
1249-
'resources.posts.fields.language'
1250-
) as HTMLInputElement;
1219+
const input = (await screen.findByLabelText(
1220+
'Author'
1221+
)) as HTMLInputElement;
12511222
input.focus();
12521223
fireEvent.change(input, {
12531224
target: { value: '' },
@@ -1256,8 +1227,36 @@ describe('<AutocompleteInput />', () => {
12561227
expect(
12571228
screen.queryByText('Start typing to create a new item')
12581229
).not.toBeNull();
1259-
expect(screen.queryByText('ra.action.create')).toBeNull();
1260-
expect(screen.queryByText('ra.action.create_item')).toBeNull();
1230+
expect(screen.queryByText(/Create/)).toBeNull();
1231+
});
1232+
it('should not show the create option when a choice is selected when using a custom createLabel', async () => {
1233+
render(<CreateLabel />);
1234+
1235+
const input = (await screen.findByLabelText(
1236+
'Author'
1237+
)) as HTMLInputElement;
1238+
input.focus();
1239+
1240+
// First, clear the input
1241+
fireEvent.change(input, {
1242+
target: { value: '' },
1243+
});
1244+
// We expect only the 'Start typing to create a new item' option
1245+
await screen.findByText('Victor Hugo');
1246+
expect(
1247+
screen.queryByText('Start typing to create a new item')
1248+
).not.toBeNull();
1249+
expect(screen.queryByText(/Create/)).toBeNull();
1250+
1251+
// Then, change the input to an existing value
1252+
fireEvent.click(screen.getByText('Leo Tolstoy'));
1253+
fireEvent.focus(input);
1254+
// We expect all create labels not to render
1255+
await screen.findByText('Victor Hugo');
1256+
expect(
1257+
screen.queryByText('Start typing to create a new item')
1258+
).toBeNull();
1259+
expect(screen.queryByText(/Create/)).toBeNull();
12611260
});
12621261
it('should include an option with the createItemLabel when the input not empty', async () => {
12631262
const choices = [

packages/ra-ui-materialui/src/input/AutocompleteInput.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -519,7 +519,7 @@ If you provided a React element for the optionText prop, you must also provide t
519519
// add create option if necessary
520520
const { inputValue } = params;
521521
if (onCreate || create) {
522-
if (inputValue === '' && createLabel) {
522+
if (inputValue === '' && filterValue === '' && createLabel) {
523523
// create option with createLabel
524524
filteredOptions = filteredOptions.concat(getCreateItem(''));
525525
} else if (!doesQueryMatchSuggestion(filterValue)) {

0 commit comments

Comments
 (0)