react-native-paper-dates 0.22.42 → 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 (60) 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/commonjs/translations/utils.js +1 -1
  18. package/lib/commonjs/translations/utils.js.map +1 -1
  19. package/lib/module/Date/Calendar.js +9 -4
  20. package/lib/module/Date/Calendar.js.map +1 -1
  21. package/lib/module/Date/DatePickerInput.js +3 -2
  22. package/lib/module/Date/DatePickerInput.js.map +1 -1
  23. package/lib/module/Date/Month.js +50 -41
  24. package/lib/module/Date/Month.js.map +1 -1
  25. package/lib/module/Date/Swiper.js +42 -13
  26. package/lib/module/Date/Swiper.js.map +1 -1
  27. package/lib/module/Date/Swiper.native.js +34 -17
  28. package/lib/module/Date/Swiper.native.js.map +1 -1
  29. package/lib/module/Date/SwiperUtils.js +48 -7
  30. package/lib/module/Date/SwiperUtils.js.map +1 -1
  31. package/lib/module/Date/YearPicker.js +2 -1
  32. package/lib/module/Date/YearPicker.js.map +1 -1
  33. package/lib/module/Date/dateUtils.js +42 -10
  34. package/lib/module/Date/dateUtils.js.map +1 -1
  35. package/lib/module/translations/utils.js +1 -1
  36. package/lib/module/translations/utils.js.map +1 -1
  37. package/lib/typescript/Date/Calendar.d.ts.map +1 -1
  38. package/lib/typescript/Date/DatePickerInput.d.ts.map +1 -1
  39. package/lib/typescript/Date/Month.d.ts +6 -4
  40. package/lib/typescript/Date/Month.d.ts.map +1 -1
  41. package/lib/typescript/Date/Swiper.d.ts +1 -1
  42. package/lib/typescript/Date/Swiper.d.ts.map +1 -1
  43. package/lib/typescript/Date/Swiper.native.d.ts.map +1 -1
  44. package/lib/typescript/Date/SwiperUtils.d.ts +8 -1
  45. package/lib/typescript/Date/SwiperUtils.d.ts.map +1 -1
  46. package/lib/typescript/Date/YearPicker.d.ts.map +1 -1
  47. package/lib/typescript/Date/dateUtils.d.ts +10 -4
  48. package/lib/typescript/Date/dateUtils.d.ts.map +1 -1
  49. package/lib/typescript/translations/utils.d.ts +2 -1
  50. package/lib/typescript/translations/utils.d.ts.map +1 -1
  51. package/package.json +4 -3
  52. package/src/Date/Calendar.tsx +8 -3
  53. package/src/Date/DatePickerInput.tsx +3 -2
  54. package/src/Date/Month.tsx +210 -152
  55. package/src/Date/Swiper.native.tsx +60 -16
  56. package/src/Date/Swiper.tsx +57 -9
  57. package/src/Date/SwiperUtils.ts +63 -6
  58. package/src/Date/YearPicker.tsx +3 -3
  59. package/src/Date/dateUtils.tsx +61 -10
  60. package/src/translations/utils.ts +13 -3
@@ -7,7 +7,14 @@ import {
7
7
  } from './Month'
8
8
  import { beginOffset, estimatedMonthHeight, totalMonths } from './dateUtils'
9
9
  import { useLatest } from '../shared/utils'
10
- import { RenderProps, SwiperProps, useYearChange } from './SwiperUtils'
10
+ import {
11
+ RenderProps,
12
+ SwiperProps,
13
+ useYearChange,
14
+ isIndexWithinRange,
15
+ getMinIndex,
16
+ getMaxIndex,
17
+ } from './SwiperUtils'
11
18
  import AutoSizer from './AutoSizer'
12
19
  import {
13
20
  memo,
@@ -31,18 +38,34 @@ function Swiper({
31
38
  selectedYear,
32
39
  initialIndex,
33
40
  startWeekOnMonday,
41
+ startYear,
42
+ endYear,
34
43
  }: SwiperProps) {
35
44
  const isHorizontal = scrollMode === 'horizontal'
36
45
 
37
46
  const [index, setIndex] = useState(initialIndex)
38
47
 
39
48
  const onPrev = useCallback(() => {
40
- setIndex((prev) => prev - 1)
41
- }, [setIndex])
49
+ setIndex((prev) => {
50
+ const newIndex = prev - 1
51
+ // Check if the new index is within allowed range
52
+ if (isIndexWithinRange(newIndex, startYear, endYear)) {
53
+ return newIndex
54
+ }
55
+ return prev // Don't change if outside range
56
+ })
57
+ }, [setIndex, startYear, endYear])
42
58
 
43
59
  const onNext = useCallback(() => {
44
- setIndex((prev) => prev + 1)
45
- }, [setIndex])
60
+ setIndex((prev) => {
61
+ const newIndex = prev + 1
62
+ // Check if the new index is within allowed range
63
+ if (isIndexWithinRange(newIndex, startYear, endYear)) {
64
+ return newIndex
65
+ }
66
+ return prev // Don't change if outside range
67
+ })
68
+ }, [setIndex, startYear, endYear])
46
69
 
47
70
  const renderProps = {
48
71
  index,
@@ -52,13 +75,15 @@ function Swiper({
52
75
  const indexRef = useLatest(index)
53
76
  useYearChange(
54
77
  (newIndex) => {
55
- if (newIndex) {
78
+ if (newIndex && isIndexWithinRange(newIndex, startYear, endYear)) {
56
79
  setIndex(newIndex)
57
80
  }
58
81
  },
59
82
  {
60
83
  selectedYear,
61
84
  currentIndexRef: indexRef,
85
+ startYear,
86
+ endYear,
62
87
  }
63
88
  )
64
89
 
@@ -79,6 +104,8 @@ function Swiper({
79
104
  estimatedHeight={estimatedMonthHeight}
80
105
  renderItem={renderItem}
81
106
  startWeekOnMonday={startWeekOnMonday}
107
+ startYear={startYear}
108
+ endYear={endYear}
82
109
  />
83
110
  )}
84
111
  </AutoSizer>
@@ -97,6 +124,8 @@ function VerticalScroller({
97
124
  estimatedHeight,
98
125
  renderItem,
99
126
  startWeekOnMonday,
127
+ startYear,
128
+ endYear,
100
129
  }: {
101
130
  renderItem: (renderProps: RenderProps) => any
102
131
  width: number
@@ -104,12 +133,26 @@ function VerticalScroller({
104
133
  initialIndex: number
105
134
  estimatedHeight: number
106
135
  startWeekOnMonday: boolean
136
+ startYear?: number
137
+ endYear?: number
107
138
  }) {
139
+ // Ensure initial index is within allowed range
140
+ const constrainedInitialIndex = isIndexWithinRange(
141
+ initialIndex,
142
+ startYear,
143
+ endYear
144
+ )
145
+ ? initialIndex
146
+ : Math.max(
147
+ Math.min(initialIndex, getMaxIndex(endYear)),
148
+ getMinIndex(startYear)
149
+ )
150
+
108
151
  const [visibleIndexes, setVisibleIndexes] = useState<number[]>(
109
- visibleArray(initialIndex)
152
+ visibleArray(constrainedInitialIndex)
110
153
  )
111
154
 
112
- const idx = useRef<number>(initialIndex)
155
+ const idx = useRef<number>(constrainedInitialIndex)
113
156
  const parentRef = useRef<HTMLDivElement | null>(null)
114
157
 
115
158
  useIsomorphicLayoutEffect(() => {
@@ -137,12 +180,17 @@ function VerticalScroller({
137
180
  const offset = top - beginOffset
138
181
  const index = getIndexFromVerticalOffset(offset, startWeekOnMonday)
139
182
 
183
+ // Check if the new index is within allowed range
184
+ if (!isIndexWithinRange(index, startYear, endYear)) {
185
+ return
186
+ }
187
+
140
188
  if (idx.current !== index) {
141
189
  idx.current = index
142
190
  setVisibleIndexesThrottled(visibleArray(index))
143
191
  }
144
192
  },
145
- [setVisibleIndexesThrottled, startWeekOnMonday]
193
+ [setVisibleIndexesThrottled, startWeekOnMonday, startYear, endYear]
146
194
  )
147
195
 
148
196
  return (
@@ -4,8 +4,10 @@ import {
4
4
  addMonths,
5
5
  differenceInMonths,
6
6
  getRealIndex,
7
- startAtIndex,
7
+ getStartAtIndex,
8
+ getTotalMonths,
8
9
  } from './dateUtils'
10
+ import { defaultStartYear, defaultEndYear } from './dateUtils'
9
11
 
10
12
  export type RenderProps = {
11
13
  index: number
@@ -21,6 +23,50 @@ export type SwiperProps = {
21
23
  renderFooter?: (renderProps: RenderProps) => any
22
24
  selectedYear: number | undefined
23
25
  startWeekOnMonday: boolean
26
+ startYear?: number
27
+ endYear?: number
28
+ }
29
+
30
+ // Helper function to get the minimum allowed index based on startYear
31
+ export function getMinIndex(startYear?: number, endYear?: number): number {
32
+ if (!startYear) return 0
33
+
34
+ const today = new Date()
35
+ const startDate = new Date(startYear, 0, 1) // January 1st of startYear
36
+ const months = differenceInMonths(today, startDate)
37
+ const dynamicStartAtIndex = getStartAtIndex(startYear, endYear)
38
+ const minIndex = dynamicStartAtIndex + months
39
+ const totalMonths = getTotalMonths(startYear, endYear)
40
+
41
+ // Allow any valid index within the dynamic range, no hard minimum
42
+ return Math.max(0, Math.min(minIndex, totalMonths - 1))
43
+ }
44
+
45
+ // Helper function to get the maximum allowed index based on endYear
46
+ export function getMaxIndex(startYear?: number, endYear?: number): number {
47
+ const dynamicStartAtIndex = getStartAtIndex(startYear, endYear)
48
+ const totalMonths = getTotalMonths(startYear, endYear)
49
+
50
+ if (!endYear) return totalMonths - 1
51
+
52
+ const today = new Date()
53
+ const endDate = new Date(endYear, 11, 31) // December 31st of endYear
54
+ const months = differenceInMonths(today, endDate)
55
+ const maxIndex = dynamicStartAtIndex + months
56
+
57
+ // Allow any valid index within the dynamic range
58
+ return Math.max(0, Math.min(maxIndex, totalMonths - 1))
59
+ }
60
+
61
+ // Helper function to check if an index is within allowed range
62
+ export function isIndexWithinRange(
63
+ index: number,
64
+ startYear?: number,
65
+ endYear?: number
66
+ ): boolean {
67
+ const minIndex = getMinIndex(startYear || defaultStartYear, endYear)
68
+ const maxIndex = getMaxIndex(startYear, endYear || defaultEndYear)
69
+ return index >= minIndex && index <= maxIndex
24
70
  }
25
71
 
26
72
  export function useYearChange(
@@ -28,25 +74,36 @@ export function useYearChange(
28
74
  {
29
75
  selectedYear,
30
76
  currentIndexRef,
77
+ startYear,
78
+ endYear,
31
79
  }: {
32
80
  currentIndexRef: MutableRefObject<number>
33
81
  selectedYear: number | undefined
82
+ startYear?: number
83
+ endYear?: number
34
84
  }
35
85
  ) {
36
86
  const onChangeRef = useLatest(onChange)
37
87
  useEffect(() => {
38
88
  if (selectedYear) {
39
89
  const currentIndex = currentIndexRef.current || 0
40
- const currentDate = addMonths(new Date(), getRealIndex(currentIndex))
90
+ const currentDate = addMonths(
91
+ new Date(),
92
+ getRealIndex(currentIndex, startYear, endYear)
93
+ )
41
94
  currentDate.setFullYear(selectedYear)
42
95
 
43
96
  const today = new Date()
44
97
  const months = differenceInMonths(today, currentDate)
98
+ const dynamicStartAtIndex = getStartAtIndex(startYear, endYear)
99
+ const totalMonths = getTotalMonths(startYear, endYear)
45
100
 
46
- const newIndex = startAtIndex + months
47
- if (currentIndex !== newIndex) {
48
- onChangeRef.current(newIndex)
101
+ const newIndex = dynamicStartAtIndex + months
102
+ // Ensure the new index is within valid bounds
103
+ const boundedIndex = Math.max(0, Math.min(newIndex, totalMonths - 1))
104
+ if (currentIndex !== boundedIndex) {
105
+ onChangeRef.current(boundedIndex)
49
106
  }
50
107
  }
51
- }, [currentIndexRef, onChangeRef, selectedYear])
108
+ }, [currentIndexRef, onChangeRef, selectedYear, startYear, endYear])
52
109
  }
@@ -3,6 +3,7 @@ import { MD2Theme, Text, TouchableRipple, useTheme } from 'react-native-paper'
3
3
  import { range } from '../shared/utils'
4
4
  import { memo, useEffect, useRef } from 'react'
5
5
  import { sharedStyles } from '../shared/styles'
6
+ import { defaultStartYear, defaultEndYear } from './dateUtils'
6
7
 
7
8
  const ITEM_HEIGHT = 62
8
9
 
@@ -23,8 +24,8 @@ export default function YearPicker({
23
24
 
24
25
  const flatList = useRef<FlatList<number> | null>(null)
25
26
  const years = range(
26
- isNaN(startYear) ? 1800 : startYear,
27
- isNaN(endYear) ? 2200 : endYear
27
+ isNaN(startYear) ? defaultStartYear : startYear,
28
+ isNaN(endYear) ? defaultEndYear : endYear
28
29
  )
29
30
 
30
31
  // scroll to selected year
@@ -149,5 +150,4 @@ const styles = StyleSheet.create({
149
150
  fontSize: 16,
150
151
  },
151
152
  })
152
-
153
153
  const Year = memo(YearPure)
@@ -170,19 +170,61 @@ export function isLeapYear({ year }: { year: number }) {
170
170
 
171
171
  export const daySize = 46
172
172
  export const estimatedMonthHeight = 360
173
- export const startAtIndex = 1200
173
+ export const defaultStartYear = 1800
174
+ export const defaultEndYear = 2200
175
+
176
+ // Dynamic calculation functions to replace fixed constants
177
+ export function getStartAtIndex(startYear?: number, _endYear?: number): number {
178
+ const start = startYear || 1800
179
+ const today = new Date()
180
+ const currentYear = today.getFullYear()
181
+
182
+ // Calculate months from start year to current year
183
+ const monthsFromStart = (currentYear - start) * 12 + today.getMonth()
184
+
185
+ // Ensure we have enough buffer for the range
186
+ return Math.max(monthsFromStart, 0)
187
+ }
188
+
189
+ export function getTotalMonths(startYear?: number, endYear?: number): number {
190
+ const start = startYear || 1800
191
+ const end = endYear || 2200
192
+ return (end - start + 1) * 12
193
+ }
194
+
195
+ export function getBeginOffset(startYear?: number, endYear?: number): number {
196
+ return estimatedMonthHeight * getStartAtIndex(startYear, endYear)
197
+ }
198
+
199
+ // Keep the old constants for backward compatibility but make them dynamic
200
+ export const startAtIndex = 2800
174
201
  export const totalMonths = startAtIndex * 2
175
202
  export const beginOffset = estimatedMonthHeight * startAtIndex
203
+
204
+ // Create a dynamic grid counts array
205
+ export function createGridCounts(count: number): Array<number | undefined> {
206
+ return new Array<number | undefined>(count)
207
+ }
208
+
176
209
  export const gridCounts = new Array<number | undefined>(totalMonths)
177
210
 
178
- export function getGridCount(index: number, startWeekOnMonday: boolean) {
179
- const cHeight = gridCounts[index]
211
+ export function getGridCount(
212
+ index: number,
213
+ startWeekOnMonday: boolean,
214
+ startYear?: number,
215
+ endYear?: number
216
+ ) {
217
+ const dynamicGridCounts = createGridCounts(getTotalMonths(startYear, endYear))
218
+ const cHeight = dynamicGridCounts[index]
180
219
  if (cHeight) {
181
220
  return cHeight
182
221
  }
183
- const monthDate = addMonths(new Date(), getRealIndex(index))
222
+ const monthDate = addMonths(
223
+ new Date(),
224
+ getRealIndex(index, startYear, endYear)
225
+ )
184
226
  const h = getGridCountForDate(monthDate, startWeekOnMonday)
185
- gridCounts[index] = h
227
+ dynamicGridCounts[index] = h
186
228
  return h
187
229
  }
188
230
 
@@ -194,19 +236,28 @@ export function getGridCountForDate(date: Date, startWeekOnMonday: boolean) {
194
236
  return Math.ceil((daysInMonth + dayOfWeek) / 7)
195
237
  }
196
238
 
197
- export function getRealIndex(index: number) {
198
- return index - startAtIndex
239
+ export function getRealIndex(
240
+ index: number,
241
+ startYear?: number,
242
+ endYear?: number
243
+ ) {
244
+ return index - getStartAtIndex(startYear, endYear)
199
245
  }
200
246
 
201
- export function getInitialIndex(date: Date | undefined) {
247
+ export function getInitialIndex(
248
+ date: Date | undefined,
249
+ startYear?: number,
250
+ endYear?: number
251
+ ) {
252
+ const dynamicStartAtIndex = getStartAtIndex(startYear, endYear)
202
253
  if (!date) {
203
- return startAtIndex
254
+ return dynamicStartAtIndex
204
255
  }
205
256
 
206
257
  const today = new Date()
207
258
  const months = differenceInMonths(today, date)
208
259
 
209
- return startAtIndex + months
260
+ return dynamicStartAtIndex + months
210
261
  }
211
262
 
212
263
  export function useInputFormatter({ locale }: { locale: string | undefined }) {
@@ -17,7 +17,14 @@ export type TranslationsType = {
17
17
  minute: string
18
18
  }
19
19
 
20
- let translationsPerLocale: Record<string, TranslationsType> = {}
20
+ export type TranslationResolver = (
21
+ locale: string | undefined
22
+ ) => TranslationsType
23
+
24
+ let translationsPerLocale: Record<
25
+ string,
26
+ TranslationsType | TranslationResolver
27
+ > = {}
21
28
 
22
29
  export function getTranslation<K extends keyof TranslationsType>(
23
30
  locale: string | undefined,
@@ -32,7 +39,10 @@ export function getTranslation<K extends keyof TranslationsType>(
32
39
  )
33
40
  return fallback || key
34
41
  }
35
- const translation = translationsPerLocale[l][key]
42
+ const translation: TranslationsType[K] =
43
+ typeof translationForLocale === 'function'
44
+ ? translationForLocale(locale)[key]
45
+ : translationForLocale[key]
36
46
  if (!translation) {
37
47
  console.warn(
38
48
  `[react-native-paper-dates] The locale ${locale} is registered, but ${key} is missing`
@@ -43,7 +53,7 @@ export function getTranslation<K extends keyof TranslationsType>(
43
53
 
44
54
  export function registerTranslation(
45
55
  locale: string,
46
- translations: TranslationsType
56
+ translations: TranslationsType | TranslationResolver
47
57
  ) {
48
58
  translationsPerLocale[locale] = translations
49
59
  }