Zum Inhalt springen
Docxcelerate

Nodes

Section

Der einzige Node, der andere Nodes aufnimmt, und die Überschrift, zu der sein Titel wird.

The only construct that nests today. Its title carries into the document outline, so the structure you write is the structure the reader sees.

Helper
section, Section
Node-Art
section
Kategorie
Struktur
Wird aufgelöst
Locally
Kinder
Any node, including other sections. No depth limit.
Option Typ Was sie bewirkt
id erforderlich string Stable address for the node. Generation endpoints target it and build artifacts diff on it, so treat a rename as a breaking change.
title erforderlich string The heading printed above the children, and the outline entry.
nodes NodeComponent[] The children. Passed as the second argument, as the nodes option, or as JSX children of <Section> — the three are the same call.
derivers DeriverInvocation[] Values computed before the node resolves, written to derived.* and readable from a template token. Built with derive().

Einen schreiben

Ein Abschnitt bekommt seine Optionen und seine Kinder — Node-Komponenten, dieselben Werte, die Sie auch auf der obersten Ebene eines Dokuments platzieren würden:

import { section } from "docxcelerate";

export const Opening = section<MemberData>({ id: "opening", title: "Your renewal" }, [
  Greeting,
  PriceChange,
]);

In TSX liest sich derselbe Aufruf wie Markup:

<Section id="opening" title="Your renewal">
  <Greeting />
  <PriceChange />
</Section>

Beides ergibt denselben Baum. Templates behandelt, wann welche Form sich lohnt.

Kinder können alles sein

Absätze, Bilder, Diagramme, eine Inhaltsverzeichnis-Markierung oder weitere Abschnitte. Kein anderer Node hat Kinder, also ist die Tiefe eines Dokuments die Tiefe seiner Abschnitte.

An einem Node ändert sich nichts dadurch, dass er in einen Abschnitt wandert: Er löst sich in jeder Tiefe gleich auf, und seine id bekommt kein Präfix.

Titel wandern in die Gliederung

title ist erforderlich und keine Verzierung — daraus wird die Überschrift über den Kindern und der Eintrag, aus dem ein Inhaltsverzeichnis entsteht. Eine Gruppe, die keine Überschrift will, will keinen Abschnitt; setzen Sie die Nodes dann direkt ins Dokument.

Varianten

A titled group

src/nodes/section/basic.node.ts

Two paragraphs under one heading — the common case.

import { section } from "docxcelerate";
import { PriceChange } from "../paragraph/conditional.node.ts";
import { Greeting } from "../paragraph/static.node.ts";
import type { SampleData } from "../sample-data.ts";

/**
 * A section takes an id, a title and its children. The children are the same
 * node components you would place at the top level.
 */
export const Opening = section<SampleData>({ id: "opening", title: "Your renewal" }, [
  Greeting,
  PriceChange,
]);
section · a titled group Open ↗
Wozu es aufgelöst wird

Der Node, wie er im DocumentModel erscheint: das JSON, das ein Renderer bekommt. Kein Styling, kein Layout.

{
  "id": "opening",
  "kind": "section",
  "title": "Your renewal",
  "children": [
    {
      "id": "greeting",
      "kind": "paragraph",
      "mode": "static",
      "text": "Dear Adaeze Nkemelu,"
    },
    {
      "id": "price-change",
      "kind": "paragraph",
      "mode": "static",
      "text": "Your Peak Anytime membership is rising by 5.1%, from £468 to £492 a year. That is £41 a month from 1 October 2026."
    }
  ]
}

Mixed and nested children

src/nodes/section/nested.node.ts

A graph, then a nested section holding a graph and a dynamic paragraph.

import { section } from "docxcelerate";
import { ClassMix } from "../graph/pie.node.ts";
import { VisitsByMonth } from "../graph/bar.node.ts";
import { NextSteps } from "../paragraph/dynamic.node.ts";
import type { SampleData } from "../sample-data.ts";

/**
 * Children can be of any kind, including another section — the one place a
 * letter tree gains depth. The resolved document nests exactly as this reads.
 */
export const YourYear = section<SampleData>({ id: "your-year", title: "Your year here" }, [
  VisitsByMonth,
  section<SampleData>({ id: "activity-mix", title: "Where the time went" }, [
    ClassMix,
    NextSteps,
  ]),
]);
section · mixed and nested children Open ↗
Wozu es aufgelöst wird

Der Node, wie er im DocumentModel erscheint: das JSON, das ein Renderer bekommt. Kein Styling, kein Layout.

{
  "id": "your-year",
  "kind": "section",
  "title": "Your year here",
  "children": [
    {
      "id": "visits-by-month",
      "kind": "graph",
      "mode": "static",
      "graphType": "bar",
      "data": {
        "labels": [
          "Apr",
          "May",
          "Jun",
          "Jul",
          "Aug",
          "Sep"
        ],
        "series": [
          {
            "name": "Visits",
            "values": [
              11,
              14,
              9,
              16,
              18,
              12
            ]
          }
        ]
      },
      "caption": "Your visits to Riverside Leisure Centre, last six months"
    },
    {
      "id": "activity-mix",
      "kind": "section",
      "title": "Where the time went",
      "children": [
        {
          "id": "class-mix",
          "kind": "graph",
          "mode": "static",
          "graphType": "pie",
          "data": {
            "labels": [
              "Swim",
              "Strength",
              "Classes"
            ],
            "series": [
              {
                "name": "Share of visits",
                "values": [
                  42,
                  33,
                  25
                ]
              }
            ]
          },
          "caption": "How you used the centre, by activity"
        },
        {
          "id": "next-steps",
          "kind": "paragraph",
          "mode": "dynamic",
          "text": "Your membership renews automatically on 1 October 2026. Nothing is needed from you unless you want to change plan."
        }
      ]
    }
  ]
}

Anmerkungen

  • Die Tiefe steckt im Baum, nicht in den Überschriften. Beide mitgelieferten Renderer drucken jeden Abschnittstitel auf einer Ebene — <h2> im Browser, Überschrift 1 im DOCX — wie tief er auch verschachtelt ist. Das JSON verschachtelt korrekt, das ist also eine Beschränkung der Renderer; ein drei Ebenen tiefes Dokument sieht aber noch nicht drei Ebenen tief aus.
  • Einen dynamischen Abschnitt gibt es nicht. Ein Endpoint füllt Nodes aus; er entscheidet nicht, was das Dokument enthält.
  • Ein leerer Abschnitt rendert als einzelne Überschrift. Kommen die Kinder aus einem Filter, der leer laufen kann, prüfen Sie das weiter oben.

Diese Seite auf GitHub bearbeiten ↗