Audience: Contributor
Persist vs runtime field contracts for page trees (builder, API, import, tests). Not a dump of every IPageDefinition SEO/import field.
See also: Overview · Page structure · Actions and validators
Source of truth: common/model/src/model/*.ts and common/projects/lokakrt/dynamic/src/lib/model/element.model.ts.
interface IElementReference {
type: string;
props?: IProp[];
actions?: IAction[];
validators?: IFormValidator[];
children?: IElementReference[];
data?: Record<string, unknown>;
}
| Field | Required | Notes |
|---|---|---|
type |
yes | Must match a catalog properties.type.const |
props |
no | Omitted when empty after trim |
actions |
no | Event handlers |
validators |
no | Form field validators |
children |
no | Nested nodes; omitted when empty |
data |
no | Opaque bag (e.g. block overrides) |
ElementReferenceOps.trim deletes empty props / actions / validators / data / children (recursively). Prefer already-trimmed trees when writing or importing JSON.
Extends IElementReference with palette metadata:
| Field | Notes |
|---|---|
name |
Display title (from schema title) |
icon |
Optional catalog/API field — not written by DbInitService from schema |
hintField |
Prop used for canvas label (&hint: true on the prop schema) |
palette |
false → hidden from Insert; still nestable |
children |
Default insert tree from children.json |
IContentDefinition is { id, children }. IPageDefinition adds title, slug, settings, and related metadata. Page trees are edited through the working-copy overlay; Publish freezes the shared tip. For product wording see Preview & Publish.
| Field | Role |
|---|---|
children |
Working draft tree (autosave / Save / AI Apply·Promote·restoreDraft) |
title / slug |
Page identity |
actions |
Page lifecycle actions (e.g. onLoad) |
settings |
Access, theme patch, SEO, tabs-shell cache |
The live snapshot after Publish is not a field on this shape — see Preview & Publish. Do not invent page-level keys when synthesizing trees for import/API. See common/model/src/model/page-definition.model.ts. Autosave ≠ named Save ≠ Publish ≠ History — Preview & Publish.
type PropType = 'attr' | 'css' | 'url' | 'none';
interface IProp {
name: string;
value: IValue;
fallback?: IValue | string | number | boolean;
type?: PropType;
group?: string;
parentGroup?: string;
groupIdx?: number;
subGroupIdx?: number;
editorIdx?: number;
variance?: string;
resultExpr?: string;
responsive?: IResponsiveOverrides; // { tablet?, desktop? }
}
type IValue = { raw?: unknown; expr?: EvalExpressionInput; interval?: number };
| Rule | Detail |
|---|---|
| One mode | Prefer either raw or expr; do not treat both as a merged composition |
| Empty | ValueOps.isEmpty — missing/{}, empty string raw, or missing expr |
attr |
Host attribute / Ionic property |
css |
Style contribution (name often = CSS property; resultExpr may rewrite) |
url |
Bound URL |
none |
Logical / non-rendered (e.g. blockId on lkt-block) |
| Responsive | Only when PropDefinitionOps.isBreakpointResponsiveProp — type === 'css' or name class / style |
Editor-only fields belong on catalog definitions, not on every persisted instance prop. catalogElementToInstance keeps only name, type, value, fallback, variance, resultExpr (drops responsive, groups, options; omits root validators).
type EventType =
| 'click' | 'change' | 'mouseenter' | 'mouseleave'
| 'visible' | 'onLoad' | 'submitSuccess' | 'submitFailure';
Do not invent events. onLoad is page-only (PAGE_EVENT_TYPES). submitSuccess / submitFailure are offered only for lkt-form (ActionOps.eventTypesForElement). Full discriminators: Actions and validators.
ElementModel (canvas) assigns runtime id and may stamp version for undo/history. ElementModel.definition serializes:
typepropsactions / validators when presentchildren recursivelyBlockOps.createInstance(blockId, overrides) → { type: "lkt-block", props: [{ name: "blockId", type: "none", value: { raw } }], data?: { overrides } } — never the expanded master subtree. Schema may allow actions on lkt-block, but definition does not round-trip them.Strip before AJV: builder version stamps (SchemaService.validateChildren strips them).
{
"type": "ion-button",
"props": [
{ "name": "fill", "type": "attr", "value": { "raw": "solid" } }
],
"children": [
{
"type": "text",
"props": [
{ "name": "html", "value": { "raw": "Save" } },
{ "name": "wrapper", "value": { "raw": "span" } }
]
}
]
}
{
"type": "ion-button",
"id": "…",
"lkt_id": "…",
"version": 3,
"extraMadeUpKey": true
}