@pdfme/jsx 0.0.0

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 ADDED
@@ -0,0 +1,32 @@
1
+ # @pdfme/jsx
2
+
3
+ Small JSX authoring layer for creating pdfme templates from stacking layout primitives.
4
+
5
+ ```tsx
6
+ /** @jsxImportSource @pdfme/jsx */
7
+ import { Page, Stack, Text, renderToTemplate } from '@pdfme/jsx';
8
+
9
+ const { template, inputs } = await renderToTemplate(
10
+ <Page margin={{ x: 12, y: 16 }}>
11
+ <Stack gap={4}>
12
+ <Text size={18}>Invoice</Text>
13
+ <Text name="customerName">Alice</Text>
14
+ </Stack>
15
+ </Page>,
16
+ );
17
+ ```
18
+
19
+ This package emits regular pdfme `Template` and `inputs` values. It does not depend on React;
20
+ it provides its own `jsx-runtime` and `jsx-dev-runtime`.
21
+ `renderToTemplate` is async because automatic text height measurement may need font data.
22
+
23
+ ## MVP constraints
24
+
25
+ - `Text` height is measured with pdfme's text/rich text wrapping helpers when `height` is omitted.
26
+ Pass an explicit `height` when you need a fixed field box.
27
+ - `PageBreak` is supported only along a `Page` / `Stack` / `Box` layout path. It is rejected inside
28
+ `Row`, `Text`, `List`, and `Table`.
29
+ - All `Page` nodes in one `renderToTemplate` call must use the same page size, orientation, and
30
+ margin because a pdfme blank `basePdf` has one shared size and padding.
31
+ - `Table widths` are percentages passed to pdfme `headWidthPercentages`, for example
32
+ `widths={[70, 30]}`.
@@ -0,0 +1,10 @@
1
+ import type { BoxProps, ListProps, PageBreakProps, PageProps, RowProps, SpacerProps, StackProps, TableProps, TextProps } from './types.js';
2
+ export declare const Page: (props: PageProps) => import("./types.js").PdfJsxElement<"page">;
3
+ export declare const Stack: (props: StackProps) => import("./types.js").PdfJsxElement<"stack">;
4
+ export declare const Row: (props: RowProps) => import("./types.js").PdfJsxElement<"row">;
5
+ export declare const Box: (props: BoxProps) => import("./types.js").PdfJsxElement<"box">;
6
+ export declare const Spacer: (props: SpacerProps) => import("./types.js").PdfJsxElement<"spacer">;
7
+ export declare const Text: (props: TextProps) => import("./types.js").PdfJsxElement<"text">;
8
+ export declare const List: (props: ListProps) => import("./types.js").PdfJsxElement<"list">;
9
+ export declare const Table: (props: TableProps) => import("./types.js").PdfJsxElement<"table">;
10
+ export declare const PageBreak: (props?: PageBreakProps) => import("./types.js").PdfJsxElement<"pagebreak">;
@@ -0,0 +1,3 @@
1
+ export { Box, List, Page, PageBreak, Row, Spacer, Stack, Table, Text } from './components.js';
2
+ export { renderToTemplate } from './render.js';
3
+ export type { BoxProps, BoxSides, CellStyle, ListItem, ListProps, PageBreakProps, PageOrientation, PageProps, PageSize, PageSizePreset, PdfJsxChild, PdfJsxElement, RenderOptions, RenderResult, RowProps, SpacerProps, StackProps, TableProps, TextProps, } from './types.js';
package/dist/index.js ADDED
@@ -0,0 +1,508 @@
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";
4
+ //#region src/components.ts
5
+ var makeBuiltin = (kind) => (props) => createElementNode(kind, props);
6
+ var Page = makeBuiltin("page");
7
+ var Stack = makeBuiltin("stack");
8
+ var Row = makeBuiltin("row");
9
+ var Box = makeBuiltin("box");
10
+ var Spacer = makeBuiltin("spacer");
11
+ var Text = makeBuiltin("text");
12
+ var List = makeBuiltin("list");
13
+ var Table = makeBuiltin("table");
14
+ var PageBreak = (props) => createElementNode("pagebreak", props);
15
+ //#endregion
16
+ //#region src/render.ts
17
+ var DEFAULT_FONT_SIZE = 10;
18
+ var DEFAULT_LINE_HEIGHT = 1;
19
+ var DEFAULT_CHARACTER_SPACING = 0;
20
+ var DEFAULT_FONT_COLOR = "#000000";
21
+ var DEFAULT_DYNAMIC_FONT_SIZE = {
22
+ min: 4,
23
+ max: 72,
24
+ fit: "vertical"
25
+ };
26
+ var renderToTemplate = async (node, options = {}) => {
27
+ validatePageBreakPlacement(node);
28
+ const pages = flattenChildren(expandPageBreaks(node)).filter((child) => isPdfJsxElement(child) && child.kind === "page");
29
+ if (pages.length === 0) throw new Error("@pdfme/jsx: renderToTemplate root must contain at least one <Page>.");
30
+ const firstPageProps = pages[0]?.props;
31
+ const firstMargin = resolveBoxSides(firstPageProps.margin);
32
+ const pageSize = resolvePageSize(firstPageProps.size, firstPageProps.orientation);
33
+ validateConsistentPageProps(pages, pageSize, firstMargin);
34
+ const inputs = {};
35
+ const usedNames = /* @__PURE__ */ new Set();
36
+ const nameCounters = {};
37
+ const font = options.font ?? getDefaultFont();
38
+ const _cache = /* @__PURE__ */ new Map();
39
+ const pageSchemas = [];
40
+ for (const page of pages) {
41
+ const props = page.props;
42
+ const margin = resolveBoxSides(props.margin);
43
+ const frame = {
44
+ x: margin.left,
45
+ y: margin.top,
46
+ width: pageSize.width - margin.left - margin.right,
47
+ height: pageSize.height - margin.top - margin.bottom
48
+ };
49
+ const ctx = {
50
+ schemas: [],
51
+ inputs,
52
+ usedNames,
53
+ nameCounters,
54
+ defaultFont: props.font,
55
+ font,
56
+ _cache
57
+ };
58
+ await layoutChildren(page.children, frame, "stack", { gap: 0 }, ctx);
59
+ pageSchemas.push(ctx.schemas);
60
+ }
61
+ return {
62
+ template: {
63
+ basePdf: options.basePdf ?? {
64
+ width: pageSize.width,
65
+ height: pageSize.height,
66
+ padding: [
67
+ firstMargin.top,
68
+ firstMargin.right,
69
+ firstMargin.bottom,
70
+ firstMargin.left
71
+ ]
72
+ },
73
+ schemas: pageSchemas
74
+ },
75
+ inputs: [inputs]
76
+ };
77
+ };
78
+ var flattenChildren = (children) => {
79
+ if (children == null || children === false || children === true) return [];
80
+ if (typeof children === "string" || typeof children === "number") return [children];
81
+ if (Array.isArray(children)) return children.flatMap((child) => flattenChildren(child));
82
+ if (isPdfJsxFragment(children)) return flattenChildren(children.children);
83
+ if (isPdfJsxElement(children)) return [children];
84
+ return [];
85
+ };
86
+ var childrenToString = (children) => flattenChildren(children).map((child) => {
87
+ if (typeof child === "string" || typeof child === "number") return String(child);
88
+ return childrenToString(child.children);
89
+ }).join("");
90
+ var splitChildrenByPageBreak = (children) => {
91
+ const segments = [[]];
92
+ for (const child of flattenForSplitting(children)) {
93
+ if (isPdfJsxElement(child) && child.kind === "pagebreak") {
94
+ segments.push([]);
95
+ continue;
96
+ }
97
+ if (isPdfJsxElement(child) && (child.kind === "page" || child.kind === "stack" || child.kind === "box")) {
98
+ const childSegments = splitChildrenByPageBreak(child.children);
99
+ if (childSegments.length === 1) {
100
+ segments[segments.length - 1]?.push(child);
101
+ continue;
102
+ }
103
+ segments[segments.length - 1]?.push(cloneElementWithChildren(child, childSegments[0] ?? []));
104
+ for (let i = 1; i < childSegments.length; i += 1) segments.push([cloneElementWithChildren(child, childSegments[i] ?? [])]);
105
+ continue;
106
+ }
107
+ segments[segments.length - 1]?.push(child);
108
+ }
109
+ return segments;
110
+ };
111
+ var flattenForSplitting = (children) => {
112
+ if (children == null || children === false || children === true) return [];
113
+ if (Array.isArray(children)) return children.flatMap((child) => flattenForSplitting(child));
114
+ if (isPdfJsxFragment(children)) return flattenForSplitting(children.children);
115
+ return [children];
116
+ };
117
+ var expandPageBreaks = (node) => splitChildrenByPageBreak(node).flat();
118
+ var layoutChildren = async (children, frame, mode, opts, ctx) => {
119
+ const items = flattenChildren(children);
120
+ const widths = mode === "row" ? resolveRowWidths(items, frame.width, opts.gap) : void 0;
121
+ let cursor = 0;
122
+ let crossMax = 0;
123
+ for (let i = 0; i < items.length; i += 1) {
124
+ const child = items[i];
125
+ const width = mode === "row" ? widths?.[i] ?? 0 : frame.width;
126
+ const childFrame = mode === "stack" ? {
127
+ x: frame.x,
128
+ y: frame.y + cursor,
129
+ width,
130
+ height: Math.max(0, frame.height - cursor)
131
+ } : {
132
+ x: frame.x + cursor,
133
+ y: frame.y,
134
+ width,
135
+ height: frame.height
136
+ };
137
+ const size = typeof child === "string" || typeof child === "number" ? await renderText({ children: String(child) }, childFrame, ctx) : await renderElement(child, childFrame, mode, ctx);
138
+ const advance = mode === "stack" ? size.height : width;
139
+ cursor += advance + (i < items.length - 1 ? opts.gap : 0);
140
+ crossMax = Math.max(crossMax, mode === "stack" ? size.width : size.height);
141
+ }
142
+ return mode === "stack" ? {
143
+ width: crossMax,
144
+ height: cursor
145
+ } : {
146
+ width: cursor,
147
+ height: crossMax
148
+ };
149
+ };
150
+ var resolveRowWidths = (items, frameWidth, gap) => {
151
+ let fixedWidth = 0;
152
+ let flexCount = 0;
153
+ const widths = items.map((item) => {
154
+ if (typeof item === "string" || typeof item === "number") {
155
+ flexCount += 1;
156
+ return;
157
+ }
158
+ const width = item.props.width;
159
+ if (typeof width === "number") {
160
+ fixedWidth += width;
161
+ return width;
162
+ }
163
+ flexCount += 1;
164
+ });
165
+ const remaining = Math.max(0, frameWidth - fixedWidth - Math.max(0, items.length - 1) * gap);
166
+ const flexWidth = flexCount > 0 ? remaining / flexCount : 0;
167
+ return widths.map((width) => width ?? flexWidth);
168
+ };
169
+ var renderElement = async (element, frame, parentMode, ctx) => {
170
+ switch (element.kind) {
171
+ case "stack": return renderStack(element.props, element.children, frame, ctx);
172
+ case "row": return renderRow(element.props, element.children, frame, ctx);
173
+ case "box": return renderBox(element.props, element.children, frame, parentMode, ctx);
174
+ case "spacer": return Promise.resolve(renderSpacer(element.props));
175
+ case "text": return renderText({
176
+ ...element.props,
177
+ children: element.children
178
+ }, frame, ctx);
179
+ case "list": return renderList({
180
+ ...element.props,
181
+ children: element.children
182
+ }, frame, ctx);
183
+ case "table": return renderTable(element.props, frame, ctx);
184
+ default: return {
185
+ width: 0,
186
+ height: 0
187
+ };
188
+ }
189
+ };
190
+ var renderStack = (props, children, frame, ctx) => layoutChildren(children, {
191
+ ...frame,
192
+ width: props.width ?? frame.width
193
+ }, "stack", { gap: props.gap ?? 0 }, ctx);
194
+ var renderRow = (props, children, frame, ctx) => layoutChildren(children, {
195
+ ...frame,
196
+ width: props.width ?? frame.width,
197
+ height: props.height ?? frame.height
198
+ }, "row", { gap: props.gap ?? 0 }, ctx);
199
+ var renderBox = async (props, children, frame, _parentMode, ctx) => {
200
+ const width = props.width ?? frame.width;
201
+ const padding = resolveBoxSides(props.padding);
202
+ const needsRect = Boolean(props.background || props.borderColor || props.borderWidth);
203
+ const beforeCount = ctx.schemas.length;
204
+ if (needsRect) ctx.schemas.push({
205
+ name: resolveName(ctx, "box"),
206
+ type: "rectangle",
207
+ position: {
208
+ x: frame.x,
209
+ y: frame.y
210
+ },
211
+ width,
212
+ height: 0,
213
+ rotate: props.rotate ?? 0,
214
+ opacity: props.opacity ?? 1,
215
+ readOnly: true,
216
+ color: props.background ?? "",
217
+ borderColor: props.borderColor ?? "",
218
+ borderWidth: props.borderWidth ?? 0,
219
+ radius: props.radius ?? 0
220
+ });
221
+ const childSize = await layoutChildren(children, {
222
+ x: frame.x + padding.left,
223
+ y: frame.y + padding.top,
224
+ width: width - padding.left - padding.right,
225
+ height: (props.height ?? frame.height) - padding.top - padding.bottom
226
+ }, "stack", { gap: 0 }, ctx);
227
+ const height = props.height ?? childSize.height + padding.top + padding.bottom;
228
+ if (needsRect) ctx.schemas[beforeCount] = {
229
+ ...ctx.schemas[beforeCount],
230
+ height
231
+ };
232
+ return {
233
+ width,
234
+ height
235
+ };
236
+ };
237
+ var renderSpacer = (props) => ({
238
+ width: props.width ?? 0,
239
+ height: props.height ?? 0
240
+ });
241
+ var renderText = async (props, frame, ctx) => {
242
+ const fontSize = props.size ?? DEFAULT_FONT_SIZE;
243
+ const lineHeight = props.lineHeight ?? DEFAULT_LINE_HEIGHT;
244
+ const width = props.width ?? frame.width;
245
+ const value = childrenToString(props.children);
246
+ const name = resolveName(ctx, "text", props.name);
247
+ const readOnly = props.readOnly ?? props.name == null;
248
+ const schema = {
249
+ name,
250
+ type: "text",
251
+ content: value,
252
+ position: {
253
+ x: frame.x,
254
+ y: frame.y
255
+ },
256
+ width,
257
+ height: props.height ?? 0,
258
+ rotate: props.rotate ?? 0,
259
+ opacity: props.opacity ?? 1,
260
+ readOnly,
261
+ required: props.required,
262
+ alignment: props.align ?? "left",
263
+ verticalAlignment: props.valign ?? "top",
264
+ fontSize,
265
+ fontName: props.font ?? ctx.defaultFont,
266
+ lineHeight,
267
+ characterSpacing: props.spacing ?? DEFAULT_CHARACTER_SPACING,
268
+ fontColor: props.color ?? DEFAULT_FONT_COLOR,
269
+ backgroundColor: props.background ?? "",
270
+ textFormat: props.textFormat ?? "plain",
271
+ overflow: props.overflow,
272
+ strikethrough: props.strikethrough ?? false,
273
+ underline: props.underline ?? false
274
+ };
275
+ if (props.borderColor) schema.borderColor = props.borderColor;
276
+ if (props.borderWidth != null) schema.borderWidth = props.borderWidth;
277
+ if (props.dynamicFontSize) schema.dynamicFontSize = {
278
+ min: props.dynamicFontSize.min ?? DEFAULT_DYNAMIC_FONT_SIZE.min,
279
+ max: props.dynamicFontSize.max ?? DEFAULT_DYNAMIC_FONT_SIZE.max,
280
+ fit: props.dynamicFontSize.fit ?? DEFAULT_DYNAMIC_FONT_SIZE.fit
281
+ };
282
+ if (props.height == null) schema.height = await measureTextHeight({
283
+ value,
284
+ schema,
285
+ font: ctx.font,
286
+ _cache: ctx._cache
287
+ });
288
+ if (!readOnly) ctx.inputs[name] = value;
289
+ ctx.schemas.push(schema);
290
+ return {
291
+ width,
292
+ height: schema.height
293
+ };
294
+ };
295
+ var renderList = (props, frame, ctx) => {
296
+ const fontSize = props.size ?? DEFAULT_FONT_SIZE;
297
+ const lineHeight = props.lineHeight ?? DEFAULT_LINE_HEIGHT;
298
+ const items = normalizeListItems(props);
299
+ const serialized = JSON.stringify(items.map(serializeListItem));
300
+ const width = props.width ?? frame.width;
301
+ const height = props.height ?? Math.max(1, items.length) * estimateTextHeight(fontSize, lineHeight) + Math.max(0, items.length - 1) * (props.itemSpacing ?? 1);
302
+ const name = resolveName(ctx, "list", props.name);
303
+ const readOnly = props.readOnly ?? props.name == null;
304
+ const schema = {
305
+ name,
306
+ type: "list",
307
+ content: serialized,
308
+ position: {
309
+ x: frame.x,
310
+ y: frame.y
311
+ },
312
+ width,
313
+ height,
314
+ rotate: props.rotate ?? 0,
315
+ opacity: props.opacity ?? 1,
316
+ readOnly,
317
+ required: props.required,
318
+ alignment: props.align ?? "left",
319
+ verticalAlignment: "top",
320
+ fontSize,
321
+ fontName: props.font ?? ctx.defaultFont,
322
+ lineHeight,
323
+ characterSpacing: props.spacing ?? DEFAULT_CHARACTER_SPACING,
324
+ fontColor: props.color ?? DEFAULT_FONT_COLOR,
325
+ backgroundColor: props.background ?? "",
326
+ listStyle: props.listStyle ?? "bullet",
327
+ markerWidth: props.markerWidth ?? 6,
328
+ markerGap: props.markerGap ?? 2,
329
+ indentSize: props.indentSize ?? 6,
330
+ itemSpacing: props.itemSpacing ?? 1
331
+ };
332
+ if (!readOnly) ctx.inputs[name] = serialized;
333
+ ctx.schemas.push(schema);
334
+ return {
335
+ width,
336
+ height
337
+ };
338
+ };
339
+ var renderTable = (props, frame, ctx) => {
340
+ const rows = (props.rows ?? props.data ?? []).map((row) => row.map(String));
341
+ const width = props.width ?? frame.width;
342
+ const showHead = props.showHead ?? true;
343
+ const headerHeight = props.headerHeight ?? 9;
344
+ const rowHeight = props.rowHeight ?? 6.5;
345
+ const height = props.height ?? (showHead ? headerHeight : 0) + Math.max(1, rows.length) * rowHeight;
346
+ const name = resolveName(ctx, "table", props.name);
347
+ const readOnly = props.readOnly ?? props.name == null;
348
+ const value = JSON.stringify(rows);
349
+ const schema = {
350
+ name,
351
+ type: "table",
352
+ content: value,
353
+ position: {
354
+ x: frame.x,
355
+ y: frame.y
356
+ },
357
+ width,
358
+ height,
359
+ rotate: props.rotate ?? 0,
360
+ opacity: props.opacity ?? 1,
361
+ readOnly,
362
+ required: props.required,
363
+ showHead,
364
+ repeatHead: props.repeatHead ?? false,
365
+ head: props.head,
366
+ headWidthPercentages: normalizeColumnWidths(props.widths, props.head.length),
367
+ tableStyles: {
368
+ borderColor: props.tableStyles?.borderColor ?? "#000000",
369
+ borderWidth: props.tableStyles?.borderWidth ?? .3
370
+ },
371
+ headStyles: {
372
+ ...defaultCellStyle(props.font ?? ctx.defaultFont, props.fontSize),
373
+ fontColor: "#ffffff",
374
+ backgroundColor: "#2980ba",
375
+ ...normalizeCellStyle(props.headStyles)
376
+ },
377
+ bodyStyles: {
378
+ ...defaultCellStyle(props.font ?? ctx.defaultFont, props.fontSize),
379
+ alternateBackgroundColor: "#f5f5f5",
380
+ ...normalizeCellStyle(props.bodyStyles)
381
+ },
382
+ columnStyles: props.columnStyles ?? {}
383
+ };
384
+ if (!readOnly) ctx.inputs[name] = value;
385
+ ctx.schemas.push(schema);
386
+ return {
387
+ width,
388
+ height
389
+ };
390
+ };
391
+ var normalizeListItems = (props) => {
392
+ if (props.items) return props.items.map((item) => typeof item === "string" ? {
393
+ text: item,
394
+ level: 0
395
+ } : {
396
+ text: item.text,
397
+ level: item.level ?? 0
398
+ });
399
+ return childrenToString(props.children).split("\n").map((item) => item.trim()).filter(Boolean).map((text) => ({
400
+ text,
401
+ level: 0
402
+ }));
403
+ };
404
+ var serializeListItem = (item) => `${" ".repeat(Math.max(0, item.level))}${item.text}`;
405
+ var normalizeColumnWidths = (widths, columnCount) => {
406
+ if (widths && widths.length > 0) return widths;
407
+ if (columnCount <= 0) return [];
408
+ return Array.from({ length: columnCount }, () => 100 / columnCount);
409
+ };
410
+ var defaultCellStyle = (fontName, fontSize = 10) => ({
411
+ fontName,
412
+ alignment: "left",
413
+ verticalAlignment: "middle",
414
+ fontSize,
415
+ lineHeight: 1,
416
+ characterSpacing: 0,
417
+ fontColor: "#000000",
418
+ backgroundColor: "#ffffff",
419
+ borderColor: "#000000",
420
+ borderWidth: {
421
+ top: 0,
422
+ right: 0,
423
+ bottom: 0,
424
+ left: 0
425
+ },
426
+ padding: {
427
+ top: 5,
428
+ right: 5,
429
+ bottom: 5,
430
+ left: 5
431
+ }
432
+ });
433
+ var normalizeCellStyle = (style) => {
434
+ if (!style) return {};
435
+ const { borderWidth, padding, ...rest } = style;
436
+ return {
437
+ ...rest,
438
+ ...borderWidth != null ? { borderWidth: resolveBoxSides(borderWidth) } : {},
439
+ ...padding != null ? { padding: resolveBoxSides(padding) } : {}
440
+ };
441
+ };
442
+ var resolveBoxSides = (value) => {
443
+ if (value == null) return {
444
+ top: 0,
445
+ right: 0,
446
+ bottom: 0,
447
+ left: 0
448
+ };
449
+ if (typeof value === "number") return {
450
+ top: value,
451
+ right: value,
452
+ bottom: value,
453
+ left: value
454
+ };
455
+ const x = value.x ?? 0;
456
+ const y = value.y ?? 0;
457
+ return {
458
+ top: value.top ?? y,
459
+ right: value.right ?? x,
460
+ bottom: value.bottom ?? y,
461
+ left: value.left ?? x
462
+ };
463
+ };
464
+ var resolveName = (ctx, prefix, userName) => {
465
+ if (userName) {
466
+ if (ctx.usedNames.has(userName)) throw new Error(`@pdfme/jsx: duplicate schema name "${userName}"`);
467
+ ctx.usedNames.add(userName);
468
+ return userName;
469
+ }
470
+ let name = "";
471
+ do {
472
+ ctx.nameCounters[prefix] = (ctx.nameCounters[prefix] ?? 0) + 1;
473
+ name = `${prefix}_${ctx.nameCounters[prefix]}`;
474
+ } while (ctx.usedNames.has(name));
475
+ ctx.usedNames.add(name);
476
+ return name;
477
+ };
478
+ var estimateTextHeight = (fontSize, lineHeight) => Math.max(4, pt2mm(fontSize * lineHeight));
479
+ var validateConsistentPageProps = (pages, firstPageSize, firstMargin) => {
480
+ for (let i = 1; i < pages.length; i += 1) {
481
+ const props = pages[i]?.props;
482
+ const pageSize = resolvePageSize(props.size, props.orientation);
483
+ const margin = resolveBoxSides(props.margin);
484
+ if (!isSameSize(pageSize, firstPageSize) || !isSameBoxSides(margin, firstMargin)) throw new Error("@pdfme/jsx: all <Page> nodes must use the same size, orientation, and margin. pdfme templates have one blank basePdf size and padding.");
485
+ }
486
+ };
487
+ var isSameSize = (first, second) => first.width === second.width && first.height === second.height;
488
+ var isSameBoxSides = (first, second) => first.top === second.top && first.right === second.right && first.bottom === second.bottom && first.left === second.left;
489
+ var PAGE_BREAK_PARENT_KINDS = new Set([
490
+ "page",
491
+ "stack",
492
+ "box"
493
+ ]);
494
+ var validatePageBreakPlacement = (node, parentKind = void 0, canBreak = false) => {
495
+ for (const child of flattenForSplitting(node)) {
496
+ if (!isPdfJsxElement(child)) continue;
497
+ if (child.kind === "pagebreak") {
498
+ if (!canBreak || !parentKind || !PAGE_BREAK_PARENT_KINDS.has(parentKind)) throw new Error("@pdfme/jsx: <PageBreak> can only be used inside <Page>, <Stack>, or <Box>.");
499
+ continue;
500
+ }
501
+ const childCanBreak = child.kind === "page" ? true : canBreak && PAGE_BREAK_PARENT_KINDS.has(child.kind);
502
+ validatePageBreakPlacement(child.children, child.kind, childCanBreak);
503
+ }
504
+ };
505
+ //#endregion
506
+ export { Box, List, Page, PageBreak, Row, Spacer, Stack, Table, Text, renderToTemplate };
507
+
508
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":[],"sources":["../src/components.ts","../src/render.ts"],"sourcesContent":["import { createElementNode } from './node.js';\nimport type {\n BoxProps,\n ListProps,\n PageBreakProps,\n PageProps,\n RowProps,\n SpacerProps,\n StackProps,\n TableProps,\n TextProps,\n} from './types.js';\n\nconst makeBuiltin =\n <Props extends Record<string, unknown>, K extends Parameters<typeof createElementNode>[0]>(\n kind: K,\n ) =>\n (props: Props): ReturnType<typeof createElementNode<K>> =>\n createElementNode(kind, props);\n\nexport const Page = makeBuiltin<PageProps, 'page'>('page');\nexport const Stack = makeBuiltin<StackProps, 'stack'>('stack');\nexport const Row = makeBuiltin<RowProps, 'row'>('row');\nexport const Box = makeBuiltin<BoxProps, 'box'>('box');\nexport const Spacer = makeBuiltin<SpacerProps, 'spacer'>('spacer');\nexport const Text = makeBuiltin<TextProps, 'text'>('text');\nexport const List = makeBuiltin<ListProps, 'list'>('list');\nexport const Table = makeBuiltin<TableProps, 'table'>('table');\nexport const PageBreak = (props?: PageBreakProps) => createElementNode('pagebreak', props);\n","import { getDefaultFont, pt2mm, resolvePageSize } from '@pdfme/common';\nimport type { Font, Schema, Template } from '@pdfme/common';\nimport type {\n CellStyle as SchemaCellStyle,\n ListSchema,\n TableSchema,\n TextSchema,\n} from '@pdfme/schemas/types';\nimport { measureTextHeight } from '@pdfme/schemas/utils';\nimport { cloneElementWithChildren, isPdfJsxElement, isPdfJsxFragment } from './node.js';\nimport type {\n BoxProps,\n BoxSides,\n CellStyle,\n ListProps,\n PageProps,\n PdfJsxChild,\n PdfJsxElement,\n RenderOptions,\n RenderResult,\n RowProps,\n SpacerProps,\n StackProps,\n TableProps,\n TextProps,\n} from './types.js';\n\ntype Rect = { x: number; y: number; width: number; height: number };\n\ntype RenderCtx = {\n schemas: Schema[];\n inputs: Record<string, string>;\n usedNames: Set<string>;\n nameCounters: Record<string, number>;\n defaultFont?: string;\n font: Font;\n _cache: Map<string | number, unknown>;\n};\n\nconst DEFAULT_FONT_SIZE = 10;\nconst DEFAULT_LINE_HEIGHT = 1;\nconst DEFAULT_CHARACTER_SPACING = 0;\nconst DEFAULT_FONT_COLOR = '#000000';\nconst DEFAULT_DYNAMIC_FONT_SIZE = {\n min: 4,\n max: 72,\n fit: 'vertical',\n} as const satisfies NonNullable<TextSchema['dynamicFontSize']>;\n\nexport const renderToTemplate = async (\n node: PdfJsxChild,\n options: RenderOptions = {},\n): Promise<RenderResult> => {\n validatePageBreakPlacement(node);\n const expanded = expandPageBreaks(node);\n const pages = flattenChildren(expanded).filter(\n (child): child is PdfJsxElement<'page'> => isPdfJsxElement(child) && child.kind === 'page',\n );\n\n if (pages.length === 0) {\n throw new Error('@pdfme/jsx: renderToTemplate root must contain at least one <Page>.');\n }\n\n const firstPageProps = pages[0]?.props as PageProps;\n const firstMargin = resolveBoxSides(firstPageProps.margin);\n const pageSize = resolvePageSize(firstPageProps.size, firstPageProps.orientation);\n validateConsistentPageProps(pages, pageSize, firstMargin);\n const inputs: Record<string, string> = {};\n const usedNames = new Set<string>();\n const nameCounters: Record<string, number> = {};\n const font = options.font ?? getDefaultFont();\n const _cache = new Map<string | number, unknown>();\n const pageSchemas: Schema[][] = [];\n\n for (const page of pages) {\n const props = page.props as PageProps;\n const margin = resolveBoxSides(props.margin);\n const frame = {\n x: margin.left,\n y: margin.top,\n width: pageSize.width - margin.left - margin.right,\n height: pageSize.height - margin.top - margin.bottom,\n };\n const ctx: RenderCtx = {\n schemas: [],\n inputs,\n usedNames,\n nameCounters,\n defaultFont: props.font,\n font,\n _cache,\n };\n await layoutChildren(page.children, frame, 'stack', { gap: 0 }, ctx);\n pageSchemas.push(ctx.schemas);\n }\n\n const template: Template = {\n basePdf: options.basePdf ?? {\n width: pageSize.width,\n height: pageSize.height,\n padding: [firstMargin.top, firstMargin.right, firstMargin.bottom, firstMargin.left],\n },\n schemas: pageSchemas,\n };\n\n return { template, inputs: [inputs] };\n};\n\nconst flattenChildren = (\n children: PdfJsxChild | PdfJsxChild[],\n): (PdfJsxElement | string | number)[] => {\n if (children == null || children === false || children === true) return [];\n if (typeof children === 'string' || typeof children === 'number') return [children];\n if (Array.isArray(children)) return children.flatMap((child) => flattenChildren(child));\n if (isPdfJsxFragment(children)) return flattenChildren(children.children);\n if (isPdfJsxElement(children)) return [children];\n return [];\n};\n\nconst childrenToString = (children: PdfJsxChild | PdfJsxChild[]): string =>\n flattenChildren(children)\n .map((child) => {\n if (typeof child === 'string' || typeof child === 'number') return String(child);\n return childrenToString(child.children);\n })\n .join('');\n\nconst splitChildrenByPageBreak = (children: PdfJsxChild | PdfJsxChild[]): PdfJsxChild[][] => {\n const segments: PdfJsxChild[][] = [[]];\n\n for (const child of flattenForSplitting(children)) {\n if (isPdfJsxElement(child) && child.kind === 'pagebreak') {\n segments.push([]);\n continue;\n }\n\n if (\n isPdfJsxElement(child) &&\n (child.kind === 'page' || child.kind === 'stack' || child.kind === 'box')\n ) {\n const childSegments = splitChildrenByPageBreak(child.children);\n if (childSegments.length === 1) {\n segments[segments.length - 1]?.push(child);\n continue;\n }\n\n segments[segments.length - 1]?.push(cloneElementWithChildren(child, childSegments[0] ?? []));\n for (let i = 1; i < childSegments.length; i += 1) {\n segments.push([cloneElementWithChildren(child, childSegments[i] ?? [])]);\n }\n continue;\n }\n\n segments[segments.length - 1]?.push(child);\n }\n\n return segments;\n};\n\nconst flattenForSplitting = (children: PdfJsxChild | PdfJsxChild[]): PdfJsxChild[] => {\n if (children == null || children === false || children === true) return [];\n if (Array.isArray(children)) return children.flatMap((child) => flattenForSplitting(child));\n if (isPdfJsxFragment(children)) return flattenForSplitting(children.children);\n return [children];\n};\n\nconst expandPageBreaks = (node: PdfJsxChild): PdfJsxChild[] =>\n splitChildrenByPageBreak(node).flat();\n\nconst layoutChildren = async (\n children: PdfJsxChild | PdfJsxChild[],\n frame: Rect,\n mode: 'stack' | 'row',\n opts: { gap: number },\n ctx: RenderCtx,\n): Promise<{ width: number; height: number }> => {\n const items = flattenChildren(children);\n const widths = mode === 'row' ? resolveRowWidths(items, frame.width, opts.gap) : undefined;\n let cursor = 0;\n let crossMax = 0;\n\n for (let i = 0; i < items.length; i += 1) {\n const child = items[i];\n const width = mode === 'row' ? (widths?.[i] ?? 0) : frame.width;\n const childFrame =\n mode === 'stack'\n ? { x: frame.x, y: frame.y + cursor, width, height: Math.max(0, frame.height - cursor) }\n : { x: frame.x + cursor, y: frame.y, width, height: frame.height };\n\n const size =\n typeof child === 'string' || typeof child === 'number'\n ? await renderText({ children: String(child) }, childFrame, ctx)\n : await renderElement(child, childFrame, mode, ctx);\n\n const advance = mode === 'stack' ? size.height : width;\n cursor += advance + (i < items.length - 1 ? opts.gap : 0);\n crossMax = Math.max(crossMax, mode === 'stack' ? size.width : size.height);\n }\n\n return mode === 'stack'\n ? { width: crossMax, height: cursor }\n : { width: cursor, height: crossMax };\n};\n\nconst resolveRowWidths = (\n items: (PdfJsxElement | string | number)[],\n frameWidth: number,\n gap: number,\n): number[] => {\n let fixedWidth = 0;\n let flexCount = 0;\n const widths = items.map((item) => {\n if (typeof item === 'string' || typeof item === 'number') {\n flexCount += 1;\n return undefined;\n }\n const width = (item.props as { width?: number }).width;\n if (typeof width === 'number') {\n fixedWidth += width;\n return width;\n }\n flexCount += 1;\n return undefined;\n });\n\n const remaining = Math.max(0, frameWidth - fixedWidth - Math.max(0, items.length - 1) * gap);\n const flexWidth = flexCount > 0 ? remaining / flexCount : 0;\n return widths.map((width) => width ?? flexWidth);\n};\n\nconst renderElement = async (\n element: PdfJsxElement,\n frame: Rect,\n parentMode: 'stack' | 'row',\n ctx: RenderCtx,\n): Promise<{ width: number; height: number }> => {\n switch (element.kind) {\n case 'stack':\n return renderStack(element.props as StackProps, element.children, frame, ctx);\n case 'row':\n return renderRow(element.props as RowProps, element.children, frame, ctx);\n case 'box':\n return renderBox(element.props as BoxProps, element.children, frame, parentMode, ctx);\n case 'spacer':\n return Promise.resolve(renderSpacer(element.props as SpacerProps));\n case 'text':\n return renderText(\n { ...(element.props as TextProps), children: element.children },\n frame,\n ctx,\n );\n case 'list':\n return renderList(\n { ...(element.props as ListProps), children: element.children },\n frame,\n ctx,\n );\n case 'table':\n return renderTable(element.props as TableProps, frame, ctx);\n default:\n return { width: 0, height: 0 };\n }\n};\n\nconst renderStack = (\n props: StackProps,\n children: PdfJsxChild[],\n frame: Rect,\n ctx: RenderCtx,\n): Promise<{ width: number; height: number }> =>\n layoutChildren(\n children,\n { ...frame, width: props.width ?? frame.width },\n 'stack',\n {\n gap: props.gap ?? 0,\n },\n ctx,\n );\n\nconst renderRow = (\n props: RowProps,\n children: PdfJsxChild[],\n frame: Rect,\n ctx: RenderCtx,\n): Promise<{ width: number; height: number }> =>\n layoutChildren(\n children,\n { ...frame, width: props.width ?? frame.width, height: props.height ?? frame.height },\n 'row',\n { gap: props.gap ?? 0 },\n ctx,\n );\n\nconst renderBox = async (\n props: BoxProps,\n children: PdfJsxChild[],\n frame: Rect,\n _parentMode: 'stack' | 'row',\n ctx: RenderCtx,\n): Promise<{ width: number; height: number }> => {\n const width = props.width ?? frame.width;\n const padding = resolveBoxSides(props.padding);\n const needsRect = Boolean(props.background || props.borderColor || props.borderWidth);\n const beforeCount = ctx.schemas.length;\n\n if (needsRect) {\n ctx.schemas.push({\n name: resolveName(ctx, 'box'),\n type: 'rectangle',\n position: { x: frame.x, y: frame.y },\n width,\n height: 0,\n rotate: props.rotate ?? 0,\n opacity: props.opacity ?? 1,\n readOnly: true,\n color: props.background ?? '',\n borderColor: props.borderColor ?? '',\n borderWidth: props.borderWidth ?? 0,\n radius: props.radius ?? 0,\n });\n }\n\n const innerFrame = {\n x: frame.x + padding.left,\n y: frame.y + padding.top,\n width: width - padding.left - padding.right,\n height: (props.height ?? frame.height) - padding.top - padding.bottom,\n };\n const childSize = await layoutChildren(children, innerFrame, 'stack', { gap: 0 }, ctx);\n const height = props.height ?? childSize.height + padding.top + padding.bottom;\n\n if (needsRect) {\n ctx.schemas[beforeCount] = { ...ctx.schemas[beforeCount]!, height };\n }\n\n return { width, height };\n};\n\nconst renderSpacer = (props: SpacerProps): { width: number; height: number } => ({\n width: props.width ?? 0,\n height: props.height ?? 0,\n});\n\nconst renderText = async (\n props: TextProps,\n frame: Rect,\n ctx: RenderCtx,\n): Promise<{ width: number; height: number }> => {\n const fontSize = props.size ?? DEFAULT_FONT_SIZE;\n const lineHeight = props.lineHeight ?? DEFAULT_LINE_HEIGHT;\n const width = props.width ?? frame.width;\n const value = childrenToString(props.children);\n const name = resolveName(ctx, 'text', props.name);\n const readOnly = props.readOnly ?? props.name == null;\n\n const schema: TextSchema = {\n name,\n type: 'text',\n content: value,\n position: { x: frame.x, y: frame.y },\n width,\n height: props.height ?? 0,\n rotate: props.rotate ?? 0,\n opacity: props.opacity ?? 1,\n readOnly,\n required: props.required,\n alignment: props.align ?? 'left',\n verticalAlignment: props.valign ?? 'top',\n fontSize,\n fontName: props.font ?? ctx.defaultFont,\n lineHeight,\n characterSpacing: props.spacing ?? DEFAULT_CHARACTER_SPACING,\n fontColor: props.color ?? DEFAULT_FONT_COLOR,\n backgroundColor: props.background ?? '',\n textFormat: props.textFormat ?? 'plain',\n overflow: props.overflow,\n strikethrough: props.strikethrough ?? false,\n underline: props.underline ?? false,\n };\n\n if (props.borderColor) schema.borderColor = props.borderColor;\n if (props.borderWidth != null) schema.borderWidth = props.borderWidth;\n if (props.dynamicFontSize) {\n schema.dynamicFontSize = {\n min: props.dynamicFontSize.min ?? DEFAULT_DYNAMIC_FONT_SIZE.min,\n max: props.dynamicFontSize.max ?? DEFAULT_DYNAMIC_FONT_SIZE.max,\n fit: props.dynamicFontSize.fit ?? DEFAULT_DYNAMIC_FONT_SIZE.fit,\n };\n }\n if (props.height == null) {\n schema.height = await measureTextHeight({ value, schema, font: ctx.font, _cache: ctx._cache });\n }\n if (!readOnly) ctx.inputs[name] = value;\n ctx.schemas.push(schema);\n\n return { width, height: schema.height };\n};\n\nconst renderList = (\n props: ListProps,\n frame: Rect,\n ctx: RenderCtx,\n): { width: number; height: number } => {\n const fontSize = props.size ?? DEFAULT_FONT_SIZE;\n const lineHeight = props.lineHeight ?? DEFAULT_LINE_HEIGHT;\n const items = normalizeListItems(props);\n const serialized = JSON.stringify(items.map(serializeListItem));\n const width = props.width ?? frame.width;\n const height =\n props.height ??\n Math.max(1, items.length) * estimateTextHeight(fontSize, lineHeight) +\n Math.max(0, items.length - 1) * (props.itemSpacing ?? 1);\n const name = resolveName(ctx, 'list', props.name);\n const readOnly = props.readOnly ?? props.name == null;\n\n const schema: ListSchema = {\n name,\n type: 'list',\n content: serialized,\n position: { x: frame.x, y: frame.y },\n width,\n height,\n rotate: props.rotate ?? 0,\n opacity: props.opacity ?? 1,\n readOnly,\n required: props.required,\n alignment: props.align ?? 'left',\n verticalAlignment: 'top',\n fontSize,\n fontName: props.font ?? ctx.defaultFont,\n lineHeight,\n characterSpacing: props.spacing ?? DEFAULT_CHARACTER_SPACING,\n fontColor: props.color ?? DEFAULT_FONT_COLOR,\n backgroundColor: props.background ?? '',\n listStyle: props.listStyle ?? 'bullet',\n markerWidth: props.markerWidth ?? 6,\n markerGap: props.markerGap ?? 2,\n indentSize: props.indentSize ?? 6,\n itemSpacing: props.itemSpacing ?? 1,\n };\n\n if (!readOnly) ctx.inputs[name] = serialized;\n ctx.schemas.push(schema);\n\n return { width, height };\n};\n\nconst renderTable = (\n props: TableProps,\n frame: Rect,\n ctx: RenderCtx,\n): { width: number; height: number } => {\n const rows = (props.rows ?? props.data ?? []).map((row) => row.map(String));\n const width = props.width ?? frame.width;\n const showHead = props.showHead ?? true;\n const headerHeight = props.headerHeight ?? 9;\n const rowHeight = props.rowHeight ?? 6.5;\n const height =\n props.height ?? (showHead ? headerHeight : 0) + Math.max(1, rows.length) * rowHeight;\n const name = resolveName(ctx, 'table', props.name);\n const readOnly = props.readOnly ?? props.name == null;\n const value = JSON.stringify(rows);\n\n const schema: TableSchema = {\n name,\n type: 'table',\n content: value,\n position: { x: frame.x, y: frame.y },\n width,\n height,\n rotate: props.rotate ?? 0,\n opacity: props.opacity ?? 1,\n readOnly,\n required: props.required,\n showHead,\n repeatHead: props.repeatHead ?? false,\n head: props.head,\n headWidthPercentages: normalizeColumnWidths(props.widths, props.head.length),\n tableStyles: {\n borderColor: props.tableStyles?.borderColor ?? '#000000',\n borderWidth: props.tableStyles?.borderWidth ?? 0.3,\n },\n headStyles: {\n ...defaultCellStyle(props.font ?? ctx.defaultFont, props.fontSize),\n fontColor: '#ffffff',\n backgroundColor: '#2980ba',\n ...normalizeCellStyle(props.headStyles),\n },\n bodyStyles: {\n ...defaultCellStyle(props.font ?? ctx.defaultFont, props.fontSize),\n alternateBackgroundColor: '#f5f5f5',\n ...normalizeCellStyle(props.bodyStyles),\n },\n columnStyles: props.columnStyles ?? {},\n };\n\n if (!readOnly) ctx.inputs[name] = value;\n ctx.schemas.push(schema);\n\n return { width, height };\n};\n\nconst normalizeListItems = (props: ListProps): { text: string; level: number }[] => {\n if (props.items) {\n return props.items.map((item) =>\n typeof item === 'string'\n ? { text: item, level: 0 }\n : { text: item.text, level: item.level ?? 0 },\n );\n }\n return childrenToString(props.children)\n .split('\\n')\n .map((item) => item.trim())\n .filter(Boolean)\n .map((text) => ({ text, level: 0 }));\n};\n\nconst serializeListItem = (item: { text: string; level: number }) =>\n `${'\\t'.repeat(Math.max(0, item.level))}${item.text}`;\n\nconst normalizeColumnWidths = (widths: number[] | undefined, columnCount: number): number[] => {\n if (widths && widths.length > 0) return widths;\n if (columnCount <= 0) return [];\n return Array.from({ length: columnCount }, () => 100 / columnCount);\n};\n\nconst defaultCellStyle = (fontName: string | undefined, fontSize = 10): SchemaCellStyle => ({\n fontName,\n alignment: 'left',\n verticalAlignment: 'middle',\n fontSize,\n lineHeight: 1,\n characterSpacing: 0,\n fontColor: '#000000',\n backgroundColor: '#ffffff',\n borderColor: '#000000',\n borderWidth: { top: 0, right: 0, bottom: 0, left: 0 },\n padding: { top: 5, right: 5, bottom: 5, left: 5 },\n});\n\nconst normalizeCellStyle = (\n style: CellStyle | undefined,\n): Partial<SchemaCellStyle & { alternateBackgroundColor: string }> => {\n if (!style) return {};\n const { borderWidth, padding, ...rest } = style;\n return {\n ...rest,\n ...(borderWidth != null ? { borderWidth: resolveBoxSides(borderWidth) } : {}),\n ...(padding != null ? { padding: resolveBoxSides(padding) } : {}),\n };\n};\n\nconst resolveBoxSides = (value?: number | BoxSides) => {\n if (value == null) return { top: 0, right: 0, bottom: 0, left: 0 };\n if (typeof value === 'number') return { top: value, right: value, bottom: value, left: value };\n const x = value.x ?? 0;\n const y = value.y ?? 0;\n return {\n top: value.top ?? y,\n right: value.right ?? x,\n bottom: value.bottom ?? y,\n left: value.left ?? x,\n };\n};\n\nconst resolveName = (ctx: RenderCtx, prefix: string, userName?: string): string => {\n if (userName) {\n if (ctx.usedNames.has(userName)) {\n throw new Error(`@pdfme/jsx: duplicate schema name \"${userName}\"`);\n }\n ctx.usedNames.add(userName);\n return userName;\n }\n\n let name = '';\n do {\n ctx.nameCounters[prefix] = (ctx.nameCounters[prefix] ?? 0) + 1;\n name = `${prefix}_${ctx.nameCounters[prefix]}`;\n } while (ctx.usedNames.has(name));\n ctx.usedNames.add(name);\n return name;\n};\n\nconst estimateTextHeight = (fontSize: number, lineHeight: number) =>\n Math.max(4, pt2mm(fontSize * lineHeight));\n\nconst validateConsistentPageProps = (\n pages: PdfJsxElement<'page'>[],\n firstPageSize: { width: number; height: number },\n firstMargin: ReturnType<typeof resolveBoxSides>,\n) => {\n for (let i = 1; i < pages.length; i += 1) {\n const props = pages[i]?.props as PageProps;\n const pageSize = resolvePageSize(props.size, props.orientation);\n const margin = resolveBoxSides(props.margin);\n\n if (!isSameSize(pageSize, firstPageSize) || !isSameBoxSides(margin, firstMargin)) {\n throw new Error(\n '@pdfme/jsx: all <Page> nodes must use the same size, orientation, and margin. pdfme templates have one blank basePdf size and padding.',\n );\n }\n }\n};\n\nconst isSameSize = (\n first: { width: number; height: number },\n second: { width: number; height: number },\n) => first.width === second.width && first.height === second.height;\n\nconst isSameBoxSides = (\n first: ReturnType<typeof resolveBoxSides>,\n second: ReturnType<typeof resolveBoxSides>,\n) =>\n first.top === second.top &&\n first.right === second.right &&\n first.bottom === second.bottom &&\n first.left === second.left;\n\nconst PAGE_BREAK_PARENT_KINDS = new Set(['page', 'stack', 'box']);\n\nconst validatePageBreakPlacement = (\n node: PdfJsxChild | PdfJsxChild[],\n parentKind: string | undefined = undefined,\n canBreak = false,\n) => {\n for (const child of flattenForSplitting(node)) {\n if (!isPdfJsxElement(child)) continue;\n\n if (child.kind === 'pagebreak') {\n if (!canBreak || !parentKind || !PAGE_BREAK_PARENT_KINDS.has(parentKind)) {\n throw new Error(\n '@pdfme/jsx: <PageBreak> can only be used inside <Page>, <Stack>, or <Box>.',\n );\n }\n continue;\n }\n\n const childCanBreak =\n child.kind === 'page' ? true : canBreak && PAGE_BREAK_PARENT_KINDS.has(child.kind);\n validatePageBreakPlacement(child.children, child.kind, childCanBreak);\n }\n};\n"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export { Fragment, jsx, jsxs } from './jsx-runtime.js';
2
+ export { jsx as jsxDEV } from './jsx-runtime.js';
@@ -0,0 +1,3 @@
1
+ import { t as Fragment } from "./node-BeNL0xMl.js";
2
+ import { jsx, jsxs } from "./jsx-runtime.js";
3
+ export { Fragment, jsx, jsx as jsxDEV, jsxs };
@@ -0,0 +1,14 @@
1
+ import { Fragment } from './node.js';
2
+ import type { PdfJsxChild, PdfJsxElement, PdfJsxFragment } from './types.js';
3
+ type Component = (props: Record<string, unknown>) => PdfJsxChild;
4
+ export { Fragment };
5
+ export declare const jsx: (type: Component | typeof Fragment, props: Record<string, unknown> | null, key?: string | number | null) => PdfJsxChild;
6
+ export declare const jsxs: (type: Component | typeof Fragment, props: Record<string, unknown> | null, key?: string | number | null) => PdfJsxChild;
7
+ export declare namespace JSX {
8
+ type Element = PdfJsxElement | PdfJsxFragment;
9
+ interface ElementChildrenAttribute {
10
+ children: unknown;
11
+ }
12
+ interface IntrinsicElements {
13
+ }
14
+ }
@@ -0,0 +1,15 @@
1
+ import { i as createFragmentNode, t as Fragment } from "./node-BeNL0xMl.js";
2
+ //#region src/jsx-runtime.ts
3
+ var jsx = (type, props, key) => {
4
+ if (type === Fragment) return createFragmentNode(props, key);
5
+ if (typeof type === "function") return type({
6
+ ...props,
7
+ key
8
+ });
9
+ throw new Error("@pdfme/jsx: intrinsic JSX elements are not supported. Use pdfme components.");
10
+ };
11
+ var jsxs = jsx;
12
+ //#endregion
13
+ export { Fragment, jsx, jsxs };
14
+
15
+ //# sourceMappingURL=jsx-runtime.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jsx-runtime.js","names":[],"sources":["../src/jsx-runtime.ts"],"sourcesContent":["import { createFragmentNode, Fragment } from './node.js';\nimport type { PdfJsxChild, PdfJsxElement, PdfJsxFragment } from './types.js';\n\ntype Component = (props: Record<string, unknown>) => PdfJsxChild;\n\nexport { Fragment };\n\nexport const jsx = (\n type: Component | typeof Fragment,\n props: Record<string, unknown> | null,\n key?: string | number | null,\n): PdfJsxChild => {\n if (type === Fragment) return createFragmentNode(props, key);\n if (typeof type === 'function') return type({ ...props, key });\n throw new Error('@pdfme/jsx: intrinsic JSX elements are not supported. Use pdfme components.');\n};\n\nexport const jsxs = jsx;\n\nexport namespace JSX {\n export type Element = PdfJsxElement | PdfJsxFragment;\n export interface ElementChildrenAttribute {\n children: unknown;\n }\n export interface IntrinsicElements {}\n}\n"],"mappings":";;AAOA,IAAa,OACX,MACA,OACA,QACgB;AAChB,KAAI,SAAS,SAAU,QAAO,mBAAmB,OAAO,IAAI;AAC5D,KAAI,OAAO,SAAS,WAAY,QAAO,KAAK;EAAE,GAAG;EAAO;EAAK,CAAC;AAC9D,OAAM,IAAI,MAAM,8EAA8E;;AAGhG,IAAa,OAAO"}
@@ -0,0 +1,30 @@
1
+ //#region src/node.ts
2
+ var Fragment = Symbol.for("@pdfme/jsx.fragment");
3
+ var isPdfJsxElement = (value) => typeof value === "object" && value !== null && "kind" in value && typeof value.kind === "string";
4
+ var isPdfJsxFragment = (value) => typeof value === "object" && value !== null && "kind" in value && value.kind === "fragment";
5
+ var normalizeChildren = (children) => {
6
+ if (children === void 0) return [];
7
+ return Array.isArray(children) ? children : [children];
8
+ };
9
+ var createElementNode = (kind, rawProps, key) => {
10
+ const { children, ...props } = rawProps ?? {};
11
+ return {
12
+ kind,
13
+ props,
14
+ children: normalizeChildren(children),
15
+ key
16
+ };
17
+ };
18
+ var createFragmentNode = (rawProps, key) => ({
19
+ kind: "fragment",
20
+ children: normalizeChildren(rawProps?.children),
21
+ key
22
+ });
23
+ var cloneElementWithChildren = (element, children) => ({
24
+ ...element,
25
+ children
26
+ });
27
+ //#endregion
28
+ export { isPdfJsxElement as a, createFragmentNode as i, cloneElementWithChildren as n, isPdfJsxFragment as o, createElementNode as r, Fragment as t };
29
+
30
+ //# sourceMappingURL=node-BeNL0xMl.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"node-BeNL0xMl.js","names":[],"sources":["../src/node.ts"],"sourcesContent":["import type { BuiltinKind, PdfJsxChild, PdfJsxElement, PdfJsxFragment } from './types.js';\n\nexport const Fragment = Symbol.for('@pdfme/jsx.fragment');\n\nexport const isPdfJsxElement = (value: unknown): value is PdfJsxElement =>\n typeof value === 'object' &&\n value !== null &&\n 'kind' in value &&\n typeof (value as { kind?: unknown }).kind === 'string';\n\nexport const isPdfJsxFragment = (value: unknown): value is PdfJsxFragment =>\n typeof value === 'object' &&\n value !== null &&\n 'kind' in value &&\n (value as { kind?: unknown }).kind === 'fragment';\n\nexport const normalizeChildren = (children: unknown): PdfJsxChild[] => {\n if (children === undefined) return [];\n return Array.isArray(children) ? (children as PdfJsxChild[]) : [children as PdfJsxChild];\n};\n\nexport const createElementNode = <K extends BuiltinKind>(\n kind: K,\n rawProps: Record<string, unknown> | null | undefined,\n key?: string | number | null,\n): PdfJsxElement<K> => {\n const { children, ...props } = rawProps ?? {};\n return {\n kind,\n props,\n children: normalizeChildren(children),\n key,\n };\n};\n\nexport const createFragmentNode = (\n rawProps: Record<string, unknown> | null | undefined,\n key?: string | number | null,\n): PdfJsxFragment => ({\n kind: 'fragment',\n children: normalizeChildren(rawProps?.children),\n key,\n});\n\nexport const cloneElementWithChildren = (\n element: PdfJsxElement,\n children: PdfJsxChild[],\n): PdfJsxElement => ({\n ...element,\n children,\n});\n"],"mappings":";AAEA,IAAa,WAAW,OAAO,IAAI,sBAAsB;AAEzD,IAAa,mBAAmB,UAC9B,OAAO,UAAU,YACjB,UAAU,QACV,UAAU,SACV,OAAQ,MAA6B,SAAS;AAEhD,IAAa,oBAAoB,UAC/B,OAAO,UAAU,YACjB,UAAU,QACV,UAAU,SACT,MAA6B,SAAS;AAEzC,IAAa,qBAAqB,aAAqC;AACrE,KAAI,aAAa,KAAA,EAAW,QAAO,EAAE;AACrC,QAAO,MAAM,QAAQ,SAAS,GAAI,WAA6B,CAAC,SAAwB;;AAG1F,IAAa,qBACX,MACA,UACA,QACqB;CACrB,MAAM,EAAE,UAAU,GAAG,UAAU,YAAY,EAAE;AAC7C,QAAO;EACL;EACA;EACA,UAAU,kBAAkB,SAAS;EACrC;EACD;;AAGH,IAAa,sBACX,UACA,SACoB;CACpB,MAAM;CACN,UAAU,kBAAkB,UAAU,SAAS;CAC/C;CACD;AAED,IAAa,4BACX,SACA,cACmB;CACnB,GAAG;CACH;CACD"}
package/dist/node.d.ts ADDED
@@ -0,0 +1,8 @@
1
+ import type { BuiltinKind, PdfJsxChild, PdfJsxElement, PdfJsxFragment } from './types.js';
2
+ export declare const Fragment: unique symbol;
3
+ export declare const isPdfJsxElement: (value: unknown) => value is PdfJsxElement;
4
+ export declare const isPdfJsxFragment: (value: unknown) => value is PdfJsxFragment;
5
+ export declare const normalizeChildren: (children: unknown) => PdfJsxChild[];
6
+ export declare const createElementNode: <K extends BuiltinKind>(kind: K, rawProps: Record<string, unknown> | null | undefined, key?: string | number | null) => PdfJsxElement<K>;
7
+ export declare const createFragmentNode: (rawProps: Record<string, unknown> | null | undefined, key?: string | number | null) => PdfJsxFragment;
8
+ export declare const cloneElementWithChildren: (element: PdfJsxElement, children: PdfJsxChild[]) => PdfJsxElement;
@@ -0,0 +1,2 @@
1
+ import type { PdfJsxChild, RenderOptions, RenderResult } from './types.js';
2
+ export declare const renderToTemplate: (node: PdfJsxChild, options?: RenderOptions) => Promise<RenderResult>;
@@ -0,0 +1,139 @@
1
+ import type { BasePdf, Font, PageOrientation, PageSize, Schema, Template } from '@pdfme/common';
2
+ import type { ALIGNMENT, LIST_STYLE, ListItem as SchemaListItem, CellStyle as SchemaCellStyle, TableSchema, TextSchema } from '@pdfme/schemas/types';
3
+ export type { PageOrientation, PageSize, PageSizePreset } from '@pdfme/common';
4
+ export type BuiltinKind = 'page' | 'stack' | 'row' | 'box' | 'spacer' | 'text' | 'list' | 'table' | 'pagebreak';
5
+ export type PdfJsxElement<K extends BuiltinKind = BuiltinKind> = {
6
+ kind: K;
7
+ props: Record<string, unknown>;
8
+ children: PdfJsxChild[];
9
+ key?: string | number | null;
10
+ };
11
+ export type PdfJsxFragment = {
12
+ kind: 'fragment';
13
+ children: PdfJsxChild[];
14
+ key?: string | number | null;
15
+ };
16
+ export type PdfJsxChild = PdfJsxElement | PdfJsxFragment | string | number | boolean | null | undefined | PdfJsxChild[];
17
+ export type RenderResult = {
18
+ template: Template;
19
+ inputs: Record<string, string>[];
20
+ };
21
+ export type BoxSides = {
22
+ /** Overrides y for the top side. */
23
+ top?: number;
24
+ /** Overrides x for the right side. */
25
+ right?: number;
26
+ /** Overrides y for the bottom side. */
27
+ bottom?: number;
28
+ /** Overrides x for the left side. */
29
+ left?: number;
30
+ /** Horizontal shorthand used when left/right are omitted. */
31
+ x?: number;
32
+ /** Vertical shorthand used when top/bottom are omitted. */
33
+ y?: number;
34
+ };
35
+ export type CommonProps = Partial<Pick<Schema, 'rotate' | 'opacity'>>;
36
+ export type PageProps = {
37
+ size?: PageSize;
38
+ orientation?: PageOrientation;
39
+ margin?: number | BoxSides;
40
+ font?: string;
41
+ children?: PdfJsxChild;
42
+ };
43
+ export type StackProps = {
44
+ gap?: number;
45
+ width?: number;
46
+ children?: PdfJsxChild;
47
+ };
48
+ export type RowProps = {
49
+ gap?: number;
50
+ width?: number;
51
+ height?: number;
52
+ children?: PdfJsxChild;
53
+ };
54
+ export type BoxProps = CommonProps & {
55
+ width?: number;
56
+ height?: number;
57
+ padding?: number | BoxSides;
58
+ background?: string;
59
+ borderColor?: string;
60
+ borderWidth?: number;
61
+ radius?: number;
62
+ children?: PdfJsxChild;
63
+ };
64
+ export type SpacerProps = {
65
+ width?: number;
66
+ height?: number;
67
+ };
68
+ type TextSchemaProps = Partial<Pick<TextSchema, 'name' | 'width' | 'height' | 'lineHeight' | 'strikethrough' | 'underline' | 'readOnly' | 'required' | 'textFormat' | 'overflow'>>;
69
+ export type TextProps = CommonProps & TextSchemaProps & {
70
+ children?: PdfJsxChild;
71
+ size?: TextSchema['fontSize'];
72
+ font?: TextSchema['fontName'];
73
+ align?: TextSchema['alignment'];
74
+ valign?: TextSchema['verticalAlignment'];
75
+ spacing?: TextSchema['characterSpacing'];
76
+ color?: TextSchema['fontColor'];
77
+ background?: TextSchema['backgroundColor'];
78
+ borderColor?: string;
79
+ borderWidth?: number;
80
+ dynamicFontSize?: Partial<NonNullable<TextSchema['dynamicFontSize']>>;
81
+ };
82
+ export type ListItem = string | {
83
+ text: SchemaListItem['text'];
84
+ level?: SchemaListItem['level'];
85
+ };
86
+ export type ListProps = CommonProps & {
87
+ name?: string;
88
+ items?: ListItem[];
89
+ children?: PdfJsxChild;
90
+ width?: number;
91
+ height?: number;
92
+ size?: number;
93
+ font?: string;
94
+ align?: ALIGNMENT;
95
+ lineHeight?: number;
96
+ spacing?: number;
97
+ color?: string;
98
+ background?: string;
99
+ readOnly?: boolean;
100
+ required?: boolean;
101
+ listStyle?: LIST_STYLE;
102
+ markerWidth?: number;
103
+ markerGap?: number;
104
+ indentSize?: number;
105
+ itemSpacing?: number;
106
+ };
107
+ export type CellStyle = Partial<Omit<SchemaCellStyle, 'borderWidth' | 'padding'>> & {
108
+ borderWidth?: number | BoxSides;
109
+ padding?: number | BoxSides;
110
+ };
111
+ export type TableProps = CommonProps & {
112
+ name?: string;
113
+ head: string[];
114
+ rows?: (string | number)[][];
115
+ data?: (string | number)[][];
116
+ /** Column width percentages passed to pdfme headWidthPercentages. */
117
+ widths?: number[];
118
+ width?: number;
119
+ height?: number;
120
+ font?: string;
121
+ fontSize?: number;
122
+ showHead?: boolean;
123
+ repeatHead?: boolean;
124
+ rowHeight?: number;
125
+ headerHeight?: number;
126
+ readOnly?: boolean;
127
+ required?: boolean;
128
+ tableStyles?: Partial<TableSchema['tableStyles']>;
129
+ headStyles?: CellStyle;
130
+ bodyStyles?: CellStyle & {
131
+ alternateBackgroundColor?: string;
132
+ };
133
+ columnStyles?: TableSchema['columnStyles'];
134
+ };
135
+ export type PageBreakProps = Record<string, unknown>;
136
+ export type RenderOptions = {
137
+ basePdf?: BasePdf;
138
+ font?: Font;
139
+ };
package/package.json ADDED
@@ -0,0 +1,67 @@
1
+ {
2
+ "name": "@pdfme/jsx",
3
+ "version": "0.0.0",
4
+ "description": "Author pdfme templates with JSX stacking layout primitives.",
5
+ "keywords": [
6
+ "jsx",
7
+ "pdf",
8
+ "pdf-generation",
9
+ "pdfme",
10
+ "template"
11
+ ],
12
+ "homepage": "https://pdfme.com",
13
+ "bugs": {
14
+ "url": "https://github.com/pdfme/pdfme/issues"
15
+ },
16
+ "license": "MIT",
17
+ "author": "hand-dot",
18
+ "repository": {
19
+ "type": "git",
20
+ "url": "git@github.com:pdfme/pdfme.git"
21
+ },
22
+ "files": [
23
+ "dist",
24
+ "README.md"
25
+ ],
26
+ "type": "module",
27
+ "sideEffects": false,
28
+ "main": "./dist/index.js",
29
+ "module": "./dist/index.js",
30
+ "types": "./dist/index.d.ts",
31
+ "exports": {
32
+ ".": {
33
+ "types": "./dist/index.d.ts",
34
+ "import": "./dist/index.js",
35
+ "default": "./dist/index.js"
36
+ },
37
+ "./jsx-runtime": {
38
+ "types": "./dist/jsx-runtime.d.ts",
39
+ "import": "./dist/jsx-runtime.js",
40
+ "default": "./dist/jsx-runtime.js"
41
+ },
42
+ "./jsx-dev-runtime": {
43
+ "types": "./dist/jsx-dev-runtime.d.ts",
44
+ "import": "./dist/jsx-dev-runtime.js",
45
+ "default": "./dist/jsx-dev-runtime.js"
46
+ }
47
+ },
48
+ "publishConfig": {
49
+ "access": "public"
50
+ },
51
+ "scripts": {
52
+ "dev": "vite build --watch",
53
+ "build": "vite build && tsc -p tsconfig.build.json",
54
+ "clean": "rimraf dist",
55
+ "lint": "vp lint -c ../../.oxlintrc.json src",
56
+ "fmt": "vp fmt -c ../../.oxfmtrc.json src --write",
57
+ "test": "vitest run --config ../../vitest.config.ts"
58
+ },
59
+ "devDependencies": {
60
+ "@pdfme/common": "*",
61
+ "@pdfme/schemas": "*"
62
+ },
63
+ "peerDependencies": {
64
+ "@pdfme/common": "latest",
65
+ "@pdfme/schemas": "latest"
66
+ }
67
+ }