rjsf-team / react-jsonschema-form

A React component for building Web forms from JSON Schema.
https://rjsf-team.github.io/react-jsonschema-form/
Apache License 2.0
14.03k stars 2.18k forks source link

RJSF anyOf customization #4151

Open memchenko opened 4 months ago

memchenko commented 4 months ago

Prerequisites

What theme are you using?

core

What is your question?

Hi everyone!

First, I want to thank you for such awesome library! We use it with collegues a lot and it seems there's no a better alternative.

My question relates to rendering of conditional fields. I know there's support for dependencies field and for now we specify conditional fields using this property. And at this moment we're in process of developing a mechanism which would translate Typebox data specification into JSONSchema which would then be rendered by RJSF into form. And the problem is that typebox codegen doesn't generate dependencies field and seems that there's no other way of describing conditional fields other than with a union of types. This union then is translated as anyOf in terms of JSONSchema. Here https://rjsf-team.github.io/react-jsonschema-form/docs/api-reference/uiSchema/#anyof I read there's possibility to support such approach with uiSchema here. But I'm not sure if it's possible to customize which widget and field would handle my conditional properties. When I tried it didn't worked. Below is an example illustrating my question.

Let's say I have a JSONSchema like this:

{
  type: "object",
  anyOf: [
    {
      properties: {
        a: {
          const: "x",
        },
      },
    },
    {
      properties: {
        a: {
          const: "y",
        },
        b: {
          type: "string",
        },
      },
    }
  ],
}

And when I specify uiSchema like the following:

{
  anyOf: [
    {
      a: {
        "ui:widget": "buttonGroup",
      },
    },
    {
      a: {
        "ui:widget": "buttonGroup",
      },
      b: {
        "ui:widget": "phone",
      },
    },
  ],
}

RJSF doesn't respect what I specify in "ui:widget" fields but renders "select" widget instead. How can I specify custom widget for rendering of such conditional fields? Is it possible at all in case of such json schema definition?

Thanks in advance!

heath-freenome commented 4 months ago

@memchenko I've created an example using your schema with a UiSchema that sets the title. I believe that you can do the same for yours only use widget instead. So something like:

{
   a: {
     "ui:widget": "buttonGroup"
   },
  b: {
     "ui:widget": "phone",
  }
}
memchenko commented 4 months ago

@heath-freenome Hi, thank you for your response! The example you created contains a couple of problems I try to solve. First problem is that widget for a property doesn't get all the possible options. Here you can see the the select has not any option:

Screen Shot 2024-04-08 at 12 55 46 PM

And the second problem is that there appears the dropdown on the top with options "Option 1" and "Option 2" which allows to switch between schemas. However, I'd like it to work the way dependencies definition works. Meaning when user selects an option in the dropdown for the a property a corresponding subschema applies. This is what I get with this approach so far though:

Screen Shot 2024-04-08 at 12 55 57 PM

For illustration I tweaked your example, you can check it here

nickgros commented 4 months ago

@memchenko I think the issue here is that we don't have great support for the const keyword (see #1241)

If you replace the const with oneOf/const(or enum) it should be closer to what you expect. Here's a playground link.