@pdfme/jsx 6.1.1-dev.8 → 6.1.2-dev.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +104 -12
- package/dist/components.d.ts +12 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +655 -58
- package/dist/index.js.map +1 -1
- package/dist/types.d.ts +89 -9
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,14 +1,25 @@
|
|
|
1
1
|
import { a as isPdfJsxElement, n as cloneElementWithChildren, o as isPdfJsxFragment, r as createElementNode } from "./node-BeNL0xMl.js";
|
|
2
|
-
import { getDefaultFont, pt2mm, resolvePageSize } from "@pdfme/common";
|
|
3
|
-
import { measureTextHeight } from "@pdfme/schemas/utils";
|
|
2
|
+
import { getDefaultFont, isBlankPdf, pt2mm, resolvePageSize } from "@pdfme/common";
|
|
3
|
+
import { escapeInlineMarkdown, getVariableNames, measureTextHeight, visitVariables } from "@pdfme/schemas/utils";
|
|
4
4
|
//#region src/components.ts
|
|
5
5
|
var makeBuiltin = (kind) => (props) => createElementNode(kind, props);
|
|
6
|
+
var Document = makeBuiltin("document");
|
|
6
7
|
var Page = makeBuiltin("page");
|
|
8
|
+
var Static = makeBuiltin("static");
|
|
9
|
+
var Header = makeBuiltin("header");
|
|
10
|
+
var Footer = makeBuiltin("footer");
|
|
11
|
+
var Absolute = makeBuiltin("absolute");
|
|
7
12
|
var Stack = makeBuiltin("stack");
|
|
8
13
|
var Row = makeBuiltin("row");
|
|
9
14
|
var Box = makeBuiltin("box");
|
|
10
15
|
var Spacer = makeBuiltin("spacer");
|
|
11
16
|
var Text = makeBuiltin("text");
|
|
17
|
+
var MultiVariableText = makeBuiltin("multiVariableText");
|
|
18
|
+
var Image = makeBuiltin("image");
|
|
19
|
+
var Svg = makeBuiltin("svg");
|
|
20
|
+
var Rectangle = makeBuiltin("rectangle");
|
|
21
|
+
var Ellipse = makeBuiltin("ellipse");
|
|
22
|
+
var Line = makeBuiltin("line");
|
|
12
23
|
var List = makeBuiltin("list");
|
|
13
24
|
var Table = makeBuiltin("table");
|
|
14
25
|
var PageBreak = (props) => createElementNode("pagebreak", props);
|
|
@@ -18,6 +29,10 @@ var DEFAULT_FONT_SIZE = 10;
|
|
|
18
29
|
var DEFAULT_LINE_HEIGHT = 1;
|
|
19
30
|
var DEFAULT_CHARACTER_SPACING = 0;
|
|
20
31
|
var DEFAULT_FONT_COLOR = "#000000";
|
|
32
|
+
var DEFAULT_VISUAL_HEIGHT = 40;
|
|
33
|
+
var DEFAULT_LINE_THICKNESS = .5;
|
|
34
|
+
var DEFAULT_LINE_COLOR = "#000000";
|
|
35
|
+
var DEFAULT_SHAPE_BORDER_COLOR = "#000000";
|
|
21
36
|
var DEFAULT_DYNAMIC_FONT_SIZE = {
|
|
22
37
|
min: 4,
|
|
23
38
|
max: 72,
|
|
@@ -25,7 +40,11 @@ var DEFAULT_DYNAMIC_FONT_SIZE = {
|
|
|
25
40
|
};
|
|
26
41
|
var renderToTemplate = async (node, options = {}) => {
|
|
27
42
|
validatePageBreakPlacement(node);
|
|
28
|
-
const
|
|
43
|
+
const root = resolveRenderRoot(node);
|
|
44
|
+
validateAbsolutePlacement(root.children);
|
|
45
|
+
validateStaticPlacement(root.children, root.hasDocument);
|
|
46
|
+
const { pages: rawPages, blocks: staticBlocks } = extractDocumentChildren(root);
|
|
47
|
+
const pages = rawPages.map((page) => applyDocumentPageDefaults(page, root.documentProps));
|
|
29
48
|
if (pages.length === 0) throw new Error("@pdfme/jsx: renderToTemplate root must contain at least one <Page>.");
|
|
30
49
|
const firstPageProps = pages[0]?.props;
|
|
31
50
|
const firstMargin = resolveBoxSides(firstPageProps.margin);
|
|
@@ -37,6 +56,21 @@ var renderToTemplate = async (node, options = {}) => {
|
|
|
37
56
|
const font = options.font ?? getDefaultFont();
|
|
38
57
|
const _cache = /* @__PURE__ */ new Map();
|
|
39
58
|
const pageSchemas = [];
|
|
59
|
+
const staticSchemas = [];
|
|
60
|
+
const hasStaticChildren = hasStaticBlocks(staticBlocks);
|
|
61
|
+
if (hasStaticChildren && options.basePdf != null && !isBlankPdf(options.basePdf)) throw new Error("@pdfme/jsx: <Header>, <Footer>, and <Static> are supported only with a blank basePdf.");
|
|
62
|
+
if (hasStaticChildren) await layoutStaticBlocks({
|
|
63
|
+
blocks: staticBlocks,
|
|
64
|
+
margin: firstMargin,
|
|
65
|
+
pageSize,
|
|
66
|
+
staticSchemas,
|
|
67
|
+
inputs,
|
|
68
|
+
usedNames,
|
|
69
|
+
nameCounters,
|
|
70
|
+
defaultFont: firstPageProps.font,
|
|
71
|
+
font,
|
|
72
|
+
_cache
|
|
73
|
+
});
|
|
40
74
|
for (const page of pages) {
|
|
41
75
|
const props = page.props;
|
|
42
76
|
const margin = resolveBoxSides(props.margin);
|
|
@@ -55,21 +89,29 @@ var renderToTemplate = async (node, options = {}) => {
|
|
|
55
89
|
font,
|
|
56
90
|
_cache
|
|
57
91
|
};
|
|
58
|
-
await layoutChildren(page.children, frame, "stack", {
|
|
92
|
+
await layoutChildren(page.children, frame, "stack", {
|
|
93
|
+
gap: 0,
|
|
94
|
+
alignItems: "stretch",
|
|
95
|
+
justifyContent: "start"
|
|
96
|
+
}, ctx);
|
|
59
97
|
pageSchemas.push(ctx.schemas);
|
|
60
98
|
}
|
|
99
|
+
const basePdf = options.basePdf ?? {
|
|
100
|
+
width: pageSize.width,
|
|
101
|
+
height: pageSize.height,
|
|
102
|
+
padding: [
|
|
103
|
+
firstMargin.top,
|
|
104
|
+
firstMargin.right,
|
|
105
|
+
firstMargin.bottom,
|
|
106
|
+
firstMargin.left
|
|
107
|
+
]
|
|
108
|
+
};
|
|
61
109
|
return {
|
|
62
110
|
template: {
|
|
63
|
-
basePdf:
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
firstMargin.top,
|
|
68
|
-
firstMargin.right,
|
|
69
|
-
firstMargin.bottom,
|
|
70
|
-
firstMargin.left
|
|
71
|
-
]
|
|
72
|
-
},
|
|
111
|
+
basePdf: staticSchemas.length > 0 && isBlankPdf(basePdf) ? {
|
|
112
|
+
...basePdf,
|
|
113
|
+
staticSchema: [...basePdf.staticSchema ?? [], ...staticSchemas]
|
|
114
|
+
} : basePdf,
|
|
73
115
|
schemas: pageSchemas
|
|
74
116
|
},
|
|
75
117
|
inputs: [inputs]
|
|
@@ -115,14 +157,141 @@ var flattenForSplitting = (children) => {
|
|
|
115
157
|
return [children];
|
|
116
158
|
};
|
|
117
159
|
var expandPageBreaks = (node) => splitChildrenByPageBreak(node).flat();
|
|
160
|
+
var STATIC_DIRECT_KINDS = new Set([
|
|
161
|
+
"header",
|
|
162
|
+
"footer",
|
|
163
|
+
"static"
|
|
164
|
+
]);
|
|
165
|
+
var createEmptyStaticBlocks = () => ({
|
|
166
|
+
footer: [],
|
|
167
|
+
header: [],
|
|
168
|
+
staticBottom: [],
|
|
169
|
+
staticTop: []
|
|
170
|
+
});
|
|
171
|
+
var resolveRenderRoot = (node) => {
|
|
172
|
+
const topLevelChildren = flattenChildren(node);
|
|
173
|
+
const documents = topLevelChildren.filter((child) => isPdfJsxElement(child) && child.kind === "document");
|
|
174
|
+
if (documents.length === 0) return {
|
|
175
|
+
children: expandPageBreaks(node),
|
|
176
|
+
hasDocument: false
|
|
177
|
+
};
|
|
178
|
+
if (documents.length > 1) throw new Error("@pdfme/jsx: only one <Document> root is supported.");
|
|
179
|
+
if (topLevelChildren.some((child) => child !== documents[0])) throw new Error("@pdfme/jsx: <Document> must be the only root element.");
|
|
180
|
+
const document = documents[0];
|
|
181
|
+
return {
|
|
182
|
+
children: expandPageBreaks(document.children),
|
|
183
|
+
documentProps: document.props,
|
|
184
|
+
hasDocument: true
|
|
185
|
+
};
|
|
186
|
+
};
|
|
187
|
+
var extractDocumentChildren = (root) => {
|
|
188
|
+
const blocks = createEmptyStaticBlocks();
|
|
189
|
+
const pages = [];
|
|
190
|
+
for (const child of flattenChildren(root.children)) {
|
|
191
|
+
if (!isPdfJsxElement(child)) continue;
|
|
192
|
+
if (child.kind === "page") {
|
|
193
|
+
pages.push(child);
|
|
194
|
+
continue;
|
|
195
|
+
}
|
|
196
|
+
if (!root.hasDocument || !STATIC_DIRECT_KINDS.has(child.kind)) continue;
|
|
197
|
+
if (child.kind === "header") blocks.header.push(...child.children);
|
|
198
|
+
else if (child.kind === "footer") blocks.footer.push(...child.children);
|
|
199
|
+
else if (child.kind === "static") blocks[getStaticPlacement(child) === "top" ? "staticTop" : "staticBottom"].push(...child.children);
|
|
200
|
+
}
|
|
201
|
+
return {
|
|
202
|
+
pages,
|
|
203
|
+
blocks
|
|
204
|
+
};
|
|
205
|
+
};
|
|
206
|
+
var applyDocumentPageDefaults = (page, documentProps) => {
|
|
207
|
+
if (!documentProps) return page;
|
|
208
|
+
const { children: _children, ...props } = documentProps;
|
|
209
|
+
return {
|
|
210
|
+
...page,
|
|
211
|
+
props: {
|
|
212
|
+
...props,
|
|
213
|
+
...page.props
|
|
214
|
+
}
|
|
215
|
+
};
|
|
216
|
+
};
|
|
217
|
+
var hasStaticBlocks = (blocks) => blocks.header.length > 0 || blocks.footer.length > 0 || blocks.staticTop.length > 0 || blocks.staticBottom.length > 0;
|
|
218
|
+
var layoutStaticBlocks = async (arg) => {
|
|
219
|
+
const contentWidth = Math.max(0, arg.pageSize.width - arg.margin.left - arg.margin.right);
|
|
220
|
+
const blockFrames = [
|
|
221
|
+
{
|
|
222
|
+
children: arg.blocks.staticTop,
|
|
223
|
+
frame: {
|
|
224
|
+
x: 0,
|
|
225
|
+
y: 0,
|
|
226
|
+
width: arg.pageSize.width,
|
|
227
|
+
height: arg.pageSize.height
|
|
228
|
+
}
|
|
229
|
+
},
|
|
230
|
+
{
|
|
231
|
+
children: arg.blocks.header,
|
|
232
|
+
frame: {
|
|
233
|
+
x: arg.margin.left,
|
|
234
|
+
y: 0,
|
|
235
|
+
width: contentWidth,
|
|
236
|
+
height: arg.margin.top
|
|
237
|
+
}
|
|
238
|
+
},
|
|
239
|
+
{
|
|
240
|
+
children: arg.blocks.footer,
|
|
241
|
+
frame: {
|
|
242
|
+
x: arg.margin.left,
|
|
243
|
+
y: arg.pageSize.height - arg.margin.bottom,
|
|
244
|
+
width: contentWidth,
|
|
245
|
+
height: arg.margin.bottom
|
|
246
|
+
}
|
|
247
|
+
},
|
|
248
|
+
{
|
|
249
|
+
children: arg.blocks.staticBottom,
|
|
250
|
+
frame: {
|
|
251
|
+
x: 0,
|
|
252
|
+
y: 0,
|
|
253
|
+
width: arg.pageSize.width,
|
|
254
|
+
height: arg.pageSize.height
|
|
255
|
+
},
|
|
256
|
+
placement: "bottom"
|
|
257
|
+
}
|
|
258
|
+
];
|
|
259
|
+
for (const { children, frame, placement } of blockFrames) {
|
|
260
|
+
if (children.length === 0) continue;
|
|
261
|
+
const schemas = [];
|
|
262
|
+
const size = await layoutChildren(children, frame, "stack", {
|
|
263
|
+
gap: 0,
|
|
264
|
+
alignItems: "stretch",
|
|
265
|
+
justifyContent: "start"
|
|
266
|
+
}, {
|
|
267
|
+
schemas,
|
|
268
|
+
inputs: arg.inputs,
|
|
269
|
+
usedNames: arg.usedNames,
|
|
270
|
+
nameCounters: arg.nameCounters,
|
|
271
|
+
defaultFont: arg.defaultFont,
|
|
272
|
+
font: arg.font,
|
|
273
|
+
_cache: arg._cache
|
|
274
|
+
});
|
|
275
|
+
if (placement === "bottom") shiftSchemas(schemas, 0, schemas.length, 0, Math.max(0, frame.height - size.height));
|
|
276
|
+
arg.staticSchemas.push(...schemas);
|
|
277
|
+
}
|
|
278
|
+
};
|
|
118
279
|
var layoutChildren = async (children, frame, mode, opts, ctx) => {
|
|
119
280
|
const items = flattenChildren(children);
|
|
120
|
-
const
|
|
281
|
+
const flowItems = items.filter((item) => !isAbsoluteElement(item));
|
|
282
|
+
const widths = mode === "row" ? resolveRowWidths(flowItems, frame.width, opts.gap) : void 0;
|
|
121
283
|
let cursor = 0;
|
|
122
284
|
let crossMax = 0;
|
|
285
|
+
let flowIndex = 0;
|
|
286
|
+
const layoutItems = [];
|
|
123
287
|
for (let i = 0; i < items.length; i += 1) {
|
|
124
288
|
const child = items[i];
|
|
125
|
-
|
|
289
|
+
if (isAbsoluteElement(child)) {
|
|
290
|
+
await renderAbsolute(child.props, child.children, frame, ctx);
|
|
291
|
+
continue;
|
|
292
|
+
}
|
|
293
|
+
const margin = getChildMargin(child);
|
|
294
|
+
const width = mode === "row" ? widths?.[flowIndex] ?? 0 : resolveStackChildWidth(child, frame.width, margin);
|
|
126
295
|
const childFrame = mode === "stack" ? {
|
|
127
296
|
x: frame.x,
|
|
128
297
|
y: frame.y + cursor,
|
|
@@ -134,68 +303,200 @@ var layoutChildren = async (children, frame, mode, opts, ctx) => {
|
|
|
134
303
|
width,
|
|
135
304
|
height: frame.height
|
|
136
305
|
};
|
|
306
|
+
childFrame.x += margin.left;
|
|
307
|
+
childFrame.y += margin.top;
|
|
308
|
+
childFrame.height = Math.max(0, childFrame.height - margin.top - margin.bottom);
|
|
309
|
+
const schemaStart = ctx.schemas.length;
|
|
137
310
|
const size = typeof child === "string" || typeof child === "number" ? await renderText({ children: String(child) }, childFrame, ctx) : await renderElement(child, childFrame, mode, ctx);
|
|
138
|
-
const
|
|
139
|
-
|
|
140
|
-
|
|
311
|
+
const schemaEnd = ctx.schemas.length;
|
|
312
|
+
const mainSize = mode === "stack" ? margin.top + size.height + margin.bottom : margin.left + width + margin.right;
|
|
313
|
+
const outerHeight = margin.top + size.height + margin.bottom;
|
|
314
|
+
layoutItems.push({
|
|
315
|
+
schemaStart,
|
|
316
|
+
schemaEnd,
|
|
317
|
+
outerHeight
|
|
318
|
+
});
|
|
319
|
+
if (mode === "stack") {
|
|
320
|
+
const outerWidth = margin.left + size.width + margin.right;
|
|
321
|
+
const dx = resolveAlignOffset(frame.width, outerWidth, opts.alignItems);
|
|
322
|
+
if (dx !== 0) shiftSchemas(ctx.schemas, schemaStart, schemaEnd, dx, 0);
|
|
323
|
+
}
|
|
324
|
+
cursor += mainSize + (flowIndex < flowItems.length - 1 ? opts.gap : 0);
|
|
325
|
+
flowIndex += 1;
|
|
326
|
+
crossMax = Math.max(crossMax, mode === "stack" ? margin.left + size.width + margin.right : margin.top + size.height + margin.bottom);
|
|
327
|
+
}
|
|
328
|
+
const contentMainSize = cursor;
|
|
329
|
+
const containerMainSize = opts.mainSize ?? contentMainSize;
|
|
330
|
+
applyJustifyContent(ctx.schemas, layoutItems, mode, contentMainSize, containerMainSize, opts);
|
|
331
|
+
if (mode === "row") {
|
|
332
|
+
const rowHeight = opts.crossSize ?? crossMax;
|
|
333
|
+
for (const item of layoutItems) {
|
|
334
|
+
const dy = resolveAlignOffset(rowHeight, item.outerHeight, opts.alignItems);
|
|
335
|
+
if (dy !== 0) shiftSchemas(ctx.schemas, item.schemaStart, item.schemaEnd, 0, dy);
|
|
336
|
+
}
|
|
337
|
+
return {
|
|
338
|
+
width: containerMainSize,
|
|
339
|
+
height: rowHeight
|
|
340
|
+
};
|
|
141
341
|
}
|
|
142
|
-
return
|
|
342
|
+
return {
|
|
143
343
|
width: crossMax,
|
|
144
|
-
height:
|
|
145
|
-
} : {
|
|
146
|
-
width: cursor,
|
|
147
|
-
height: crossMax
|
|
344
|
+
height: containerMainSize
|
|
148
345
|
};
|
|
149
346
|
};
|
|
150
347
|
var resolveRowWidths = (items, frameWidth, gap) => {
|
|
151
|
-
let
|
|
152
|
-
let
|
|
153
|
-
const
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
348
|
+
let usedWidth = 0;
|
|
349
|
+
let totalGrow = 0;
|
|
350
|
+
const parts = items.map((item) => {
|
|
351
|
+
const margin = getChildMargin(item);
|
|
352
|
+
const width = getChildWidth(item);
|
|
353
|
+
const grow = getChildFlexGrow(item) ?? (width == null ? 1 : 0);
|
|
354
|
+
const basis = width ?? 0;
|
|
355
|
+
usedWidth += basis + margin.left + margin.right;
|
|
356
|
+
totalGrow += grow;
|
|
357
|
+
return {
|
|
358
|
+
basis,
|
|
359
|
+
grow
|
|
360
|
+
};
|
|
164
361
|
});
|
|
165
|
-
const remaining = Math.max(0, frameWidth -
|
|
166
|
-
const
|
|
167
|
-
return
|
|
362
|
+
const remaining = Math.max(0, frameWidth - usedWidth - Math.max(0, items.length - 1) * gap);
|
|
363
|
+
const flexUnit = totalGrow > 0 ? remaining / totalGrow : 0;
|
|
364
|
+
return parts.map(({ basis, grow }) => basis + grow * flexUnit);
|
|
365
|
+
};
|
|
366
|
+
var getChildMargin = (child) => {
|
|
367
|
+
if (typeof child === "string" || typeof child === "number") return resolveBoxSides();
|
|
368
|
+
return resolveBoxSides(child.props.margin);
|
|
369
|
+
};
|
|
370
|
+
var getChildWidth = (child) => {
|
|
371
|
+
if (typeof child === "string" || typeof child === "number") return void 0;
|
|
372
|
+
const width = child.props.width;
|
|
373
|
+
return typeof width === "number" ? width : void 0;
|
|
374
|
+
};
|
|
375
|
+
var getChildFlexGrow = (child) => {
|
|
376
|
+
if (typeof child === "string" || typeof child === "number") return void 0;
|
|
377
|
+
const props = child.props;
|
|
378
|
+
const flexGrow = props.flexGrow ?? props.flex;
|
|
379
|
+
return typeof flexGrow === "number" ? Math.max(0, flexGrow) : void 0;
|
|
380
|
+
};
|
|
381
|
+
var isAbsoluteElement = (child) => isPdfJsxElement(child) && child.kind === "absolute";
|
|
382
|
+
var getStaticPlacement = (element) => {
|
|
383
|
+
const placement = element.props.placement ?? "top";
|
|
384
|
+
if (placement !== "top" && placement !== "bottom") throw new Error("@pdfme/jsx: <Static> placement must be \"top\" or \"bottom\".");
|
|
385
|
+
return placement;
|
|
386
|
+
};
|
|
387
|
+
var resolveStackChildWidth = (child, frameWidth, margin) => {
|
|
388
|
+
const width = getChildWidth(child);
|
|
389
|
+
if (width != null) return width;
|
|
390
|
+
return Math.max(0, frameWidth - margin.left - margin.right);
|
|
391
|
+
};
|
|
392
|
+
var applyJustifyContent = (schemas, items, mode, contentMainSize, containerMainSize, opts) => {
|
|
393
|
+
const extraSpace = Math.max(0, containerMainSize - contentMainSize);
|
|
394
|
+
if (extraSpace === 0 || opts.justifyContent === "start") return;
|
|
395
|
+
const extraGap = opts.justifyContent === "space-between" && items.length > 1 ? extraSpace / (items.length - 1) : 0;
|
|
396
|
+
const startOffset = opts.justifyContent === "center" ? extraSpace / 2 : opts.justifyContent === "end" ? extraSpace : 0;
|
|
397
|
+
let runningExtraGap = 0;
|
|
398
|
+
for (const item of items) {
|
|
399
|
+
const offset = startOffset + runningExtraGap;
|
|
400
|
+
if (offset !== 0) shiftSchemas(schemas, item.schemaStart, item.schemaEnd, mode === "row" ? offset : 0, mode === "stack" ? offset : 0);
|
|
401
|
+
runningExtraGap += extraGap;
|
|
402
|
+
}
|
|
403
|
+
};
|
|
404
|
+
var resolveAlignOffset = (containerSize, itemSize, alignItems) => {
|
|
405
|
+
if (alignItems === "center") return Math.max(0, (containerSize - itemSize) / 2);
|
|
406
|
+
if (alignItems === "end") return Math.max(0, containerSize - itemSize);
|
|
407
|
+
return 0;
|
|
408
|
+
};
|
|
409
|
+
var shiftSchemas = (schemas, start, end, dx, dy) => {
|
|
410
|
+
for (let i = start; i < end; i += 1) {
|
|
411
|
+
const schema = schemas[i];
|
|
412
|
+
if (!schema) continue;
|
|
413
|
+
schema.position = {
|
|
414
|
+
x: schema.position.x + dx,
|
|
415
|
+
y: schema.position.y + dy
|
|
416
|
+
};
|
|
417
|
+
}
|
|
168
418
|
};
|
|
169
419
|
var renderElement = async (element, frame, parentMode, ctx) => {
|
|
420
|
+
const props = parentMode === "row" && getChildFlexGrow(element) != null ? {
|
|
421
|
+
...element.props,
|
|
422
|
+
width: frame.width
|
|
423
|
+
} : element.props;
|
|
170
424
|
switch (element.kind) {
|
|
171
|
-
case "stack": return renderStack(
|
|
172
|
-
case "row": return renderRow(
|
|
173
|
-
case "box": return renderBox(
|
|
174
|
-
case "spacer": return Promise.resolve(renderSpacer(
|
|
425
|
+
case "stack": return renderStack(props, element.children, frame, ctx);
|
|
426
|
+
case "row": return renderRow(props, element.children, frame, ctx);
|
|
427
|
+
case "box": return renderBox(props, element.children, frame, parentMode, ctx);
|
|
428
|
+
case "spacer": return Promise.resolve(renderSpacer(props));
|
|
175
429
|
case "text": return renderText({
|
|
176
|
-
...
|
|
430
|
+
...props,
|
|
431
|
+
children: element.children
|
|
432
|
+
}, frame, ctx);
|
|
433
|
+
case "multiVariableText": return renderMultiVariableText({
|
|
434
|
+
...props,
|
|
435
|
+
children: element.children
|
|
436
|
+
}, frame, ctx);
|
|
437
|
+
case "image": return renderImage(props, frame, ctx);
|
|
438
|
+
case "svg": return renderSvg({
|
|
439
|
+
...props,
|
|
177
440
|
children: element.children
|
|
178
441
|
}, frame, ctx);
|
|
442
|
+
case "rectangle": return renderShape("rectangle", props, frame, ctx);
|
|
443
|
+
case "ellipse": return renderShape("ellipse", props, frame, ctx);
|
|
444
|
+
case "line": return renderLine(props, frame, ctx);
|
|
179
445
|
case "list": return renderList({
|
|
180
|
-
...
|
|
446
|
+
...props,
|
|
181
447
|
children: element.children
|
|
182
448
|
}, frame, ctx);
|
|
183
|
-
case "table": return renderTable(
|
|
449
|
+
case "table": return renderTable(props, frame, ctx);
|
|
450
|
+
case "document": throw new Error("@pdfme/jsx: <Document> must be the root element.");
|
|
451
|
+
case "header":
|
|
452
|
+
case "footer":
|
|
453
|
+
case "static": throw new Error("@pdfme/jsx: <Header>, <Footer>, and <Static> can only be used as direct children of <Document>.");
|
|
454
|
+
case "absolute": return renderAbsolute(props, element.children, frame, ctx);
|
|
184
455
|
default: return {
|
|
185
456
|
width: 0,
|
|
186
457
|
height: 0
|
|
187
458
|
};
|
|
188
459
|
}
|
|
189
460
|
};
|
|
461
|
+
var renderAbsolute = async (props, children, frame, ctx) => {
|
|
462
|
+
const x = props.x ?? 0;
|
|
463
|
+
const y = props.y ?? 0;
|
|
464
|
+
await layoutChildren(children, {
|
|
465
|
+
x: frame.x + x,
|
|
466
|
+
y: frame.y + y,
|
|
467
|
+
width: props.width ?? Math.max(0, frame.width - x),
|
|
468
|
+
height: props.height ?? Math.max(0, frame.height - y)
|
|
469
|
+
}, "stack", {
|
|
470
|
+
gap: 0,
|
|
471
|
+
alignItems: "stretch",
|
|
472
|
+
justifyContent: "start"
|
|
473
|
+
}, ctx);
|
|
474
|
+
return {
|
|
475
|
+
width: 0,
|
|
476
|
+
height: 0
|
|
477
|
+
};
|
|
478
|
+
};
|
|
190
479
|
var renderStack = (props, children, frame, ctx) => layoutChildren(children, {
|
|
191
480
|
...frame,
|
|
192
|
-
width: props.width ?? frame.width
|
|
193
|
-
|
|
481
|
+
width: props.width ?? frame.width,
|
|
482
|
+
height: props.height ?? frame.height
|
|
483
|
+
}, "stack", {
|
|
484
|
+
gap: props.gap ?? 0,
|
|
485
|
+
alignItems: props.alignItems ?? "stretch",
|
|
486
|
+
justifyContent: props.justifyContent ?? "start",
|
|
487
|
+
mainSize: props.height
|
|
488
|
+
}, ctx);
|
|
194
489
|
var renderRow = (props, children, frame, ctx) => layoutChildren(children, {
|
|
195
490
|
...frame,
|
|
196
491
|
width: props.width ?? frame.width,
|
|
197
492
|
height: props.height ?? frame.height
|
|
198
|
-
}, "row", {
|
|
493
|
+
}, "row", {
|
|
494
|
+
gap: props.gap ?? 0,
|
|
495
|
+
alignItems: props.alignItems ?? "start",
|
|
496
|
+
justifyContent: props.justifyContent ?? "start",
|
|
497
|
+
mainSize: props.width,
|
|
498
|
+
crossSize: props.height
|
|
499
|
+
}, ctx);
|
|
199
500
|
var renderBox = async (props, children, frame, _parentMode, ctx) => {
|
|
200
501
|
const width = props.width ?? frame.width;
|
|
201
502
|
const padding = resolveBoxSides(props.padding);
|
|
@@ -223,7 +524,11 @@ var renderBox = async (props, children, frame, _parentMode, ctx) => {
|
|
|
223
524
|
y: frame.y + padding.top,
|
|
224
525
|
width: width - padding.left - padding.right,
|
|
225
526
|
height: (props.height ?? frame.height) - padding.top - padding.bottom
|
|
226
|
-
}, "stack", {
|
|
527
|
+
}, "stack", {
|
|
528
|
+
gap: 0,
|
|
529
|
+
alignItems: "stretch",
|
|
530
|
+
justifyContent: "start"
|
|
531
|
+
}, ctx);
|
|
227
532
|
const height = props.height ?? childSize.height + padding.top + padding.bottom;
|
|
228
533
|
if (needsRect) ctx.schemas[beforeCount] = {
|
|
229
534
|
...ctx.schemas[beforeCount],
|
|
@@ -243,8 +548,10 @@ var renderText = async (props, frame, ctx) => {
|
|
|
243
548
|
const lineHeight = props.lineHeight ?? DEFAULT_LINE_HEIGHT;
|
|
244
549
|
const width = props.width ?? frame.width;
|
|
245
550
|
const value = childrenToString(props.children);
|
|
246
|
-
const name = resolveName(ctx, "text", props.name);
|
|
247
551
|
const readOnly = props.readOnly ?? props.name == null;
|
|
552
|
+
const textFormat = props.textFormat ?? "plain";
|
|
553
|
+
if (!readOnly && textFormat === "inline-markdown") throw new Error("@pdfme/jsx: editable <Text> does not support textFormat=\"inline-markdown\". Use read-only <Text> or <MultiVariableText>.");
|
|
554
|
+
const name = resolveName(ctx, "text", props.name);
|
|
248
555
|
const schema = {
|
|
249
556
|
name,
|
|
250
557
|
type: "text",
|
|
@@ -267,13 +574,14 @@ var renderText = async (props, frame, ctx) => {
|
|
|
267
574
|
characterSpacing: props.spacing ?? DEFAULT_CHARACTER_SPACING,
|
|
268
575
|
fontColor: props.color ?? DEFAULT_FONT_COLOR,
|
|
269
576
|
backgroundColor: props.background ?? "",
|
|
270
|
-
textFormat
|
|
577
|
+
textFormat,
|
|
271
578
|
overflow: props.overflow,
|
|
272
579
|
strikethrough: props.strikethrough ?? false,
|
|
273
580
|
underline: props.underline ?? false
|
|
274
581
|
};
|
|
275
582
|
if (props.borderColor) schema.borderColor = props.borderColor;
|
|
276
|
-
if (props.borderWidth != null) schema.borderWidth = props.borderWidth;
|
|
583
|
+
if (props.borderWidth != null) schema.borderWidth = resolveBoxSides(props.borderWidth);
|
|
584
|
+
if (props.padding != null) schema.padding = resolveBoxSides(props.padding);
|
|
277
585
|
if (props.dynamicFontSize) schema.dynamicFontSize = {
|
|
278
586
|
min: props.dynamicFontSize.min ?? DEFAULT_DYNAMIC_FONT_SIZE.min,
|
|
279
587
|
max: props.dynamicFontSize.max ?? DEFAULT_DYNAMIC_FONT_SIZE.max,
|
|
@@ -292,6 +600,174 @@ var renderText = async (props, frame, ctx) => {
|
|
|
292
600
|
height: schema.height
|
|
293
601
|
};
|
|
294
602
|
};
|
|
603
|
+
var renderMultiVariableText = async (props, frame, ctx) => {
|
|
604
|
+
const fontSize = props.size ?? DEFAULT_FONT_SIZE;
|
|
605
|
+
const lineHeight = props.lineHeight ?? DEFAULT_LINE_HEIGHT;
|
|
606
|
+
const width = props.width ?? frame.width;
|
|
607
|
+
const templateText = props.text ?? childrenToString(props.children);
|
|
608
|
+
const values = normalizeMultiVariableTextValues(props.values);
|
|
609
|
+
const variables = resolveMultiVariableTextVariables(templateText, props.variables, values);
|
|
610
|
+
const name = resolveName(ctx, "multiVariableText", props.name);
|
|
611
|
+
const readOnly = props.readOnly ?? props.name == null;
|
|
612
|
+
const textFormat = props.textFormat ?? "plain";
|
|
613
|
+
const content = readOnly ? substituteMultiVariableText(templateText, values, textFormat === "inline-markdown") : JSON.stringify(values);
|
|
614
|
+
const schema = {
|
|
615
|
+
name,
|
|
616
|
+
type: "multiVariableText",
|
|
617
|
+
content,
|
|
618
|
+
position: {
|
|
619
|
+
x: frame.x,
|
|
620
|
+
y: frame.y
|
|
621
|
+
},
|
|
622
|
+
width,
|
|
623
|
+
height: props.height ?? 0,
|
|
624
|
+
rotate: props.rotate ?? 0,
|
|
625
|
+
opacity: props.opacity ?? 1,
|
|
626
|
+
readOnly,
|
|
627
|
+
required: props.required,
|
|
628
|
+
alignment: props.align ?? "left",
|
|
629
|
+
verticalAlignment: props.valign ?? "top",
|
|
630
|
+
fontSize,
|
|
631
|
+
fontName: props.font ?? ctx.defaultFont,
|
|
632
|
+
lineHeight,
|
|
633
|
+
characterSpacing: props.spacing ?? DEFAULT_CHARACTER_SPACING,
|
|
634
|
+
fontColor: props.color ?? DEFAULT_FONT_COLOR,
|
|
635
|
+
backgroundColor: props.background ?? "",
|
|
636
|
+
textFormat,
|
|
637
|
+
overflow: props.overflow,
|
|
638
|
+
strikethrough: props.strikethrough ?? false,
|
|
639
|
+
underline: props.underline ?? false,
|
|
640
|
+
text: templateText,
|
|
641
|
+
variables
|
|
642
|
+
};
|
|
643
|
+
if (props.borderColor) schema.borderColor = props.borderColor;
|
|
644
|
+
if (props.borderWidth != null) schema.borderWidth = resolveBoxSides(props.borderWidth);
|
|
645
|
+
if (props.padding != null) schema.padding = resolveBoxSides(props.padding);
|
|
646
|
+
if (props.dynamicFontSize) schema.dynamicFontSize = {
|
|
647
|
+
min: props.dynamicFontSize.min ?? DEFAULT_DYNAMIC_FONT_SIZE.min,
|
|
648
|
+
max: props.dynamicFontSize.max ?? DEFAULT_DYNAMIC_FONT_SIZE.max,
|
|
649
|
+
fit: props.dynamicFontSize.fit ?? DEFAULT_DYNAMIC_FONT_SIZE.fit
|
|
650
|
+
};
|
|
651
|
+
if (props.height == null) schema.height = await measureTextHeight({
|
|
652
|
+
value: readOnly ? content : substituteMultiVariableText(templateText, values, textFormat === "inline-markdown"),
|
|
653
|
+
schema,
|
|
654
|
+
font: ctx.font,
|
|
655
|
+
_cache: ctx._cache
|
|
656
|
+
});
|
|
657
|
+
if (!readOnly) ctx.inputs[name] = content;
|
|
658
|
+
ctx.schemas.push(schema);
|
|
659
|
+
return {
|
|
660
|
+
width,
|
|
661
|
+
height: schema.height
|
|
662
|
+
};
|
|
663
|
+
};
|
|
664
|
+
var renderImage = (props, frame, ctx) => {
|
|
665
|
+
const width = props.width ?? frame.width;
|
|
666
|
+
const height = props.height ?? DEFAULT_VISUAL_HEIGHT;
|
|
667
|
+
const name = resolveName(ctx, "image", props.name);
|
|
668
|
+
const readOnly = props.readOnly ?? props.name == null;
|
|
669
|
+
const content = props.src ?? "";
|
|
670
|
+
const schema = {
|
|
671
|
+
name,
|
|
672
|
+
type: "image",
|
|
673
|
+
content,
|
|
674
|
+
position: {
|
|
675
|
+
x: frame.x,
|
|
676
|
+
y: frame.y
|
|
677
|
+
},
|
|
678
|
+
width,
|
|
679
|
+
height,
|
|
680
|
+
rotate: props.rotate ?? 0,
|
|
681
|
+
opacity: props.opacity ?? 1,
|
|
682
|
+
readOnly,
|
|
683
|
+
required: props.required
|
|
684
|
+
};
|
|
685
|
+
if (!readOnly) ctx.inputs[name] = content;
|
|
686
|
+
ctx.schemas.push(schema);
|
|
687
|
+
return {
|
|
688
|
+
width,
|
|
689
|
+
height
|
|
690
|
+
};
|
|
691
|
+
};
|
|
692
|
+
var renderSvg = (props, frame, ctx) => {
|
|
693
|
+
const width = props.width ?? frame.width;
|
|
694
|
+
const height = props.height ?? DEFAULT_VISUAL_HEIGHT;
|
|
695
|
+
const name = resolveName(ctx, "svg", props.name);
|
|
696
|
+
const readOnly = props.readOnly ?? props.name == null;
|
|
697
|
+
const content = props.svg ?? childrenToString(props.children);
|
|
698
|
+
const schema = {
|
|
699
|
+
name,
|
|
700
|
+
type: "svg",
|
|
701
|
+
content,
|
|
702
|
+
position: {
|
|
703
|
+
x: frame.x,
|
|
704
|
+
y: frame.y
|
|
705
|
+
},
|
|
706
|
+
width,
|
|
707
|
+
height,
|
|
708
|
+
rotate: props.rotate ?? 0,
|
|
709
|
+
opacity: props.opacity ?? 1,
|
|
710
|
+
readOnly,
|
|
711
|
+
required: props.required
|
|
712
|
+
};
|
|
713
|
+
if (!readOnly) ctx.inputs[name] = content;
|
|
714
|
+
ctx.schemas.push(schema);
|
|
715
|
+
return {
|
|
716
|
+
width,
|
|
717
|
+
height
|
|
718
|
+
};
|
|
719
|
+
};
|
|
720
|
+
var renderShape = (type, props, frame, ctx) => {
|
|
721
|
+
const width = props.width ?? frame.width;
|
|
722
|
+
const height = props.height ?? DEFAULT_VISUAL_HEIGHT;
|
|
723
|
+
const fill = props.fill ?? "";
|
|
724
|
+
const borderWidth = props.borderWidth ?? (props.borderColor || !fill ? 1 : 0);
|
|
725
|
+
const schema = {
|
|
726
|
+
name: resolveName(ctx, type, props.name),
|
|
727
|
+
type,
|
|
728
|
+
position: {
|
|
729
|
+
x: frame.x,
|
|
730
|
+
y: frame.y
|
|
731
|
+
},
|
|
732
|
+
width,
|
|
733
|
+
height,
|
|
734
|
+
rotate: props.rotate ?? 0,
|
|
735
|
+
opacity: props.opacity ?? 1,
|
|
736
|
+
readOnly: true,
|
|
737
|
+
borderWidth,
|
|
738
|
+
borderColor: props.borderColor ?? (borderWidth > 0 ? DEFAULT_SHAPE_BORDER_COLOR : ""),
|
|
739
|
+
color: fill,
|
|
740
|
+
radius: type === "rectangle" ? props.radius ?? 0 : 0
|
|
741
|
+
};
|
|
742
|
+
ctx.schemas.push(schema);
|
|
743
|
+
return {
|
|
744
|
+
width,
|
|
745
|
+
height
|
|
746
|
+
};
|
|
747
|
+
};
|
|
748
|
+
var renderLine = (props, frame, ctx) => {
|
|
749
|
+
const width = props.width ?? frame.width;
|
|
750
|
+
const height = props.height ?? DEFAULT_LINE_THICKNESS;
|
|
751
|
+
const schema = {
|
|
752
|
+
name: resolveName(ctx, "line", props.name),
|
|
753
|
+
type: "line",
|
|
754
|
+
position: {
|
|
755
|
+
x: frame.x,
|
|
756
|
+
y: frame.y
|
|
757
|
+
},
|
|
758
|
+
width,
|
|
759
|
+
height,
|
|
760
|
+
rotate: props.rotate ?? 0,
|
|
761
|
+
opacity: props.opacity ?? 1,
|
|
762
|
+
readOnly: true,
|
|
763
|
+
color: props.color ?? DEFAULT_LINE_COLOR
|
|
764
|
+
};
|
|
765
|
+
ctx.schemas.push(schema);
|
|
766
|
+
return {
|
|
767
|
+
width,
|
|
768
|
+
height
|
|
769
|
+
};
|
|
770
|
+
};
|
|
295
771
|
var renderList = (props, frame, ctx) => {
|
|
296
772
|
const fontSize = props.size ?? DEFAULT_FONT_SIZE;
|
|
297
773
|
const lineHeight = props.lineHeight ?? DEFAULT_LINE_HEIGHT;
|
|
@@ -363,7 +839,7 @@ var renderTable = (props, frame, ctx) => {
|
|
|
363
839
|
showHead,
|
|
364
840
|
repeatHead: props.repeatHead ?? false,
|
|
365
841
|
head: props.head,
|
|
366
|
-
headWidthPercentages:
|
|
842
|
+
headWidthPercentages: normalizeColumnWeights(props.columnWeights, props.head.length),
|
|
367
843
|
tableStyles: {
|
|
368
844
|
borderColor: props.tableStyles?.borderColor ?? "#000000",
|
|
369
845
|
borderWidth: props.tableStyles?.borderWidth ?? .3
|
|
@@ -402,8 +878,47 @@ var normalizeListItems = (props) => {
|
|
|
402
878
|
}));
|
|
403
879
|
};
|
|
404
880
|
var serializeListItem = (item) => `${" ".repeat(Math.max(0, item.level))}${item.text}`;
|
|
405
|
-
var
|
|
406
|
-
|
|
881
|
+
var normalizeMultiVariableTextValues = (values) => {
|
|
882
|
+
const normalized = {};
|
|
883
|
+
Object.entries(values ?? {}).forEach(([key, value]) => {
|
|
884
|
+
normalized[key] = value == null ? "" : String(value);
|
|
885
|
+
});
|
|
886
|
+
return normalized;
|
|
887
|
+
};
|
|
888
|
+
var resolveMultiVariableTextVariables = (templateText, variables, values) => {
|
|
889
|
+
const result = [];
|
|
890
|
+
const seen = /* @__PURE__ */ new Set();
|
|
891
|
+
const add = (name) => {
|
|
892
|
+
if (!seen.has(name)) {
|
|
893
|
+
seen.add(name);
|
|
894
|
+
result.push(name);
|
|
895
|
+
}
|
|
896
|
+
};
|
|
897
|
+
variables?.forEach(add);
|
|
898
|
+
getVariableNames(templateText).forEach(add);
|
|
899
|
+
Object.keys(values).forEach(add);
|
|
900
|
+
return result;
|
|
901
|
+
};
|
|
902
|
+
var substituteMultiVariableText = (templateText, values, escapeMarkdown) => {
|
|
903
|
+
let result = "";
|
|
904
|
+
let lastIndex = 0;
|
|
905
|
+
visitVariables(templateText, ({ name, startIndex, endIndex }) => {
|
|
906
|
+
result += templateText.slice(lastIndex, startIndex);
|
|
907
|
+
const value = values[name];
|
|
908
|
+
if (value != null) result += escapeMarkdown ? escapeInlineMarkdown(value) : value;
|
|
909
|
+
lastIndex = endIndex + 1;
|
|
910
|
+
});
|
|
911
|
+
return result + templateText.slice(lastIndex);
|
|
912
|
+
};
|
|
913
|
+
var normalizeColumnWeights = (columnWeights, columnCount) => {
|
|
914
|
+
if (columnWeights && columnWeights.length > 0) {
|
|
915
|
+
const normalizedWidths = Array.from({ length: columnCount }, (_, index) => {
|
|
916
|
+
const width = columnWeights[index];
|
|
917
|
+
return typeof width === "number" && Number.isFinite(width) && width > 0 ? width : 1;
|
|
918
|
+
});
|
|
919
|
+
const totalWidth = normalizedWidths.reduce((sum, width) => sum + width, 0);
|
|
920
|
+
if (totalWidth > 0) return normalizedWidths.map((width) => width / totalWidth * 100);
|
|
921
|
+
}
|
|
407
922
|
if (columnCount <= 0) return [];
|
|
408
923
|
return Array.from({ length: columnCount }, () => 100 / columnCount);
|
|
409
924
|
};
|
|
@@ -491,6 +1006,33 @@ var PAGE_BREAK_PARENT_KINDS = new Set([
|
|
|
491
1006
|
"stack",
|
|
492
1007
|
"box"
|
|
493
1008
|
]);
|
|
1009
|
+
var STATIC_CONTAINER_KINDS = new Set([
|
|
1010
|
+
"absolute",
|
|
1011
|
+
"stack",
|
|
1012
|
+
"row",
|
|
1013
|
+
"box"
|
|
1014
|
+
]);
|
|
1015
|
+
var STATIC_LEAF_KINDS = new Set([
|
|
1016
|
+
"spacer",
|
|
1017
|
+
"text",
|
|
1018
|
+
"image",
|
|
1019
|
+
"svg",
|
|
1020
|
+
"rectangle",
|
|
1021
|
+
"ellipse",
|
|
1022
|
+
"line"
|
|
1023
|
+
]);
|
|
1024
|
+
var ABSOLUTE_PARENT_KINDS = new Set([
|
|
1025
|
+
"page",
|
|
1026
|
+
"header",
|
|
1027
|
+
"footer",
|
|
1028
|
+
"static",
|
|
1029
|
+
"box"
|
|
1030
|
+
]);
|
|
1031
|
+
var STATIC_BLOCK_KINDS = new Set([
|
|
1032
|
+
"header",
|
|
1033
|
+
"footer",
|
|
1034
|
+
"static"
|
|
1035
|
+
]);
|
|
494
1036
|
var validatePageBreakPlacement = (node, parentKind = void 0, canBreak = false) => {
|
|
495
1037
|
for (const child of flattenForSplitting(node)) {
|
|
496
1038
|
if (!isPdfJsxElement(child)) continue;
|
|
@@ -502,7 +1044,62 @@ var validatePageBreakPlacement = (node, parentKind = void 0, canBreak = false) =
|
|
|
502
1044
|
validatePageBreakPlacement(child.children, child.kind, childCanBreak);
|
|
503
1045
|
}
|
|
504
1046
|
};
|
|
1047
|
+
var validateAbsolutePlacement = (node, parentKind = void 0) => {
|
|
1048
|
+
for (const child of flattenForSplitting(node)) {
|
|
1049
|
+
if (!isPdfJsxElement(child)) continue;
|
|
1050
|
+
if (child.kind === "absolute" && (!parentKind || !ABSOLUTE_PARENT_KINDS.has(parentKind))) throw new Error("@pdfme/jsx: <Absolute> can only be used inside <Page>, <Header>, <Footer>, <Static>, or <Box>.");
|
|
1051
|
+
validateAbsolutePlacement(child.children, child.kind);
|
|
1052
|
+
}
|
|
1053
|
+
};
|
|
1054
|
+
var validateStaticPlacement = (children, hasDocument) => {
|
|
1055
|
+
for (const child of flattenChildren(children)) {
|
|
1056
|
+
if (!isPdfJsxElement(child)) {
|
|
1057
|
+
if (hasDocument && String(child).trim() !== "") throw new Error("@pdfme/jsx: <Document> children must be <Header>, <Footer>, <Static>, or <Page>.");
|
|
1058
|
+
continue;
|
|
1059
|
+
}
|
|
1060
|
+
if (STATIC_BLOCK_KINDS.has(child.kind)) {
|
|
1061
|
+
if (!hasDocument) throw new Error("@pdfme/jsx: <Header>, <Footer>, and <Static> can only be used as direct children of <Document>.");
|
|
1062
|
+
if (child.kind === "static") {
|
|
1063
|
+
if (getStaticPlacement(child) === "bottom" && hasElementKind(child.children, "absolute")) throw new Error("@pdfme/jsx: <Absolute> is not supported inside bottom <Static>. Use top <Static>, <Header>, <Footer>, or <Page> for fixed page coordinates.");
|
|
1064
|
+
}
|
|
1065
|
+
validateStaticChildren(child.children);
|
|
1066
|
+
continue;
|
|
1067
|
+
}
|
|
1068
|
+
if (hasDocument && child.kind !== "page") throw new Error("@pdfme/jsx: <Document> children must be <Header>, <Footer>, <Static>, or <Page>.");
|
|
1069
|
+
validateNoNestedStaticBlock(child);
|
|
1070
|
+
}
|
|
1071
|
+
};
|
|
1072
|
+
var validateNoNestedStaticBlock = (node) => {
|
|
1073
|
+
if (!isPdfJsxElement(node)) return;
|
|
1074
|
+
for (const child of flattenForSplitting(node.children)) {
|
|
1075
|
+
if (isPdfJsxElement(child) && STATIC_BLOCK_KINDS.has(child.kind)) throw new Error("@pdfme/jsx: <Header>, <Footer>, and <Static> can only be used as direct children of <Document>.");
|
|
1076
|
+
validateNoNestedStaticBlock(child);
|
|
1077
|
+
}
|
|
1078
|
+
};
|
|
1079
|
+
var hasElementKind = (node, kind) => {
|
|
1080
|
+
for (const child of flattenForSplitting(node)) {
|
|
1081
|
+
if (!isPdfJsxElement(child)) continue;
|
|
1082
|
+
if (child.kind === kind || hasElementKind(child.children, kind)) return true;
|
|
1083
|
+
}
|
|
1084
|
+
return false;
|
|
1085
|
+
};
|
|
1086
|
+
var validateStaticChildren = (children) => {
|
|
1087
|
+
for (const child of flattenForSplitting(children)) {
|
|
1088
|
+
if (!isPdfJsxElement(child)) continue;
|
|
1089
|
+
if (STATIC_CONTAINER_KINDS.has(child.kind)) {
|
|
1090
|
+
validateStaticChildren(child.children);
|
|
1091
|
+
continue;
|
|
1092
|
+
}
|
|
1093
|
+
if (!STATIC_LEAF_KINDS.has(child.kind)) throw new Error(`@pdfme/jsx: <Static> does not support <${child.kind}> children. Supported: read-only Stack, Row, Box, Spacer, Text, Image, Svg, Rectangle, Ellipse, and Line.`);
|
|
1094
|
+
validateStaticLeafProps(child);
|
|
1095
|
+
}
|
|
1096
|
+
};
|
|
1097
|
+
var validateStaticLeafProps = (element) => {
|
|
1098
|
+
if (element.kind !== "text" && element.kind !== "image" && element.kind !== "svg") return;
|
|
1099
|
+
const props = element.props;
|
|
1100
|
+
if (props.readOnly === false || props.name != null && props.readOnly !== true) throw new Error("@pdfme/jsx: <Static> children must be read-only.");
|
|
1101
|
+
};
|
|
505
1102
|
//#endregion
|
|
506
|
-
export { Box, List, Page, PageBreak, Row, Spacer, Stack, Table, Text, renderToTemplate };
|
|
1103
|
+
export { Absolute, Box, Document, Ellipse, Footer, Header, Image, Line, List, MultiVariableText, Page, PageBreak, Rectangle, Row, Spacer, Stack, Static, Svg, Table, Text, renderToTemplate };
|
|
507
1104
|
|
|
508
1105
|
//# sourceMappingURL=index.js.map
|