Skip to content

The Shape record

A Shape is the unit the canvas stores:

type Shape = {
readonly id: ShapeId;
readonly frame: Frame;
readonly drawable: Drawable;
readonly index: ZIndex;
readonly style: Style;
readonly groupIds: readonly GroupId[];
};
Field Meaning
id The branded shape id
frame Where the shape is on the page, see Ids and frames
drawable What is inside the frame, see Drawables and geometry
index The shape’s place in the z-order, a fractional index string
style How the shape looks, see Style. Picking reads its fill
groupIds The groups the shape belongs to, innermost first and outermost last. Empty if none

ZIndex is a branded string, so a plain string cannot stand in for one. parseZIndex is the way in from outside.

Groups

A group has no record of its own. It is the set of shapes whose groupIds contain the same GroupId, as in Excalidraw. Grouping appends a fresh id to each member, so a shape in a group of groups carries two ids, the inner one first. Ungrouping drops the last id. ADR 0009 (docs/decisions/0009-groups.md) gives the reasons.

parseShape reads groupIds as an optional array of non-empty strings. A document saved before groups existed has no such field, and its shapes parse with an empty groupIds.