Layouts
Layout renderers that control how form elements are arranged — vertical stacks, horizontal rows, accordion groups, tabs, and dynamic arrays.
Layouts are UI Schema elements that contain other elements. They have no direct connection to schema properties — they only control visual structure.
VerticalLayout
Stacks elements in a column with flex flex-col gap-2. This is the default root layout for most forms.
npx shadcn@latest add https://mksingh.dev/r/jsonforms-vertical-layout.json{
"type": "VerticalLayout",
"elements": [
{ "type": "Control", "scope": "#/properties/firstName" },
{ "type": "Control", "scope": "#/properties/lastName" }
]
}HorizontalLayout
Arranges elements in a row with equal widths (flex-1 per child). Useful for side-by-side fields.
npx shadcn@latest add https://mksingh.dev/r/jsonforms-horizontal-layout.json{
"type": "HorizontalLayout",
"elements": [
{ "type": "Control", "scope": "#/properties/firstName" },
{ "type": "Control", "scope": "#/properties/lastName" }
]
}Group
Wraps a set of fields in a collapsible ShadCN Accordion. The label property becomes the accordion trigger text. Defaults to open.
npx shadcn@latest add https://mksingh.dev/r/jsonforms-group.json{
"type": "Group",
"label": "Contact Details",
"elements": [
{ "type": "Control", "scope": "#/properties/email" },
{ "type": "Control", "scope": "#/properties/phone" }
]
}Categorization (Tabs)
Renders a set of categories as ShadCN Tabs. Each category becomes a tab, and its elements render inside the tab panel. Good for multi-section forms.
npx shadcn@latest add https://mksingh.dev/r/jsonforms-categorization.json{
"type": "Categorization",
"elements": [
{
"type": "Category",
"label": "Personal",
"elements": [
{ "type": "Control", "scope": "#/properties/firstName" }
]
},
{
"type": "Category",
"label": "Address",
"elements": [
{ "type": "Control", "scope": "#/properties/street" }
]
}
]
}Label
Renders a static piece of text inside a layout. Useful for headings or instructions inside the form.
npx shadcn@latest add https://mksingh.dev/r/jsonforms-label.json{
"type": "Label",
"text": "Fill in your details below"
}Array Layout
Renders arrays of objects as a list of collapsible accordion panels. Each item gets:
- Its own expand panel numbered from 1
- Full form rendered via
JsonFormsDispatch - Up / Down buttons to reorder
- Remove button to delete
Triggered automatically on array schemas where the items are objects (isObjectArrayWithNesting).
npx shadcn@latest add https://mksingh.dev/r/jsonforms-array-layout.json{
"type": "array",
"items": {
"type": "object",
"properties": {
"name": { "type": "string" },
"email": { "type": "string", "format": "email" }
}
}
}{
"type": "Control",
"scope": "#/properties/contacts",
"label": "Contact"
}The array layout uses
findUISchemato auto-generate the inner form layout if you don't provide one. You can override it by registering a custom UI Schema in theuischemasprop of<JsonForms />.
Disabling add/remove
Pass enabled={false} at the <JsonForms /> level or use JSONForms' rule system to disable the array control — the add and action buttons are gated on the enabled prop.
Nesting layouts
All layouts compose naturally. A common pattern for a real-world form:
{
"type": "VerticalLayout",
"elements": [
{ "type": "Label", "text": "New User" },
{
"type": "HorizontalLayout",
"elements": [
{ "type": "Control", "scope": "#/properties/firstName" },
{ "type": "Control", "scope": "#/properties/lastName" }
]
},
{
"type": "Group",
"label": "Address",
"elements": [
{ "type": "Control", "scope": "#/properties/street" },
{ "type": "Control", "scope": "#/properties/city" }
]
}
]
}