Skip to content

Commit e5b0dec

Browse files
authored
Improve React Vanilla Array Control rendering
Replaces the array control fieldset rendering with a div/header section similar to the array table control. Signed-off-by: Ralph Soika <[email protected]>
1 parent 73142a3 commit e5b0dec

File tree

3 files changed

+70
-34
lines changed

3 files changed

+70
-34
lines changed

packages/vanilla/example/example.css

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -406,12 +406,12 @@ jsonforms-tree>dialog>.content {
406406
border-bottom: none;
407407
}
408408

409-
.array-table-layout.control>header {
409+
.array-table-layout.control>header, .array-control-layout.control>header {
410410
display: flex;
411411
margin: 0.25em;
412412
}
413413

414-
.array-table-layout header label {
414+
.array-table-layout header label, .array-control-layout header label {
415415
flex: 1;
416416
font-weight: bold;
417417
}
@@ -447,4 +447,11 @@ jsonforms-tree>dialog>.content {
447447

448448
.array-table-layout td>* {
449449
flex: 1;
450-
}
450+
}
451+
.array-control-layout .children>div {
452+
border-top: 1px solid var(--jsf-border-color);
453+
padding-top: 10px;
454+
}
455+
456+
457+

packages/vanilla/src/complex/array/ArrayControl.tsx

Lines changed: 48 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -24,58 +24,75 @@
2424
*/
2525
import range from 'lodash/range';
2626
import React, { useMemo } from 'react';
27-
import { ArrayControlProps, composePaths, createDefaultValue, findUISchema } from '@jsonforms/core';
27+
import { ArrayControlProps, composePaths, createDefaultValue, findUISchema, Helpers, ControlElement } from '@jsonforms/core';
2828
import { JsonFormsDispatch } from '@jsonforms/react';
2929
import { VanillaRendererProps } from '../../index';
3030

31+
const { convertToValidClassName } = Helpers;
32+
3133
export const ArrayControl = ({
3234
classNames,
3335
data,
3436
label,
3537
path,
3638
schema,
39+
errors,
3740
addItem,
3841
uischema,
3942
uischemas,
43+
getStyleAsClassName,
4044
renderers,
4145
rootSchema
4246
}: ArrayControlProps & VanillaRendererProps) => {
47+
48+
const controlElement = uischema as ControlElement;
4349
const childUiSchema = useMemo(
4450
() => findUISchema(uischemas, schema, uischema.scope, path, undefined, uischema, rootSchema),
4551
[uischemas, schema, uischema.scope, path, uischema, rootSchema]
4652
);
53+
const isValid = errors.length === 0;
54+
const validationClass = getStyleAsClassName('array.control.validation');
55+
const divClassNames = [validationClass]
56+
.concat(isValid ? '' : getStyleAsClassName('array.control.validation.error'))
57+
.join(' ');
58+
const buttonClass = getStyleAsClassName('array.control.button');
59+
const labelClass = getStyleAsClassName('array.control.label');
60+
const controlClass = [
61+
getStyleAsClassName('array.control'),
62+
convertToValidClassName(controlElement.scope)
63+
].join(' ');
64+
4765
return (
48-
<div className={classNames.wrapper}>
49-
<fieldset className={classNames.fieldSet}>
50-
<legend>
51-
<button
52-
className={classNames.button}
66+
<div className={controlClass}>
67+
<header>
68+
<label className={labelClass}>{label}</label>
69+
<button
70+
className={buttonClass}
5371
onClick={addItem(path, createDefaultValue(schema))}
54-
>
55-
+
56-
</button>
57-
<label className={'array.label'}>{label}</label>
58-
</legend>
59-
<div className={classNames.children}>
60-
{data ? (
61-
range(0, data.length).map(index => {
62-
const childPath = composePaths(path, `${index}`);
63-
64-
return (
65-
<JsonFormsDispatch
66-
schema={schema}
67-
uischema={childUiSchema || uischema}
68-
path={childPath}
69-
key={childPath}
70-
renderers={renderers}
71-
/>
72-
);
73-
})
74-
) : (
75-
<p>No data</p>
76-
)}
77-
</div>
78-
</fieldset>
72+
>Add to {label}
73+
</button>
74+
</header>
75+
<div className={divClassNames}>
76+
{errors}
77+
</div>
78+
<div className={classNames.children}>
79+
{data ? (
80+
range(0, data.length).map(index => {
81+
const childPath = composePaths(path, `${index}`);
82+
return (
83+
<JsonFormsDispatch
84+
schema={schema}
85+
uischema={childUiSchema || uischema}
86+
path={childPath}
87+
key={childPath}
88+
renderers={renderers}
89+
/>
90+
);
91+
})
92+
) : (
93+
<p>No data</p>
94+
)}
95+
</div>
7996
</div>
8097
);
8198
};

packages/vanilla/src/styles/styles.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,18 @@ export const vanillaStyles: StyleDef[] = [
137137
name: 'array.table',
138138
classNames: ['array-table-layout', 'control']
139139
},
140+
{
141+
name: 'array.control.validation.error',
142+
classNames: ['validation_error']
143+
},
144+
{
145+
name: 'array.control.validation',
146+
classNames: ['validation']
147+
},
148+
{
149+
name: 'array.control',
150+
classNames: ['array-control-layout', 'control']
151+
},
140152
{
141153
name: 'input.description',
142154
classNames: ['input-description']

0 commit comments

Comments
 (0)