Preferences
Array inputs
Repeating rows with their own schema, limits, summaries and per-row gates.
An array input collects any number of rows, each shaped by itemSchema:
{
key: 'triggers',
label: 'Triggers',
type: 'array',
minItems: 1,
maxItems: 10,
itemSummaryKeys: ['entity', 'state'], // what a collapsed row shows
itemSchema: {
inputs: [
{ key: 'entity', label: 'Device', type: 'entity', required: true },
{ key: 'state', label: 'Changes to', type: 'enum', required: true,
options: [ /* 'light.on', 'light.off', 'lock.locked', … */ ],
filterOptionsByEntityDomain: 'entity' }, // narrow per row by the picked device's domain
],
},
}What your code receives
The global is a JSON array of plain row objects:
// triggers === [{ entity: 'binary_sensor.hall', state: 'binary_sensor.on' }, …]
function initialize() {
for (const row of triggers ?? []) {
const [, value] = row.state.split('.');
subscribe(new EntityWrapper(row.entity), { to: value }, onTrigger);
}
}Entity fields inside rows are ids, not wrappers — wrap them with new EntityWrapper(id).
Row-level behaviour
Everything on Conditions and visibility works
inside a row and refers to siblings in the same row: requiresEntityFeature,
requiresSiblingOneOf, filterOptionsBySiblingPrefix, filterOptionsByEntityDomain,
domainFilterFrom, unitFromEntity.
Tips
itemSummaryKeyskeeps long lists readable; without it the app derives a summary from filled fields.thermostatScheduleis a specialised array (a 7-day × 24-hour grid editor) that stores rows like{ day, timeOfDay, hvacMode, heatSetpoint, coolSetpoint, fanMode }and hydrates likearray.- The Simple Trigger example is a compact array-driven wizard:
rows of actions with per-row option filtering and a dynamic
preferencesfunction. The Motion Light by Time of Day example uses rows with amultipleentity field and a brightness gated on the picked lights.