diff --git a/packages/ra-core/src/form/useChoices.ts b/packages/ra-core/src/form/useChoices.ts index 127281965b8..4ae81da172b 100644 --- a/packages/ra-core/src/form/useChoices.ts +++ b/packages/ra-core/src/form/useChoices.ts @@ -65,7 +65,9 @@ const useChoices = ({ ? optionText(choice) : get(choice, optionText); - return translateChoice + return isValidElement(choiceName) + ? choiceName + : translateChoice ? translate(choiceName, { _: choiceName }) : String(choiceName); }, diff --git a/packages/ra-ui-materialui/src/input/AutocompleteInput.spec.tsx b/packages/ra-ui-materialui/src/input/AutocompleteInput.spec.tsx index 5dbe54b9619..48b01d7b088 100644 --- a/packages/ra-ui-materialui/src/input/AutocompleteInput.spec.tsx +++ b/packages/ra-ui-materialui/src/input/AutocompleteInput.spec.tsx @@ -1,5 +1,5 @@ import * as React from 'react'; -import { render, fireEvent, waitFor } from '@testing-library/react'; +import { render, fireEvent, waitFor, act } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import { AutocompleteInput } from './AutocompleteInput'; @@ -534,6 +534,38 @@ describe('', () => { }); }); + it('should throw an error if no inputText was provided when the optionText returns an element', () => { + const mock = jest.spyOn(console, 'error').mockImplementation(() => {}); + const SuggestionItem = ({ record }: { record?: any }) => ( +
+ ); + + const t = () => { + act(() => { + render( +
( + } + matchSuggestion={() => true} + choices={[ + { id: 1, name: 'bar' }, + { id: 2, name: 'foo' }, + ]} + /> + )} + /> + ); + }); + }; + expect(t).toThrow( + 'When optionText returns a React element, you must also provide the inputText prop' + ); + mock.mockRestore(); + }); + it('should display helperText if specified', () => { const { queryByText } = render( { const isFunction = typeof optionText === 'function'; if (isFunction) { + const selectedItemText = optionText(selectedItem); + + if (isValidElement(selectedItemText) && !inputText) { + throw new Error( + 'When optionText returns a React element, you must also provide the inputText prop' + ); + } + const hasOption = choices.some(choice => { const text = optionText(choice) as string; return get(choice, text) === filterValue; }); - const selectedItemText = optionText(selectedItem); - return hasOption || selectedItemText === filterValue; } @@ -246,7 +252,14 @@ export const AutocompleteInput = (props: AutocompleteInputProps) => { }); return selectedItemText === filterValue || hasOption; - }, [choices, optionText, filterValue, matchSuggestion, selectedItem]); + }, [ + optionText, + selectedItem, + choices, + filterValue, + matchSuggestion, + inputText, + ]); const shouldAllowCreate = !doesQueryMatchSuggestion;