11import React from 'react' ;
22import PropTypes from 'prop-types' ;
3+ import clsx from 'clsx' ;
4+
35import { useFieldApi , useFormApi , FieldArray as FieldArrayFF } from '@data-driven-forms/react-form-renderer' ;
46
5- const ArrayItem = ( { remove, fields, name } ) => {
7+ import { Button , FormGroup } from 'carbon-components-react' ;
8+ import { AddAlt32 , Subtract32 } from '@carbon/icons-react' ;
9+
10+ import './field-array.scss' ;
11+
12+ import prepareProps from '../common/prepare-props' ;
13+
14+ const ArrayItem = ( { remove, fields, name, removeText, buttonDisabled, RemoveButtonProps, ArrayItemProps } ) => {
615 const formOptions = useFormApi ( ) ;
716
817 const editedFields = fields . map ( ( field ) => ( {
@@ -11,34 +20,138 @@ const ArrayItem = ({ remove, fields, name }) => {
1120 } ) ) ;
1221
1322 return (
14- < div >
23+ < div { ... ArrayItemProps } >
1524 { formOptions . renderForm ( editedFields , formOptions ) }
16- < button onClick = { remove } > Remove</ button >
25+ < Button
26+ disabled = { buttonDisabled }
27+ renderIcon = { Subtract32 }
28+ id = { `remove-${ name } ` }
29+ kind = "danger"
30+ onClick = { remove }
31+ { ...RemoveButtonProps }
32+ className = { clsx ( 'ddorg__carbon-field-array-remove' , RemoveButtonProps . className ) }
33+ >
34+ { removeText }
35+ </ Button >
1736 </ div >
1837 ) ;
1938} ;
2039
2140ArrayItem . propTypes = {
2241 remove : PropTypes . func ,
2342 fields : PropTypes . array ,
24- name : PropTypes . string
43+ name : PropTypes . string ,
44+ removeText : PropTypes . node ,
45+ buttonDisabled : PropTypes . bool ,
46+ RemoveButtonProps : PropTypes . object ,
47+ ArrayItemProps : PropTypes . object
48+ } ;
49+
50+ ArrayItem . defaultProps = {
51+ RemoveButtonProps : { } ,
52+ ArrayItemProps : { }
2553} ;
2654
2755const FieldArray = ( props ) => {
28- const { itemDefault, fields, input, arrayValidator } = useFieldApi ( props ) ;
56+ const {
57+ AddContainerProps,
58+ AddButtonProps,
59+ FormGroupProps,
60+ WrapperProps,
61+ ArrayItemProps,
62+ RemoveButtonProps,
63+ defaultItem,
64+ maxItems,
65+ minItems,
66+ fields,
67+ input,
68+ arrayValidator,
69+ labelText,
70+ buttonLabels,
71+ noItemsMessage,
72+ meta
73+ } = useFieldApi ( prepareProps ( props ) ) ;
74+
75+ const buttonLabelsFinal = {
76+ add : 'Add' ,
77+ remove : 'Remove' ,
78+ ...buttonLabels
79+ } ;
80+
81+ const invalid = meta . touched && ! Array . isArray ( meta . error ) && meta . error ;
2982
3083 return (
31- < FieldArrayFF name = { input . name } validate = { arrayValidator } >
32- { ( fieldArrayProps ) => (
33- < div >
34- { fieldArrayProps . fields . map ( ( name , index ) => (
35- < ArrayItem key = { index } remove = { ( ) => fieldArrayProps . fields . remove ( index ) } name = { name } fields = { fields } />
36- ) ) }
37- < button onClick = { ( ) => fieldArrayProps . fields . push ( itemDefault ) } > Add</ button >
38- </ div >
39- ) }
40- </ FieldArrayFF >
84+ < FormGroup
85+ legendText = { labelText || '' }
86+ invalid = { Boolean ( invalid ) }
87+ message = { Boolean ( invalid ) }
88+ messageText = { invalid || '' }
89+ { ...FormGroupProps }
90+ className = { clsx ( 'ddorg__carbon-field-array-form-group' , FormGroupProps . className ) }
91+ >
92+ < FieldArrayFF name = { input . name } validate = { arrayValidator } >
93+ { ( fieldArrayProps ) => (
94+ < div { ...WrapperProps } >
95+ { fieldArrayProps . fields . length === 0 && noItemsMessage }
96+ { fieldArrayProps . fields . map ( ( name , index ) => (
97+ < ArrayItem
98+ removeText = { buttonLabelsFinal . remove }
99+ key = { index }
100+ remove = { ( ) => fieldArrayProps . fields . remove ( index ) }
101+ name = { name }
102+ fields = { fields }
103+ buttonDisabled = { minItems >= fieldArrayProps . fields . length }
104+ ArrayItemProps = { ArrayItemProps }
105+ RemoveButtonProps = { RemoveButtonProps }
106+ />
107+ ) ) }
108+ < div { ...AddContainerProps } className = { clsx ( 'ddorg__carbon-field-array-add-container' , AddContainerProps . className ) } >
109+ < Button
110+ disabled = { fieldArrayProps . fields . length >= maxItems }
111+ renderIcon = { AddAlt32 }
112+ id = { `add-${ input . name } ` }
113+ onClick = { ( ) => fieldArrayProps . fields . push ( defaultItem ) }
114+ { ...AddButtonProps }
115+ className = { clsx ( 'ddorg__carbon-field-array-add' , AddButtonProps . className ) }
116+ >
117+ { buttonLabelsFinal . add }
118+ </ Button >
119+ </ div >
120+ </ div >
121+ ) }
122+ </ FieldArrayFF >
123+ </ FormGroup >
41124 ) ;
42125} ;
43126
127+ FieldArray . propTypes = {
128+ noItemsMessage : PropTypes . node ,
129+ maxItems : PropTypes . number ,
130+ minItems : PropTypes . number ,
131+ buttonLabels : PropTypes . shape ( {
132+ add : PropTypes . node ,
133+ remove : PropTypes . node
134+ } ) ,
135+ AddContainerProps : PropTypes . object ,
136+ AddButtonProps : PropTypes . object ,
137+ FormGroupProps : PropTypes . object ,
138+ WrapperProps : PropTypes . object ,
139+ ArrayItemProps : PropTypes . object ,
140+ RemoveButtonProps : PropTypes . object ,
141+ defaultItem : PropTypes . any ,
142+ fields : PropTypes . array
143+ } ;
144+
145+ FieldArray . defaultProps = {
146+ noItemsMessage : 'No items' ,
147+ maxItems : Infinity ,
148+ minItems : 0 ,
149+ AddContainerProps : { } ,
150+ AddButtonProps : { } ,
151+ FormGroupProps : { } ,
152+ WrapperProps : { } ,
153+ ArrayItemProps : { } ,
154+ RemoveButtonProps : { }
155+ } ;
156+
44157export default FieldArray ;
0 commit comments