react-native-paper-dates 0.22.43 → 0.22.44

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/lib/commonjs/Date/Calendar.js +8 -4
  2. package/lib/commonjs/Date/Calendar.js.map +1 -1
  3. package/lib/commonjs/Date/DatePickerInput.js +3 -2
  4. package/lib/commonjs/Date/DatePickerInput.js.map +1 -1
  5. package/lib/commonjs/Date/Month.js +49 -40
  6. package/lib/commonjs/Date/Month.js.map +1 -1
  7. package/lib/commonjs/Date/Swiper.js +41 -12
  8. package/lib/commonjs/Date/Swiper.js.map +1 -1
  9. package/lib/commonjs/Date/Swiper.native.js +32 -15
  10. package/lib/commonjs/Date/Swiper.native.js.map +1 -1
  11. package/lib/commonjs/Date/SwiperUtils.js +49 -6
  12. package/lib/commonjs/Date/SwiperUtils.js.map +1 -1
  13. package/lib/commonjs/Date/YearPicker.js +2 -1
  14. package/lib/commonjs/Date/YearPicker.js.map +1 -1
  15. package/lib/commonjs/Date/dateUtils.js +47 -11
  16. package/lib/commonjs/Date/dateUtils.js.map +1 -1
  17. package/lib/module/Date/Calendar.js +9 -4
  18. package/lib/module/Date/Calendar.js.map +1 -1
  19. package/lib/module/Date/DatePickerInput.js +3 -2
  20. package/lib/module/Date/DatePickerInput.js.map +1 -1
  21. package/lib/module/Date/Month.js +50 -41
  22. package/lib/module/Date/Month.js.map +1 -1
  23. package/lib/module/Date/Swiper.js +42 -13
  24. package/lib/module/Date/Swiper.js.map +1 -1
  25. package/lib/module/Date/Swiper.native.js +34 -17
  26. package/lib/module/Date/Swiper.native.js.map +1 -1
  27. package/lib/module/Date/SwiperUtils.js +48 -7
  28. package/lib/module/Date/SwiperUtils.js.map +1 -1
  29. package/lib/module/Date/YearPicker.js +2 -1
  30. package/lib/module/Date/YearPicker.js.map +1 -1
  31. package/lib/module/Date/dateUtils.js +42 -10
  32. package/lib/module/Date/dateUtils.js.map +1 -1
  33. package/lib/typescript/Date/Calendar.d.ts.map +1 -1
  34. package/lib/typescript/Date/DatePickerInput.d.ts.map +1 -1
  35. package/lib/typescript/Date/Month.d.ts +6 -4
  36. package/lib/typescript/Date/Month.d.ts.map +1 -1
  37. package/lib/typescript/Date/Swiper.d.ts +1 -1
  38. package/lib/typescript/Date/Swiper.d.ts.map +1 -1
  39. package/lib/typescript/Date/Swiper.native.d.ts.map +1 -1
  40. package/lib/typescript/Date/SwiperUtils.d.ts +8 -1
  41. package/lib/typescript/Date/SwiperUtils.d.ts.map +1 -1
  42. package/lib/typescript/Date/YearPicker.d.ts.map +1 -1
  43. package/lib/typescript/Date/dateUtils.d.ts +10 -4
  44. package/lib/typescript/Date/dateUtils.d.ts.map +1 -1
  45. package/package.json +3 -2
  46. package/src/Date/Calendar.tsx +8 -3
  47. package/src/Date/DatePickerInput.tsx +3 -2
  48. package/src/Date/Month.tsx +210 -152
  49. package/src/Date/Swiper.native.tsx +60 -16
  50. package/src/Date/Swiper.tsx +57 -9
  51. package/src/Date/SwiperUtils.ts +63 -6
  52. package/src/Date/YearPicker.tsx +3 -3
  53. package/src/Date/dateUtils.tsx +61 -10
@@ -11,18 +11,18 @@ import Day, { EmptyDay } from './Day'
11
11
  import {
12
12
  addMonths,
13
13
  areDatesOnSameDay,
14
- beginOffset,
15
14
  daySize,
16
- DisableWeekDaysType,
17
15
  estimatedMonthHeight,
18
- getDaysInMonth,
19
16
  getFirstDayOfMonth,
20
17
  getGridCount,
21
18
  getRealIndex,
22
- gridCounts,
19
+ getStartAtIndex,
20
+ getTotalMonths,
21
+ createGridCounts,
22
+ DisableWeekDaysType,
23
+ getDaysInMonth,
23
24
  isDateBetween,
24
25
  showWeekDay,
25
- startAtIndex,
26
26
  useRangeChecker,
27
27
  } from './dateUtils'
28
28
  import { getCalendarHeaderHeight } from './CalendarHeader'
@@ -51,6 +51,8 @@ interface BaseMonthProps {
51
51
  roundness: number
52
52
  validRange?: ValidRangeType
53
53
  startWeekOnMonday: boolean
54
+ startYear?: number
55
+ endYear?: number
54
56
  // some of these should be required in final implementation
55
57
  startDate?: CalendarDate
56
58
  endDate?: CalendarDate
@@ -76,29 +78,31 @@ interface MonthMultiProps extends BaseMonthProps {
76
78
 
77
79
  function Month(props: MonthSingleProps | MonthRangeProps | MonthMultiProps) {
78
80
  const {
79
- index,
81
+ locale,
80
82
  mode,
81
- date,
82
- dates,
83
- startDate,
84
- endDate,
83
+ index,
85
84
  onPressYear,
86
85
  selectingYear,
87
86
  onPressDate,
88
- scrollMode,
89
87
  primaryColor,
90
88
  selectColor,
91
89
  roundness,
92
- disableWeekDays,
93
- locale,
94
90
  validRange,
91
+ disableWeekDays,
92
+ scrollMode,
93
+ startDate,
94
+ endDate,
95
+ date,
96
+ dates,
95
97
  startWeekOnMonday,
98
+ startYear,
99
+ endYear,
96
100
  } = props
97
101
  const isHorizontal = scrollMode === 'horizontal'
98
102
 
99
103
  const theme = useTheme()
100
104
  const textColorOnPrimary = useTextColorOnPrimary()
101
- const realIndex = getRealIndex(index)
105
+ const realIndex = getRealIndex(index, startYear, endYear)
102
106
  const { isDisabled, isWithinValidRange } = useRangeChecker(validRange)
103
107
 
104
108
  const { monthName, month, year } = useMemo(() => {
@@ -118,129 +122,131 @@ function Month(props: MonthSingleProps | MonthRangeProps | MonthMultiProps) {
118
122
  const dayOfWeek = getFirstDayOfMonth({ year, month, startWeekOnMonday })
119
123
  const emptyDays = dayOfWeek
120
124
 
121
- return monthGrid(index, startWeekOnMonday).map(({ days, weekGrid }) => {
122
- return {
123
- weekIndex: weekGrid,
124
- generatedDays: days.map((_, dayIndex) => {
125
- const isFirstWeek = weekGrid === 0
126
- const realDayIndex = emptyDays - dayIndex
127
- const beforeWeekDay = isFirstWeek && realDayIndex > 0
128
- const dayOfMonth = weekGrid * 7 + dayIndex - emptyDays + 1
129
- const afterWeekDay = dayOfMonth > daysInMonth
130
-
131
- const day = new Date(year, month, dayOfMonth)
132
- const isToday = areDatesOnSameDay(day, today)
133
-
134
- let inRange = false
135
- let disabled = isDisabled(day)
136
- let selected = false
137
-
138
- let leftCrop = dayOfMonth === 1
139
- let rightCrop = dayOfMonth === daysInMonth
140
-
141
- const isFirstDayOfMonth = dayOfMonth === 1
142
- const isLastDayOfMonth = dayOfMonth === daysInMonth
143
-
144
- if (mode === 'range') {
145
- const selectedStartDay = areDatesOnSameDay(day, startDate)
146
- const selectedEndDay = areDatesOnSameDay(day, endDate)
147
- selected = selectedStartDay || selectedEndDay
148
- inRange = isDateBetween(day, {
149
- startDate,
150
- endDate,
151
- })
152
- if (selectedStartDay) {
153
- leftCrop = true
154
- }
155
- if (selectedEndDay) {
156
- rightCrop = true
157
- }
158
- if (dayIndex === 0 && !selectedStartDay) {
159
- leftCrop = false
160
- }
161
-
162
- if (dayIndex === 6 && !selectedEndDay) {
163
- rightCrop = false
164
- }
165
-
166
- if (
167
- (isFirstDayOfMonth && selectedEndDay) ||
168
- (isLastDayOfMonth && selectedStartDay)
169
- ) {
170
- inRange = false
171
- }
172
- } else if (mode === 'multiple') {
173
- const safeDates = dates || []
174
- selected = safeDates.some((d) => areDatesOnSameDay(day, d))
175
-
176
- const yesterday = new Date(year, month, dayOfMonth - 1)
177
- const tomorrow = new Date(year, month, dayOfMonth + 1)
178
-
179
- const yesterdaySelected = safeDates.some((d) =>
180
- areDatesOnSameDay(d, yesterday)
181
- )
182
- const tomorrowSelected = safeDates.some((d) =>
183
- areDatesOnSameDay(d, tomorrow)
184
- )
185
-
186
- if (selected) {
187
- if (tomorrowSelected && yesterdaySelected) {
188
- inRange = true
189
- }
190
- if (tomorrowSelected && !yesterdaySelected) {
191
- inRange = true
125
+ return monthGrid(index, startWeekOnMonday, startYear, endYear).map(
126
+ ({ days, weekGrid }) => {
127
+ return {
128
+ weekIndex: weekGrid,
129
+ generatedDays: days.map((_, dayIndex) => {
130
+ const isFirstWeek = weekGrid === 0
131
+ const realDayIndex = emptyDays - dayIndex
132
+ const beforeWeekDay = isFirstWeek && realDayIndex > 0
133
+ const dayOfMonth = weekGrid * 7 + dayIndex - emptyDays + 1
134
+ const afterWeekDay = dayOfMonth > daysInMonth
135
+
136
+ const day = new Date(year, month, dayOfMonth)
137
+ const isToday = areDatesOnSameDay(day, today)
138
+
139
+ let inRange = false
140
+ let disabled = isDisabled(day)
141
+ let selected = false
142
+
143
+ let leftCrop = dayOfMonth === 1
144
+ let rightCrop = dayOfMonth === daysInMonth
145
+
146
+ const isFirstDayOfMonth = dayOfMonth === 1
147
+ const isLastDayOfMonth = dayOfMonth === daysInMonth
148
+
149
+ if (mode === 'range') {
150
+ const selectedStartDay = areDatesOnSameDay(day, startDate)
151
+ const selectedEndDay = areDatesOnSameDay(day, endDate)
152
+ selected = selectedStartDay || selectedEndDay
153
+ inRange = isDateBetween(day, {
154
+ startDate,
155
+ endDate,
156
+ })
157
+ if (selectedStartDay) {
192
158
  leftCrop = true
193
159
  }
194
-
195
- if (yesterdaySelected && !tomorrowSelected) {
196
- inRange = true
160
+ if (selectedEndDay) {
197
161
  rightCrop = true
198
162
  }
163
+ if (dayIndex === 0 && !selectedStartDay) {
164
+ leftCrop = false
165
+ }
199
166
 
200
- if (isFirstDayOfMonth && !tomorrowSelected) {
201
- inRange = false
167
+ if (dayIndex === 6 && !selectedEndDay) {
168
+ rightCrop = false
202
169
  }
203
170
 
204
- if (isLastDayOfMonth && !yesterdaySelected) {
171
+ if (
172
+ (isFirstDayOfMonth && selectedEndDay) ||
173
+ (isLastDayOfMonth && selectedStartDay)
174
+ ) {
205
175
  inRange = false
206
176
  }
177
+ } else if (mode === 'multiple') {
178
+ const safeDates = dates || []
179
+ selected = safeDates.some((d) => areDatesOnSameDay(day, d))
180
+
181
+ const yesterday = new Date(year, month, dayOfMonth - 1)
182
+ const tomorrow = new Date(year, month, dayOfMonth + 1)
183
+
184
+ const yesterdaySelected = safeDates.some((d) =>
185
+ areDatesOnSameDay(d, yesterday)
186
+ )
187
+ const tomorrowSelected = safeDates.some((d) =>
188
+ areDatesOnSameDay(d, tomorrow)
189
+ )
207
190
 
208
- if (inRange && !leftCrop && !rightCrop) {
209
- selected = false
191
+ if (selected) {
192
+ if (tomorrowSelected && yesterdaySelected) {
193
+ inRange = true
194
+ }
195
+ if (tomorrowSelected && !yesterdaySelected) {
196
+ inRange = true
197
+ leftCrop = true
198
+ }
199
+
200
+ if (yesterdaySelected && !tomorrowSelected) {
201
+ inRange = true
202
+ rightCrop = true
203
+ }
204
+
205
+ if (isFirstDayOfMonth && !tomorrowSelected) {
206
+ inRange = false
207
+ }
208
+
209
+ if (isLastDayOfMonth && !yesterdaySelected) {
210
+ inRange = false
211
+ }
212
+
213
+ if (inRange && !leftCrop && !rightCrop) {
214
+ selected = false
215
+ }
210
216
  }
217
+ } else if (mode === 'single') {
218
+ selected = areDatesOnSameDay(day, date)
219
+ }
220
+
221
+ const isWithinOptionalValidRange = isWithinValidRange(day)
222
+
223
+ if (inRange && !disabled) {
224
+ disabled = false
211
225
  }
212
- } else if (mode === 'single') {
213
- selected = areDatesOnSameDay(day, date)
214
- }
215
-
216
- const isWithinOptionalValidRange = isWithinValidRange(day)
217
-
218
- if (inRange && !disabled) {
219
- disabled = false
220
- }
221
-
222
- if (!isWithinOptionalValidRange) {
223
- disabled = true
224
- }
225
-
226
- return {
227
- beforeWeekDay,
228
- afterWeekDay,
229
- year,
230
- month,
231
- dayOfMonth,
232
- dayIndex,
233
- mode,
234
- selected,
235
- inRange,
236
- leftCrop,
237
- rightCrop,
238
- isToday,
239
- disabled,
240
- }
241
- }),
226
+
227
+ if (!isWithinOptionalValidRange) {
228
+ disabled = true
229
+ }
230
+
231
+ return {
232
+ beforeWeekDay,
233
+ afterWeekDay,
234
+ year,
235
+ month,
236
+ dayOfMonth,
237
+ dayIndex,
238
+ mode,
239
+ selected,
240
+ inRange,
241
+ leftCrop,
242
+ rightCrop,
243
+ isToday,
244
+ disabled,
245
+ }
246
+ }),
247
+ }
242
248
  }
243
- })
249
+ )
244
250
  }, [
245
251
  year,
246
252
  month,
@@ -253,6 +259,8 @@ function Month(props: MonthSingleProps | MonthRangeProps | MonthMultiProps) {
253
259
  dates,
254
260
  date,
255
261
  startWeekOnMonday,
262
+ startYear,
263
+ endYear,
256
264
  ])
257
265
 
258
266
  let textFont = theme?.isV3
@@ -269,7 +277,15 @@ function Month(props: MonthSingleProps | MonthRangeProps | MonthMultiProps) {
269
277
 
270
278
  return (
271
279
  <View
272
- style={{ height: getMonthHeight(scrollMode, index, startWeekOnMonday) }}
280
+ style={{
281
+ height: getMonthHeight(
282
+ scrollMode,
283
+ index,
284
+ startWeekOnMonday,
285
+ startYear,
286
+ endYear
287
+ ),
288
+ }}
273
289
  >
274
290
  <View
275
291
  style={[
@@ -398,8 +414,13 @@ const styles = StyleSheet.create({
398
414
  },
399
415
  })
400
416
 
401
- const monthGrid = (index: number, startWeekOnMonday: boolean) => {
402
- return Array(getGridCount(index, startWeekOnMonday))
417
+ const monthGrid = (
418
+ index: number,
419
+ startWeekOnMonday: boolean,
420
+ startYear?: number,
421
+ endYear?: number
422
+ ) => {
423
+ return Array(getGridCount(index, startWeekOnMonday, startYear, endYear))
403
424
  .fill(null)
404
425
  .map((_, weekGrid) => {
405
426
  const days = Array(7).fill(null)
@@ -407,28 +428,45 @@ const monthGrid = (index: number, startWeekOnMonday: boolean) => {
407
428
  })
408
429
  }
409
430
 
410
- function getIndexCount(index: number): number {
411
- if (index > startAtIndex) {
412
- return index - startAtIndex
431
+ function getIndexCount(
432
+ index: number,
433
+ startYear?: number,
434
+ endYear?: number
435
+ ): number {
436
+ const dynamicStartAtIndex = getStartAtIndex(startYear, endYear)
437
+ if (index > dynamicStartAtIndex) {
438
+ return index - dynamicStartAtIndex
413
439
  }
414
440
 
415
- return -(startAtIndex - index)
441
+ return -(dynamicStartAtIndex - index)
416
442
  }
417
443
 
418
- function weeksOffset(index: number, startWeekOnMonday: boolean): number {
419
- if (index === startAtIndex) {
444
+ function weeksOffset(
445
+ index: number,
446
+ startWeekOnMonday: boolean,
447
+ startYear?: number,
448
+ endYear?: number
449
+ ): number {
450
+ const dynamicStartAtIndex = getStartAtIndex(startYear, endYear)
451
+ const dynamicGridCounts = createGridCounts(getTotalMonths(startYear, endYear))
452
+
453
+ if (index === dynamicStartAtIndex) {
420
454
  return 0
421
455
  }
422
456
  let off = 0
423
- if (index > startAtIndex) {
424
- for (let i = 0; i < index - startAtIndex; i++) {
425
- const cIndex = startAtIndex + i
426
- off += gridCounts[cIndex] || getGridCount(cIndex, startWeekOnMonday)
457
+ if (index > dynamicStartAtIndex) {
458
+ for (let i = 0; i < index - dynamicStartAtIndex; i++) {
459
+ const cIndex = dynamicStartAtIndex + i
460
+ off +=
461
+ dynamicGridCounts[cIndex] ||
462
+ getGridCount(cIndex, startWeekOnMonday, startYear, endYear)
427
463
  }
428
464
  } else {
429
- for (let i = 0; i < startAtIndex - index; i++) {
430
- const cIndex = startAtIndex - i - 1
431
- off -= gridCounts[cIndex] || getGridCount(cIndex, startWeekOnMonday)
465
+ for (let i = 0; i < dynamicStartAtIndex - index; i++) {
466
+ const cIndex = dynamicStartAtIndex - i - 1
467
+ off -=
468
+ dynamicGridCounts[cIndex] ||
469
+ getGridCount(cIndex, startWeekOnMonday, startYear, endYear)
432
470
  }
433
471
  }
434
472
  return off
@@ -436,19 +474,33 @@ function weeksOffset(index: number, startWeekOnMonday: boolean): number {
436
474
 
437
475
  export function getIndexFromHorizontalOffset(
438
476
  offset: number,
439
- width: number
477
+ width: number,
478
+ startYear?: number,
479
+ endYear?: number
440
480
  ): number {
441
- return startAtIndex + Math.floor(offset / width)
481
+ const dynamicStartAtIndex = getStartAtIndex(startYear, endYear)
482
+ return dynamicStartAtIndex + Math.floor(offset / width)
442
483
  }
443
484
 
444
485
  export function getIndexFromVerticalOffset(
445
486
  offset: number,
446
- startWeekOnMonday: boolean
487
+ startWeekOnMonday: boolean,
488
+ startYear?: number,
489
+ endYear?: number
447
490
  ): number {
448
- let estimatedIndex = startAtIndex + Math.ceil(offset / estimatedMonthHeight)
491
+ const dynamicStartAtIndex = getStartAtIndex(startYear, endYear)
492
+ const dynamicBeginOffset = estimatedMonthHeight * dynamicStartAtIndex
493
+ let estimatedIndex =
494
+ dynamicStartAtIndex + Math.ceil(offset / estimatedMonthHeight)
449
495
 
450
- const realOffset = getVerticalMonthsOffset(estimatedIndex, startWeekOnMonday)
451
- const difference = (realOffset - beginOffset - offset) / estimatedMonthHeight
496
+ const realOffset = getVerticalMonthsOffset(
497
+ estimatedIndex,
498
+ startWeekOnMonday,
499
+ startYear,
500
+ endYear
501
+ )
502
+ const difference =
503
+ (realOffset - dynamicBeginOffset - offset) / estimatedMonthHeight
452
504
  if (difference >= 1 || difference <= -1) {
453
505
  estimatedIndex -= Math.floor(difference)
454
506
  }
@@ -464,23 +516,29 @@ export function getHorizontalMonthOffset(index: number, width: number) {
464
516
 
465
517
  export function getVerticalMonthsOffset(
466
518
  index: number,
467
- startWeekOnMonday: boolean
519
+ startWeekOnMonday: boolean,
520
+ startYear?: number,
521
+ endYear?: number
468
522
  ) {
469
- const count = getIndexCount(index)
470
- const ob = weeksOffset(index, startWeekOnMonday)
523
+ const count = getIndexCount(index, startYear, endYear)
524
+ const ob = weeksOffset(index, startWeekOnMonday, startYear, endYear)
471
525
  const monthsHeight = weekSize * ob
472
526
  const c = monthsHeight + count * (dayNamesHeight + montHeaderHeight)
527
+ const dynamicBeginOffset =
528
+ estimatedMonthHeight * getStartAtIndex(startYear, endYear)
473
529
 
474
- return (c || 0) + beginOffset
530
+ return (c || 0) + dynamicBeginOffset
475
531
  }
476
532
 
477
533
  export function getMonthHeight(
478
534
  scrollMode: 'horizontal' | 'vertical',
479
535
  index: number,
480
- startWeekOnMonday: boolean
536
+ startWeekOnMonday: boolean,
537
+ startYear?: number,
538
+ endYear?: number
481
539
  ): number {
482
540
  const calendarHeight = getCalendarHeaderHeight(scrollMode)
483
- const gc = getGridCount(index, startWeekOnMonday)
541
+ const gc = getGridCount(index, startWeekOnMonday, startYear, endYear)
484
542
 
485
543
  const currentMonthHeight = weekSize * gc
486
544
  const extraHeight =
@@ -13,8 +13,12 @@ import {
13
13
  montHeaderHeight,
14
14
  } from './Month'
15
15
 
16
- import { SwiperProps, useYearChange } from './SwiperUtils'
17
- import { beginOffset, estimatedMonthHeight, totalMonths } from './dateUtils'
16
+ import { SwiperProps, useYearChange, isIndexWithinRange } from './SwiperUtils'
17
+ import {
18
+ estimatedMonthHeight,
19
+ getTotalMonths,
20
+ getBeginOffset,
21
+ } from './dateUtils'
18
22
  import AutoSizer from './AutoSizer'
19
23
  import { memo, useCallback, useRef, useState } from 'react'
20
24
  import { sharedStyles } from '../shared/styles'
@@ -49,6 +53,8 @@ function SwiperInner({
49
53
  width,
50
54
  height,
51
55
  startWeekOnMonday,
56
+ startYear,
57
+ endYear,
52
58
  }: SwiperProps & { width: number; height: number }) {
53
59
  const idx = useRef<number>(initialIndex)
54
60
  const isHorizontal = scrollMode === 'horizontal'
@@ -60,6 +66,10 @@ function SwiperInner({
60
66
 
61
67
  const scrollTo = useCallback(
62
68
  (index: number, animated: boolean) => {
69
+ if (!isIndexWithinRange(index, startYear, endYear)) {
70
+ return
71
+ }
72
+
63
73
  idx.current = index
64
74
  setVisibleIndexes(getVisibleArray(index, { isHorizontal, height }))
65
75
 
@@ -68,7 +78,12 @@ function SwiperInner({
68
78
  }
69
79
  const offset = isHorizontal
70
80
  ? getHorizontalMonthOffset(index, width)
71
- : getVerticalMonthsOffset(index, startWeekOnMonday) - montHeaderHeight
81
+ : getVerticalMonthsOffset(
82
+ index,
83
+ startWeekOnMonday,
84
+ startYear,
85
+ endYear
86
+ ) - montHeaderHeight
72
87
 
73
88
  if (isHorizontal) {
74
89
  parentRef.current.scrollTo({
@@ -84,16 +99,30 @@ function SwiperInner({
84
99
  })
85
100
  }
86
101
  },
87
- [parentRef, isHorizontal, width, height, startWeekOnMonday]
102
+ [
103
+ parentRef,
104
+ isHorizontal,
105
+ width,
106
+ height,
107
+ startWeekOnMonday,
108
+ startYear,
109
+ endYear,
110
+ ]
88
111
  )
89
112
 
90
113
  const onPrev = useCallback(() => {
91
- scrollTo(idx.current - 1, true)
92
- }, [scrollTo, idx])
114
+ const newIndex = idx.current - 1
115
+ if (isIndexWithinRange(newIndex, startYear, endYear)) {
116
+ scrollTo(newIndex, true)
117
+ }
118
+ }, [scrollTo, idx, startYear, endYear])
93
119
 
94
120
  const onNext = useCallback(() => {
95
- scrollTo(idx.current + 1, true)
96
- }, [scrollTo, idx])
121
+ const newIndex = idx.current + 1
122
+ if (isIndexWithinRange(newIndex, startYear, endYear)) {
123
+ scrollTo(newIndex, true)
124
+ }
125
+ }, [scrollTo, idx, startYear, endYear])
97
126
 
98
127
  const scrollToInitial = useCallback(() => {
99
128
  scrollTo(idx.current, false)
@@ -103,23 +132,30 @@ function SwiperInner({
103
132
  (e: NativeSyntheticEvent<NativeScrollEvent>) => {
104
133
  const contentOffset = e.nativeEvent.contentOffset
105
134
  const viewSize = e.nativeEvent.layoutMeasurement
135
+ const dynamicBeginOffset = getBeginOffset(startYear, endYear)
106
136
  const newIndex = isHorizontal
107
137
  ? Math.round(contentOffset.x / viewSize.width)
108
138
  : getIndexFromVerticalOffset(
109
- contentOffset.y - beginOffset,
110
- startWeekOnMonday
139
+ contentOffset.y - dynamicBeginOffset,
140
+ startWeekOnMonday,
141
+ startYear,
142
+ endYear
111
143
  )
112
144
 
113
145
  if (newIndex === 0) {
114
146
  return
115
147
  }
116
148
 
149
+ if (!isIndexWithinRange(newIndex, startYear, endYear)) {
150
+ return
151
+ }
152
+
117
153
  if (idx.current !== newIndex) {
118
154
  idx.current = newIndex
119
155
  setVisibleIndexes(getVisibleArray(newIndex, { isHorizontal, height }))
120
156
  }
121
157
  },
122
- [idx, height, isHorizontal, startWeekOnMonday]
158
+ [idx, height, isHorizontal, startWeekOnMonday, startYear, endYear]
123
159
  )
124
160
 
125
161
  const renderProps = {
@@ -130,13 +166,15 @@ function SwiperInner({
130
166
 
131
167
  useYearChange(
132
168
  (newIndex) => {
133
- if (newIndex) {
169
+ if (newIndex && isIndexWithinRange(newIndex, startYear, endYear)) {
134
170
  scrollTo(newIndex, false)
135
171
  }
136
172
  },
137
173
  {
138
174
  selectedYear,
139
175
  currentIndexRef: idx,
176
+ startYear,
177
+ endYear,
140
178
  }
141
179
  )
142
180
 
@@ -162,8 +200,10 @@ function SwiperInner({
162
200
  {
163
201
  height: isHorizontal
164
202
  ? height
165
- : estimatedMonthHeight * totalMonths,
166
- width: isHorizontal ? width * totalMonths : width,
203
+ : estimatedMonthHeight * getTotalMonths(startYear, endYear),
204
+ width: isHorizontal
205
+ ? width * getTotalMonths(startYear, endYear)
206
+ : width,
167
207
  },
168
208
  ]}
169
209
  >
@@ -177,7 +217,9 @@ function SwiperInner({
177
217
  ? 0
178
218
  : getVerticalMonthsOffset(
179
219
  visibleIndexes[vi],
180
- startWeekOnMonday
220
+ startWeekOnMonday,
221
+ startYear,
222
+ endYear
181
223
  ),
182
224
  left: isHorizontal
183
225
  ? getHorizontalMonthOffset(visibleIndexes[vi], width)
@@ -191,7 +233,9 @@ function SwiperInner({
191
233
  : getMonthHeight(
192
234
  scrollMode,
193
235
  visibleIndexes[vi],
194
- startWeekOnMonday
236
+ startWeekOnMonday,
237
+ startYear,
238
+ endYear
195
239
  ),
196
240
  }}
197
241
  >