react-native-paper-dates 0.8.5 → 0.9.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.
Files changed (186) hide show
  1. package/README.md +30 -1
  2. package/lib/commonjs/Date/AnimatedCrossView.js.map +1 -1
  3. package/lib/commonjs/Date/AutoSizer.js.map +1 -1
  4. package/lib/commonjs/Date/Calendar.js +6 -2
  5. package/lib/commonjs/Date/Calendar.js.map +1 -1
  6. package/lib/commonjs/Date/CalendarEdit.js +4 -4
  7. package/lib/commonjs/Date/CalendarEdit.js.map +1 -1
  8. package/lib/commonjs/Date/CalendarHeader.js.map +1 -1
  9. package/lib/commonjs/Date/DatePickerInput.js +33 -87
  10. package/lib/commonjs/Date/DatePickerInput.js.map +1 -1
  11. package/lib/commonjs/Date/DatePickerInput.shared.js +6 -0
  12. package/lib/commonjs/Date/DatePickerInput.shared.js.map +1 -0
  13. package/lib/commonjs/Date/DatePickerInputWithoutModal.js +117 -0
  14. package/lib/commonjs/Date/DatePickerInputWithoutModal.js.map +1 -0
  15. package/lib/commonjs/Date/DatePickerModal.js +1 -1
  16. package/lib/commonjs/Date/DatePickerModal.js.map +1 -1
  17. package/lib/commonjs/Date/DatePickerModalContent.js +14 -8
  18. package/lib/commonjs/Date/DatePickerModalContent.js.map +1 -1
  19. package/lib/commonjs/Date/DatePickerModalContentHeader.js +5 -3
  20. package/lib/commonjs/Date/DatePickerModalContentHeader.js.map +1 -1
  21. package/lib/commonjs/Date/DatePickerModalHeader.js +5 -5
  22. package/lib/commonjs/Date/DatePickerModalHeader.js.map +1 -1
  23. package/lib/commonjs/Date/DatePickerModalHeaderBackground.js.map +1 -1
  24. package/lib/commonjs/Date/DateRangeInput.js +3 -2
  25. package/lib/commonjs/Date/DateRangeInput.js.map +1 -1
  26. package/lib/commonjs/Date/Day.js.map +1 -1
  27. package/lib/commonjs/Date/DayName.js.map +1 -1
  28. package/lib/commonjs/Date/DayNames.js.map +1 -1
  29. package/lib/commonjs/Date/DayRange.js.map +1 -1
  30. package/lib/commonjs/Date/Month.js.map +1 -1
  31. package/lib/commonjs/Date/Swiper.js.map +1 -1
  32. package/lib/commonjs/Date/Swiper.native.js +2 -1
  33. package/lib/commonjs/Date/Swiper.native.js.map +1 -1
  34. package/lib/commonjs/Date/SwiperUtils.js.map +1 -1
  35. package/lib/commonjs/Date/Week.js.map +1 -1
  36. package/lib/commonjs/Date/YearPicker.js +5 -5
  37. package/lib/commonjs/Date/YearPicker.js.map +1 -1
  38. package/lib/commonjs/Date/dateUtils.js.map +1 -1
  39. package/lib/commonjs/Date/dateUtils.test.js.map +1 -1
  40. package/lib/commonjs/Date/inputUtils.js +1 -1
  41. package/lib/commonjs/Date/inputUtils.js.map +1 -1
  42. package/lib/commonjs/TextInputMask.js +1 -1
  43. package/lib/commonjs/TextInputMask.js.map +1 -1
  44. package/lib/commonjs/Time/AmPmSwitcher.js.map +1 -1
  45. package/lib/commonjs/Time/AnalogClock.js +6 -4
  46. package/lib/commonjs/Time/AnalogClock.js.map +1 -1
  47. package/lib/commonjs/Time/AnalogClockHours.js +1 -1
  48. package/lib/commonjs/Time/AnalogClockHours.js.map +1 -1
  49. package/lib/commonjs/Time/AnalogClockMinutes.js.map +1 -1
  50. package/lib/commonjs/Time/AnimatedClockSwitcher.js.map +1 -1
  51. package/lib/commonjs/Time/TimeInput.js +1 -1
  52. package/lib/commonjs/Time/TimeInput.js.map +1 -1
  53. package/lib/commonjs/Time/TimeInputs.js +2 -2
  54. package/lib/commonjs/Time/TimeInputs.js.map +1 -1
  55. package/lib/commonjs/Time/TimePicker.js.map +1 -1
  56. package/lib/commonjs/Time/TimePickerModal.js +7 -2
  57. package/lib/commonjs/Time/TimePickerModal.js.map +1 -1
  58. package/lib/commonjs/Time/timeUtils.js +7 -1
  59. package/lib/commonjs/Time/timeUtils.js.map +1 -1
  60. package/lib/commonjs/index.js.map +1 -1
  61. package/lib/commonjs/translations/ar.js +25 -0
  62. package/lib/commonjs/translations/ar.js.map +1 -0
  63. package/lib/commonjs/translations/de.js.map +1 -1
  64. package/lib/commonjs/translations/en.js.map +1 -1
  65. package/lib/commonjs/translations/enGB.js.map +1 -1
  66. package/lib/commonjs/translations/fr.js +25 -0
  67. package/lib/commonjs/translations/fr.js.map +1 -0
  68. package/lib/commonjs/translations/ko.js +25 -0
  69. package/lib/commonjs/translations/ko.js.map +1 -0
  70. package/lib/commonjs/translations/nl.js.map +1 -1
  71. package/lib/commonjs/translations/pl.js.map +1 -1
  72. package/lib/commonjs/translations/pt.js.map +1 -1
  73. package/lib/commonjs/translations/utils.js +1 -1
  74. package/lib/commonjs/translations/utils.js.map +1 -1
  75. package/lib/commonjs/utils.js.map +1 -1
  76. package/lib/module/Date/AnimatedCrossView.js.map +1 -1
  77. package/lib/module/Date/AutoSizer.js.map +1 -1
  78. package/lib/module/Date/Calendar.js +6 -2
  79. package/lib/module/Date/Calendar.js.map +1 -1
  80. package/lib/module/Date/CalendarEdit.js +4 -4
  81. package/lib/module/Date/CalendarEdit.js.map +1 -1
  82. package/lib/module/Date/CalendarHeader.js.map +1 -1
  83. package/lib/module/Date/DatePickerInput.js +34 -87
  84. package/lib/module/Date/DatePickerInput.js.map +1 -1
  85. package/lib/module/Date/DatePickerInput.shared.js +2 -0
  86. package/lib/module/Date/DatePickerInput.shared.js.map +1 -0
  87. package/lib/module/Date/DatePickerInputWithoutModal.js +97 -0
  88. package/lib/module/Date/DatePickerInputWithoutModal.js.map +1 -0
  89. package/lib/module/Date/DatePickerModal.js +1 -1
  90. package/lib/module/Date/DatePickerModal.js.map +1 -1
  91. package/lib/module/Date/DatePickerModalContent.js +14 -8
  92. package/lib/module/Date/DatePickerModalContent.js.map +1 -1
  93. package/lib/module/Date/DatePickerModalContentHeader.js +5 -3
  94. package/lib/module/Date/DatePickerModalContentHeader.js.map +1 -1
  95. package/lib/module/Date/DatePickerModalHeader.js +5 -5
  96. package/lib/module/Date/DatePickerModalHeader.js.map +1 -1
  97. package/lib/module/Date/DatePickerModalHeaderBackground.js.map +1 -1
  98. package/lib/module/Date/DateRangeInput.js +3 -2
  99. package/lib/module/Date/DateRangeInput.js.map +1 -1
  100. package/lib/module/Date/Day.js.map +1 -1
  101. package/lib/module/Date/DayName.js.map +1 -1
  102. package/lib/module/Date/DayNames.js.map +1 -1
  103. package/lib/module/Date/DayRange.js.map +1 -1
  104. package/lib/module/Date/Month.js.map +1 -1
  105. package/lib/module/Date/Swiper.js.map +1 -1
  106. package/lib/module/Date/Swiper.native.js +2 -1
  107. package/lib/module/Date/Swiper.native.js.map +1 -1
  108. package/lib/module/Date/SwiperUtils.js.map +1 -1
  109. package/lib/module/Date/Week.js.map +1 -1
  110. package/lib/module/Date/YearPicker.js +5 -5
  111. package/lib/module/Date/YearPicker.js.map +1 -1
  112. package/lib/module/Date/dateUtils.js.map +1 -1
  113. package/lib/module/Date/dateUtils.test.js.map +1 -1
  114. package/lib/module/Date/inputUtils.js +1 -1
  115. package/lib/module/Date/inputUtils.js.map +1 -1
  116. package/lib/module/TextInputMask.js +1 -1
  117. package/lib/module/TextInputMask.js.map +1 -1
  118. package/lib/module/Time/AmPmSwitcher.js.map +1 -1
  119. package/lib/module/Time/AnalogClock.js +7 -5
  120. package/lib/module/Time/AnalogClock.js.map +1 -1
  121. package/lib/module/Time/AnalogClockHours.js +1 -1
  122. package/lib/module/Time/AnalogClockHours.js.map +1 -1
  123. package/lib/module/Time/AnalogClockMinutes.js.map +1 -1
  124. package/lib/module/Time/AnimatedClockSwitcher.js.map +1 -1
  125. package/lib/module/Time/TimeInput.js +1 -1
  126. package/lib/module/Time/TimeInput.js.map +1 -1
  127. package/lib/module/Time/TimeInputs.js +2 -2
  128. package/lib/module/Time/TimeInputs.js.map +1 -1
  129. package/lib/module/Time/TimePicker.js.map +1 -1
  130. package/lib/module/Time/TimePickerModal.js +8 -3
  131. package/lib/module/Time/TimePickerModal.js.map +1 -1
  132. package/lib/module/Time/timeUtils.js +3 -0
  133. package/lib/module/Time/timeUtils.js.map +1 -1
  134. package/lib/module/index.js.map +1 -1
  135. package/lib/module/translations/ar.js +18 -0
  136. package/lib/module/translations/ar.js.map +1 -0
  137. package/lib/module/translations/de.js.map +1 -1
  138. package/lib/module/translations/en.js.map +1 -1
  139. package/lib/module/translations/enGB.js.map +1 -1
  140. package/lib/module/translations/fr.js +18 -0
  141. package/lib/module/translations/fr.js.map +1 -0
  142. package/lib/module/translations/ko.js +18 -0
  143. package/lib/module/translations/ko.js.map +1 -0
  144. package/lib/module/translations/nl.js.map +1 -1
  145. package/lib/module/translations/pl.js.map +1 -1
  146. package/lib/module/translations/pt.js.map +1 -1
  147. package/lib/module/translations/utils.js +1 -1
  148. package/lib/module/translations/utils.js.map +1 -1
  149. package/lib/module/utils.js.map +1 -1
  150. package/lib/typescript/Date/Calendar.d.ts +2 -0
  151. package/lib/typescript/Date/DatePickerInput.d.ts +2 -16
  152. package/lib/typescript/Date/DatePickerInput.shared.d.ts +13 -0
  153. package/lib/typescript/Date/DatePickerInputWithoutModal.d.ts +51 -0
  154. package/lib/typescript/Date/DatePickerModalContent.d.ts +1 -0
  155. package/lib/typescript/Date/DatePickerModalContentHeader.d.ts +3 -0
  156. package/lib/typescript/Date/DatePickerModalHeader.d.ts +2 -0
  157. package/lib/typescript/Date/DateRangeInput.d.ts +2 -1
  158. package/lib/typescript/Date/YearPicker.d.ts +3 -1
  159. package/lib/typescript/TextInputMask.d.ts +31 -6
  160. package/lib/typescript/Time/TimePickerModal.d.ts +3 -1
  161. package/lib/typescript/Time/timeUtils.d.ts +1 -0
  162. package/lib/typescript/translations/ar.d.ts +3 -0
  163. package/lib/typescript/translations/fr.d.ts +3 -0
  164. package/lib/typescript/translations/ko.d.ts +3 -0
  165. package/package.json +26 -25
  166. package/src/Date/Calendar.tsx +7 -1
  167. package/src/Date/CalendarEdit.tsx +4 -4
  168. package/src/Date/DatePickerInput.shared.tsx +17 -0
  169. package/src/Date/DatePickerInput.tsx +32 -102
  170. package/src/Date/DatePickerInputWithoutModal.tsx +110 -0
  171. package/src/Date/DatePickerModalContent.tsx +10 -1
  172. package/src/Date/DatePickerModalContentHeader.tsx +13 -2
  173. package/src/Date/DatePickerModalHeader.tsx +5 -2
  174. package/src/Date/DateRangeInput.tsx +8 -2
  175. package/src/Date/Swiper.native.tsx +1 -0
  176. package/src/Date/YearPicker.tsx +5 -4
  177. package/src/Date/inputUtils.ts +1 -1
  178. package/src/Time/AnalogClock.tsx +12 -18
  179. package/src/Time/AnalogClockHours.tsx +1 -1
  180. package/src/Time/TimeInputs.tsx +2 -2
  181. package/src/Time/TimePickerModal.tsx +9 -2
  182. package/src/Time/timeUtils.ts +10 -0
  183. package/src/translations/ar.ts +21 -0
  184. package/src/translations/fr.ts +23 -0
  185. package/src/translations/ko.ts +21 -0
  186. package/src/translations/utils.ts +1 -1
@@ -0,0 +1,17 @@
1
+ import type { ValidRangeType } from './Calendar'
2
+ import type * as React from 'react'
3
+ import type { TextInput } from 'react-native-paper'
4
+
5
+ export type DatePickerInputProps = {
6
+ inputMode: 'start' | 'end'
7
+ locale: string
8
+ onChange: (date: Date | undefined) => void
9
+ value: Date | undefined
10
+ validRange?: ValidRangeType | undefined
11
+ withModal?: boolean
12
+ withDateFormatInLabel?: boolean
13
+ calendarIcon?: string
14
+ } & Omit<
15
+ React.ComponentProps<typeof TextInput>,
16
+ 'value' | 'onChange' | 'onChangeText'
17
+ >
@@ -1,55 +1,27 @@
1
1
  import * as React from 'react'
2
2
 
3
- import TextInputWithMask from '../TextInputMask'
4
- import { HelperText, IconButton, TextInput, useTheme } from 'react-native-paper'
5
- import { View, StyleSheet } from 'react-native'
3
+ import { IconButton } from 'react-native-paper'
4
+ import { StyleSheet } from 'react-native'
6
5
  import DatePickerModal from './DatePickerModal'
7
- import useDateInput from './inputUtils'
8
- import type { ValidRangeType } from './Calendar'
9
6
  import { useLatest } from '../utils'
7
+ import type { DatePickerInputProps } from './DatePickerInput.shared'
8
+ import DatePickerInputWithoutModal from './DatePickerInputWithoutModal'
10
9
 
11
10
  function DatePickerInput(
12
11
  {
13
- label,
14
- value,
15
- onChange,
16
- style,
17
- locale,
18
- validRange,
19
- inputMode,
20
12
  withModal = true,
21
- withDateFormatInLabel = true,
13
+ calendarIcon = 'calendar',
22
14
  ...rest
23
- }: {
24
- inputMode: 'start' | 'end'
25
- locale: string
26
- onChange: (date: Date | undefined) => void
27
- value: Date | undefined
28
- validRange?: ValidRangeType | undefined
29
- withModal?: boolean
30
- withDateFormatInLabel?: boolean
31
- } & Omit<
32
- React.ComponentProps<typeof TextInput>,
33
- 'value' | 'onChange' | 'onChangeText'
34
- >,
15
+ }: DatePickerInputProps,
35
16
  ref: any
36
17
  ) {
37
- const theme = useTheme()
38
- const { formattedValue, inputFormat, onChangeText, error } = useDateInput({
39
- locale,
40
- value,
41
- validRange,
42
- inputMode,
43
- onChange,
44
- })
45
-
46
18
  const [visible, setVisible] = React.useState<boolean>(false)
47
19
  const onDismiss = React.useCallback(() => {
48
20
  setVisible(false)
49
21
  }, [setVisible])
50
- const onChangeRef = useLatest(onChange)
22
+ const onChangeRef = useLatest(rest.onChange)
51
23
  const onInnerConfirm = React.useCallback(
52
- ({ date }) => {
24
+ ({ date }: any) => {
53
25
  setVisible(false)
54
26
  onChangeRef.current(date)
55
27
  },
@@ -57,81 +29,39 @@ function DatePickerInput(
57
29
  )
58
30
 
59
31
  return (
60
- <>
61
- <View style={styles.root}>
62
- <TextInputWithMask
63
- {...rest}
64
- ref={ref}
65
- label={getLabel({
66
- // TODO: support label components?
67
- label: label as any,
68
- inputFormat,
69
- withDateFormatInLabel,
70
- })}
71
- value={formattedValue}
72
- keyboardType={'number-pad'}
73
- placeholder={inputFormat}
74
- mask={inputFormat}
75
- onChangeText={onChangeText}
76
- keyboardAppearance={theme.dark ? 'dark' : 'default'}
77
- error={!!error}
78
- style={[styles.input, style]}
79
- />
80
- {withModal ? (
32
+ <DatePickerInputWithoutModal
33
+ ref={ref}
34
+ {...rest}
35
+ inputButtons={
36
+ withModal ? (
81
37
  <IconButton
82
38
  size={24}
83
39
  style={styles.calendarButton}
84
- icon="calendar"
40
+ icon={calendarIcon}
85
41
  onPress={() => setVisible(true)}
86
42
  />
87
- ) : null}
88
- </View>
89
- <HelperText type="error" visible={!!error}>
90
- {error}
91
- </HelperText>
92
-
93
- {withModal ? (
94
- <DatePickerModal
95
- date={value}
96
- mode="single"
97
- visible={visible}
98
- onDismiss={onDismiss}
99
- onConfirm={onInnerConfirm}
100
- locale={locale}
101
- dateMode={inputMode}
102
- validRange={validRange}
103
- />
104
- ) : null}
105
- </>
43
+ ) : null
44
+ }
45
+ modal={({ value, locale, inputMode, validRange }) =>
46
+ withModal ? (
47
+ <DatePickerModal
48
+ date={value}
49
+ mode="single"
50
+ visible={visible}
51
+ onDismiss={onDismiss}
52
+ onConfirm={onInnerConfirm}
53
+ locale={locale}
54
+ dateMode={inputMode}
55
+ validRange={validRange}
56
+ />
57
+ ) : null
58
+ }
59
+ />
106
60
  )
107
61
  }
108
62
 
109
- function getLabel({
110
- withDateFormatInLabel,
111
- inputFormat,
112
- label,
113
- }: {
114
- withDateFormatInLabel: boolean
115
- inputFormat: string
116
- label: string | undefined
117
- }) {
118
- if (withDateFormatInLabel) {
119
- return label ? `${label} (${inputFormat})` : inputFormat
120
- }
121
- return label || ''
122
- }
123
-
124
63
  const styles = StyleSheet.create({
125
- root: {
126
- minWidth: 150,
127
- flexDirection: 'row',
128
- position: 'relative',
129
- alignItems: 'center',
130
- flexGrow: 1,
131
- },
132
- input: {
133
- flexGrow: 1,
134
- },
135
64
  calendarButton: { position: 'absolute', right: 0, zIndex: 10 },
136
65
  })
66
+
137
67
  export default React.forwardRef(DatePickerInput)
@@ -0,0 +1,110 @@
1
+ import * as React from 'react'
2
+
3
+ import TextInputWithMask from '../TextInputMask'
4
+ import { HelperText, useTheme } from 'react-native-paper'
5
+ import { View, StyleSheet } from 'react-native'
6
+ import useDateInput from './inputUtils'
7
+ import type { DatePickerInputProps } from './DatePickerInput.shared'
8
+
9
+ function DatePickerInputWithoutModal(
10
+ {
11
+ label,
12
+ value,
13
+ onChange,
14
+ style,
15
+ locale,
16
+ validRange,
17
+ inputMode,
18
+ withDateFormatInLabel = true,
19
+ modal,
20
+ inputButtons,
21
+ ...rest
22
+ }: DatePickerInputProps & {
23
+ modal?: (params: {
24
+ value: DatePickerInputProps['value']
25
+ locale: DatePickerInputProps['locale']
26
+ inputMode: DatePickerInputProps['inputMode']
27
+ validRange: DatePickerInputProps['validRange']
28
+ }) => any
29
+ inputButtons?: any
30
+ },
31
+ ref: any
32
+ ) {
33
+ const theme = useTheme()
34
+ const { formattedValue, inputFormat, onChangeText, error } = useDateInput({
35
+ locale,
36
+ value,
37
+ validRange,
38
+ inputMode,
39
+ onChange,
40
+ })
41
+
42
+ return (
43
+ <>
44
+ <View style={styles.root}>
45
+ <TextInputWithMask
46
+ {...rest}
47
+ ref={ref}
48
+ label={getLabel({
49
+ // TODO: support label components?
50
+ label: label as any,
51
+ inputFormat,
52
+ withDateFormatInLabel,
53
+ })}
54
+ value={formattedValue}
55
+ keyboardType={'number-pad'}
56
+ placeholder={inputFormat}
57
+ mask={inputFormat}
58
+ onChangeText={onChangeText}
59
+ keyboardAppearance={theme.dark ? 'dark' : 'default'}
60
+ error={!!error}
61
+ style={[styles.input, style]}
62
+ />
63
+ {inputButtons}
64
+ {!!error ? (
65
+ <View style={styles.helperText}>
66
+ <HelperText
67
+ style={styles.helperText}
68
+ type="error"
69
+ visible={!!error}
70
+ >
71
+ {error}
72
+ </HelperText>
73
+ </View>
74
+ ) : null}
75
+ </View>
76
+ {modal?.({ value, locale, inputMode, validRange })}
77
+ </>
78
+ )
79
+ }
80
+
81
+ function getLabel({
82
+ withDateFormatInLabel,
83
+ inputFormat,
84
+ label,
85
+ }: {
86
+ withDateFormatInLabel: boolean
87
+ inputFormat: string
88
+ label: string | undefined
89
+ }) {
90
+ if (withDateFormatInLabel) {
91
+ return label ? `${label} (${inputFormat})` : inputFormat
92
+ }
93
+ return label || ''
94
+ }
95
+
96
+ const styles = StyleSheet.create({
97
+ root: {
98
+ minWidth: 150,
99
+ flexGrow: 1,
100
+ justifyContent: 'center',
101
+ },
102
+ helperTextContainer: {
103
+ flexDirection: 'row',
104
+ },
105
+ helperText: {
106
+ flex: 1,
107
+ },
108
+ input: {},
109
+ })
110
+ export default React.forwardRef(DatePickerInputWithoutModal)
@@ -31,6 +31,7 @@ interface DatePickerModalContentBaseProps {
31
31
  locale: string
32
32
  onDismiss: () => any
33
33
  disableSafeTop?: boolean
34
+ saveLabelDisabled?: boolean
34
35
  }
35
36
 
36
37
  export interface DatePickerModalContentRangeProps
@@ -81,6 +82,8 @@ export function DatePickerModalContent(
81
82
  locale,
82
83
  validRange,
83
84
  dateMode,
85
+ startYear,
86
+ endYear,
84
87
  } = props
85
88
 
86
89
  const anyProps = props as any
@@ -106,7 +109,7 @@ export function DatePickerModalContent(
106
109
  const [collapsed, setCollapsed] = React.useState<boolean>(true)
107
110
 
108
111
  const onInnerChange = React.useCallback(
109
- (params) => {
112
+ (params: any) => {
110
113
  onChange && onChange(params)
111
114
  setState((prev) => ({ ...prev, ...params }))
112
115
  },
@@ -142,8 +145,10 @@ export function DatePickerModalContent(
142
145
  onSave={onInnerConfirm}
143
146
  onDismiss={onDismiss}
144
147
  saveLabel={props.saveLabel}
148
+ saveLabelDisabled={props.saveLabelDisabled ?? false}
145
149
  uppercase={props.uppercase ?? true}
146
150
  disableSafeTop={disableSafeTop}
151
+ closeIcon={props.closeIcon}
147
152
  />
148
153
  <DatePickerModalContentHeader
149
154
  state={state}
@@ -158,6 +163,8 @@ export function DatePickerModalContent(
158
163
  endLabel={props.endLabel}
159
164
  uppercase={props.uppercase ?? true}
160
165
  locale={locale}
166
+ editIcon={props.editIcon}
167
+ calendarIcon={props.calendarIcon}
161
168
  />
162
169
  </DatePickerModalHeaderBackground>
163
170
 
@@ -175,6 +182,8 @@ export function DatePickerModalContent(
175
182
  dates={state.dates}
176
183
  validRange={validRange}
177
184
  dateMode={dateMode}
185
+ startYear={startYear}
186
+ endYear={endYear}
178
187
  />
179
188
  }
180
189
  calendarEdit={
@@ -16,6 +16,9 @@ export interface HeaderPickProps {
16
16
  headerSeparator?: string
17
17
  startLabel?: string
18
18
  endLabel?: string
19
+ editIcon?: string
20
+ calendarIcon?: string
21
+ closeIcon?: string
19
22
  }
20
23
 
21
24
  export interface HeaderContentProps extends HeaderPickProps {
@@ -49,7 +52,15 @@ function getLabel(
49
52
  export default function DatePickerModalContentHeader(
50
53
  props: HeaderContentProps
51
54
  ) {
52
- const { onToggle, collapsed, mode, moreLabel, uppercase } = props
55
+ const {
56
+ onToggle,
57
+ collapsed,
58
+ mode,
59
+ moreLabel,
60
+ uppercase,
61
+ editIcon = 'pencil',
62
+ calendarIcon = 'calendar',
63
+ } = props
53
64
 
54
65
  const label = getLabel(props.locale, props.mode, props.label)
55
66
 
@@ -80,7 +91,7 @@ export default function DatePickerModalContentHeader(
80
91
  <View style={styles.fill} />
81
92
  {allowEditing ? (
82
93
  <IconButton
83
- icon={collapsed ? 'pencil' : 'calendar'}
94
+ icon={collapsed ? editIcon : calendarIcon}
84
95
  accessibilityLabel={
85
96
  collapsed
86
97
  ? getTranslation(props.locale, 'typeInDate')
@@ -8,16 +8,18 @@ import { getTranslation } from '../translations/utils'
8
8
  export interface DatePickerModalHeaderProps {
9
9
  disableSafeTop?: boolean
10
10
  saveLabel?: string
11
+ saveLabelDisabled?: boolean
11
12
  uppercase?: boolean
12
13
  onDismiss: () => void
13
14
  onSave: () => void
14
15
  locale: string | undefined
16
+ closeIcon?: string
15
17
  }
16
18
 
17
19
  export default function DatePickerModalHeader(
18
20
  props: DatePickerModalHeaderProps
19
21
  ) {
20
- const { disableSafeTop, locale } = props
22
+ const { disableSafeTop, locale, closeIcon = 'close' } = props
21
23
  const saveLabel = props.saveLabel || getTranslation(locale, 'save')
22
24
  const color = useHeaderTextColor()
23
25
  return (
@@ -31,7 +33,7 @@ export default function DatePickerModalHeader(
31
33
  >
32
34
  <Appbar style={styles.appbarHeader}>
33
35
  <Appbar.Action
34
- icon="close"
36
+ icon={closeIcon}
35
37
  accessibilityLabel={getTranslation(locale, 'close')}
36
38
  onPress={props.onDismiss}
37
39
  color={color}
@@ -41,6 +43,7 @@ export default function DatePickerModalHeader(
41
43
  <Button
42
44
  color={color}
43
45
  onPress={props.onSave}
46
+ disabled={props.saveLabelDisabled ?? false}
44
47
  uppercase={props.uppercase ?? true}
45
48
  testID="react-native-paper-dates-save"
46
49
  >
@@ -5,7 +5,13 @@ import { Text, IconButton } from 'react-native-paper'
5
5
  import DatePickerModal from './DatePickerModal'
6
6
 
7
7
  // WORK IN PROGRESS
8
- export default function DateRangeInput({ locale }: { locale: string }) {
8
+ export default function DateRangeInput({
9
+ locale,
10
+ calendarIcon = 'calendar',
11
+ }: {
12
+ locale: string
13
+ calendarIcon?: string
14
+ }) {
9
15
  const [visible, setVisible] = React.useState<boolean>(false)
10
16
  const onDismiss = React.useCallback(() => {
11
17
  setVisible(false)
@@ -50,7 +56,7 @@ export default function DateRangeInput({ locale }: { locale: string }) {
50
56
  <Text>Tot</Text>
51
57
  </View>
52
58
  <View>
53
- <IconButton icon="calendar" onPress={() => setVisible(true)} />
59
+ <IconButton icon={calendarIcon} onPress={() => setVisible(true)} />
54
60
  <Text style={{ opacity: 0 }} accessible={false}>
55
61
  tot
56
62
  </Text>
@@ -147,6 +147,7 @@ function SwiperInner({
147
147
  return (
148
148
  <>
149
149
  <ScrollView
150
+ scrollsToTop={false}
150
151
  ref={parentRef}
151
152
  horizontal={isHorizontal}
152
153
  pagingEnabled={isHorizontal}
@@ -5,21 +5,22 @@ import { range } from '../utils'
5
5
 
6
6
  const ITEM_HEIGHT = 62
7
7
 
8
- const startYear = 1800
9
- const endYear = 2200
10
- const years = range(startYear, endYear)
11
-
12
8
  export default function YearPicker({
13
9
  selectedYear,
14
10
  selectingYear,
15
11
  onPressYear,
12
+ startYear,
13
+ endYear,
16
14
  }: {
17
15
  selectedYear: number | undefined
18
16
  selectingYear: boolean
19
17
  onPressYear: (year: number) => any
18
+ startYear: number
19
+ endYear: number
20
20
  }) {
21
21
  const theme = useTheme()
22
22
  const flatList = React.useRef<FlatList<number> | null>(null)
23
+ const years = range(isNaN(startYear) ? 1800 : startYear, isNaN(endYear) ? 2200 : endYear)
23
24
 
24
25
  // scroll to selected year
25
26
  React.useEffect(() => {
@@ -21,7 +21,7 @@ export default function useDateInput({
21
21
  const [error, setError] = React.useState<null | string>(null)
22
22
  const formatter = useInputFormatter({ locale })
23
23
  const inputFormat = useInputFormat({ formatter, locale })
24
- const formattedValue = formatter.format(value)
24
+ const formattedValue = value !== null ? formatter.format(value) : '';
25
25
  const onChangeText = (date: string) => {
26
26
  const dayIndex = inputFormat.indexOf('DD')
27
27
  const monthIndex = inputFormat.indexOf('MM')
@@ -12,18 +12,17 @@ import {
12
12
  getAngle,
13
13
  getHours,
14
14
  getHourType,
15
+ getHourTypeFromOffset,
15
16
  getMinutes,
17
+ hourTypes,
16
18
  PossibleClockTypes,
17
19
  } from './timeUtils'
18
20
  import * as React from 'react'
19
-
20
21
  import { useLatest } from '../utils'
21
22
  import AnalogClockHours from './AnalogClockHours'
22
-
23
23
  import AnimatedClockSwitcher from './AnimatedClockSwitcher'
24
24
  import AnalogClockMinutes from './AnalogClockMinutes'
25
25
  import { DisplayModeContext } from './TimePicker'
26
-
27
26
  function AnalogClock({
28
27
  hours,
29
28
  minutes,
@@ -45,9 +44,7 @@ function AnalogClock({
45
44
  const { mode } = React.useContext(DisplayModeContext)
46
45
  // used to make pointer shorter if hours are selected and above 12
47
46
  const shortPointer = (hours === 0 || hours > 12) && is24Hour
48
-
49
47
  const clockRef = React.useRef<View | null>(null)
50
-
51
48
  // Hooks are nice, sometimes... :-)..
52
49
  // We need the latest values, since the onPointerMove uses a closure to the function
53
50
  const hoursRef = useLatest(hours)
@@ -56,31 +53,35 @@ function AnalogClock({
56
53
  const focusedRef = useLatest(focused)
57
54
  const is24HourRef = useLatest(is24Hour)
58
55
  const modeRef = useLatest(mode)
59
-
60
56
  const onPointerMove = React.useCallback(
61
57
  (e: GestureResponderEvent, final: boolean) => {
62
58
  let x = e.nativeEvent.locationX
63
59
  let y = e.nativeEvent.locationY
64
-
65
60
  let angle = getAngle(x, y, circleSize)
66
-
67
61
  if (focusedRef.current === clockTypes.hours) {
68
62
  let hours24 = is24HourRef.current
69
63
  let previousHourType = getHourType(hoursRef.current)
70
64
  let pickedHours = getHours(angle, previousHourType)
71
65
 
72
- let hours12AndPm = !hours24 && modeRef.current === 'PM'
66
+ let hours12AndPm = !hours24 && modeRef.current === 'AM'
67
+
68
+ let hourTypeFromOffset = getHourTypeFromOffset(x, y, circleSize)
69
+ let hours24AndPM = hours24 && hourTypeFromOffset === hourTypes.pm
73
70
 
74
71
  // Avoiding the "24h"
75
72
  // Should be 12h for 12 hours and PM mode
76
- if ((hours12AndPm || hours24) && pickedHours + 12 < 24) {
73
+
74
+ if (hours12AndPm || hours24AndPM) {
77
75
  pickedHours += 12
78
76
  }
79
77
  if (modeRef.current === 'AM' && pickedHours === 12) {
80
78
  pickedHours = 0
81
79
  }
82
80
 
83
- if (pickedHours === 24) {
81
+ if (
82
+ (!hours24 && modeRef.current === 'AM' && pickedHours === 12) ||
83
+ pickedHours === 24
84
+ ) {
84
85
  pickedHours = 0
85
86
  }
86
87
 
@@ -103,13 +104,11 @@ function AnalogClock({
103
104
  },
104
105
  [focusedRef, is24HourRef, hoursRef, onChangeRef, minutesRef, modeRef]
105
106
  )
106
-
107
107
  const panResponder = React.useRef(
108
108
  PanResponder.create({
109
109
  onPanResponderGrant: (e) => onPointerMove(e, false),
110
110
  onPanResponderMove: (e) => onPointerMove(e, false),
111
111
  onPanResponderRelease: (e) => onPointerMove(e, true),
112
-
113
112
  onStartShouldSetPanResponder: returnTrue,
114
113
  onStartShouldSetPanResponderCapture: () => false,
115
114
  onMoveShouldSetPanResponder: returnTrue,
@@ -118,7 +117,6 @@ function AnalogClock({
118
117
  onShouldBlockNativeResponder: returnTrue,
119
118
  })
120
119
  ).current
121
-
122
120
  const dynamicSize = focused === clockTypes.hours && shortPointer ? 33 : 0
123
121
  const pointerNumber = focused === clockTypes.hours ? hours : minutes
124
122
  const degreesPerNumber = focused === clockTypes.hours ? 30 : 6
@@ -178,7 +176,6 @@ function AnalogClock({
178
176
  </View>
179
177
  )
180
178
  }
181
-
182
179
  const styles = StyleSheet.create({
183
180
  clock: {
184
181
  height: circleSize,
@@ -204,15 +201,12 @@ const styles = StyleSheet.create({
204
201
  },
205
202
  line: {
206
203
  position: 'absolute',
207
-
208
204
  marginBottom: -1,
209
205
  height: 2,
210
206
  borderRadius: 4,
211
207
  },
212
208
  })
213
-
214
209
  function returnTrue() {
215
210
  return true
216
211
  }
217
-
218
212
  export default React.memo(AnalogClock)
@@ -34,7 +34,7 @@ function AnalogClockHours({
34
34
  <View style={styles.outerHourInner}>
35
35
  {/* Display 00 instead of 12 for AM hours */}
36
36
  <Text style={hours === i + 1 ? { color } : null} selectable={false}>
37
- {mode === 'AM' && i + 1 === 12 ? '00' : i + 1}
37
+ {mode === 'AM' && !is24Hour && i + 1 === 12 ? '00' : i + 1}
38
38
  </Text>
39
39
  </View>
40
40
  </View>
@@ -118,8 +118,8 @@ function TimeInputs({
118
118
  onSubmitEditing={onSubmitEndInput}
119
119
  onChanged={(newMinutesFromInput) => {
120
120
  let newMinutes = newMinutesFromInput
121
- if (newMinutesFromInput > 60) {
122
- newMinutes = 60
121
+ if (newMinutesFromInput > 59) {
122
+ newMinutes = 59
123
123
  }
124
124
  onChange({
125
125
  hours,
@@ -13,7 +13,7 @@ import { Button, IconButton, overlay, useTheme } from 'react-native-paper'
13
13
  import TimePicker from './TimePicker'
14
14
  import {
15
15
  clockTypes,
16
- inputTypeIcons,
16
+ getTimeInputTypeIcon,
17
17
  inputTypes,
18
18
  PossibleClockTypes,
19
19
  PossibleInputTypes,
@@ -40,6 +40,8 @@ export function TimePickerModal({
40
40
  confirmLabel = 'Ok',
41
41
  animationType = 'none',
42
42
  locale,
43
+ keyboardIcon = 'keyboard-outline',
44
+ clockIcon = 'clock-outline',
43
45
  }: {
44
46
  locale?: undefined | string
45
47
  label?: string
@@ -52,6 +54,8 @@ export function TimePickerModal({
52
54
  onDismiss: () => any
53
55
  onConfirm: (hoursAndMinutes: { hours: number; minutes: number }) => any
54
56
  animationType?: 'slide' | 'fade' | 'none'
57
+ keyboardIcon?: string
58
+ clockIcon?: string
55
59
  }) {
56
60
  const theme = useTheme()
57
61
 
@@ -152,7 +156,10 @@ export function TimePickerModal({
152
156
  </View>
153
157
  <View style={styles.bottom}>
154
158
  <IconButton
155
- icon={inputTypeIcons[reverseInputTypes[inputType]]}
159
+ icon={getTimeInputTypeIcon(inputType, {
160
+ keyboard: keyboardIcon,
161
+ picker: clockIcon,
162
+ })}
156
163
  onPress={() => setInputType(reverseInputTypes[inputType])}
157
164
  size={24}
158
165
  style={styles.inputTypeToggle}
@@ -45,6 +45,16 @@ export const inputTypeIcons: InputIconMap = {
45
45
  picker: 'clock-outline',
46
46
  }
47
47
 
48
+ export const getTimeInputTypeIcon = (
49
+ inputType: PossibleInputTypes,
50
+ inputIconMap?: InputIconMap
51
+ ) => {
52
+ return (
53
+ inputIconMap?.[reverseInputTypes[inputType]] ||
54
+ inputTypeIcons?.[reverseInputTypes[inputType]]
55
+ )
56
+ }
57
+
48
58
  export type PossibleClockTypes = 'hours' | 'minutes'
49
59
  export type ClockTypeMap = {
50
60
  [clockType in PossibleClockTypes]: PossibleClockTypes