1
1
import React , { Component } from 'react' ;
2
- import {
3
- Text ,
4
- View ,
5
- Dimensions ,
6
- Animated ,
7
- ViewPropTypes ,
8
- } from 'react-native' ;
2
+ import { Text , View , Dimensions , Animated , ViewPropTypes } from 'react-native' ;
9
3
import PropTypes from 'prop-types' ;
10
4
import XDate from 'xdate' ;
11
5
@@ -14,91 +8,94 @@ import dateutils from '../dateutils';
14
8
import CalendarList from '../calendar-list' ;
15
9
import ReservationsList from './reservation-list' ;
16
10
import styleConstructor from './style' ;
17
- import { VelocityTracker } from '../input' ;
11
+ import { VelocityTracker } from '../input' ;
12
+
18
13
19
14
const HEADER_HEIGHT = 104 ;
20
15
const KNOB_HEIGHT = 24 ;
21
-
22
16
//Fallback when RN version is < 0.44
23
17
const viewPropTypes = ViewPropTypes || View . propTypes ;
24
18
19
+ /**
20
+ * @description : Agenda component
21
+ * @extends : CalendarList
22
+ * @extendslink : docs/CalendarList
23
+ * @example : https://github.com/wix/react-native-calendars/blob/master/example/src/screens/agenda.js
24
+ * @gif : https://github.com/wix/react-native-calendars/blob/master/demo/agenda.gif
25
+ */
25
26
export default class AgendaView extends Component {
27
+ static displayName = 'Agenda' ;
28
+
26
29
static propTypes = {
27
- // Specify theme properties to override specific styles for calendar parts. Default = {}
30
+ /** Specify theme properties to override specific styles for calendar parts. Default = {} */
28
31
theme : PropTypes . object ,
29
-
30
- // agenda container style
32
+ /** agenda container style */
31
33
style : viewPropTypes . style ,
32
-
33
- // the list of items that have to be displayed in agenda. If you want to render item as empty date
34
- // the value of date key has to be an empty array []. If there exists no value for date key it is
35
- // considered that the date in question is not yet loaded
34
+ /** the list of items that have to be displayed in agenda. If you want to render item as empty date
35
+ the value of date key has to be an empty array []. If there exists no value for date key it is
36
+ considered that the date in question is not yet loaded */
36
37
items : PropTypes . object ,
37
-
38
- // callback that gets called when items for a certain month should be loaded (month became visible)
38
+ /** callback that gets called when items for a certain month should be loaded (month became visible) */
39
39
loadItemsForMonth : PropTypes . func ,
40
- // callback that fires when the calendar is opened or closed
40
+ /** callback that fires when the calendar is opened or closed */
41
41
onCalendarToggled : PropTypes . func ,
42
- // callback that gets called on day press
42
+ /** callback that gets called on day press */
43
43
onDayPress : PropTypes . func ,
44
- // callback that gets called when day changes while scrolling agenda list
44
+ /** callback that gets called when day changes while scrolling agenda list */
45
45
onDaychange : PropTypes . func ,
46
- // specify how each item should be rendered in agenda
46
+ /** specify how each item should be rendered in agenda */
47
47
renderItem : PropTypes . func ,
48
- // specify how each date should be rendered. day can be undefined if the item is not first in that day.
48
+ /** specify how each date should be rendered. day can be undefined if the item is not first in that day. */
49
49
renderDay : PropTypes . func ,
50
- // specify how agenda knob should look like
50
+ /** specify how agenda knob should look like */
51
51
renderKnob : PropTypes . func ,
52
- // specify how empty date content with no items should be rendered
52
+ /** specify how empty date content with no items should be rendered */
53
53
renderEmptyDay : PropTypes . func ,
54
- // specify what should be rendered instead of ActivityIndicator
54
+ /** specify what should be rendered instead of ActivityIndicator */
55
55
renderEmptyData : PropTypes . func ,
56
- // specify your item comparison function for increased performance
56
+ /** specify your item comparison function for increased performance */
57
57
rowHasChanged : PropTypes . func ,
58
-
59
- // Max amount of months allowed to scroll to the past. Default = 50
58
+ /** Max amount of months allowed to scroll to the past. Default = 50 */
60
59
pastScrollRange : PropTypes . number ,
61
-
62
- // Max amount of months allowed to scroll to the future. Default = 50
60
+ /** Max amount of months allowed to scroll to the future. Default = 50 */
63
61
futureScrollRange : PropTypes . number ,
64
-
65
- // initially selected day
62
+ /** initially selected day */
66
63
selected : PropTypes . any ,
67
- // Minimum date that can be selected, dates before minDate will be grayed out. Default = undefined
64
+ /** Minimum date that can be selected, dates before minDate will be grayed out. Default = undefined */
68
65
minDate : PropTypes . any ,
69
- // Maximum date that can be selected, dates after maxDate will be grayed out. Default = undefined
66
+ /** Maximum date that can be selected, dates after maxDate will be grayed out. Default = undefined */
70
67
maxDate : PropTypes . any ,
71
-
72
- // If firstDay=1 week starts from Monday. Note that dayNames and dayNamesShort should still start from Sunday.
68
+ /** If firstDay=1 week starts from Monday. Note that dayNames and dayNamesShort should still start from Sunday. */
73
69
firstDay : PropTypes . number ,
74
-
75
- // Collection of dates that have to be marked. Default = items
70
+ /** Collection of dates that have to be marked. Default = items */
76
71
markedDates : PropTypes . object ,
77
- // Optional marking type if custom markedDates are provided
78
- markingType : PropTypes . string ,
79
-
80
- // Hide knob button. Default = false
72
+ /** Optional marking type if custom markedDates are provided */
73
+ markingType : PropTypes . string , /*
74
+ /** Hide knob button. Default = false */
81
75
hideKnob : PropTypes . bool ,
82
- // Month format in calendar title. Formatting values: http://arshaw.com/xdate/#Formatting
76
+ /** Month format in calendar title. Formatting values: http://arshaw.com/xdate/#Formatting */
83
77
monthFormat : PropTypes . string ,
84
- // A RefreshControl component, used to provide pull-to-refresh functionality for the ScrollView.
78
+ /** A RefreshControl component, used to provide pull-to-refresh functionality for the ScrollView. */
85
79
refreshControl : PropTypes . element ,
86
- // If provided, a standard RefreshControl will be added for "Pull to Refresh" functionality. Make sure to also set the refreshing prop correctly.
80
+ /** If provided, a standard RefreshControl will be added for "Pull to Refresh" functionality. Make sure to also set the refreshing prop correctly. */
87
81
onRefresh : PropTypes . func ,
88
- // Set this true while waiting for new data from a refresh.
82
+ /** Set this true while waiting for new data from a refresh. */
89
83
refreshing : PropTypes . bool ,
90
- // Display loading indicador. Default = false
91
- displayLoadingIndicator : PropTypes . bool ,
84
+ /** Display loading indicador. Default = false */
85
+ displayLoadingIndicator : PropTypes . bool
92
86
} ;
93
87
94
88
constructor ( props ) {
95
89
super ( props ) ;
90
+
96
91
this . styles = styleConstructor ( props . theme ) ;
92
+
97
93
const windowSize = Dimensions . get ( 'window' ) ;
98
94
this . viewHeight = windowSize . height ;
99
95
this . viewWidth = windowSize . width ;
100
96
this . scrollTimeout = undefined ;
101
97
this . headerState = 'idle' ;
98
+
102
99
this . state = {
103
100
scrollY : new Animated . Value ( 0 ) ,
104
101
calendarIsReady : false ,
@@ -107,6 +104,7 @@ export default class AgendaView extends Component {
107
104
selectedDay : parseDate ( this . props . selected ) || XDate ( true ) ,
108
105
topDay : parseDate ( this . props . selected ) || XDate ( true ) ,
109
106
} ;
107
+
110
108
this . currentMonth = this . state . selectedDay . clone ( ) ;
111
109
this . onLayout = this . onLayout . bind ( this ) ;
112
110
this . onScrollPadLayout = this . onScrollPadLayout . bind ( this ) ;
@@ -149,19 +147,20 @@ export default class AgendaView extends Component {
149
147
onTouchStart ( ) {
150
148
this . headerState = 'touched' ;
151
149
if ( this . knob ) {
152
- this . knob . setNativeProps ( { style : { opacity : 0.5 } } ) ;
150
+ this . knob . setNativeProps ( { style : { opacity : 0.5 } } ) ;
153
151
}
154
152
}
155
153
156
154
onTouchEnd ( ) {
157
155
if ( this . knob ) {
158
- this . knob . setNativeProps ( { style : { opacity : 1 } } ) ;
156
+ this . knob . setNativeProps ( { style : { opacity : 1 } } ) ;
159
157
}
160
158
161
159
if ( this . headerState === 'touched' ) {
162
160
this . setScrollPadPosition ( 0 , true ) ;
163
161
this . enableCalendarScrolling ( ) ;
164
162
}
163
+
165
164
this . headerState = 'idle' ;
166
165
}
167
166
@@ -179,6 +178,7 @@ export default class AgendaView extends Component {
179
178
const maxY = this . initialScrollPadPosition ( ) ;
180
179
const snapY = ( projectedY > maxY / 2 ) ? maxY : 0 ;
181
180
this . setScrollPadPosition ( snapY , true ) ;
181
+
182
182
if ( snapY === 0 ) {
183
183
this . enableCalendarScrolling ( ) ;
184
184
}
@@ -230,6 +230,7 @@ export default class AgendaView extends Component {
230
230
this . setState ( {
231
231
calendarScrollable : true
232
232
} ) ;
233
+
233
234
if ( this . props . onCalendarToggled ) {
234
235
this . props . onCalendarToggled ( true ) ;
235
236
}
@@ -250,23 +251,29 @@ export default class AgendaView extends Component {
250
251
251
252
chooseDay ( d , optimisticScroll ) {
252
253
const day = parseDate ( d ) ;
254
+
253
255
this . setState ( {
254
256
calendarScrollable : false ,
255
257
selectedDay : day . clone ( )
256
258
} ) ;
259
+
257
260
if ( this . props . onCalendarToggled ) {
258
261
this . props . onCalendarToggled ( false ) ;
259
262
}
263
+
260
264
if ( ! optimisticScroll ) {
261
265
this . setState ( {
262
266
topDay : day . clone ( )
263
267
} ) ;
264
268
}
269
+
265
270
this . setScrollPadPosition ( this . initialScrollPadPosition ( ) , true ) ;
266
271
this . calendar . scrollToDay ( day , this . calendarOffset ( ) , true ) ;
272
+
267
273
if ( this . props . loadItemsForMonth ) {
268
274
this . props . loadItemsForMonth ( xdateToData ( day ) ) ;
269
275
}
276
+
270
277
if ( this . props . onDayPress ) {
271
278
this . props . onDayPress ( xdateToData ( day ) ) ;
272
279
}
@@ -297,6 +304,7 @@ export default class AgendaView extends Component {
297
304
onDayChange ( day ) {
298
305
const newDate = parseDate ( day ) ;
299
306
const withAnimation = dateutils . sameMonth ( newDate , this . state . selectedDay ) ;
307
+
300
308
this . calendar . scrollToDay ( day , this . calendarOffset ( ) , withAnimation ) ;
301
309
this . setState ( {
302
310
selectedDay : parseDate ( day )
@@ -309,6 +317,7 @@ export default class AgendaView extends Component {
309
317
310
318
generateMarkings ( ) {
311
319
let markings = this . props . markedDates ;
320
+
312
321
if ( ! markings ) {
313
322
markings = { } ;
314
323
Object . keys ( this . props . items || { } ) . forEach ( key => {
@@ -317,41 +326,43 @@ export default class AgendaView extends Component {
317
326
}
318
327
} ) ;
319
328
}
329
+
320
330
const key = this . state . selectedDay . toString ( 'yyyy-MM-dd' ) ;
321
331
return { ...markings , [ key ] : { ...( markings [ key ] || { } ) , ...{ selected : true } } } ;
322
332
}
323
333
324
334
render ( ) {
325
335
const agendaHeight = Math . max ( 0 , this . viewHeight - HEADER_HEIGHT ) ;
326
336
const weekDaysNames = dateutils . weekDayNames ( this . props . firstDay ) ;
337
+
327
338
const weekdaysStyle = [ this . styles . weekdays , {
328
339
opacity : this . state . scrollY . interpolate ( {
329
340
inputRange : [ agendaHeight - HEADER_HEIGHT , agendaHeight ] ,
330
341
outputRange : [ 0 , 1 ] ,
331
- extrapolate : 'clamp' ,
342
+ extrapolate : 'clamp'
332
343
} ) ,
333
344
transform : [ { translateY : this . state . scrollY . interpolate ( {
334
345
inputRange : [ Math . max ( 0 , agendaHeight - HEADER_HEIGHT ) , agendaHeight ] ,
335
346
outputRange : [ - HEADER_HEIGHT , 0 ] ,
336
- extrapolate : 'clamp' ,
347
+ extrapolate : 'clamp'
337
348
} ) } ]
338
349
} ] ;
339
350
340
351
const headerTranslate = this . state . scrollY . interpolate ( {
341
352
inputRange : [ 0 , agendaHeight ] ,
342
353
outputRange : [ agendaHeight , 0 ] ,
343
- extrapolate : 'clamp' ,
354
+ extrapolate : 'clamp'
344
355
} ) ;
345
356
346
357
const contentTranslate = this . state . scrollY . interpolate ( {
347
358
inputRange : [ 0 , agendaHeight ] ,
348
359
outputRange : [ 0 , agendaHeight / 2 ] ,
349
- extrapolate : 'clamp' ,
360
+ extrapolate : 'clamp'
350
361
} ) ;
351
362
352
363
const headerStyle = [
353
364
this . styles . header ,
354
- { bottom : agendaHeight , transform : [ { translateY : headerTranslate } ] } ,
365
+ { bottom : agendaHeight , transform : [ { translateY : headerTranslate } ] }
355
366
] ;
356
367
357
368
if ( ! this . state . calendarIsReady ) {
@@ -369,7 +380,7 @@ export default class AgendaView extends Component {
369
380
width : 80 ,
370
381
height : KNOB_HEIGHT ,
371
382
top : scrollPadPosition ,
372
- left : ( this . viewWidth - 80 ) / 2 ,
383
+ left : ( this . viewWidth - 80 ) / 2
373
384
} ;
374
385
375
386
let knob = ( < View style = { this . styles . knobContainer } /> ) ;
@@ -389,7 +400,7 @@ export default class AgendaView extends Component {
389
400
{ this . renderReservations ( ) }
390
401
</ View >
391
402
< Animated . View style = { headerStyle } >
392
- < Animated . View style = { { flex :1 , transform : [ { translateY : contentTranslate } ] } } >
403
+ < Animated . View style = { { flex :1 , transform : [ { translateY : contentTranslate } ] } } >
393
404
< CalendarList
394
405
onLayout = { ( ) => {
395
406
this . calendar . scrollToDay ( this . state . selectedDay . clone ( ) , this . calendarOffset ( ) , false ) ;
@@ -438,11 +449,11 @@ export default class AgendaView extends Component {
438
449
onScrollBeginDrag = { this . onStartDrag }
439
450
onScrollEndDrag = { this . onSnapAfterDrag }
440
451
onScroll = { Animated . event (
441
- [ { nativeEvent : { contentOffset : { y : this . state . scrollY } } } ] ,
442
- { useNativeDriver : true } ,
452
+ [ { nativeEvent : { contentOffset : { y : this . state . scrollY } } } ] ,
453
+ { useNativeDriver : true } ,
443
454
) }
444
455
>
445
- < View style = { { height : agendaHeight + KNOB_HEIGHT } } onLayout = { this . onScrollPadLayout } />
456
+ < View style = { { height : agendaHeight + KNOB_HEIGHT } } onLayout = { this . onScrollPadLayout } />
446
457
</ Animated . ScrollView >
447
458
</ View >
448
459
) ;
0 commit comments