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
20 changes: 10 additions & 10 deletions packages/examples/next-14/app/form/page.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {
View,
Text,
Checkbox,
FormField,
FieldSet,
TextInput,
Select,
List,
Expand All @@ -32,7 +32,7 @@ export default function Form() {
height: '100%',
}}
>
<FormField name="user-info" style={{ flexDirection: 'column' }}>
<FieldSet name="user-info" style={{ flexDirection: 'column' }}>
<Text>TextInput</Text>
<TextInput
name="username"
Expand Down Expand Up @@ -80,7 +80,7 @@ export default function Form() {
defaultValue=""
style={{ height: '50px' }}
/>
</FormField>
</FieldSet>
</View>
</Page>

Expand All @@ -92,7 +92,7 @@ export default function Form() {
height: '100%',
}}
>
<FormField name="user-details" style={{ flexDirection: 'column' }}>
<FieldSet name="user-details" style={{ flexDirection: 'column' }}>
<Text>TextInput (multiline)</Text>
<TextInput
name="details"
Expand All @@ -101,7 +101,7 @@ export default function Form() {
multiline
style={{ fontSize: 8, height: '100px' }}
/>
</FormField>
</FieldSet>
</View>
</Page>

Expand All @@ -113,17 +113,17 @@ export default function Form() {
height: '100%',
}}
>
<Text>TextInput (no FormField)</Text>
<Text>TextInput (no FieldSet)</Text>
<TextInput
name="textinput-no-formfield"
value="no formfield"
name="textinput-no-fieldset"
value="no fieldset"
align="center"
style={{ height: '50px' }}
/>

<Text>Checkbox (checked, no FormField)</Text>
<Text>Checkbox (checked, no FieldSet)</Text>
<Checkbox
name="checkbox-no-formfield"
name="checkbox-no-fieldset"
checked
style={{ height: '20px' }}
/>
Expand Down
20 changes: 10 additions & 10 deletions packages/examples/next-15/app/form/page.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {
View,
Text,
Checkbox,
FormField,
FieldSet,
TextInput,
Select,
List,
Expand All @@ -32,7 +32,7 @@ export default function Form() {
height: '100%',
}}
>
<FormField name="user-info" style={{ flexDirection: 'column' }}>
<FieldSet name="user-info" style={{ flexDirection: 'column' }}>
<Text>TextInput</Text>
<TextInput
name="username"
Expand Down Expand Up @@ -80,7 +80,7 @@ export default function Form() {
defaultValue=""
style={{ height: '50px' }}
/>
</FormField>
</FieldSet>
</View>
</Page>

Expand All @@ -92,7 +92,7 @@ export default function Form() {
height: '100%',
}}
>
<FormField name="user-details" style={{ flexDirection: 'column' }}>
<FieldSet name="user-details" style={{ flexDirection: 'column' }}>
<Text>TextInput (multiline)</Text>
<TextInput
name="details"
Expand All @@ -101,7 +101,7 @@ export default function Form() {
multiline
style={{ fontSize: 8, height: '100px' }}
/>
</FormField>
</FieldSet>
</View>
</Page>

Expand All @@ -113,17 +113,17 @@ export default function Form() {
height: '100%',
}}
>
<Text>TextInput (no FormField)</Text>
<Text>TextInput (no FieldSet)</Text>
<TextInput
name="textinput-no-formfield"
value="no formfield"
name="textinput-no-fieldset"
value="no fieldset"
align="center"
style={{ height: '50px' }}
/>

<Text>Checkbox (checked, no FormField)</Text>
<Text>Checkbox (checked, no FieldSet)</Text>
<Checkbox
name="checkbox-no-formfield"
name="checkbox-no-fieldset"
checked
style={{ height: '20px' }}
/>
Expand Down
2 changes: 1 addition & 1 deletion packages/primitives/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export const Note = 'NOTE';
export const Path = 'PATH';
export const Rect = 'RECT';
export const Line = 'LINE';
export const FormField = 'FORM_FIELD';
export const FieldSet = 'FIELD_SET';
export const TextInput = 'TEXT_INPUT';
export const Select = 'SELECT';
export const Checkbox = 'CHECKBOX';
Expand Down
4 changes: 2 additions & 2 deletions packages/primitives/tests/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ describe('primitives', () => {
expect(primitives.Line).toBeTruthy();
});

test('should export form field', () => {
expect(primitives.FormField).toBeTruthy();
test('should export field set', () => {
expect(primitives.FieldSet).toBeTruthy();
});

test('should export text input', () => {
Expand Down
18 changes: 0 additions & 18 deletions packages/render/src/primitives/form/renderFormField.js

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { parseCheckboxOptions } from '../../utils/parseFormOptions';
import { parseCheckboxOptions } from '../utils/parseFormOptions';

const renderCheckbox = (ctx, node, options = {}) => {
const { top, left, width, height } = node.box || {};

// Element's name
const name = node.props?.name || '';
const formFieldOptions = options.formFields?.at(0);
const fieldSetOptions = options.fieldSets?.at(0);

if (!ctx._root.data.AcroForm) {
ctx.initForm();
Expand All @@ -17,7 +17,7 @@ const renderCheckbox = (ctx, node, options = {}) => {
top,
width,
height,
parseCheckboxOptions(ctx, node, formFieldOptions),
parseCheckboxOptions(ctx, node, fieldSetOptions),
);
};

Expand Down
22 changes: 22 additions & 0 deletions packages/render/src/primitives/renderFieldSet.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
const renderFieldSet = (ctx, node, options = {}) => {
const name = node.props?.name || '';

if (!ctx._root.data.AcroForm) {
ctx.initForm();
}

const formField = ctx.formField(name);
const option = options;

if (!option.fieldSets) {
option.fieldSets = [formField];
} else {
option.fieldSets.push(formField);
}
};

export const cleanUpFieldSet = (_ctx, _node, options) => {
options.fieldSets.pop();
};

export default renderFieldSet;
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { parseSelectAndListFieldOptions } from '../../utils/parseFormOptions';
import { parseSelectAndListFieldOptions } from '../utils/parseFormOptions';

const renderList = (ctx, node) => {
const { top, left, width, height } = node.box || {};
Expand Down
14 changes: 7 additions & 7 deletions packages/render/src/primitives/renderNode.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@ import setLink from '../operations/setLink';
import clipNode from '../operations/clipNode';
import transform from '../operations/transform';
import setDestination from '../operations/setDestination';
import renderTextInput from './form/renderTextInput';
import renderSelect from './form/renderSelect';
import renderFormField, { cleanUpFormField } from './form/renderFormField';
import renderList from './form/renderList';
import renderCheckbox from './form/renderCheckbox';
import renderTextInput from './renderTextInput';
import renderSelect from './renderSelect';
import renderFieldSet, { cleanUpFieldSet } from './renderFieldSet';
import renderList from './renderList';
import renderCheckbox from './renderCheckbox';

const isRecursiveNode = (node) => node.type !== P.Text && node.type !== P.Svg;

Expand All @@ -40,7 +40,7 @@ const renderFns = {
[P.Text]: renderText,
[P.Note]: renderNote,
[P.Image]: renderImage,
[P.FormField]: renderFormField,
[P.FieldSet]: renderFieldSet,
[P.TextInput]: renderTextInput,
[P.Select]: renderSelect,
[P.Checkbox]: renderCheckbox,
Expand All @@ -51,7 +51,7 @@ const renderFns = {
};

const cleanUpFns = {
[P.FormField]: cleanUpFormField,
[P.FieldSet]: cleanUpFieldSet,
};

const renderNode = (ctx, node, options) => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { parseSelectAndListFieldOptions } from '../../utils/parseFormOptions';
import { parseSelectAndListFieldOptions } from '../utils/parseFormOptions';

const renderSelect = (ctx, node) => {
const { top, left, width, height } = node.box || {};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { parseTextFieldOptions } from '../../utils/parseFormOptions';
import { parseTextFieldOptions } from '../utils/parseFormOptions';

const renderTextInput = (ctx, node, options = {}) => {
const { top, left, width, height } = node.box || {};

// Element's name
const name = node.props?.name || '';
const formFieldOptions = options.formFields?.at(0);
const fieldSetOptions = options.fieldSets?.at(0);

if (!ctx._root.data.AcroForm) {
ctx.initForm();
Expand All @@ -17,7 +17,7 @@ const renderTextInput = (ctx, node, options = {}) => {
top,
width,
height,
parseTextFieldOptions(node, formFieldOptions),
parseTextFieldOptions(node, fieldSetOptions),
);
};

Expand Down
8 changes: 4 additions & 4 deletions packages/render/src/utils/parseFormOptions.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,10 @@ const parseCommonFormOptions = (node) => {
};
};

const parseTextFieldOptions = (node, formField) => {
const parseTextFieldOptions = (node, fieldSet) => {
return clean({
...parseCommonFormOptions(node),
parent: formField || undefined,
parent: fieldSet || undefined,
align: node.props?.align || 'left',
multiline: node.props?.multiline || undefined,
password: node.props?.password || false,
Expand Down Expand Up @@ -68,7 +68,7 @@ const getAppearance = (ctx, codepoint, width, height) => {
return appearance;
};

const parseCheckboxOptions = (ctx, node, formField) => {
const parseCheckboxOptions = (ctx, node, fieldSet) => {
const { width, height } = node.box || {};

const onOption = node.props?.onState || 'Yes';
Expand Down Expand Up @@ -103,7 +103,7 @@ const parseCheckboxOptions = (ctx, node, formField) => {
...parseCommonFormOptions(node),
backgroundColor: node.props?.backgroundColor || undefined,
borderColor: node.props?.borderColor || undefined,
parent: formField || undefined,
parent: fieldSet || undefined,
value: `/${node.props?.checked === true ? onOption : offOption}`,
defaultValue: `/${node.props?.checked === true ? onOption : offOption}`,
AS: node.props?.checked === true ? onOption : offOption,
Expand Down
20 changes: 10 additions & 10 deletions packages/render/tests/primitives/renderForm.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,32 +2,32 @@ import { describe, expect, test } from 'vitest';
import * as P from '@react-pdf/primitives';

import createCTX from '../ctx';
import renderFormField from '../../src/primitives/form/renderFormField';
import renderFieldSet from '../../src/primitives/renderFieldSet';

describe('primitive renderFormField', () => {
test('should render FormField correctly', () => {
describe('primitive renderFieldSet', () => {
test('should render FieldSet correctly', () => {
const ctx = createCTX();
const args = 'example';
const props = { name: args };
const node = { type: P.FormField, props };
const node = { type: P.FieldSet, props };

renderFormField(ctx, node);
renderFieldSet(ctx, node);

expect(ctx.formField.mock.calls).toHaveLength(1);
expect(ctx.formField.mock.calls[0]).toHaveLength(1);
expect(ctx.formField.mock.calls[0][0]).toBe(args);
});

test.todo('FormField with one textInput direct child', () => {
test.todo('FieldSet with one textInput direct child', () => {
const ctx = createCTX();
const node = { type: P.FormField, children: [{ type: P.TextInput }] };
const node = { type: P.FieldSet, children: [{ type: P.TextInput }] };

renderFormField(ctx, node);
renderFieldSet(ctx, node);

expect(ctx.textInput.mock.calls).toHaveLength(1);
});

test.todo('FormField with one TextInput indirect child', () => {
test.todo('FieldSet with one TextInput indirect child', () => {
const ctx = createCTX();
const node = {
type: P.TextInput,
Expand All @@ -43,7 +43,7 @@ describe('primitive renderFormField', () => {
],
};

renderFormField(ctx, node);
renderFieldSet(ctx, node);

expect(ctx.textInput.mock.calls).toHaveLength(1);
});
Expand Down
6 changes: 3 additions & 3 deletions packages/renderer/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -244,12 +244,12 @@ declare namespace ReactPDF {
defaultValue?: number | string;
}

interface FormFieldProps extends NodeProps {
interface FieldSetProps extends NodeProps {
name: string;
}

export class FormField extends React.Component<
React.PropsWithChildren<FormFieldProps>
export class FieldSet extends React.Component<
React.PropsWithChildren<FieldSetProps>
> {}

// see http://pdfkit.org/docs/forms.html#text_field_formatting
Expand Down