Skip to main content

From a schema to screens

The shape of the schema decides the shape of the UI, and one platform fact drives all of it: a native modal form has exactly two controls, its submit and its dismiss. There is no third control to navigate with, so a form can never offer "open this sub-section" or "edit this list".

The ui-compiler filter reads the definition out of core.register() and bakes one screen per section into the addon's pack, shaped for the settings that section has. Nothing about a section travels at runtime; only the values do.

One rule per level​

The level holdsIt renders as
only form fieldsa form
one or more sub-groups and/or listsa screen of buttons, one row per sub-group or list

A level cannot mix form fields with sub-groups or lists. registerConfig() and the ui-compiler reject that shape with the path that needs restructuring. Put the form fields in a named child group instead. This keeps every screen unambiguous: it is either a form or a menu.

Walking a schema shaped like the reference addon:

server: {
economy: { // only groups -> screen of buttons
balances: { /* fields */ }, // -> form
currency: { /* fields */ }, // -> form
},
display: { // only destinations -> screen of buttons
general: { // -> form
prefix: { /* ... */ },
},
advanced: { /* fields */ }, // -> own form, reached from display
},
moderation: { // only lists -> screen of buttons, one row per list
blockedItems: { type: 'list', /* ... */ },
},
}

Depth is unbounded, and each level answers only for itself: a tree can be pure structure for three levels and then hold settings.

A list is not a form field

Lists have no native modal control, so every level that holds one opens a screen of buttons and each list gets a real editor there. Put any form fields in a child group beside the list.

What each entry becomes​

typeExtra fieldsRendered as
boolean—toggle
numbermin, max (required), step?slider, or a text input when the range exceeds 100
stringmaxLength?text input
selectoptions, a string array or a string enumtoggle-button segments taking one, up to 3 options; a dropdown beyond that
multiselectoptions, a string array or a string enumthe same segments taking any number, up to 3 options; one checkbox per option beyond that
listmaxItems?no control. It gets an editor of its own where there is room for a button, and shows its items plus the command where there is not

Every entry takes label and an optional description. The entry types themselves, what each requires and what value it infers, are the settings subsystem's.

Why segments stop at three

Segments show every choice at once and take one press to change; a dropdown hides them behind a press and a scroll. Past three the segments are too narrow to read, which is the point the dropdown, or a column of checkboxes, starts winning. Nothing to configure: the count decides.

Groups are nested objects, and may name themselves with $label and $description. Without them the UI derives a title from the key.

Editing a list in game​

Reached from a button screen, a list opens its own editor: current items as rows, a press to remove one, and an Add button. Adding presents a native modal with a text field. maxItems disables Add and says why.

Each list change writes immediately. The list editor does not have a Save button because every add, edit, or removal is already a complete list value.

Next steps​