Basis
Documenten en nodes
Een document is een boom van componenten, die elk hun data als state aannemen en de nodes teruggeven die ze willen.
Een document is een template plus een datatype. Het template is een boom van
componenten; elk geeft nodes terug, en de boom oplossen tegen data levert
een DocumentModel op — pure JSON, zonder dat daarmee iets over rendering gezegd
is.
Een component neemt zijn data als state
import { Paragraph, useState } from "docxcelerate/template";
import type { DocumentData } from "../types.ts";
export const Greeting: Paragraph = () => {
const [state] = useState((data: DocumentData) => ({
name: data.residentName,
}));
return <Paragraph id="greeting">Dear {state.name},</Paragraph>;
};
useState is waar data een component binnenkomt, en de enige plek. Alles daarna
leest state. Dat is een regel met een reden: doordat elke afhankelijkheid door
één declaratie loopt, staat opgeschreven wat een component nodig heeft in plaats
van verspreid door de code die het gebruikt.
De initializer is gewoon TypeScript. Er is geen templatetaal, dus condities, formattering en imports zijn simpelweg beschikbaar.
Paragraph benoemt zowel het element als het componenttype — een waarde en een
type mogen een naam delen — dus const Greeting: Paragraph zegt wat dit
oplevert, en er een <Section> uit teruggeven is een compileerfout.
Data kan ook als props binnenkomen
Een component die krijgt wat hij nodig heeft, hoeft er niet zelf naar te grijpen:
export const Arrears: Paragraph<{ amount: number }> = ({ amount }) => {
const { currency } = useFormat();
return <Paragraph id="arrears">You owe {currency(amount)}.</Paragraph>;
};
Iemand moet de data eerst lezen, dus een component met alleen props zit onder een ouder die ze als state heeft aangenomen. Gebruik props voor componenten die je tegen verschillende waarden wilt hergebruiken, en state voor componenten die weten bij welk document ze horen.
Beslissingen zijn een gewone if
export const Balance: Paragraph = () => {
const [state] = useState((data: DocumentData) => ({
settled: data.balanceDue === 0,
}));
if (state.settled) {
return <Paragraph id="settled">Nothing outstanding.</Paragraph>;
}
return <Paragraph id="arrears">A balance remains.</Paragraph>;
};
Geef elke tak zijn eigen id. Het opgeloste document legt dan vast welke deze ontvanger kreeg, en dat is het verschil tussen een document dat je kunt controleren en een dat je alleen kunt bekijken.
Er is één ding om te weten over vertakken voordat je naar een engine publiceert: zie wat er verandert bij publiceren.
Ids
Een id is hoe een engine een node adresseert en hoe buildartefacten tussen runs diffbaar blijven, dus behandel een hernoeming als een breaking change.
Je mag hem weglaten. Een node zonder id krijgt er een van waar hij staat, en dat voorkomt dat takken en lussen je dwingen namen te verzinnen. Wat niet kan, is er een twee keer gebruiken: twee nodes die één id claimen is een fout, gemeld met beide posities, en geen race die de laatste wint.
Secties nesten, nodes niet
Section is de enige constructie die nest. De titel gaat mee in de
documentstructuur:
<Section id="opening" title="Opening">
<Greeting />
<Offer />
</Section>
Zie Section voor wat een sectie mag bevatten en hoe diep.
Hooks
Hooks zijn hoe een component de build om zich heen bereikt:
| Hook | Wat het je geeft |
|---|---|
useState | Data, één keer aangenomen en bewaard |
useShared | Een waarde achtergelaten voor de componenten die daarna renderen |
useSetPrompts | Prompts voor de node die dit oplevert — wat hem dynamisch maakt |
useSetPlaceholders | Wat previews tonen in plaats van gegenereerde inhoud |
usePlaceholderData | Vervangende namen, datums en cijfers voor previews |
useFormat | Landinstellingbewuste valuta, datums, lijsten en meervouden |
useAvailableTokens | Het tokenbudget dat deze build heeft toegewezen |
useDeriver | Voert nu een geregistreerde deriver uit |
Ze lopen in aanroepvolgorde, dus elke hook moet bereikt zijn vóór de eerste
await en vóór elke vertakking — dezelfde regel die React hanteert, om dezelfde
reden. Er een aanroepen na een await is een fout die dat ook zegt, in plaats
van zich stilletjes vast te haken aan de volgende component die rendert.
Het document bouwen
import { buildDocument } from "docxcelerate";
const doc = await buildDocument(documentTemplate, data);
Het resultaat is een DocumentModel: een schemaVersion, een id, een title
en een nodes-array. Het bevat geen styling en geen lay-out — die worden later
toegepast door de renderer die het verwerkt.
Voor een documentproject gedefinieerd met defineDocumentProject gebruik je
liever buildProjectPreviewDocument, dat de stijl van het project toepast en
dynamische nodes naar hun placeholders oplost:
import { buildProjectPreviewDocument } from "docxcelerate";
const doc = await buildProjectPreviewDocument(project);
Dat is precies wat de preview-app aanroept, dus wat je in code bouwt komt overeen met wat je in de browser zag.
Deze pagina bewerken op GitHub ↗ Deze pagina als Markdown lezen