-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: added Form Annotation support #2845
Open
natterstefan
wants to merge
32
commits into
diegomura:master
Choose a base branch
from
traveltechdeluxe:feat/form-annotation
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from 30 commits
Commits
Show all changes
32 commits
Select commit
Hold shift + click to select a range
eee292a
Adding Form Annotation
axel7083 e39acab
Adding types
axel7083 51b4493
Fixing FormField scope issue and adding Unit Test
axel7083 687aa06
HotFix: Preventing problem in renderFormCombo for accessing node.box
axel7083 b562369
fix: lint
diegomura 824d05c
Merge remote-tracking branch 'axel7083/master'
runelk f20153a
Change FormText to TextInput for more consistent naming.
runelk 33ef422
Change FormCombo to Picker for more consistent naming.
runelk c36d8c9
Fix spelling error.
runelk 24183a0
Merge remote-tracking branch 'runelk/master'
natterstefan 6264795
chore: format code
natterstefan e6fa36b
test: fixed tests
natterstefan 9f68eaa
fix: fixed types
natterstefan c6f86f5
fix: fixed issue when using <Form/> multiple times
natterstefan 49322f8
feat: added form example
natterstefan 81b75d2
feat: updated example
natterstefan 8aa7a0a
test: fixed tests
natterstefan d05e812
feat: updated example
natterstefan a08b945
feat: added checkbox
natterstefan c7fb5e2
fix: fixed types
natterstefan d9a1e84
feat: added multiline example
natterstefan 96e4d7d
feat: added support for checked appearance (Checkbox)
natterstefan 7162e6f
feat: removed Form component, check AcroForm in form components
natterstefan 3dac42b
fixup! fixed obsolete !!this._root.data.AcroForm check
natterstefan ef4fee3
feat: removed FormPushButton
natterstefan 3e6c660
fixup! removed P.Form
natterstefan de0c19d
fixup! once more remove leftover code
natterstefan fd6e5f9
feat: introduced cleanup feature, suggested by @PhilippBloss
natterstefan 43bd666
fix: revert changes in acroform
natterstefan 39cb88a
feat: improved macos appearance
natterstefan 81dc6fa
feat: removed requirement to render TextInput and Checkbox within For…
natterstefan e1e3726
fix: fixed PDF appearance on macOS (e.g. checked Checkbox)
natterstefan File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
import React from 'react'; | ||
import { | ||
Document, | ||
Page, | ||
View, | ||
Text, | ||
Checkbox, | ||
FormField, | ||
TextInput, | ||
Picker, | ||
FormList, | ||
} from '@react-pdf/renderer'; | ||
|
||
const FormPdf = () => ( | ||
<Document> | ||
<Page> | ||
<View | ||
style={{ | ||
backgroundColor: 'rgba(182,28,28,0.62)', | ||
width: '30%', | ||
height: '100%', | ||
}} | ||
> | ||
<FormField name="user-info" style={{ flexDirection: 'column' }}> | ||
<Text>TextInput</Text> | ||
<TextInput | ||
name="username" | ||
value="foo" | ||
align="center" | ||
style={{ height: '50px' }} | ||
/> | ||
|
||
{/* Nested works as well */} | ||
<View> | ||
<Text>TextInput</Text> | ||
<TextInput | ||
name="password" | ||
value="bar" | ||
align="center" | ||
style={{ height: '50px' }} | ||
password | ||
/> | ||
</View> | ||
|
||
<Text>Checkbox (not checked)</Text> | ||
<Checkbox name="checkbox-default" style={{ height: '20px' }} /> | ||
|
||
<Text>Checkbox (checked)</Text> | ||
<Checkbox | ||
name="checkbox-checked" | ||
checked | ||
style={{ height: '20px' }} | ||
/> | ||
|
||
<Text>Picker</Text> | ||
<Picker | ||
name="combo" | ||
select={['', 'option 1', 'option 2']} | ||
value="" | ||
defaultValue="" | ||
style={{ height: '20px' }} | ||
/> | ||
|
||
<Text>FormList</Text> | ||
<FormList | ||
name="list" | ||
select={['', 'option 1', 'option 2']} | ||
value="" | ||
defaultValue="" | ||
style={{ height: '50px' }} | ||
/> | ||
</FormField> | ||
</View> | ||
</Page> | ||
|
||
<Page> | ||
<View | ||
style={{ | ||
backgroundColor: 'rgba(182,28,28,0.62)', | ||
width: '30%', | ||
height: '100%', | ||
}} | ||
> | ||
<FormField name="user-details" style={{ flexDirection: 'column' }}> | ||
<Text>TextInput (multiline)</Text> | ||
<TextInput | ||
name="details" | ||
value="hello" | ||
align="center" | ||
multiline | ||
style={{ fontSize: 8, height: '100px' }} | ||
/> | ||
</FormField> | ||
</View> | ||
</Page> | ||
</Document> | ||
); | ||
|
||
export default FormPdf; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
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); | ||
|
||
if (!formFieldOptions) | ||
natterstefan marked this conversation as resolved.
Show resolved
Hide resolved
|
||
throw new Error( | ||
'The TextInput element must be a children of a FormField element.', | ||
); | ||
|
||
if (!ctx._root.data.AcroForm) { | ||
ctx.initForm(); | ||
} | ||
|
||
ctx.formCheckbox( | ||
name, | ||
left, | ||
top, | ||
width, | ||
height, | ||
parseCheckboxOptions(ctx, node, formFieldOptions), | ||
); | ||
}; | ||
|
||
export default renderCheckbox; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
const renderFormField = (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.formFields) option.formFields = [formField]; | ||
else option.formFields.push(formField); | ||
}; | ||
|
||
export const cleanUpFormField = (_ctx, _node, options) => { | ||
options.formFields.pop(); | ||
}; | ||
|
||
export default renderFormField; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
import { parsePickerAndListFieldOptions } from '../../utils/parseFormOptions'; | ||
|
||
const renderFormList = (ctx, node) => { | ||
const { top, left, width, height } = node.box || {}; | ||
|
||
// Element's name | ||
const name = node.props?.name || ''; | ||
|
||
if (!ctx._root.data.AcroForm) { | ||
ctx.initForm(); | ||
} | ||
|
||
ctx.formList( | ||
name, | ||
left, | ||
top, | ||
width, | ||
height, | ||
parsePickerAndListFieldOptions(node), | ||
); | ||
}; | ||
|
||
export default renderFormList; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
import { parsePickerAndListFieldOptions } from '../../utils/parseFormOptions'; | ||
|
||
const renderPicker = (ctx, node) => { | ||
const { top, left, width, height } = node.box || {}; | ||
|
||
// Element's name | ||
const name = node.props?.name || ''; | ||
|
||
if (!ctx._root.data.AcroForm) { | ||
ctx.initForm(); | ||
} | ||
|
||
ctx.formCombo( | ||
name, | ||
left, | ||
top, | ||
width, | ||
height, | ||
parsePickerAndListFieldOptions(node), | ||
); | ||
}; | ||
|
||
export default renderPicker; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
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); | ||
|
||
if (!formFieldOptions) | ||
natterstefan marked this conversation as resolved.
Show resolved
Hide resolved
|
||
throw new Error( | ||
'The TextInput element must be a children of a FormField element.', | ||
); | ||
|
||
if (!ctx._root.data.AcroForm) { | ||
ctx.initForm(); | ||
} | ||
|
||
ctx.formText( | ||
name, | ||
left, | ||
top, | ||
width, | ||
height, | ||
parseTextFieldOptions(node, formFieldOptions), | ||
); | ||
}; | ||
|
||
export default renderTextInput; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not a strong opinion, but would
Form
be more semantic? ForField
I imagine like an input, but this is actually a form wrapperThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @diegomura,
thanks for your response. Let's see what I suggested here in the past: #2845 (comment). 🤔
My initial thought was to align the names with the ones used in
pdfkit
(here). SoTextInput
becomesFormText
,Picker
becomesFormPicker
, and so on. But you made a valid point back in 2022 suggesting we should stick to the native web primitives. I got used to the current names while preparing the PR.Regarding
FormField
: I chose the same name aspdfkit
mainly to align our (react-pdf) and their (pdfkit) docs and keep them similar. I don't know if that's practical.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What about something like
FormGroup
? Form rather sounds like the single and complete set of inputs, but they rather are a subsection. E.g., you could separate billing address and shipping address into twogroups
.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @PhilippBloss,
your suggestion makes sense to me, considering what pdfkit states in their docs as well:
What do you think of
fieldset
(https://developer.mozilla.org/en-US/docs/Web/HTML/Element/fieldset):There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds good as well. Would give the decision to @diegomura
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would take over the docs, except @natterstefan has already started with those