Skip to content

Commit 2c35dd0

Browse files
committed
feat(carbon): add field array component
1 parent 8ab13af commit 2c35dd0

File tree

3 files changed

+100
-16
lines changed

3 files changed

+100
-16
lines changed

packages/carbon-component-mapper/demo/demo-schemas/widget-schema.js

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ export const arraySchemaDDF = {
1414
name: 'name',
1515
label: 'Name',
1616
placeholder: 'Borek',
17-
isRequired: true,
1817
validate: [
1918
{
2019
type: 'required'
@@ -63,7 +62,6 @@ export const arraySchemaDDF = {
6362
fields: [
6463
{
6564
component: 'text-field',
66-
isRequired: true,
6765
validate: [
6866
{
6967
type: 'required'

packages/carbon-component-mapper/src/files/field-array.js

Lines changed: 80 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,14 @@ import React from 'react';
22
import PropTypes from 'prop-types';
33
import { useFieldApi, useFormApi, FieldArray as FieldArrayFF } from '@data-driven-forms/react-form-renderer';
44

5-
const ArrayItem = ({ remove, fields, name }) => {
5+
import { Button, FormGroup } from 'carbon-components-react';
6+
import { AddAlt32, Subtract32 } from '@carbon/icons-react';
7+
8+
import './field-array.scss';
9+
10+
import prepareProps from '../common/prepare-props';
11+
12+
const ArrayItem = ({ remove, fields, name, removeText, buttonDisabled }) => {
613
const formOptions = useFormApi();
714

815
const editedFields = fields.map((field) => ({
@@ -13,32 +20,91 @@ const ArrayItem = ({ remove, fields, name }) => {
1320
return (
1421
<div>
1522
{formOptions.renderForm(editedFields, formOptions)}
16-
<button onClick={remove}>Remove</button>
23+
<Button
24+
disabled={buttonDisabled}
25+
renderIcon={Subtract32}
26+
id={`remove-${name}`}
27+
kind="danger"
28+
onClick={remove}
29+
className={'ddorg__carbon-field-array-remove'}
30+
>
31+
{removeText}
32+
</Button>
1733
</div>
1834
);
1935
};
2036

2137
ArrayItem.propTypes = {
2238
remove: PropTypes.func,
2339
fields: PropTypes.array,
24-
name: PropTypes.string
40+
name: PropTypes.string,
41+
removeText: PropTypes.node,
42+
buttonDisabled: PropTypes.bool
2543
};
2644

2745
const FieldArray = (props) => {
28-
const { itemDefault, fields, input, arrayValidator } = useFieldApi(props);
46+
const { itemDefault, maxItems, minItems, fields, input, arrayValidator, labelText, buttonLabels, noItemsMessage, meta } = useFieldApi(
47+
prepareProps(props)
48+
);
49+
50+
const buttonLabelsFinal = {
51+
add: 'Add',
52+
remove: 'Remove',
53+
...buttonLabels
54+
};
55+
56+
const invalid = meta.touched && meta.error && !Array.isArray(meta.error);
2957

3058
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>
59+
<FormGroup
60+
legendText={labelText}
61+
invalid={Boolean(invalid)}
62+
message={Boolean(invalid)}
63+
messageText={invalid || ''}
64+
className={'ddorg__carbon-field-array-form-group'}
65+
>
66+
<FieldArrayFF name={input.name} validate={arrayValidator}>
67+
{(fieldArrayProps) => (
68+
<div>
69+
{fieldArrayProps.fields.length === 0 && noItemsMessage}
70+
{fieldArrayProps.fields.map((name, index) => (
71+
<ArrayItem
72+
removeText={buttonLabelsFinal.remove}
73+
key={index}
74+
remove={() => fieldArrayProps.fields.remove(index)}
75+
name={name}
76+
fields={fields}
77+
buttonDisabled={minItems >= fieldArrayProps.fields.length}
78+
/>
79+
))}
80+
<div className={'ddorg__carbon-field-array-add-container'}>
81+
<Button
82+
disabled={fieldArrayProps.fields.length >= maxItems}
83+
renderIcon={AddAlt32}
84+
id={`add-${input.name}`}
85+
onClick={() => fieldArrayProps.fields.push(itemDefault)}
86+
className={'ddorg__carbon-field-array-add'}
87+
>
88+
{buttonLabelsFinal.add}
89+
</Button>
90+
</div>
91+
</div>
92+
)}
93+
</FieldArrayFF>
94+
</FormGroup>
4195
);
4296
};
4397

98+
FieldArray.propTypes = {
99+
noItemsMessage: PropTypes.node,
100+
maxItems: PropTypes.number,
101+
minItems: PropTypes.number
102+
};
103+
104+
FieldArray.defaultProps = {
105+
noItemsMessage: 'No items',
106+
maxItems: Infinity,
107+
minItems: 0
108+
};
109+
44110
export default FieldArray;
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
.ddorg__carbon-field-array-add {
2+
margin-top: 16px;
3+
}
4+
5+
.ddorg__carbon-field-array-add-container {
6+
width: 100%;
7+
display: flex;
8+
flex-direction: row-reverse;
9+
}
10+
11+
.ddorg__carbon-field-array-remove {
12+
margin-top: 8px;
13+
margin-bottom: 8px;
14+
}
15+
16+
.ddorg__carbon-field-array-form-group {
17+
.bx--form__requirements {
18+
color: #da1e28;
19+
}
20+
}

0 commit comments

Comments
 (0)