@momo-kits/calendar 0.168.1-rn862.1 → 0.169.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.
- package/CalendarHeader.tsx +107 -0
- package/CalendarPro.tsx +15 -20
- package/ContainerContext.ts +3 -0
- package/Day.tsx +14 -14
- package/HeaderControl.tsx +1 -2
- package/LunarDateConverter.ts +21 -19
- package/Month.tsx +5 -14
- package/MonthList.tsx +36 -23
- package/TabHeader.tsx +57 -80
- package/Util.ts +2 -101
- package/index.tsx +42 -110
- package/package.json +7 -7
- package/styles.ts +22 -16
- package/types.ts +5 -38
- package/LunarService.ts +0 -206
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import React, { useContext } from 'react';
|
|
2
|
+
import { View } from 'react-native';
|
|
3
|
+
import moment from 'moment';
|
|
4
|
+
import { ApplicationContext, Switch, Text } from '@momo-kits/foundation';
|
|
5
|
+
import TabHeader from './TabHeader';
|
|
6
|
+
import { TabHeaderRef } from './types';
|
|
7
|
+
import styles from './styles';
|
|
8
|
+
|
|
9
|
+
type SwitchReturnSelectionProps = {
|
|
10
|
+
hidden?: boolean;
|
|
11
|
+
title?: string;
|
|
12
|
+
value: boolean;
|
|
13
|
+
onChange: () => void;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export const SwitchReturnSelection: React.FC<
|
|
17
|
+
SwitchReturnSelectionProps
|
|
18
|
+
> = props => {
|
|
19
|
+
const { translate, theme } = useContext(ApplicationContext);
|
|
20
|
+
if (props.hidden) return null;
|
|
21
|
+
return (
|
|
22
|
+
<View style={styles.headerContainer}>
|
|
23
|
+
<View
|
|
24
|
+
style={[
|
|
25
|
+
styles.viewSwitch,
|
|
26
|
+
{ backgroundColor: theme.colors.background.surface },
|
|
27
|
+
]}
|
|
28
|
+
>
|
|
29
|
+
<Text typography="label_default_medium">
|
|
30
|
+
{props.title || translate?.('chooseRoundtrip')}
|
|
31
|
+
</Text>
|
|
32
|
+
<Switch value={props.value} onChange={props.onChange} />
|
|
33
|
+
</View>
|
|
34
|
+
</View>
|
|
35
|
+
);
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
type HeaderPanelProps = {
|
|
39
|
+
isDoubleDateMode: boolean;
|
|
40
|
+
cellHeader1: React.RefObject<TabHeaderRef | null>;
|
|
41
|
+
cellHeader2: React.RefObject<TabHeaderRef | null>;
|
|
42
|
+
cellHeaderSingle: React.RefObject<TabHeaderRef | null>;
|
|
43
|
+
onChangeTab: (tabId: number) => void;
|
|
44
|
+
headerFrom?: string;
|
|
45
|
+
headerTo?: string;
|
|
46
|
+
firstDate: moment.Moment | null;
|
|
47
|
+
secondDate: moment.Moment | null;
|
|
48
|
+
selectedDate: moment.Moment;
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
export const HeaderPanel: React.FC<HeaderPanelProps> = props => {
|
|
52
|
+
const { theme } = useContext(ApplicationContext);
|
|
53
|
+
const {
|
|
54
|
+
isDoubleDateMode,
|
|
55
|
+
cellHeader1,
|
|
56
|
+
cellHeader2,
|
|
57
|
+
cellHeaderSingle,
|
|
58
|
+
onChangeTab,
|
|
59
|
+
headerFrom,
|
|
60
|
+
headerTo,
|
|
61
|
+
firstDate,
|
|
62
|
+
secondDate,
|
|
63
|
+
selectedDate,
|
|
64
|
+
} = props;
|
|
65
|
+
return isDoubleDateMode ? (
|
|
66
|
+
<View
|
|
67
|
+
style={[
|
|
68
|
+
styles.viewPanel,
|
|
69
|
+
{ backgroundColor: theme.colors.background.default },
|
|
70
|
+
]}
|
|
71
|
+
>
|
|
72
|
+
<TabHeader
|
|
73
|
+
id={0}
|
|
74
|
+
ref={cellHeader1}
|
|
75
|
+
onChangeTab={onChangeTab}
|
|
76
|
+
label={headerFrom || 'depart'}
|
|
77
|
+
activeTab
|
|
78
|
+
date={firstDate}
|
|
79
|
+
/>
|
|
80
|
+
<View style={styles.tabGap} />
|
|
81
|
+
<TabHeader
|
|
82
|
+
id={1}
|
|
83
|
+
ref={cellHeader2}
|
|
84
|
+
onChangeTab={onChangeTab}
|
|
85
|
+
label={headerTo || 'return'}
|
|
86
|
+
activeTab={false}
|
|
87
|
+
date={secondDate}
|
|
88
|
+
/>
|
|
89
|
+
</View>
|
|
90
|
+
) : (
|
|
91
|
+
<View
|
|
92
|
+
style={[
|
|
93
|
+
styles.viewPanel,
|
|
94
|
+
{ backgroundColor: theme.colors.background.default },
|
|
95
|
+
]}
|
|
96
|
+
>
|
|
97
|
+
<TabHeader
|
|
98
|
+
id={0}
|
|
99
|
+
disabled
|
|
100
|
+
ref={cellHeaderSingle}
|
|
101
|
+
label={headerFrom || 'depart'}
|
|
102
|
+
activeTab
|
|
103
|
+
date={selectedDate}
|
|
104
|
+
/>
|
|
105
|
+
</View>
|
|
106
|
+
);
|
|
107
|
+
};
|
package/CalendarPro.tsx
CHANGED
|
@@ -7,18 +7,16 @@ import React, {
|
|
|
7
7
|
forwardRef,
|
|
8
8
|
useImperativeHandle,
|
|
9
9
|
} from 'react';
|
|
10
|
-
import {
|
|
10
|
+
import { ScrollView, View } from 'react-native';
|
|
11
11
|
import moment, { Moment } from 'moment';
|
|
12
12
|
import {
|
|
13
13
|
ApplicationContext,
|
|
14
14
|
CheckBox,
|
|
15
|
-
Colors,
|
|
16
15
|
Spacing,
|
|
17
16
|
Text,
|
|
18
17
|
} from '@momo-kits/foundation';
|
|
19
18
|
import MonthList from './MonthList';
|
|
20
19
|
import HeaderControl from './HeaderControl';
|
|
21
|
-
import LunarDateConverter from './LunarDateConverter';
|
|
22
20
|
import Util from './Util';
|
|
23
21
|
import {
|
|
24
22
|
CalendarProProps,
|
|
@@ -27,7 +25,7 @@ import {
|
|
|
27
25
|
MonthListRef,
|
|
28
26
|
Holidays,
|
|
29
27
|
} from './types';
|
|
30
|
-
import { ContainerContext } from './
|
|
28
|
+
import { ContainerContext } from './ContainerContext';
|
|
31
29
|
import styles from './styles';
|
|
32
30
|
|
|
33
31
|
const CalendarPro = forwardRef<CalendarProRef, CalendarProProps>(
|
|
@@ -53,8 +51,7 @@ const CalendarPro = forwardRef<CalendarProRef, CalendarProProps>(
|
|
|
53
51
|
const { theme, translate } = useContext(ApplicationContext);
|
|
54
52
|
const size = useContext(ContainerContext);
|
|
55
53
|
|
|
56
|
-
const
|
|
57
|
-
const headerRef = useRef<Moment>(today.clone());
|
|
54
|
+
const headerRef = useRef<Moment>(moment());
|
|
58
55
|
const headerControlRef = useRef<HeaderControlRef>(null);
|
|
59
56
|
const monthListRef = useRef<MonthListRef>(null);
|
|
60
57
|
|
|
@@ -84,10 +81,6 @@ const CalendarPro = forwardRef<CalendarProRef, CalendarProProps>(
|
|
|
84
81
|
const [temp, setTemp] = useState<any[]>([]);
|
|
85
82
|
const [headerKey, setHeaderKey] = useState<string>('');
|
|
86
83
|
const [ownUpdate, setOwnUpdate] = useState<boolean>(false);
|
|
87
|
-
const converter: any = useMemo(
|
|
88
|
-
() => (new LunarDateConverter()),
|
|
89
|
-
[],
|
|
90
|
-
);
|
|
91
84
|
|
|
92
85
|
useImperativeHandle(ref, () => ({
|
|
93
86
|
setDoubleDateAndTabIndex: (
|
|
@@ -99,11 +92,6 @@ const CalendarPro = forwardRef<CalendarProRef, CalendarProProps>(
|
|
|
99
92
|
if (firstDate) setStartDate(firstDate);
|
|
100
93
|
if (secondDate !== undefined) setEndDate(secondDate);
|
|
101
94
|
},
|
|
102
|
-
setDateRange: (dateRange: { startDate: any; endDate: any }) => {
|
|
103
|
-
if (monthListRef.current && dateRange.startDate) {
|
|
104
|
-
monthListRef.current.scrollToMonth(moment(dateRange.startDate));
|
|
105
|
-
}
|
|
106
|
-
},
|
|
107
95
|
}));
|
|
108
96
|
|
|
109
97
|
// Sync showLunar prop
|
|
@@ -205,7 +193,12 @@ const CalendarPro = forwardRef<CalendarProRef, CalendarProProps>(
|
|
|
205
193
|
}
|
|
206
194
|
|
|
207
195
|
return (
|
|
208
|
-
<View
|
|
196
|
+
<View
|
|
197
|
+
style={[
|
|
198
|
+
styles.container,
|
|
199
|
+
{ backgroundColor: theme.colors.background.surface },
|
|
200
|
+
]}
|
|
201
|
+
>
|
|
209
202
|
<HeaderControl
|
|
210
203
|
ref={headerControlRef}
|
|
211
204
|
selectedDate={propSelectedDate}
|
|
@@ -218,11 +211,15 @@ const CalendarPro = forwardRef<CalendarProRef, CalendarProProps>(
|
|
|
218
211
|
{[1, 2, 3, 4, 5, 6, 7].map(dayIdx => (
|
|
219
212
|
<Text
|
|
220
213
|
key={dayIdx}
|
|
221
|
-
color={
|
|
214
|
+
color={
|
|
215
|
+
dayIdx >= 6
|
|
216
|
+
? theme.colors.error.primary
|
|
217
|
+
: theme.colors.text.default
|
|
218
|
+
}
|
|
222
219
|
typography="label_s_medium"
|
|
223
220
|
style={[
|
|
224
221
|
styles.textDay,
|
|
225
|
-
{ width: (size.width - Spacing.
|
|
222
|
+
{ width: (size.width - Spacing.S * 2) / 7 },
|
|
226
223
|
]}
|
|
227
224
|
>
|
|
228
225
|
{translate?.(Util.mapWeeKDate(dayIdx))}
|
|
@@ -231,7 +228,6 @@ const CalendarPro = forwardRef<CalendarProRef, CalendarProProps>(
|
|
|
231
228
|
</View>
|
|
232
229
|
<MonthList
|
|
233
230
|
ref={monthListRef}
|
|
234
|
-
today={today}
|
|
235
231
|
minDate={minDate}
|
|
236
232
|
maxDate={maxDate}
|
|
237
233
|
startDate={startDate!}
|
|
@@ -241,7 +237,6 @@ const CalendarPro = forwardRef<CalendarProRef, CalendarProProps>(
|
|
|
241
237
|
isShowLunar={!isOffLunar && showLunar}
|
|
242
238
|
isDoubleDateMode={isDoubleDateMode}
|
|
243
239
|
tabSelected={tabSelected}
|
|
244
|
-
lunarConverter={converter}
|
|
245
240
|
holidays={holidays}
|
|
246
241
|
selectedDate={propSelectedDate}
|
|
247
242
|
priceList={priceListFormat}
|
package/Day.tsx
CHANGED
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
exportFontFamily,
|
|
10
10
|
} from '@momo-kits/foundation';
|
|
11
11
|
import { DayProps } from './types';
|
|
12
|
-
import { ContainerContext } from './
|
|
12
|
+
import { ContainerContext } from './ContainerContext';
|
|
13
13
|
import styles from './styles';
|
|
14
14
|
|
|
15
15
|
const Day: React.FC<DayProps> = props => {
|
|
@@ -36,13 +36,12 @@ const Day: React.FC<DayProps> = props => {
|
|
|
36
36
|
|
|
37
37
|
const { theme } = useContext(ApplicationContext);
|
|
38
38
|
const size = useContext(ContainerContext);
|
|
39
|
-
const scaledHeight = useScaleSize(48);
|
|
40
39
|
const scaledSpacing = useScaleSize(Spacing.XS);
|
|
41
40
|
const scaledFontSize = useScaleSize(8);
|
|
42
41
|
const scaledLineHeight = useScaleSize(12);
|
|
43
42
|
const lunarFontFamily = exportFontFamily('regular');
|
|
44
43
|
|
|
45
|
-
const itemWidth = (size.width - Spacing.
|
|
44
|
+
const itemWidth = (size.width - Spacing.S * 2) / 7;
|
|
46
45
|
if (isEmpty || !date) {
|
|
47
46
|
return <View style={[styles.dayContainer, { width: itemWidth }]} />;
|
|
48
47
|
}
|
|
@@ -111,10 +110,9 @@ const Day: React.FC<DayProps> = props => {
|
|
|
111
110
|
styles.day,
|
|
112
111
|
{
|
|
113
112
|
width: itemWidth,
|
|
114
|
-
paddingVertical:
|
|
113
|
+
paddingVertical: price ? Spacing.XS : Spacing.S,
|
|
115
114
|
},
|
|
116
115
|
(isStart || isEnd) && { backgroundColor: theme.colors.primary },
|
|
117
|
-
!!price && { height: scaledHeight },
|
|
118
116
|
{ height: size.height },
|
|
119
117
|
]}
|
|
120
118
|
disabled={!(isValid && isInScope)}
|
|
@@ -123,15 +121,17 @@ const Day: React.FC<DayProps> = props => {
|
|
|
123
121
|
{lunarDate && showLunar && !!date && (
|
|
124
122
|
<RNText
|
|
125
123
|
allowFontScaling={false}
|
|
126
|
-
style={
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
124
|
+
style={[
|
|
125
|
+
styles.lunarText,
|
|
126
|
+
{
|
|
127
|
+
top: scaledSpacing,
|
|
128
|
+
right: scaledSpacing,
|
|
129
|
+
color: lunarTextColor,
|
|
130
|
+
fontSize: scaledFontSize,
|
|
131
|
+
lineHeight: scaledLineHeight,
|
|
132
|
+
fontFamily: lunarFontFamily,
|
|
133
|
+
},
|
|
134
|
+
]}
|
|
135
135
|
>
|
|
136
136
|
{lunarLabel}
|
|
137
137
|
</RNText>
|
package/HeaderControl.tsx
CHANGED
|
@@ -7,7 +7,6 @@ import React, {
|
|
|
7
7
|
} from 'react';
|
|
8
8
|
import {TouchableOpacity, View} from 'react-native';
|
|
9
9
|
import moment from 'moment';
|
|
10
|
-
import Moment from 'moment';
|
|
11
10
|
import {ApplicationContext, Icon, Text} from '@momo-kits/foundation';
|
|
12
11
|
|
|
13
12
|
import Util from './Util';
|
|
@@ -19,7 +18,7 @@ const HeaderControl: ForwardRefRenderFunction<
|
|
|
19
18
|
HeaderControlProps
|
|
20
19
|
> = ({onPressBackArrow, onPressNextArrow, selectedDate}, ref) => {
|
|
21
20
|
const {translate} = useContext(ApplicationContext);
|
|
22
|
-
const [info, setInfo] = useState<{date:
|
|
21
|
+
const [info, setInfo] = useState<{date: moment.Moment}>({
|
|
23
22
|
date: moment(selectedDate || new Date()),
|
|
24
23
|
});
|
|
25
24
|
|
package/LunarDateConverter.ts
CHANGED
|
@@ -77,6 +77,7 @@ function LunarSolarConverter(this: any) {
|
|
|
77
77
|
* @return {number}
|
|
78
78
|
*/
|
|
79
79
|
this.GetBitInt = function (data: number, length: number, shift: number) {
|
|
80
|
+
// eslint-disable-next-line no-bitwise -- unpacks bit-packed lunar table data
|
|
80
81
|
return (data & (((1 << length) - 1) << shift)) >> shift;
|
|
81
82
|
};
|
|
82
83
|
|
|
@@ -86,43 +87,43 @@ function LunarSolarConverter(this: any) {
|
|
|
86
87
|
*/
|
|
87
88
|
this.SolarToInt = function (y: number, m: number, d: number) {
|
|
88
89
|
m = (m + 9) % 12;
|
|
89
|
-
y = parseInt(String(y)) - parseInt(String(m / 10));
|
|
90
|
+
y = parseInt(String(y), 10) - parseInt(String(m / 10), 10);
|
|
90
91
|
return (
|
|
91
92
|
365 * y +
|
|
92
|
-
parseInt(String(y / 4)) -
|
|
93
|
-
parseInt(String(y / 100)) +
|
|
94
|
-
parseInt(String(y / 400)) +
|
|
95
|
-
parseInt(String((m * 306 + 5) / 10)) +
|
|
93
|
+
parseInt(String(y / 4), 10) -
|
|
94
|
+
parseInt(String(y / 100), 10) +
|
|
95
|
+
parseInt(String(y / 400), 10) +
|
|
96
|
+
parseInt(String((m * 306 + 5) / 10), 10) +
|
|
96
97
|
(d - 1)
|
|
97
98
|
);
|
|
98
99
|
};
|
|
99
100
|
|
|
100
101
|
this.SolarFromInt = function (g: number) {
|
|
101
|
-
let y = parseInt(String((10000 * g + 14780) / 3652425));
|
|
102
|
+
let y = parseInt(String((10000 * g + 14780) / 3652425), 10);
|
|
102
103
|
let ddd =
|
|
103
104
|
g -
|
|
104
105
|
(365 * y +
|
|
105
|
-
parseInt(String(y / 4)) -
|
|
106
|
-
parseInt(String(y / 100)) +
|
|
107
|
-
parseInt(String(y / 400)));
|
|
106
|
+
parseInt(String(y / 4), 10) -
|
|
107
|
+
parseInt(String(y / 100), 10) +
|
|
108
|
+
parseInt(String(y / 400), 10));
|
|
108
109
|
if (ddd < 0) {
|
|
109
110
|
y--;
|
|
110
111
|
ddd =
|
|
111
112
|
g -
|
|
112
113
|
(365 * y +
|
|
113
|
-
parseInt(String(y / 4)) -
|
|
114
|
-
parseInt(String(y / 100)) +
|
|
115
|
-
parseInt(String(y / 400)));
|
|
114
|
+
parseInt(String(y / 4), 10) -
|
|
115
|
+
parseInt(String(y / 100), 10) +
|
|
116
|
+
parseInt(String(y / 400), 10));
|
|
116
117
|
}
|
|
117
|
-
const mi = parseInt(String((100 * ddd + 52) / 3060));
|
|
118
|
+
const mi = parseInt(String((100 * ddd + 52) / 3060), 10);
|
|
118
119
|
const mm = ((mi + 2) % 12) + 1;
|
|
119
|
-
y += parseInt(String((mi + 2) / 12));
|
|
120
|
-
const dd = ddd - parseInt(String((mi * 306 + 5) / 10)) + 1;
|
|
120
|
+
y += parseInt(String((mi + 2) / 12), 10);
|
|
121
|
+
const dd = ddd - parseInt(String((mi * 306 + 5) / 10), 10) + 1;
|
|
121
122
|
// @ts-ignore
|
|
122
123
|
const solar = new Solar();
|
|
123
|
-
solar.solarYear = parseInt(String(y));
|
|
124
|
-
solar.solarMonth = parseInt(String(mm));
|
|
125
|
-
solar.solarDay = parseInt(String(dd));
|
|
124
|
+
solar.solarYear = parseInt(String(y), 10);
|
|
125
|
+
solar.solarMonth = parseInt(String(mm), 10);
|
|
126
|
+
solar.solarDay = parseInt(String(dd), 10);
|
|
126
127
|
return solar;
|
|
127
128
|
};
|
|
128
129
|
|
|
@@ -181,6 +182,7 @@ function LunarSolarConverter(this: any) {
|
|
|
181
182
|
const lunar = new Lunar();
|
|
182
183
|
let index = solar.solarYear - this.solar_1_1[0];
|
|
183
184
|
const data =
|
|
185
|
+
// eslint-disable-next-line no-bitwise -- packs date to compare with solar_1_1 table
|
|
184
186
|
(solar.solarYear << 9) | (solar.solarMonth << 5) | solar.solarDay;
|
|
185
187
|
if (this.solar_1_1[index] > data) {
|
|
186
188
|
index--;
|
|
@@ -209,7 +211,7 @@ function LunarSolarConverter(this: any) {
|
|
|
209
211
|
break;
|
|
210
212
|
}
|
|
211
213
|
}
|
|
212
|
-
const lunarD = parseInt(String(offset));
|
|
214
|
+
const lunarD = parseInt(String(offset), 10);
|
|
213
215
|
lunar.lunarYear = lunarY;
|
|
214
216
|
lunar.lunarMonth = lunarM;
|
|
215
217
|
lunar.isleap = false;
|
package/Month.tsx
CHANGED
|
@@ -2,9 +2,10 @@ import React, {useContext, useMemo} from 'react';
|
|
|
2
2
|
import {View} from 'react-native';
|
|
3
3
|
import moment, {Moment} from 'moment';
|
|
4
4
|
import Day from './Day';
|
|
5
|
-
import {useScaleSize
|
|
5
|
+
import {useScaleSize} from '@momo-kits/foundation';
|
|
6
6
|
import {MonthProps} from './types';
|
|
7
|
-
import {ContainerContext} from './
|
|
7
|
+
import {ContainerContext} from './ContainerContext';
|
|
8
|
+
import styles from './styles';
|
|
8
9
|
|
|
9
10
|
const Month: React.FC<MonthProps> = ({
|
|
10
11
|
dateList,
|
|
@@ -60,21 +61,11 @@ const Month: React.FC<MonthProps> = ({
|
|
|
60
61
|
|
|
61
62
|
return (
|
|
62
63
|
<View style={{width: size.width}}>
|
|
63
|
-
<View
|
|
64
|
-
style={{
|
|
65
|
-
paddingHorizontal: Spacing.S,
|
|
66
|
-
width: '100%',
|
|
67
|
-
alignItems: 'center',
|
|
68
|
-
}}>
|
|
64
|
+
<View style={styles.monthRows}>
|
|
69
65
|
{rows.map((dayList, rowIndex) => (
|
|
70
66
|
<View
|
|
71
67
|
key={`row${rowIndex}`}
|
|
72
|
-
style={{
|
|
73
|
-
flexDirection: 'row',
|
|
74
|
-
alignItems: 'center',
|
|
75
|
-
marginBottom: Spacing.XS,
|
|
76
|
-
height: scaledHeight,
|
|
77
|
-
}}>
|
|
68
|
+
style={[styles.monthRow, {height: scaledHeight}]}>
|
|
78
69
|
{dayList.map((item, i) => {
|
|
79
70
|
const {isEmpty, date: dateMoment, lunarDate} = item;
|
|
80
71
|
// compute key for price/disabled only if not empty
|
package/MonthList.tsx
CHANGED
|
@@ -5,7 +5,6 @@ import React, {
|
|
|
5
5
|
useImperativeHandle,
|
|
6
6
|
useCallback,
|
|
7
7
|
useContext,
|
|
8
|
-
useEffect,
|
|
9
8
|
useLayoutEffect,
|
|
10
9
|
useMemo,
|
|
11
10
|
useRef,
|
|
@@ -17,7 +16,7 @@ import {
|
|
|
17
16
|
NativeSyntheticEvent,
|
|
18
17
|
Platform,
|
|
19
18
|
} from 'react-native';
|
|
20
|
-
import { ContainerContext } from './
|
|
19
|
+
import { ContainerContext } from './ContainerContext';
|
|
21
20
|
import LunarDateConverter from './LunarDateConverter';
|
|
22
21
|
import Month from './Month';
|
|
23
22
|
import { MonthListProps, MonthListRef } from './types';
|
|
@@ -39,15 +38,22 @@ const MonthList = forwardRef<MonthListRef, MonthListProps>((props, ref) => {
|
|
|
39
38
|
isShowLunar,
|
|
40
39
|
isDoubleDateMode,
|
|
41
40
|
disabledDays,
|
|
41
|
+
tabSelected,
|
|
42
|
+
onChoose,
|
|
43
|
+
bestPriceColor,
|
|
42
44
|
onScrollCalendar,
|
|
43
|
-
...restProps
|
|
44
45
|
} = props;
|
|
45
46
|
|
|
46
47
|
const size = useContext(ContainerContext);
|
|
47
48
|
const scaledHeight48 = useScaleSize(48);
|
|
48
49
|
const listRef = useRef<FlatList>(null);
|
|
49
50
|
const currentKey = useRef<string | null>(null);
|
|
51
|
+
const targetIndex = useRef<number | null>(null);
|
|
50
52
|
const [heightStyle, setHeightStyle] = useState({});
|
|
53
|
+
const onScrollCalendarRef = useRef(onScrollCalendar);
|
|
54
|
+
onScrollCalendarRef.current = onScrollCalendar;
|
|
55
|
+
const scaledHeight48Ref = useRef(scaledHeight48);
|
|
56
|
+
scaledHeight48Ref.current = scaledHeight48;
|
|
51
57
|
|
|
52
58
|
const data = useMemo(() => {
|
|
53
59
|
const months: { date: Moment; dateList: any[] }[] = [];
|
|
@@ -69,9 +75,6 @@ const MonthList = forwardRef<MonthListRef, MonthListProps>((props, ref) => {
|
|
|
69
75
|
}
|
|
70
76
|
while (cursor.month() === monthIdx) {
|
|
71
77
|
const cloned = cursor.clone();
|
|
72
|
-
const hol = holidays.find(
|
|
73
|
-
h => h.day === cloned.date() && h.month === cloned.month() + 1,
|
|
74
|
-
);
|
|
75
78
|
dayList.push({
|
|
76
79
|
isEmpty: false,
|
|
77
80
|
date: cloned,
|
|
@@ -80,8 +83,6 @@ const MonthList = forwardRef<MonthListRef, MonthListProps>((props, ref) => {
|
|
|
80
83
|
solarMonth: cloned.month() + 1,
|
|
81
84
|
solarYear: cloned.year(),
|
|
82
85
|
}),
|
|
83
|
-
isSolarHoliday: !!(hol && !hol.lunar),
|
|
84
|
-
isLunarHoliday: !!(hol && hol.lunar),
|
|
85
86
|
});
|
|
86
87
|
cursor.add(1, 'days');
|
|
87
88
|
}
|
|
@@ -96,7 +97,7 @@ const MonthList = forwardRef<MonthListRef, MonthListProps>((props, ref) => {
|
|
|
96
97
|
mMin.add(1, 'month');
|
|
97
98
|
}
|
|
98
99
|
return months;
|
|
99
|
-
}, [minDate, maxDate
|
|
100
|
+
}, [minDate, maxDate]);
|
|
100
101
|
|
|
101
102
|
const getIndexOfMonth = useCallback(
|
|
102
103
|
(date: Moment) => data.findIndex(item => item.date.isSame(date, 'month')),
|
|
@@ -138,6 +139,9 @@ const MonthList = forwardRef<MonthListRef, MonthListProps>((props, ref) => {
|
|
|
138
139
|
(month: Moment) => {
|
|
139
140
|
const idx = getIndexOfMonth(month);
|
|
140
141
|
if (listRef.current && idx !== -1) {
|
|
142
|
+
const offset = idx * pageWidth.current;
|
|
143
|
+
targetIndex.current =
|
|
144
|
+
Math.abs(offset - scrollOffset.current) < 1 ? null : idx;
|
|
141
145
|
listRef.current.scrollToIndex({ index: idx, animated: true });
|
|
142
146
|
}
|
|
143
147
|
},
|
|
@@ -146,29 +150,31 @@ const MonthList = forwardRef<MonthListRef, MonthListProps>((props, ref) => {
|
|
|
146
150
|
|
|
147
151
|
useImperativeHandle(ref, () => ({ scrollToMonth }));
|
|
148
152
|
|
|
149
|
-
useEffect(() => {
|
|
150
|
-
const timer = setTimeout(() => {
|
|
151
|
-
scrollToMonth(selectedDate);
|
|
152
|
-
}, 500);
|
|
153
|
-
return () => clearTimeout(timer);
|
|
154
|
-
}, []);
|
|
155
|
-
|
|
156
153
|
const onViewableItemsChanged = useRef(({ changed }: { changed: any[] }) => {
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
154
|
+
const visible = changed.find(token => token.isViewable);
|
|
155
|
+
if (targetIndex.current !== null && visible?.index !== targetIndex.current) {
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
targetIndex.current = null;
|
|
159
|
+
if (visible) {
|
|
160
|
+
const { item, key, index } = visible;
|
|
161
|
+
if (onScrollCalendarRef.current && item && currentKey.current !== key) {
|
|
160
162
|
currentKey.current = key;
|
|
161
163
|
try {
|
|
162
164
|
setHeightStyle({
|
|
163
165
|
height:
|
|
164
|
-
(
|
|
166
|
+
(scaledHeight48Ref.current * item.dateList.length) / 7 +
|
|
165
167
|
Spacing.L * 2 +
|
|
166
168
|
Spacing.XS,
|
|
167
169
|
});
|
|
168
170
|
} catch {
|
|
169
171
|
setHeightStyle({});
|
|
170
172
|
}
|
|
171
|
-
|
|
173
|
+
onScrollCalendarRef.current({
|
|
174
|
+
date: item.date,
|
|
175
|
+
key,
|
|
176
|
+
currentIndex: index,
|
|
177
|
+
});
|
|
172
178
|
}
|
|
173
179
|
}
|
|
174
180
|
}).current;
|
|
@@ -201,7 +207,6 @@ const MonthList = forwardRef<MonthListRef, MonthListProps>((props, ref) => {
|
|
|
201
207
|
const priceListDate = priceList?.[keyMonth]?.day;
|
|
202
208
|
return (
|
|
203
209
|
<Month
|
|
204
|
-
{...restProps}
|
|
205
210
|
key={index}
|
|
206
211
|
month={item.date}
|
|
207
212
|
dateList={item.dateList}
|
|
@@ -214,11 +219,13 @@ const MonthList = forwardRef<MonthListRef, MonthListProps>((props, ref) => {
|
|
|
214
219
|
isShowLunar={isShowLunar}
|
|
215
220
|
isDoubleDateMode={isDoubleDateMode}
|
|
216
221
|
disabledDays={disabledDays}
|
|
222
|
+
tabSelected={tabSelected}
|
|
223
|
+
onChoose={onChoose}
|
|
224
|
+
bestPriceColor={bestPriceColor}
|
|
217
225
|
/>
|
|
218
226
|
);
|
|
219
227
|
},
|
|
220
228
|
[
|
|
221
|
-
restProps,
|
|
222
229
|
priceList,
|
|
223
230
|
holidays,
|
|
224
231
|
minDate,
|
|
@@ -228,6 +235,9 @@ const MonthList = forwardRef<MonthListRef, MonthListProps>((props, ref) => {
|
|
|
228
235
|
isShowLunar,
|
|
229
236
|
isDoubleDateMode,
|
|
230
237
|
disabledDays,
|
|
238
|
+
tabSelected,
|
|
239
|
+
onChoose,
|
|
240
|
+
bestPriceColor,
|
|
231
241
|
],
|
|
232
242
|
);
|
|
233
243
|
|
|
@@ -244,6 +254,9 @@ const MonthList = forwardRef<MonthListRef, MonthListProps>((props, ref) => {
|
|
|
244
254
|
keyExtractor={keyExtractor}
|
|
245
255
|
onScrollToIndexFailed={() => {}}
|
|
246
256
|
onScroll={onScroll}
|
|
257
|
+
onScrollBeginDrag={() => {
|
|
258
|
+
targetIndex.current = null;
|
|
259
|
+
}}
|
|
247
260
|
scrollEnabled
|
|
248
261
|
initialNumToRender={3}
|
|
249
262
|
maxToRenderPerBatch={MAX_RENDER_PER_BATCH}
|