11import * as React from 'react' ;
22
3- import { StyleSheet , View } from 'react-native' ;
3+ import { Platform , ScrollView , StyleSheet , View } from 'react-native' ;
44import { Form , useFormState } from '../../src/index' ;
5- import { Button , Surface , TextInput , Title } from 'react-native-paper' ;
5+ import { Appbar , Button , Surface , Title } from 'react-native-paper' ;
66import TextInputWithError from './TextInputWithError' ;
7+ import { useRef } from 'react' ;
78
89type AddressCompany = {
910 name : string ;
@@ -28,10 +29,8 @@ type FormType = {
2829 address ?: AddressType | null ;
2930} ;
3031export default function App ( ) {
31- const [
32- { values, errors, submit, formProps, hasError } ,
33- fh ,
34- ] = useFormState < FormType > (
32+ const scrollViewRef = useRef < ScrollView > ( null ) ;
33+ const [ { submit, formProps, hasError } , fh ] = useFormState < FormType > (
3534 {
3635 email : '' ,
3736 telephone : '' ,
@@ -46,6 +45,7 @@ export default function App() {
4645 } ,
4746 } ,
4847 {
48+ scrollViewRef : scrollViewRef ,
4949 onChange : ( ) => {
5050 // TODO: fix enum in backend
5151 } ,
@@ -56,99 +56,106 @@ export default function App() {
5656 }
5757 ) ;
5858
59- console . log ( { values, errors } ) ;
59+ // console.log({ values, errors });
6060 return (
6161 < View style = { styles . root } >
62- < Form { ...formProps } >
63- < TextInputWithError
64- mode = "outlined"
65- error = { hasError ( 'email' ) }
66- { ...fh . email ( 'email' , {
67- validate : ( v ) => {
68- return looksLikeMail ( v ) ? true : 'Email-address is invalid' ;
69- } ,
70- label : 'Email' ,
71- } ) }
72- />
73- < TextInputWithError
74- mode = "outlined"
75- { ...fh . telephone ( 'telephone' , {
76- required : true ,
77- minLength : 3 ,
78- maxLength : 10 ,
79- shouldFollowRegexes : [ telephoneRegex ] ,
80- label : 'Telephone' ,
81- } ) }
82- />
83- < TextInputWithError
84- mode = "outlined"
85- { ...fh . text ( 'postalCode' , {
86- enhance : ( v ) => {
87- return ( v || '' ) . toUpperCase ( ) ;
88- } ,
89- label : 'Postalcode' ,
90- } ) }
91- />
62+ < Appbar . Header >
63+ < Appbar . Content title = "Form" />
64+ </ Appbar . Header >
65+ < ScrollView style = { styles . scrollView } ref = { scrollViewRef } >
66+ < View style = { styles . inner } >
67+ < Form { ...formProps } >
68+ < TextInputWithError
69+ mode = "outlined"
70+ error = { hasError ( 'email' ) }
71+ { ...fh . email ( 'email' , {
72+ validate : ( v ) => {
73+ return looksLikeMail ( v ) ? true : 'Email-address is invalid' ;
74+ } ,
75+ label : 'Email' ,
76+ } ) }
77+ />
78+ < TextInputWithError
79+ mode = "outlined"
80+ { ...fh . telephone ( 'telephone' , {
81+ required : true ,
82+ minLength : 3 ,
83+ maxLength : 10 ,
84+ shouldFollowRegexes : [ telephoneRegex ] ,
85+ label : 'Telephone' ,
86+ } ) }
87+ />
88+ < TextInputWithError
89+ mode = "outlined"
90+ { ...fh . text ( 'postalCode' , {
91+ enhance : ( v ) => {
92+ return ( v || '' ) . toUpperCase ( ) ;
93+ } ,
94+ label : 'Postalcode' ,
95+ } ) }
96+ />
9297
93- < TextInputWithError
94- mode = "outlined"
95- { ...fh . password ( 'password' , {
96- required : true ,
97- minLength : 3 ,
98- maxLength : 10 ,
99- label : 'Password' ,
100- } ) }
101- />
98+ < TextInputWithError
99+ mode = "outlined"
100+ { ...fh . password ( 'password' , {
101+ required : true ,
102+ minLength : 3 ,
103+ maxLength : 10 ,
104+ label : 'Password' ,
105+ } ) }
106+ />
102107
103- < TextInputWithError
104- mode = "outlined"
105- { ...fh . number ( 'age' , {
106- required : true ,
107- minLength : 3 ,
108- maxLength : 10 ,
109- label : 'Age' ,
110- } ) }
111- />
112- < TextInputWithError
113- mode = "outlined"
114- { ...fh . decimal ( 'money' , {
115- required : true ,
116- minLength : 3 ,
117- maxLength : 10 ,
118- label : 'Money bank account' ,
119- } ) }
120- />
121- < TextInputWithError
122- mode = "outlined"
123- { ...fh . text ( 'organization.telephone' , {
124- required : true ,
125- minLength : 3 ,
126- maxLength : 10 ,
127- shouldFollowRegexes : [ telephoneRegex ] ,
128- label : 'Organization telephone' ,
129- } ) }
130- />
131- < TextInputWithError
132- mode = "outlined"
133- { ...fh . number ( 'organization.revenue' , {
134- required : true ,
135- minLength : 3 ,
136- maxLength : 10 ,
137- validate : ( v ) => {
138- if ( v < 10 ) {
139- return 'revenue too low' ;
140- }
141- return undefined ;
142- } ,
143- label : 'Organization revenue' ,
144- } ) }
145- />
146- < AddressEdit { ...fh . raw ( 'address' ) } />
147- < AddressCompanyEdit { ...fh . raw ( 'address.company' ) } />
148- < Button mode = "contained" onPress = { submit } style = { { marginTop : 24 } } >
149- Save
150- </ Button >
151- </ Form >
108+ < TextInputWithError
109+ mode = "outlined"
110+ { ...fh . number ( 'age' , {
111+ required : true ,
112+ minLength : 3 ,
113+ maxLength : 10 ,
114+ label : 'Age' ,
115+ } ) }
116+ />
117+ < TextInputWithError
118+ mode = "outlined"
119+ { ...fh . decimal ( 'money' , {
120+ required : true ,
121+ minLength : 3 ,
122+ maxLength : 10 ,
123+ label : 'Money bank account' ,
124+ } ) }
125+ />
126+ < TextInputWithError
127+ mode = "outlined"
128+ { ...fh . text ( 'organization.telephone' , {
129+ required : true ,
130+ minLength : 3 ,
131+ maxLength : 10 ,
132+ shouldFollowRegexes : [ telephoneRegex ] ,
133+ label : 'Organization telephone' ,
134+ } ) }
135+ />
136+ < TextInputWithError
137+ mode = "outlined"
138+ { ...fh . number ( 'organization.revenue' , {
139+ required : true ,
140+ minLength : 3 ,
141+ maxLength : 10 ,
142+ validate : ( v ) => {
143+ if ( v < 10 ) {
144+ return 'revenue too low' ;
145+ }
146+ return undefined ;
147+ } ,
148+ label : 'Organization revenue' ,
149+ } ) }
150+ />
151+ < AddressEdit { ...fh . raw ( 'address' ) } />
152+ < AddressCompanyEdit { ...fh . raw ( 'address.company' ) } />
153+ < Button mode = "contained" onPress = { submit } style = { { marginTop : 24 } } >
154+ Save
155+ </ Button >
156+ </ Form >
157+ </ View >
158+ </ ScrollView >
152159 </ View >
153160 ) ;
154161}
@@ -171,12 +178,12 @@ function AddressEdit({
171178 < Surface { ...rest } >
172179 < Title > Nested form</ Title >
173180 < Form { ...formProps } >
174- < TextInput
181+ < TextInputWithError
175182 mode = "outlined"
176183 label = "Street"
177184 { ...fh . streetAddress ( 'street' , { required : true } ) }
178185 />
179- < TextInput
186+ < TextInputWithError
180187 mode = "outlined"
181188 label = "House number"
182189 { ...fh . streetAddress ( 'houseNumber' ) }
@@ -204,7 +211,11 @@ function AddressCompanyEdit({
204211 < Surface { ...rest } style = { { padding : 12 } } >
205212 < Title > Nested form</ Title >
206213 < Form { ...formProps } >
207- < TextInput mode = "outlined" label = "Street" { ...fh . text ( 'name' ) } />
214+ < TextInputWithError
215+ mode = "outlined"
216+ label = "Street"
217+ { ...fh . text ( 'name' ) }
218+ />
208219 </ Form >
209220 </ Surface >
210221 ) ;
@@ -228,8 +239,11 @@ function looksLikeMail(str: string): boolean {
228239}
229240
230241const styles = StyleSheet . create ( {
231- root : {
242+ root : { flex : 1 , maxHeight : Platform . OS === 'web' ? '100vh' : undefined } ,
243+ scrollView : {
232244 flex : 1 ,
245+ } ,
246+ inner : {
233247 marginTop : 100 ,
234248 marginLeft : 12 ,
235249 marginRight : 12 ,
0 commit comments