@unlev/exeq 0.5.1 → 0.5.3

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.d.mts CHANGED
@@ -188,7 +188,7 @@ interface PdfViewerProps {
188
188
  onMoveEnd?: () => void;
189
189
  mode: 'designer' | 'signer';
190
190
  currentSigner?: string;
191
- renderFieldContent?: (field: FormField) => React.ReactNode;
191
+ renderFieldContent?: (field: FormField, pageWidthPt?: number, pageHeightPt?: number) => React.ReactNode;
192
192
  zoom?: number;
193
193
  /** Called with field IDs inside a drag-selection rectangle */
194
194
  onMarqueeSelect?: (ids: string[]) => void;
package/dist/index.d.ts CHANGED
@@ -188,7 +188,7 @@ interface PdfViewerProps {
188
188
  onMoveEnd?: () => void;
189
189
  mode: 'designer' | 'signer';
190
190
  currentSigner?: string;
191
- renderFieldContent?: (field: FormField) => React.ReactNode;
191
+ renderFieldContent?: (field: FormField, pageWidthPt?: number, pageHeightPt?: number) => React.ReactNode;
192
192
  zoom?: number;
193
193
  /** Called with field IDs inside a drag-selection rectangle */
194
194
  onMarqueeSelect?: (ids: string[]) => void;
package/dist/index.js CHANGED
@@ -416,6 +416,8 @@ function PdfViewer({
416
416
  selectedIds: selectedFieldIds,
417
417
  mode,
418
418
  currentSigner,
419
+ pageWidthPt: page.pdfWidth,
420
+ pageHeightPt: page.pdfHeight,
419
421
  renderContent: renderFieldContent
420
422
  },
421
423
  field.id
@@ -506,6 +508,8 @@ function FieldOverlayItem({
506
508
  selectedIds,
507
509
  mode,
508
510
  currentSigner,
511
+ pageWidthPt,
512
+ pageHeightPt,
509
513
  renderContent
510
514
  }) {
511
515
  const overlayRef = (0, import_react.useRef)(null);
@@ -632,7 +636,7 @@ function FieldOverlayItem({
632
636
  onMouseDown: handleMouseDown,
633
637
  children: [
634
638
  mode === "designer" && !isRedact && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "field-overlay-label", style: { backgroundColor: color }, children: field.label }),
635
- renderContent ? renderContent(field) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "field-overlay-placeholder", children: field.value || field.placeholder }),
639
+ renderContent ? renderContent(field, pageWidthPt, pageHeightPt) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "field-overlay-placeholder", children: field.value || field.placeholder }),
636
640
  mode === "designer" && isSelected && !field.locked && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
637
641
  "div",
638
642
  {
@@ -2278,6 +2282,19 @@ function resolveAllFormulas(fields, customTransforms, values) {
2278
2282
  });
2279
2283
  }
2280
2284
 
2285
+ // src/utils/fitText.ts
2286
+ function fitFontSize(o) {
2287
+ let size = o.autoShrink ? Math.min(o.fontSize, o.fieldHeightPt * 0.7) : o.fontSize;
2288
+ if (o.autoShrink && o.value) {
2289
+ const padding = 4;
2290
+ while (size > 4) {
2291
+ if (o.measure(o.value, size) <= o.fieldWidthPt - padding) break;
2292
+ size -= 0.5;
2293
+ }
2294
+ }
2295
+ return size;
2296
+ }
2297
+
2281
2298
  // src/utils/pdfFiller.ts
2282
2299
  var FONT_VARIANTS = {
2283
2300
  Helvetica: [import_pdf_lib.StandardFonts.Helvetica, import_pdf_lib.StandardFonts.HelveticaBold, import_pdf_lib.StandardFonts.HelveticaOblique, import_pdf_lib.StandardFonts.HelveticaBoldOblique],
@@ -2369,14 +2386,14 @@ async function renderFieldsOnPages(pages, fields, getFont, getSignature) {
2369
2386
  const font = await getFont(field.fontFamily || "Helvetica", field.bold, field.italic);
2370
2387
  const spacing = field.letterSpacing || 0;
2371
2388
  const textWidthAtSize = (text, size) => font.widthOfTextAtSize(text, size) + spacing * (text.length - 1);
2372
- let fontSize = field.autoShrink ? Math.min(field.fontSize, h * 0.7) : field.fontSize;
2373
- if (field.autoShrink) {
2374
- const padding = 4;
2375
- while (fontSize > 4) {
2376
- if (textWidthAtSize(field.value, fontSize) <= w - padding) break;
2377
- fontSize -= 0.5;
2378
- }
2379
- }
2389
+ const fontSize = fitFontSize({
2390
+ value: field.value,
2391
+ fontSize: field.fontSize,
2392
+ autoShrink: field.autoShrink,
2393
+ fieldWidthPt: w,
2394
+ fieldHeightPt: h,
2395
+ measure: textWidthAtSize
2396
+ });
2380
2397
  const textX = x + 2;
2381
2398
  const baselineY = y + h * 0.3;
2382
2399
  if (spacing > 0) {
@@ -2630,6 +2647,41 @@ function FieldNavigator({
2630
2647
 
2631
2648
  // src/components/pdf-builder/SignerView.tsx
2632
2649
  var import_jsx_runtime6 = require("react/jsx-runtime");
2650
+ var useIsoLayoutEffect = typeof window !== "undefined" ? import_react7.useLayoutEffect : import_react7.useEffect;
2651
+ function shrinkToFit(el, maxPt, selfBox) {
2652
+ if (!el) return;
2653
+ const box = selfBox ? el : el.parentElement;
2654
+ if (!box) return;
2655
+ let pt = Math.max(1, maxPt);
2656
+ el.style.fontSize = `${pt}pt`;
2657
+ let guard = 0;
2658
+ while (pt > 2 && guard++ < 400 && (el.scrollWidth > box.clientWidth + 0.5 || el.scrollHeight > box.clientHeight + 0.5)) {
2659
+ pt -= 0.5;
2660
+ el.style.fontSize = `${pt}pt`;
2661
+ }
2662
+ }
2663
+ function FitInput({
2664
+ maxPt,
2665
+ ...rest
2666
+ }) {
2667
+ const ref = (0, import_react7.useRef)(null);
2668
+ useIsoLayoutEffect(() => {
2669
+ shrinkToFit(ref.current, maxPt, true);
2670
+ });
2671
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("input", { ref, ...rest });
2672
+ }
2673
+ function FitText({
2674
+ maxPt,
2675
+ className,
2676
+ style,
2677
+ children
2678
+ }) {
2679
+ const ref = (0, import_react7.useRef)(null);
2680
+ useIsoLayoutEffect(() => {
2681
+ shrinkToFit(ref.current, maxPt, false);
2682
+ });
2683
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { ref, className, style, children });
2684
+ }
2633
2685
  function SignerView({
2634
2686
  apiKey,
2635
2687
  initialPdfUrl,
@@ -2886,7 +2938,7 @@ ${row.join(",")}`, "csv");
2886
2938
  return null;
2887
2939
  }
2888
2940
  if (field.formula) {
2889
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "field-overlay-value formula", children: field.value || "..." });
2941
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(FitText, { maxPt: field.fontSize, className: "field-overlay-value formula", style: getCssTextStyle(field), children: field.value || "..." });
2890
2942
  }
2891
2943
  const editable = field.assignee === signer;
2892
2944
  if (!editable) {
@@ -2896,7 +2948,7 @@ ${row.join(",")}`, "csv");
2896
2948
  if (field.type === "checkbox") {
2897
2949
  return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "field-checkbox-display readonly", children: field.value === "true" ? "\u2713" : "" });
2898
2950
  }
2899
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "field-overlay-placeholder readonly", children: field.value || field.placeholder });
2951
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(FitText, { maxPt: field.fontSize, className: "field-overlay-placeholder readonly", style: getCssTextStyle(field), children: field.value || field.placeholder });
2900
2952
  }
2901
2953
  if (isSignatureField(field)) {
2902
2954
  if (field.value) {
@@ -2918,10 +2970,9 @@ ${row.join(",")}`, "csv");
2918
2970
  );
2919
2971
  }
2920
2972
  if (field.type === "signed-date") {
2921
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "field-overlay-value", children: field.value || (/* @__PURE__ */ new Date()).toLocaleDateString() });
2973
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(FitText, { maxPt: field.fontSize, className: "field-overlay-value", style: getCssTextStyle(field), children: field.value || (/* @__PURE__ */ new Date()).toLocaleDateString() });
2922
2974
  }
2923
2975
  const fontStyle = {
2924
- fontSize: `${field.fontSize}pt`,
2925
2976
  letterSpacing: field.letterSpacing ? `${field.letterSpacing}pt` : void 0,
2926
2977
  lineHeight: field.lineHeight ? `${field.lineHeight}` : void 0,
2927
2978
  ...getCssTextStyle(field)
@@ -2935,7 +2986,7 @@ ${row.join(",")}`, "csv");
2935
2986
  onChange: (e) => handleFieldUpdate(field.id, e.target.value),
2936
2987
  onFocus: () => setSelectedFieldId(field.id),
2937
2988
  onClick: (e) => e.stopPropagation(),
2938
- style: fontStyle,
2989
+ style: { fontSize: `${field.fontSize}pt`, ...fontStyle },
2939
2990
  children: [
2940
2991
  /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("option", { value: "", children: field.placeholder || "Select..." }),
2941
2992
  (field.options || []).map((opt) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("option", { value: opt, children: opt }, opt))
@@ -2944,8 +2995,9 @@ ${row.join(",")}`, "csv");
2944
2995
  );
2945
2996
  }
2946
2997
  return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
2947
- "input",
2998
+ FitInput,
2948
2999
  {
3000
+ maxPt: field.fontSize,
2949
3001
  type: field.textSubtype === "email" ? "email" : field.textSubtype === "number" ? "number" : field.textSubtype === "phone" ? "tel" : field.textSubtype === "date" ? "date" : "text",
2950
3002
  className: "field-inline-input",
2951
3003
  value: field.value,