react-native-paper-dates 0.24.0 → 0.24.2

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 (120) 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 +26 -12
  4. package/lib/commonjs/Date/AutoSizer.js.map +1 -1
  5. package/lib/commonjs/Date/Calendar.js +8 -4
  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 +33 -12
  12. package/lib/commonjs/Date/DatePickerModal.js.map +1 -1
  13. package/lib/commonjs/Date/DatePickerModalContent.js +69 -35
  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 +35 -22
  24. package/lib/commonjs/Date/Swiper.js.map +1 -1
  25. package/lib/commonjs/Date/Swiper.native.js +54 -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 +27 -13
  39. package/lib/module/Date/AutoSizer.js.map +1 -1
  40. package/lib/module/Date/Calendar.js +8 -4
  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 +35 -14
  47. package/lib/module/Date/DatePickerModal.js.map +1 -1
  48. package/lib/module/Date/DatePickerModalContent.js +69 -35
  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 +36 -23
  59. package/lib/module/Date/Swiper.js.map +1 -1
  60. package/lib/module/Date/Swiper.native.js +55 -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 +3 -1
  73. package/lib/typescript/Date/AutoSizer.d.ts.map +1 -1
  74. package/lib/typescript/Date/Calendar.d.ts +9 -0
  75. package/lib/typescript/Date/Calendar.d.ts.map +1 -1
  76. package/lib/typescript/Date/CalendarEdit.d.ts +3 -1
  77. package/lib/typescript/Date/CalendarEdit.d.ts.map +1 -1
  78. package/lib/typescript/Date/CalendarHeader.d.ts +5 -1
  79. package/lib/typescript/Date/CalendarHeader.d.ts.map +1 -1
  80. package/lib/typescript/Date/DatePickerModal.d.ts.map +1 -1
  81. package/lib/typescript/Date/DatePickerModalContent.d.ts +8 -0
  82. package/lib/typescript/Date/DatePickerModalContent.d.ts.map +1 -1
  83. package/lib/typescript/Date/DatePickerModalContentHeader.d.ts +2 -0
  84. package/lib/typescript/Date/DatePickerModalContentHeader.d.ts.map +1 -1
  85. package/lib/typescript/Date/DatePickerModalHeader.d.ts +2 -0
  86. package/lib/typescript/Date/DatePickerModalHeader.d.ts.map +1 -1
  87. package/lib/typescript/Date/DatePickerModalHeaderBackground.d.ts +3 -1
  88. package/lib/typescript/Date/DatePickerModalHeaderBackground.d.ts.map +1 -1
  89. package/lib/typescript/Date/Month.d.ts.map +1 -1
  90. package/lib/typescript/Date/Swiper.d.ts +1 -1
  91. package/lib/typescript/Date/Swiper.d.ts.map +1 -1
  92. package/lib/typescript/Date/Swiper.native.d.ts.map +1 -1
  93. package/lib/typescript/Date/SwiperUtils.d.ts +5 -0
  94. package/lib/typescript/Date/SwiperUtils.d.ts.map +1 -1
  95. package/lib/typescript/Date/YearPicker.d.ts.map +1 -1
  96. package/lib/typescript/Date/weekdayColumns.d.ts +9 -0
  97. package/lib/typescript/Date/weekdayColumns.d.ts.map +1 -0
  98. package/lib/typescript/shared/styles.d.ts +3 -0
  99. package/lib/typescript/shared/styles.d.ts.map +1 -1
  100. package/lib/typescript/shared/utils.d.ts +1 -0
  101. package/lib/typescript/shared/utils.d.ts.map +1 -1
  102. package/package.json +1 -1
  103. package/src/Date/AnimatedCrossView.tsx +2 -1
  104. package/src/Date/AutoSizer.tsx +36 -9
  105. package/src/Date/Calendar.tsx +13 -4
  106. package/src/Date/CalendarEdit.tsx +60 -51
  107. package/src/Date/CalendarHeader.tsx +38 -6
  108. package/src/Date/DatePickerModal.tsx +40 -13
  109. package/src/Date/DatePickerModalContent.tsx +78 -40
  110. package/src/Date/DatePickerModalContentHeader.tsx +14 -3
  111. package/src/Date/DatePickerModalHeader.tsx +47 -50
  112. package/src/Date/DatePickerModalHeaderBackground.tsx +30 -8
  113. package/src/Date/Month.tsx +73 -44
  114. package/src/Date/Swiper.native.tsx +92 -44
  115. package/src/Date/Swiper.tsx +46 -20
  116. package/src/Date/SwiperUtils.ts +2 -0
  117. package/src/Date/YearPicker.tsx +14 -2
  118. package/src/Date/weekdayColumns.ts +75 -0
  119. package/src/shared/styles.tsx +3 -0
  120. package/src/shared/utils.ts +6 -0
@@ -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)
@@ -12,9 +12,9 @@ import DatePickerModalContent, {
12
12
  DatePickerModalContentRangeProps,
13
13
  DatePickerModalContentSingleProps,
14
14
  } from './DatePickerModalContent'
15
- import { memo } from 'react'
15
+ import { memo, useCallback, useMemo, useState } from 'react'
16
16
  import { sharedStyles } from '../shared/styles'
17
- import { supportedOrientations } from '../shared/utils'
17
+ import { supportedOrientations, useIsLargeScreen } from '../shared/utils'
18
18
 
19
19
  interface DatePickerModalProps {
20
20
  visible: boolean
@@ -57,20 +57,44 @@ export function DatePickerModal(
57
57
  default: 'slide',
58
58
  })
59
59
 
60
- const theme = useTheme()
61
- const dimensions = useWindowDimensions()
60
+ // The calendar unmounts when the modal closes. Keep its size from the last
61
+ // open, so the next open draws the month on the first frame instead of
62
+ // waiting for the calendar to measure itself. Only reused for the same window
63
+ // size, since rotating or resizing changes the layout.
64
+ const { width: windowWidth, height: windowHeight } = useWindowDimensions()
65
+ const windowKey = `${windowWidth}x${windowHeight}`
66
+ const [lastCalendarLayout, setLastCalendarLayout] = useState<{
67
+ windowKey: string
68
+ width: number
69
+ height: number
70
+ } | null>(null)
71
+ const onCalendarLayout = useCallback(
72
+ ({ width, height }: { width: number; height: number }) => {
73
+ setLastCalendarLayout((prev) =>
74
+ prev &&
75
+ prev.windowKey === windowKey &&
76
+ prev.width === width &&
77
+ prev.height === height
78
+ ? prev
79
+ : { windowKey, width, height }
80
+ )
81
+ },
82
+ [windowKey]
83
+ )
84
+ const rememberedCalendarLayout = useMemo(
85
+ () =>
86
+ lastCalendarLayout && lastCalendarLayout.windowKey === windowKey
87
+ ? { width: lastCalendarLayout.width, height: lastCalendarLayout.height }
88
+ : undefined,
89
+ [lastCalendarLayout, windowKey]
90
+ )
62
91
 
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
92
+ const theme = useTheme()
93
+ const isLargeScreen = useIsLargeScreen()
69
94
  const shouldUseSheet =
70
95
  Platform.OS === 'ios' &&
71
96
  (presentationStyle === 'pageSheet' || presentationStyle === 'formSheet')
72
- const useFormSheet =
73
- shouldUseSheet && dimensions.width > 650 && dimensions.height > 650
97
+ const useFormSheet = shouldUseSheet && isLargeScreen
74
98
  const isSheet = shouldUseSheet
75
99
 
76
100
  return (
@@ -107,7 +131,7 @@ export function DatePickerModal(
107
131
  style={[
108
132
  styles.modalContent,
109
133
  { backgroundColor: theme.colors.elevation.level3 },
110
- dimensions.width > 650
134
+ isLargeScreen
111
135
  ? useFormSheet
112
136
  ? styles.modalContentFormSheet
113
137
  : styles.modalContentBig
@@ -122,6 +146,8 @@ export function DatePickerModal(
122
146
  statusBarOnTopOfBackdrop={isSheet || statusBarOnTopOfBackdrop}
123
147
  withDateFormatInLabel={props.withDateFormatInLabel}
124
148
  placeholder={props.placeholder}
149
+ initialLayout={rest.initialLayout ?? rememberedCalendarLayout}
150
+ onCalendarLayout={onCalendarLayout}
125
151
  />
126
152
  </View>
127
153
  </View>
@@ -134,6 +160,7 @@ const styles = StyleSheet.create({
134
160
  modalContent: {
135
161
  flex: 1,
136
162
  width: '100%',
163
+ minHeight: 0,
137
164
  },
138
165
  modalContentBig: {
139
166
  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 { LayoutChangeEvent, Platform, 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
@@ -37,6 +40,12 @@ interface DatePickerModalContentBaseProps {
37
40
  disableSafeTop?: boolean
38
41
  disableStatusBar?: boolean
39
42
  statusBarOnTopOfBackdrop?: boolean
43
+
44
+ /**
45
+ * Called with the calendar's measured size. `DatePickerModal` uses it to
46
+ * draw the calendar immediately the next time it opens.
47
+ */
48
+ onCalendarLayout?: (layout: { width: number; height: number }) => void
40
49
  }
41
50
 
42
51
  export interface DatePickerModalContentRangeProps
@@ -89,9 +98,12 @@ export function DatePickerModalContent(
89
98
  dayContent,
90
99
  dayContentPosition,
91
100
  dayContentStyle,
101
+ initialLayout,
102
+ onCalendarLayout,
92
103
  } = props
93
104
  const anyProps = props as any
94
105
  const defaultUppercase = false
106
+ const insets = useSafeAreaInsets()
95
107
 
96
108
  // use local state to add only onConfirm state changes
97
109
  const [state, setState] = useState<LocalState>({
@@ -141,9 +153,22 @@ export function DatePickerModalContent(
141
153
  setCollapsed((prev) => !prev)
142
154
  }, [setCollapsed])
143
155
 
156
+ // The calendar fills this view inside the inset padding. Not on web, where
157
+ // the range calendar's header sits above the part that sizes itself.
158
+ const onCalendarContainerLayout = useCallback(
159
+ (event: LayoutChangeEvent) => {
160
+ const { width, height } = event.nativeEvent.layout
161
+ const calendarWidth = width - insets.left - insets.right
162
+ if (onCalendarLayout && calendarWidth > 0 && height > 0) {
163
+ onCalendarLayout({ width: calendarWidth, height })
164
+ }
165
+ },
166
+ [onCalendarLayout, insets.left, insets.right]
167
+ )
168
+
144
169
  return (
145
170
  <>
146
- <DatePickerModalHeaderBackground>
171
+ <DatePickerModalHeaderBackground disableWeekDays={disableWeekDays}>
147
172
  <DatePickerModalStatusBar
148
173
  disableSafeTop={!!disableSafeTop}
149
174
  disableStatusBar={!!disableStatusBar}
@@ -157,6 +182,7 @@ export function DatePickerModalContent(
157
182
  saveLabelDisabled={props.saveLabelDisabled ?? false}
158
183
  uppercase={props.uppercase ?? defaultUppercase}
159
184
  closeIcon={props.closeIcon}
185
+ disableWeekDays={disableWeekDays}
160
186
  />
161
187
  <DatePickerModalContentHeader
162
188
  state={state}
@@ -174,47 +200,59 @@ export function DatePickerModalContent(
174
200
  editIcon={props?.editIcon}
175
201
  calendarIcon={props.calendarIcon}
176
202
  allowEditing={props.allowEditing ?? true}
203
+ disableWeekDays={disableWeekDays}
177
204
  />
178
205
  </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
- />
206
+ <View
207
+ style={[
208
+ sharedStyles.root,
209
+ sharedStyles.minHeightZero,
210
+ { paddingLeft: insets.left, paddingRight: insets.right },
211
+ ]}
212
+ onLayout={Platform.OS === 'web' ? undefined : onCalendarContainerLayout}
213
+ >
214
+ <AnimatedCrossView
215
+ collapsed={collapsed}
216
+ calendar={
217
+ <Calendar
218
+ locale={locale}
219
+ mode={mode}
220
+ startDate={state.startDate}
221
+ endDate={state.endDate}
222
+ date={state.date}
223
+ onChange={onInnerChange}
224
+ disableWeekDays={disableWeekDays}
225
+ dates={state.dates}
226
+ validRange={validRange}
227
+ dateMode={dateMode}
228
+ startYear={startYear}
229
+ endYear={endYear}
230
+ startWeekOnMonday={startWeekOnMonday}
231
+ dayContent={dayContent}
232
+ dayContentPosition={dayContentPosition}
233
+ dayContentStyle={dayContentStyle}
234
+ initialLayout={initialLayout}
235
+ />
236
+ }
237
+ calendarEdit={
238
+ <CalendarEdit
239
+ mode={mode}
240
+ state={state}
241
+ label={props.label}
242
+ startLabel={props.startLabel}
243
+ endLabel={props.endLabel}
244
+ collapsed={collapsed}
245
+ onChange={onInnerChange}
246
+ validRange={validRange}
247
+ locale={locale}
248
+ inputEnabled={props.inputEnabled}
249
+ withDateFormatInLabel={props.withDateFormatInLabel}
250
+ placeholder={props.placeholder}
251
+ disableWeekDays={disableWeekDays}
252
+ />
253
+ }
254
+ />
255
+ </View>
218
256
  </>
219
257
  )
220
258
  }
@@ -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',
@@ -1,8 +1,13 @@
1
- import { Animated, StyleSheet } from 'react-native'
2
- import { Appbar, Button, useTheme } from 'react-native-paper'
1
+ import { StyleSheet, View } from 'react-native'
2
+ import { Button, IconButton, useTheme } from 'react-native-paper'
3
3
  import { useHeaderTextColor } from '../shared/utils'
4
4
  import { getTranslation } from '../translations/utils'
5
- import { useSafeAreaInsets } from 'react-native-safe-area-context'
5
+ import { sharedStyles } from '../shared/styles'
6
+ import type { DisableWeekDaysType } from './dateUtils'
7
+ import {
8
+ alignIconToFirstWeekday,
9
+ alignTextToLastWeekday,
10
+ } from './weekdayColumns'
6
11
 
7
12
  export interface DatePickerModalHeaderProps {
8
13
  saveLabel?: string
@@ -12,68 +17,60 @@ export interface DatePickerModalHeaderProps {
12
17
  onSave: () => void
13
18
  locale: string | undefined
14
19
  closeIcon?: string
20
+ disableWeekDays?: DisableWeekDaysType
15
21
  }
16
22
 
17
23
  export default function DatePickerModalHeader(
18
24
  props: DatePickerModalHeaderProps
19
25
  ) {
20
- const { locale, closeIcon = 'close' } = props
26
+ const { locale, closeIcon = 'close', disableWeekDays } = props
21
27
  const saveLabel = props.saveLabel || getTranslation(locale, 'save')
22
28
  const color = useHeaderTextColor()
23
- const insets = useSafeAreaInsets()
24
-
25
29
  const theme = useTheme()
26
30
 
27
31
  return (
28
- <>
29
- <Animated.View
30
- style={[
31
- styles.animated,
32
- {
33
- paddingLeft: insets.left,
34
- paddingRight: insets.right,
35
- },
36
- ]}
37
- >
38
- <Appbar style={styles.appbarHeader}>
39
- <Appbar.Action
40
- icon={closeIcon}
41
- accessibilityLabel={getTranslation(locale, 'close')}
42
- onPress={props.onDismiss}
43
- color={color}
44
- testID="react-native-paper-dates-close"
45
- />
46
- <Button
47
- textColor={theme.colors.primary}
48
- onPress={props.onSave}
49
- disabled={props.saveLabelDisabled ?? false}
50
- uppercase={props.uppercase ?? true}
51
- contentStyle={styles.buttonStyle}
52
- mode="text"
53
- labelStyle={styles.buttonLabel}
54
- testID="react-native-paper-dates-save"
55
- >
56
- {saveLabel}
57
- </Button>
58
- </Appbar>
59
- </Animated.View>
60
- </>
32
+ <View style={styles.headerBar}>
33
+ <IconButton
34
+ icon={closeIcon}
35
+ accessibilityLabel={getTranslation(locale, 'close')}
36
+ onPress={props.onDismiss}
37
+ iconColor={color}
38
+ testID="react-native-paper-dates-close"
39
+ style={[styles.closeButton, alignIconToFirstWeekday(disableWeekDays)]}
40
+ />
41
+ <View style={sharedStyles.root} />
42
+ <View style={alignTextToLastWeekday(disableWeekDays)}>
43
+ <Button
44
+ textColor={theme.colors.primary}
45
+ onPress={props.onSave}
46
+ disabled={props.saveLabelDisabled ?? false}
47
+ uppercase={props.uppercase ?? true}
48
+ compact
49
+ mode="text"
50
+ testID="react-native-paper-dates-save"
51
+ style={styles.saveButton}
52
+ >
53
+ {saveLabel}
54
+ </Button>
55
+ </View>
56
+ </View>
61
57
  )
62
58
  }
63
59
 
64
60
  const styles = StyleSheet.create({
65
- animated: {
66
- elevation: 4,
67
- },
68
- appbarHeader: {
69
- elevation: 0,
70
- backgroundColor: 'transparent',
71
- justifyContent: 'space-between',
61
+ headerBar: {
62
+ flexDirection: 'row',
63
+ alignItems: 'center',
64
+ width: '100%',
65
+ paddingTop: 12,
72
66
  },
73
- buttonStyle: {
74
- paddingHorizontal: 8,
67
+ closeButton: {
68
+ marginTop: 0,
69
+ marginBottom: 0,
70
+ marginEnd: 0,
75
71
  },
76
- buttonLabel: {
77
- flexGrow: 1,
72
+ saveButton: {
73
+ marginVertical: 0,
74
+ marginEnd: 0,
78
75
  },
79
76
  })
@@ -1,26 +1,48 @@
1
- import { Animated } from 'react-native'
1
+ import { Animated, StyleSheet, useWindowDimensions, View } from 'react-native'
2
2
  import { Divider } from 'react-native-paper'
3
- import { useHeaderBackgroundColor } from '../shared/utils'
3
+ import { useHeaderBackgroundColor, useIsLargeScreen } from '../shared/utils'
4
4
  import { useSafeAreaInsets } from 'react-native-safe-area-context'
5
+ import type { DisableWeekDaysType } from './dateUtils'
6
+ import { weekdaySpan, weekdaySpanOvershoot } from './weekdayColumns'
5
7
 
6
8
  export default function DatePickerModalHeaderBackground({
7
9
  children,
10
+ disableWeekDays,
8
11
  }: {
9
12
  children: any
13
+ disableWeekDays?: DisableWeekDaysType
10
14
  }) {
11
15
  const backgroundColor = useHeaderBackgroundColor()
12
16
  const insets = useSafeAreaInsets()
17
+ const { width, height } = useWindowDimensions()
18
+ const isLargeScreen = useIsLargeScreen()
19
+ const isPhoneLandscape = width > height && !isLargeScreen
13
20
 
14
21
  return (
15
22
  <Animated.View
16
- style={{
17
- backgroundColor,
18
- paddingLeft: insets.left,
19
- paddingRight: insets.right,
20
- }}
23
+ style={[
24
+ styles.background,
25
+ {
26
+ backgroundColor,
27
+ paddingLeft: insets.left,
28
+ paddingRight: insets.right,
29
+ },
30
+ ]}
21
31
  >
22
32
  {children}
23
- <Divider />
33
+ {isPhoneLandscape ? (
34
+ <View style={weekdaySpan(disableWeekDays)}>
35
+ <Divider style={weekdaySpanOvershoot} />
36
+ </View>
37
+ ) : (
38
+ <Divider />
39
+ )}
24
40
  </Animated.View>
25
41
  )
26
42
  }
43
+
44
+ const styles = StyleSheet.create({
45
+ background: {
46
+ width: '100%',
47
+ },
48
+ })