-
Notifications
You must be signed in to change notification settings - Fork 2.3k
Description
Prerequisites
- I have read the documentation
What theme are you using?
core
Is your feature request related to a problem? Please describe.
In my project, we define a variety of schemas in our backend API and dynamically fetch those from the frontend to display relevant forms. In some of these forms, we have object fields that we would like to be able to display horizontally instead of vertically. Take for example an array of HTTP headers:
{
"type": "array",
"items": {
"type": "object",
"properties": {
"header" { "type": "string" },
"value": { "type": "string" }
}
}
}
We would like to be able to display those side-by-side as below:
However, we have other object fields (the form itself being one example) for which we want to keep the default vertical layout.
Because schemas are defined on the backend, we can't easily provide a custom ObjectFieldTemplate
for this field.
Describe the solution you'd like
We'd like to be able to provide multiple ObjectFieldTemplate
implementations to our form (say VerticalObjectFieldTemplate
and HorizontalObjectFieldTemplate
) and have the ability to pick one from the ui schema. For example:
function MyForm() {
const { schema, uiSchema } = useDynamicSchema()
return <Form schema={schema} uiSchema={uiSchema} templates={{ ObjectFieldTemplate: {'vertical': VerticalObjectFieldTemplate, 'horizontal': HorizontalObjectFieldTemplate}} />
schema:
{
"type": "object",
"properties": {
"headers": {
"type": "array",
"items": {
"type": "object",
"properties": {
"header" { "type": "string" },
"value": { "type": "string" }
}
}
}
}
}
uiSchema:
{
"headers": {
"items": {
"ui:ObjectFieldTemplate": "horizontal"
}
}
}
Describe alternatives you've considered
Our current solution is to do basically that, but by modifying the ui schema by replacing "ui:ObjectFieldTemplate": "horizontal"
by its implementation in the frontend after fetching it from the backend. This works, but it's not exactly simple nor elegant.
We've also looked into custom widgets and fields, but the former is too low level and the latter appears too generic. With a custom field, we weren't able to get the object field's properties without digging around in the registry and form data in somewhat complex ways.
We've also considered the options of simply adding some arbitrary key to they ui schema and using that as a sort of additional prop to a custom ObjectFieldTemplate. It's simple enough, but it opens the door to all sorts of implicit contracts between backend and frontend that would be hard to track, maintain and debug.
We've also tried playing around with ui:classNames
and ui:style
, but between the various layers of Template
, Field
and Render
components that don't always pass all props down to their children, this quickly ends up becoming confusing and finicky.