Creating nested layouts from nested schema object with auto generated UI Schema

I’m looking to avoid specifying a UI schema as we have clients who are writing schemas for us and writing a UI schema is not something we want them to have to do.
However im looking to be able to create some horizontal and vertical nested areas for some fields by using a nested object like so:

groupArea: {
  type: "object",
  properties: {
    name: {
      type: "string",
    },
    anotherField: {
      type: "string"
    }
  }, 
}

this exists in side an existing:

$schema: "http://json-schema.org/draft-07/schema#",
type: "object",
properties: {
  otherRootField: {
    type: "string",
  },
  rootLevelField: {
    type: "string"
  },
  groupArea: {
     ...
  }
}

I’ve added a layout renderer like so:

  ...vanillaRenderers,
  {
    tester: rankWith(3, schemaTypeIs("string")),
    renderer: TextControl,
  },
  {
    tester: rankWith(
      4,
      schemaMatches((schema) => schema.hasOwnProperty("enum"))
    ),
    renderer: RadioControl,
  },
  {
    tester: rankWith(5, schemaTypeIs("object")),
    renderer: withJsonFormsLayoutProps((props) => {
      return (
        <div style={{ backgroundColor: "red", width: '300px', height: '300px' }}>
          <VerticalLayout {...props} />
        </div>
      );
    }),
  },

but I find that the UI schema generator just creates an empty object for the nested object instead of a VerticalLayout with the items underneath.
Please let me know if theres a way to do this :slight_smile:

Hi @rcc,

In our off the shelf renderers the nested layouts works in the following way:

  1. The initial UI schema is generated. Note that we always generate a shallow ui schema, i.e. an object or array is just represented by a single control.
  2. Each element of that generated UI Schema is rendered, thereby the object is rendered by the MaterialObjectRenderer
  3. This object renderer then invoked the UI schema generator for the sub-schema it was called for, e.g. groupArea. This generated UI Schema will be a simple Group element with again a shallow list of controls.
  4. The appropriate renderers then take over again, i.e. the group and respective control renderers

In your code you are registering very generically only on schemaTypeIs('object'). This is not specific enough. For example in the example above, both the control and layout renderers will return true here. You should also check the UI Schema part as we do in the code base.

Then, as you can see with the linked MaterialObjectRenderer, you still need to invoke the UI schema generator in your control. The withJsonFormsLayoutProps does not do this automatically for you.


What I would like to suggest is to copy the MaterialObjectRenderer from our code base, register it with a higher priority than ours and then modify it to your liking.