Using mui input fields like TextField, Select, Radio button to create custom renderers?

Can I create custom renderers using mui input fields like TextField (React Text Field component - Material UI), Select, Radio button?

And also, can I use one custom renderer for multiple fields like if there’s a schema as follows


{
  "type": "object",
  "properties": {
    "name": {
      "type": "string",
      "minLength": 1
    },
    "description": {
      "title": "Long Description",
      "type": "string"
    },
}

So, both of them will be text fields, can I create one custom renderer and use it for both?

Hi @AhsanSaleemMemon,

Can I create custom renderers using mui input fields like TextField (Text field React component - Material UI), Select, Radio button?

Custom renderers have full control over their rendering output so you can use any Material UI component or even rendering technology you want within any renderer set. Therefore you can definitely use TextField, Select etc. from Material UI.

And also, can I use one custom renderer for multiple fields

Yes! Renderers are dispatched to using a tester-based system. Each renderer has an associated tester with the following interface (simplified):

(uischema: UISchemaElement, schema: JsonSchema) => number;

The tester with the highest returned number wins and its associated renderer is used. So you can inspect the schema and uischema and always return a high number for your custom renderers when appropriate. For this we also offer useful utils.

For example the following tester will be used for all type: 'string' elements, see isStringControl

import { isStringControl, rankWith } from '@jsonforms/core';

const myStringTester = rankWith(100, isStringControl);

Can you share a sample code to create a custom renderer using mui TextField?

Based on this code the following is a basic implementation (untested) using some of the features JSON Forms provides.

import {
  ControlProps,
  isStringControl,
  RankedTester,
  rankWith
} from '@jsonforms/core';
import { withJsonFormsControlProps } from '@jsonforms/react';

const MyTextFieldControl = (props: ControlProps) => (
  <TextField
    label={props.label}
    value={props.data}
    onChange={(event) => props.handleChange(props.path, event.target.value)}
    error={!!props.errors}
    helperText={props.errors || props.description}
    disabled={!props.enabled} />
);

const myTextFieldControlTester: RankedTester = rankWith(
  2, // higher than the one of JSON Forms Material which uses '1'
  isStringControl
);

// hand this over together with the provided `renderers` to the `JsonForms` component
export const myTextFieldControlEntry = { 
  renderer: withJsonFormsControlProps(MyTextFieldControl),
  tester: myTextFieldControlTester
}

Note that this basic implementation does not fully match the standard behavior of our off-the-shelf provided renderers nor uses all of the provided utilities of JSON Forms. Check the implementation of the provided MaterialTextControl as a starting point.