The interface as a JSON file (ui.json)
The interface as a JSON file (ui.json)
Section intitulée « The interface as a JSON file (ui.json) »Everything declarative — translations, model, settings fields, commands, menus,
toolbars, placements and panels — can live in a JSON file next to the plugin
instead of in code. The plugin loads it explicitly from setup():
ctx.ui.define({ slice, icons, states, values, payloads, components });await ctx.ui.load("ui.json"); // relative to the plugin's own folderconst settings = ctx.ui.settings(); // the handle for the declared fieldsThe manifest goes through the very same registry calls as code, so namespacing,
i18n and cleanup on disable behave identically. ctx.ui.apply(object) does the
same thing with an object you already have in memory.
Sections
Section intitulée « Sections »| Section | What it declares |
|---|---|
messages |
{ en: {...}, fr: {...} } — the plugin’s own catalogs |
models |
documentation of the plugin’s data shapes |
settings |
{ order, fields: [...] } — the settings fields |
commands |
id, title, event, shortcut, icon, state, payload |
menus |
id, title, order, standalone, parent |
placements |
a command or a widget in a menu or a toolbar |
panels |
a surface contribution: toolbar + tree/list/graph/form/forms/value/palette, or a named component |
views |
a work-area view: { id, type, config } for a view engine, or a named component |
Ids you declare are namespaced automatically ("new" becomes "notes.new"),
and so are toolbars ("view:editor", "panel:documents"). References to
something the shell owns are left untouched, so "menu": "file" places a
command in the shell’s File menu. Titles and labels are i18n keys relative to
the plugin.
What JSON cannot hold: named references
Section intitulée « What JSON cannot hold: named references »Icons, live command state, tree rows, widget values, dynamic payloads and custom
components are registered in code with ctx.ui.define() and referenced by name:
{ "id": "save", "title": "command.save", "event": "notes/document.save", "icon": "save", "state": { "ref": "saveState" }, "payload": { "ref": "doc" } }Simple cases need no code at all — small selectors read the plugin slice:
{ "state": { "from": "slice", "exists": "documents" } }{ "value": { "from": "slice", "path": "activeDocId" } }{ "items": { "from": "slice", "path": "documents", "map": { "id": "id", "label": "title", "trailingWhen": "dirty", "payload": { "docId": "id" } } } }{ "payload": { "from": "context", "pick": { "docId": "params.docId" }, "fallback": { "docId": "activeDocId" } } }Icon names come from the shared icon set (ctx.icons) or from
ctx.ui.define({ icons }).
The Notes sample works this way: its whole interface lives in
plugins/notes-tsx/ui.json. Only handlers, the editor view, the close prompt and
undo/redo stay in code.
Documentation sous licence CC BY 4.0 · © les contributeurs de SCFlow ·Retour à supplychainflow.org