import * as React from 'react' ; import { ReactElement , useMemo } from 'react' ; import PropTypes from 'prop-types' ; import { getFieldLabelTranslationArgs , InputProps , useReferenceArrayInputController , useInput , useTranslate , SortPayload , PaginationPayload , Translate , ResourceContextProvider , ReferenceArrayInputContextProvider , ListContextProvider , } from 'ra-core' ; import sanitizeInputRestProps from './sanitizeInputRestProps' ; import ReferenceError from './ReferenceError' ; import { FieldInputProps , FieldMetaState } from 'react-final-form' ; export interface ReferenceArrayInputProps extends InputProps { allowEmpty ? : boolean ; basePath ? : string ; children : ReactElement ; classes ? : any ; className ? : string ; label ? : string ; reference : string ; resource ? : string ; enableGetChoices ? : ( filters : any ) => boolean ; [ key ] : any ; } example example example example example example const ReferenceArrayInput = ( { children , id : idOverride , onBlur , onChange , onFocus , validate , parse , format , ... props } ) => { if ( React . Children . count ( children ) !== 1 ) { throw new Error ( '<ReferenceArrayInput> only accepts a single child (like <Datagrid>)' ) ; } const { id , input , isRequired , meta } = useInput ( { id : idOverride , onBlur , onChange , onFocus , source : props . source , validate , parse , format , ... props , } ) ; const controllerProps = useReferenceArrayInputController ( { ... props , input , } ) ; const listContext = useMemo ( ( ) => ( { ... controllerProps , setSort : controllerProps . setSortForList , } ) , [ controllerProps ] ) ; const translate = useTranslate ( ) ; return ( < ResourceContextProvider value = { props . reference } > < ReferenceArrayInputContextProvider value = { controllerProps } > < ListContextProvider value = { listContext } > < ReferenceArrayInputView id = { id } input = { input } isRequired = { isRequired } meta = { meta } translate = { translate } children = { children } { ... props } choices = { controllerProps . choices } loaded = { controllerProps . loaded } loading = { controllerProps . loading } setFilter = { controllerProps . setFilter } setPagination = { controllerProps . setPagination } setSort = { controllerProps . setSort } / > < /ListContextProvider> < /ReferenceArrayInputContextProvider> < /ResourceContextProvider>); } ; ReferenceArrayInput . propTypes = { allowEmpty : PropTypes . bool , basePath : PropTypes . string , children : PropTypes . element . isRequired , className : PropTypes . string , filter : PropTypes . object , filterToQuery : PropTypes . func . isRequired , label : PropTypes . string , perPage : PropTypes . number , reference : PropTypes . string . isRequired , resource : PropTypes . string , sort : PropTypes . shape ( { field : PropTypes . string , order : PropTypes . oneOf ( [ 'ASC' , 'DESC' ] ) , } ) , source : PropTypes . string , } ; ReferenceArrayInput . defaultProps = { filter : { } , filterToQuery : searchText => ( searchText ? { q : searchText } : { } ) , perPage : 25 , sort : { field : 'id' , order : 'DESC' } , } ; const sanitizeRestProps = ( { basePath , crudGetMany , crudGetMatching , filterToQuery , perPage , reference , referenceSource , resource , ... rest } ) => sanitizeInputRestProps ( rest ) ; export interface ReferenceArrayInputViewProps { allowEmpty ? : boolean ; basePath ? : string ; children : ReactElement ; choices : any [ ] ; classes ? : object ; className ? : string ; error ? : string ; helperText ? : string | boolean ; id : string ; input : FieldInputProps < any , HTMLElement > ; isRequired : boolean ; label ? : string ; loaded : boolean ; loading : boolean ; meta : FieldMetaState < any > ; onChange : any ; options ? : any ; reference : string ; resource ? : string ; setFilter : ( v : string ) => void ; setPagination : ( pagination : PaginationPayload ) => void ; setSort : ( sort : SortPayload , order ? : string ) => void ; source : string ; translate : Translate ; warning ? : string ; } export const ReferenceArrayInputView = ( { allowEmpty , basePath , children , choices , className , error , input , loaded , loading , isRequired , label , meta , onChange , options , reference , resource , setFilter , setPagination , setSort , source , translate , warning , ... rest } ) => { const translatedLabel = translate ( ... getFieldLabelTranslationArgs ( { label , resource , source , } ) ) ; if ( error ) { return < ReferenceError label = { translatedLabel } error = { error } / > ; } return React . cloneElement ( children , { allowEmpty , basePath : basePath ? basePath . replace ( resource , reference ) : `/${ reference }` , choices , className , error , input , isRequired , label : translatedLabel , loaded , loading , meta : { ... meta , helperText : warning || false , } , onChange , options , resource : reference , setFilter , setPagination , setSort , source , translateChoice : false , limitChoicesToValue : true , ... sanitizeRestProps ( rest ) , ... children . props , } ) ; } ; ReferenceArrayInputView . propTypes = { allowEmpty : PropTypes . bool , basePath : PropTypes . string , children : PropTypes . element , choices : PropTypes . array , className : PropTypes . string , error : PropTypes . string , loading : PropTypes . bool , input : PropTypes . object . isRequired , label : PropTypes . string , meta : PropTypes . object , onChange : PropTypes . func , options : PropTypes . object , resource : PropTypes . string , setFilter : PropTypes . func , setPagination : PropTypes . func , setSort : PropTypes . func , source : PropTypes . string , translate : PropTypes . func . isRequired , warning : PropTypes . string , } ; export default ReferenceArrayInput ;