react-native-paper-dates 0.4.6 → 0.7.0
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.
- package/README.md +79 -22
- package/lib/commonjs/Date/AnimatedCrossView.js +9 -8
- package/lib/commonjs/Date/AnimatedCrossView.js.map +1 -1
- package/lib/commonjs/Date/AutoSizer.js +6 -5
- package/lib/commonjs/Date/AutoSizer.js.map +1 -1
- package/lib/commonjs/Date/Calendar.js +46 -39
- package/lib/commonjs/Date/Calendar.js.map +1 -1
- package/lib/commonjs/Date/CalendarEdit.js +32 -111
- package/lib/commonjs/Date/CalendarEdit.js.map +1 -1
- package/lib/commonjs/Date/CalendarHeader.js +23 -12
- package/lib/commonjs/Date/CalendarHeader.js.map +1 -1
- package/lib/commonjs/Date/DatePickerInput.js +93 -20
- package/lib/commonjs/Date/DatePickerInput.js.map +1 -1
- package/lib/commonjs/Date/DatePickerModal.js +2 -2
- package/lib/commonjs/Date/DatePickerModalContent.js +7 -4
- package/lib/commonjs/Date/DatePickerModalContent.js.map +1 -1
- package/lib/commonjs/Date/DatePickerModalContentHeader.js +43 -34
- package/lib/commonjs/Date/DatePickerModalContentHeader.js.map +1 -1
- package/lib/commonjs/Date/DatePickerModalHeader.js +12 -5
- package/lib/commonjs/Date/DatePickerModalHeader.js.map +1 -1
- package/lib/commonjs/Date/DatePickerModalHeaderBackground.js +6 -5
- package/lib/commonjs/Date/DatePickerModalHeaderBackground.js.map +1 -1
- package/lib/commonjs/Date/DateRangeInput.js +23 -24
- package/lib/commonjs/Date/DateRangeInput.js.map +1 -1
- package/lib/commonjs/Date/Day.js +7 -3
- package/lib/commonjs/Date/Day.js.map +1 -1
- package/lib/commonjs/Date/DayName.js +6 -5
- package/lib/commonjs/Date/DayName.js.map +1 -1
- package/lib/commonjs/Date/DayNames.js +7 -6
- package/lib/commonjs/Date/DayNames.js.map +1 -1
- package/lib/commonjs/Date/DayRange.js +9 -8
- package/lib/commonjs/Date/DayRange.js.map +1 -1
- package/lib/commonjs/Date/Month.js +59 -49
- package/lib/commonjs/Date/Month.js.map +1 -1
- package/lib/commonjs/Date/Swiper.js +35 -29
- package/lib/commonjs/Date/Swiper.js.map +1 -1
- package/lib/commonjs/Date/Swiper.native.js +29 -23
- package/lib/commonjs/Date/Swiper.native.js.map +1 -1
- package/lib/commonjs/Date/SwiperUtils.js +7 -6
- package/lib/commonjs/Date/SwiperUtils.js.map +1 -1
- package/lib/commonjs/Date/YearPicker.js +30 -20
- package/lib/commonjs/Date/YearPicker.js.map +1 -1
- package/lib/commonjs/Date/dateUtils.js +106 -37
- package/lib/commonjs/Date/dateUtils.js.map +1 -1
- package/lib/commonjs/Date/inputUtils.js +84 -0
- package/lib/commonjs/Date/inputUtils.js.map +1 -0
- package/lib/commonjs/TextInputMask.js +11 -10
- package/lib/commonjs/TextInputMask.js.map +1 -1
- package/lib/commonjs/Time/AmPmSwitcher.js +37 -19
- package/lib/commonjs/Time/AmPmSwitcher.js.map +1 -1
- package/lib/commonjs/Time/AnalogClock.js +25 -15
- package/lib/commonjs/Time/AnalogClock.js.map +1 -1
- package/lib/commonjs/Time/AnalogClockHours.js +17 -11
- package/lib/commonjs/Time/AnalogClockHours.js.map +1 -1
- package/lib/commonjs/Time/AnalogClockMinutes.js +7 -6
- package/lib/commonjs/Time/AnalogClockMinutes.js.map +1 -1
- package/lib/commonjs/Time/AnimatedClockSwitcher.js +8 -7
- package/lib/commonjs/Time/AnimatedClockSwitcher.js.map +1 -1
- package/lib/commonjs/Time/TimeInput.js +16 -12
- package/lib/commonjs/Time/TimeInput.js.map +1 -1
- package/lib/commonjs/Time/TimeInputs.js +12 -11
- package/lib/commonjs/Time/TimeInputs.js.map +1 -1
- package/lib/commonjs/Time/TimePicker.js +37 -15
- package/lib/commonjs/Time/TimePicker.js.map +1 -1
- package/lib/commonjs/Time/TimePickerModal.js +19 -15
- package/lib/commonjs/Time/TimePickerModal.js.map +1 -1
- package/lib/commonjs/Time/timeUtils.js +14 -9
- package/lib/commonjs/Time/timeUtils.js.map +1 -1
- package/lib/commonjs/index.js +66 -5
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/translations/en.js +25 -0
- package/lib/commonjs/translations/en.js.map +1 -0
- package/lib/commonjs/translations/enGB.js +25 -0
- package/lib/commonjs/translations/enGB.js.map +1 -0
- package/lib/commonjs/translations/nl.js +25 -0
- package/lib/commonjs/translations/nl.js.map +1 -0
- package/lib/commonjs/translations/pl.js +25 -0
- package/lib/commonjs/translations/pl.js.map +1 -0
- package/lib/commonjs/translations/utils.js +31 -0
- package/lib/commonjs/translations/utils.js.map +1 -0
- package/lib/commonjs/utils.js +19 -9
- package/lib/commonjs/utils.js.map +1 -1
- package/lib/module/Date/AnimatedCrossView.js +7 -6
- package/lib/module/Date/AnimatedCrossView.js.map +1 -1
- package/lib/module/Date/AutoSizer.js +4 -3
- package/lib/module/Date/AutoSizer.js.map +1 -1
- package/lib/module/Date/Calendar.js +46 -39
- package/lib/module/Date/Calendar.js.map +1 -1
- package/lib/module/Date/CalendarEdit.js +28 -104
- package/lib/module/Date/CalendarEdit.js.map +1 -1
- package/lib/module/Date/CalendarHeader.js +19 -9
- package/lib/module/Date/CalendarHeader.js.map +1 -1
- package/lib/module/Date/DatePickerInput.js +88 -18
- package/lib/module/Date/DatePickerInput.js.map +1 -1
- package/lib/module/Date/DatePickerModalContent.js +5 -2
- package/lib/module/Date/DatePickerModalContent.js.map +1 -1
- package/lib/module/Date/DatePickerModalContentHeader.js +38 -30
- package/lib/module/Date/DatePickerModalContentHeader.js.map +1 -1
- package/lib/module/Date/DatePickerModalHeader.js +9 -3
- package/lib/module/Date/DatePickerModalHeader.js.map +1 -1
- package/lib/module/Date/DatePickerModalHeaderBackground.js +4 -3
- package/lib/module/Date/DatePickerModalHeaderBackground.js.map +1 -1
- package/lib/module/Date/DateRangeInput.js +22 -22
- package/lib/module/Date/DateRangeInput.js.map +1 -1
- package/lib/module/Date/Day.js +5 -1
- package/lib/module/Date/Day.js.map +1 -1
- package/lib/module/Date/DayName.js +4 -3
- package/lib/module/Date/DayName.js.map +1 -1
- package/lib/module/Date/DayNames.js +5 -4
- package/lib/module/Date/DayNames.js.map +1 -1
- package/lib/module/Date/DayRange.js +7 -6
- package/lib/module/Date/DayRange.js.map +1 -1
- package/lib/module/Date/Month.js +54 -45
- package/lib/module/Date/Month.js.map +1 -1
- package/lib/module/Date/Swiper.js +32 -26
- package/lib/module/Date/Swiper.js.map +1 -1
- package/lib/module/Date/Swiper.native.js +27 -21
- package/lib/module/Date/Swiper.native.js.map +1 -1
- package/lib/module/Date/SwiperUtils.js +5 -4
- package/lib/module/Date/SwiperUtils.js.map +1 -1
- package/lib/module/Date/YearPicker.js +28 -18
- package/lib/module/Date/YearPicker.js.map +1 -1
- package/lib/module/Date/dateUtils.js +78 -29
- package/lib/module/Date/dateUtils.js.map +1 -1
- package/lib/module/Date/inputUtils.js +70 -0
- package/lib/module/Date/inputUtils.js.map +1 -0
- package/lib/module/TextInputMask.js +9 -8
- package/lib/module/TextInputMask.js.map +1 -1
- package/lib/module/Time/AmPmSwitcher.js +35 -18
- package/lib/module/Time/AmPmSwitcher.js.map +1 -1
- package/lib/module/Time/AnalogClock.js +23 -14
- package/lib/module/Time/AnalogClock.js.map +1 -1
- package/lib/module/Time/AnalogClockHours.js +14 -9
- package/lib/module/Time/AnalogClockHours.js.map +1 -1
- package/lib/module/Time/AnalogClockMinutes.js +5 -4
- package/lib/module/Time/AnalogClockMinutes.js.map +1 -1
- package/lib/module/Time/AnimatedClockSwitcher.js +6 -5
- package/lib/module/Time/AnimatedClockSwitcher.js.map +1 -1
- package/lib/module/Time/TimeInput.js +14 -10
- package/lib/module/Time/TimeInput.js.map +1 -1
- package/lib/module/Time/TimeInputs.js +10 -9
- package/lib/module/Time/TimeInputs.js.map +1 -1
- package/lib/module/Time/TimePicker.js +32 -12
- package/lib/module/Time/TimePicker.js.map +1 -1
- package/lib/module/Time/TimePickerModal.js +17 -13
- package/lib/module/Time/TimePickerModal.js.map +1 -1
- package/lib/module/Time/timeUtils.js +5 -1
- package/lib/module/Time/timeUtils.js.map +1 -1
- package/lib/module/index.js +6 -0
- package/lib/module/index.js.map +1 -1
- package/lib/module/translations/en.js +18 -0
- package/lib/module/translations/en.js.map +1 -0
- package/lib/module/translations/enGB.js +18 -0
- package/lib/module/translations/enGB.js.map +1 -0
- package/lib/module/translations/nl.js +18 -0
- package/lib/module/translations/nl.js.map +1 -0
- package/lib/module/translations/pl.js +18 -0
- package/lib/module/translations/pl.js.map +1 -0
- package/lib/module/translations/utils.js +22 -0
- package/lib/module/translations/utils.js.map +1 -0
- package/lib/module/utils.js +11 -5
- package/lib/module/utils.js.map +1 -1
- package/lib/typescript/{src/Date → Date}/AnimatedCrossView.d.ts +0 -0
- package/lib/typescript/{src/Date → Date}/AutoSizer.d.ts +0 -0
- package/lib/typescript/{src/Date → Date}/Calendar.d.ts +5 -3
- package/lib/typescript/{src/Date → Date}/CalendarEdit.d.ts +3 -3
- package/lib/typescript/{src/Date → Date}/CalendarHeader.d.ts +1 -1
- package/lib/typescript/Date/DatePickerInput.d.ts +18 -0
- package/lib/typescript/{src/Date → Date}/DatePickerModal.d.ts +0 -0
- package/lib/typescript/{src/Date → Date}/DatePickerModalContent.d.ts +2 -1
- package/lib/typescript/{src/Date → Date}/DatePickerModalContentHeader.d.ts +4 -4
- package/lib/typescript/{src/Date → Date}/DatePickerModalHeader.d.ts +1 -0
- package/lib/typescript/{src/Date → Date}/DatePickerModalHeaderBackground.d.ts +0 -0
- package/lib/typescript/Date/DateRangeInput.d.ts +3 -0
- package/lib/typescript/{src/Date → Date}/Day.d.ts +0 -0
- package/lib/typescript/{src/Date → Date}/DayName.d.ts +0 -0
- package/lib/typescript/{src/Date → Date}/DayNames.d.ts +0 -0
- package/lib/typescript/{src/Date → Date}/DayRange.d.ts +0 -0
- package/lib/typescript/{src/Date → Date}/Month.d.ts +0 -0
- package/lib/typescript/{src/Date → Date}/Swiper.d.ts +0 -0
- package/lib/typescript/{src/Date → Date}/Swiper.native.d.ts +0 -0
- package/lib/typescript/{src/Date → Date}/SwiperUtils.d.ts +1 -1
- package/lib/typescript/{src/Date → Date}/Week.d.ts +0 -0
- package/lib/typescript/{src/Date → Date}/YearPicker.d.ts +0 -0
- package/lib/typescript/{src/Date → Date}/dateUtils.d.ts +15 -0
- package/lib/typescript/{src/Date → Date}/dateUtils.test.d.ts +0 -0
- package/lib/typescript/Date/inputUtils.d.ts +14 -0
- package/lib/typescript/TextInputMask.d.ts +11 -0
- package/lib/typescript/Time/AmPmSwitcher.d.ts +4 -0
- package/lib/typescript/{src/Time → Time}/AnalogClock.d.ts +1 -1
- package/lib/typescript/{src/Time → Time}/AnalogClockHours.d.ts +0 -0
- package/lib/typescript/{src/Time → Time}/AnalogClockMinutes.d.ts +0 -0
- package/lib/typescript/{src/Time → Time}/AnimatedClockSwitcher.d.ts +0 -0
- package/lib/typescript/{src/Time → Time}/TimeInput.d.ts +0 -0
- package/lib/typescript/{src/Time → Time}/TimeInputs.d.ts +1 -1
- package/lib/typescript/{src/Time → Time}/TimePicker.d.ts +4 -0
- package/lib/typescript/{src/Time → Time}/TimePickerModal.d.ts +1 -1
- package/lib/typescript/{src/Time → Time}/timeUtils.d.ts +0 -0
- package/lib/typescript/index.d.ts +13 -0
- package/lib/typescript/translations/en.d.ts +3 -0
- package/lib/typescript/translations/enGB.d.ts +3 -0
- package/lib/typescript/translations/nl.d.ts +3 -0
- package/lib/typescript/translations/pl.d.ts +3 -0
- package/lib/typescript/translations/utils.d.ts +18 -0
- package/lib/typescript/utils.d.ts +58 -0
- package/package.json +39 -38
- package/src/.DS_Store +0 -0
- package/src/Date/Calendar.tsx +14 -13
- package/src/Date/CalendarEdit.tsx +17 -121
- package/src/Date/CalendarHeader.tsx +18 -3
- package/src/Date/DatePickerInput.tsx +103 -25
- package/src/Date/DatePickerModalContent.tsx +5 -1
- package/src/Date/DatePickerModalContentHeader.tsx +26 -12
- package/src/Date/DatePickerModalHeader.tsx +8 -1
- package/src/Date/DateRangeInput.tsx +26 -17
- package/src/Date/Day.tsx +4 -0
- package/src/Date/Month.tsx +20 -44
- package/src/Date/Swiper.tsx +1 -0
- package/src/Date/SwiperUtils.ts +1 -1
- package/src/Date/YearPicker.tsx +6 -1
- package/src/Date/dateUtils.tsx +70 -9
- package/src/Date/inputUtils.ts +94 -0
- package/src/TextInputMask.tsx +10 -3
- package/src/Time/AmPmSwitcher.tsx +20 -11
- package/src/Time/AnalogClock.tsx +12 -14
- package/src/Time/AnalogClockHours.tsx +14 -5
- package/src/Time/AnalogClockMinutes.tsx +4 -1
- package/src/Time/TimeInput.tsx +3 -0
- package/src/Time/TimeInputs.tsx +1 -5
- package/src/Time/TimePicker.tsx +44 -22
- package/src/Time/TimePickerModal.tsx +4 -1
- package/src/Time/timeUtils.ts +4 -1
- package/src/index.tsx +7 -0
- package/src/translations/en.ts +20 -0
- package/src/translations/enGB.ts +20 -0
- package/src/translations/nl.ts +20 -0
- package/src/translations/pl.ts +21 -0
- package/src/translations/utils.ts +47 -0
- package/src/utils.ts +13 -5
- package/lib/typescript/src/Date/DatePickerInput.d.ts +0 -1
- package/lib/typescript/src/Date/DateRangeInput.d.ts +0 -1
- package/lib/typescript/src/TextInputMask.d.ts +0 -3
- package/lib/typescript/src/Time/AmPmSwitcher.d.ts +0 -4
- package/lib/typescript/src/index.d.ts +0 -6
- package/lib/typescript/src/utils.d.ts +0 -7
package/src/Date/Month.tsx
CHANGED
|
@@ -18,8 +18,7 @@ import {
|
|
|
18
18
|
startAtIndex,
|
|
19
19
|
beginOffset,
|
|
20
20
|
estimatedMonthHeight,
|
|
21
|
-
|
|
22
|
-
dateToUnix,
|
|
21
|
+
useRangeChecker,
|
|
23
22
|
} from './dateUtils'
|
|
24
23
|
import { getCalendarHeaderHeight } from './CalendarHeader'
|
|
25
24
|
import type {
|
|
@@ -91,35 +90,7 @@ function Month(props: MonthSingleProps | MonthRangeProps | MonthMultiProps) {
|
|
|
91
90
|
const textColorOnPrimary = useTextColorOnPrimary()
|
|
92
91
|
const realIndex = getRealIndex(index)
|
|
93
92
|
const isHorizontal = scrollMode === 'horizontal'
|
|
94
|
-
|
|
95
|
-
const validRangeStart =
|
|
96
|
-
validRange?.startDate instanceof Date
|
|
97
|
-
? dateToUnix(
|
|
98
|
-
new Date(
|
|
99
|
-
validRange?.startDate.getFullYear(),
|
|
100
|
-
validRange?.startDate.getMonth(),
|
|
101
|
-
validRange?.startDate.getDate(),
|
|
102
|
-
0,
|
|
103
|
-
0,
|
|
104
|
-
0
|
|
105
|
-
)
|
|
106
|
-
)
|
|
107
|
-
: undefined
|
|
108
|
-
|
|
109
|
-
const validRangeEnd =
|
|
110
|
-
validRange?.endDate instanceof Date
|
|
111
|
-
? dateToUnix(
|
|
112
|
-
new Date(
|
|
113
|
-
validRange?.endDate.getFullYear(),
|
|
114
|
-
validRange?.endDate.getMonth(),
|
|
115
|
-
validRange?.endDate.getDate(),
|
|
116
|
-
23,
|
|
117
|
-
59,
|
|
118
|
-
59
|
|
119
|
-
)
|
|
120
|
-
)
|
|
121
|
-
: undefined
|
|
122
|
-
|
|
93
|
+
const { isDisabled, isWithinValidRange } = useRangeChecker(validRange)
|
|
123
94
|
const { monthName, month, year } = React.useMemo(() => {
|
|
124
95
|
const md = addMonths(new Date(), realIndex)
|
|
125
96
|
const y = md.getFullYear()
|
|
@@ -151,13 +122,15 @@ function Month(props: MonthSingleProps | MonthRangeProps | MonthMultiProps) {
|
|
|
151
122
|
const isToday = areDatesOnSameDay(day, today)
|
|
152
123
|
|
|
153
124
|
let inRange = false
|
|
154
|
-
let disabled =
|
|
125
|
+
let disabled = isDisabled(day)
|
|
155
126
|
let selected = false
|
|
127
|
+
|
|
156
128
|
let leftCrop = dayOfMonth === 1
|
|
157
129
|
let rightCrop = dayOfMonth === daysInMonth
|
|
158
130
|
|
|
159
131
|
const isFirstDayOfMonth = dayOfMonth === 1
|
|
160
132
|
const isLastDayOfMonth = dayOfMonth === daysInMonth
|
|
133
|
+
|
|
161
134
|
if (mode === 'range') {
|
|
162
135
|
const selectedStartDay = areDatesOnSameDay(day, startDate)
|
|
163
136
|
const selectedEndDay = areDatesOnSameDay(day, endDate)
|
|
@@ -226,18 +199,13 @@ function Month(props: MonthSingleProps | MonthRangeProps | MonthMultiProps) {
|
|
|
226
199
|
selected = false
|
|
227
200
|
}
|
|
228
201
|
}
|
|
229
|
-
|
|
230
|
-
//
|
|
231
202
|
} else if (mode === 'single') {
|
|
232
203
|
selected = areDatesOnSameDay(day, date)
|
|
233
204
|
}
|
|
234
|
-
//
|
|
235
|
-
const isWithinOptionalValidRange = isDateWithinOptionalRange(day, {
|
|
236
|
-
startUnix: validRangeStart,
|
|
237
|
-
endUnix: validRangeEnd,
|
|
238
|
-
})
|
|
239
205
|
|
|
240
|
-
|
|
206
|
+
const isWithinOptionalValidRange = isWithinValidRange(day)
|
|
207
|
+
|
|
208
|
+
if (inRange && !disabled) {
|
|
241
209
|
disabled = false
|
|
242
210
|
}
|
|
243
211
|
|
|
@@ -267,13 +235,13 @@ function Month(props: MonthSingleProps | MonthRangeProps | MonthMultiProps) {
|
|
|
267
235
|
year,
|
|
268
236
|
month,
|
|
269
237
|
index,
|
|
238
|
+
isDisabled,
|
|
239
|
+
mode,
|
|
240
|
+
isWithinValidRange,
|
|
270
241
|
startDate,
|
|
271
242
|
endDate,
|
|
272
|
-
date,
|
|
273
243
|
dates,
|
|
274
|
-
|
|
275
|
-
validRangeEnd,
|
|
276
|
-
mode,
|
|
244
|
+
date,
|
|
277
245
|
])
|
|
278
246
|
|
|
279
247
|
return (
|
|
@@ -292,12 +260,17 @@ function Month(props: MonthSingleProps | MonthRangeProps | MonthMultiProps) {
|
|
|
292
260
|
<TouchableRipple
|
|
293
261
|
disabled={!isHorizontal}
|
|
294
262
|
onPress={isHorizontal ? () => onPressYear(year) : undefined}
|
|
263
|
+
accessibilityRole="button"
|
|
264
|
+
accessibilityLabel={`${monthName} ${year}`}
|
|
295
265
|
style={[
|
|
296
266
|
styles.yearButton,
|
|
297
267
|
{
|
|
298
268
|
borderRadius: roundness,
|
|
299
269
|
},
|
|
300
270
|
]}
|
|
271
|
+
// RN types bug
|
|
272
|
+
hasTVPreferredFocus={undefined}
|
|
273
|
+
tvParallaxProperties={undefined}
|
|
301
274
|
>
|
|
302
275
|
<View
|
|
303
276
|
style={[
|
|
@@ -317,6 +290,9 @@ function Month(props: MonthSingleProps | MonthRangeProps | MonthMultiProps) {
|
|
|
317
290
|
<IconButton
|
|
318
291
|
onPress={isHorizontal ? () => onPressYear(year) : undefined}
|
|
319
292
|
icon={selectingYear ? 'chevron-up' : 'chevron-down'}
|
|
293
|
+
// RN types bug
|
|
294
|
+
hasTVPreferredFocus={undefined}
|
|
295
|
+
tvParallaxProperties={undefined}
|
|
320
296
|
/>
|
|
321
297
|
</View>
|
|
322
298
|
</View>
|
package/src/Date/Swiper.tsx
CHANGED
|
@@ -94,6 +94,7 @@ function VerticalScroller({
|
|
|
94
94
|
const [visibleIndexes, setVisibleIndexes] = React.useState<number[]>(
|
|
95
95
|
visibleArray(initialIndex)
|
|
96
96
|
)
|
|
97
|
+
// eslint-disable-next-line no-undef
|
|
97
98
|
const parentRef = React.useRef<HTMLDivElement | null>(null)
|
|
98
99
|
|
|
99
100
|
useIsomorphicLayoutEffect(() => {
|
package/src/Date/SwiperUtils.ts
CHANGED
package/src/Date/YearPicker.tsx
CHANGED
|
@@ -67,14 +67,19 @@ function YearPure({
|
|
|
67
67
|
}: {
|
|
68
68
|
year: number
|
|
69
69
|
selected: boolean
|
|
70
|
-
onPressYear: (
|
|
70
|
+
onPressYear: (newYear: number) => any
|
|
71
71
|
}) {
|
|
72
72
|
const theme = useTheme()
|
|
73
73
|
return (
|
|
74
74
|
<View style={styles.year}>
|
|
75
75
|
<TouchableRipple
|
|
76
76
|
onPress={() => onPressYear(year)}
|
|
77
|
+
accessibilityRole="button"
|
|
78
|
+
accessibilityLabel={String(year)}
|
|
77
79
|
style={styles.yearButton}
|
|
80
|
+
// RN types bug
|
|
81
|
+
hasTVPreferredFocus={undefined}
|
|
82
|
+
tvParallaxProperties={undefined}
|
|
78
83
|
>
|
|
79
84
|
<View
|
|
80
85
|
style={[
|
package/src/Date/dateUtils.tsx
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
import * as React from 'react'
|
|
2
|
+
import { useLatest } from '../utils'
|
|
3
|
+
import type { ValidRangeType } from './Calendar'
|
|
4
|
+
|
|
1
5
|
export type DisableWeekDaysType = number[]
|
|
2
6
|
|
|
3
7
|
export function showWeekDay(
|
|
@@ -61,15 +65,42 @@ export function getFirstDayOfMonth({
|
|
|
61
65
|
return new Date(year, month, 1).getDay()
|
|
62
66
|
}
|
|
63
67
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
68
|
+
export function useRangeChecker(validRange: ValidRangeType | undefined) {
|
|
69
|
+
const validStart = validRange?.startDate
|
|
70
|
+
const validEnd = validRange?.endDate
|
|
71
|
+
const startUnix =
|
|
72
|
+
validStart instanceof Date
|
|
73
|
+
? dateToUnix(getStartOfDay(validStart))
|
|
74
|
+
: undefined
|
|
75
|
+
|
|
76
|
+
const endUnix =
|
|
77
|
+
validEnd instanceof Date ? dateToUnix(getEndOfDay(validEnd)) : undefined
|
|
78
|
+
|
|
79
|
+
const validDisabledDatesRef = useLatest(validRange?.disabledDates)
|
|
80
|
+
|
|
81
|
+
const isWithinValidRange = React.useCallback(
|
|
82
|
+
(day: Date) => {
|
|
83
|
+
return isDateWithinOptionalRange(day, {
|
|
84
|
+
startUnix: startUnix,
|
|
85
|
+
endUnix: endUnix,
|
|
86
|
+
})
|
|
87
|
+
},
|
|
88
|
+
[startUnix, endUnix]
|
|
89
|
+
)
|
|
90
|
+
|
|
91
|
+
const isDisabled = React.useCallback(
|
|
92
|
+
(day: Date) => {
|
|
93
|
+
return validDisabledDatesRef.current
|
|
94
|
+
? validDisabledDatesRef.current.some((disabledDate) =>
|
|
95
|
+
areDatesOnSameDay(disabledDate, day)
|
|
96
|
+
)
|
|
97
|
+
: false
|
|
98
|
+
},
|
|
99
|
+
[validDisabledDatesRef]
|
|
100
|
+
)
|
|
101
|
+
|
|
102
|
+
return { isDisabled, isWithinValidRange, validStart, validEnd }
|
|
103
|
+
}
|
|
73
104
|
|
|
74
105
|
export function areDatesOnSameDay(a: Date, b?: Date | null | undefined) {
|
|
75
106
|
if (!b) {
|
|
@@ -170,6 +201,36 @@ export function getInitialIndex(date: Date | undefined) {
|
|
|
170
201
|
return startAtIndex + months
|
|
171
202
|
}
|
|
172
203
|
|
|
204
|
+
export function useInputFormatter({ locale }: { locale: string | undefined }) {
|
|
205
|
+
return React.useMemo(() => {
|
|
206
|
+
return new Intl.DateTimeFormat(locale, {
|
|
207
|
+
month: '2-digit',
|
|
208
|
+
day: '2-digit',
|
|
209
|
+
year: 'numeric',
|
|
210
|
+
})
|
|
211
|
+
}, [locale])
|
|
212
|
+
}
|
|
213
|
+
export function getStartOfDay(d: Date): Date {
|
|
214
|
+
return new Date(d.getFullYear(), d.getMonth(), d.getDate(), 0, 0, 0)
|
|
215
|
+
}
|
|
216
|
+
export function getEndOfDay(d: Date): Date {
|
|
217
|
+
return new Date(d.getFullYear(), d.getMonth(), d.getDate(), 23, 59, 59)
|
|
218
|
+
}
|
|
219
|
+
export function useInputFormat({
|
|
220
|
+
formatter,
|
|
221
|
+
}: {
|
|
222
|
+
formatter: Intl.DateTimeFormat
|
|
223
|
+
}) {
|
|
224
|
+
return React.useMemo(() => {
|
|
225
|
+
// TODO: something cleaner and more universal?
|
|
226
|
+
const inputDate = formatter.format(new Date(2020, 10 - 1, 1))
|
|
227
|
+
return inputDate
|
|
228
|
+
.replace('2020', 'YYYY')
|
|
229
|
+
.replace('10', 'MM')
|
|
230
|
+
.replace('01', 'DD')
|
|
231
|
+
}, [formatter])
|
|
232
|
+
}
|
|
233
|
+
|
|
173
234
|
export function differenceInMonths(firstDate: Date, secondDate: Date) {
|
|
174
235
|
let diffMonths = (secondDate.getFullYear() - firstDate.getFullYear()) * 12
|
|
175
236
|
diffMonths -= firstDate.getMonth()
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { useInputFormat, useInputFormatter, useRangeChecker } from './dateUtils'
|
|
2
|
+
import * as React from 'react'
|
|
3
|
+
import type { ValidRangeType } from './Calendar'
|
|
4
|
+
import { getTranslation } from 'react-native-paper-dates'
|
|
5
|
+
|
|
6
|
+
export default function useDateInput({
|
|
7
|
+
locale,
|
|
8
|
+
value,
|
|
9
|
+
validRange,
|
|
10
|
+
inputMode,
|
|
11
|
+
onChange,
|
|
12
|
+
}: {
|
|
13
|
+
onChange: (d: Date) => void
|
|
14
|
+
locale: undefined | string
|
|
15
|
+
value: Date | undefined
|
|
16
|
+
validRange: ValidRangeType | undefined
|
|
17
|
+
inputMode: 'start' | 'end'
|
|
18
|
+
}) {
|
|
19
|
+
const { isDisabled, isWithinValidRange, validStart, validEnd } =
|
|
20
|
+
useRangeChecker(validRange)
|
|
21
|
+
const [error, setError] = React.useState<null | string>(null)
|
|
22
|
+
const formatter = useInputFormatter({ locale })
|
|
23
|
+
const inputFormat = useInputFormat({ formatter })
|
|
24
|
+
const formattedValue = formatter.format(value)
|
|
25
|
+
const onChangeText = (date: string) => {
|
|
26
|
+
const dayIndex = inputFormat.indexOf('DD')
|
|
27
|
+
const monthIndex = inputFormat.indexOf('MM')
|
|
28
|
+
const yearIndex = inputFormat.indexOf('YYYY')
|
|
29
|
+
|
|
30
|
+
const day = Number(date.slice(dayIndex, dayIndex + 2))
|
|
31
|
+
const year = Number(date.slice(yearIndex, yearIndex + 4))
|
|
32
|
+
const month = Number(date.slice(monthIndex, monthIndex + 2))
|
|
33
|
+
|
|
34
|
+
if (Number.isNaN(day) || Number.isNaN(year) || Number.isNaN(month)) {
|
|
35
|
+
setError(
|
|
36
|
+
getTranslation(
|
|
37
|
+
locale,
|
|
38
|
+
'notAccordingToDateFormat',
|
|
39
|
+
() => 'notAccordingToDateFormat'
|
|
40
|
+
)(inputFormat)
|
|
41
|
+
)
|
|
42
|
+
return
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const finalDate =
|
|
46
|
+
inputMode === 'end'
|
|
47
|
+
? new Date(year, month - 1, day, 23, 59, 59)
|
|
48
|
+
: new Date(year, month - 1, day)
|
|
49
|
+
|
|
50
|
+
if (isDisabled(finalDate)) {
|
|
51
|
+
setError(getTranslation(locale, 'dateIsDisabled'))
|
|
52
|
+
return
|
|
53
|
+
}
|
|
54
|
+
if (!isWithinValidRange(finalDate)) {
|
|
55
|
+
let errors =
|
|
56
|
+
validStart && validEnd
|
|
57
|
+
? [
|
|
58
|
+
`${getTranslation(locale, 'mustBeBetween')} ${formatter.format(
|
|
59
|
+
validStart
|
|
60
|
+
)} - ${formatter.format(validEnd)}`,
|
|
61
|
+
]
|
|
62
|
+
: [
|
|
63
|
+
validStart
|
|
64
|
+
? `${getTranslation(
|
|
65
|
+
locale,
|
|
66
|
+
'mustBeHigherThan'
|
|
67
|
+
)} ${formatter.format(validStart)}`
|
|
68
|
+
: '',
|
|
69
|
+
validEnd
|
|
70
|
+
? `${getTranslation(
|
|
71
|
+
locale,
|
|
72
|
+
'mustBeLowerThan'
|
|
73
|
+
)} ${formatter.format(validEnd)}`
|
|
74
|
+
: '',
|
|
75
|
+
]
|
|
76
|
+
setError(errors.filter((n) => n).join(' '))
|
|
77
|
+
return
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
setError(null)
|
|
81
|
+
if (inputMode === 'end') {
|
|
82
|
+
onChange(finalDate)
|
|
83
|
+
} else {
|
|
84
|
+
onChange(finalDate)
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
return {
|
|
88
|
+
onChange,
|
|
89
|
+
error,
|
|
90
|
+
formattedValue,
|
|
91
|
+
onChangeText,
|
|
92
|
+
inputFormat,
|
|
93
|
+
}
|
|
94
|
+
}
|
package/src/TextInputMask.tsx
CHANGED
|
@@ -67,10 +67,17 @@ function enhanceTextWithMask(
|
|
|
67
67
|
}
|
|
68
68
|
|
|
69
69
|
function TextInputWithMask(
|
|
70
|
-
{
|
|
70
|
+
{
|
|
71
|
+
onChangeText,
|
|
72
|
+
value,
|
|
73
|
+
mask,
|
|
74
|
+
...rest
|
|
75
|
+
}: React.ComponentProps<typeof TextInput> & { mask: string },
|
|
71
76
|
ref: any
|
|
72
77
|
) {
|
|
73
|
-
const [controlledValue, setControlledValue] = React.useState<string>(
|
|
78
|
+
const [controlledValue, setControlledValue] = React.useState<string>(
|
|
79
|
+
value || ''
|
|
80
|
+
)
|
|
74
81
|
|
|
75
82
|
const onInnerChange = (text: string) => {
|
|
76
83
|
const enhancedText = enhanceTextWithMask(text, mask, controlledValue)
|
|
@@ -82,7 +89,7 @@ function TextInputWithMask(
|
|
|
82
89
|
}
|
|
83
90
|
|
|
84
91
|
React.useEffect(() => {
|
|
85
|
-
setControlledValue(value)
|
|
92
|
+
setControlledValue(value || '')
|
|
86
93
|
}, [value])
|
|
87
94
|
|
|
88
95
|
return (
|
|
@@ -3,15 +3,17 @@ import { View, StyleSheet } from 'react-native'
|
|
|
3
3
|
import { Text, TouchableRipple, useTheme } from 'react-native-paper'
|
|
4
4
|
import { useMemo } from 'react'
|
|
5
5
|
import Color from 'color'
|
|
6
|
-
import {
|
|
6
|
+
import { useSwitchColors } from './timeUtils'
|
|
7
|
+
import { DisplayModeContext } from './TimePicker'
|
|
7
8
|
|
|
8
9
|
export default function AmPmSwitcher({
|
|
9
|
-
hours,
|
|
10
10
|
onChange,
|
|
11
|
+
hours,
|
|
11
12
|
}: {
|
|
12
13
|
hours: number
|
|
13
|
-
onChange: (
|
|
14
|
+
onChange: (newHours: number) => any
|
|
14
15
|
}) {
|
|
16
|
+
const { setMode, mode } = React.useContext(DisplayModeContext)
|
|
15
17
|
const theme = useTheme()
|
|
16
18
|
const backgroundColor = useMemo<string>(() => {
|
|
17
19
|
if (theme.dark) {
|
|
@@ -20,10 +22,7 @@ export default function AmPmSwitcher({
|
|
|
20
22
|
return Color(theme.colors.surface).darken(0.1).hex()
|
|
21
23
|
}, [theme])
|
|
22
24
|
|
|
23
|
-
const
|
|
24
|
-
const isAM = hourType === hourTypes.am
|
|
25
|
-
const isPM = hourType === hourTypes.pm
|
|
26
|
-
|
|
25
|
+
const isAM = mode === 'AM'
|
|
27
26
|
return (
|
|
28
27
|
<View
|
|
29
28
|
style={[
|
|
@@ -36,16 +35,26 @@ export default function AmPmSwitcher({
|
|
|
36
35
|
>
|
|
37
36
|
<SwitchButton
|
|
38
37
|
label="AM"
|
|
39
|
-
onPress={
|
|
38
|
+
onPress={() => {
|
|
39
|
+
setMode('AM')
|
|
40
|
+
if (hours - 12 >= 0) {
|
|
41
|
+
onChange(hours - 12)
|
|
42
|
+
}
|
|
43
|
+
}}
|
|
40
44
|
selected={isAM}
|
|
41
45
|
disabled={isAM}
|
|
42
46
|
/>
|
|
43
47
|
<View style={[styles.switchSeparator, { backgroundColor }]} />
|
|
44
48
|
<SwitchButton
|
|
45
49
|
label="PM"
|
|
46
|
-
onPress={
|
|
47
|
-
|
|
48
|
-
|
|
50
|
+
onPress={() => {
|
|
51
|
+
setMode('PM')
|
|
52
|
+
if (hours + 12 <= 24) {
|
|
53
|
+
onChange(hours + 12)
|
|
54
|
+
}
|
|
55
|
+
}}
|
|
56
|
+
selected={!isAM}
|
|
57
|
+
disabled={!isAM}
|
|
49
58
|
/>
|
|
50
59
|
</View>
|
|
51
60
|
)
|
package/src/Time/AnalogClock.tsx
CHANGED
|
@@ -12,9 +12,7 @@ import {
|
|
|
12
12
|
getAngle,
|
|
13
13
|
getHours,
|
|
14
14
|
getHourType,
|
|
15
|
-
getHourTypeFromOffset,
|
|
16
15
|
getMinutes,
|
|
17
|
-
hourTypes,
|
|
18
16
|
PossibleClockTypes,
|
|
19
17
|
} from './timeUtils'
|
|
20
18
|
import * as React from 'react'
|
|
@@ -24,6 +22,7 @@ import AnalogClockHours from './AnalogClockHours'
|
|
|
24
22
|
|
|
25
23
|
import AnimatedClockSwitcher from './AnimatedClockSwitcher'
|
|
26
24
|
import AnalogClockMinutes from './AnalogClockMinutes'
|
|
25
|
+
import { DisplayModeContext } from './TimePicker'
|
|
27
26
|
|
|
28
27
|
function AnalogClock({
|
|
29
28
|
hours,
|
|
@@ -36,18 +35,14 @@ function AnalogClock({
|
|
|
36
35
|
minutes: number
|
|
37
36
|
focused: PossibleClockTypes
|
|
38
37
|
is24Hour: boolean
|
|
39
|
-
onChange: ({
|
|
40
|
-
hours,
|
|
41
|
-
minutes,
|
|
42
|
-
focused,
|
|
43
|
-
}: {
|
|
38
|
+
onChange: (hoursMinutesAndFocused: {
|
|
44
39
|
hours: number
|
|
45
40
|
minutes: number
|
|
46
41
|
focused?: undefined | PossibleClockTypes
|
|
47
42
|
}) => any
|
|
48
43
|
}) {
|
|
49
44
|
const theme = useTheme()
|
|
50
|
-
|
|
45
|
+
const { mode } = React.useContext(DisplayModeContext)
|
|
51
46
|
// used to make pointer shorter if hours are selected and above 12
|
|
52
47
|
const shortPointer = (hours === 0 || hours > 12) && is24Hour
|
|
53
48
|
|
|
@@ -60,6 +55,7 @@ function AnalogClock({
|
|
|
60
55
|
const minutesRef = useLatest(minutes)
|
|
61
56
|
const focusedRef = useLatest(focused)
|
|
62
57
|
const is24HourRef = useLatest(is24Hour)
|
|
58
|
+
const modeRef = useLatest(mode)
|
|
63
59
|
|
|
64
60
|
const onPointerMove = React.useCallback(
|
|
65
61
|
(e: GestureResponderEvent, final: boolean) => {
|
|
@@ -73,14 +69,16 @@ function AnalogClock({
|
|
|
73
69
|
let previousHourType = getHourType(hoursRef.current)
|
|
74
70
|
let pickedHours = getHours(angle, previousHourType)
|
|
75
71
|
|
|
76
|
-
let
|
|
77
|
-
let hours24AndPM = hours24 && hourTypeFromOffset === hourTypes.pm
|
|
78
|
-
let hours12AndPm = !hours24 && previousHourType === hourTypes.pm
|
|
72
|
+
let hours12AndPm = !hours24 && modeRef.current === 'PM'
|
|
79
73
|
|
|
80
|
-
//
|
|
81
|
-
|
|
74
|
+
// Avoiding the "24h"
|
|
75
|
+
// Should be 12h for 12 hours and PM mode
|
|
76
|
+
if ((hours12AndPm || hours24) && pickedHours + 12 < 24) {
|
|
82
77
|
pickedHours += 12
|
|
83
78
|
}
|
|
79
|
+
if (modeRef.current === 'AM' && pickedHours === 12) {
|
|
80
|
+
pickedHours = 0
|
|
81
|
+
}
|
|
84
82
|
|
|
85
83
|
if (pickedHours === 24) {
|
|
86
84
|
pickedHours = 0
|
|
@@ -103,7 +101,7 @@ function AnalogClock({
|
|
|
103
101
|
}
|
|
104
102
|
}
|
|
105
103
|
},
|
|
106
|
-
[focusedRef, is24HourRef, hoursRef, onChangeRef, minutesRef]
|
|
104
|
+
[focusedRef, is24HourRef, hoursRef, onChangeRef, minutesRef, modeRef]
|
|
107
105
|
)
|
|
108
106
|
|
|
109
107
|
const panResponder = React.useRef(
|
|
@@ -3,6 +3,7 @@ import { View, StyleSheet } from 'react-native'
|
|
|
3
3
|
import { Text } from 'react-native-paper'
|
|
4
4
|
import { circleSize } from './timeUtils'
|
|
5
5
|
import { useTextColorOnPrimary } from '../utils'
|
|
6
|
+
import { DisplayModeContext } from './TimePicker'
|
|
6
7
|
|
|
7
8
|
function AnalogClockHours({
|
|
8
9
|
is24Hour,
|
|
@@ -11,9 +12,11 @@ function AnalogClockHours({
|
|
|
11
12
|
is24Hour: boolean
|
|
12
13
|
hours: number
|
|
13
14
|
}) {
|
|
14
|
-
const
|
|
15
|
-
const
|
|
15
|
+
const { mode } = React.useContext(DisplayModeContext)
|
|
16
|
+
const outerRange = getHourNumbers(false, circleSize, 12, 12)
|
|
17
|
+
const innerRange = getHourNumbers(true, circleSize, 12, 12)
|
|
16
18
|
const color = useTextColorOnPrimary()
|
|
19
|
+
|
|
17
20
|
return (
|
|
18
21
|
<>
|
|
19
22
|
{outerRange.map((a, i) => (
|
|
@@ -29,8 +32,9 @@ function AnalogClockHours({
|
|
|
29
32
|
]}
|
|
30
33
|
>
|
|
31
34
|
<View style={styles.outerHourInner}>
|
|
35
|
+
{/* Display 00 instead of 12 for AM hours */}
|
|
32
36
|
<Text style={hours === i + 1 ? { color } : null} selectable={false}>
|
|
33
|
-
{i + 1}
|
|
37
|
+
{mode === 'AM' && i + 1 === 12 ? '00' : i + 1}
|
|
34
38
|
</Text>
|
|
35
39
|
</View>
|
|
36
40
|
</View>
|
|
@@ -97,14 +101,19 @@ const styles = StyleSheet.create({
|
|
|
97
101
|
innerHourText: { fontSize: 13 },
|
|
98
102
|
})
|
|
99
103
|
|
|
100
|
-
function getHourNumbers(
|
|
104
|
+
function getHourNumbers(
|
|
105
|
+
is24Hour: boolean,
|
|
106
|
+
size: number,
|
|
107
|
+
count: number,
|
|
108
|
+
arrayLength: number
|
|
109
|
+
) {
|
|
101
110
|
let angle = 0
|
|
102
111
|
let step = (2 * Math.PI) / count
|
|
103
112
|
let radius = size / (is24Hour ? 4 : 2.5)
|
|
104
113
|
|
|
105
114
|
angle = (-90 * Math.PI) / 180 + Math.PI / 6
|
|
106
115
|
|
|
107
|
-
return Array(
|
|
116
|
+
return Array(arrayLength)
|
|
108
117
|
.fill(true)
|
|
109
118
|
.map(() => {
|
|
110
119
|
let x = Math.round(size / 2 + radius * Math.cos(angle))
|
|
@@ -30,7 +30,10 @@ function AnalogClockMinutes({ minutes }: { minutes: number }) {
|
|
|
30
30
|
]}
|
|
31
31
|
>
|
|
32
32
|
<View style={styles.outerHourInner}>
|
|
33
|
-
<Text
|
|
33
|
+
<Text
|
|
34
|
+
style={isCurrent ? { color } : undefined}
|
|
35
|
+
selectable={false}
|
|
36
|
+
>
|
|
34
37
|
{isZero ? '00' : currentMinutes}
|
|
35
38
|
</Text>
|
|
36
39
|
</View>
|
package/src/Time/TimeInput.tsx
CHANGED
|
@@ -96,6 +96,9 @@ function TimeInput(
|
|
|
96
96
|
rippleColor={Color(theme.colors.primary).fade(0.7).hex()}
|
|
97
97
|
onPress={() => onPress(clockType)}
|
|
98
98
|
borderless={true}
|
|
99
|
+
// RN types bug
|
|
100
|
+
hasTVPreferredFocus={undefined}
|
|
101
|
+
tvParallaxProperties={undefined}
|
|
99
102
|
>
|
|
100
103
|
<View />
|
|
101
104
|
</TouchableRipple>
|
package/src/Time/TimeInputs.tsx
CHANGED
|
@@ -35,11 +35,7 @@ function TimeInputs({
|
|
|
35
35
|
hours: number
|
|
36
36
|
minutes: number
|
|
37
37
|
onFocusInput: (type: PossibleClockTypes) => any
|
|
38
|
-
onChange: ({
|
|
39
|
-
hours,
|
|
40
|
-
minutes,
|
|
41
|
-
focused,
|
|
42
|
-
}: {
|
|
38
|
+
onChange: (hoursMinutesAndFocused: {
|
|
43
39
|
hours: number
|
|
44
40
|
minutes: number
|
|
45
41
|
focused?: undefined | PossibleClockTypes
|