react-native-paper-dates 0.24.0 → 0.24.1

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 (116) hide show
  1. package/lib/commonjs/Date/AnimatedCrossView.js +2 -2
  2. package/lib/commonjs/Date/AnimatedCrossView.js.map +1 -1
  3. package/lib/commonjs/Date/AutoSizer.js +24 -11
  4. package/lib/commonjs/Date/AutoSizer.js.map +1 -1
  5. package/lib/commonjs/Date/Calendar.js +5 -3
  6. package/lib/commonjs/Date/Calendar.js.map +1 -1
  7. package/lib/commonjs/Date/CalendarEdit.js +70 -61
  8. package/lib/commonjs/Date/CalendarEdit.js.map +1 -1
  9. package/lib/commonjs/Date/CalendarHeader.js +30 -15
  10. package/lib/commonjs/Date/CalendarHeader.js.map +1 -1
  11. package/lib/commonjs/Date/DatePickerModal.js +5 -11
  12. package/lib/commonjs/Date/DatePickerModal.js.map +1 -1
  13. package/lib/commonjs/Date/DatePickerModalContent.js +48 -34
  14. package/lib/commonjs/Date/DatePickerModalContent.js.map +1 -1
  15. package/lib/commonjs/Date/DatePickerModalContentHeader.js +12 -5
  16. package/lib/commonjs/Date/DatePickerModalContentHeader.js.map +1 -1
  17. package/lib/commonjs/Date/DatePickerModalHeader.js +40 -40
  18. package/lib/commonjs/Date/DatePickerModalHeader.js.map +1 -1
  19. package/lib/commonjs/Date/DatePickerModalHeaderBackground.js +22 -4
  20. package/lib/commonjs/Date/DatePickerModalHeaderBackground.js.map +1 -1
  21. package/lib/commonjs/Date/Month.js +44 -30
  22. package/lib/commonjs/Date/Month.js.map +1 -1
  23. package/lib/commonjs/Date/Swiper.js +31 -21
  24. package/lib/commonjs/Date/Swiper.js.map +1 -1
  25. package/lib/commonjs/Date/Swiper.native.js +37 -21
  26. package/lib/commonjs/Date/Swiper.native.js.map +1 -1
  27. package/lib/commonjs/Date/SwiperUtils.js.map +1 -1
  28. package/lib/commonjs/Date/YearPicker.js +3 -1
  29. package/lib/commonjs/Date/YearPicker.js.map +1 -1
  30. package/lib/commonjs/Date/weekdayColumns.js +60 -0
  31. package/lib/commonjs/Date/weekdayColumns.js.map +1 -0
  32. package/lib/commonjs/shared/styles.js +3 -0
  33. package/lib/commonjs/shared/styles.js.map +1 -1
  34. package/lib/commonjs/shared/utils.js +9 -0
  35. package/lib/commonjs/shared/utils.js.map +1 -1
  36. package/lib/module/Date/AnimatedCrossView.js +2 -2
  37. package/lib/module/Date/AnimatedCrossView.js.map +1 -1
  38. package/lib/module/Date/AutoSizer.js +25 -12
  39. package/lib/module/Date/AutoSizer.js.map +1 -1
  40. package/lib/module/Date/Calendar.js +5 -3
  41. package/lib/module/Date/Calendar.js.map +1 -1
  42. package/lib/module/Date/CalendarEdit.js +70 -61
  43. package/lib/module/Date/CalendarEdit.js.map +1 -1
  44. package/lib/module/Date/CalendarHeader.js +31 -16
  45. package/lib/module/Date/CalendarHeader.js.map +1 -1
  46. package/lib/module/Date/DatePickerModal.js +7 -13
  47. package/lib/module/Date/DatePickerModal.js.map +1 -1
  48. package/lib/module/Date/DatePickerModalContent.js +48 -34
  49. package/lib/module/Date/DatePickerModalContent.js.map +1 -1
  50. package/lib/module/Date/DatePickerModalContentHeader.js +12 -5
  51. package/lib/module/Date/DatePickerModalContentHeader.js.map +1 -1
  52. package/lib/module/Date/DatePickerModalHeader.js +43 -43
  53. package/lib/module/Date/DatePickerModalHeader.js.map +1 -1
  54. package/lib/module/Date/DatePickerModalHeaderBackground.js +24 -6
  55. package/lib/module/Date/DatePickerModalHeaderBackground.js.map +1 -1
  56. package/lib/module/Date/Month.js +46 -32
  57. package/lib/module/Date/Month.js.map +1 -1
  58. package/lib/module/Date/Swiper.js +32 -22
  59. package/lib/module/Date/Swiper.js.map +1 -1
  60. package/lib/module/Date/Swiper.native.js +38 -22
  61. package/lib/module/Date/Swiper.native.js.map +1 -1
  62. package/lib/module/Date/SwiperUtils.js.map +1 -1
  63. package/lib/module/Date/YearPicker.js +4 -2
  64. package/lib/module/Date/YearPicker.js.map +1 -1
  65. package/lib/module/Date/weekdayColumns.js +51 -0
  66. package/lib/module/Date/weekdayColumns.js.map +1 -0
  67. package/lib/module/shared/styles.js +3 -0
  68. package/lib/module/shared/styles.js.map +1 -1
  69. package/lib/module/shared/utils.js +8 -0
  70. package/lib/module/shared/utils.js.map +1 -1
  71. package/lib/typescript/Date/AnimatedCrossView.d.ts.map +1 -1
  72. package/lib/typescript/Date/AutoSizer.d.ts.map +1 -1
  73. package/lib/typescript/Date/Calendar.d.ts.map +1 -1
  74. package/lib/typescript/Date/CalendarEdit.d.ts +3 -1
  75. package/lib/typescript/Date/CalendarEdit.d.ts.map +1 -1
  76. package/lib/typescript/Date/CalendarHeader.d.ts +5 -1
  77. package/lib/typescript/Date/CalendarHeader.d.ts.map +1 -1
  78. package/lib/typescript/Date/DatePickerModal.d.ts.map +1 -1
  79. package/lib/typescript/Date/DatePickerModalContent.d.ts.map +1 -1
  80. package/lib/typescript/Date/DatePickerModalContentHeader.d.ts +2 -0
  81. package/lib/typescript/Date/DatePickerModalContentHeader.d.ts.map +1 -1
  82. package/lib/typescript/Date/DatePickerModalHeader.d.ts +2 -0
  83. package/lib/typescript/Date/DatePickerModalHeader.d.ts.map +1 -1
  84. package/lib/typescript/Date/DatePickerModalHeaderBackground.d.ts +3 -1
  85. package/lib/typescript/Date/DatePickerModalHeaderBackground.d.ts.map +1 -1
  86. package/lib/typescript/Date/Month.d.ts.map +1 -1
  87. package/lib/typescript/Date/Swiper.d.ts.map +1 -1
  88. package/lib/typescript/Date/Swiper.native.d.ts.map +1 -1
  89. package/lib/typescript/Date/SwiperUtils.d.ts +1 -0
  90. package/lib/typescript/Date/SwiperUtils.d.ts.map +1 -1
  91. package/lib/typescript/Date/YearPicker.d.ts.map +1 -1
  92. package/lib/typescript/Date/weekdayColumns.d.ts +9 -0
  93. package/lib/typescript/Date/weekdayColumns.d.ts.map +1 -0
  94. package/lib/typescript/shared/styles.d.ts +3 -0
  95. package/lib/typescript/shared/styles.d.ts.map +1 -1
  96. package/lib/typescript/shared/utils.d.ts +1 -0
  97. package/lib/typescript/shared/utils.d.ts.map +1 -1
  98. package/package.json +1 -1
  99. package/src/Date/AnimatedCrossView.tsx +2 -1
  100. package/src/Date/AutoSizer.tsx +33 -9
  101. package/src/Date/Calendar.tsx +5 -4
  102. package/src/Date/CalendarEdit.tsx +60 -51
  103. package/src/Date/CalendarHeader.tsx +38 -6
  104. package/src/Date/DatePickerModal.tsx +5 -13
  105. package/src/Date/DatePickerModalContent.tsx +55 -40
  106. package/src/Date/DatePickerModalContentHeader.tsx +14 -3
  107. package/src/Date/DatePickerModalHeader.tsx +47 -50
  108. package/src/Date/DatePickerModalHeaderBackground.tsx +30 -8
  109. package/src/Date/Month.tsx +73 -44
  110. package/src/Date/Swiper.native.tsx +70 -43
  111. package/src/Date/Swiper.tsx +44 -19
  112. package/src/Date/SwiperUtils.ts +1 -0
  113. package/src/Date/YearPicker.tsx +14 -2
  114. package/src/Date/weekdayColumns.ts +75 -0
  115. package/src/shared/styles.tsx +3 -0
  116. package/src/shared/utils.ts +6 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"weekdayColumns.d.ts","sourceRoot":"","sources":["../../../src/Date/weekdayColumns.ts"],"names":[],"mappings":"AAAA,OAAO,EAAoC,KAAK,SAAS,EAAE,MAAM,cAAc,CAAA;AAC/E,OAAO,EAAe,KAAK,mBAAmB,EAAE,MAAM,aAAa,CAAA;AAOnE,wBAAgB,uBAAuB,CACrC,eAAe,CAAC,EAAE,mBAAmB,GACpC,SAAS,CAKX;AAED,wBAAgB,uBAAuB,CACrC,eAAe,CAAC,EAAE,mBAAmB,GACpC,SAAS,CAEX;AAED,wBAAgB,sBAAsB,CACpC,eAAe,CAAC,EAAE,mBAAmB,GACpC,SAAS,CAKX;AAsBD,wBAAgB,uBAAuB,CACrC,eAAe,CAAC,EAAE,mBAAmB,GACpC,SAAS,CAEX;AAWD,wBAAgB,WAAW,CAAC,eAAe,CAAC,EAAE,mBAAmB,GAAG,SAAS,CAG5E;AAED,eAAO,MAAM,oBAAoB,EAAE,SAElC,CAAA"}
@@ -2,6 +2,9 @@ export declare const sharedStyles: {
2
2
  flexDirectionRow: {
3
3
  flexDirection: "row";
4
4
  };
5
+ minHeightZero: {
6
+ minHeight: number;
7
+ };
5
8
  opacity0: {
6
9
  opacity: number;
7
10
  };
@@ -1 +1 @@
1
- {"version":3,"file":"styles.d.ts","sourceRoot":"","sources":["../../../src/shared/styles.tsx"],"names":[],"mappings":"AAEA,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;CAgBvB,CAAA"}
1
+ {"version":3,"file":"styles.d.ts","sourceRoot":"","sources":["../../../src/shared/styles.tsx"],"names":[],"mappings":"AAEA,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;CAmBvB,CAAA"}
@@ -3,6 +3,7 @@ import Color from 'color';
3
3
  export declare const supportedOrientations: ('portrait' | 'portrait-upside-down' | 'landscape' | 'landscape-left' | 'landscape-right')[];
4
4
  export type PaperTheme = typeof MD3DarkTheme | typeof DefaultTheme;
5
5
  export declare function useLatest<T>(value: T): import("react").RefObject<T>;
6
+ export declare function useIsLargeScreen(): boolean;
6
7
  export declare function useHeaderBackgroundColor(): string;
7
8
  export declare function useHeaderTextColor(): string;
8
9
  export declare function useTextColorOnPrimary(): string;
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/shared/utils.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,YAAY,EAAY,MAAM,oBAAoB,CAAA;AACzE,OAAO,KAAK,MAAM,OAAO,CAAA;AAEzB,eAAO,MAAM,qBAAqB,EAAE,CAChC,UAAU,GACV,sBAAsB,GACtB,WAAW,GACX,gBAAgB,GAChB,iBAAiB,CACpB,EAMA,CAAA;AAED,MAAM,MAAM,UAAU,GAAG,OAAO,YAAY,GAAG,OAAO,YAAY,CAAA;AAElE,wBAAgB,SAAS,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,gCAIpC;AAED,wBAAgB,wBAAwB,WAGvC;AAED,wBAAgB,kBAAkB,WAGjC;AAED,wBAAgB,qBAAqB,WAQpC;AAED,wBAAgB,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,YAI/C;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,YAAY,CAAC,OAAO,KAAK,CAAC,EAAE,KAAK,EAAE,MAAM,iCAGzE;AAED,wBAAgB,QAAQ,CAAC,KAAK,EAAE,YAAY,CAAC,OAAO,KAAK,CAAC,EAAE,KAAK,EAAE,MAAM,iCAGxE"}
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/shared/utils.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,YAAY,EAAY,MAAM,oBAAoB,CAAA;AACzE,OAAO,KAAK,MAAM,OAAO,CAAA;AAEzB,eAAO,MAAM,qBAAqB,EAAE,CAChC,UAAU,GACV,sBAAsB,GACtB,WAAW,GACX,gBAAgB,GAChB,iBAAiB,CACpB,EAMA,CAAA;AAED,MAAM,MAAM,UAAU,GAAG,OAAO,YAAY,GAAG,OAAO,YAAY,CAAA;AAElE,wBAAgB,SAAS,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,gCAIpC;AAED,wBAAgB,gBAAgB,YAG/B;AAED,wBAAgB,wBAAwB,WAGvC;AAED,wBAAgB,kBAAkB,WAGjC;AAED,wBAAgB,qBAAqB,WAQpC;AAED,wBAAgB,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,YAI/C;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,YAAY,CAAC,OAAO,KAAK,CAAC,EAAE,KAAK,EAAE,MAAM,iCAGzE;AAED,wBAAgB,QAAQ,CAAC,KAAK,EAAE,YAAY,CAAC,OAAO,KAAK,CAAC,EAAE,KAAK,EAAE,MAAM,iCAGxE"}
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "0.24.0",
2
+ "version": "0.24.1",
3
3
  "author": "Richard Lindhout <info@webridge.nl> (https://github.com/web-ridge)",
4
4
  "bugs": {
5
5
  "url": "https://github.com/web-ridge/react-native-paper-dates/issues"
@@ -27,10 +27,11 @@ export default function AnimatedCrossView({
27
27
  }, [collapsed])
28
28
 
29
29
  return (
30
- <View style={sharedStyles.root}>
30
+ <View style={[sharedStyles.root, sharedStyles.minHeightZero]}>
31
31
  <Animated.View
32
32
  pointerEvents={collapsed ? 'auto' : 'none'}
33
33
  style={[
34
+ sharedStyles.minHeightZero,
34
35
  sharedStyles.root,
35
36
  {
36
37
  opacity: calendarOpacity.current,
@@ -1,5 +1,5 @@
1
1
  import { useCallback, useState } from 'react'
2
- import { LayoutChangeEvent, View } from 'react-native'
2
+ import { LayoutChangeEvent, useWindowDimensions, View } from 'react-native'
3
3
  import { sharedStyles } from '../shared/styles'
4
4
 
5
5
  type WidthAndHeight = {
@@ -7,36 +7,60 @@ type WidthAndHeight = {
7
7
  height: number
8
8
  }
9
9
 
10
+ type MeasuredLayout = WidthAndHeight & {
11
+ windowKey: string
12
+ }
13
+
10
14
  export default function AutoSizer({
11
15
  children,
12
16
  }: {
13
17
  children: ({ width, height }: WidthAndHeight) => any
14
18
  }) {
15
- const [layout, setLayout] = useState<WidthAndHeight | null>(null)
19
+ const { width: windowWidth, height: windowHeight } = useWindowDimensions()
20
+ const windowKey = `${windowWidth}x${windowHeight}`
21
+ const [measured, setMeasured] = useState<MeasuredLayout | null>(null)
16
22
 
17
23
  const onLayout = useCallback(
18
24
  (event: LayoutChangeEvent) => {
19
25
  const nl = event.nativeEvent.layout
20
26
  // https://github.com/necolas/react-native-web/issues/1704
21
- if (!layout || layout.width !== nl.width || layout.height !== nl.height) {
22
- setLayout({ width: nl.width, height: nl.height })
23
- }
27
+ setMeasured((prev) => {
28
+ if (
29
+ prev &&
30
+ prev.windowKey === windowKey &&
31
+ prev.width === nl.width &&
32
+ prev.height === nl.height
33
+ ) {
34
+ return prev
35
+ }
36
+ return { windowKey, width: nl.width, height: nl.height }
37
+ })
24
38
  },
25
- [layout, setLayout]
39
+ [windowKey]
26
40
  )
27
41
 
28
- const isLayoutInitialized = layout && layout.height > 0 && layout.width > 0
42
+ const layout =
43
+ measured &&
44
+ measured.windowKey === windowKey &&
45
+ measured.width > 0 &&
46
+ measured.height > 0
47
+ ? measured
48
+ : null
29
49
 
30
50
  return (
31
51
  <View
52
+ // Modals often skip onLayout during rotation. Keying by window size
53
+ // mounts a fresh sizer so the calendar gets the landscape viewport.
54
+ key={windowKey}
55
+ collapsable={false}
32
56
  onLayout={onLayout}
33
57
  style={[
34
58
  sharedStyles.overflowHidden,
35
59
  sharedStyles.root,
36
- isLayoutInitialized && layout,
60
+ sharedStyles.minHeightZero,
37
61
  ]}
38
62
  >
39
- {isLayoutInitialized ? children(layout) : null}
63
+ {layout ? children(layout) : null}
40
64
  </View>
41
65
  )
42
66
  }
@@ -204,7 +204,7 @@ function Calendar(
204
204
  const selectColor = theme.colors.primaryContainer
205
205
 
206
206
  return (
207
- <View style={sharedStyles.root}>
207
+ <View style={[sharedStyles.root, sharedStyles.minHeightZero]}>
208
208
  <Swiper
209
209
  initialIndex={getInitialIndex(firstDate, startYear, endYear)}
210
210
  selectedYear={selectedYear}
@@ -239,13 +239,14 @@ function Calendar(
239
239
  dayContentStyle={dayContentStyle}
240
240
  />
241
241
  )}
242
- renderHeader={({ onPrev, onNext }) => (
242
+ renderHeader={({ endInset, onPrev, onNext }) => (
243
243
  <CalendarHeader
244
+ disableWeekDays={disableWeekDays}
245
+ endInset={endInset}
244
246
  locale={locale}
245
- onPrev={onPrev}
246
247
  onNext={onNext}
248
+ onPrev={onPrev}
247
249
  scrollMode={scrollMode}
248
- disableWeekDays={disableWeekDays}
249
250
  startWeekOnMonday={startWeekOnMonday || false}
250
251
  />
251
252
  )}
@@ -9,6 +9,8 @@ import type { ModeType, ValidRangeType } from './Calendar'
9
9
  import type { LocalState } from './DatePickerModalContent'
10
10
 
11
11
  import DatePickerInputWithoutModal from './DatePickerInputWithoutModal'
12
+ import type { DisableWeekDaysType } from './dateUtils'
13
+ import { weekdaySpan, weekdaySpanOvershoot } from './weekdayColumns'
12
14
  import { memo, useCallback, useEffect, useRef } from 'react'
13
15
  import { useTheme } from 'react-native-paper'
14
16
  import { sharedStyles } from '../shared/styles'
@@ -26,6 +28,7 @@ function CalendarEdit({
26
28
  inputEnabled,
27
29
  withDateFormatInLabel,
28
30
  placeholder,
31
+ disableWeekDays,
29
32
  }: {
30
33
  mode: ModeType
31
34
  label?: string
@@ -39,6 +42,7 @@ function CalendarEdit({
39
42
  inputEnabled?: boolean
40
43
  withDateFormatInLabel?: boolean
41
44
  placeholder?: string
45
+ disableWeekDays?: DisableWeekDaysType
42
46
  }) {
43
47
  const theme = useTheme()
44
48
  const dateInput = useRef<TextInputNative | null>(null)
@@ -86,37 +90,17 @@ function CalendarEdit({
86
90
 
87
91
  return (
88
92
  <View style={styles.root}>
89
- {mode === 'single' ? (
90
- <DatePickerInputWithoutModal
91
- inputMode="start"
92
- ref={dateInput}
93
- mode="outlined"
94
- label={label}
95
- value={state.date}
96
- onChange={(date) => onChange({ ...state, date })}
97
- onSubmitEditing={onSubmitInput}
98
- validRange={validRange}
99
- locale={locale}
100
- withModal={false}
101
- autoComplete={'off'}
102
- inputEnabled={inputEnabled}
103
- withDateFormatInLabel={withDateFormatInLabel}
104
- placeholder={placeholder}
105
- style={inputStyle}
106
- />
107
- ) : null}
108
- {mode === 'range' ? (
109
- <View style={sharedStyles.flexDirectionRow}>
110
- <View style={sharedStyles.root}>
93
+ <View style={weekdaySpan(disableWeekDays)}>
94
+ <View style={weekdaySpanOvershoot}>
95
+ {mode === 'single' ? (
111
96
  <DatePickerInputWithoutModal
112
97
  inputMode="start"
113
- ref={startInput}
98
+ ref={dateInput}
114
99
  mode="outlined"
115
- label={startLabel}
116
- value={state.startDate}
117
- onChange={(startDate) => onChange({ ...state, startDate })}
118
- returnKeyType={'next'}
119
- onSubmitEditing={onSubmitStartInput}
100
+ label={label}
101
+ value={state.date}
102
+ onChange={(date) => onChange({ ...state, date })}
103
+ onSubmitEditing={onSubmitInput}
120
104
  validRange={validRange}
121
105
  locale={locale}
122
106
  withModal={false}
@@ -126,36 +110,61 @@ function CalendarEdit({
126
110
  placeholder={placeholder}
127
111
  style={inputStyle}
128
112
  />
129
- </View>
130
- <View style={styles.separator} />
131
- <View style={sharedStyles.root}>
132
- <DatePickerInputWithoutModal
133
- inputMode="end"
134
- ref={endInput}
135
- mode="outlined"
136
- label={endLabel}
137
- value={state.endDate}
138
- onChange={(endDate) => onChange({ ...state, endDate })}
139
- onSubmitEditing={onSubmitEndInput}
140
- validRange={validRange}
141
- locale={locale}
142
- withModal={false}
143
- autoComplete="off"
144
- inputEnabled={inputEnabled}
145
- withDateFormatInLabel={withDateFormatInLabel}
146
- placeholder={placeholder}
147
- style={inputStyle}
148
- />
149
- </View>
113
+ ) : null}
114
+ {mode === 'range' ? (
115
+ <View style={sharedStyles.flexDirectionRow}>
116
+ <View style={sharedStyles.root}>
117
+ <DatePickerInputWithoutModal
118
+ inputMode="start"
119
+ ref={startInput}
120
+ mode="outlined"
121
+ label={startLabel}
122
+ value={state.startDate}
123
+ onChange={(startDate) => onChange({ ...state, startDate })}
124
+ returnKeyType={'next'}
125
+ onSubmitEditing={onSubmitStartInput}
126
+ validRange={validRange}
127
+ locale={locale}
128
+ withModal={false}
129
+ autoComplete={'off'}
130
+ inputEnabled={inputEnabled}
131
+ withDateFormatInLabel={withDateFormatInLabel}
132
+ placeholder={placeholder}
133
+ style={inputStyle}
134
+ />
135
+ </View>
136
+ <View style={styles.separator} />
137
+ <View style={sharedStyles.root}>
138
+ <DatePickerInputWithoutModal
139
+ inputMode="end"
140
+ ref={endInput}
141
+ mode="outlined"
142
+ label={endLabel}
143
+ value={state.endDate}
144
+ onChange={(endDate) => onChange({ ...state, endDate })}
145
+ onSubmitEditing={onSubmitEndInput}
146
+ validRange={validRange}
147
+ locale={locale}
148
+ withModal={false}
149
+ autoComplete="off"
150
+ inputEnabled={inputEnabled}
151
+ withDateFormatInLabel={withDateFormatInLabel}
152
+ placeholder={placeholder}
153
+ style={inputStyle}
154
+ />
155
+ </View>
156
+ </View>
157
+ ) : null}
150
158
  </View>
151
- ) : null}
159
+ </View>
152
160
  </View>
153
161
  )
154
162
  }
155
163
 
156
164
  const styles = StyleSheet.create({
157
165
  root: {
158
- padding: 12,
166
+ paddingVertical: 12,
167
+ width: '100%',
159
168
  },
160
169
  separator: {
161
170
  width: 12,
@@ -1,11 +1,19 @@
1
- import { StyleSheet, View } from 'react-native'
1
+ import { Platform, StyleSheet, View } from 'react-native'
2
2
  import { IconButton, useTheme } from 'react-native-paper'
3
3
  import DayNames, { dayNamesHeight } from './DayNames'
4
4
  import type { DisableWeekDaysType } from './dateUtils'
5
+ import { centerIconOnLastWeekday } from './weekdayColumns'
5
6
  import { getTranslation } from '../translations/utils'
6
7
  import { sharedStyles } from '../shared/styles'
7
8
  import { memo } from 'react'
8
9
 
10
+ /** Space reserved so an overlay header does not paint over a vertical scrollbar. */
11
+ export const verticalScrollbarGutter = Platform.select({
12
+ ios: 0,
13
+ web: 16,
14
+ default: 14,
15
+ }) as number
16
+
9
17
  const buttonContainerHeight = 56
10
18
  const buttonContainerMarginTop = 4
11
19
  const buttonContainerMarginBottom = 8
@@ -29,6 +37,7 @@ function CalendarHeader({
29
37
  disableWeekDays,
30
38
  locale,
31
39
  startWeekOnMonday,
40
+ endInset = 0,
32
41
  }: {
33
42
  locale: undefined | string
34
43
  scrollMode: 'horizontal' | 'vertical'
@@ -36,30 +45,46 @@ function CalendarHeader({
36
45
  onNext: () => any
37
46
  disableWeekDays?: DisableWeekDaysType
38
47
  startWeekOnMonday: boolean
48
+ /** Shrink from the trailing edge so week names do not cover a vertical scrollbar. */
49
+ endInset?: number
39
50
  }) {
40
51
  const isHorizontal = scrollMode === 'horizontal'
41
-
42
52
  const theme = useTheme()
43
53
 
44
54
  return (
45
- <View style={styles.datePickerHeader} pointerEvents={'box-none'}>
55
+ <View
56
+ style={
57
+ endInset
58
+ ? [styles.datePickerHeader, { right: endInset }]
59
+ : styles.datePickerHeader
60
+ }
61
+ pointerEvents={'box-none'}
62
+ >
46
63
  {isHorizontal ? (
47
64
  <View style={styles.buttonContainer} pointerEvents={'box-none'}>
48
65
  <View style={sharedStyles.root} pointerEvents={'box-none'} />
49
- <View style={{ backgroundColor: theme.colors.elevation.level3 }}>
66
+ <View
67
+ style={[
68
+ styles.arrowGroup,
69
+ {
70
+ backgroundColor: theme.colors.elevation.level3,
71
+ },
72
+ centerIconOnLastWeekday(disableWeekDays),
73
+ ]}
74
+ >
50
75
  <IconButton
51
76
  icon="chevron-left"
52
77
  accessibilityLabel={getTranslation(locale, 'previous')}
53
78
  onPress={onPrev}
54
79
  testID="react-native-paper-dates-prev-month"
80
+ style={styles.arrowButton}
55
81
  />
56
- </View>
57
- <View style={{ backgroundColor: theme.colors.elevation.level3 }}>
58
82
  <IconButton
59
83
  icon="chevron-right"
60
84
  accessibilityLabel={getTranslation(locale, 'next')}
61
85
  onPress={onNext}
62
86
  testID="react-native-paper-dates-next-month"
87
+ style={styles.arrowButton}
63
88
  />
64
89
  </View>
65
90
  </View>
@@ -88,6 +113,13 @@ const styles = StyleSheet.create({
88
113
  flexDirection: 'row',
89
114
  alignItems: 'center',
90
115
  },
116
+ arrowGroup: {
117
+ flexDirection: 'row',
118
+ alignItems: 'center',
119
+ },
120
+ arrowButton: {
121
+ margin: 0,
122
+ },
91
123
  })
92
124
 
93
125
  export default memo(CalendarHeader)
@@ -3,7 +3,6 @@ import {
3
3
  Platform,
4
4
  StyleSheet,
5
5
  TouchableWithoutFeedback,
6
- useWindowDimensions,
7
6
  View,
8
7
  } from 'react-native'
9
8
  import { useTheme } from 'react-native-paper'
@@ -14,7 +13,7 @@ import DatePickerModalContent, {
14
13
  } from './DatePickerModalContent'
15
14
  import { memo } from 'react'
16
15
  import { sharedStyles } from '../shared/styles'
17
- import { supportedOrientations } from '../shared/utils'
16
+ import { supportedOrientations, useIsLargeScreen } from '../shared/utils'
18
17
 
19
18
  interface DatePickerModalProps {
20
19
  visible: boolean
@@ -58,19 +57,11 @@ export function DatePickerModal(
58
57
  })
59
58
 
60
59
  const theme = useTheme()
61
- const dimensions = useWindowDimensions()
62
-
63
- // Automatically use formSheet on iPad for better fit
64
- // iPad detection: width > 650 AND height > 650 (works in both orientations)
65
- // - iPad portrait: 744x1133, landscape: 1133x744 (both > 650)
66
- // - iPhone landscape: 932x430 (height < 650, so excluded)
67
- // pageSheet on iPad is ~540pt wide, but calendar is max 400pt, causing centering
68
- // formSheet at ~540x620pt provides a better fit for the date picker
60
+ const isLargeScreen = useIsLargeScreen()
69
61
  const shouldUseSheet =
70
62
  Platform.OS === 'ios' &&
71
63
  (presentationStyle === 'pageSheet' || presentationStyle === 'formSheet')
72
- const useFormSheet =
73
- shouldUseSheet && dimensions.width > 650 && dimensions.height > 650
64
+ const useFormSheet = shouldUseSheet && isLargeScreen
74
65
  const isSheet = shouldUseSheet
75
66
 
76
67
  return (
@@ -107,7 +98,7 @@ export function DatePickerModal(
107
98
  style={[
108
99
  styles.modalContent,
109
100
  { backgroundColor: theme.colors.elevation.level3 },
110
- dimensions.width > 650
101
+ isLargeScreen
111
102
  ? useFormSheet
112
103
  ? styles.modalContentFormSheet
113
104
  : styles.modalContentBig
@@ -134,6 +125,7 @@ const styles = StyleSheet.create({
134
125
  modalContent: {
135
126
  flex: 1,
136
127
  width: '100%',
128
+ minHeight: 0,
137
129
  },
138
130
  modalContentBig: {
139
131
  maxWidth: 400,
@@ -17,6 +17,9 @@ import CalendarEdit from './CalendarEdit'
17
17
  import DatePickerModalHeaderBackground from './DatePickerModalHeaderBackground'
18
18
  import DatePickerModalStatusBar from './DatePickerModalStatusBar'
19
19
  import { memo, useCallback, useEffect, useState } from 'react'
20
+ import { View } from 'react-native'
21
+ import { useSafeAreaInsets } from 'react-native-safe-area-context'
22
+ import { sharedStyles } from '../shared/styles'
20
23
 
21
24
  export type LocalState = {
22
25
  startDate: CalendarDate
@@ -92,6 +95,7 @@ export function DatePickerModalContent(
92
95
  } = props
93
96
  const anyProps = props as any
94
97
  const defaultUppercase = false
98
+ const insets = useSafeAreaInsets()
95
99
 
96
100
  // use local state to add only onConfirm state changes
97
101
  const [state, setState] = useState<LocalState>({
@@ -143,7 +147,7 @@ export function DatePickerModalContent(
143
147
 
144
148
  return (
145
149
  <>
146
- <DatePickerModalHeaderBackground>
150
+ <DatePickerModalHeaderBackground disableWeekDays={disableWeekDays}>
147
151
  <DatePickerModalStatusBar
148
152
  disableSafeTop={!!disableSafeTop}
149
153
  disableStatusBar={!!disableStatusBar}
@@ -157,6 +161,7 @@ export function DatePickerModalContent(
157
161
  saveLabelDisabled={props.saveLabelDisabled ?? false}
158
162
  uppercase={props.uppercase ?? defaultUppercase}
159
163
  closeIcon={props.closeIcon}
164
+ disableWeekDays={disableWeekDays}
160
165
  />
161
166
  <DatePickerModalContentHeader
162
167
  state={state}
@@ -174,47 +179,57 @@ export function DatePickerModalContent(
174
179
  editIcon={props?.editIcon}
175
180
  calendarIcon={props.calendarIcon}
176
181
  allowEditing={props.allowEditing ?? true}
182
+ disableWeekDays={disableWeekDays}
177
183
  />
178
184
  </DatePickerModalHeaderBackground>
179
- <AnimatedCrossView
180
- collapsed={collapsed}
181
- calendar={
182
- <Calendar
183
- locale={locale}
184
- mode={mode}
185
- startDate={state.startDate}
186
- endDate={state.endDate}
187
- date={state.date}
188
- onChange={onInnerChange}
189
- disableWeekDays={disableWeekDays}
190
- dates={state.dates}
191
- validRange={validRange}
192
- dateMode={dateMode}
193
- startYear={startYear}
194
- endYear={endYear}
195
- startWeekOnMonday={startWeekOnMonday}
196
- dayContent={dayContent}
197
- dayContentPosition={dayContentPosition}
198
- dayContentStyle={dayContentStyle}
199
- />
200
- }
201
- calendarEdit={
202
- <CalendarEdit
203
- mode={mode}
204
- state={state}
205
- label={props.label}
206
- startLabel={props.startLabel}
207
- endLabel={props.endLabel}
208
- collapsed={collapsed}
209
- onChange={onInnerChange}
210
- validRange={validRange}
211
- locale={locale}
212
- inputEnabled={props.inputEnabled}
213
- withDateFormatInLabel={props.withDateFormatInLabel}
214
- placeholder={props.placeholder}
215
- />
216
- }
217
- />
185
+ <View
186
+ style={[
187
+ sharedStyles.root,
188
+ sharedStyles.minHeightZero,
189
+ { paddingLeft: insets.left, paddingRight: insets.right },
190
+ ]}
191
+ >
192
+ <AnimatedCrossView
193
+ collapsed={collapsed}
194
+ calendar={
195
+ <Calendar
196
+ locale={locale}
197
+ mode={mode}
198
+ startDate={state.startDate}
199
+ endDate={state.endDate}
200
+ date={state.date}
201
+ onChange={onInnerChange}
202
+ disableWeekDays={disableWeekDays}
203
+ dates={state.dates}
204
+ validRange={validRange}
205
+ dateMode={dateMode}
206
+ startYear={startYear}
207
+ endYear={endYear}
208
+ startWeekOnMonday={startWeekOnMonday}
209
+ dayContent={dayContent}
210
+ dayContentPosition={dayContentPosition}
211
+ dayContentStyle={dayContentStyle}
212
+ />
213
+ }
214
+ calendarEdit={
215
+ <CalendarEdit
216
+ mode={mode}
217
+ state={state}
218
+ label={props.label}
219
+ startLabel={props.startLabel}
220
+ endLabel={props.endLabel}
221
+ collapsed={collapsed}
222
+ onChange={onInnerChange}
223
+ validRange={validRange}
224
+ locale={locale}
225
+ inputEnabled={props.inputEnabled}
226
+ withDateFormatInLabel={props.withDateFormatInLabel}
227
+ placeholder={props.placeholder}
228
+ disableWeekDays={disableWeekDays}
229
+ />
230
+ }
231
+ />
232
+ </View>
218
233
  </>
219
234
  )
220
235
  }
@@ -7,6 +7,11 @@ import Color from 'color'
7
7
  import { getTranslation } from '../translations/utils'
8
8
  import { useMemo } from 'react'
9
9
  import { sharedStyles } from '../shared/styles'
10
+ import type { DisableWeekDaysType } from './dateUtils'
11
+ import {
12
+ alignTextToFirstWeekday,
13
+ centerIconOnLastWeekday,
14
+ } from './weekdayColumns'
10
15
 
11
16
  export interface HeaderPickProps {
12
17
  moreLabel?: string
@@ -31,6 +36,7 @@ export interface HeaderContentProps extends HeaderPickProps {
31
36
  collapsed: boolean
32
37
  onToggle: () => any
33
38
  locale: string | undefined
39
+ disableWeekDays?: DisableWeekDaysType
34
40
  }
35
41
 
36
42
  function getLabel(
@@ -65,6 +71,7 @@ export default function DatePickerModalContentHeader(
65
71
  editIcon,
66
72
  calendarIcon,
67
73
  allowEditing,
74
+ disableWeekDays,
68
75
  } = props
69
76
  const theme = useTheme()
70
77
  const label = getLabel(props.locale, props.mode, props.label)
@@ -77,7 +84,7 @@ export default function DatePickerModalContentHeader(
77
84
 
78
85
  return (
79
86
  <View style={styles.header}>
80
- <View>
87
+ <View style={alignTextToFirstWeekday(disableWeekDays)}>
81
88
  <Text
82
89
  maxFontSizeMultiplier={1.5}
83
90
  style={[styles.label, { color: supportingTextColor, ...textFont }]}
@@ -112,6 +119,7 @@ export default function DatePickerModalContentHeader(
112
119
  iconColor={theme.colors.onSurface}
113
120
  onPress={onToggle}
114
121
  testID="react-native-paper-dates-toggle-edit"
122
+ style={[styles.editButton, centerIconOnLastWeekday(disableWeekDays)]}
115
123
  />
116
124
  ) : null}
117
125
  </View>
@@ -234,12 +242,15 @@ export function HeaderContentRange({
234
242
  }
235
243
 
236
244
  const styles = StyleSheet.create({
245
+ editButton: {
246
+ marginTop: 0,
247
+ marginBottom: 0,
248
+ marginStart: 0,
249
+ },
237
250
  header: {
238
251
  height: 75,
239
252
  alignItems: 'center',
240
253
  flexDirection: 'row',
241
- paddingLeft: 24,
242
- paddingRight: 12,
243
254
  },
244
255
  headerContentContainer: {
245
256
  flexDirection: 'row',