import * as React from 'react' ; import { cloneElement , Children , ReactElement } from 'react' ; import PropTypes from 'prop-types' ; import { isRequired , FieldTitle , composeSyncValidators , InputProps , } from 'ra-core' ; import { useFieldArray } from 'react-final-form-arrays' ; import { InputLabel , FormControl , FormHelperText } from '@material-ui/core' ; import { LinearProgress } from '../../layout' ; import InputHelperText from '../InputHelperText' ; import sanitizeInputRestProps from '../sanitizeInputRestProps' ; import Labeled from '../Labeled' ; import { ArrayInputContext } from './ArrayInputContext' ; example see https export const ArrayInput = ( props ) => { const { className , defaultValue , label , loaded , loading , children , helperText , record , resource , source , validate , variant , disabled , margin = 'dense' , ... rest } = props ; const sanitizedValidate = Array . isArray ( validate ) ? composeSyncValidators ( validate ) : validate ; const fieldProps = useFieldArray ( source , { initialValue : defaultValue , validate : sanitizedValidate , ... rest , } ) ; if ( loading ) { return ( < Labeled label = { label } source = { source } resource = { resource } className = { className } margin = { margin } > < LinearProgress /> < /Labeled>); } const { error , submitError , touched , dirty } = fieldProps . meta ; const arrayInputError = getArrayInputError ( error || submitError ) ; return ( < FormControl fullWidth margin = "normal" className = { className } error = { ( touched || dirty ) && ! ! arrayInputError } { ... sanitizeInputRestProps ( rest ) } > < InputLabel htmlFor = { source } shrink error = { ( touched || dirty ) && ! ! arrayInputError } > < FieldTitle label = { label } source = { source } resource = { resource } isRequired = { isRequired ( validate ) } / > < /InputLabel> < ArrayInputContext . Provider value = { fieldProps } > { cloneElement ( Children . only ( children ) , { ... fieldProps , record , resource , source , variant , margin , disabled , } ) } < /ArrayInputContext.Provider> { ! ! ( ( touched || dirty ) && arrayInputError ) || helperText ? ( < FormHelperText error = { ( touched || dirty ) && ! ! arrayInputError } > < InputHelperText touched = { touched || dirty } error = { arrayInputError } helperText = { helperText } / > < /FormHelperText>) : null} < /FormControl>); } ; ArrayInput . propTypes = { children : PropTypes . node , className : PropTypes . string , defaultValue : PropTypes . any , isRequired : PropTypes . bool , label : PropTypes . oneOfType ( [ PropTypes . string , PropTypes . bool ] ) , helperText : PropTypes . string , resource : PropTypes . string , source : PropTypes . string , record : PropTypes . object , options : PropTypes . object , validate : PropTypes . oneOfType ( [ PropTypes . func , PropTypes . arrayOf ( PropTypes . func ) , ] ) , } ; ArrayInput . defaultProps = { options : { } , fullWidth : true , } ; export const getArrayInputError = error => { if ( Array . isArray ( error ) ) { return undefined ; } return error ; } ; export interface ArrayInputProps extends InputProps { children : ReactElement ; disabled ? : boolean ; }