diff --git a/packages/ra-ui-materialui/src/field/ReferenceField.spec.tsx b/packages/ra-ui-materialui/src/field/ReferenceField.spec.tsx index c7a2fc93bd7..b96098b7c41 100644 --- a/packages/ra-ui-materialui/src/field/ReferenceField.spec.tsx +++ b/packages/ra-ui-materialui/src/field/ReferenceField.spec.tsx @@ -141,6 +141,22 @@ describe('', () => { }); }); + it('should display the emptyText if the field is empty', () => { + const { getByText } = renderWithRedux( + + + + ); + expect(getByText('EMPTY')).not.toBeNull(); + }); + it('should use the reference from the store if available', () => { const { container, getByText } = renderWithRedux( diff --git a/packages/ra-ui-materialui/src/field/ReferenceField.tsx b/packages/ra-ui-materialui/src/field/ReferenceField.tsx index e1fb1b9295f..6847c25ce7f 100644 --- a/packages/ra-ui-materialui/src/field/ReferenceField.tsx +++ b/packages/ra-ui-materialui/src/field/ReferenceField.tsx @@ -4,6 +4,7 @@ import PropTypes from 'prop-types'; import classnames from 'classnames'; import get from 'lodash/get'; import { makeStyles } from '@material-ui/core/styles'; +import { Typography } from '@material-ui/core'; import ErrorIcon from '@material-ui/icons/Error'; import { useReference, @@ -11,6 +12,7 @@ import { getResourceLinkPath, LinkToType, ResourceContextProvider, + Record, } from 'ra-core'; import LinearProgress from '../layout/LinearProgress'; @@ -63,40 +65,21 @@ import { ClassesOverride } from '../types'; * In previous versions of React-Admin, the prop `linkType` was used. It is now deprecated and replaced with `link`. However * backward-compatibility is still kept */ - const ReferenceField: FC = ({ - children, record, source, + emptyText, ...props -}) => { - if (React.Children.count(children) !== 1) { - throw new Error(' only accepts a single child'); - } - const { basePath, resource } = props; - const resourceLinkPath = getResourceLinkPath({ - ...props, - resource, - record, - source, - basePath, - }); - - return ( - - - {children} - - +}) => + get(record, source) == null ? ( + emptyText ? ( + + {emptyText} + + ) : null + ) : ( + ); -}; ReferenceField.propTypes = { addLabel: PropTypes.bool, @@ -132,9 +115,9 @@ ReferenceField.defaultProps = { link: 'edit', }; -export interface ReferenceFieldProps +export interface ReferenceFieldProps extends PublicFieldProps, - InjectedFieldProps { + InjectedFieldProps { children: ReactElement; classes?: ClassesOverride; reference: string; @@ -145,6 +128,41 @@ export interface ReferenceFieldProps link?: LinkToType; } +/** + * This intermediate component is made necessary by the useReference hook, + * which cannot be called conditionally when get(record, source) is empty. + */ +export const NonEmptyReferenceField: FC> = ({ children, record, source, ...props }) => { + if (React.Children.count(children) !== 1) { + throw new Error(' only accepts a single child'); + } + const { basePath, resource } = props; + const resourceLinkPath = getResourceLinkPath({ + ...props, + resource, + record, + source, + basePath, + }); + return ( + + + {children} + + + ); +}; + const useStyles = makeStyles( theme => ({ link: {