How to divide object properties into titled groups in RJSF form's UI, without modifying schema?

476 views Asked by At

Let's start with a very simple RJSF schema of a single flat object:

{
  "type": "object",
  "properties": {
    "foo": {
      "type": "string",
      "title": "Foo"
    },
    "bar": {
      "type": "string",
      "title": "Bar"
    },
    "baz": {
      "type": "integer",
      "title": "Baz"
    }
  }
}

I want to visually divide the object's properties into headlined groups - achieving the visual equivalent of grouping them under separate sub-objects with title - like this:

enter image description here

But I want this to be a visual presentation of the schema I have, I don't want to re-define the schema itself just because this is how I currently want to present it.

I would be fine with either

  1. Finding a way to render the object's properties as a group
    • it seems like object theme templates could be extremely useful here! If only I knew how to re-use the built-in ObjectFieldTemplate (I use the default bootstrap 3 theme) - then I could create a custom wrapper around multiple instances of it. But the built-in (default) ObjectFieldTemplate doesn't seem to be exported from @rjsf/core. Trying to manually re-create its behavior sounds like a terrible idea to me
    • I know I can transform the schema right before I provide it to <Form>, but this would also require transorming formData both when providing to <Form> and onChange - I would prefer a more declarative way of doing this.
  2. Arbitrarily adding a headline between the fields
    • kind of like a fake field with a custom widget, but without adding a new property to formData when submitting a form
    • injecting a fake prop into schema when passing into <Form> and removing it onChange feels really hacky
    • I would - reluctantly - settle for a custom widget that could inject title over a field, something like ui:TextWithHeadlineWidget, but I'm running into the same problem as with ObjectFieldTemplate above - I don't know how to wrap around the built-in widget, because I don't know how to import and reuse it

Do I have any good options here?

Thank you for your time

1

There are 1 answers

0
Michal Kurz On

Turns out @rjsf/core does export its templates, just hidden under getDefaultRegistry function - we can get it like this:

import Form, { getDefaultRegistry } from "@rjsf/core";

const registry = getDefaultRegistry();
const ObjectFieldTemplate = registry.templates.ObjectFieldTemplate;

Other theme packages seem to all export templates on a generateTemplates function instead.

Here is a working demo: https://codesandbox.io/s/rjsf-5-playground-gpeeps?file=/src/Test.tsx