1
1
import React from 'react' ;
2
2
import PropTypes from 'prop-types' ;
3
+ import clsx from 'clsx' ;
4
+
3
5
import { useFieldApi , useFormApi , FieldArray as FieldArrayFF } from '@data-driven-forms/react-form-renderer' ;
4
6
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 } ) => {
6
15
const formOptions = useFormApi ( ) ;
7
16
8
17
const editedFields = fields . map ( ( field ) => ( {
@@ -11,34 +20,138 @@ const ArrayItem = ({ remove, fields, name }) => {
11
20
} ) ) ;
12
21
13
22
return (
14
- < div >
23
+ < div { ... ArrayItemProps } >
15
24
{ 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 >
17
36
</ div >
18
37
) ;
19
38
} ;
20
39
21
40
ArrayItem . propTypes = {
22
41
remove : PropTypes . func ,
23
42
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 : { }
25
53
} ;
26
54
27
55
const 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 ;
29
82
30
83
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 >
41
124
) ;
42
125
} ;
43
126
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
+
44
157
export default FieldArray ;
0 commit comments