@unlev/exeq 0.5.0 → 0.5.2
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 +28 -4
- package/dist/index.d.ts +28 -4
- package/dist/index.js +108 -34
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +107 -34
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -95,19 +95,39 @@ declare function DesignerView({ apiKey, initialPdfUrl, initialTemplate, onSave,
|
|
|
95
95
|
|
|
96
96
|
type TransformFn = (value: string) => string;
|
|
97
97
|
type TransformMap = Record<string, TransformFn>;
|
|
98
|
+
/**
|
|
99
|
+
* Parse a date string robustly into a local Date (midnight, local TZ) so that
|
|
100
|
+
* getMonth/getDate/getFullYear are calendar-correct. Handles:
|
|
101
|
+
* - ISO date-only "YYYY-MM-DD" → parsed as LOCAL (avoids the classic UTC
|
|
102
|
+
* off-by-one where "2024-03-15" becomes the 14th in western timezones).
|
|
103
|
+
* - Excel serial numbers (a bare integer, e.g. "45000") → converted.
|
|
104
|
+
* - Anything else → native `new Date` (handles "M/D/YYYY", ISO datetimes, …).
|
|
105
|
+
* Returns null when unparseable.
|
|
106
|
+
*/
|
|
107
|
+
declare function parseDate(value: string): Date | null;
|
|
98
108
|
/** Built-in transforms that ship with exeq. */
|
|
99
109
|
declare const BUILTIN_TRANSFORMS: TransformMap;
|
|
100
110
|
/**
|
|
101
111
|
* Resolve a single formula string against a set of fields and transforms.
|
|
102
112
|
* Formula format: "{{Source Field Label | transform}}" or "{{Source Field Label}}" (no transform = raw value).
|
|
103
113
|
* Multiple expressions can appear in one formula: "{{First}} {{Last}}" → "Jane Smith"
|
|
114
|
+
*
|
|
115
|
+
* Source resolution order for "{{Name}}":
|
|
116
|
+
* 1. a placed field whose label (case-insensitive) or id matches Name
|
|
117
|
+
* 2. `values[Name]` — imported/contextual data not tied to a placed field
|
|
118
|
+
* 3. the built-in `today` / `now` source (current date)
|
|
119
|
+
*
|
|
120
|
+
* @param values Extra named values (e.g. imported CSV/form data) made available
|
|
121
|
+
* to formula sources even when there is no placed field for them.
|
|
104
122
|
*/
|
|
105
|
-
declare function resolveFormula(formula: string, fields: FormField[], customTransforms?: TransformMap): string;
|
|
123
|
+
declare function resolveFormula(formula: string, fields: FormField[], customTransforms?: TransformMap, values?: Record<string, string>): string;
|
|
106
124
|
/**
|
|
107
125
|
* Resolve all formula fields in a fields array.
|
|
108
126
|
* Returns a new array with computed values filled in.
|
|
127
|
+
*
|
|
128
|
+
* @param values Extra named values available to formula sources (see resolveFormula).
|
|
109
129
|
*/
|
|
110
|
-
declare function resolveAllFormulas(fields: FormField[], customTransforms?: TransformMap): FormField[];
|
|
130
|
+
declare function resolveAllFormulas(fields: FormField[], customTransforms?: TransformMap, values?: Record<string, string>): FormField[];
|
|
111
131
|
|
|
112
132
|
interface SignerViewProps {
|
|
113
133
|
/** API key for authentication */
|
|
@@ -168,7 +188,7 @@ interface PdfViewerProps {
|
|
|
168
188
|
onMoveEnd?: () => void;
|
|
169
189
|
mode: 'designer' | 'signer';
|
|
170
190
|
currentSigner?: string;
|
|
171
|
-
renderFieldContent?: (field: FormField) => React.ReactNode;
|
|
191
|
+
renderFieldContent?: (field: FormField, pageWidthPt?: number, pageHeightPt?: number) => React.ReactNode;
|
|
172
192
|
zoom?: number;
|
|
173
193
|
/** Called with field IDs inside a drag-selection rectangle */
|
|
174
194
|
onMarqueeSelect?: (ids: string[]) => void;
|
|
@@ -283,6 +303,10 @@ interface FillPdfOptions {
|
|
|
283
303
|
/** Custom transforms merged with `BUILTIN_TRANSFORMS` during formula
|
|
284
304
|
* resolution. Only meaningful when `resolveFormulas` is true. */
|
|
285
305
|
customTransforms?: TransformMap;
|
|
306
|
+
/** Extra named values made available to formula sources (e.g. imported CSV/
|
|
307
|
+
* form data) even when there is no placed field for them. Only meaningful
|
|
308
|
+
* when `resolveFormulas` is true. */
|
|
309
|
+
formulaValues?: Record<string, string>;
|
|
286
310
|
/** Linear calibration applied to field positions before rendering. */
|
|
287
311
|
calibration?: Calibration;
|
|
288
312
|
}
|
|
@@ -335,4 +359,4 @@ declare function createPdfBuilder(defaults?: CreatePdfBuilderOptions): Promise<P
|
|
|
335
359
|
declare function downloadPdf(bytes: Uint8Array, filename: string): void;
|
|
336
360
|
declare function postPdfToCallback(bytes: Uint8Array, callbackUrl: string, filename: string): Promise<void>;
|
|
337
361
|
|
|
338
|
-
export { A4, BUILTIN_TRANSFORMS, type Calibration, type CreatePdfBuilderOptions, DEFAULT_CALIBRATION, DEFAULT_SIGNER_ROLES, DesignerView, type DesignerViewProps, FIELD_DEFAULTS, FONT_FAMILIES, FieldNavigator, FieldPropertyPanel, type FieldType, type FillPdfOptions, type FormField, type PdfBuilder, PdfViewer, type RenderedPage, SIGNER_ROLE_COLORS, SignatureCanvas, SignerRoleSelector, SignerView, type SignerViewProps, type Template, type TextSubtype, type TransformFn, type TransformMap, US_LEGAL, US_LETTER, applyCalibration, createField, createPdfBuilder, downloadPdf, generateFilledPdf, generateId, getCssFontFamily, getFieldValues, getInputType, getSignerColor, isRedactField, isSignatureField, isTextLikeField, postPdfToCallback, preserveFieldValues, renderPdfPages, resolveAllFormulas, resolveFormula, sortFieldsByPosition, uniqueLabel };
|
|
362
|
+
export { A4, BUILTIN_TRANSFORMS, type Calibration, type CreatePdfBuilderOptions, DEFAULT_CALIBRATION, DEFAULT_SIGNER_ROLES, DesignerView, type DesignerViewProps, FIELD_DEFAULTS, FONT_FAMILIES, FieldNavigator, FieldPropertyPanel, type FieldType, type FillPdfOptions, type FormField, type PdfBuilder, PdfViewer, type RenderedPage, SIGNER_ROLE_COLORS, SignatureCanvas, SignerRoleSelector, SignerView, type SignerViewProps, type Template, type TextSubtype, type TransformFn, type TransformMap, US_LEGAL, US_LETTER, applyCalibration, createField, createPdfBuilder, downloadPdf, generateFilledPdf, generateId, getCssFontFamily, getFieldValues, getInputType, getSignerColor, isRedactField, isSignatureField, isTextLikeField, parseDate, postPdfToCallback, preserveFieldValues, renderPdfPages, resolveAllFormulas, resolveFormula, sortFieldsByPosition, uniqueLabel };
|
package/dist/index.d.ts
CHANGED
|
@@ -95,19 +95,39 @@ declare function DesignerView({ apiKey, initialPdfUrl, initialTemplate, onSave,
|
|
|
95
95
|
|
|
96
96
|
type TransformFn = (value: string) => string;
|
|
97
97
|
type TransformMap = Record<string, TransformFn>;
|
|
98
|
+
/**
|
|
99
|
+
* Parse a date string robustly into a local Date (midnight, local TZ) so that
|
|
100
|
+
* getMonth/getDate/getFullYear are calendar-correct. Handles:
|
|
101
|
+
* - ISO date-only "YYYY-MM-DD" → parsed as LOCAL (avoids the classic UTC
|
|
102
|
+
* off-by-one where "2024-03-15" becomes the 14th in western timezones).
|
|
103
|
+
* - Excel serial numbers (a bare integer, e.g. "45000") → converted.
|
|
104
|
+
* - Anything else → native `new Date` (handles "M/D/YYYY", ISO datetimes, …).
|
|
105
|
+
* Returns null when unparseable.
|
|
106
|
+
*/
|
|
107
|
+
declare function parseDate(value: string): Date | null;
|
|
98
108
|
/** Built-in transforms that ship with exeq. */
|
|
99
109
|
declare const BUILTIN_TRANSFORMS: TransformMap;
|
|
100
110
|
/**
|
|
101
111
|
* Resolve a single formula string against a set of fields and transforms.
|
|
102
112
|
* Formula format: "{{Source Field Label | transform}}" or "{{Source Field Label}}" (no transform = raw value).
|
|
103
113
|
* Multiple expressions can appear in one formula: "{{First}} {{Last}}" → "Jane Smith"
|
|
114
|
+
*
|
|
115
|
+
* Source resolution order for "{{Name}}":
|
|
116
|
+
* 1. a placed field whose label (case-insensitive) or id matches Name
|
|
117
|
+
* 2. `values[Name]` — imported/contextual data not tied to a placed field
|
|
118
|
+
* 3. the built-in `today` / `now` source (current date)
|
|
119
|
+
*
|
|
120
|
+
* @param values Extra named values (e.g. imported CSV/form data) made available
|
|
121
|
+
* to formula sources even when there is no placed field for them.
|
|
104
122
|
*/
|
|
105
|
-
declare function resolveFormula(formula: string, fields: FormField[], customTransforms?: TransformMap): string;
|
|
123
|
+
declare function resolveFormula(formula: string, fields: FormField[], customTransforms?: TransformMap, values?: Record<string, string>): string;
|
|
106
124
|
/**
|
|
107
125
|
* Resolve all formula fields in a fields array.
|
|
108
126
|
* Returns a new array with computed values filled in.
|
|
127
|
+
*
|
|
128
|
+
* @param values Extra named values available to formula sources (see resolveFormula).
|
|
109
129
|
*/
|
|
110
|
-
declare function resolveAllFormulas(fields: FormField[], customTransforms?: TransformMap): FormField[];
|
|
130
|
+
declare function resolveAllFormulas(fields: FormField[], customTransforms?: TransformMap, values?: Record<string, string>): FormField[];
|
|
111
131
|
|
|
112
132
|
interface SignerViewProps {
|
|
113
133
|
/** API key for authentication */
|
|
@@ -168,7 +188,7 @@ interface PdfViewerProps {
|
|
|
168
188
|
onMoveEnd?: () => void;
|
|
169
189
|
mode: 'designer' | 'signer';
|
|
170
190
|
currentSigner?: string;
|
|
171
|
-
renderFieldContent?: (field: FormField) => React.ReactNode;
|
|
191
|
+
renderFieldContent?: (field: FormField, pageWidthPt?: number, pageHeightPt?: number) => React.ReactNode;
|
|
172
192
|
zoom?: number;
|
|
173
193
|
/** Called with field IDs inside a drag-selection rectangle */
|
|
174
194
|
onMarqueeSelect?: (ids: string[]) => void;
|
|
@@ -283,6 +303,10 @@ interface FillPdfOptions {
|
|
|
283
303
|
/** Custom transforms merged with `BUILTIN_TRANSFORMS` during formula
|
|
284
304
|
* resolution. Only meaningful when `resolveFormulas` is true. */
|
|
285
305
|
customTransforms?: TransformMap;
|
|
306
|
+
/** Extra named values made available to formula sources (e.g. imported CSV/
|
|
307
|
+
* form data) even when there is no placed field for them. Only meaningful
|
|
308
|
+
* when `resolveFormulas` is true. */
|
|
309
|
+
formulaValues?: Record<string, string>;
|
|
286
310
|
/** Linear calibration applied to field positions before rendering. */
|
|
287
311
|
calibration?: Calibration;
|
|
288
312
|
}
|
|
@@ -335,4 +359,4 @@ declare function createPdfBuilder(defaults?: CreatePdfBuilderOptions): Promise<P
|
|
|
335
359
|
declare function downloadPdf(bytes: Uint8Array, filename: string): void;
|
|
336
360
|
declare function postPdfToCallback(bytes: Uint8Array, callbackUrl: string, filename: string): Promise<void>;
|
|
337
361
|
|
|
338
|
-
export { A4, BUILTIN_TRANSFORMS, type Calibration, type CreatePdfBuilderOptions, DEFAULT_CALIBRATION, DEFAULT_SIGNER_ROLES, DesignerView, type DesignerViewProps, FIELD_DEFAULTS, FONT_FAMILIES, FieldNavigator, FieldPropertyPanel, type FieldType, type FillPdfOptions, type FormField, type PdfBuilder, PdfViewer, type RenderedPage, SIGNER_ROLE_COLORS, SignatureCanvas, SignerRoleSelector, SignerView, type SignerViewProps, type Template, type TextSubtype, type TransformFn, type TransformMap, US_LEGAL, US_LETTER, applyCalibration, createField, createPdfBuilder, downloadPdf, generateFilledPdf, generateId, getCssFontFamily, getFieldValues, getInputType, getSignerColor, isRedactField, isSignatureField, isTextLikeField, postPdfToCallback, preserveFieldValues, renderPdfPages, resolveAllFormulas, resolveFormula, sortFieldsByPosition, uniqueLabel };
|
|
362
|
+
export { A4, BUILTIN_TRANSFORMS, type Calibration, type CreatePdfBuilderOptions, DEFAULT_CALIBRATION, DEFAULT_SIGNER_ROLES, DesignerView, type DesignerViewProps, FIELD_DEFAULTS, FONT_FAMILIES, FieldNavigator, FieldPropertyPanel, type FieldType, type FillPdfOptions, type FormField, type PdfBuilder, PdfViewer, type RenderedPage, SIGNER_ROLE_COLORS, SignatureCanvas, SignerRoleSelector, SignerView, type SignerViewProps, type Template, type TextSubtype, type TransformFn, type TransformMap, US_LEGAL, US_LETTER, applyCalibration, createField, createPdfBuilder, downloadPdf, generateFilledPdf, generateId, getCssFontFamily, getFieldValues, getInputType, getSignerColor, isRedactField, isSignatureField, isTextLikeField, parseDate, postPdfToCallback, preserveFieldValues, renderPdfPages, resolveAllFormulas, resolveFormula, sortFieldsByPosition, uniqueLabel };
|
package/dist/index.js
CHANGED
|
@@ -59,6 +59,7 @@ __export(lib_exports, {
|
|
|
59
59
|
isRedactField: () => isRedactField,
|
|
60
60
|
isSignatureField: () => isSignatureField,
|
|
61
61
|
isTextLikeField: () => isTextLikeField,
|
|
62
|
+
parseDate: () => parseDate,
|
|
62
63
|
postPdfToCallback: () => postPdfToCallback,
|
|
63
64
|
preserveFieldValues: () => preserveFieldValues,
|
|
64
65
|
renderPdfPages: () => renderPdfPages,
|
|
@@ -415,6 +416,8 @@ function PdfViewer({
|
|
|
415
416
|
selectedIds: selectedFieldIds,
|
|
416
417
|
mode,
|
|
417
418
|
currentSigner,
|
|
419
|
+
pageWidthPt: page.pdfWidth,
|
|
420
|
+
pageHeightPt: page.pdfHeight,
|
|
418
421
|
renderContent: renderFieldContent
|
|
419
422
|
},
|
|
420
423
|
field.id
|
|
@@ -505,6 +508,8 @@ function FieldOverlayItem({
|
|
|
505
508
|
selectedIds,
|
|
506
509
|
mode,
|
|
507
510
|
currentSigner,
|
|
511
|
+
pageWidthPt,
|
|
512
|
+
pageHeightPt,
|
|
508
513
|
renderContent
|
|
509
514
|
}) {
|
|
510
515
|
const overlayRef = (0, import_react.useRef)(null);
|
|
@@ -631,7 +636,7 @@ function FieldOverlayItem({
|
|
|
631
636
|
onMouseDown: handleMouseDown,
|
|
632
637
|
children: [
|
|
633
638
|
mode === "designer" && !isRedact && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "field-overlay-label", style: { backgroundColor: color }, children: field.label }),
|
|
634
|
-
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 }),
|
|
635
640
|
mode === "designer" && isSelected && !field.locked && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
636
641
|
"div",
|
|
637
642
|
{
|
|
@@ -2160,39 +2165,56 @@ var import_react7 = require("react");
|
|
|
2160
2165
|
var import_pdf_lib = require("pdf-lib");
|
|
2161
2166
|
|
|
2162
2167
|
// src/utils/formulaResolver.ts
|
|
2168
|
+
function parseDate(value) {
|
|
2169
|
+
const s = value.trim();
|
|
2170
|
+
if (!s) return null;
|
|
2171
|
+
if (/^\d+(\.\d+)?$/.test(s)) {
|
|
2172
|
+
const serial = parseFloat(s);
|
|
2173
|
+
if (serial > 59) {
|
|
2174
|
+
const utc = new Date(Math.round((serial - 25569) * 864e5));
|
|
2175
|
+
if (!isNaN(utc.getTime())) {
|
|
2176
|
+
return new Date(utc.getUTCFullYear(), utc.getUTCMonth(), utc.getUTCDate());
|
|
2177
|
+
}
|
|
2178
|
+
}
|
|
2179
|
+
}
|
|
2180
|
+
const iso = s.match(/^(\d{4})-(\d{2})-(\d{2})$/);
|
|
2181
|
+
if (iso) return new Date(+iso[1], +iso[2] - 1, +iso[3]);
|
|
2182
|
+
const d = new Date(s);
|
|
2183
|
+
return isNaN(d.getTime()) ? null : d;
|
|
2184
|
+
}
|
|
2163
2185
|
var BUILTIN_TRANSFORMS = {
|
|
2164
2186
|
// Date transforms (expects a parseable date string)
|
|
2165
2187
|
month: (v) => {
|
|
2166
|
-
const d =
|
|
2167
|
-
return
|
|
2188
|
+
const d = parseDate(v);
|
|
2189
|
+
return d ? String(d.getMonth() + 1) : "";
|
|
2168
2190
|
},
|
|
2169
2191
|
month2: (v) => {
|
|
2170
|
-
const d =
|
|
2171
|
-
return
|
|
2192
|
+
const d = parseDate(v);
|
|
2193
|
+
return d ? String(d.getMonth() + 1).padStart(2, "0") : "";
|
|
2172
2194
|
},
|
|
2173
2195
|
monthname: (v) => {
|
|
2174
|
-
const d =
|
|
2175
|
-
return
|
|
2196
|
+
const d = parseDate(v);
|
|
2197
|
+
return d ? d.toLocaleString("en", { month: "long" }) : "";
|
|
2176
2198
|
},
|
|
2177
2199
|
monthshort: (v) => {
|
|
2178
|
-
const d =
|
|
2179
|
-
return
|
|
2200
|
+
const d = parseDate(v);
|
|
2201
|
+
return d ? d.toLocaleString("en", { month: "short" }) : "";
|
|
2180
2202
|
},
|
|
2181
2203
|
day: (v) => {
|
|
2182
|
-
const d =
|
|
2183
|
-
return
|
|
2204
|
+
const d = parseDate(v);
|
|
2205
|
+
return d ? String(d.getDate()) : "";
|
|
2184
2206
|
},
|
|
2185
2207
|
day2: (v) => {
|
|
2186
|
-
const d =
|
|
2187
|
-
return
|
|
2208
|
+
const d = parseDate(v);
|
|
2209
|
+
return d ? String(d.getDate()).padStart(2, "0") : "";
|
|
2188
2210
|
},
|
|
2189
2211
|
year: (v) => {
|
|
2190
|
-
const d =
|
|
2191
|
-
return
|
|
2212
|
+
const d = parseDate(v);
|
|
2213
|
+
return d ? String(d.getFullYear()) : "";
|
|
2192
2214
|
},
|
|
2193
2215
|
year2: (v) => {
|
|
2194
|
-
const d =
|
|
2195
|
-
return
|
|
2216
|
+
const d = parseDate(v);
|
|
2217
|
+
return d ? String(d.getFullYear()).slice(-2) : "";
|
|
2196
2218
|
},
|
|
2197
2219
|
// String transforms
|
|
2198
2220
|
upper: (v) => v.toUpperCase(),
|
|
@@ -2221,15 +2243,27 @@ var BUILTIN_TRANSFORMS = {
|
|
|
2221
2243
|
};
|
|
2222
2244
|
var FORMULA_RE = /\{\{(.+?)\}\}/g;
|
|
2223
2245
|
var PIPE_RE = /^(.+?)\s*\|\s*(.+)$/;
|
|
2224
|
-
function
|
|
2246
|
+
function todayIso() {
|
|
2247
|
+
const d = /* @__PURE__ */ new Date();
|
|
2248
|
+
return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, "0")}-${String(d.getDate()).padStart(2, "0")}`;
|
|
2249
|
+
}
|
|
2250
|
+
function resolveFormula(formula, fields, customTransforms, values) {
|
|
2225
2251
|
const transforms = { ...BUILTIN_TRANSFORMS, ...customTransforms };
|
|
2226
2252
|
return formula.replace(FORMULA_RE, (_match, expr) => {
|
|
2227
2253
|
const pipeMatch = expr.match(PIPE_RE);
|
|
2228
2254
|
const sourceLabel = (pipeMatch ? pipeMatch[1] : expr).trim();
|
|
2229
2255
|
const transformName = pipeMatch ? pipeMatch[2].trim() : null;
|
|
2230
|
-
const
|
|
2231
|
-
|
|
2232
|
-
|
|
2256
|
+
const lowerLabel = sourceLabel.toLowerCase();
|
|
2257
|
+
const sourceField = fields.find((f) => f.label.toLowerCase() === lowerLabel) || fields.find((f) => f.id === sourceLabel);
|
|
2258
|
+
let rawValue = sourceField ? sourceField.value || "" : void 0;
|
|
2259
|
+
if (rawValue === void 0 && values) {
|
|
2260
|
+
const key = Object.keys(values).find((k) => k.toLowerCase() === lowerLabel);
|
|
2261
|
+
if (key !== void 0) rawValue = values[key] || "";
|
|
2262
|
+
}
|
|
2263
|
+
if (rawValue === void 0 && (lowerLabel === "today" || lowerLabel === "now")) {
|
|
2264
|
+
rawValue = todayIso();
|
|
2265
|
+
}
|
|
2266
|
+
if (rawValue === void 0) return "";
|
|
2233
2267
|
if (!transformName) return rawValue;
|
|
2234
2268
|
const fn = transforms[transformName];
|
|
2235
2269
|
if (!fn) return rawValue;
|
|
@@ -2240,14 +2274,38 @@ function resolveFormula(formula, fields, customTransforms) {
|
|
|
2240
2274
|
}
|
|
2241
2275
|
});
|
|
2242
2276
|
}
|
|
2243
|
-
function resolveAllFormulas(fields, customTransforms) {
|
|
2277
|
+
function resolveAllFormulas(fields, customTransforms, values) {
|
|
2244
2278
|
return fields.map((f) => {
|
|
2245
2279
|
if (!f.formula) return f;
|
|
2246
|
-
const computed = resolveFormula(f.formula, fields, customTransforms);
|
|
2280
|
+
const computed = resolveFormula(f.formula, fields, customTransforms, values);
|
|
2247
2281
|
return computed !== f.value ? { ...f, value: computed } : f;
|
|
2248
2282
|
});
|
|
2249
2283
|
}
|
|
2250
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
|
+
var measureCtx = null;
|
|
2298
|
+
function measureTextWidth(text, size, opts) {
|
|
2299
|
+
if (typeof document === "undefined") return text.length * size * 0.5;
|
|
2300
|
+
if (!measureCtx) measureCtx = document.createElement("canvas").getContext("2d");
|
|
2301
|
+
if (!measureCtx) return text.length * size * 0.5;
|
|
2302
|
+
const family = getCssFontFamily(opts?.fontFamily) || "Helvetica, Arial, sans-serif";
|
|
2303
|
+
measureCtx.font = `${opts?.italic ? "italic " : ""}${opts?.bold ? "bold " : ""}${size}px ${family}`;
|
|
2304
|
+
const base = measureCtx.measureText(text).width;
|
|
2305
|
+
const spacing = opts?.letterSpacing ? opts.letterSpacing * Math.max(0, text.length - 1) : 0;
|
|
2306
|
+
return base + spacing;
|
|
2307
|
+
}
|
|
2308
|
+
|
|
2251
2309
|
// src/utils/pdfFiller.ts
|
|
2252
2310
|
var FONT_VARIANTS = {
|
|
2253
2311
|
Helvetica: [import_pdf_lib.StandardFonts.Helvetica, import_pdf_lib.StandardFonts.HelveticaBold, import_pdf_lib.StandardFonts.HelveticaOblique, import_pdf_lib.StandardFonts.HelveticaBoldOblique],
|
|
@@ -2339,14 +2397,14 @@ async function renderFieldsOnPages(pages, fields, getFont, getSignature) {
|
|
|
2339
2397
|
const font = await getFont(field.fontFamily || "Helvetica", field.bold, field.italic);
|
|
2340
2398
|
const spacing = field.letterSpacing || 0;
|
|
2341
2399
|
const textWidthAtSize = (text, size) => font.widthOfTextAtSize(text, size) + spacing * (text.length - 1);
|
|
2342
|
-
|
|
2343
|
-
|
|
2344
|
-
|
|
2345
|
-
|
|
2346
|
-
|
|
2347
|
-
|
|
2348
|
-
|
|
2349
|
-
}
|
|
2400
|
+
const fontSize = fitFontSize({
|
|
2401
|
+
value: field.value,
|
|
2402
|
+
fontSize: field.fontSize,
|
|
2403
|
+
autoShrink: field.autoShrink,
|
|
2404
|
+
fieldWidthPt: w,
|
|
2405
|
+
fieldHeightPt: h,
|
|
2406
|
+
measure: textWidthAtSize
|
|
2407
|
+
});
|
|
2350
2408
|
const textX = x + 2;
|
|
2351
2409
|
const baselineY = y + h * 0.3;
|
|
2352
2410
|
if (spacing > 0) {
|
|
@@ -2450,7 +2508,7 @@ async function createPdfBuilder(defaults = {}) {
|
|
|
2450
2508
|
doc,
|
|
2451
2509
|
async addRecord(opts) {
|
|
2452
2510
|
const pageSize = opts.pageSize ?? defaults.pageSize;
|
|
2453
|
-
let fields = opts.resolveFormulas ? resolveAllFormulas(opts.fields, opts.customTransforms) : opts.fields;
|
|
2511
|
+
let fields = opts.resolveFormulas ? resolveAllFormulas(opts.fields, opts.customTransforms, opts.formulaValues) : opts.fields;
|
|
2454
2512
|
if (opts.calibration) {
|
|
2455
2513
|
fields = applyCalibration(
|
|
2456
2514
|
fields,
|
|
@@ -2851,7 +2909,7 @@ ${row.join(",")}`, "csv");
|
|
|
2851
2909
|
setSubmitting(false);
|
|
2852
2910
|
}
|
|
2853
2911
|
}, [pdfSource, fields, callbackUrl, allRequiredFilled, onComplete, isLastSigner, signer, onSignerComplete, includeAuditTrail, exportFormat, onExport, getValues, transforms]);
|
|
2854
|
-
const renderFieldContent = (0, import_react7.useCallback)((field) => {
|
|
2912
|
+
const renderFieldContent = (0, import_react7.useCallback)((field, pageWidthPt, pageHeightPt) => {
|
|
2855
2913
|
if (isRedactField(field)) {
|
|
2856
2914
|
return null;
|
|
2857
2915
|
}
|
|
@@ -2890,8 +2948,23 @@ ${row.join(",")}`, "csv");
|
|
|
2890
2948
|
if (field.type === "signed-date") {
|
|
2891
2949
|
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "field-overlay-value", children: field.value || (/* @__PURE__ */ new Date()).toLocaleDateString() });
|
|
2892
2950
|
}
|
|
2951
|
+
const fieldWidthPt = pageWidthPt ? field.width / 100 * pageWidthPt : Infinity;
|
|
2952
|
+
const fieldHeightPt = pageHeightPt ? field.height / 100 * pageHeightPt : 0;
|
|
2953
|
+
const effectiveFontSize = pageWidthPt ? fitFontSize({
|
|
2954
|
+
value: field.value || "",
|
|
2955
|
+
fontSize: field.fontSize,
|
|
2956
|
+
autoShrink: field.autoShrink,
|
|
2957
|
+
fieldWidthPt,
|
|
2958
|
+
fieldHeightPt,
|
|
2959
|
+
measure: (t, s) => measureTextWidth(t, s, {
|
|
2960
|
+
fontFamily: field.fontFamily,
|
|
2961
|
+
bold: field.bold,
|
|
2962
|
+
italic: field.italic,
|
|
2963
|
+
letterSpacing: field.letterSpacing
|
|
2964
|
+
})
|
|
2965
|
+
}) : field.fontSize;
|
|
2893
2966
|
const fontStyle = {
|
|
2894
|
-
fontSize: `${
|
|
2967
|
+
fontSize: `${effectiveFontSize}pt`,
|
|
2895
2968
|
letterSpacing: field.letterSpacing ? `${field.letterSpacing}pt` : void 0,
|
|
2896
2969
|
lineHeight: field.lineHeight ? `${field.lineHeight}` : void 0,
|
|
2897
2970
|
...getCssTextStyle(field)
|
|
@@ -3173,6 +3246,7 @@ function SignerRoleSelector({
|
|
|
3173
3246
|
isRedactField,
|
|
3174
3247
|
isSignatureField,
|
|
3175
3248
|
isTextLikeField,
|
|
3249
|
+
parseDate,
|
|
3176
3250
|
postPdfToCallback,
|
|
3177
3251
|
preserveFieldValues,
|
|
3178
3252
|
renderPdfPages,
|