react-native-paper-dates 0.11.8 → 0.11.10

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 (43) hide show
  1. package/lib/commonjs/Date/DatePickerInput.js +12 -3
  2. package/lib/commonjs/Date/DatePickerInput.js.map +1 -1
  3. package/lib/commonjs/Date/DatePickerInput.shared.js.map +1 -1
  4. package/lib/commonjs/Date/DatePickerInputWithoutModal.js +21 -11
  5. package/lib/commonjs/Date/DatePickerInputWithoutModal.js.map +1 -1
  6. package/lib/commonjs/Date/inputUtils.js +12 -4
  7. package/lib/commonjs/Date/inputUtils.js.map +1 -1
  8. package/lib/commonjs/TextInputMask.js +4 -0
  9. package/lib/commonjs/TextInputMask.js.map +1 -1
  10. package/lib/commonjs/Time/AnalogClock.js +1 -1
  11. package/lib/commonjs/Time/AnalogClock.js.map +1 -1
  12. package/lib/commonjs/Time/AnalogClockHours.js +1 -1
  13. package/lib/commonjs/Time/AnalogClockHours.js.map +1 -1
  14. package/lib/commonjs/Time/timeUtils.js +9 -5
  15. package/lib/commonjs/Time/timeUtils.js.map +1 -1
  16. package/lib/module/Date/DatePickerInput.js +12 -3
  17. package/lib/module/Date/DatePickerInput.js.map +1 -1
  18. package/lib/module/Date/DatePickerInput.shared.js.map +1 -1
  19. package/lib/module/Date/DatePickerInputWithoutModal.js +21 -11
  20. package/lib/module/Date/DatePickerInputWithoutModal.js.map +1 -1
  21. package/lib/module/Date/inputUtils.js +12 -4
  22. package/lib/module/Date/inputUtils.js.map +1 -1
  23. package/lib/module/TextInputMask.js +4 -0
  24. package/lib/module/TextInputMask.js.map +1 -1
  25. package/lib/module/Time/AnalogClock.js +1 -1
  26. package/lib/module/Time/AnalogClock.js.map +1 -1
  27. package/lib/module/Time/AnalogClockHours.js +1 -1
  28. package/lib/module/Time/AnalogClockHours.js.map +1 -1
  29. package/lib/module/Time/timeUtils.js +9 -5
  30. package/lib/module/Time/timeUtils.js.map +1 -1
  31. package/lib/typescript/Date/DatePickerInput.d.ts +1 -1
  32. package/lib/typescript/Date/DatePickerInput.shared.d.ts +8 -0
  33. package/lib/typescript/Date/DatePickerInputWithoutModal.d.ts +13 -1
  34. package/lib/typescript/Date/inputUtils.d.ts +2 -1
  35. package/package.json +1 -1
  36. package/src/Date/DatePickerInput.shared.tsx +8 -0
  37. package/src/Date/DatePickerInput.tsx +16 -1
  38. package/src/Date/DatePickerInputWithoutModal.tsx +36 -11
  39. package/src/Date/inputUtils.ts +16 -9
  40. package/src/TextInputMask.tsx +4 -0
  41. package/src/Time/AnalogClock.tsx +1 -1
  42. package/src/Time/AnalogClockHours.tsx +1 -1
  43. package/src/Time/timeUtils.ts +7 -4
@@ -7,8 +7,16 @@ declare const _default: React.ForwardRefExoticComponent<Pick<{
7
7
  validRange?: import("./Calendar").ValidRangeType | undefined;
8
8
  withModal?: boolean | undefined;
9
9
  withDateFormatInLabel?: boolean | undefined;
10
+ hideValidationErrors?: boolean | undefined;
11
+ hasError?: boolean | undefined;
12
+ onValidationError?: ((error: string | null) => void) | undefined;
10
13
  calendarIcon?: string | undefined;
11
14
  saveLabel?: string | undefined;
15
+ saveLabelDisabled?: boolean | undefined;
16
+ uppercase?: boolean | undefined;
17
+ startYear?: number | undefined;
18
+ endYear?: number | undefined;
19
+ onChangeText?: ((text: string | undefined) => void) | undefined;
12
20
  } & Omit<Pick<import("react-native").TextInputProps & React.RefAttributes<import("react-native").TextInput> & {
13
21
  mode?: "flat" | "outlined" | undefined;
14
22
  left?: React.ReactNode;
@@ -51,7 +59,11 @@ declare const _default: React.ForwardRefExoticComponent<Pick<{
51
59
  inputMode: "end" | "start";
52
60
  validRange: import("./Calendar").ValidRangeType | undefined;
53
61
  saveLabel: string | undefined;
62
+ saveLabelDisabled: boolean | undefined;
63
+ uppercase: boolean | undefined;
64
+ startYear: number | undefined;
65
+ endYear: number | undefined;
54
66
  }) => any) | undefined;
55
67
  inputButtons?: any;
56
- }, "label" | "style" | "children" | "pointerEvents" | "allowFontScaling" | "numberOfLines" | "onLayout" | "onPressIn" | "onPressOut" | "testID" | "nativeID" | "maxFontSizeMultiplier" | "disabled" | "selectionColor" | "textBreakStrategy" | "accessible" | "accessibilityActions" | "accessibilityLabel" | "accessibilityRole" | "accessibilityState" | "accessibilityHint" | "accessibilityValue" | "onAccessibilityAction" | "accessibilityLabelledBy" | "accessibilityLiveRegion" | "importantForAccessibility" | "accessibilityElementsHidden" | "accessibilityLanguage" | "accessibilityViewIsModal" | "onAccessibilityEscape" | "onAccessibilityTap" | "onMagicTap" | "accessibilityIgnoresInvertColors" | "left" | "right" | "key" | "hitSlop" | "removeClippedSubviews" | "collapsable" | "needsOffscreenAlphaCompositing" | "renderToHardwareTextureAndroid" | "focusable" | "shouldRasterizeIOS" | "isTVSelectable" | "hasTVPreferredFocus" | "tvParallaxProperties" | "tvParallaxShiftDistanceX" | "tvParallaxShiftDistanceY" | "tvParallaxTiltAngle" | "tvParallaxMagnification" | "onStartShouldSetResponder" | "onMoveShouldSetResponder" | "onResponderEnd" | "onResponderGrant" | "onResponderReject" | "onResponderMove" | "onResponderRelease" | "onResponderStart" | "onResponderTerminationRequest" | "onResponderTerminate" | "onStartShouldSetResponderCapture" | "onMoveShouldSetResponderCapture" | "onTouchStart" | "onTouchMove" | "onTouchEnd" | "onTouchCancel" | "onTouchEndCapture" | "onPointerEnter" | "onPointerEnterCapture" | "onPointerLeave" | "onPointerLeaveCapture" | "onPointerMove" | "onPointerMoveCapture" | "onPointerCancel" | "onPointerCancelCapture" | "onPointerDown" | "onPointerDownCapture" | "onPointerUp" | "onPointerUpCapture" | "value" | "mode" | "error" | "placeholder" | "onFocus" | "onBlur" | "onChange" | "onKeyPress" | "onScroll" | "defaultValue" | "spellCheck" | "autoCapitalize" | "autoCorrect" | "autoFocus" | "autoComplete" | "maxLength" | "textAlign" | "textAlignVertical" | "multiline" | "onContentSizeChange" | "scrollEnabled" | "textColor" | "dense" | "render" | "blurOnSubmit" | "caretHidden" | "contextMenuHidden" | "editable" | "keyboardType" | "onEndEditing" | "onSelectionChange" | "onSubmitEditing" | "onTextInput" | "placeholderTextColor" | "returnKeyType" | "secureTextEntry" | "selectTextOnFocus" | "selection" | "inputAccessoryViewID" | "clearButtonMode" | "clearTextOnFocus" | "dataDetectorTypes" | "enablesReturnKeyAutomatically" | "keyboardAppearance" | "passwordRules" | "rejectResponderTermination" | "selectionState" | "textContentType" | "cursorColor" | "importantForAutofill" | "disableFullscreenUI" | "inlineImageLeft" | "inlineImagePadding" | "returnKeyLabel" | "underlineColorAndroid" | "showSoftInputOnFocus" | "underlineColor" | "activeUnderlineColor" | "outlineColor" | "activeOutlineColor" | "outlineStyle" | "underlineStyle" | "theme" | "locale" | "validRange" | "calendarIcon" | "inputMode" | "saveLabel" | "withDateFormatInLabel" | "modal" | "inputButtons" | "withModal"> & React.RefAttributes<unknown>>;
68
+ }, "label" | "style" | "children" | "pointerEvents" | "allowFontScaling" | "numberOfLines" | "onLayout" | "onPressIn" | "onPressOut" | "testID" | "nativeID" | "maxFontSizeMultiplier" | "disabled" | "selectionColor" | "textBreakStrategy" | "accessible" | "accessibilityActions" | "accessibilityLabel" | "accessibilityRole" | "accessibilityState" | "accessibilityHint" | "accessibilityValue" | "onAccessibilityAction" | "accessibilityLabelledBy" | "accessibilityLiveRegion" | "importantForAccessibility" | "accessibilityElementsHidden" | "accessibilityLanguage" | "accessibilityViewIsModal" | "onAccessibilityEscape" | "onAccessibilityTap" | "onMagicTap" | "accessibilityIgnoresInvertColors" | "left" | "right" | "key" | "hitSlop" | "removeClippedSubviews" | "collapsable" | "needsOffscreenAlphaCompositing" | "renderToHardwareTextureAndroid" | "focusable" | "shouldRasterizeIOS" | "isTVSelectable" | "hasTVPreferredFocus" | "tvParallaxProperties" | "tvParallaxShiftDistanceX" | "tvParallaxShiftDistanceY" | "tvParallaxTiltAngle" | "tvParallaxMagnification" | "onStartShouldSetResponder" | "onMoveShouldSetResponder" | "onResponderEnd" | "onResponderGrant" | "onResponderReject" | "onResponderMove" | "onResponderRelease" | "onResponderStart" | "onResponderTerminationRequest" | "onResponderTerminate" | "onStartShouldSetResponderCapture" | "onMoveShouldSetResponderCapture" | "onTouchStart" | "onTouchMove" | "onTouchEnd" | "onTouchCancel" | "onTouchEndCapture" | "onPointerEnter" | "onPointerEnterCapture" | "onPointerLeave" | "onPointerLeaveCapture" | "onPointerMove" | "onPointerMoveCapture" | "onPointerCancel" | "onPointerCancelCapture" | "onPointerDown" | "onPointerDownCapture" | "onPointerUp" | "onPointerUpCapture" | "value" | "mode" | "error" | "placeholder" | "onFocus" | "onBlur" | "onChange" | "onKeyPress" | "onScroll" | "defaultValue" | "spellCheck" | "autoCapitalize" | "autoCorrect" | "autoFocus" | "autoComplete" | "maxLength" | "textAlign" | "textAlignVertical" | "multiline" | "onContentSizeChange" | "scrollEnabled" | "textColor" | "dense" | "render" | "blurOnSubmit" | "caretHidden" | "contextMenuHidden" | "editable" | "keyboardType" | "onChangeText" | "onEndEditing" | "onSelectionChange" | "onSubmitEditing" | "onTextInput" | "placeholderTextColor" | "returnKeyType" | "secureTextEntry" | "selectTextOnFocus" | "selection" | "inputAccessoryViewID" | "clearButtonMode" | "clearTextOnFocus" | "dataDetectorTypes" | "enablesReturnKeyAutomatically" | "keyboardAppearance" | "passwordRules" | "rejectResponderTermination" | "selectionState" | "textContentType" | "cursorColor" | "importantForAutofill" | "disableFullscreenUI" | "inlineImageLeft" | "inlineImagePadding" | "returnKeyLabel" | "underlineColorAndroid" | "showSoftInputOnFocus" | "underlineColor" | "activeUnderlineColor" | "outlineColor" | "activeOutlineColor" | "outlineStyle" | "underlineStyle" | "theme" | "locale" | "uppercase" | "validRange" | "startYear" | "endYear" | "calendarIcon" | "inputMode" | "onValidationError" | "saveLabel" | "saveLabelDisabled" | "withDateFormatInLabel" | "hasError" | "hideValidationErrors" | "modal" | "inputButtons" | "withModal"> & React.RefAttributes<unknown>>;
57
69
  export default _default;
@@ -1,10 +1,11 @@
1
1
  import type { ValidRangeType } from './Calendar';
2
- export default function useDateInput({ locale, value, validRange, inputMode, onChange, }: {
2
+ export default function useDateInput({ locale, value, validRange, inputMode, onChange, onValidationError, }: {
3
3
  onChange: (d: Date) => void;
4
4
  locale: undefined | string;
5
5
  value: Date | undefined;
6
6
  validRange: ValidRangeType | undefined;
7
7
  inputMode: 'start' | 'end';
8
+ onValidationError?: ((error: string | null) => void) | undefined;
8
9
  }): {
9
10
  onChange: (d: Date) => void;
10
11
  error: string | null;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-paper-dates",
3
- "version": "0.11.8",
3
+ "version": "0.11.10",
4
4
  "description": "Performant Date Picker for React Native Paper",
5
5
  "main": "lib/commonjs/index",
6
6
  "module": "lib/module/index",
@@ -10,8 +10,16 @@ export type DatePickerInputProps = {
10
10
  validRange?: ValidRangeType | undefined
11
11
  withModal?: boolean
12
12
  withDateFormatInLabel?: boolean
13
+ hideValidationErrors?: boolean
14
+ hasError?: boolean
15
+ onValidationError?: ((error: string | null) => void) | undefined
13
16
  calendarIcon?: string
14
17
  saveLabel?: string
18
+ saveLabelDisabled?: boolean
19
+ uppercase?: boolean
20
+ startYear?: number
21
+ endYear?: number
22
+ onChangeText?: (text: string | undefined) => void
15
23
  } & Omit<
16
24
  React.ComponentProps<typeof TextInput>,
17
25
  'value' | 'onChange' | 'onChangeText'
@@ -42,7 +42,18 @@ function DatePickerInput(
42
42
  />
43
43
  ) : null
44
44
  }
45
- modal={({ value, locale, inputMode, validRange, saveLabel }) =>
45
+ // eslint-disable-next-line react/no-unstable-nested-components
46
+ modal={({
47
+ value,
48
+ locale,
49
+ inputMode,
50
+ validRange,
51
+ saveLabel,
52
+ saveLabelDisabled,
53
+ uppercase,
54
+ startYear,
55
+ endYear,
56
+ }) =>
46
57
  withModal ? (
47
58
  <DatePickerModal
48
59
  date={value}
@@ -54,6 +65,10 @@ function DatePickerInput(
54
65
  dateMode={inputMode}
55
66
  validRange={validRange}
56
67
  saveLabel={saveLabel}
68
+ saveLabelDisabled={saveLabelDisabled ?? false}
69
+ uppercase={uppercase ?? true}
70
+ startYear={startYear ?? 1800}
71
+ endYear={endYear ?? 2200}
57
72
  />
58
73
  ) : null
59
74
  }
@@ -16,9 +16,17 @@ function DatePickerInputWithoutModal(
16
16
  validRange,
17
17
  inputMode,
18
18
  withDateFormatInLabel = true,
19
+ hasError,
20
+ hideValidationErrors,
21
+ onValidationError,
19
22
  modal,
20
23
  inputButtons,
21
24
  saveLabel,
25
+ saveLabelDisabled,
26
+ uppercase,
27
+ startYear,
28
+ endYear,
29
+ onChangeText,
22
30
  ...rest
23
31
  }: DatePickerInputProps & {
24
32
  modal?: (params: {
@@ -27,18 +35,28 @@ function DatePickerInputWithoutModal(
27
35
  inputMode: DatePickerInputProps['inputMode']
28
36
  validRange: DatePickerInputProps['validRange']
29
37
  saveLabel: DatePickerInputProps['saveLabel']
38
+ saveLabelDisabled: DatePickerInputProps['saveLabelDisabled']
39
+ uppercase: DatePickerInputProps['uppercase']
40
+ startYear: DatePickerInputProps['startYear']
41
+ endYear: DatePickerInputProps['endYear']
30
42
  }) => any
31
43
  inputButtons?: any
32
44
  },
33
45
  ref: any
34
46
  ) {
35
47
  const theme = useTheme()
36
- const { formattedValue, inputFormat, onChangeText, error } = useDateInput({
48
+ const {
49
+ formattedValue,
50
+ inputFormat,
51
+ onChangeText: onDateInputChangeText,
52
+ error,
53
+ } = useDateInput({
37
54
  locale,
38
55
  value,
39
56
  validRange,
40
57
  inputMode,
41
58
  onChange,
59
+ onValidationError,
42
60
  })
43
61
 
44
62
  return (
@@ -55,23 +73,33 @@ function DatePickerInputWithoutModal(
55
73
  withDateFormatInLabel,
56
74
  })}
57
75
  value={formattedValue}
58
- keyboardType={'number-pad'}
59
- placeholder={inputFormat}
76
+ keyboardType={rest.keyboardType ?? 'number-pad'}
60
77
  mask={inputFormat}
61
- onChangeText={onChangeText}
78
+ onChangeText={onDateInputChangeText}
79
+ onChange={(e) => onChangeText && onChangeText(e.nativeEvent.text)}
62
80
  keyboardAppearance={theme.dark ? 'dark' : 'default'}
63
- error={!!error}
81
+ error={(!!error && !hideValidationErrors) || !!hasError}
64
82
  style={[styles.input, style]}
65
83
  />
66
84
  {inputButtons}
67
85
  </View>
68
- {error ? (
69
- <HelperText style={styles.helperText} type="error" visible={!!error}>
86
+ {error && !hideValidationErrors ? (
87
+ <HelperText type="error" visible={!!error}>
70
88
  {error}
71
89
  </HelperText>
72
90
  ) : null}
73
91
  </View>
74
- {modal?.({ value, locale, inputMode, validRange, saveLabel })}
92
+ {modal?.({
93
+ value,
94
+ locale,
95
+ inputMode,
96
+ validRange,
97
+ saveLabel,
98
+ saveLabelDisabled,
99
+ uppercase,
100
+ startYear,
101
+ endYear,
102
+ })}
75
103
  </>
76
104
  )
77
105
  }
@@ -104,8 +132,5 @@ const styles = StyleSheet.create({
104
132
  input: {
105
133
  flexGrow: 1,
106
134
  },
107
- helperText: {
108
- // flex: 1,
109
- },
110
135
  })
111
136
  export default React.forwardRef(DatePickerInputWithoutModal)
@@ -9,19 +9,21 @@ export default function useDateInput({
9
9
  validRange,
10
10
  inputMode,
11
11
  onChange,
12
+ onValidationError,
12
13
  }: {
13
14
  onChange: (d: Date) => void
14
15
  locale: undefined | string
15
16
  value: Date | undefined
16
17
  validRange: ValidRangeType | undefined
17
18
  inputMode: 'start' | 'end'
19
+ onValidationError?: ((error: string | null) => void) | undefined
18
20
  }) {
19
21
  const { isDisabled, isWithinValidRange, validStart, validEnd } =
20
22
  useRangeChecker(validRange)
21
23
  const [error, setError] = React.useState<null | string>(null)
22
24
  const formatter = useInputFormatter({ locale })
23
25
  const inputFormat = useInputFormat({ formatter, locale })
24
- const formattedValue = value !== null ? formatter.format(value) : ''
26
+ const formattedValue = value ? formatter.format(value) : ''
25
27
  const onChangeText = (date: string) => {
26
28
  const dayIndex = inputFormat.indexOf('DD')
27
29
  const monthIndex = inputFormat.indexOf('MM')
@@ -35,13 +37,13 @@ export default function useDateInput({
35
37
  const month = Number(date.slice(monthIndex, monthIndex + 2))
36
38
 
37
39
  if (Number.isNaN(day) || Number.isNaN(year) || Number.isNaN(month)) {
38
- setError(
39
- getTranslation(
40
- locale,
41
- 'notAccordingToDateFormat',
42
- () => 'notAccordingToDateFormat'
43
- )(inputFormat)
44
- )
40
+ const inputError = getTranslation(
41
+ locale,
42
+ 'notAccordingToDateFormat',
43
+ () => 'notAccordingToDateFormat'
44
+ )(inputFormat)
45
+ setError(inputError)
46
+ onValidationError && onValidationError(inputError)
45
47
  return
46
48
  }
47
49
 
@@ -51,7 +53,9 @@ export default function useDateInput({
51
53
  : new Date(year, month - 1, day)
52
54
 
53
55
  if (isDisabled(finalDate)) {
54
- setError(getTranslation(locale, 'dateIsDisabled'))
56
+ const inputError = getTranslation(locale, 'dateIsDisabled')
57
+ setError(inputError)
58
+ onValidationError && onValidationError(inputError)
55
59
  return
56
60
  }
57
61
  if (!isWithinValidRange(finalDate)) {
@@ -80,11 +84,14 @@ export default function useDateInput({
80
84
  )(formatter.format(validEnd))
81
85
  : '',
82
86
  ]
87
+ const inputError = errors.filter((n) => n).join(' ')
83
88
  setError(errors.filter((n) => n).join(' '))
89
+ onValidationError && onValidationError(inputError)
84
90
  return
85
91
  }
86
92
 
87
93
  setError(null)
94
+ onValidationError && onValidationError(null)
88
95
  if (inputMode === 'end') {
89
96
  onChange(finalDate)
90
97
  } else {
@@ -69,6 +69,7 @@ function enhanceTextWithMask(
69
69
  function TextInputWithMask(
70
70
  {
71
71
  onChangeText,
72
+ onChange,
72
73
  value,
73
74
  mask,
74
75
  ...rest
@@ -101,6 +102,9 @@ function TextInputWithMask(
101
102
  {...rest}
102
103
  value={controlledValue}
103
104
  onChangeText={onInnerChange}
105
+ onChange={(e) => {
106
+ onChange && onChange(e)
107
+ }}
104
108
  onBlur={onInnerBlur}
105
109
  />
106
110
  )
@@ -63,7 +63,7 @@ function AnalogClock({
63
63
  let previousHourType = getHourType(hoursRef.current)
64
64
  let pickedHours = getHours(angle, previousHourType)
65
65
 
66
- let hours12AndPm = !hours24 && modeRef.current === 'AM'
66
+ let hours12AndPm = !hours24 && modeRef.current === 'PM'
67
67
 
68
68
  let hourTypeFromOffset = getHourTypeFromOffset(x, y, circleSize)
69
69
  let hours24AndPM = hours24 && hourTypeFromOffset === hourTypes.pm
@@ -38,7 +38,7 @@ function AnalogClockHours({
38
38
  variant="bodyLarge"
39
39
  selectable={false}
40
40
  >
41
- {mode === 'AM' && !is24Hour && i + 1 === 12 ? '00' : i + 1}
41
+ {mode === 'AM' && is24Hour && i + 1 === 12 ? '00' : i + 1}
42
42
  </Text>
43
43
  </View>
44
44
  </View>
@@ -242,15 +242,18 @@ export function useInputColors(highlighted: boolean) {
242
242
  }
243
243
 
244
244
  export function toHourInputFormat(hours: number, is24Hour: boolean): number {
245
- if (hours === 24) {
246
- return 0
247
- }
248
245
  if (is24Hour) {
246
+ if (hours === 24) {
247
+ return 0
248
+ }
249
249
  return hours
250
250
  }
251
251
  if (hours > 12) {
252
252
  return hours - 12
253
253
  }
254
+ if (hours === 0) {
255
+ return hours + 12
256
+ }
254
257
  return hours
255
258
  }
256
259
 
@@ -262,7 +265,7 @@ export function toHourOutputFormat(
262
265
  if (is24Hour) {
263
266
  return newHours
264
267
  }
265
- if (previousHours > 12 && newHours < 12) {
268
+ if ((!is24Hour && previousHours === 0) || newHours === 0) {
266
269
  return newHours + 12
267
270
  }
268
271
  return newHours