Skip to content

Commit 2590854

Browse files
rvsiaHyperkid123
authored andcommitted
fix(blueprint): add missing field array component
1 parent f8fabbd commit 2590854

File tree

4 files changed

+549
-4
lines changed

4 files changed

+549
-4
lines changed

packages/blueprint-component-mapper/demo/index.js

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,8 @@ import demoSchema from '@data-driven-forms/common/src/demoschema';
1919
const Summary = (props) => <div>Custom summary component.</div>;
2020

2121
const fieldArrayState = {
22-
schema: wizardSchema,
22+
schema: arraySchemaDDF,
2323
additionalOptions: {
24-
wizard: true,
25-
showFormControls: false,
2624
initialValues: {
2725
number: [1, 2, 3, 4],
2826
minMax: [null, null, null, null]
Lines changed: 144 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,148 @@
1+
import React, { useContext } from 'react';
2+
import PropTypes from 'prop-types';
3+
import clsx from 'clsx';
4+
import { useFieldApi, useFormApi, FieldArray as FieldArrayFF } from '@data-driven-forms/react-form-renderer';
5+
6+
import { Button, Intent, FormGroup } from '@blueprintjs/core';
7+
8+
import BlueprintContext from './blueprint-context';
9+
10+
import './field-array.scss';
11+
12+
const ArrayItem = ({ remove, fields, name, removeLabel, ArrayItemProps, RemoveButtonProps, disabledRemove }) => {
13+
const formOptions = useFormApi();
14+
15+
const editedFields = fields.map((field) => ({
16+
...field,
17+
...(field.name ? { name: `${name}.${field.name}` } : { name })
18+
}));
19+
20+
return (
21+
<div {...ArrayItemProps}>
22+
{formOptions.renderForm(editedFields, formOptions)}
23+
<Button
24+
onClick={remove}
25+
intent={Intent.DANGER}
26+
disabled={disabledRemove}
27+
{...RemoveButtonProps}
28+
className={clsx('ddorg__blueprint_mapper--field-array-remove', RemoveButtonProps && RemoveButtonProps.className)}
29+
>
30+
{removeLabel}
31+
</Button>
32+
</div>
33+
);
34+
};
35+
36+
ArrayItem.propTypes = {
37+
remove: PropTypes.func,
38+
fields: PropTypes.array,
39+
name: PropTypes.string,
40+
removeLabel: PropTypes.node,
41+
ArrayItemProps: PropTypes.object,
42+
RemoveButtonProps: PropTypes.object,
43+
disabledRemove: PropTypes.bool
44+
};
45+
146
const FieldArray = (props) => {
2-
return 'FieldArray';
47+
const {
48+
defaultItem,
49+
fields,
50+
arrayValidator,
51+
label,
52+
description,
53+
buttonLabels,
54+
AddContainerProps,
55+
AddButtonProps,
56+
RemoveButtonProps,
57+
ArrayItemProps,
58+
FieldArrayProps,
59+
noItemsMessage,
60+
validateOnMount,
61+
meta,
62+
helperText,
63+
isRequired,
64+
FormGroupProps,
65+
maxItems,
66+
minItems
67+
} = useFieldApi(props);
68+
69+
const { required } = useContext(BlueprintContext);
70+
71+
const { error, touched } = meta;
72+
const showError = (validateOnMount || touched) && error;
73+
74+
const text = showError ? error : helperText || description;
75+
76+
const intent = showError && error && { intent: Intent.DANGER };
77+
const labelInfo = isRequired && { labelInfo: required };
78+
79+
const combinedLabels = {
80+
add: 'Add',
81+
remove: 'Remove',
82+
...buttonLabels
83+
};
84+
85+
return (
86+
<FormGroup helperText={text} label={label} {...labelInfo} {...FormGroupProps} {...intent}>
87+
<FieldArrayFF name={props.name} validate={arrayValidator}>
88+
{(fieldArrayProps) => (
89+
<div {...FieldArrayProps}>
90+
{fieldArrayProps.fields.length === 0 && noItemsMessage}
91+
{fieldArrayProps.fields.map((name, index) => (
92+
<ArrayItem
93+
key={index}
94+
remove={() => fieldArrayProps.fields.remove(index)}
95+
name={name}
96+
fields={fields}
97+
removeLabel={combinedLabels.remove}
98+
ArrayItemProps={ArrayItemProps}
99+
RemoveButtonProps={RemoveButtonProps}
100+
disabledRemove={fieldArrayProps.fields.length <= minItems}
101+
/>
102+
))}
103+
<div
104+
{...AddContainerProps}
105+
className={clsx('ddorg__blueprint_mapper--field-array-add-container', AddContainerProps && AddContainerProps.className)}
106+
>
107+
<Button
108+
onClick={() => fieldArrayProps.fields.push(defaultItem)}
109+
intent={Intent.SUCCESS}
110+
disabled={fieldArrayProps.fields.length >= maxItems}
111+
{...AddButtonProps}
112+
>
113+
{combinedLabels.add}
114+
</Button>
115+
</div>
116+
</div>
117+
)}
118+
</FieldArrayFF>
119+
</FormGroup>
120+
);
121+
};
122+
123+
FieldArray.propTypes = {
124+
name: PropTypes.string,
125+
defaultItem: PropTypes.any,
126+
fields: PropTypes.array,
127+
label: PropTypes.node,
128+
description: PropTypes.node,
129+
buttonLabels: PropTypes.object,
130+
AddContainerProps: PropTypes.object,
131+
AddButtonProps: PropTypes.object,
132+
RemoveButtonProps: PropTypes.object,
133+
ArrayItemProps: PropTypes.object,
134+
FieldArrayProps: PropTypes.object,
135+
noItemsMessage: PropTypes.node,
136+
validateOnMount: PropTypes.bool,
137+
helperText: PropTypes.node,
138+
isRequired: PropTypes.bool,
139+
FormGroupProps: PropTypes.object,
140+
maxItems: PropTypes.number,
141+
minItems: PropTypes.number
142+
};
143+
144+
FieldArray.defaultProps = {
145+
noItemsMessage: 'No items'
3146
};
4147

5148
export default FieldArray;
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
.ddorg__blueprint_mapper--field-array-add-container {
2+
display: flex;
3+
flex-flow: row-reverse;
4+
margin-bottom: 15px;
5+
}
6+
7+
.ddorg__blueprint_mapper--field-array-remove {
8+
margin-bottom: 15px;
9+
}

0 commit comments

Comments
 (0)