Appearance
Choice Component
A component for selecting one or multiple values from a list of choices. When you see "kind": "choice" in a component, it represents a selection field that can display as radio buttons, checkboxes, or a dropdown menu, with choices coming from either a static list or a remote API.
Understanding Choice Component Fields
When reading a choice component in the schema, you'll see these fields:
| Field | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Unique identifier for this choice field |
kind | string | Yes | Always "choice" for choice components |
metadata | object | Yes | Component-specific metadata (required for choice) |
metadata.multiple | boolean | No | If true, allows multiple selections |
metadata.dataSource | DataSource | Yes | Defines where choices come from (static or remote) |
metadata.variant | string | Yes | Display style: "radio", "checkbox", or "dropdown" |
rules | object | No | Validation rules that apply to this field |
rules.required | boolean | No | If true, at least one selection must be made |
rules.minSelected | number | No | Minimum selections required (when multiple: true) |
rules.maxSelected | number | No | Maximum selections allowed (when multiple: true) |
Reading Metadata
metadata.multiple
- What it means: When
true, users can select multiple values (returns an array). Whenfalseor missing, only single selection is allowed (returns a single value) - How to use: Check this to determine if you should handle the value as an array or a single value
metadata.variant
- What it means: Controls the visual display of choices
"radio": Radio buttons for single selection (best for 2-5 options)"checkbox": Checkboxes for multiple selection (best for 2-10 options)"dropdown": Dropdown menu (best for long lists or space-constrained layouts)
- How to use: Use this value to render the appropriate UI component
metadata.dataSource
Defines where the choices come from. There are two types:
Static Data Source
Choices are predefined in the schema. Look for "type": "static" in the dataSource.
Structure:
| Field | Type | Required | Description |
|---|---|---|---|
type | string | Yes | Always "static" for static data source |
choices | Choice array | Yes | Array of available choices |
choices[].value | any | Yes | The value returned when selected |
choices[].label | LocalizedString | Yes | Display label (object with language keys) |
choices[].description | LocalizedString | No | Optional description for the choice |
choices[].metadata | object | No | Optional metadata for the choice |
Example:
json
{
"metadata": {
"variant": "radio",
"dataSource": {
"type": "static",
"choices": [
{
"value": "male",
"label": { "en": "Man" },
"description": { "en": "You identify as male" }
},
{
"value": "female",
"label": { "en": "Woman" },
"description": { "en": "You identify as a woman" }
}
]
}
}
}What this tells you:
- Display as radio buttons (
variant: "radio") - Two choices available: "male" and "female"
- Each choice has a label and description in English
- Use the
valuewhen submitting, display thelabelto users
Remote Data Source
Choices are fetched from an API endpoint. Look for "type": "remote" in the dataSource.
Structure:
| Field | Type | Required | Description |
|---|---|---|---|
type | string | Yes | Always "remote" for remote data source |
url | string | Yes | API endpoint URL to fetch choices from |
method | string | Yes | HTTP method: "GET" or "POST" |
itemsPath | string | No | JSON path to items array in API response |
nextCursorPath | string | No | JSON path to next cursor for pagination |
keys | object | No | Mapping keys for value, label, description |
keys.value | string | No | Key for choice value in API response |
keys.label | string | No | Key for choice label in API response |
keys.description | string | No | Key for choice description in API response |
params | object | No | Query parameter names for search/cursor |
params.search | string | No | Query parameter name for search |
params.cursor | string | No | Query parameter name for pagination cursor |
Example:
json
{
"metadata": {
"variant": "dropdown",
"dataSource": {
"type": "remote",
"url": "/api/countries",
"method": "GET",
"itemsPath": "data.items",
"keys": {
"value": "code",
"label": "name"
},
"params": {
"search": "q"
}
}
}
}What this tells you:
- Fetch choices from
/api/countriesusing GET - Items are in
data.itemspath of the response - Use
codefield as value,namefield as label - Support search via
qquery parameter
Understanding Validation Rules
rules.required
- What it means: If
true, at least one selection must be made. Validation fails if no value is selected - How to use: Mark the field as required in your form UI
rules.minSelected
- What it means: Minimum number of selections required when
multiple: true - How to use: Validate that at least this many selections are made
- Note: Only applicable when
metadata.multiple: true
rules.maxSelected
- What it means: Maximum number of selections allowed when
multiple: true - How to use: Limit selections to this number and show validation error if exceeded
- Note: Only applicable when
metadata.multiple: true
Example: Reading a Single Selection Choice Component
json
{
"id": "gender",
"kind": "choice",
"metadata": {
"variant": "radio",
"dataSource": {
"type": "static",
"choices": [
{ "value": "male", "label": { "en": "Man" } },
{ "value": "female", "label": { "en": "Woman" } },
{ "value": "non-binary", "label": { "en": "Non-Binary" } }
]
}
},
"rules": {
"required": true
}
}What this tells you:
- Field ID is
"gender"- use this to reference the field - Display as radio buttons
- Three choices available (male, female, non-binary)
- Field is required
- Returns a single value (not an array, since
multipleis not set)
Example: Reading a Multiple Selection Choice Component
json
{
"id": "sexualOrientation",
"kind": "choice",
"metadata": {
"variant": "checkbox",
"multiple": true,
"dataSource": {
"type": "static",
"choices": [
{ "value": "heterosexual", "label": { "en": "Heterosexual" } },
{ "value": "bisexual", "label": { "en": "Bisexual" } },
{ "value": "gay", "label": { "en": "Gay" } }
]
}
},
"rules": {
"required": true
}
}What this tells you:
- Field ID is
"sexualOrientation" - Display as checkboxes
- Multiple selections allowed (
multiple: true) - Returns an array of values
- Field is required