1- import {
2- ArrayInputContext ,
3- FieldTitle ,
4- InputProps ,
5- OptionalResourceContextProvider ,
6- SourceContextProvider ,
7- type SourceContextValue ,
8- composeSyncValidators ,
9- isRequired ,
10- useApplyInputDefaultValues ,
11- useFormGroupContext ,
12- useFormGroups ,
13- useGetValidationErrorMessage ,
14- useSourceContext ,
15- } from '../' ;
161import * as React from 'react' ;
17- import { useEffect } from 'react' ;
18- import { useFieldArray , useFormContext } from 'react-hook-form' ;
2+ import { isRequired } from '../form/validation/validate' ;
3+ import { InputProps } from '../form/useInput' ;
4+ import { FieldTitle } from '../util/FieldTitle' ;
5+ import { ArrayInputBase } from '../controller/input/ArrayInputBase' ;
196
207export const ArrayInput = ( props : ArrayInputProps ) => {
218 const {
22- defaultValue = [ ] ,
239 label,
24- isPending,
2510 children,
2611 resource : resourceFromProps ,
2712 source : arraySource ,
2813 validate,
2914 } = props ;
3015
31- const formGroupName = useFormGroupContext ( ) ;
32- const formGroups = useFormGroups ( ) ;
33- const parentSourceContext = useSourceContext ( ) ;
34- const finalSource = parentSourceContext . getSource ( arraySource ) ;
35-
36- const sanitizedValidate = Array . isArray ( validate )
37- ? composeSyncValidators ( validate )
38- : validate ;
39- const getValidationErrorMessage = useGetValidationErrorMessage ( ) ;
40-
41- const { getValues } = useFormContext ( ) ;
42-
43- const fieldProps = useFieldArray ( {
44- name : finalSource ,
45- rules : {
46- validate : async value => {
47- if ( ! sanitizedValidate ) return true ;
48- const error = await sanitizedValidate (
49- value ,
50- getValues ( ) ,
51- props
52- ) ;
53-
54- if ( ! error ) return true ;
55- return getValidationErrorMessage ( error ) ;
56- } ,
57- } ,
58- } ) ;
59-
60- useEffect ( ( ) => {
61- if ( formGroups && formGroupName != null ) {
62- formGroups . registerField ( finalSource , formGroupName ) ;
63- }
64-
65- return ( ) => {
66- if ( formGroups && formGroupName != null ) {
67- formGroups . unregisterField ( finalSource , formGroupName ) ;
68- }
69- } ;
70- } , [ finalSource , formGroups , formGroupName ] ) ;
71-
72- useApplyInputDefaultValues ( {
73- inputProps : { ...props , defaultValue } ,
74- isArrayInput : true ,
75- fieldArrayInputControl : fieldProps ,
76- } ) ;
77-
78- // The SourceContext will be read by children of ArrayInput to compute their composed source and label
79- //
80- // <ArrayInput source="orders" /> => SourceContext is "orders"
81- // <SimpleFormIterator> => SourceContext is "orders.0"
82- // <DateInput source="date" /> => final source for this input will be "orders.0.date"
83- // </SimpleFormIterator>
84- // </ArrayInput>
85- //
86- const sourceContext = React . useMemo < SourceContextValue > (
87- ( ) => ( {
88- // source is the source of the ArrayInput child
89- getSource : ( source : string ) => {
90- if ( ! source ) {
91- // SimpleFormIterator calls getSource('') to get the arraySource
92- return parentSourceContext . getSource ( arraySource ) ;
93- }
94-
95- // We want to support nesting and composition with other inputs (e.g. TranslatableInputs, ReferenceOneInput, etc),
96- // we must also take into account the parent SourceContext
97- //
98- // <ArrayInput source="orders" /> => SourceContext is "orders"
99- // <SimpleFormIterator> => SourceContext is "orders.0"
100- // <DateInput source="date" /> => final source for this input will be "orders.0.date"
101- // <ArrayInput source="items" /> => SourceContext is "orders.0.items"
102- // <SimpleFormIterator> => SourceContext is "orders.0.items.0"
103- // <TextInput source="reference" /> => final source for this input will be "orders.0.items.0.reference"
104- // </SimpleFormIterator>
105- // </ArrayInput>
106- // </SimpleFormIterator>
107- // </ArrayInput>
108- return parentSourceContext . getSource (
109- `${ arraySource } .${ source } `
110- ) ;
111- } ,
112- // if Array source is items, and child source is name, .0.name => resources.orders.fields.items.name
113- getLabel : ( source : string ) =>
114- parentSourceContext . getLabel ( `${ arraySource } .${ source } ` ) ,
115- } ) ,
116- [ parentSourceContext , arraySource ]
117- ) ;
118-
119- if ( isPending ) {
120- return null ;
121- }
122-
12316 return (
12417 < div >
12518 < div >
@@ -130,13 +23,7 @@ export const ArrayInput = (props: ArrayInputProps) => {
13023 isRequired = { isRequired ( validate ) }
13124 />
13225 </ div >
133- < ArrayInputContext . Provider value = { fieldProps } >
134- < OptionalResourceContextProvider value = { resourceFromProps } >
135- < SourceContextProvider value = { sourceContext } >
136- { children }
137- </ SourceContextProvider >
138- </ OptionalResourceContextProvider >
139- </ ArrayInputContext . Provider >
26+ < ArrayInputBase { ...props } > { children } </ ArrayInputBase >
14027 </ div >
14128 ) ;
14229} ;
0 commit comments