Узлы
Модель узлов
Что общего у всех узлов, чем они различаются и где описан каждый из них.
Документ — это дерево узлов. Каждый узел есть три вещи: id, вид и правило, по которому получается содержимое.
paragraph<MemberData>({
id: "greeting", // the address
render: (data) => `Dear ${data.memberName},`, // the rule
}); // the helper is the kind
Разрешённый на ваших данных, он превращается в обычный JSON:
{ "id": "greeting", "kind": "paragraph", "mode": "static", "text": "Dear Adaeze Nkemelu," }
Ни стилей, ни вёрстки. Это дело рендерера.
Каталог
У каждого типа есть своя страница со всеми принимаемыми опциями и предпросмотром каждого способа записи.
Структура
section Groups nodes under a titled heading.
The only construct that nests today. Its title carries into the document outline, so the structure you write is the structure the reader sees.
Хелперы: section, Section
export const Opening = section<SampleData>({ id: "opening", title: "Your renewal" }, [
Greeting,
PriceChange,
]); tableOfContents A marker for a contents list, ahead of the renderers that build one. Хелпера пока нет
The kind is part of the letter schema and both renderers accept it, but no authoring helper is exported yet. Writing the component by hand works — a node component is a function returning a definition, and the helpers are conveniences over exactly that shape.
export const Contents: NodeComponent<SampleData> = () => ({
kind: "tableOfContents",
id: "contents",
title: "What is in this letter",
}); Текст
paragraph A block of prose, rendered from your data or from prompts.
The workhorse. A static paragraph returns a string from your typed data; a dynamic one carries prompts and a placeholder, and is filled at request time. Both land as the same node kind, differing only by `mode`.
export const Greeting = paragraph<SampleData>({
id: "greeting",
render: (data) => `Dear ${data.memberName},`,
}); Медиа
image A picture resolved from your data or described by a prompt.
A static image points at something you hold — a signature, a logo, a site photograph — with every field able to vary per recipient. A dynamic image describes what is wanted and leaves the endpoint to make it.
export const Signature = image<SampleData>({
id: "signature",
src: (data) => data.signatureUrl,
alt: (data) => `Signed by ${data.managerName}`,
width: 180,
height: 60,
}); clipArt Named visual blocks — rules, marks, callouts — drawn by the renderer. В планах
Not built yet. Nothing is fetched: the node names a shape and the renderer draws it, so it stays sharp in the DOCX and ships no asset.
Данные
graph A bar, line or pie chart declared as data.
Charts are declared, never drawn: `graphType` fixes the form, `data` returns the payload. Holding numbers rather than an image means one declaration serves every renderer and stays diffable in the artifact.
export const VisitsByMonth = graph<SampleData>({
id: "visits-by-month",
graphType: "bar",
data: (data) => ({
labels: data.visitsByMonth.map((entry) => entry.month),
series: [{ name: "Visits", values: data.visitsByMonth.map((entry) => entry.visits) }],
}),
caption: (data) => `Your visits to ${data.centreName}, last six months`,
}); table Rows and columns, with cells that are themselves nodes. В планах
Not built yet. The intent is a node whose cells hold other nodes, so a table composes the way a section does rather than becoming a second content model beside it.
Идентификаторы — это адреса
Идентификатор узла — то, чем эндпоинт генерации адресует именно этот абзац, и то, по чему два артефакта сборки выстраиваются друг против друга в диффе. Переименование ломает всё, что ссылается на узел извне, — ровно как переименование маршрута API.
Держите их уникальными в пределах документа. Это ничего не стоит и делает логи читаемыми.
Статические и динамические
Статический узел вычисляет содержимое локально из ваших данных. Динамический узел несёт промпты и заполнитель и заполняется во время запроса.
Вы никогда не объявляете, какой вам нужен. На каждый вид есть один хелпер —
paragraph, image, graph, — а режим выводится из переданных опций: укажете
член локального разрешения (render, src, data) — узел статический; укажете
вместо этого промпты — динамический. Оба разрешаются в один и тот же kind и
различаются в собранном документе значением mode.
Указать и то и другое — ошибка компиляции, так что у mode ровно один источник
истины. О том, где проходит граница и почему, — Статика и
динамика.
Вложенность
section — сегодня единственный узел, содержащий
дочерние, и он принимает любой вид, включая другие разделы. Следующим будет узел
таблицы с узлами в ячейках, по тому же принципу: контейнеры содержат те
компоненты, которые вы и так пишете, а не вторую модель содержимого рядом с
ними.
Об этих предпросмотрах
Каждый предпросмотр здесь — настоящая сборка. В src/nodes/ репозитория этого
сайта лежит по файлу на вариант, написанному против опубликованного пакета; шаг
сборки разрешает каждый из них через buildDocument и отрисовывает тем же
рендерером, который отдаёт dxcl dev. Показанный исходник — это тот файл,
который выполнялся, а JSON — то, что вернулось. Поэтому такие страницы ломаются
громко, а не устаревают тихо.