Canvas templates
A starting point a person can drop onto the canvas.
import { function canvasTemplate(template: Omit<CanvasTemplate, "kind">): CanvasTemplateDeclare a ready-made canvas element, filled in and named, for the insert menu. A template carries no renderer of its own. It names an existing `tag` and the attributes to stamp out with it, so one element can ship several starting points, sized and positioned, grouped and ordered in the picker. Introducing a tag is {@link canvasElement } . Offering a variant of a tag is this.canvasTemplate, function defineMod<const TMod extends ModDefinition>(definition: TMod & ValidateModHooks<TMod>): ModThe entry point of the SDK. A mod's module default-exports one `defineMod` call and nothing else. The returned value is data. It registers nothing, starts nothing, and touches no host state. The host folds it twice. At build time it runs the module in a throwaway sandbox and reads the value to derive the serializable manifest. At runtime it folds the same value again to wire your handlers into their lanes: ext-host for commands, tools, effects, and hooks; the sandboxed renderer for views and widgets. That double fold is why the module must be pure. It is re-executed to produce the manifest, so anything at the top level, a file read, a network call, a timer, a `console` line, runs during a build with no host attached. Put behavior inside handlers: `run`, `activate`, `handle`. The `ValidateModHooks` constraint makes the call fail to typecheck when a `hook.beforeAction` targets an action that is neither a known host action nor `command:` plus one of this mod's own command ids.defineMod } from '@modular/sdk'; export defaultdefineMod<{ readonly metadata: { readonly displayName: "Shapes"; readonly description: "Canvas work"; }; readonly canvas: readonly [CanvasTemplate]; }>(definition: { readonly metadata: { readonly displayName: "Shapes"; readonly description: "Canvas work"; }; readonly canvas: readonly [CanvasTemplate]; }): ModThe entry point of the SDK. A mod's module default-exports one `defineMod` call and nothing else. The returned value is data. It registers nothing, starts nothing, and touches no host state. The host folds it twice. At build time it runs the module in a throwaway sandbox and reads the value to derive the serializable manifest. At runtime it folds the same value again to wire your handlers into their lanes: ext-host for commands, tools, effects, and hooks; the sandboxed renderer for views and widgets. That double fold is why the module must be pure. It is re-executed to produce the manifest, so anything at the top level, a file read, a network call, a timer, a `console` line, runs during a build with no host attached. Put behavior inside handlers: `run`, `activate`, `handle`. The `ValidateModHooks` constraint makes the call fail to typecheck when a `hook.beforeAction` targets an action that is neither a known host action nor `command:` plus one of this mod's own command ids.defineMod({metadata: { readonly displayName: "Shapes"; readonly description: "Canvas work"; }metadata: { displayName: "Shapes"displayName: 'Shapes', description: "Canvas work"description: 'Canvas work' }, canvas: readonly [CanvasTemplate]canvas: [ function canvasTemplate(template: Omit<CanvasTemplate, "kind">): CanvasTemplateDeclare a ready-made canvas element, filled in and named, for the insert menu. A template carries no renderer of its own. It names an existing `tag` and the attributes to stamp out with it, so one element can ship several starting points, sized and positioned, grouped and ordered in the picker. Introducing a tag is {@link canvasElement } . Offering a variant of a tag is this.canvasTemplate({ id: stringid: 'shapes.sticky', label: stringlabel: 'Sticky note', element: CanvasTemplateElementelement: { CanvasTemplateElement.tag: stringtag: 'shapes-note', CanvasTemplateElement.attrs: Readonly<Record<string, CanvasTemplateAttrValue>>attrs: { colour: stringcolour: 'amber', text: stringtext: '' }, }, }), ], });
element is the element to place and the attributes to place it with, not an
element id. A template is a preset, so the attribute values are the preset.
Members
CanvasTemplate — id, label,
element, group, icon, order, kind.
element points at a canvas element by id. A template
does not define behaviour; it names an element and gives a person a labelled way
to reach it.
group and order are purely presentational — they decide where the template
sits in the picker. label is what a person reads, unlike the element's name.
Templates and elements are two jobs
An element says this kind of thing can exist. A template says here is a convenient one to start from. Shipping an element with no template means the capability exists but nothing offers it; shipping several templates over one element is normal.