@@ -4,13 +4,15 @@ import PropTypes from 'prop-types';
4
4
import classnames from 'classnames' ;
5
5
import get from 'lodash/get' ;
6
6
import { makeStyles } from '@material-ui/core/styles' ;
7
+ import { Typography } from '@material-ui/core' ;
7
8
import ErrorIcon from '@material-ui/icons/Error' ;
8
9
import {
9
10
useReference ,
10
11
UseReferenceProps ,
11
12
getResourceLinkPath ,
12
13
LinkToType ,
13
14
ResourceContextProvider ,
15
+ Record ,
14
16
} from 'ra-core' ;
15
17
16
18
import LinearProgress from '../layout/LinearProgress' ;
@@ -63,40 +65,21 @@ import { ClassesOverride } from '../types';
63
65
* In previous versions of React-Admin, the prop `linkType` was used. It is now deprecated and replaced with `link`. However
64
66
* backward-compatibility is still kept
65
67
*/
66
-
67
68
const ReferenceField : FC < ReferenceFieldProps > = ( {
68
- children,
69
69
record,
70
70
source,
71
+ emptyText,
71
72
...props
72
- } ) => {
73
- if ( React . Children . count ( children ) !== 1 ) {
74
- throw new Error ( '<ReferenceField> only accepts a single child' ) ;
75
- }
76
- const { basePath, resource } = props ;
77
- const resourceLinkPath = getResourceLinkPath ( {
78
- ...props ,
79
- resource,
80
- record,
81
- source,
82
- basePath,
83
- } ) ;
84
-
85
- return (
86
- < ResourceContextProvider value = { props . reference } >
87
- < PureReferenceFieldView
88
- { ...props }
89
- { ...useReference ( {
90
- reference : props . reference ,
91
- id : get ( record , source ) ,
92
- } ) }
93
- resourceLinkPath = { resourceLinkPath }
94
- >
95
- { children }
96
- </ PureReferenceFieldView >
97
- </ ResourceContextProvider >
73
+ } ) =>
74
+ get ( record , source ) == null ? (
75
+ emptyText ? (
76
+ < Typography component = "span" variant = "body2" >
77
+ { emptyText }
78
+ </ Typography >
79
+ ) : null
80
+ ) : (
81
+ < NonEmptyReferenceField { ...props } record = { record } source = { source } />
98
82
) ;
99
- } ;
100
83
101
84
ReferenceField . propTypes = {
102
85
addLabel : PropTypes . bool ,
@@ -132,9 +115,9 @@ ReferenceField.defaultProps = {
132
115
link : 'edit' ,
133
116
} ;
134
117
135
- export interface ReferenceFieldProps
118
+ export interface ReferenceFieldProps < RecordType extends Record = Record >
136
119
extends PublicFieldProps ,
137
- InjectedFieldProps {
120
+ InjectedFieldProps < RecordType > {
138
121
children : ReactElement ;
139
122
classes ?: ClassesOverride < typeof useStyles > ;
140
123
reference : string ;
@@ -145,6 +128,41 @@ export interface ReferenceFieldProps
145
128
link ?: LinkToType ;
146
129
}
147
130
131
+ /**
132
+ * This intermediate component is made necessary by the useReference hook,
133
+ * which cannot be called conditionally when get(record, source) is empty.
134
+ */
135
+ export const NonEmptyReferenceField : FC < Omit <
136
+ ReferenceFieldProps ,
137
+ 'emptyText'
138
+ > > = ( { children, record, source, ...props } ) => {
139
+ if ( React . Children . count ( children ) !== 1 ) {
140
+ throw new Error ( '<ReferenceField> only accepts a single child' ) ;
141
+ }
142
+ const { basePath, resource } = props ;
143
+ const resourceLinkPath = getResourceLinkPath ( {
144
+ ...props ,
145
+ resource,
146
+ record,
147
+ source,
148
+ basePath,
149
+ } ) ;
150
+ return (
151
+ < ResourceContextProvider value = { props . reference } >
152
+ < PureReferenceFieldView
153
+ { ...props }
154
+ { ...useReference ( {
155
+ reference : props . reference ,
156
+ id : get ( record , source ) ,
157
+ } ) }
158
+ resourceLinkPath = { resourceLinkPath }
159
+ >
160
+ { children }
161
+ </ PureReferenceFieldView >
162
+ </ ResourceContextProvider >
163
+ ) ;
164
+ } ;
165
+
148
166
const useStyles = makeStyles (
149
167
theme => ( {
150
168
link : {
0 commit comments