anyOf renderer without generated UI schema

The React Material Renderers come with some combinator renderers, specifically - anyOf renderer.

The UI schema for this looks like:

    {
      "type": "Control",
      "label": "Basic Information",
      "scope": "#/properties/addressOrUser"
    }

This relies on UI schema generation to generate the UI schema for the address, or user object once the user has made a selection.

I’m trying to develop a custom control that works the same way, however, I need to be able to specify the elements within it and not rely on the UI schema for that object being auto-generated.

For example, let’s say within addressOrUser, I need a custom control that relies on a specific scope, or UI schema option. How could I specify the individual fields for the different possible objects within my custom anyOf control, or would this not be possible?

Hi @p12y ,

you should not need a custom renderer to specify custom UI Schemas for your address and user objects. Instead, you can hand in UI Schemas for them via the <JsonForms> component’s uischemas property. See the jsonforms react docs: React Integration - JSON Forms

Hope that helps and best regards,
Lucas

Thanks for the quick reply @lucas-koehler! It’s not clear to me how to use these to specify the UI schemas for the objects. May I please ask for a brief example of what that would look like for the anyOf combinator example?

For example, if I wanted to provide a UI schema for the user object, while still using the material anyOf renderer. I’m not sure how I’d achieve that with uischemas.

I really appreciate the help, thanks again.

The only way I can really think of is to differentiate based on some attribute of the schema, such as title. For instance:

  {
    tester: (jsonSchema: JsonSchema, schemaPath: string) => {
      return schemaPath === '#/properties/addressOrUser' &&
      jsonSchema.title === 'User'
        ? 2
        : 0;
    },
    uischema: {
      type: 'HorizontalLayout',
      elements: [
        {
          type: 'Control',
          scope: '#/properties/name',
          label: 'Name',
        },
        {
          type: 'Control',
          scope: '#/properties/mail',
          label: 'Mail',
        },
      ],
    },
  },

Am I on the right track, or is there a better way?

Hello @p12y ,
you are on the right track. Unfortunately, the schemaPath in the tester arguments does not contain a hint on the selected sub-object of a combinator as you already discovered.

While your solution should work fine, it is susceptible to bugs when the schema’s title is changed. I’d suggest adding an additional property to the user and address schemas that uniquely identifies them but is not user visible. E.g. you could add a property like `“_type”: “user” to the user schema.

EDIT: Note that json schema recommends prefixing custom properties with x- (e.g. x-type). See Custom Annotations Will Continue

Best regards,
Lucas

Got it, thank you Lucas.