Which Type to use to type UISchema for react JSX.Element Properties?

I am on a project that uses react-ts and the vanilla-renderers. (“@jsonforms/react”: “^3.5.1”, “@jsonforms/vanilla-renderers”: “^3.5.1”)

In short, what I try to achieve

I want a wrapper-JSX.Element for the JsonForms-JSX.Element so I can embed a generic form in my custom layout, simply providing the data,schema and uischema for any record type.

What I struggle with

I can’t get the type for the UISchema right, I get complaints about the “element” property (using UISchemaElement) or the “scope” property (using Layout) not being allowed.

Here’s my assumptions and setup

Assumptions

  • I can reuse the JsonForms JSX.Element properties types and use the same types for my JSX.Element

Wrapper JSX.Element

import {JsonSchema, Layout} from '@jsonforms/core'
import { JsonForms } from '@jsonforms/react';
import {
  vanillaCells,
  vanillaRenderers
} from '@jsonforms/vanilla-renderers';

type DocFormProperties = {
 data: any;
 docSchema: JsonSchema;
 docUISchema: UISchemaElement;
}
export const DocForm = ({data, docSchema, docUISchema}:DocFormProperties) => {
 return (
  <div className="wrapper">
   <JsonForms
    schema={docSchema}
    uischema={docUISchema}
    renderers={vanillaRenderers}
    data={data}
    cells={vanillaCells}
   />
  </div>
)
}

Using type UISchemaElement

Now when I try to define the UI schema for a record using UISchemaElement, intelliSense gives me an error that “elements” is not an allowed property:

import { JsonSchema, UISchemaElement } from '@jsonforms/core';

export const projectSchema: JsonSchema = {
  type: 'object',
  properties: {
    name: {
      type: 'string',
    },
    description: {
      type: 'string',
    },
  },
  additionalProperties: true,
  required: ['name'],
};

export const projectUISchema: UISchemaElement = {
  type: 'VerticalLayout',
  elements: [
    {
      type: 'Control',
      scope: '#/properties/name',
    },
    {
      type: 'Control',
      scope: '#/properties/description',
    },
  ],
};

Using type Layout

Or when I use Layout, intelliSense isn’t happy with the “scope” property of the Control, since Layout uses UISchemaElement and UISchemaElement seems not to be Scopable:

import { JsonSchema, Layout } from '@jsonforms/core';

export const projectSchema: JsonSchema = {
  type: 'object',
  properties: {
    name: {
      type: 'string',
    },
    description: {
      type: 'string',
    },
  },
  additionalProperties: true,
  required: ['name'],
};

export const projectUISchema: Layout = {
  type: 'VerticalLayout',
  elements: [
    {
      type: 'Control',
      scope: '#/properties/name',
    },
    {
      type: 'Control',
      scope: '#/properties/description',
    },
  ],
};

The error messages make sense when I check the type definitions, but honestly, I am a bit buffled now what to do.

@sdirix I am sure I am overseeing something, any hint to solve this? I can run the code using “UISchemaElement” and the forms render correctly, however, I don’t get my schema definitions “compliant”.

Hi @kimamil,

Currently our types are set up in way which does not let Typescript auto-infer them in a convenient fashion. This is not on purpose, we would like to see them improved.

See #2109 for a more detailed discussion and ways to workaround the issue.

1 Like