@@ -6,10 +6,11 @@ import {
66 Keyboard ,
77} from 'react-native'
88
9- import { CalendarDate , ModeType } from './Calendar'
9+ import { CalendarDate , ModeType , ValidRangeType } from './Calendar'
1010import { LocalState } from './DatePickerModalContent'
1111import TextInputWithMask from '../TextInputMask'
12- import { Text , useTheme } from 'react-native-paper'
12+ import { HelperText , useTheme } from 'react-native-paper'
13+ import { dateToUnix , isDateWithinOptionalRange } from './dateUtils'
1314
1415function CalendarEdit ( {
1516 mode,
@@ -19,6 +20,7 @@ function CalendarEdit({
1920 endLabel = 'End' ,
2021 collapsed,
2122 onChange,
23+ validRange,
2224} : {
2325 mode : ModeType
2426 label ?: string
@@ -27,6 +29,7 @@ function CalendarEdit({
2729 state : LocalState
2830 collapsed : boolean
2931 onChange : ( s : LocalState ) => any
32+ validRange : ValidRangeType | undefined
3033} ) {
3134 const dateInput = React . useRef < TextInputNative | null > ( null )
3235 const startInput = React . useRef < TextInputNative | null > ( null )
@@ -80,6 +83,7 @@ function CalendarEdit({
8083 value = { state . date }
8184 onChange = { ( date ) => onChange ( { ...state , date } ) }
8285 onSubmitEditing = { onSubmitInput }
86+ validRange = { validRange }
8387 />
8488 ) : null }
8589 { mode === 'range' ? (
@@ -91,6 +95,7 @@ function CalendarEdit({
9195 onChange = { ( startDate ) => onChange ( { ...state , startDate } ) }
9296 returnKeyType = { 'next' }
9397 onSubmitEditing = { onSubmitStartInput }
98+ validRange = { validRange }
9499 />
95100 < View style = { styles . separator } />
96101 < CalendarInput
@@ -100,6 +105,7 @@ function CalendarEdit({
100105 onChange = { ( endDate ) => onChange ( { ...state , endDate } ) }
101106 isEndDate
102107 onSubmitEditing = { onSubmitEndInput }
108+ validRange = { validRange }
103109 />
104110 </ >
105111 ) : null }
@@ -117,6 +123,7 @@ function CalendarInputPure(
117123 returnKeyType,
118124 onSubmitEditing,
119125 locale,
126+ validRange,
120127 } : {
121128 locale ?: undefined | string
122129 label : string
@@ -125,11 +132,12 @@ function CalendarInputPure(
125132 isEndDate ?: boolean
126133 returnKeyType ?: string
127134 onSubmitEditing ?: ( ) => any
135+ validRange : ValidRangeType | undefined
128136 } ,
129137 ref : any
130138) {
131139 const theme = useTheme ( )
132- const [ error , setError ] = React . useState ( false )
140+ const [ error , setError ] = React . useState < null | string > ( null )
133141 const formatter = React . useMemo ( ( ) => {
134142 return new Intl . DateTimeFormat ( locale , {
135143 month : '2-digit' ,
@@ -156,15 +164,40 @@ function CalendarInputPure(
156164 const day = Number ( date . slice ( dayIndex , dayIndex + 2 ) )
157165 const year = Number ( date . slice ( yearIndex , yearIndex + 4 ) )
158166 const month = Number ( date . slice ( monthIndex , monthIndex + 2 ) )
159- if ( ! Number . isNaN ( day ) && ! Number . isNaN ( year ) && ! Number . isNaN ( month ) ) {
160- setError ( false )
161- if ( isEndDate ) {
162- onChange ( new Date ( year , month - 1 , day , 23 , 59 , 59 ) )
163- } else {
164- onChange ( new Date ( year , month - 1 , day ) )
165- }
167+
168+ if ( Number . isNaN ( day ) || Number . isNaN ( year ) || Number . isNaN ( month ) ) {
169+ setError ( inputFormat )
170+ return
171+ }
172+
173+ const finalDate = isEndDate
174+ ? new Date ( year , month - 1 , day , 23 , 59 , 59 )
175+ : new Date ( year , month - 1 , day )
176+
177+ const validStart = validRange ?. startDate
178+ const validEnd = validRange ?. endDate
179+ if (
180+ ! isDateWithinOptionalRange ( finalDate , {
181+ startUnix : validStart ? dateToUnix ( validStart ) : undefined ,
182+ endUnix : validEnd ? dateToUnix ( validEnd ) : undefined ,
183+ } )
184+ ) {
185+ let errors =
186+ validStart && validEnd
187+ ? [ `${ formatter . format ( validStart ) } - ${ formatter . format ( validEnd ) } ` ]
188+ : [
189+ validStart ? `> ${ formatter . format ( validStart ) } ` : '' ,
190+ validEnd ? `< ${ formatter . format ( validEnd ) } ` : '' ,
191+ ]
192+ setError ( errors . filter ( ( n ) => n ) . join ( ' ' ) )
193+ return
194+ }
195+
196+ setError ( null )
197+ if ( isEndDate ) {
198+ onChange ( finalDate )
166199 } else {
167- setError ( true )
200+ onChange ( finalDate )
168201 }
169202 }
170203 return (
@@ -181,20 +214,11 @@ function CalendarInputPure(
181214 returnKeyType = { returnKeyType }
182215 onSubmitEditing = { onSubmitEditing }
183216 keyboardAppearance = { theme . dark ? 'dark' : 'default' }
217+ error = { ! ! error }
184218 />
185- { error && (
186- < Text
187- style = { [
188- {
189- color : theme . colors . error ,
190- } ,
191- theme . fonts . medium ,
192- styles . errorText ,
193- ] }
194- >
195- { inputFormat }
196- </ Text >
197- ) }
219+ < HelperText type = "error" visible = { ! ! error } >
220+ { error }
221+ </ HelperText >
198222 </ View >
199223 )
200224}
@@ -207,10 +231,6 @@ const styles = StyleSheet.create({
207231 inputContainer : { flex : 1 } ,
208232 input : { flex : 1 } ,
209233 separator : { width : 12 } ,
210- errorText : {
211- textAlign : 'right' ,
212- marginTop : 12 ,
213- } ,
214234} )
215235
216236export default React . memo ( CalendarEdit )
0 commit comments