@servicetitan/dte-pdf-editor 1.93.3 → 1.95.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 +37 -2
- package/dist/components/pdf-fields-overlay/pdf-overlay-field-fillable.d.ts.map +1 -1
- package/dist/components/pdf-fields-overlay/pdf-overlay-field-fillable.js +4 -6
- package/dist/components/pdf-fields-overlay/pdf-overlay-field-fillable.js.map +1 -1
- package/dist/components/pdf-view/pdf-view-fillable.d.ts.map +1 -1
- package/dist/components/pdf-view/pdf-view-fillable.js +27 -4
- package/dist/components/pdf-view/pdf-view-fillable.js.map +1 -1
- package/dist/components/shared/char-limit-indicator.d.ts +8 -0
- package/dist/components/shared/char-limit-indicator.d.ts.map +1 -0
- package/dist/components/shared/char-limit-indicator.js +9 -0
- package/dist/components/shared/char-limit-indicator.js.map +1 -0
- package/dist/components/shared/index.d.ts +1 -0
- package/dist/components/shared/index.d.ts.map +1 -1
- package/dist/components/shared/index.js +1 -0
- package/dist/components/shared/index.js.map +1 -1
- package/dist/styles/pdf-field-overlay.css +9 -2
- package/dist/styles/pdf-field.css +22 -1
- package/dist/utils/field/field-text-box.utils.d.ts +31 -0
- package/dist/utils/field/field-text-box.utils.d.ts.map +1 -0
- package/dist/utils/field/field-text-box.utils.js +102 -0
- package/dist/utils/field/field-text-box.utils.js.map +1 -0
- package/dist/utils/field/fit-field-text.utils.d.ts +13 -0
- package/dist/utils/field/fit-field-text.utils.d.ts.map +1 -0
- package/dist/utils/field/fit-field-text.utils.js +44 -0
- package/dist/utils/field/fit-field-text.utils.js.map +1 -0
- package/dist/utils/field/get-field-max-length.utils.d.ts +38 -0
- package/dist/utils/field/get-field-max-length.utils.d.ts.map +1 -0
- package/dist/utils/field/get-field-max-length.utils.js +166 -0
- package/dist/utils/field/get-field-max-length.utils.js.map +1 -0
- package/dist/utils/field/index.d.ts +2 -0
- package/dist/utils/field/index.d.ts.map +1 -1
- package/dist/utils/field/index.js +2 -0
- package/dist/utils/field/index.js.map +1 -1
- package/dist/utils/field/text-wrap.utils.d.ts +26 -0
- package/dist/utils/field/text-wrap.utils.d.ts.map +1 -0
- package/dist/utils/field/text-wrap.utils.js +53 -0
- package/dist/utils/field/text-wrap.utils.js.map +1 -0
- package/package.json +1 -1
- package/src/components/pdf-fields-overlay/pdf-overlay-field-fillable.tsx +41 -28
- package/src/components/pdf-view/pdf-view-fillable.tsx +82 -36
- package/src/components/shared/char-limit-indicator.tsx +23 -0
- package/src/components/shared/index.ts +1 -0
- package/src/styles/pdf-field-overlay.css +9 -2
- package/src/styles/pdf-field.css +22 -1
- package/src/utils/field/__tests__/fit-field-text.utils.test.ts +224 -0
- package/src/utils/field/__tests__/get-field-max-length.utils.test.ts +751 -0
- package/src/utils/field/__tests__/text-wrap.utils.test.ts +181 -0
- package/src/utils/field/field-text-box.utils.ts +143 -0
- package/src/utils/field/fit-field-text.utils.ts +61 -0
- package/src/utils/field/get-field-max-length.utils.ts +211 -0
- package/src/utils/field/index.ts +2 -0
- package/src/utils/field/text-wrap.utils.ts +78 -0
package/README.md
CHANGED
|
@@ -10,7 +10,8 @@ formulas.
|
|
|
10
10
|
- 🎯 **Drag & Drop Field Placement**: Intuitively place fields on PDF pages by dragging from a sidebar
|
|
11
11
|
- 📊 **Data Model Integration**: Connect fields to structured data models using JSON Schema
|
|
12
12
|
- ✍️ **E-Signature Support**: Add signature, initials, date signed, and full name fields
|
|
13
|
-
- 📝 **Fillable Fields**: Support for text, number, date, checkbox, and radio button inputs
|
|
13
|
+
- 📝 **Fillable Fields**: Support for text, number, date, checkbox, and radio button inputs; text and number fields
|
|
14
|
+
show a live character counter and only accept as much as fits the field
|
|
14
15
|
- 🧮 **Calculated Fields**: Formula-based fields with validation, autosuggest, and advanced formatting (number, currency,
|
|
15
16
|
percent, date, rounding, separators)
|
|
16
17
|
- 🗂️ **Forms Fields**: Bind PDF placements to job form submission values (`__submission_fields.*` paths), with async
|
|
@@ -27,6 +28,9 @@ formulas.
|
|
|
27
28
|
|
|
28
29
|
### Recent changes
|
|
29
30
|
|
|
31
|
+
- **feature/DTE-4671** (fillable text & number character limit) — text, multiline and number fields count characters
|
|
32
|
+
and accept only what fits the rendered field; text controls now use the field's font family and weight. See
|
|
33
|
+
[RELEASE_NOTES.md](./RELEASE_NOTES.md) and [Text and number field limits](#text-and-number-field-limits).
|
|
30
34
|
- **fix/inconsistncy** — PDF overlay layout, typography, and text clipping aligned with the backend PDF renderer;
|
|
31
35
|
searchable lookup-backed display-condition values. See [RELEASE_NOTES.md](./RELEASE_NOTES.md).
|
|
32
36
|
- **fix/DTE-4360** (radio groups) — see [RELEASE_NOTES.md](./RELEASE_NOTES.md).
|
|
@@ -182,6 +186,36 @@ current values — useful for a non-interactive preview of a partially or fully
|
|
|
182
186
|
This prop applies on top of `viewMode` / `fillingBy` scoping (e.g. in `'preview'` mode, fillable fields are normally
|
|
183
187
|
interactive unless `makeFillableFieldsReadonly` is set).
|
|
184
188
|
|
|
189
|
+
#### Text and number field limits
|
|
190
|
+
|
|
191
|
+
Single-line **text**, **multiline text** and **number** fillable fields limit what can be entered to what fits the
|
|
192
|
+
field, so the filled value never runs past the box the backend PDF renderer clips it to (it hard-clips, with no
|
|
193
|
+
ellipsis). A `typed/capacity` counter is shown under each field and turns red when no more text fits.
|
|
194
|
+
|
|
195
|
+
- **Single-line text and number** — the text's width must fit the field width.
|
|
196
|
+
- **Multiline text** (`PdfField.multiline`) — the text, word-wrapped at the field width, must fit the lines that fit the
|
|
197
|
+
field height (`floor(height / line height)`, with a line height of 1× the font size). Explicit newlines, blank lines,
|
|
198
|
+
long unbroken words and non-Latin text count.
|
|
199
|
+
- **Measured, not counted** — width is measured at the field's own `styles.fontFamily`, `fontWeight` and `fontSize`, so
|
|
200
|
+
narrow text (`iiii`) fills a field further than wide text (`WWWW`), and bold or a larger font fits less. The
|
|
201
|
+
counter's capacity is the characters typed plus how many more characters of typical text still fit, so it moves as
|
|
202
|
+
the user types.
|
|
203
|
+
- **Pasting and editing mid-text** — text that does not fully fit is cut back to the part that does; text that was
|
|
204
|
+
already there is never dropped, and an edit that would only add overflow is refused. Deleting is always allowed and a
|
|
205
|
+
single character always fits.
|
|
206
|
+
- **Numbers** reserve the browser's spin-button gutter (15px), and are a guaranteed fit: the capacity is bounded by the
|
|
207
|
+
widest of the digits, `.` and `-`.
|
|
208
|
+
|
|
209
|
+
Notes for hosts:
|
|
210
|
+
|
|
211
|
+
- Nothing about the limit is stored or sent — it is purely an editing constraint. Values longer than a field can show
|
|
212
|
+
(for example set through `data`) are displayed unchanged and can only be shortened.
|
|
213
|
+
- The limit assumes the fillable controls keep the library's box model: **no padding, no border, `line-height: 1`**
|
|
214
|
+
(`.dte-pdf-field-fillable`). Override those in host CSS and capacities will be off.
|
|
215
|
+
- Text, number and textarea controls inherit `font-family` and `font-weight` from the field, so a field's
|
|
216
|
+
`styles.fontFamily` / `fontWeight` are applied in `PdfView` as well as measured.
|
|
217
|
+
- Measurement uses canvas `measureText`; without canvas (SSR, jsdom) a ratio-based estimate is used.
|
|
218
|
+
|
|
185
219
|
#### Example
|
|
186
220
|
|
|
187
221
|
```tsx
|
|
@@ -278,7 +312,7 @@ Union of fillable, e-sign, generic, and form field sub-types:
|
|
|
278
312
|
|
|
279
313
|
Types of fillable fields:
|
|
280
314
|
|
|
281
|
-
- `text`: Text input
|
|
315
|
+
- `text`: Text input (single-line, or a textarea when `PdfField.multiline` is set)
|
|
282
316
|
- `number`: Number input
|
|
283
317
|
- `date`: Date picker
|
|
284
318
|
- `checkbox`: Checkbox
|
|
@@ -539,6 +573,7 @@ The package includes default styles. To customize, you can override CSS classes:
|
|
|
539
573
|
- `.dte-pdf-wrapper`: PDF document wrapper
|
|
540
574
|
- `.dte-pdf-field-overlay`: Field overlay container
|
|
541
575
|
- `.dte-pdf-field-text--single-line` / `--multiline` / `--wrapped`: Text clip modes (hard clip, no ellipsis)
|
|
576
|
+
- `.dte-pdf-field-char-count`: Character counter under text and number fields (`--at-limit` when full)
|
|
542
577
|
- `.dte-pdf-editor-sidebar-container`: Sidebar container
|
|
543
578
|
|
|
544
579
|
Field overlays use **border-box** sizing with **no padding** so `width`/`height` match the backend PDF clip rectangle.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pdf-overlay-field-fillable.d.ts","sourceRoot":"","sources":["../../../src/components/pdf-fields-overlay/pdf-overlay-field-fillable.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAY,MAAM,OAAO,CAAC;AAErC,OAAO,EAAE,KAAK,QAAQ,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"pdf-overlay-field-fillable.d.ts","sourceRoot":"","sources":["../../../src/components/pdf-fields-overlay/pdf-overlay-field-fillable.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAY,MAAM,OAAO,CAAC;AAErC,OAAO,EAAE,KAAK,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAatD,UAAU,4BAA4B;IAClC,KAAK,EAAE,QAAQ,CAAC;IAChB,iBAAiB,CAAC,KAAK,EAAE,QAAQ,GAAG,IAAI,CAAC;CAC5C;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,uBAAuB,EAAE,EAAE,CAAC,4BAA4B,CAgLpE,CAAC"}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { Fragment } from 'react';
|
|
3
3
|
import { v4 as uuidv4 } from 'uuid';
|
|
4
|
-
import { getDropdownFieldItems, getFieldPlaceholderText, getFieldTextClipClassName, getFillablePaintedLabel, getTodayDateInputValue, isRadioDefaultSelected, } from '../../utils';
|
|
4
|
+
import { getDropdownFieldItems, getFieldMaxLength, getFieldPlaceholderText, getFieldTextClipClassName, getFillablePaintedLabel, getTodayDateInputValue, isRadioDefaultSelected, } from '../../utils';
|
|
5
|
+
import { CharLimitIndicator } from '../shared';
|
|
5
6
|
import { AddHandle } from './add-handle';
|
|
6
7
|
/**
|
|
7
8
|
* Every case below previews `field.default` through an uncontrolled, read-only DOM element
|
|
@@ -58,7 +59,7 @@ export const PdfOverlayFieldFillable = ({ field, handleAddNewField, }) => {
|
|
|
58
59
|
}
|
|
59
60
|
case 'number': {
|
|
60
61
|
const defaultNumberValue = ((_e = field.default) === null || _e === void 0 ? void 0 : _e.type) === 'number' ? field.default.value : '';
|
|
61
|
-
return (_jsx("input", { type: "number", readOnly: true, defaultValue: defaultNumberValue, className: `dte-pdf-field-fillable ${clipClassName}`, placeholder: placeholderText }, defaultNumberValue));
|
|
62
|
+
return (_jsxs(Fragment, { children: [_jsx("input", { type: "number", readOnly: true, defaultValue: defaultNumberValue, className: `dte-pdf-field-fillable ${clipClassName}`, placeholder: placeholderText }, defaultNumberValue), _jsx(CharLimitIndicator, { maxLength: getFieldMaxLength(field, String(defaultNumberValue)), value: String(defaultNumberValue) })] }));
|
|
62
63
|
}
|
|
63
64
|
case 'dropdown': {
|
|
64
65
|
const defaultDropdownValue = ((_f = field.default) === null || _f === void 0 ? void 0 : _f.type) === 'dropdown' ? field.default.value : '';
|
|
@@ -66,10 +67,7 @@ export const PdfOverlayFieldFillable = ({ field, handleAddNewField, }) => {
|
|
|
66
67
|
}
|
|
67
68
|
default: {
|
|
68
69
|
const defaultTextValue = ((_g = field.default) === null || _g === void 0 ? void 0 : _g.type) === 'text' ? field.default.value : '';
|
|
69
|
-
|
|
70
|
-
return (_jsx("textarea", { readOnly: true, defaultValue: defaultTextValue, style: { font: 'inherit', lineHeight: 'inherit', outline: 'none' }, placeholder: placeholderText, className: `dte-pdf-field-fillable ${clipClassName}` }, defaultTextValue));
|
|
71
|
-
}
|
|
72
|
-
return (_jsx("input", { type: "text", readOnly: true, defaultValue: defaultTextValue, placeholder: placeholderText, className: `dte-pdf-field-fillable ${clipClassName}` }, defaultTextValue));
|
|
70
|
+
return (_jsxs(Fragment, { children: [field.multiline ? (_jsx("textarea", { readOnly: true, defaultValue: defaultTextValue, style: { font: 'inherit', lineHeight: 'inherit', outline: 'none' }, placeholder: placeholderText, className: `dte-pdf-field-fillable ${clipClassName}` }, defaultTextValue)) : (_jsx("input", { type: "text", readOnly: true, defaultValue: defaultTextValue, placeholder: placeholderText, className: `dte-pdf-field-fillable ${clipClassName}` }, defaultTextValue)), _jsx(CharLimitIndicator, { maxLength: getFieldMaxLength(field, defaultTextValue), value: defaultTextValue })] }));
|
|
73
71
|
}
|
|
74
72
|
}
|
|
75
73
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pdf-overlay-field-fillable.js","sourceRoot":"","sources":["../../../src/components/pdf-fields-overlay/pdf-overlay-field-fillable.tsx"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"pdf-overlay-field-fillable.js","sourceRoot":"","sources":["../../../src/components/pdf-fields-overlay/pdf-overlay-field-fillable.tsx"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pdf-view-fillable.d.ts","sourceRoot":"","sources":["../../../src/components/pdf-view/pdf-view-fillable.tsx"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"pdf-view-fillable.d.ts","sourceRoot":"","sources":["../../../src/components/pdf-view/pdf-view-fillable.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAe,EAAE,EAAY,MAAM,OAAO,CAAC;AAClD,OAAO,EACH,KAAK,iBAAiB,EACtB,KAAK,eAAe,EACpB,KAAK,QAAQ,EACb,KAAK,WAAW,EACnB,MAAM,uBAAuB,CAAC;AAa/B,UAAU,oBAAoB;IAC1B,KAAK,EAAE,QAAQ,CAAC;IAChB,IAAI,CAAC,EAAE,eAAe,CAAC;IACvB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,QAAQ,CAAC,EAAE,WAAW,CAAC;IACvB,YAAY,CAAC,CAAC,WAAW,EAAE,iBAAiB,EAAE,KAAK,EAAE,QAAQ,GAAG,IAAI,CAAC;CACxE;AAED,UAAU,sBAAsB;IAC5B,KAAK,EAAE,QAAQ,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CACjC;AAyCD,eAAO,MAAM,iBAAiB,EAAE,EAAE,CAAC,sBAAsB,CA0BxD,CAAC;AAEF,eAAO,MAAM,qBAAqB,EAAE,EAAE,CAAC,sBAAsB,CAyB5D,CAAC;AAEF,eAAO,MAAM,eAAe,EAAE,EAAE,CAAC,oBAAoB,CA+JpD,CAAC"}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import {
|
|
2
|
+
import { Fragment } from 'react';
|
|
3
|
+
import { dateToUtcZero, fitFieldTextChange, getDropdownFieldItems, getFieldMaxLength, getFieldPlaceholderText, getFieldTextClipClassName, getFillablePaintedLabel, toDateInputValue, } from '../../utils';
|
|
4
|
+
import { CharLimitIndicator } from '../shared';
|
|
3
5
|
const fillableTextStyles = {
|
|
4
6
|
background: 'transparent',
|
|
5
7
|
width: '100%',
|
|
@@ -11,11 +13,30 @@ const fillableTextStyles = {
|
|
|
11
13
|
padding: 0,
|
|
12
14
|
margin: 0,
|
|
13
15
|
};
|
|
16
|
+
/**
|
|
17
|
+
* Passes on a text change, cut back to what fits the field. A change that adds only overflow is
|
|
18
|
+
* dropped; either way the caret stays where the user was typing, as with a native `maxLength`.
|
|
19
|
+
*/
|
|
20
|
+
const applyFittedChange = (field, value, event, onChange) => {
|
|
21
|
+
const { selectionStart, value: nextValue } = event.target;
|
|
22
|
+
const fittedValue = fitFieldTextChange(field, value, nextValue);
|
|
23
|
+
if (fittedValue !== value) {
|
|
24
|
+
onChange(fittedValue);
|
|
25
|
+
}
|
|
26
|
+
if (fittedValue !== nextValue && selectionStart != null) {
|
|
27
|
+
const caret = fittedValue.length - (nextValue.length - selectionStart);
|
|
28
|
+
const input = event.target;
|
|
29
|
+
// after React has put the fitted value back into the control, which moves the caret
|
|
30
|
+
queueMicrotask(() => input.setSelectionRange(caret, caret));
|
|
31
|
+
}
|
|
32
|
+
};
|
|
14
33
|
export const FillableTextInput = ({ disabled, field, onChange, readOnly, value, }) => {
|
|
15
|
-
|
|
34
|
+
const maxLength = getFieldMaxLength(field, value);
|
|
35
|
+
return (_jsxs(Fragment, { children: [_jsx("input", { readOnly: readOnly, type: "text", className: `dte-pdf-field-fillable ${getFieldTextClipClassName(field)}`, style: fillableTextStyles, disabled: disabled, id: field.path, name: field.path, value: value, onChange: e => applyFittedChange(field, value, e, onChange), placeholder: getFieldPlaceholderText(field) }), _jsx(CharLimitIndicator, { maxLength: maxLength, value: value })] }));
|
|
16
36
|
};
|
|
17
37
|
export const FillableTextareaInput = ({ disabled, field, onChange, readOnly, value, }) => {
|
|
18
|
-
|
|
38
|
+
const maxLength = getFieldMaxLength(field, value);
|
|
39
|
+
return (_jsxs(Fragment, { children: [_jsx("textarea", { readOnly: readOnly, className: `dte-pdf-field-fillable ${getFieldTextClipClassName(field)}`, style: { ...fillableTextStyles, resize: 'none' }, disabled: disabled, id: field.path, name: field.path, value: value, onChange: e => applyFittedChange(field, value, e, onChange), placeholder: getFieldPlaceholderText(field) }), _jsx(CharLimitIndicator, { maxLength: maxLength, value: value })] }));
|
|
19
40
|
};
|
|
20
41
|
export const PdfViewFillable = ({ data, field, fillingBy, onDataChange, readOnly, viewMode, }) => {
|
|
21
42
|
const resolvedValue = data === null || data === void 0 ? void 0 : data[field.path];
|
|
@@ -63,7 +84,9 @@ export const PdfViewFillable = ({ data, field, fillingBy, onDataChange, readOnly
|
|
|
63
84
|
}, placeholder: getFieldPlaceholderText(field, 'mm/dd/yyyy') }));
|
|
64
85
|
}
|
|
65
86
|
if (field.subType === 'number') {
|
|
66
|
-
|
|
87
|
+
const numberValue = resolvedValue == null ? '' : String(resolvedValue);
|
|
88
|
+
const maxLength = getFieldMaxLength(field, numberValue);
|
|
89
|
+
return (_jsxs(Fragment, { children: [_jsx("input", { readOnly: readOnly, type: "number", className: `dte-pdf-field-fillable ${getFieldTextClipClassName(field)}`, style: fillableTextStyles, disabled: !isFillable, id: field.path, name: field.path, value: numberValue, onChange: e => applyFittedChange(field, numberValue, e, handleDataChange), placeholder: getFieldPlaceholderText(field) }), _jsx(CharLimitIndicator, { maxLength: maxLength, value: numberValue })] }));
|
|
67
90
|
}
|
|
68
91
|
if (field.subType === 'dropdown') {
|
|
69
92
|
return (_jsxs("select", { style: fillableTextStyles, disabled: isInputDisabled, id: field.path, name: field.path, value: resolvedValue !== null && resolvedValue !== void 0 ? resolvedValue : '', onChange: e => handleDataChange(e.target.value), children: [_jsx("option", { value: "", disabled: true, hidden: true, children: getFieldPlaceholderText(field) || 'Select...' }), getDropdownFieldItems(field).map(item => (_jsx("option", { value: item.value, children: item.label }, item.value)))] }));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pdf-view-fillable.js","sourceRoot":"","sources":["../../../src/components/pdf-view/pdf-view-fillable.tsx"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"pdf-view-fillable.js","sourceRoot":"","sources":["../../../src/components/pdf-view/pdf-view-fillable.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAmB,QAAQ,EAAE,MAAM,OAAO,CAAC;AAOlD,OAAO,EACH,aAAa,EACb,kBAAkB,EAClB,qBAAqB,EACrB,iBAAiB,EACjB,uBAAuB,EACvB,yBAAyB,EACzB,uBAAuB,EACvB,gBAAgB,GACnB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AAmB/C,MAAM,kBAAkB,GAAG;IACvB,UAAU,EAAE,aAAa;IACzB,KAAK,EAAE,MAAM;IACb,MAAM,EAAE,MAAM;IACd,MAAM,EAAE,MAAM;IACd,QAAQ,EAAE,SAAS;IACnB,KAAK,EAAE,SAAS;IAChB,SAAS,EAAE,YAAqB;IAChC,OAAO,EAAE,CAAC;IACV,MAAM,EAAE,CAAC;CACH,CAAC;AAIX;;;GAGG;AACH,MAAM,iBAAiB,GAAG,CACtB,KAAe,EACf,KAAa,EACb,KAA8B,EAC9B,QAAiC,EACnC,EAAE;IACA,MAAM,EAAE,cAAc,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,KAAK,CAAC,MAAM,CAAC;IAC1D,MAAM,WAAW,GAAG,kBAAkB,CAAC,KAAK,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC;IAEhE,IAAI,WAAW,KAAK,KAAK,EAAE,CAAC;QACxB,QAAQ,CAAC,WAAW,CAAC,CAAC;IAC1B,CAAC;IAED,IAAI,WAAW,KAAK,SAAS,IAAI,cAAc,IAAI,IAAI,EAAE,CAAC;QACtD,MAAM,KAAK,GAAG,WAAW,CAAC,MAAM,GAAG,CAAC,SAAS,CAAC,MAAM,GAAG,cAAc,CAAC,CAAC;QACvE,MAAM,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC;QAC3B,oFAAoF;QACpF,cAAc,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,iBAAiB,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC;IAChE,CAAC;AACL,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,iBAAiB,GAA+B,CAAC,EAC1D,QAAQ,EACR,KAAK,EACL,QAAQ,EACR,QAAQ,EACR,KAAK,GACR,EAAE,EAAE;IACD,MAAM,SAAS,GAAG,iBAAiB,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;IAElD,OAAO,CACH,MAAC,QAAQ,eACL,gBACI,QAAQ,EAAE,QAAQ,EAClB,IAAI,EAAC,MAAM,EACX,SAAS,EAAE,0BAA0B,yBAAyB,CAAC,KAAK,CAAC,EAAE,EACvE,KAAK,EAAE,kBAAkB,EACzB,QAAQ,EAAE,QAAQ,EAClB,EAAE,EAAE,KAAK,CAAC,IAAI,EACd,IAAI,EAAE,KAAK,CAAC,IAAI,EAChB,KAAK,EAAE,KAAK,EACZ,QAAQ,EAAE,CAAC,CAAC,EAAE,CAAC,iBAAiB,CAAC,KAAK,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,CAAC,EAC3D,WAAW,EAAE,uBAAuB,CAAC,KAAK,CAAC,GAC7C,EACF,KAAC,kBAAkB,IAAC,SAAS,EAAE,SAAS,EAAE,KAAK,EAAE,KAAK,GAAI,IACnD,CACd,CAAC;AACN,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,qBAAqB,GAA+B,CAAC,EAC9D,QAAQ,EACR,KAAK,EACL,QAAQ,EACR,QAAQ,EACR,KAAK,GACR,EAAE,EAAE;IACD,MAAM,SAAS,GAAG,iBAAiB,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;IAElD,OAAO,CACH,MAAC,QAAQ,eACL,mBACI,QAAQ,EAAE,QAAQ,EAClB,SAAS,EAAE,0BAA0B,yBAAyB,CAAC,KAAK,CAAC,EAAE,EACvE,KAAK,EAAE,EAAE,GAAG,kBAAkB,EAAE,MAAM,EAAE,MAAM,EAAE,EAChD,QAAQ,EAAE,QAAQ,EAClB,EAAE,EAAE,KAAK,CAAC,IAAI,EACd,IAAI,EAAE,KAAK,CAAC,IAAI,EAChB,KAAK,EAAE,KAAK,EACZ,QAAQ,EAAE,CAAC,CAAC,EAAE,CAAC,iBAAiB,CAAC,KAAK,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,CAAC,EAC3D,WAAW,EAAE,uBAAuB,CAAC,KAAK,CAAC,GAC7C,EACF,KAAC,kBAAkB,IAAC,SAAS,EAAE,SAAS,EAAE,KAAK,EAAE,KAAK,GAAI,IACnD,CACd,CAAC;AACN,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,eAAe,GAA6B,CAAC,EACtD,IAAI,EACJ,KAAK,EACL,SAAS,EACT,YAAY,EACZ,QAAQ,EACR,QAAQ,GACX,EAAE,EAAE;IACD,MAAM,aAAa,GAAG,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAG,KAAK,CAAC,IAAK,CAAC,CAAC;IAC1C,MAAM,wBAAwB,GAAG,SAAS,aAAT,SAAS,uBAAT,SAAS,CAAE,QAAQ,CAAC,KAAK,CAAC,SAAU,CAAC,CAAC;IACvE,MAAM,UAAU,GAAG,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,wBAAwB,CAAC;IAE5E,MAAM,eAAe,GAAG,CAAC,UAAU,IAAI,CAAC,CAAC,QAAQ,CAAC;IAElD,MAAM,gBAAgB,GAAG,CAAC,UAAqC,EAAE,EAAE;QAC/D,IAAI,QAAQ,EAAE,CAAC;YACX,OAAO;QACX,CAAC;QACD,MAAM,WAAW,GAAG,EAAE,CAAC,KAAK,CAAC,IAAK,CAAC,EAAE,UAAU,EAAE,CAAC;QAClD,YAAY,aAAZ,YAAY,uBAAZ,YAAY,CAAG,WAAW,EAAE,KAAK,CAAC,CAAC;IACvC,CAAC,CAAC;IAEF,IAAI,KAAK,CAAC,OAAO,KAAK,UAAU,EAAE,CAAC;QAC/B,OAAO,CACH,eACI,SAAS,EAAC,uBAAuB,EACjC,KAAK,EAAE;gBACH,OAAO,EAAE,MAAM;gBACf,UAAU,EAAE,QAAQ;gBACpB,UAAU,EAAE,SAAS;aACxB,aAED,gBACI,KAAK,EAAE,KAAK,CAAC,KAAK,EAClB,KAAK,EAAE;wBACH,KAAK,EAAE,KAAK,CAAC,KAAK;wBAClB,MAAM,EAAE,KAAK,CAAC,MAAM;wBACpB,MAAM,EAAE,CAAC;wBACT,MAAM,EAAE,MAAM;qBACjB,EACD,IAAI,EAAC,UAAU,EACf,OAAO,EAAE,aAAa,aAAb,aAAa,cAAb,aAAa,GAAI,KAAK,EAC/B,QAAQ,EAAE,eAAe,EACzB,IAAI,EAAE,KAAK,CAAC,IAAI,EAChB,QAAQ,EAAE,CAAC,CAAC,EAAE,CAAC,gBAAgB,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,GACnD,EACD,uBAAuB,CAAC,KAAK,CAAC,IAC7B,CACT,CAAC;IACN,CAAC;IAED,IAAI,KAAK,CAAC,OAAO,KAAK,OAAO,EAAE,CAAC;QAC5B,OAAO,CACH,eACI,SAAS,EAAC,uBAAuB,EACjC,KAAK,EAAE;gBACH,OAAO,EAAE,MAAM;gBACf,UAAU,EAAE,QAAQ;gBACpB,UAAU,EAAE,SAAS;gBACrB,KAAK,EAAE,MAAM;gBACb,MAAM,EAAE,MAAM;aACjB,aAED,gBACI,KAAK,EAAE,KAAK,CAAC,KAAK,EAClB,KAAK,EAAE;wBACH,KAAK,EAAE,KAAK,CAAC,KAAK;wBAClB,MAAM,EAAE,KAAK,CAAC,MAAM;wBACpB,MAAM,EAAE,CAAC;wBACT,MAAM,EAAE,MAAM;qBACjB,EACD,IAAI,EAAC,OAAO,EACZ,KAAK,EAAE,KAAK,CAAC,EAAE,EACf,OAAO,EAAE,aAAa,KAAK,KAAK,CAAC,EAAE,EACnC,QAAQ,EAAE,eAAe,EACzB,IAAI,EAAE,KAAK,CAAC,IAAI,EAChB,QAAQ,EAAE,GAAG,EAAE,CAAC,gBAAgB,CAAC,KAAK,CAAC,EAAE,CAAC,GAC5C,EACD,uBAAuB,CAAC,KAAK,CAAC,IAC7B,CACT,CAAC;IACN,CAAC;IAED,IAAI,KAAK,CAAC,OAAO,KAAK,MAAM,EAAE,CAAC;QAC3B,MAAM,cAAc,GAAG,gBAAgB,CAAC,aAAa,CAAC,CAAC;QACvD,OAAO,CACH,gBACI,QAAQ,EAAE,QAAQ,EAClB,IAAI,EAAC,MAAM,EACX,SAAS,EAAE,0BAA0B,yBAAyB,CAAC,KAAK,CAAC,EAAE,EACvE,KAAK,EAAE,kBAAkB,EACzB,QAAQ,EAAE,CAAC,UAAU,EACrB,EAAE,EAAE,KAAK,CAAC,IAAI,EACd,IAAI,EAAE,KAAK,CAAC,IAAI,EAChB,KAAK,EAAE,cAAc,EACrB,QAAQ,EAAE,CAAC,CAAC,EAAE;gBACV,MAAM,OAAO,GAAG,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;gBAC/B,gBAAgB,CAAC,OAAO,CAAC,CAAC,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YAC5D,CAAC,EACD,WAAW,EAAE,uBAAuB,CAAC,KAAK,EAAE,YAAY,CAAC,GAC3D,CACL,CAAC;IACN,CAAC;IAED,IAAI,KAAK,CAAC,OAAO,KAAK,QAAQ,EAAE,CAAC;QAC7B,MAAM,WAAW,GAAG,aAAa,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC;QACvE,MAAM,SAAS,GAAG,iBAAiB,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC;QAExD,OAAO,CACH,MAAC,QAAQ,eACL,gBACI,QAAQ,EAAE,QAAQ,EAClB,IAAI,EAAC,QAAQ,EACb,SAAS,EAAE,0BAA0B,yBAAyB,CAAC,KAAK,CAAC,EAAE,EACvE,KAAK,EAAE,kBAAkB,EACzB,QAAQ,EAAE,CAAC,UAAU,EACrB,EAAE,EAAE,KAAK,CAAC,IAAI,EACd,IAAI,EAAE,KAAK,CAAC,IAAI,EAChB,KAAK,EAAE,WAAW,EAClB,QAAQ,EAAE,CAAC,CAAC,EAAE,CAAC,iBAAiB,CAAC,KAAK,EAAE,WAAW,EAAE,CAAC,EAAE,gBAAgB,CAAC,EACzE,WAAW,EAAE,uBAAuB,CAAC,KAAK,CAAC,GAC7C,EACF,KAAC,kBAAkB,IAAC,SAAS,EAAE,SAAS,EAAE,KAAK,EAAE,WAAW,GAAI,IACzD,CACd,CAAC;IACN,CAAC;IAED,IAAI,KAAK,CAAC,OAAO,KAAK,UAAU,EAAE,CAAC;QAC/B,OAAO,CACH,kBACI,KAAK,EAAE,kBAAkB,EACzB,QAAQ,EAAE,eAAe,EACzB,EAAE,EAAE,KAAK,CAAC,IAAI,EACd,IAAI,EAAE,KAAK,CAAC,IAAI,EAChB,KAAK,EAAE,aAAa,aAAb,aAAa,cAAb,aAAa,GAAI,EAAE,EAC1B,QAAQ,EAAE,CAAC,CAAC,EAAE,CAAC,gBAAgB,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,aAE/C,iBAAQ,KAAK,EAAC,EAAE,EAAC,QAAQ,QAAC,MAAM,kBAC3B,uBAAuB,CAAC,KAAK,CAAC,IAAI,WAAW,GACzC,EACR,qBAAqB,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CACtC,iBAAyB,KAAK,EAAE,IAAI,CAAC,KAAK,YACrC,IAAI,CAAC,KAAK,IADF,IAAI,CAAC,KAAK,CAEd,CACZ,CAAC,IACG,CACZ,CAAC;IACN,CAAC;IAED,MAAM,aAAa,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,iBAAiB,CAAC;IAClF,OAAO,CACH,KAAC,aAAa,IACV,QAAQ,EAAE,QAAQ,EAClB,KAAK,EAAE,KAAK,EACZ,KAAK,EAAE,aAAa,aAAb,aAAa,cAAb,aAAa,GAAI,EAAE,EAC1B,QAAQ,EAAE,CAAC,UAAU,EACrB,QAAQ,EAAE,gBAAgB,GAC5B,CACL,CAAC;AACN,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"char-limit-indicator.d.ts","sourceRoot":"","sources":["../../../src/components/shared/char-limit-indicator.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAE3B,UAAU,uBAAuB;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;CACjB;AAED,eAAO,MAAM,kBAAkB,EAAE,EAAE,CAAC,uBAAuB,CAe1D,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
export const CharLimitIndicator = ({ maxLength, value }) => {
|
|
3
|
+
if (maxLength == null) {
|
|
4
|
+
return null;
|
|
5
|
+
}
|
|
6
|
+
const filledCount = value.length;
|
|
7
|
+
return (_jsxs("span", { className: `dte-pdf-field-char-count${filledCount >= maxLength ? ' --at-limit' : ''}`, "aria-live": "polite", children: [filledCount, "/", maxLength] }));
|
|
8
|
+
};
|
|
9
|
+
//# sourceMappingURL=char-limit-indicator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"char-limit-indicator.js","sourceRoot":"","sources":["../../../src/components/shared/char-limit-indicator.tsx"],"names":[],"mappings":";AAOA,MAAM,CAAC,MAAM,kBAAkB,GAAgC,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,EAAE,EAAE;IACpF,IAAI,SAAS,IAAI,IAAI,EAAE,CAAC;QACpB,OAAO,IAAI,CAAC;IAChB,CAAC;IAED,MAAM,WAAW,GAAG,KAAK,CAAC,MAAM,CAAC;IAEjC,OAAO,CACH,gBACI,SAAS,EAAE,2BAA2B,WAAW,IAAI,SAAS,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,EAAE,eAC3E,QAAQ,aAEjB,WAAW,OAAG,SAAS,IACrB,CACV,CAAC;AACN,CAAC,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/shared/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/shared/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC;AAClC,cAAc,wBAAwB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/components/shared/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/components/shared/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC;AAClC,cAAc,wBAAwB,CAAC"}
|
|
@@ -12,10 +12,10 @@
|
|
|
12
12
|
}
|
|
13
13
|
|
|
14
14
|
.dte-pdf-field-error-message {
|
|
15
|
-
|
|
15
|
+
bottom: -4px;
|
|
16
|
+
transform: translateY(100%);
|
|
16
17
|
min-width: 100px;
|
|
17
18
|
position: absolute;
|
|
18
|
-
margin-top: var(--spacing-1, 8px);
|
|
19
19
|
color: var(--danger);
|
|
20
20
|
font-size: var(--typescale-small, 10px);
|
|
21
21
|
}
|
|
@@ -105,6 +105,13 @@
|
|
|
105
105
|
}
|
|
106
106
|
}
|
|
107
107
|
|
|
108
|
+
textarea.dte-pdf-field-fillable,
|
|
109
|
+
input[type='text'].dte-pdf-field-fillable,
|
|
110
|
+
input[type='number'].dte-pdf-field-fillable {
|
|
111
|
+
font-family: inherit;
|
|
112
|
+
font-weight: inherit;
|
|
113
|
+
}
|
|
114
|
+
|
|
108
115
|
.dte-pdf-field-generic-table {
|
|
109
116
|
padding: var(--spacing-0, 0);
|
|
110
117
|
margin: var(--spacing-0, 0);
|
|
@@ -47,7 +47,8 @@
|
|
|
47
47
|
background-color: var(--color-neutral-0, #ffffff);
|
|
48
48
|
border-radius: 4px;
|
|
49
49
|
padding: 1px var(--spacing-half, 4px);
|
|
50
|
-
top:
|
|
50
|
+
top: 0;
|
|
51
|
+
transform: translateY(-50%);
|
|
51
52
|
left: 3px;
|
|
52
53
|
font-size: var(--typescale-small, 10px);
|
|
53
54
|
line-height: 1;
|
|
@@ -63,7 +64,27 @@
|
|
|
63
64
|
}
|
|
64
65
|
}
|
|
65
66
|
|
|
67
|
+
.dte-pdf-field-char-count {
|
|
68
|
+
position: absolute;
|
|
69
|
+
right: 3px;
|
|
70
|
+
bottom: 0;
|
|
71
|
+
transform: translateY(50%);
|
|
72
|
+
padding: 1px var(--spacing-half, 4px);
|
|
73
|
+
border-radius: 4px;
|
|
74
|
+
background-color: var(--color-neutral-0, #ffffff);
|
|
75
|
+
box-shadow: 0 0 0 1px var(--pdf-field-color);
|
|
76
|
+
color: var(--pdf-field-color-dark);
|
|
77
|
+
font-size: var(--typescale-small, 10px);
|
|
78
|
+
user-select: none;
|
|
79
|
+
|
|
80
|
+
&.--at-limit {
|
|
81
|
+
color: var(--danger, #dc3545);
|
|
82
|
+
box-shadow: 0 0 0 1px var(--danger, #dc3545);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
66
86
|
input::placeholder,
|
|
87
|
+
textarea::placeholder,
|
|
67
88
|
input[type='date'],
|
|
68
89
|
input[type='date']::-webkit-calendar-picker-indicator {
|
|
69
90
|
color: var(--pdf-field-color);
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { type PdfField } from '../../interface/types';
|
|
2
|
+
import { type TextMeasurer } from './text-wrap.utils';
|
|
3
|
+
export type FieldTextLayout = 'single-line' | 'multiline' | 'number';
|
|
4
|
+
/** Tolerance for float noise, so an exact fit (e.g. 28 x 7.1px in 198.8px) isn't rejected. */
|
|
5
|
+
export declare const EPSILON = 0.000001;
|
|
6
|
+
/** What a text-entry field offers to lay text out in, with a way to measure that text. */
|
|
7
|
+
export interface FieldTextBox {
|
|
8
|
+
layout: FieldTextLayout;
|
|
9
|
+
/** Content-box width in px (field width minus horizontal padding and borders). */
|
|
10
|
+
width: number;
|
|
11
|
+
/** Content-box height in px. */
|
|
12
|
+
height: number;
|
|
13
|
+
/** Height of one line box in px. */
|
|
14
|
+
lineHeight: number;
|
|
15
|
+
measure: TextMeasurer;
|
|
16
|
+
/** Same key, same geometry and font: results for it can be shared. */
|
|
17
|
+
key: string;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* The measurable text box of a fillable `text`/`number` field, measured with canvas at the
|
|
21
|
+
* field's own font family, weight and size. `undefined` for every other kind of field.
|
|
22
|
+
*/
|
|
23
|
+
export declare const getFieldTextBox: (field: PdfField) => FieldTextBox | undefined;
|
|
24
|
+
/** Whole lines of text that fit the box height; always at least one. */
|
|
25
|
+
export declare const getMaxLines: ({ height, lineHeight, }: Pick<FieldTextBox, "height" | "lineHeight">) => number;
|
|
26
|
+
/**
|
|
27
|
+
* Whether `text` fits the box without overflowing: its width on one line, or its wrapped lines.
|
|
28
|
+
* A single character always counts as fitting, so no field is ever left impossible to type in.
|
|
29
|
+
*/
|
|
30
|
+
export declare const doesTextFitBox: (box: FieldTextBox, text: string) => boolean;
|
|
31
|
+
//# sourceMappingURL=field-text-box.utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"field-text-box.utils.d.ts","sourceRoot":"","sources":["../../../src/utils/field/field-text-box.utils.ts"],"names":[],"mappings":"AACA,OAAO,EAAiB,KAAK,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAGrE,OAAO,EAAmC,KAAK,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEvF,MAAM,MAAM,eAAe,GAAG,aAAa,GAAG,WAAW,GAAG,QAAQ,CAAC;AAErE,8FAA8F;AAC9F,eAAO,MAAM,OAAO,WAAO,CAAC;AAqB5B,0FAA0F;AAC1F,MAAM,WAAW,YAAY;IACzB,MAAM,EAAE,eAAe,CAAC;IACxB,kFAAkF;IAClF,KAAK,EAAE,MAAM,CAAC;IACd,gCAAgC;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,oCAAoC;IACpC,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,YAAY,CAAC;IACtB,sEAAsE;IACtE,GAAG,EAAE,MAAM,CAAC;CACf;AAqDD;;;GAGG;AACH,eAAO,MAAM,eAAe,GAAI,OAAO,QAAQ,KAAG,YAAY,GAAG,SAoBhE,CAAC;AAEF,wEAAwE;AACxE,eAAO,MAAM,WAAW,GAAI,yBAGzB,IAAI,CAAC,YAAY,EAAE,QAAQ,GAAG,YAAY,CAAC,WAE7C,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,cAAc,GAAI,KAAK,YAAY,EAAE,MAAM,MAAM,KAAG,OAShE,CAAC"}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { FieldTypeEnum } from '../../interface/types';
|
|
2
|
+
import { getFieldFontSizeInPixels } from './get-field-font-size.utils';
|
|
3
|
+
import { getFieldTypographyStyle } from './get-field-typography.utils';
|
|
4
|
+
import { advanceWrap, INITIAL_WRAP_STATE } from './text-wrap.utils';
|
|
5
|
+
/** Tolerance for float noise, so an exact fit (e.g. 28 x 7.1px in 198.8px) isn't rejected. */
|
|
6
|
+
export const EPSILON = 1e-6;
|
|
7
|
+
/**
|
|
8
|
+
* `.dte-pdf-field-fillable` box model (pdf-field-overlay.css): no padding or border, and
|
|
9
|
+
* `line-height: 1`. Update together with the CSS if either changes.
|
|
10
|
+
*/
|
|
11
|
+
const FILLABLE_TEXT_INSET_PX = { horizontal: 0, vertical: 0 };
|
|
12
|
+
const FILLABLE_LINE_HEIGHT_RATIO = 1;
|
|
13
|
+
/**
|
|
14
|
+
* Chrome keeps the inner spin button's 15px gutter free of text in `<input type="number">` even
|
|
15
|
+
* while the button is hidden, so a long value is clipped by this much. Applied in every browser,
|
|
16
|
+
* so one that doesn't reserve it is at worst slightly conservative.
|
|
17
|
+
*/
|
|
18
|
+
const NUMBER_INPUT_SPIN_BUTTON_PX = 15;
|
|
19
|
+
/** Per-glyph width (em) used when canvas measurement isn't available (SSR, jsdom). */
|
|
20
|
+
const FALLBACK_TEXT_WIDTH_EM = 0.46;
|
|
21
|
+
const FALLBACK_DIGIT_WIDTH_EM = 0.556;
|
|
22
|
+
const FALLBACK_BOLD_WIDTH_FACTOR = 1.06;
|
|
23
|
+
let measureContext;
|
|
24
|
+
const getMeasureContext = () => {
|
|
25
|
+
var _a;
|
|
26
|
+
if (measureContext === undefined) {
|
|
27
|
+
measureContext =
|
|
28
|
+
typeof document === 'undefined'
|
|
29
|
+
? null
|
|
30
|
+
: ((_a = document.createElement('canvas').getContext('2d')) !== null && _a !== void 0 ? _a : null);
|
|
31
|
+
}
|
|
32
|
+
return measureContext;
|
|
33
|
+
};
|
|
34
|
+
const createTextMeasurer = ({ fontFamily, fontSizePx, fontWeight }, layout) => {
|
|
35
|
+
const ctx = getMeasureContext();
|
|
36
|
+
if (!ctx) {
|
|
37
|
+
const isBold = fontWeight === 'bold';
|
|
38
|
+
const widthEm = layout === 'number'
|
|
39
|
+
? FALLBACK_DIGIT_WIDTH_EM
|
|
40
|
+
: FALLBACK_TEXT_WIDTH_EM * (isBold ? FALLBACK_BOLD_WIDTH_FACTOR : 1);
|
|
41
|
+
return text => text.length * fontSizePx * widthEm;
|
|
42
|
+
}
|
|
43
|
+
const font = `${fontWeight} ${fontSizePx}px ${fontFamily}`;
|
|
44
|
+
return text => {
|
|
45
|
+
ctx.font = font;
|
|
46
|
+
return ctx.measureText(text).width;
|
|
47
|
+
};
|
|
48
|
+
};
|
|
49
|
+
const getFieldTextLayout = (field) => {
|
|
50
|
+
if (field.type !== FieldTypeEnum.fillable) {
|
|
51
|
+
return undefined;
|
|
52
|
+
}
|
|
53
|
+
if (field.subType === 'number') {
|
|
54
|
+
return 'number';
|
|
55
|
+
}
|
|
56
|
+
if (field.subType === 'text') {
|
|
57
|
+
return field.multiline ? 'multiline' : 'single-line';
|
|
58
|
+
}
|
|
59
|
+
return undefined;
|
|
60
|
+
};
|
|
61
|
+
/**
|
|
62
|
+
* The measurable text box of a fillable `text`/`number` field, measured with canvas at the
|
|
63
|
+
* field's own font family, weight and size. `undefined` for every other kind of field.
|
|
64
|
+
*/
|
|
65
|
+
export const getFieldTextBox = (field) => {
|
|
66
|
+
const layout = getFieldTextLayout(field);
|
|
67
|
+
if (!layout) {
|
|
68
|
+
return undefined;
|
|
69
|
+
}
|
|
70
|
+
const { fontFamily, fontWeight } = getFieldTypographyStyle(field);
|
|
71
|
+
const fontSizePx = getFieldFontSizeInPixels(field);
|
|
72
|
+
const spinButtonWidth = layout === 'number' ? NUMBER_INPUT_SPIN_BUTTON_PX : 0;
|
|
73
|
+
const width = field.width - 2 * FILLABLE_TEXT_INSET_PX.horizontal - spinButtonWidth;
|
|
74
|
+
const height = field.height - 2 * FILLABLE_TEXT_INSET_PX.vertical;
|
|
75
|
+
return {
|
|
76
|
+
layout,
|
|
77
|
+
width,
|
|
78
|
+
height,
|
|
79
|
+
lineHeight: fontSizePx * FILLABLE_LINE_HEIGHT_RATIO,
|
|
80
|
+
measure: createTextMeasurer({ fontFamily, fontSizePx, fontWeight }, layout),
|
|
81
|
+
key: [layout, width, height, fontSizePx, fontWeight, fontFamily].join('|'),
|
|
82
|
+
};
|
|
83
|
+
};
|
|
84
|
+
/** Whole lines of text that fit the box height; always at least one. */
|
|
85
|
+
export const getMaxLines = ({ height, lineHeight, }) => {
|
|
86
|
+
return Math.max(1, Math.floor(height / lineHeight + EPSILON));
|
|
87
|
+
};
|
|
88
|
+
/**
|
|
89
|
+
* Whether `text` fits the box without overflowing: its width on one line, or its wrapped lines.
|
|
90
|
+
* A single character always counts as fitting, so no field is ever left impossible to type in.
|
|
91
|
+
*/
|
|
92
|
+
export const doesTextFitBox = (box, text) => {
|
|
93
|
+
if (Array.from(text).length <= 1) {
|
|
94
|
+
return true;
|
|
95
|
+
}
|
|
96
|
+
if (box.layout === 'multiline') {
|
|
97
|
+
const { lines } = advanceWrap(INITIAL_WRAP_STATE, text, box.width, box.measure);
|
|
98
|
+
return lines <= getMaxLines(box);
|
|
99
|
+
}
|
|
100
|
+
return box.measure(text) <= box.width + EPSILON;
|
|
101
|
+
};
|
|
102
|
+
//# sourceMappingURL=field-text-box.utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"field-text-box.utils.js","sourceRoot":"","sources":["../../../src/utils/field/field-text-box.utils.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { type PdfField } from '../../interface/types';
|
|
2
|
+
/**
|
|
3
|
+
* The value a fillable `text`/`number` field should take when its text goes from `previousValue`
|
|
4
|
+
* to `nextValue`: `nextValue` when the text fits the field, otherwise as much of it as fits.
|
|
5
|
+
*
|
|
6
|
+
* Fit is measured from the rendered text (width on one line, wrapped lines in a multiline
|
|
7
|
+
* field), so narrow text keeps filling the field after wide text has stopped. Like the native
|
|
8
|
+
* `maxLength`, it is the text just inserted or pasted that is cut back, never what was already
|
|
9
|
+
* there, and an edit that would only add overflow is refused outright. Deleting is always allowed,
|
|
10
|
+
* even from a value that already overflows.
|
|
11
|
+
*/
|
|
12
|
+
export declare const fitFieldTextChange: (field: PdfField, previousValue: string, nextValue: string) => string;
|
|
13
|
+
//# sourceMappingURL=fit-field-text.utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fit-field-text.utils.d.ts","sourceRoot":"","sources":["../../../src/utils/field/fit-field-text.utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AA4BtD;;;;;;;;;GASG;AACH,eAAO,MAAM,kBAAkB,GAC3B,OAAO,QAAQ,EACf,eAAe,MAAM,EACrB,WAAW,MAAM,KAClB,MAkBF,CAAC"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { doesTextFitBox, getFieldTextBox } from './field-text-box.utils';
|
|
2
|
+
import { findLargestFit } from './get-field-max-length.utils';
|
|
3
|
+
/** Splits `next` into what `previous` and `next` share at both ends, and what sits between. */
|
|
4
|
+
const getInsertion = (previous, next) => {
|
|
5
|
+
const shorter = Math.min(previous.length, next.length);
|
|
6
|
+
let headLength = 0;
|
|
7
|
+
while (headLength < shorter && previous[headLength] === next[headLength]) {
|
|
8
|
+
headLength += 1;
|
|
9
|
+
}
|
|
10
|
+
let tailLength = 0;
|
|
11
|
+
while (tailLength < shorter - headLength &&
|
|
12
|
+
previous[previous.length - 1 - tailLength] === next[next.length - 1 - tailLength]) {
|
|
13
|
+
tailLength += 1;
|
|
14
|
+
}
|
|
15
|
+
return {
|
|
16
|
+
head: next.slice(0, headLength),
|
|
17
|
+
inserted: next.slice(headLength, next.length - tailLength),
|
|
18
|
+
tail: next.slice(next.length - tailLength),
|
|
19
|
+
};
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* The value a fillable `text`/`number` field should take when its text goes from `previousValue`
|
|
23
|
+
* to `nextValue`: `nextValue` when the text fits the field, otherwise as much of it as fits.
|
|
24
|
+
*
|
|
25
|
+
* Fit is measured from the rendered text (width on one line, wrapped lines in a multiline
|
|
26
|
+
* field), so narrow text keeps filling the field after wide text has stopped. Like the native
|
|
27
|
+
* `maxLength`, it is the text just inserted or pasted that is cut back, never what was already
|
|
28
|
+
* there, and an edit that would only add overflow is refused outright. Deleting is always allowed,
|
|
29
|
+
* even from a value that already overflows.
|
|
30
|
+
*/
|
|
31
|
+
export const fitFieldTextChange = (field, previousValue, nextValue) => {
|
|
32
|
+
const box = getFieldTextBox(field);
|
|
33
|
+
if (!box || doesTextFitBox(box, nextValue)) {
|
|
34
|
+
return nextValue;
|
|
35
|
+
}
|
|
36
|
+
const { head, inserted, tail } = getInsertion(previousValue, nextValue);
|
|
37
|
+
const insertedChars = Array.from(inserted);
|
|
38
|
+
const withInserted = (count) => {
|
|
39
|
+
return head + insertedChars.slice(0, count).join('') + tail;
|
|
40
|
+
};
|
|
41
|
+
const keep = findLargestFit(count => doesTextFitBox(box, withInserted(count)), insertedChars.length);
|
|
42
|
+
return keep === 0 && insertedChars.length > 0 ? previousValue : withInserted(keep);
|
|
43
|
+
};
|
|
44
|
+
//# sourceMappingURL=fit-field-text.utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fit-field-text.utils.js","sourceRoot":"","sources":["../../../src/utils/field/fit-field-text.utils.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzE,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAE9D,+FAA+F;AAC/F,MAAM,YAAY,GAAG,CAAC,QAAgB,EAAE,IAAY,EAAE,EAAE;IACpD,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;IAEvD,IAAI,UAAU,GAAG,CAAC,CAAC;IACnB,OAAO,UAAU,GAAG,OAAO,IAAI,QAAQ,CAAC,UAAU,CAAC,KAAK,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC;QACvE,UAAU,IAAI,CAAC,CAAC;IACpB,CAAC;IAED,IAAI,UAAU,GAAG,CAAC,CAAC;IACnB,OACI,UAAU,GAAG,OAAO,GAAG,UAAU;QACjC,QAAQ,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,GAAG,UAAU,CAAC,KAAK,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,GAAG,UAAU,CAAC,EACnF,CAAC;QACC,UAAU,IAAI,CAAC,CAAC;IACpB,CAAC;IAED,OAAO;QACH,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,UAAU,CAAC;QAC/B,QAAQ,EAAE,IAAI,CAAC,KAAK,CAAC,UAAU,EAAE,IAAI,CAAC,MAAM,GAAG,UAAU,CAAC;QAC1D,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,GAAG,UAAU,CAAC;KAC7C,CAAC;AACN,CAAC,CAAC;AAEF;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAC9B,KAAe,EACf,aAAqB,EACrB,SAAiB,EACX,EAAE;IACR,MAAM,GAAG,GAAG,eAAe,CAAC,KAAK,CAAC,CAAC;IACnC,IAAI,CAAC,GAAG,IAAI,cAAc,CAAC,GAAG,EAAE,SAAS,CAAC,EAAE,CAAC;QACzC,OAAO,SAAS,CAAC;IACrB,CAAC;IAED,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,GAAG,YAAY,CAAC,aAAa,EAAE,SAAS,CAAC,CAAC;IACxE,MAAM,aAAa,GAAG,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC3C,MAAM,YAAY,GAAG,CAAC,KAAa,EAAE,EAAE;QACnC,OAAO,IAAI,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC;IAChE,CAAC,CAAC;IAEF,MAAM,IAAI,GAAG,cAAc,CACvB,KAAK,CAAC,EAAE,CAAC,cAAc,CAAC,GAAG,EAAE,YAAY,CAAC,KAAK,CAAC,CAAC,EACjD,aAAa,CAAC,MAAM,CACvB,CAAC;IAEF,OAAO,IAAI,KAAK,CAAC,IAAI,aAAa,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;AACvF,CAAC,CAAC"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { type PdfField } from '../../interface/types';
|
|
2
|
+
import { type FieldTextBox } from './field-text-box.utils';
|
|
3
|
+
/**
|
|
4
|
+
* Largest `length` in `[0, max]` for which `fits(length)` holds; `fits` must be monotone
|
|
5
|
+
* (once a length stops fitting, longer ones don't either) and `fits(0)` is taken as true.
|
|
6
|
+
*/
|
|
7
|
+
export declare const findLargestFit: (fits: (length: number) => boolean, max?: number) => number;
|
|
8
|
+
type TextBoxGeometry = Omit<FieldTextBox, 'key'>;
|
|
9
|
+
export type TextCapacityParams = TextBoxGeometry & {
|
|
10
|
+
/** What is already typed; it counts towards the capacity and uses up some of the room. */
|
|
11
|
+
value?: string;
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* Highest character count a text box can hold, from rendered text widths: the characters
|
|
15
|
+
* already in `value` plus how many more fit after it.
|
|
16
|
+
*
|
|
17
|
+
* - `number`: guaranteed fit, bounded by the widest of the digits, `.` and `-`
|
|
18
|
+
* - `single-line`: expected fit for typical text, from the mean glyph width of a sample
|
|
19
|
+
* - `multiline`: expected fit for typical text, from simulated word wrapping into the
|
|
20
|
+
* `floor(height / lineHeight)` lines available
|
|
21
|
+
*
|
|
22
|
+
* Narrow text leaves more room than wide text, so the answer moves with what is typed. A
|
|
23
|
+
* value that already overflows has no room left: the capacity is just its own length.
|
|
24
|
+
* At least 1; `undefined` when `measure` yields no usable text width, since there is then
|
|
25
|
+
* no basis for a limit.
|
|
26
|
+
*/
|
|
27
|
+
export declare const estimateTextCapacity: ({ value, ...box }: TextCapacityParams) => number | undefined;
|
|
28
|
+
/**
|
|
29
|
+
* Max character count a fillable `text`/`number` field can hold given what is typed in it, so
|
|
30
|
+
* the counter can say how much room is left. With no `value` it is the field's capacity when
|
|
31
|
+
* empty. Input is limited by what actually fits, see `fitFieldTextChange`, not by this count.
|
|
32
|
+
*
|
|
33
|
+
* See {@link estimateTextCapacity} for how each field kind is measured. Text is measured
|
|
34
|
+
* with canvas at the field's own font, so it follows family, weight and size.
|
|
35
|
+
*/
|
|
36
|
+
export declare const getFieldMaxLength: (field: PdfField, value?: string) => number | undefined;
|
|
37
|
+
export {};
|
|
38
|
+
//# sourceMappingURL=get-field-max-length.utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-field-max-length.utils.d.ts","sourceRoot":"","sources":["../../../src/utils/field/get-field-max-length.utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,EAAyC,KAAK,YAAY,EAAE,MAAM,wBAAwB,CAAC;AA+BlG;;;GAGG;AACH,eAAO,MAAM,cAAc,GAAI,MAAM,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,EAAE,YAAkB,KAAG,MAsBtF,CAAC;AAkBF,KAAK,eAAe,GAAG,IAAI,CAAC,YAAY,EAAE,KAAK,CAAC,CAAC;AA2DjD,MAAM,MAAM,kBAAkB,GAAG,eAAe,GAAG;IAC/C,0FAA0F;IAC1F,KAAK,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,oBAAoB,GAAI,mBAGlC,kBAAkB,KAAG,MAAM,GAAG,SAqBhC,CAAC;AAKF;;;;;;;GAOG;AACH,eAAO,MAAM,iBAAiB,GAAI,OAAO,QAAQ,EAAE,cAAU,KAAG,MAAM,GAAG,SAmBxE,CAAC"}
|