8
8
useEffect ,
9
9
FC ,
10
10
ReactElement ,
11
+ useMemo ,
11
12
} from 'react' ;
12
13
import PropTypes from 'prop-types' ;
13
14
import {
@@ -34,6 +35,7 @@ import DatagridLoading from './DatagridLoading';
34
35
import DatagridBody , { PureDatagridBody } from './DatagridBody' ;
35
36
import useDatagridStyles from './useDatagridStyles' ;
36
37
import { ClassesOverride } from '../../types' ;
38
+ import DatagridContextProvider from './DatagridContextProvider' ;
37
39
38
40
/**
39
41
* The Datagrid component renders a list of records as a table.
@@ -116,6 +118,7 @@ const Datagrid: FC<DatagridProps> = React.forwardRef((props, ref) => {
116
118
hasBulkActions = false ,
117
119
hover,
118
120
isRowSelectable,
121
+ isRowExpandable,
119
122
resource,
120
123
rowClick,
121
124
rowStyle,
@@ -137,6 +140,10 @@ const Datagrid: FC<DatagridProps> = React.forwardRef((props, ref) => {
137
140
} = useListContext ( props ) ;
138
141
const version = useVersion ( ) ;
139
142
143
+ const contextValue = useMemo ( ( ) => ( { isRowExpandable } ) , [
144
+ isRowExpandable ,
145
+ ] ) ;
146
+
140
147
const updateSort = useCallback (
141
148
event => {
142
149
event . stopPropagation ( ) ;
@@ -246,83 +253,87 @@ const Datagrid: FC<DatagridProps> = React.forwardRef((props, ref) => {
246
253
* the datagrid displays the current data.
247
254
*/
248
255
return (
249
- < Table
250
- ref = { ref }
251
- className = { classnames ( classes . table , className ) }
252
- size = { size }
253
- { ...sanitizeListRestProps ( rest ) }
254
- >
255
- < TableHead className = { classes . thead } >
256
- < TableRow
257
- className = { classnames ( classes . row , classes . headerRow ) }
258
- >
259
- { expand && (
260
- < TableCell
261
- padding = "none"
262
- className = { classnames (
263
- classes . headerCell ,
264
- classes . expandHeader
265
- ) }
266
- />
267
- ) }
268
- { hasBulkActions && (
269
- < TableCell
270
- padding = "checkbox"
271
- className = { classes . headerCell }
272
- >
273
- < Checkbox
274
- className = "select-all"
275
- color = "primary"
276
- checked = {
277
- selectedIds . length > 0 &&
278
- all . length > 0 &&
279
- all . every ( id => selectedIds . includes ( id ) )
280
- }
281
- onChange = { handleSelectAll }
256
+ < DatagridContextProvider value = { contextValue } >
257
+ < Table
258
+ ref = { ref }
259
+ className = { classnames ( classes . table , className ) }
260
+ size = { size }
261
+ { ...sanitizeListRestProps ( rest ) }
262
+ >
263
+ < TableHead className = { classes . thead } >
264
+ < TableRow
265
+ className = { classnames ( classes . row , classes . headerRow ) }
266
+ >
267
+ { expand && (
268
+ < TableCell
269
+ padding = "none"
270
+ className = { classnames (
271
+ classes . headerCell ,
272
+ classes . expandHeader
273
+ ) }
282
274
/>
283
- </ TableCell >
284
- ) }
285
- { Children . map ( children , ( field , index ) =>
286
- isValidElement ( field ) ? (
287
- < DatagridHeaderCell
275
+ ) }
276
+ { hasBulkActions && (
277
+ < TableCell
278
+ padding = "checkbox"
288
279
className = { classes . headerCell }
289
- currentSort = { currentSort }
290
- field = { field }
291
- isSorting = {
292
- currentSort . field ===
293
- ( ( field . props as any ) . sortBy ||
294
- ( field . props as any ) . source )
295
- }
296
- key = { ( field . props as any ) . source || index }
297
- resource = { resource }
298
- updateSort = { updateSort }
299
- />
300
- ) : null
301
- ) }
302
- </ TableRow >
303
- </ TableHead >
304
- { cloneElement (
305
- body ,
306
- {
307
- basePath,
308
- className : classes . tbody ,
309
- classes,
310
- expand,
311
- rowClick,
312
- data,
313
- hasBulkActions,
314
- hover,
315
- ids,
316
- onToggleItem : handleToggleItem ,
317
- resource,
318
- rowStyle,
319
- selectedIds,
320
- isRowSelectable,
321
- version,
322
- } ,
323
- children
324
- ) }
325
- </ Table >
280
+ >
281
+ < Checkbox
282
+ className = "select-all"
283
+ color = "primary"
284
+ checked = {
285
+ selectedIds . length > 0 &&
286
+ all . length > 0 &&
287
+ all . every ( id =>
288
+ selectedIds . includes ( id )
289
+ )
290
+ }
291
+ onChange = { handleSelectAll }
292
+ />
293
+ </ TableCell >
294
+ ) }
295
+ { Children . map ( children , ( field , index ) =>
296
+ isValidElement ( field ) ? (
297
+ < DatagridHeaderCell
298
+ className = { classes . headerCell }
299
+ currentSort = { currentSort }
300
+ field = { field }
301
+ isSorting = {
302
+ currentSort . field ===
303
+ ( ( field . props as any ) . sortBy ||
304
+ ( field . props as any ) . source )
305
+ }
306
+ key = { ( field . props as any ) . source || index }
307
+ resource = { resource }
308
+ updateSort = { updateSort }
309
+ />
310
+ ) : null
311
+ ) }
312
+ </ TableRow >
313
+ </ TableHead >
314
+ { cloneElement (
315
+ body ,
316
+ {
317
+ basePath,
318
+ className : classes . tbody ,
319
+ classes,
320
+ expand,
321
+ rowClick,
322
+ data,
323
+ hasBulkActions,
324
+ hover,
325
+ ids,
326
+ onToggleItem : handleToggleItem ,
327
+ resource,
328
+ rowStyle,
329
+ selectedIds,
330
+ isRowSelectable,
331
+ version,
332
+ } ,
333
+ children
334
+ ) }
335
+ </ Table >
336
+ </ DatagridContextProvider >
326
337
) ;
327
338
} ) ;
328
339
@@ -353,6 +364,7 @@ Datagrid.propTypes = {
353
364
total : PropTypes . number ,
354
365
version : PropTypes . number ,
355
366
isRowSelectable : PropTypes . func ,
367
+ isRowExpandable : PropTypes . func ,
356
368
} ;
357
369
358
370
type RowClickFunction = (
@@ -376,6 +388,7 @@ export interface DatagridProps extends Omit<TableProps, 'size' | 'classes'> {
376
388
hasBulkActions ?: boolean ;
377
389
hover ?: boolean ;
378
390
isRowSelectable ?: ( record : Record ) => boolean ;
391
+ isRowExpandable ?: ( record : Record ) => boolean ;
379
392
optimized ?: boolean ;
380
393
rowClick ?: string | RowClickFunction ;
381
394
rowStyle ?: ( record : Record , index : number ) => any ;
0 commit comments