Skip to content

Commit bd235f9

Browse files
TylerRickerikras
andauthored
Forward refs to input component (#18)
* Forward ref * Temporarily update react-final-form to a fork that fixes Field to forward refs * Add a prepare script that builds dist/ so that dist won't be missing if you install the package from from a git repo instead of from npm * Fixed deps Co-authored-by: Erik Rasmussen <rasmussenerik@gmail.com>
1 parent 1bae36c commit bd235f9

File tree

4 files changed

+103
-42
lines changed

4 files changed

+103
-42
lines changed

package-lock.json

Lines changed: 28 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@
1212
"scripts": {
1313
"start": "nps",
1414
"test": "nps test",
15-
"precommit": "lint-staged && npm start validate"
15+
"precommit": "lint-staged && npm start validate",
16+
"prepare": "nps build"
1617
},
1718
"author": "Erik Rasmussen <rasmussenerik@gmail.com> (http://github.com/erikras)",
1819
"license": "MIT",
@@ -66,7 +67,7 @@
6667
"raf": "^3.4.1",
6768
"react": "^16.8.1",
6869
"react-dom": "^16.8.1",
69-
"react-final-form": "^4.0.2",
70+
"react-final-form": "^6.5.0",
7071
"react-test-renderer": "^16.8.1",
7172
"rollup": "^1.1.2",
7273
"rollup-plugin-babel": "^4.3.2",
@@ -77,11 +78,11 @@
7778
"rollup-plugin-uglify": "^6.0.2"
7879
},
7980
"peerDependencies": {
80-
"final-form": ">=4.0.0",
81+
"final-form": ">=4.20.0",
8182
"prop-types": "^15.6.0",
8283
"react": "^15.3.0 || ^16.0.0-0",
8384
"react-dom": "^15.3.0 || ^16.0.0-0",
84-
"react-final-form": ">=3.0.0"
85+
"react-final-form": ">=6.5.0"
8586
},
8687
"jest": {
8788
"testEnvironment": "jsdom"

src/Html5ValidationField.js

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ type WithValidity = {
2222
setCustomValidity: (error: ?string) => void
2323
}
2424

25-
export default class Html5ValidationField extends React.Component<Props> {
25+
class Html5ValidationField extends React.Component<Props> {
2626
props: Props
2727
input: ?WithValidity
2828

@@ -81,9 +81,9 @@ export default class Html5ValidationField extends React.Component<Props> {
8181
}
8282
const errorKey: ?string = errorKeys.find(key => (validity: Object)[key])
8383
let error = errorKey && this.props[errorKey]
84-
if (typeof error === 'function') {
85-
error = error(value, this.props)
86-
}
84+
if (typeof error === 'function') {
85+
error = error(value, this.props)
86+
}
8787
input.setCustomValidity(error)
8888
return error
8989
}
@@ -104,8 +104,20 @@ export default class Html5ValidationField extends React.Component<Props> {
104104
tooShort,
105105
typeMismatch,
106106
valueMissing,
107+
innerRef,
107108
...rest
108109
} = this.props
109-
return React.createElement(Field, { validate: this.validate, ...rest })
110+
return React.createElement(Field, {
111+
validate: this.validate,
112+
ref: innerRef,
113+
...rest
114+
})
110115
}
111116
}
117+
118+
export default React.forwardRef((props, ref) => (
119+
React.createElement(Html5ValidationField, {
120+
innerRef: ref,
121+
...props
122+
})
123+
))

src/Html5ValidationField.test.js

Lines changed: 53 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,22 @@ describe('Html5ValidationField', () => {
7070
})
7171
})
7272

73+
it('should pass ref through to the input', () => {
74+
const ref = React.createRef()
75+
TestUtils.renderIntoDocument(
76+
<Form onSubmit={onSubmitMock} subscription={{ values: true }}>
77+
{() => (
78+
<form>
79+
<Html5ValidationField name="name" component="input" ref={ref} />
80+
</form>
81+
)}
82+
</Form>
83+
)
84+
85+
expect(ref.current).not.toBe(null)
86+
expect(ref.current instanceof HTMLInputElement).toBe(true)
87+
})
88+
7389
describe('Html5ValidationField.messages', () => {
7490
const testNotPassThrough = message => {
7591
const consoleSpy = jest
@@ -537,34 +553,43 @@ describe('Html5ValidationField', () => {
537553
}
538554
)
539555
})
540-
it('should support functions as default error keys', () => {
541-
const setCustomValidity = jest.fn()
542-
mockFindNode(
543-
{
544-
nodeName: 'input',
545-
setCustomValidity,
546-
validity: {
547-
tooShort: true
548-
}
549-
},
550-
() => {
551-
const spy = jest.fn(({ input }) => <input {...input} />)
552-
TestUtils.renderIntoDocument(
553-
<Form initialValues={{ foo: 'bar' }} onSubmit={onSubmitMock} subscription={{}}>
554-
{() =>
555-
<Html5ValidationField
556-
tooShort={(value, { minLength }) =>
557-
`Value ${value} should have at least ${minLength} characters.`}
558-
minLength={8} name="foo" render={spy} />
556+
it('should support functions as default error keys', () => {
557+
const setCustomValidity = jest.fn()
558+
mockFindNode(
559+
{
560+
nodeName: 'input',
561+
setCustomValidity,
562+
validity: {
563+
tooShort: true
564+
}
565+
},
566+
() => {
567+
const spy = jest.fn(({ input }) => <input {...input} />)
568+
TestUtils.renderIntoDocument(
569+
<Form
570+
initialValues={{ foo: 'bar' }}
571+
onSubmit={onSubmitMock}
572+
subscription={{}}
573+
>
574+
{() => (
575+
<Html5ValidationField
576+
tooShort={(value, { minLength }) =>
577+
`Value ${value} should have at least ${minLength} characters.`
559578
}
560-
</Form>
561-
)
562-
expect(spy).toHaveBeenCalled()
563-
expect(spy).toHaveBeenCalledTimes(2)
564-
expect(spy.mock.calls[1][0].meta.error).toBe('Value bar should have at least 8 characters.')
565-
}
566-
)
567-
})
579+
minLength={8}
580+
name="foo"
581+
render={spy}
582+
/>
583+
)}
584+
</Form>
585+
)
586+
expect(spy).toHaveBeenCalled()
587+
expect(spy).toHaveBeenCalledTimes(2)
588+
expect(spy.mock.calls[1][0].meta.error).toBe(
589+
'Value bar should have at least 8 characters.'
590+
)
591+
}
592+
)
593+
})
568594
})
569-
570595
})

0 commit comments

Comments
 (0)