Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

### Unreleased

- Add a `hidden` option to form annotation methods, for a field that should start hidden (e.g. one an interactive action reveals later) instead of the usual default of visible and printable

### [v0.20.2] - 2026-08-29

- Fix bundlers and file tracers packing the ESM copies of the standard font metrics instead of the CommonJS ones the Node build actually loads, which left `Cannot find module` errors for every standard font at runtime, by resolving the internal `#standard-fonts/*` mapping to a single file under all conditions
Expand Down
3 changes: 3 additions & 0 deletions docs/forms.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,9 @@ The following `options` are accepted by all form annotation methods:
- `borderColor` - Field border color.
- `fontSize` [_number_] - Sets the font size used in the field appearance string.
The default, `0`, means auto sizing.
- `hidden` [_boolean_] - Builds the field starting hidden, instead of the
usual default of visible and printable, for a field an interactive action
(see `onClick` below) will reveal later.

Color options accept an array of RGB values, a hex color, or a named CSS color.
Method-specific options listed below are accepted in addition to these common
Expand Down
13 changes: 13 additions & 0 deletions lib/mixins/acroform.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,18 @@ function mapTypeAndFlags(type, userOptions, pdfObject) {
}
}

// The Widget annotation's own visibility/print flags (PDF spec Table 168),
// distinct from the field's `Ff` flags mapTypeAndFlags() handles above.
// formAnnotation() defaults this to 4 (print only) when left unset.
function mapVisibility(options, pdfObject) {
if (options.hidden) {
// Hidden (2) + Print (4): not shown or interactive until an action
// reveals it (e.g. a sibling field's onClick), but still printable once
// it is.
pdfObject.F = 6;
}
}

function mapJustify(userOptions, pdfObject) {
const result = FIELD_JUSTIFY[userOptions.align];
if (typeof result === 'number' && result !== 0) {
Expand Down Expand Up @@ -307,6 +319,7 @@ export default {
const pdfObject = {};

mapTypeAndFlags(type, options, pdfObject);
mapVisibility(options, pdfObject);
mapJustify(options, pdfObject);
this._mapFont(options, pdfObject);
mapStrings(options, pdfObject);
Expand Down
15 changes: 15 additions & 0 deletions tests/unit/acroform.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,21 @@ describe('acroform', () => {
expect(docData[2]).toBe(expected[2]);
});

test('a field built with hidden: true starts hidden', () => {
doc.initForm();
const docData = logData(doc);
doc.formPushButton('btn1', 20, 20, 100, 30, { hidden: true });
// 6 = Hidden + Print, overriding the usual default of 4 (print only)
expect(docData[1]).toContain('/F 6');
});

test('a field without hidden keeps the usual print-only default', () => {
doc.initForm();
const docData = logData(doc);
doc.formPushButton('btn1', 20, 20, 100, 30, {});
expect(docData[1]).toContain('/F 4');
});

test('type flags do not leak implementation markers', () => {
doc.initForm();
const docData = logData(doc);
Expand Down
Loading