Single-line and multiline regions
Loading interactive example…Open in new tab ↗
A card owns one canonical story with two named slots. The title is single-line; the body accepts paragraphs and lists. Double-click each region to edit it: Enter finishes the title, while Enter creates another block in the body.
Add body checklist appends a new block in the body with a fresh identity. Try title checklist submits an invalid story through the same public command. The shared grammar rejects it before publication, preserving document, selection and history. The shell displays the error; Undo remains available only for prior successful edits. Reset starts with the original two blocks and empty history.
Declare the slots
The built-in card already declares title and body using ShapeTextLayerDefinition. A custom shape uses those same definitions:
| Definition field | Purpose |
|---|---|
slotId | Matches canonical blocks to the named region. |
singleLine | Restricts the region to a line and determines Enter behavior. |
bounds | Places the region within the shape's resolved geometry. |
The story's title block has role: TextRole.title and slotId: 'title'. Body blocks use slotId: 'body'. All regions share the drawing's font catalog and canonical text commands; widgets do not maintain separate text.
dart
final before = session.document.shapeById('card')!.textStory!;
final item = TextParagraph(
id: DiagramTextCommands.nextBlockId(before),
kind: ParagraphKind.checklistItem,
slotId: 'body',
runs: [TextRun('Remember the blanket')],
);
session.text.replace(
elementId: 'card',
before: before,
after: before.copyWith(blocks: [...before.blocks, item]),
).requireAllowed();JSON retains block identities, roles, slots, marks and list kinds. Use Undo to restore an earlier edit or restore a saved JSON snapshot.
Source: apps/demo/lib/examples/text/regions.dart. See paragraph grammar.