---
sidebar_label: Designing the UI schema
toc_max_heading_level: 3
doc_id: 3b09d681-58f2-4cde-9f3f-4c50a2e72174
description: Reference for all UI schema elements in nullplatform, including layouts, controls, arrays, display elements, rules, options, and scope patterns.
keywords:
  - UI schema
  - JSONForms
  - JSON Schema
  - form design
  - services
  - catalogs
  - scopes
---

# Designing the UI schema

This page explains how to design the **UI Schema** used to control layout, grouping, labels, and behaviors of forms
in nullplatform. It works together with your **JSON Schema**, which defines the data structure and validation rules.

> 💡 The UI schema controls *how forms look and how users interact with them*.


## Where the UI Schema fits

Add a `uiSchema` object under your specification’s `attributes.schema` to control layout and behavior.

```json
{
  "attributes": {
    "schema": {
      "type": "object",
      "properties": {
        "name": { "type": "string" }
      },
      "uiSchema": {
        "type": "VerticalLayout",
        "elements": [
          { "type": "Control", "scope": "#/properties/name" }
        ]
      }
    }
  }
}
```

## UI Schema building blocks

UI schemas are built from layout and control elements. They don't change your data model. They only affect how fields render in the UI.

| Type         | Purpose                                | Examples                                                        |
| ------------ | -------------------------------------- | --------------------------------------------------------------- |
| **Layouts**  | Structure and position fields          | `VerticalLayout`, `HorizontalLayout`, `Group`, `Categorization` |
| **Controls** | Bind UI elements to JSON Schema fields | `Control`, `ListWithDetail`                                     |
| **Display**  | Read-only presentation                 | `Label`, `chip`                                                 |
| **Rules**    | Dynamic behavior                       | `SHOW`, `HIDE`, `APPLY`, `DISABLE`                              |


## Scope patterns (JSON Pointer quick reference)

Use **JSON Pointers** to bind controls to schema fields.

- Root property → `#/properties/name` → `data.name`
- Nested → `#/properties/address/properties/street` → `data.address.street`
- Array (inside an item editor) → `#/properties/name` → `data.items[i].name`

Example:

```json
{ "type": "Control", "scope": "#/properties/address/properties/zipCode" }
```

---


## Layout elements

Use layouts to organize the form. Layouts **don't bind data**; they arrange other elements.

### VerticalLayout
Stack children vertically.

```json
{ "type": "VerticalLayout", "elements": [ { "type": "Control", "scope": "#/properties/name" } ] }
```

### HorizontalLayout
Place children in a row (auto‑wraps on small screens).

```json
{ "type": "HorizontalLayout", "elements": [
  { "type": "Control", "scope": "#/properties/firstName" },
  { "type": "Control", "scope": "#/properties/lastName" }
]}
```

### Group
Group related fields with an optional **card** and title.

```json
{ "type": "Group", "label": "Credentials", "elements": [
  { "type": "Control", "scope": "#/properties/username" },
  { "type": "Control", "scope": "#/properties/password", "options": { "format": "password" } }
]}
```

### Categorization and Category
Render content as **tabs** or as a **stepper**.

```json
{
  "type": "Categorization",
  "options": { "variant": "stepper", "showNavButtons": true },
  "elements": [
    { "type": "Category", "label": "General", "elements": [
      { "type": "Control", "scope": "#/properties/name" }
    ]},
    { "type": "Category", "label": "Advanced", "elements": [
      { "type": "Control", "scope": "#/properties/toggles" }
    ]}
  ]
}
```

---

## Controls (bind to schema properties)

Controls display/edit values defined in your **JSON Schema**.

### Control
Generic control for any property. Common options: `label`, `focus`, `trim`, `hideRequiredAsterisk`, `showUnfocusedDescription`.

```json
{ "type": "Control", "scope": "#/properties/email", "label": "Email" }
```

#### String controls

**Text (single/multi‑line)**
```json
{ "type": "Control", "scope": "#/properties/description", "options": { "multi": true } }
```

**Password**
```json
{ "type": "Control", "scope": "#/properties/secret", "options": { "format": "password" } }
```

**Enum (select / autocomplete)**
```json
{ "type": "Control", "scope": "#/properties/country", "options": { "autocomplete": true, "placeholder": "Select a country" } }
```

**Radio group (inline/stacked)**
```json
{ "type": "Control", "scope": "#/properties/plan", "options": { "format": "radio", "direction": "vertical" } }
```

**Radio cards**
```json
{ "type": "Control", "scope": "#/properties/plan", "options": { "format": "radio-cards" } }
```

**Chip display for values (mapping supported)**
```json
{ "type": "Control", "scope": "#/properties/status", "options": {
  "format": "chip",
  "mapping": {
    "active": { "label": "Active", "color": "success", "icon": "ic:outline-check" },
    "pending": { "label": "Pending", "color": "warning" }
  }
}}
```

#### Number / Integer controls

**Numeric input / slider**
```json
{ "type": "Control", "scope": "#/properties/threshold" }
```
```json
{ "type": "Control", "scope": "#/properties/volume", "options": { "valueLabelDisplay": "on" } }
```

#### Boolean controls

**Checkbox / Toggle**
```json
{ "type": "Control", "scope": "#/properties/maintenanceMode" }
```
```json
{ "type": "Control", "scope": "#/properties/notifications", "options": { "toggle": true } }
```

#### Date / Time controls

```json
{ "type": "Control", "scope": "#/properties/birthDate", "options": { "dateFormat": "YYYY-MM-DD" } }
```
```json
{ "type": "Control", "scope": "#/properties/appointmentTime", "options": { "ampm": true } }
```
```json
{ "type": "Control", "scope": "#/properties/eventDateTime", "options": { "dateTimeFormat": "YYYY-MM-DD HH:mm" } }
```

#### anyOf / oneOf controls (select/autocomplete/radio)

```json
{ "type": "Control", "scope": "#/properties/animal", "options": { "autocomplete": true } }
```

---

## Arrays and tables

Arrays can be rendered in different patterns depending on your UX needs.

### Array layout (accordion with per‑item editors)
```json
{ "type": "Control", "scope": "#/properties/contacts", "options": {
  "elementLabelProp": "name",
  "showArrayLayoutSortButtons": true
}}
```

### Table
```json
{ "type": "Control", "scope": "#/properties/products", "options": {
  "showArrayTableSortButtons": true
}}
```

### List with detail (master‑detail)
```json
{ "type": "ListWithDetail", "scope": "#/properties/contacts", "options": { "elementLabelProp": "name" } }
```

---

## Display (read‑only) patterns

Use display elements to **show** values without inputs.

```json
{ "type": "Control", "scope": "#/properties/apiKey", "options": { "direction": "row", "icon": "key" } }
```

Supported displays: text, link (URL), number, boolean, array/object summaries, and oneOf read‑only labels.

---

## Rules (conditional UI)

Rules let you **show/hide** or **enable/disable** elements. With the extended **APPLY** effect, you can patch labels/options dynamically.

```json
{
  "type": "Control",
  "scope": "#/properties/ssn",
  "rule": {
    "effect": "SHOW",
    "condition": { "scope": "#/properties/country", "schema": { "const": "USA" } }
  }
}
```

👉 For complex behavior, see [Advanced UI Schema](advanced.md).

---


## Common options (quick table)

| Option                                      | Type    | Use                                                         |
| ------------------------------------------- | ------- | ----------------------------------------------------------- |
| `showUnfocusedDescription`                  | boolean | Always show the description (not only on focus)             |
| `hideRequiredAsterisk`                      | boolean | Hide the * on required labels                               |
| `trim`                                      | boolean | Fixed width (e.g., text size by `maxLength`)                |
| `focus`                                     | boolean | Autofocus this element on mount                             |
| `elementLabelProp`                          | string  | Property used as item label in arrays                       |
| `disableAdd` / `disableRemove`              | boolean | Disable add/remove in arrays                                |
| `showArrayLayoutSortButtons`                | boolean | Sorting arrows for array layout                             |
| `showArrayTableSortButtons`                 | boolean | Sorting arrows for array table                              |
| `variant`                                   | string  | `stepper` for Categorization; `filled`/`outlined` for chips |
| `ampm`, `views`, `dateFormat`, `timeFormat` | various | Date/time formats and views                                 |
