@signiphi/pdf-compose 0.1.0-beta.10 → 0.1.0-beta.12

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/dist/index.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  import * as React12 from 'react';
2
2
  import React12__default, { createContext, useCallback, useState, useRef, useEffect, useMemo, useContext } from 'react';
3
- import { AlertTriangle, RefreshCw, FileText, ChevronDown, Circle, CheckSquare, Calendar, Hash, PenTool, Type, Braces, Droplets, ChevronLeft, ChevronRight, ZoomOut, ZoomIn, Maximize2, Loader2, Plus, Save, FileDown, CheckCircle2, PanelLeftOpen, PanelLeftClose, Undo, Redo, Bold, Italic, Underline as Underline$1, Code, Heading1, Heading2, Heading3, List, ListOrdered, Quote, Minus, AlignLeft, AlignCenter, AlignRight, Trash2, X, PenLine, Upload, Search, WrapText, Download } from 'lucide-react';
3
+ import { AlertTriangle, RefreshCw, FileText, ChevronDown, Circle, CheckSquare, Calendar, Hash, PenTool, Type, Braces, Droplets, Image, ChevronLeft, ChevronRight, ZoomOut, ZoomIn, Maximize2, Loader2, Plus, Save, FileDown, CheckCircle2, PanelLeftOpen, PanelLeftClose, Undo, Redo, Bold, Italic, Underline as Underline$1, Code, Heading1, Heading2, Heading3, List, ListOrdered, Quote, Minus, AlignLeft, AlignCenter, AlignRight, Trash2, X, PenLine, Upload, Search, WrapText, Download } from 'lucide-react';
4
4
  import { ReactNodeViewRenderer, NodeViewWrapper, useEditor, EditorContent } from '@tiptap/react';
5
5
  import StarterKit from '@tiptap/starter-kit';
6
6
  import Underline from '@tiptap/extension-underline';
@@ -15,7 +15,7 @@ import { clsx } from 'clsx';
15
15
  import { twMerge } from 'tailwind-merge';
16
16
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
17
17
  import { v4 } from 'uuid';
18
- import { PDFDocument, StandardFonts, rgb, degrees, PDFName as PDFName$1, PDFString as PDFString$1 } from 'pdf-lib';
18
+ import { PDFDocument, StandardFonts, rgb, degrees, PDFName as PDFName$1, PDFString, PDFHexString as PDFHexString$1 } from 'pdf-lib';
19
19
  import { NodeSelection } from '@tiptap/pm/state';
20
20
  import { Slot } from '@radix-ui/react-slot';
21
21
  import { cva } from 'class-variance-authority';
@@ -418,6 +418,72 @@ var WatermarkNode = Node.create({
418
418
  return ReactNodeViewRenderer(WatermarkNodeView);
419
419
  }
420
420
  });
421
+ function ImageNodeView({ node, selected }) {
422
+ const { src, varName, alt, width, height, align } = node.attrs;
423
+ const hasRenderableSrc = !!src && /^(https?:|data:)/i.test(src);
424
+ const wrapperJustify = align === "center" ? "justify-center" : align === "right" ? "justify-end" : "justify-start";
425
+ const toCssSize = (v) => /^\d+(\.\d+)?$/.test(v) ? `${v}px` : v;
426
+ const sizeStyle = {};
427
+ if (width) sizeStyle.width = toCssSize(width);
428
+ if (height) sizeStyle.height = toCssSize(height);
429
+ return /* @__PURE__ */ jsx(NodeViewWrapper, { children: /* @__PURE__ */ jsx("div", { className: cn("flex my-1", wrapperJustify), "data-image-node": "", children: hasRenderableSrc ? /* @__PURE__ */ jsx(
430
+ "img",
431
+ {
432
+ src,
433
+ alt: alt || varName || "",
434
+ style: sizeStyle,
435
+ className: cn(
436
+ "max-w-full rounded-sm object-contain",
437
+ selected && "ring-2 ring-primary ring-offset-1"
438
+ ),
439
+ draggable: false
440
+ }
441
+ ) : /* @__PURE__ */ jsxs(
442
+ "div",
443
+ {
444
+ "data-image-placeholder": "",
445
+ className: cn(
446
+ "inline-flex items-center gap-2 px-3 py-2 rounded-md border border-dashed text-sm",
447
+ "bg-slate-50 text-slate-500 border-slate-300",
448
+ selected && "ring-2 ring-primary ring-offset-1"
449
+ ),
450
+ style: height ? { minHeight: toCssSize(height) } : void 0,
451
+ title: varName ? `Image variable: ${varName}` : "Image",
452
+ children: [
453
+ /* @__PURE__ */ jsx(Image, { size: 16 }),
454
+ /* @__PURE__ */ jsx("span", { children: varName ? `Image: ${varName}` : alt || "Image" })
455
+ ]
456
+ }
457
+ ) }) });
458
+ }
459
+
460
+ // src/extensions/image-node.ts
461
+ var ImageNode = Node.create({
462
+ name: "imageNode",
463
+ group: "block",
464
+ atom: true,
465
+ selectable: true,
466
+ draggable: false,
467
+ addAttributes() {
468
+ return {
469
+ src: { default: "" },
470
+ varName: { default: "" },
471
+ alt: { default: "" },
472
+ width: { default: "" },
473
+ height: { default: "" },
474
+ align: { default: "" }
475
+ };
476
+ },
477
+ parseHTML() {
478
+ return [{ tag: "div[data-image-node]" }];
479
+ },
480
+ renderHTML({ HTMLAttributes }) {
481
+ return ["div", mergeAttributes({ "data-image-node": "" }, HTMLAttributes)];
482
+ },
483
+ addNodeView() {
484
+ return ReactNodeViewRenderer(ImageNodeView);
485
+ }
486
+ });
421
487
  var RepeatNode = Node.create({
422
488
  name: "repeatBlock",
423
489
  group: "block",
@@ -1062,11 +1128,23 @@ function parseBlocks(lines, startIdx, stopCondition) {
1062
1128
  continue;
1063
1129
  }
1064
1130
  const inlineNodes = parseInline(line);
1065
- const nonWhitespace = inlineNodes.filter(
1066
- (n) => !(n.type === "text" && !(n.text || "").trim())
1067
- );
1068
- if (nonWhitespace.length === 1 && nonWhitespace[0].type === "imageNode") {
1069
- content.push(nonWhitespace[0]);
1131
+ if (inlineNodes.some((n) => n.type === "imageNode")) {
1132
+ let run = [];
1133
+ const flushRun = () => {
1134
+ if (run.some((n) => !(n.type === "text" && !(n.text || "").trim()))) {
1135
+ content.push({ type: "paragraph", content: run });
1136
+ }
1137
+ run = [];
1138
+ };
1139
+ for (const n of inlineNodes) {
1140
+ if (n.type === "imageNode") {
1141
+ flushRun();
1142
+ content.push(n);
1143
+ } else {
1144
+ run.push(n);
1145
+ }
1146
+ }
1147
+ flushRun();
1070
1148
  } else {
1071
1149
  content.push({ type: "paragraph", content: inlineNodes });
1072
1150
  }
@@ -1391,13 +1469,13 @@ near: ${snippet}`;
1391
1469
 
1392
1470
  // src/utils/pdf-metadata.ts
1393
1471
  var PDFName;
1394
- var PDFString;
1472
+ var PDFHexString;
1395
1473
  function initPdfMetadata(pdfLibModule) {
1396
1474
  PDFName = pdfLibModule.PDFName;
1397
- PDFString = pdfLibModule.PDFString;
1475
+ PDFHexString = pdfLibModule.PDFHexString;
1398
1476
  }
1399
1477
  function setSigniphiMetadata(pdfDoc, metadata) {
1400
- if (!PDFName || !PDFString) {
1478
+ if (!PDFName || !PDFHexString) {
1401
1479
  throw new Error("PDF metadata classes not initialized \u2014 call initPdfMetadata before setSigniphiMetadata");
1402
1480
  }
1403
1481
  try {
@@ -1408,7 +1486,7 @@ function setSigniphiMetadata(pdfDoc, metadata) {
1408
1486
  }
1409
1487
  const infoDict = infoObj;
1410
1488
  const metadataString = JSON.stringify(metadata);
1411
- infoDict.set(PDFName.of("SigniphiMetadata"), PDFString.of(metadataString));
1489
+ infoDict.set(PDFName.of("SigniphiMetadata"), PDFHexString.fromText(metadataString));
1412
1490
  } catch (error) {
1413
1491
  throw new Error(`Failed to embed document metadata: ${getErrorMessage(error)}`);
1414
1492
  }
@@ -2535,7 +2613,7 @@ async function addFormFields(pdfDoc, fieldPositions, fields) {
2535
2613
  }
2536
2614
  textField.acroField.dict.set(
2537
2615
  PDFName$1.of("TU"),
2538
- PDFString$1.of(tuValue)
2616
+ PDFString.of(tuValue)
2539
2617
  );
2540
2618
  }
2541
2619
  if (field.defaultValue && field.defaultValue.trim()) {
@@ -2579,7 +2657,7 @@ async function addFormFields(pdfDoc, fieldPositions, fields) {
2579
2657
  if (field.label && field.label.trim()) {
2580
2658
  sigField.acroField.dict.set(
2581
2659
  PDFName$1.of("TU"),
2582
- PDFString$1.of(field.label)
2660
+ PDFString.of(field.label)
2583
2661
  );
2584
2662
  }
2585
2663
  sigField.enableReadOnly();
@@ -2601,7 +2679,7 @@ async function addFormFields(pdfDoc, fieldPositions, fields) {
2601
2679
  if (field.label && field.label.trim()) {
2602
2680
  initialsField.acroField.dict.set(
2603
2681
  PDFName$1.of("TU"),
2604
- PDFString$1.of(field.label)
2682
+ PDFString.of(field.label)
2605
2683
  );
2606
2684
  }
2607
2685
  const initialsFontSize = Math.min(
@@ -2616,7 +2694,7 @@ async function addFormFields(pdfDoc, fieldPositions, fields) {
2616
2694
  const daStr = daRef.value;
2617
2695
  if (typeof daStr === "string") {
2618
2696
  const newDa = daStr.replace(/\/Helv\b/, "/TiBo").replace(/\/HeBo\b/, "/TiBo");
2619
- acro.acroField.dict.set(PDFName$1.of("DA"), PDFString$1.of(newDa));
2697
+ acro.acroField.dict.set(PDFName$1.of("DA"), PDFString.of(newDa));
2620
2698
  }
2621
2699
  }
2622
2700
  } catch (fontError) {
@@ -2642,7 +2720,7 @@ async function addFormFields(pdfDoc, fieldPositions, fields) {
2642
2720
  if (tuValue) {
2643
2721
  dateField.acroField.dict.set(
2644
2722
  PDFName$1.of("TU"),
2645
- PDFString$1.of(tuValue)
2723
+ PDFString.of(tuValue)
2646
2724
  );
2647
2725
  }
2648
2726
  if (field.required) dateField.enableRequired();
@@ -2726,7 +2804,7 @@ async function addFormFields(pdfDoc, fieldPositions, fields) {
2726
2804
  warnings.push(`Failed to create ${field.type} field "${field.name}": ${getErrorMessage(err)}`);
2727
2805
  }
2728
2806
  }
2729
- initPdfMetadata({ PDFName: PDFName$1, PDFString: PDFString$1 });
2807
+ initPdfMetadata({ PDFName: PDFName$1, PDFHexString: PDFHexString$1 });
2730
2808
  const metadata = buildMetadataObject(fields, actualFieldNames);
2731
2809
  setSigniphiMetadata(pdfDoc, metadata);
2732
2810
  return warnings;
@@ -3192,6 +3270,7 @@ function useDocumentGenerator(options = {}) {
3192
3270
  ColumnsNode,
3193
3271
  ColumnNode,
3194
3272
  WatermarkNode,
3273
+ ImageNode,
3195
3274
  RepeatNode,
3196
3275
  SubtotalsNode
3197
3276
  ],
@@ -7428,6 +7507,6 @@ function parseXmlTemplate(xmlString) {
7428
7507
  };
7429
7508
  }
7430
7509
 
7431
- export { DocumentGenerator, EditorPanel, FormFieldType, PreviewPanel, RepeatNode, SubtotalsNode, ThemeProvider, expandBlockVariables, expandRepeatContent, extractVariablesFromContent, generatePdfFromMarkdown, generatePdfFromTiptap, isZeroLike, markdownToTiptap, parseXmlTemplate, suppressZeroContent, tiptapToMarkdown, useDocumentGenerator, useTheme };
7510
+ export { DocumentGenerator, EditorPanel, FormFieldType, ImageNode, PreviewPanel, RepeatNode, SubtotalsNode, ThemeProvider, expandBlockVariables, expandRepeatContent, extractVariablesFromContent, generatePdfFromMarkdown, generatePdfFromTiptap, isZeroLike, markdownToTiptap, parseXmlTemplate, suppressZeroContent, tiptapToMarkdown, useDocumentGenerator, useTheme };
7432
7511
  //# sourceMappingURL=index.mjs.map
7433
7512
  //# sourceMappingURL=index.mjs.map