Stack: [React + MUI5 + JsonForms]
Hello!
I’m trying to wrap every form element in a custom component while maintaining the use of Material-UI renderers. In this process, I developed a custom renderer, but I’m facing issues where Material-UI styles and certain properties, such as labels from the UI schema, are not being applied as expected. Is there a specialized component, like MaterialDispatch
, that I should be using instead?
Additionally, I attempted to replace Dispatch component with JsonFormsDispatch, but it led to the app freezing without throwing any errors.
Here is the snippet which utilizes schema and UI schema from the JsonForms documentation.
In order to compare the behavior with&without the custom render, remove WrapperRenderer from renderers array prop
Could you help me out with a solution or point me to the right docs?
import { ControlProps, isControl, rankWith } from '@jsonforms/core';
import {
materialCells,
materialRenderers,
} from '@jsonforms/material-renderers';
import {
Dispatch,
JsonForms,
withJsonFormsControlProps,
} from '@jsonforms/react';
import { FunctionComponent, useState } from 'react';
const CustomWrapper: FunctionComponent<ControlProps> = (props) => (
<div>
some wrapping view
<Dispatch {...props} />
</div>
);
const wrapperTester = rankWith(3, isControl);
export const WrapperRenderer = {
tester: wrapperTester,
renderer: withJsonFormsControlProps(CustomWrapper),
};
export const Poc: FunctionComponent = () => {
const [data, setData] = useState({});
return (
<JsonForms
schema={schema}
uischema={uiSchema}
data={data}
renderers={[...materialRenderers, WrapperRenderer]}
cells={materialCells}
onChange={({ data }) => setData(data)}
/>
);
};
const schema = {
type: 'object',
properties: {
name: {
type: 'string',
minLength: 3,
description: 'Please enter your name',
},
vegetarian: {
type: 'boolean',
},
birthDate: {
type: 'string',
format: 'date',
},
nationality: {
type: 'string',
enum: ['DE', 'IT', 'JP', 'US', 'RU', 'Other'],
},
personalData: {
type: 'object',
properties: {
age: {
type: 'integer',
description: 'Please enter your age.',
},
height: {
type: 'number',
},
drivingSkill: {
type: 'number',
maximum: 10,
minimum: 1,
default: 7,
},
},
required: ['age', 'height'],
},
occupation: {
type: 'string',
},
postalCode: {
type: 'string',
maxLength: 5,
},
},
required: ['occupation', 'nationality'],
};
const uiSchema = {
type: 'VerticalLayout',
elements: [
{
type: 'HorizontalLayout',
elements: [
{
type: 'Control',
scope: '#/properties/name',
},
{
type: 'Control',
scope: '#/properties/personalData/properties/age',
},
{
type: 'Control',
scope: '#/properties/birthDate',
},
],
},
{
type: 'Label',
text: 'Additional Information',
},
{
type: 'HorizontalLayout',
elements: [
{
type: 'Control',
scope: '#/properties/personalData/properties/height',
},
{
type: 'Control',
scope: '#/properties/nationality',
},
{
type: 'Control',
scope: '#/properties/occupation',
suggestion: [
'Accountant',
'Engineer',
'Freelancer',
'Journalism',
'Physician',
'Student',
'Teacher',
'Other',
],
},
],
},
],
};
export default WrapperRenderer;