Skip to content

Template support for MultiSchemaField(OneOfField/AnyOfField) #3918

Open
@YuJianghao

Description

@YuJianghao

Prerequisites

What theme are you using?

other

Is your feature request related to a problem? Please describe.

When building the Carbon theme (#3883), I met the following problem:

Suppose I want to implement the following oneOf UI:

  • A key oneOf that told the user this is a oneOf
  • A gray background that indicates which part(in this case, the loram field) the oneOf is controlling.

image

Without modifying the default OneOfField. I got:

image

The problem is: How can I change the UI without rewriting the entire OneOfField?

Describe the solution you'd like

Provide a OneOfTemplate/AnyOfTemplate, and replace the render part of the OneOfField

return (
<div className='panel panel-default panel-body'>
<div className='form-group'>
<Widget
id={this.getFieldId()}
name={`${name}${schema.oneOf ? '__oneof_select' : '__anyof_select'}`}
schema={{ type: 'number', default: 0 } as S}
onChange={this.onOptionChange}
onBlur={onBlur}
onFocus={onFocus}
disabled={disabled || isEmpty(enumOptions)}
multiple={false}
rawErrors={rawErrors}
errorSchema={fieldErrorSchema}
value={selectedOption >= 0 ? selectedOption : undefined}
options={{ enumOptions, ...uiOptions }}
registry={registry}
formContext={formContext}
placeholder={placeholder}
autocomplete={autocomplete}
autofocus={autofocus}
label={title ?? name}
hideLabel={!displayLabel}
/>
</div>
{option !== null && <_SchemaField {...this.props} schema={optionSchema!} />}
</div>

to:

    const OneOfTemplateProps = {
      widget: <Widget /* some props for widget*/ />,
      content: option !== null && <_SchemaField {...this.props} schema={optionSchema!} />,
      // ...other props for OneOfTemplate
    }

    return <OneOfTemplate {... OneOfTemplateProps}/>

Then I can create the target UI by implementing a template without touching the complicated logic:

function OneOfTemplate({widget, content}){
  return (
    <FormGroup {...someProps}>
      <LayerBackground {...someProps}>
        {widget}
        {content}
      </LayerBackground>
    </FormGroup>
  );
}

Describe alternatives you've considered

Rewrite the whole OneOfField can do this, but not good enough.

Metadata

Metadata

Assignees

No one assigned

    Labels

    corefeatureIs a feature requesthelp wantedtemplatesRelated to the templates capabilities of RJSFutilsRelated to @rjsf/utils

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions