Form layouts
A FormLayout says how the node editor lays out a type's properties. It is plain data that the type
carries as layout: tabs of items, each item taking a share of the row.
import type { FormLayout } from '@relatude/sdk';
const layout: FormLayout = {
tabs: [
{ id: 'content', title: 'Content', icon: 'file-text', items: [
{ kind: 'field', property: 'Title' },
{ kind: 'field', property: 'Slug', width: 60 },
{ kind: 'field', property: 'Category', width: 40, label: 'Section' },
{ kind: 'field', property: 'Body' },
] },
{ id: 'publishing', title: 'Publishing', icon: 'globe', color: 'green', items: [
{ kind: 'heading', text: 'On the site', description: 'Whether readers see it yet.' },
{ kind: 'field', property: 'Published', width: 33.33 },
{ kind: 'field', property: 'PublishDate', width: 66.67 },
{ kind: 'panel', title: 'Finding it', collapsible: true, collapsed: true, items: [
{ kind: 'field', property: 'Tags' },
] },
] },
// the Meta tab, on a tab strip of its own
{ id: 'meta', icon: 'sliders', strip: 'system', items: [{ kind: 'meta' }] },
],
hidden: ['LegacyCode'],
};
await cms.data.saveLayout?.('IArticle', layout); // null goes back to the default form| Item | Is |
|---|---|
{ kind: 'field', property, label?, help? } |
a property's editor, by CodeName; label and help replace the property's own |
{ kind: 'heading', text, description?, color? } |
a title over the items that follow |
{ kind: 'panel', title?, description?, color?, collapsible?, collapsed?, items } |
a framed group; its items' widths are shares of the panel, and collapsed opens it closed |
{ kind: 'meta' } |
the node's meta: address, access, site, release and expiry |
- Width is 5 to 100 percent, the whole row when left out. Items share a row while they fit, so make a row add up to 100 (thirds are 33.33 and 66.67). A narrow editor puts every item on a row of its own.
- Tabs.
idkeeps a tab open while the layout changes. A type's own tab has the type's CodeName as its id, and the Meta tab hasmeta; both can leave outtitle.iconis an icon name or SVG source. - Strips. Tabs with the same
stripshare a tab bar. Strips are stacked in the order of their first tabs, and tabs without one are on the first. - Colours. A tab, heading or panel can take a
colorfrom the palette:gray,red,orange,amber,green,teal,blue,indigo,violetorpink. Each has a light and a dark variant. - The name property (
nameProperty) is always at the top of the form, never on a tab.
The editor reconciles a layout with the type each time it shows the form. A property the layout
neither places nor hides goes last on its declaring type's tab, or on the first tab. Fields for
properties the type no longer has, and tabs or panels left empty, are dropped. So hidden is the
only way to leave a property out, and the property keeps its values. Without a layout, a type gets a
tab for each type that declares its properties, its own first, then Meta.
Layouts belong to the database and are the same for every user. Only administrators can save them
(whoami answers admin: true):
- In design mode, turned on with Design in the top bar or Design this form in an editor's menu. Every open node editor then shows its real form with controls to arrange, resize and colour it, and Save form saves it.
- From code, with
cms.data.saveLayout(type, layout),store.saveFormLayout(type, layout)or theform-layoutcommand ({ type, layout }).nullgoes back to the default form.
Layouts are kept in the CMS settings (Forms.Layouts). The server refuses a layout that places a
property the type does not have, places a property twice, repeats a tab id, or breaks the width or
colour rules.