Layout Schema
Field reference for the layout JSON. Concepts are in Layouts; this is the lookup. (The app is the source of truth; treat unspecified fields as optional with sane defaults.)
LayoutConfig (top level)
{
"name": "string (required) — display name",
"headerTitle": "string — header bar title (defaults to name)",
"version": 1,
"accentColor": "#hex — app accent color (default #667eea)",
"connection": { ConnectionConfig } | null,
"appearance": { AppearanceConfig } | null,
"theme": { ThemeConfig } | null,
"tabs": [ TabDefinition, … ],
"pollGroups": { "name": { "event": "string", "interval": number, "payload": any } },
"dynamicTabs": [ { "event": "string" } ]
}
versionis required by editor/push tooling — include"version": 1.themeand per-control theming are premium (custom theming requires the Pro entitlement; otherwise the default glass theme is used). See Control Catalog.
ConnectionConfig
{
"url": "wss://… or ws://… (required)",
"token": "string | null",
"e2eeKey": "base64 string | null",
"identity": {
"name": "string — device display name",
"channel": "string — mesh channel",
"role": "string — mesh role",
"canBroadcast": false,
"canRoute": false
}
}
See Connection & Pairing.
TabDefinition
{
"title": "string (required)",
"icon": "string — SF Symbol name (required)",
"grid": { "columns": int, "rows": int },
"children": [ ChildDefinition, … ]
}
ChildDefinition — control or group
ControlDefinition
{
"type": "button|toggle|slider|stepper|segmented|picker|datePicker|textInput|colorPicker|label|image|gauge|sparkline|progressRing|statusLight|map|graph|chat|qrCode|webView|logConsole|joystick|list|cardList|divider|spacer|…",
"id": "string (required, unique)",
"position": [row, col],
"span": [rowSpan, colSpan], // default [1,1]
"label": "string",
"defaultValue": any,
"icon": "string — SF Symbol",
"tint": "#hex",
"hideLabel": bool,
"hideBackground": bool,
// type-specific (see control-catalog):
"min": number, "max": number, "step": number,
"minIcon": "string", "maxIcon": "string",
"options": ["string", …],
"placeholder": "string",
"text": "string (label type)",
"systemName": "string (image type — SF Symbol)",
"gaugeStyle": "full|three_quarter|half",
"segments": [{ "limit": number, "color": "#hex" }],
"progressStyle": "ring|bar",
"sparklinePoints": int, "sparklineFill": bool,
"pickerStyle": "menu|wheel|inline",
"datePickerStyle": "compact|wheel|graphical",
"datePickerMode": "date|time|dateAndTime",
"mapStyle": "standard|satellite|hybrid", "mapInteractive": bool,
"graphConfig": { … see the in-app graph doc },
"config": { "target": string|null, "showTypingIndicators": bool, "historyCount": int }, // chat
// behavior (see data-flow):
"action": ActionDefinition,
"sync": [ SyncDefinition, … ],
"visible": { "when": "control-id", "operator": "eq|neq|gt|lt|gte|lte", "value": any },
"haptic": "light|medium|heavy|success|warning|error|selection",
"animation": "snappy|smooth|bouncy|gentle|instant",
"longPressGroup": GroupDefinition,
"longPressAction": ActionDefinition
}
GroupDefinition
{
"type": "group",
"id": "string (required)",
"label": "string",
"position": [row, col],
"span": [rowSpan, colSpan],
"grid": { "columns": int, "rows": int },
"children": [ ChildDefinition, … ],
"dynamic": "string — event name for dynamic content",
"visible": { … }
}
ActionDefinition (device → server)
{
"method": "meshsocket",
"mode": "request | broadcast",
"event": "broadcast_request | route_msg | route_msg_noreply",
"payload": { "key": "{{value}}" }
}
mode: "request" awaits a reply; otherwise fire-and-forget. {{value}} is
substituted with the control's value (native type when the whole string is exactly
"{{value}}"). See Data Flow — sync & actions.
SyncDefinition (server → device)
{
"method": "meshsocket",
"type": "listen",
"event": "broadcast | <custom>",
"filter": { "key": "value" },
"valuePath": "dot.notation.path"
}
event: "broadcast" listens on the shared channel; filter selects frames
(shallow equality on each key); valuePath extracts the value. See Data Flow — sync & actions.
Grid positioning
position: [row, col]— zero-indexed within the parent grid.span: [rowSpan, colSpan]— cells occupied (default[1, 1]).- Children must fit their parent grid (tab or group).
Icons
SF Symbol names, e.g. slider.horizontal.3, bolt.fill, gauge.with.dots.needle.67percent,
map.fill, chart.line.uptrend.xyaxis, house.fill, antenna.radiowaves.left.and.right.
See also Control Catalog and Message Reference.