react-native-molecules 0.5.0-beta.2 → 0.5.0-beta.21

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 (160) hide show
  1. package/README.md +1 -1
  2. package/components/Accordion/Accordion.tsx +2 -6
  3. package/components/Accordion/AccordionItem.tsx +16 -12
  4. package/components/Accordion/AccordionItemContent.tsx +6 -1
  5. package/components/Accordion/AccordionItemHeader.tsx +1 -1
  6. package/components/Accordion/utils.ts +6 -0
  7. package/components/ActivityIndicator/ActivityIndicator.tsx +6 -15
  8. package/components/Appbar/AppbarBase.tsx +18 -13
  9. package/components/Button/Button.tsx +209 -264
  10. package/components/Button/index.tsx +9 -3
  11. package/components/Button/types.ts +16 -2
  12. package/components/Button/utils.ts +230 -208
  13. package/components/Checkbox/CheckboxBase.ios.tsx +10 -14
  14. package/components/Checkbox/CheckboxBase.tsx +14 -121
  15. package/components/Checkbox/utils.ts +0 -25
  16. package/components/Chip/Chip.tsx +40 -52
  17. package/components/Chip/utils.ts +3 -7
  18. package/components/DateField/DateField.tsx +111 -0
  19. package/components/DateField/index.tsx +6 -0
  20. package/components/{DatePickerInput/inputUtils.ts → DateField/useDateFieldState.ts} +17 -49
  21. package/components/DatePicker/DateCalendar.tsx +83 -0
  22. package/components/DatePicker/DatePickerActions.tsx +73 -0
  23. package/components/DatePicker/DatePickerModal.tsx +245 -0
  24. package/components/DatePicker/DatePickerPopover.tsx +79 -0
  25. package/components/DatePicker/DatePickerProvider.tsx +158 -0
  26. package/components/DatePicker/DatePickerTrigger.tsx +23 -0
  27. package/components/DatePicker/context.tsx +83 -0
  28. package/components/DatePicker/index.tsx +45 -0
  29. package/components/DatePicker/utils.ts +293 -0
  30. package/components/DatePickerInline/DatePickerContext.tsx +1 -0
  31. package/components/DatePickerInline/DatePickerDockedHeader.tsx +117 -0
  32. package/components/DatePickerInline/DatePickerInline.tsx +16 -15
  33. package/components/DatePickerInline/DatePickerInlineBase.tsx +8 -2
  34. package/components/DatePickerInline/DatePickerInlineHeader.tsx +8 -4
  35. package/components/DatePickerInline/Day.tsx +25 -1
  36. package/components/DatePickerInline/DayNames.tsx +13 -10
  37. package/components/DatePickerInline/DayRange.tsx +2 -4
  38. package/components/DatePickerInline/HeaderItem.tsx +42 -27
  39. package/components/DatePickerInline/Month.tsx +48 -67
  40. package/components/DatePickerInline/MonthPicker.tsx +38 -44
  41. package/components/DatePickerInline/Swiper.native.tsx +21 -4
  42. package/components/DatePickerInline/Swiper.tsx +168 -13
  43. package/components/DatePickerInline/Week.tsx +6 -1
  44. package/components/DatePickerInline/YearPicker.tsx +206 -53
  45. package/components/DatePickerInline/dateUtils.tsx +17 -12
  46. package/components/DatePickerInline/types.ts +6 -2
  47. package/components/DatePickerInline/utils.ts +66 -29
  48. package/components/Drawer/Drawer.tsx +17 -6
  49. package/components/ElementGroup/ElementGroup.tsx +16 -14
  50. package/components/FilePicker/FilePicker.tsx +48 -78
  51. package/components/FilePicker/index.tsx +2 -1
  52. package/components/FilePicker/utils.ts +9 -0
  53. package/components/HelperText/HelperText.tsx +0 -35
  54. package/components/Icon/iconFactory.tsx +3 -3
  55. package/components/Icon/index.tsx +1 -1
  56. package/components/Icon/types.ts +17 -6
  57. package/components/IconButton/IconButton.tsx +42 -57
  58. package/components/IconButton/utils.ts +142 -33
  59. package/components/ListItem/ListItem.tsx +3 -1
  60. package/components/ListItem/utils.ts +1 -1
  61. package/components/LoadingIndicator/LoadingIndicator.tsx +253 -0
  62. package/components/LoadingIndicator/LoadingIndicator.web.tsx +136 -0
  63. package/components/LoadingIndicator/index.tsx +13 -0
  64. package/components/LoadingIndicator/utils.ts +117 -0
  65. package/components/Menu/Menu.tsx +3 -18
  66. package/components/NavigationRail/NavigationRail.tsx +15 -9
  67. package/components/Popover/Popover.tsx +122 -145
  68. package/components/Popover/PopoverRoot.tsx +74 -0
  69. package/components/Popover/common.ts +50 -34
  70. package/components/Popover/index.ts +18 -1
  71. package/components/Popover/usePlatformMeasure.native.ts +90 -0
  72. package/components/Popover/usePlatformMeasure.ts +118 -0
  73. package/components/Popover/utils.ts +34 -0
  74. package/components/Select/Select.tsx +368 -507
  75. package/components/Select/context.tsx +72 -0
  76. package/components/Select/index.ts +8 -14
  77. package/components/Select/types.ts +2 -4
  78. package/components/Select/utils.ts +144 -0
  79. package/components/Slot/Slot.tsx +244 -0
  80. package/components/Slot/compose-refs.tsx +62 -0
  81. package/components/Slot/index.tsx +8 -0
  82. package/components/Surface/Surface.android.tsx +34 -8
  83. package/components/Surface/Surface.ios.tsx +36 -29
  84. package/components/Surface/Surface.tsx +31 -4
  85. package/components/Surface/utils.ts +44 -30
  86. package/components/Switch/Switch.tsx +8 -2
  87. package/components/Tabs/TabItem.tsx +35 -58
  88. package/components/Tabs/TabLabel.tsx +5 -9
  89. package/components/Tabs/Tabs.tsx +154 -148
  90. package/components/Tabs/utils.ts +15 -2
  91. package/components/TextInput/TextInput.tsx +658 -575
  92. package/components/TextInput/index.tsx +19 -3
  93. package/components/TextInput/types.ts +76 -27
  94. package/components/TextInput/utils.ts +225 -145
  95. package/components/TimeField/TimeField.tsx +75 -0
  96. package/components/TimeField/index.tsx +6 -0
  97. package/components/TimeField/useTimeFieldState.ts +70 -0
  98. package/components/{TimePickerField/sanitizeTime.ts → TimeField/utils.ts} +77 -10
  99. package/components/TimePicker/TimeInput.tsx +87 -37
  100. package/components/TimePicker/TimeInputs.tsx +137 -49
  101. package/components/TimePicker/TimePicker.tsx +73 -10
  102. package/components/TimePicker/TimePickerModal.tsx +186 -0
  103. package/components/TimePicker/context.tsx +17 -0
  104. package/components/TimePicker/index.tsx +15 -3
  105. package/components/TimePicker/utils.ts +93 -0
  106. package/components/Tooltip/Tooltip.tsx +42 -67
  107. package/components/Tooltip/TooltipContent.tsx +32 -5
  108. package/components/Tooltip/TooltipTrigger.tsx +20 -20
  109. package/components/Tooltip/index.tsx +1 -1
  110. package/components/TouchableRipple/TouchableRipple.native.tsx +50 -14
  111. package/components/TouchableRipple/TouchableRipple.tsx +137 -47
  112. package/hocs/withPortal.tsx +1 -1
  113. package/hooks/index.tsx +0 -6
  114. package/hooks/useActionState.tsx +19 -8
  115. package/hooks/useControlledValue.tsx +20 -4
  116. package/hooks/useFilePicker.tsx +6 -16
  117. package/hooks/useWhatHasUpdated.tsx +48 -0
  118. package/package.json +17 -13
  119. package/shortcuts-manager/ShortcutsManager/ShortcutsManager.tsx +5 -2
  120. package/styles/shadow.ts +2 -1
  121. package/styles/themes/LightTheme.tsx +1 -1
  122. package/utils/DocumentPicker/documentPicker.ts +78 -27
  123. package/utils/DocumentPicker/types.ts +0 -1
  124. package/utils/extractPropertiesFromStyles.ts +25 -0
  125. package/utils/extractSubcomponents.ts +89 -0
  126. package/utils/lodash.ts +77 -5
  127. package/components/DatePickerDocked/DatePickerDocked.tsx +0 -30
  128. package/components/DatePickerDocked/DatePickerDockedHeader.tsx +0 -129
  129. package/components/DatePickerDocked/index.tsx +0 -17
  130. package/components/DatePickerDocked/types.ts +0 -11
  131. package/components/DatePickerDocked/utils.ts +0 -157
  132. package/components/DatePickerInput/DatePickerInput.tsx +0 -139
  133. package/components/DatePickerInput/DatePickerInputModal.tsx +0 -48
  134. package/components/DatePickerInput/DatePickerInputWithoutModal.tsx +0 -77
  135. package/components/DatePickerInput/DateRangeInput.tsx +0 -88
  136. package/components/DatePickerInput/index.tsx +0 -10
  137. package/components/DatePickerInput/types.ts +0 -28
  138. package/components/DatePickerInput/utils.ts +0 -15
  139. package/components/DatePickerModal/AnimatedCrossView.tsx +0 -94
  140. package/components/DatePickerModal/CalendarEdit.tsx +0 -139
  141. package/components/DatePickerModal/DatePickerModal.tsx +0 -85
  142. package/components/DatePickerModal/DatePickerModalContent.tsx +0 -155
  143. package/components/DatePickerModal/DatePickerModalContentHeader.tsx +0 -213
  144. package/components/DatePickerModal/DatePickerModalHeader.tsx +0 -74
  145. package/components/DatePickerModal/DatePickerModalHeaderBackground.tsx +0 -13
  146. package/components/DatePickerModal/index.tsx +0 -16
  147. package/components/DatePickerModal/types.ts +0 -92
  148. package/components/DatePickerModal/utils.ts +0 -122
  149. package/components/DateTimePicker/DateTimePicker.tsx +0 -172
  150. package/components/DateTimePicker/index.tsx +0 -10
  151. package/components/DateTimePicker/utils.ts +0 -12
  152. package/components/Popover/Popover.native.tsx +0 -185
  153. package/components/TimePickerField/TimePickerField.tsx +0 -152
  154. package/components/TimePickerField/index.tsx +0 -10
  155. package/components/TimePickerField/utils.ts +0 -94
  156. package/components/TimePickerModal/TimePickerModal.tsx +0 -115
  157. package/components/TimePickerModal/index.tsx +0 -10
  158. package/components/TimePickerModal/utils.ts +0 -47
  159. package/hooks/useSearchable.tsx +0 -74
  160. package/hooks/useSubcomponents.tsx +0 -59
@@ -1,23 +1,26 @@
1
- import { memo } from 'react';
1
+ import { memo, useMemo } from 'react';
2
2
  import { View } from 'react-native';
3
3
 
4
- import { addDays, format, startOfWeek } from '../../utils/date-fns';
4
+ import { addDays, startOfWeek } from '../../utils/date-fns';
5
+ import type { DatePickerLocale } from '../DatePicker/context';
5
6
  import { type DisableWeekDaysType, showWeekDay } from './dateUtils';
6
7
  import DayName from './DayName';
7
8
  import { dateDayNameStyles } from './utils';
8
9
 
9
- const shortDayNames = (() => {
10
- const firstDOW = startOfWeek(new Date());
11
- return Array.from(Array(7)).map((_, i) => format(addDays(firstDOW, i), 'EEEEE'));
12
- })();
13
-
14
10
  function DayNames({
15
11
  disableWeekDays,
16
- }: // locale,
17
- {
12
+ locale,
13
+ }: {
18
14
  disableWeekDays?: DisableWeekDaysType;
19
- locale?: string;
15
+ locale?: DatePickerLocale;
20
16
  }) {
17
+ const shortDayNames = useMemo(() => {
18
+ const firstDOW = startOfWeek(new Date());
19
+ return Array.from(Array(7)).map((_, i) =>
20
+ new Intl.DateTimeFormat(locale, { weekday: 'narrow' }).format(addDays(firstDOW, i)),
21
+ );
22
+ }, [locale]);
23
+
21
24
  return (
22
25
  <View style={dateDayNameStyles.container} pointerEvents={'none'}>
23
26
  {shortDayNames
@@ -1,5 +1,5 @@
1
1
  import { memo } from 'react';
2
- import { StyleSheet, View } from 'react-native';
2
+ import { View } from 'react-native';
3
3
 
4
4
  import { resolveStateVariant } from '../../utils';
5
5
  import { datePickerDayRangeStyles } from './utils';
@@ -29,9 +29,7 @@ function DayRange({
29
29
  return (
30
30
  <>
31
31
  {(inRange || isCrop) && (
32
- <View
33
- pointerEvents="none"
34
- style={[StyleSheet.absoluteFill, datePickerDayRangeStyles.container]}>
32
+ <View pointerEvents="none" style={datePickerDayRangeStyles.container}>
35
33
  {isCrop && (
36
34
  <>
37
35
  <View style={datePickerDayRangeStyles.rightCrop} />
@@ -1,7 +1,8 @@
1
- import { memo, useCallback, useMemo } from 'react';
2
- import { type StyleProp, View, type ViewStyle } from 'react-native';
1
+ import { memo, useCallback } from 'react';
2
+ import { View } from 'react-native';
3
3
 
4
- import { datePickerHeaderItemStyles } from '../DatePickerDocked/utils';
4
+ import { datePickerHeaderItemStyles } from '../DatePicker/utils';
5
+ import { Icon } from '../Icon';
5
6
  import { IconButton } from '../IconButton';
6
7
  import { Text } from '../Text';
7
8
  import { TouchableRipple } from '../TouchableRipple';
@@ -42,10 +43,11 @@ function HeaderItem({
42
43
  onNext && onNext(type);
43
44
  }, [onNext, type]);
44
45
 
45
- const containerStyle = useMemo(
46
- () =>
47
- [
46
+ return (
47
+ <View
48
+ style={[
48
49
  datePickerHeaderItemStyles.buttonContainer,
50
+ // eslint-disable-next-line react-native/no-inline-styles
49
51
  {
50
52
  justifyContent: !onPressDropdown
51
53
  ? 'flex-end'
@@ -53,22 +55,23 @@ function HeaderItem({
53
55
  ? 'flex-start'
54
56
  : 'center',
55
57
  },
56
- ] as StyleProp<ViewStyle>,
57
- [onPressDropdown, onNext],
58
- );
59
-
60
- return (
61
- <View style={containerStyle} pointerEvents={'box-none'}>
62
- {!selecting && onPrev && (
63
- <View style={datePickerHeaderItemStyles.buttonWrapper}>
58
+ ]}
59
+ pointerEvents={'box-none'}>
60
+ {onPrev && (
61
+ <View
62
+ style={[
63
+ datePickerHeaderItemStyles.buttonWrapper,
64
+ // eslint-disable-next-line react-native/no-inline-styles
65
+ (selecting || disabled) && { opacity: 0 },
66
+ ]}>
64
67
  <IconButton
65
68
  type="material-community"
66
69
  name="chevron-left"
67
- size="md"
70
+ size={24}
68
71
  // Todo: Translate
69
72
  accessibilityLabel={'Previous'}
70
73
  onPress={handleOnPrevious}
71
- disabled={value === startDateYear}
74
+ disabled={value === startDateYear || selecting || disabled}
72
75
  />
73
76
  </View>
74
77
  )}
@@ -80,27 +83,39 @@ function HeaderItem({
80
83
  accessibilityLabel={`${value}`}
81
84
  style={datePickerHeaderItemStyles.buttonStyle}>
82
85
  <View style={datePickerHeaderItemStyles.innerStyle}>
83
- <Text style={datePickerHeaderItemStyles.labelStyle} selectable={false}>
86
+ <Text
87
+ style={[
88
+ datePickerHeaderItemStyles.labelStyle,
89
+ // eslint-disable-next-line react-native/no-inline-styles
90
+ disabled && { opacity: 0.5 },
91
+ ]}
92
+ selectable={false}>
84
93
  {value}
85
94
  </Text>
86
- <IconButton
87
- onPress={handlePressDropDown}
88
- name={selecting && type === pickerType ? 'menu-up' : 'menu-down'}
89
- size="sm"
90
- disabled={disabled}
91
- />
95
+ {!disabled && (
96
+ <Icon
97
+ onPress={handlePressDropDown}
98
+ name={selecting && type === pickerType ? 'menu-up' : 'menu-down'}
99
+ size={18}
100
+ />
101
+ )}
92
102
  </View>
93
103
  </TouchableRipple>
94
104
  )}
95
- {!selecting && onNext && (
96
- <View style={datePickerHeaderItemStyles.buttonWrapper}>
105
+ {onNext && (
106
+ <View
107
+ style={[
108
+ datePickerHeaderItemStyles.buttonWrapper,
109
+ // eslint-disable-next-line react-native/no-inline-styles
110
+ (selecting || disabled) && { opacity: 0 },
111
+ ]}>
97
112
  <IconButton
98
113
  name="chevron-right"
99
- size="md"
114
+ size={24}
100
115
  // Todo: Translate
101
116
  accessibilityLabel={'Next'}
102
117
  onPress={handleOnNext}
103
- disabled={value === endDateYear}
118
+ disabled={value === endDateYear || selecting || disabled}
104
119
  />
105
120
  </View>
106
121
  )}
@@ -1,9 +1,7 @@
1
- import { memo, useCallback, useMemo } from 'react';
1
+ import { memo, useMemo } from 'react';
2
2
  import { View } from 'react-native';
3
3
 
4
- import { format } from '../../utils/date-fns';
5
4
  import { Text } from '../Text';
6
- import { useDatePickerStoreValue } from './DatePickerContext';
7
5
  import { getCalendarHeaderHeight } from './DatePickerInlineHeader';
8
6
  import {
9
7
  addMonths,
@@ -14,6 +12,7 @@ import {
14
12
  getRealIndex,
15
13
  gridCounts,
16
14
  startAtIndex,
15
+ totalMonths,
17
16
  useRangeChecker,
18
17
  } from './dateUtils';
19
18
  import type { MonthMultiProps, MonthRangeProps, MonthSingleProps } from './types';
@@ -42,11 +41,10 @@ function Month(props: MonthSingleProps | MonthRangeProps | MonthMultiProps) {
42
41
  scrollMode,
43
42
  disableWeekDays,
44
43
  validRange,
44
+ showOutsideDays,
45
+ locale,
45
46
  // customMonthStyles,
46
47
  } = props;
47
- const { localDate } = useDatePickerStoreValue(state => ({ localDate: state.localDate }));
48
- // const monthStyles = useComponentStyles('DatePicker_Month', customMonthStyles);
49
-
50
48
  const isHorizontal = scrollMode === 'horizontal';
51
49
  const { isDisabled, isWithinValidRange } = useRangeChecker(validRange);
52
50
 
@@ -54,11 +52,12 @@ function Month(props: MonthSingleProps | MonthRangeProps | MonthMultiProps) {
54
52
  const realIndex = getRealIndex(index);
55
53
 
56
54
  const md = addMonths(new Date(), realIndex);
57
- const y = mode === 'single' ? localDate.getFullYear() : md.getFullYear();
58
- const m = mode === 'single' ? localDate.getMonth() : md.getMonth();
55
+ const y = md.getFullYear();
56
+ const m = md.getMonth();
57
+ const name = new Intl.DateTimeFormat(locale, { month: 'long' }).format(md);
59
58
 
60
- return { monthName: format(md, 'LLLL'), month: m, year: y };
61
- }, [index, localDate, mode]);
59
+ return { monthName: name, month: m, year: y };
60
+ }, [index, locale]);
62
61
 
63
62
  const grid = useMemo(
64
63
  () =>
@@ -78,67 +77,34 @@ function Month(props: MonthSingleProps | MonthRangeProps | MonthMultiProps) {
78
77
  [year, month, index, isDisabled, mode, isWithinValidRange, startDate, endDate, dates, date],
79
78
  );
80
79
 
81
- const { headerStyle, yearButtonStyle, yearInnerStyle, monthLabelStyle, weekContainerStyle } =
82
- useMemo(() => {
83
- // const {
84
- // monthLabel: _monthLabel,
85
- // yearButton,
86
- // yearButtonInner,
87
- // month: _monthStyle,
88
- // monthHeader,
89
- // dockedHeaderStyle,
90
- // weekContainerStyle: weekContainer,
91
- // } = monthStyles;
92
- // const { typescale, ...monthLabel } = _monthLabel;
93
-
94
- return {
95
- headerStyle: [
96
- datePickerMonthStyles.monthHeader,
97
- isHorizontal
98
- ? [
99
- datePickerMonthStyles.dockedHeaderStyle,
100
- {
101
- marginTop: monthHeaderSingleMarginTop,
102
- marginBottom: monthHeaderSingleMarginBottom,
103
- },
104
- ]
105
- : null,
106
- ],
107
- yearButtonStyle: datePickerMonthStyles.yearButton,
108
- yearInnerStyle: datePickerMonthStyles.yearButtonInner,
109
- monthLabelStyle: [datePickerMonthStyles.monthLabel],
110
- weekContainerStyle: datePickerMonthStyles.weekContainerStyle,
111
- };
112
- }, [isHorizontal]);
113
-
114
- const renderHeader = useCallback(() => {
115
- if (!isHorizontal) {
116
- return (
80
+ const headerStyle = [
81
+ datePickerMonthStyles.monthHeader,
82
+ isHorizontal
83
+ ? [
84
+ datePickerMonthStyles.dockedHeaderStyle,
85
+ {
86
+ marginTop: monthHeaderSingleMarginTop,
87
+ marginBottom: monthHeaderSingleMarginBottom,
88
+ },
89
+ ]
90
+ : null,
91
+ ];
92
+
93
+ return (
94
+ <View>
95
+ {!isHorizontal ? (
117
96
  <View style={headerStyle}>
118
- <View accessibilityLabel={`${monthName} ${year}`} style={yearButtonStyle}>
119
- <View style={yearInnerStyle}>
120
- <Text style={monthLabelStyle} selectable={false}>
97
+ <View
98
+ accessibilityLabel={`${monthName} ${year}`}
99
+ style={[datePickerMonthStyles.yearButton]}>
100
+ <View style={[datePickerMonthStyles.yearButtonInner]}>
101
+ <Text style={datePickerMonthStyles.monthLabel} selectable={false}>
121
102
  {monthName} {year}
122
103
  </Text>
123
104
  </View>
124
105
  </View>
125
106
  </View>
126
- );
127
- }
128
- return null;
129
- }, [
130
- headerStyle,
131
- isHorizontal,
132
- monthLabelStyle,
133
- monthName,
134
- year,
135
- yearButtonStyle,
136
- yearInnerStyle,
137
- ]);
138
-
139
- return (
140
- <View>
141
- {renderHeader()}
107
+ ) : null}
142
108
  {grid.map(({ weekIndex, generatedDays }) => (
143
109
  <Week
144
110
  key={weekIndex}
@@ -146,7 +112,8 @@ function Month(props: MonthSingleProps | MonthRangeProps | MonthMultiProps) {
146
112
  generatedDays={generatedDays}
147
113
  disableWeekDays={disableWeekDays}
148
114
  onPressDate={onPressDate}
149
- style={weekContainerStyle}
115
+ showOutsideDays={showOutsideDays}
116
+ style={datePickerMonthStyles.weekContainerStyle}
150
117
  />
151
118
  ))}
152
119
  </View>
@@ -190,7 +157,21 @@ function weeksOffset(index: number): number {
190
157
  }
191
158
 
192
159
  export function getIndexFromHorizontalOffset(offset: number, width: number): number {
193
- return startAtIndex + Math.floor(offset / width);
160
+ if (!Number.isFinite(offset) || !Number.isFinite(width) || width <= 1) {
161
+ return startAtIndex;
162
+ }
163
+
164
+ const rawIndex = startAtIndex + Math.floor(offset / width);
165
+
166
+ if (rawIndex < 0) {
167
+ return 0;
168
+ }
169
+
170
+ if (rawIndex >= totalMonths) {
171
+ return totalMonths - 1;
172
+ }
173
+
174
+ return rawIndex;
194
175
  }
195
176
 
196
177
  export function getIndexFromVerticalOffset(offset: number): number {
@@ -1,21 +1,19 @@
1
- import { format, setMonth } from 'date-fns';
1
+ import { setMonth } from 'date-fns';
2
2
  import { memo, useCallback, useMemo, useRef } from 'react';
3
3
  import { FlatList, View, type ViewStyle } from 'react-native';
4
4
  import { StyleSheet } from 'react-native-unistyles';
5
5
 
6
6
  import { resolveStateVariant } from '../../utils';
7
7
  import { range } from '../../utils/dateTimePicker';
8
- import {
9
- datePickerDockedMonthItemStyles,
10
- datePickerMonthPickerStyles,
11
- } from '../DatePickerDocked/utils';
8
+ import type { DatePickerLocale } from '../DatePicker/context';
9
+ import { datePickerMonthItemStyles, datePickerMonthPickerStyles } from '../DatePicker/utils';
12
10
  import { HorizontalDivider } from '../HorizontalDivider';
13
11
  import { Icon } from '../Icon';
14
12
  import { ListItem } from '../ListItem/';
15
13
  import { Text } from '../Text';
16
14
  import { useDatePickerStore, useDatePickerStoreValue } from './DatePickerContext';
17
15
 
18
- export default function MonthPicker() {
16
+ export default function MonthPicker({ locale }: { locale?: DatePickerLocale }) {
19
17
  const [_, setStore] = useDatePickerStore(state => state);
20
18
  const { localDate, selectingMonth } = useDatePickerStoreValue(state => ({
21
19
  localDate: state.localDate,
@@ -25,20 +23,6 @@ export default function MonthPicker() {
25
23
  const flatList = useRef<FlatList<number> | null>(null);
26
24
  const months = range(0, 11);
27
25
 
28
- const { containerStyle, monthStyle } = useMemo(() => {
29
- const { backgroundColor, ...rest } = datePickerMonthPickerStyles.root;
30
-
31
- return {
32
- containerStyle: [
33
- StyleSheet.absoluteFill,
34
- styles.root,
35
- { backgroundColor },
36
- selectingMonth ? styles.opacity1 : styles.opacity0,
37
- ],
38
- monthStyle: rest,
39
- };
40
- }, [selectingMonth]);
41
-
42
26
  const handleOnChange = useCallback(
43
27
  (month: number) => {
44
28
  setStore(prev => ({
@@ -56,11 +40,12 @@ export default function MonthPicker() {
56
40
  month={item}
57
41
  selected={localDate.getMonth() === item}
58
42
  onPressMonth={handleOnChange}
59
- monthStyles={monthStyle}
43
+ monthStyles={datePickerMonthPickerStyles.root}
44
+ locale={locale}
60
45
  />
61
46
  );
62
47
  },
63
- [localDate, handleOnChange, monthStyle],
48
+ [localDate, handleOnChange, locale],
64
49
  );
65
50
 
66
51
  if (!selectingMonth) {
@@ -68,7 +53,14 @@ export default function MonthPicker() {
68
53
  }
69
54
 
70
55
  return (
71
- <View style={containerStyle} pointerEvents={selectingMonth ? 'auto' : 'none'}>
56
+ <View
57
+ style={[
58
+ StyleSheet.absoluteFill,
59
+ styles.root,
60
+ // { backgroundColor },
61
+ selectingMonth ? styles.opacity1 : styles.opacity0,
62
+ ]}
63
+ pointerEvents={selectingMonth ? 'auto' : 'none'}>
72
64
  <HorizontalDivider />
73
65
  <FlatList<number>
74
66
  ref={flatList}
@@ -86,35 +78,37 @@ function MonthPure({
86
78
  selected,
87
79
  onPressMonth,
88
80
  monthStyles,
81
+ locale,
89
82
  }: {
90
83
  month: number;
91
84
  selected: boolean;
92
85
  onPressMonth: (newMonth: number) => any;
93
86
  monthStyles: ViewStyle;
87
+ locale?: DatePickerLocale;
94
88
  }) {
95
89
  const state = resolveStateVariant({
96
90
  selected,
97
91
  });
98
- datePickerDockedMonthItemStyles.useVariants({
92
+
93
+ datePickerMonthItemStyles.useVariants({
99
94
  state: state as any,
100
95
  });
101
- // const montLocalStyles = useComponentStyles('DatePickerDocked_MonthItem', monthStyles, {
102
- // state: resolveStateVariant({
103
- // selected,
104
- // }),
105
- // });
106
- const { monthInnerStyle, monthLabelStyle, monthButtonStyle, accessibilityState } =
107
- useMemo(() => {
108
- const { monthInner, monthLabel, monthButton } = datePickerDockedMonthItemStyles;
109
-
110
- return {
111
- monthInnerStyle: monthInner,
112
- monthLabelStyle: monthLabel,
113
- monthButtonStyle: [monthButton, monthStyles],
114
- accessibilityState: { selected },
115
- };
116
- // eslint-disable-next-line react-hooks/exhaustive-deps
117
- }, [selected, monthStyles, state]);
96
+
97
+ const { monthButtonStyle, accessibilityState } = useMemo(() => {
98
+ const { monthButton } = datePickerMonthItemStyles;
99
+
100
+ return {
101
+ monthButtonStyle: [monthButton, monthStyles],
102
+ accessibilityState: { selected },
103
+ };
104
+ // eslint-disable-next-line react-hooks/exhaustive-deps
105
+ }, [selected, monthStyles, state]);
106
+
107
+ const monthLabel = useMemo(
108
+ () =>
109
+ new Intl.DateTimeFormat(locale, { month: 'long' }).format(new Date(2000, month, 1)),
110
+ [locale, month],
111
+ );
118
112
 
119
113
  const handleMonthPress = useCallback(() => {
120
114
  onPressMonth(month);
@@ -137,9 +131,9 @@ function MonthPure({
137
131
  <View style={styles.spacer} />
138
132
  )
139
133
  }>
140
- <View style={monthInnerStyle}>
141
- <Text style={monthLabelStyle} selectable={false}>
142
- {format(new Date(2000, month, 1), 'MMMM')}
134
+ <View style={datePickerMonthItemStyles.monthInner}>
135
+ <Text style={datePickerMonthItemStyles.monthLabel} selectable={false}>
136
+ {monthLabel}
143
137
  </Text>
144
138
  </View>
145
139
  </ListItem>
@@ -1,4 +1,4 @@
1
- import { memo, useCallback, useMemo, useRef, useState } from 'react';
1
+ import { memo, useCallback, useEffect, useMemo, useRef, useState } from 'react';
2
2
  import {
3
3
  type NativeScrollEvent,
4
4
  type NativeSyntheticEvent,
@@ -9,7 +9,9 @@ import {
9
9
  } from 'react-native';
10
10
 
11
11
  import AutoSizer from './AutoSizer';
12
- import { beginOffset, estimatedMonthHeight, totalMonths } from './dateUtils';
12
+ import { useDatePickerStore } from './DatePickerContext';
13
+ import { beginOffset, estimatedMonthHeight, getInitialIndex, totalMonths } from './dateUtils';
14
+ import { addMonths, getRealIndex } from './dateUtils';
13
15
  import {
14
16
  getHorizontalMonthOffset,
15
17
  getIndexFromVerticalOffset,
@@ -54,11 +56,16 @@ function SwiperInner({
54
56
  );
55
57
 
56
58
  const parentRef = useRef<ScrollView | null>(null);
59
+ const [{ localDate }, setStore] = useDatePickerStore(state => state);
57
60
 
58
61
  const scrollTo = useCallback(
59
62
  (index: number, animated: boolean) => {
60
63
  idx.current = index;
61
64
  setVisibleIndexes(getVisibleArray(index, { isHorizontal, height }));
65
+ setStore(prev => ({
66
+ ...prev,
67
+ localDate: addMonths(new Date(), getRealIndex(index)),
68
+ }));
62
69
 
63
70
  if (!parentRef.current) {
64
71
  return;
@@ -81,13 +88,19 @@ function SwiperInner({
81
88
  });
82
89
  }
83
90
  },
84
- [parentRef, isHorizontal, width, height],
91
+ [parentRef, isHorizontal, width, height, setStore],
85
92
  );
86
93
 
87
94
  const scrollToInitial = useCallback(() => {
88
95
  scrollTo(idx.current, false);
89
96
  }, [scrollTo]);
90
97
 
98
+ useEffect(() => {
99
+ const targetIndex = getInitialIndex(localDate);
100
+ if (targetIndex === idx.current) return;
101
+ scrollTo(targetIndex, false);
102
+ }, [localDate, scrollTo]);
103
+
91
104
  const onMomentumScrollEnd = useCallback(
92
105
  (e: NativeSyntheticEvent<NativeScrollEvent>) => {
93
106
  const contentOffset = e.nativeEvent.contentOffset;
@@ -103,9 +116,13 @@ function SwiperInner({
103
116
  if (idx.current !== newIndex) {
104
117
  idx.current = newIndex;
105
118
  setVisibleIndexes(getVisibleArray(newIndex, { isHorizontal, height }));
119
+ setStore(prev => ({
120
+ ...prev,
121
+ localDate: addMonths(new Date(), getRealIndex(newIndex)),
122
+ }));
106
123
  }
107
124
  },
108
- [idx, height, isHorizontal],
125
+ [idx, height, isHorizontal, setStore],
109
126
  );
110
127
 
111
128
  const { innerContainerStyle, itemContainerStyle } = useMemo(() => {