Appearance
Presentation Shapes
A stable, plugin-owned shape lifecycle on Present-mode sheets. Accessed via snaptrude.presentation.shapes.
Where presentation.annotate is fire-and-forget (every call creates a new shape), this namespace keys each shape by a caller-chosen string — so rerunning an analysis updates its sheet output in place instead of duplicating it. Shape ids are derived deterministically from the plugin id + key, so upserts converge across collaborators, and every shape is stamped with the owning plugin's id: each plugin sees and mutates only its own shapes.
Mutations are gated on the plugin write floor and require Present (documentation) mode to be open; each mutation is a single undo step. list is a never-throw read.
Types
PluginPresentationShapeSpec
The desired shape for upsert — a discriminated union over the four annotate kinds, with the same option shapes as the matching presentation.annotate call. Positions/bounds are relative to the sheet's top-left, in canvas units.
type | Payload | Mirrors |
|---|---|---|
"text" | text, position?, size?, color? | annotate.text |
"note" | text, position?, color?, size? | annotate.note |
"arrow" | start, end, color?, size? | annotate.arrow |
"geo" | kind, bounds, color?, fill? | annotate.shape |
Option types (PluginAnnotateTextSize, PluginAnnotateTextColor, PluginAnnotateGeoKind, PluginAnnotateFill) are the annotate types — see Presentation Annotate.
PluginPresentationShapeType
The shape kind of a plugin-owned shape (the type discriminant above).
"text" | "note" | "arrow" | "geo"
PluginPresentationShapesUpsertResult
| Property | Type | Description |
|---|---|---|
shapeId | string | Stable id of the canvas shape for the key |
created | boolean | true if the shape was created, false if updated |
PluginPresentationShapesListResult
| Property | Type | Description |
|---|---|---|
shapes | { key: string; shapeId: string; type: PluginPresentationShapeType }[] | One entry per live plugin-owned shape |
Functions
upsert(key, shape, options?)
Create or update the shape for a key. On first call for a key the shape is created on the target sheet and nested under the sheet frame; on later calls the existing shape is updated in place — same shape id, same sheet, one undo step. Changing the spec's type for an existing key replaces the shape (same shape id).
- Parameters:
key:string— Caller-chosen stable identifier for the shape (per plugin, non-empty)shape:PluginPresentationShapeSpec— The desired shapeoptions?:sheetId?:string— The sheet to create the shape on (defaults to the first sheet; ignored on update — the shape stays on its sheet)
- Returns:
PluginPresentationShapesUpsertResult—{ shapeId, created } - Throws:
PRECONDITION_FAILEDif Present mode is not open or the presentation has no sheets;HANDLE_INVALIDifsheetIdis unknown or not a sheet;VALIDATIONon bad args; or if plugin writes are disabled
ts
// Rerunning this call updates the label instead of adding another one.
const { shapeId, created } = await snaptrude.presentation.shapes.upsert("far-label", {
type: "text",
text: "FAR: 2.4",
position: { x: 40, y: 40 },
color: "blue"
});remove(key)
Delete the shape for a key.
- Parameters:
key:string— The key passed toupsert(non-empty)
- Returns:
boolean—trueif a shape was deleted,falseif no shape exists for the key - Throws:
PRECONDITION_FAILEDif Present mode is not open;VALIDATIONon an empty key; or if plugin writes are disabled
ts
const removed = await snaptrude.presentation.shapes.remove("far-label");removeAll()
Delete every shape owned by the calling plugin (across all sheets), in one undo step.
- Returns:
number— The number of shapes deleted - Throws:
PRECONDITION_FAILEDif Present mode is not open; or if plugin writes are disabled
ts
const deleted = await snaptrude.presentation.shapes.removeAll();list()
List the calling plugin's shapes — one entry per live shape it has upserted. A never-throw read: returns an empty list when Present mode is closed.
- Returns:
PluginPresentationShapesListResult—{ shapes }, each{ key, shapeId, type }
ts
const { shapes } = await snaptrude.presentation.shapes.list();
const hasLabel = shapes.some((s) => s.key === "far-label");Errors
Failed calls reject with a typed PluginError — see Error Handling.
| Code | When |
|---|---|
VALIDATION | Bad arguments (empty key, malformed shape spec, non-positive geo w/h) |
PRECONDITION_FAILED | Present mode is not open on a mutation, or upsert finds no sheets in the presentation |
HANDLE_INVALID | options.sheetId is unknown or not a sheet |