@momo-kits/calendar 0.79.6 → 0.80.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/CalendarPro.tsx +386 -0
- package/Day.tsx +242 -0
- package/HeaderControl.tsx +53 -0
- package/Month.tsx +114 -0
- package/{src/MonthList.tsx → MonthList.tsx} +96 -65
- package/{src/TabHeader.tsx → TabHeader.tsx} +30 -12
- package/index.tsx +481 -2
- package/package.json +1 -1
- package/styles.ts +115 -0
- package/types.ts +155 -27
- package/src/Calendar.tsx +0 -488
- package/src/CalendarPro.tsx +0 -436
- package/src/Day/index.tsx +0 -248
- package/src/Day/style.ts +0 -113
- package/src/HeaderControl.tsx +0 -69
- package/src/Month/index.tsx +0 -88
- package/src/Month/style.ts +0 -0
- /package/{src/LunarDateConverter.ts → LunarDateConverter.ts} +0 -0
- /package/{src/LunarService.ts → LunarService.ts} +0 -0
- /package/{src/Util.ts → Util.ts} +0 -0
- /package/{src/holidayData.ts → holidayData.ts} +0 -0
package/Month.tsx
ADDED
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import React, {PureComponent} from 'react';
|
|
2
|
+
|
|
3
|
+
import {View} from 'react-native';
|
|
4
|
+
import moment from 'moment';
|
|
5
|
+
import Moment from 'moment';
|
|
6
|
+
import Day from './Day';
|
|
7
|
+
import {scaleSize, Spacing} from '@momo-kits/foundation';
|
|
8
|
+
import {MonthProps} from './types';
|
|
9
|
+
import {ContainerContext} from './index';
|
|
10
|
+
|
|
11
|
+
export default class Month extends PureComponent<MonthProps> {
|
|
12
|
+
rowArray;
|
|
13
|
+
temp;
|
|
14
|
+
constructor(props: MonthProps) {
|
|
15
|
+
super(props);
|
|
16
|
+
const {dateList} = props;
|
|
17
|
+
this.rowArray = new Array(dateList.length / 7).fill('');
|
|
18
|
+
this.temp = this.rowArray.map((item, i) =>
|
|
19
|
+
dateList.slice(i * 7, i * 7 + 7),
|
|
20
|
+
);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
findHoliday = (date: Moment.Moment) => {
|
|
24
|
+
const {holidays} = this.props;
|
|
25
|
+
if (date && holidays && holidays.length > 0) {
|
|
26
|
+
const day = date.date();
|
|
27
|
+
const month = date.month() + 1;
|
|
28
|
+
return holidays.find(item => item.day === day && item.month === month);
|
|
29
|
+
}
|
|
30
|
+
return null;
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
checkHoliday = (date: moment.Moment) => {
|
|
34
|
+
const holiday = this.findHoliday(date);
|
|
35
|
+
return {
|
|
36
|
+
isSolarHoliday: !!(holiday && !holiday.lunar),
|
|
37
|
+
isLunarHoliday: !!(holiday && holiday.lunar),
|
|
38
|
+
};
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
renderDayRow = (dayList: any[], index: number) => (
|
|
42
|
+
<View
|
|
43
|
+
style={{
|
|
44
|
+
flexDirection: 'row',
|
|
45
|
+
alignItems: 'center',
|
|
46
|
+
marginBottom: Spacing.XS,
|
|
47
|
+
height: scaleSize(48),
|
|
48
|
+
}}
|
|
49
|
+
key={`row${index}`}>
|
|
50
|
+
{dayList.map((item, i) => {
|
|
51
|
+
const keyDay = moment(item.date).format('YYYY-MM-DD');
|
|
52
|
+
const priceInfo = this.props?.priceListDate?.[keyDay];
|
|
53
|
+
const {
|
|
54
|
+
minDate,
|
|
55
|
+
maxDate,
|
|
56
|
+
startDate,
|
|
57
|
+
endDate,
|
|
58
|
+
isShowLunar,
|
|
59
|
+
isDoubleDateMode,
|
|
60
|
+
disabledDays,
|
|
61
|
+
} = this.props;
|
|
62
|
+
|
|
63
|
+
const dateItem = new Date(item.date);
|
|
64
|
+
const mappedDisabledArray = disabledDays?.map(item => String(item));
|
|
65
|
+
const isDisabled = mappedDisabledArray?.includes(String(dateItem));
|
|
66
|
+
|
|
67
|
+
return (
|
|
68
|
+
<Day
|
|
69
|
+
{...this.props}
|
|
70
|
+
minDate={minDate}
|
|
71
|
+
maxDate={maxDate}
|
|
72
|
+
isShowLunar={isShowLunar}
|
|
73
|
+
isDoubleDateMode={isDoubleDateMode}
|
|
74
|
+
startDate={startDate}
|
|
75
|
+
endDate={endDate}
|
|
76
|
+
{...this.checkHoliday(item.date)}
|
|
77
|
+
date={item.date}
|
|
78
|
+
havePriceList={!!this.props.priceListDate}
|
|
79
|
+
lunarDate={item.lunarDate}
|
|
80
|
+
empty={item.empty}
|
|
81
|
+
key={`day${i.toString()}`}
|
|
82
|
+
index={i}
|
|
83
|
+
price={priceInfo?.priceAsString}
|
|
84
|
+
isBestPrice={priceInfo?.isBestPrice}
|
|
85
|
+
isDisabled={isDisabled}
|
|
86
|
+
/>
|
|
87
|
+
);
|
|
88
|
+
})}
|
|
89
|
+
</View>
|
|
90
|
+
);
|
|
91
|
+
|
|
92
|
+
render() {
|
|
93
|
+
const {month} = this.props;
|
|
94
|
+
if (month) {
|
|
95
|
+
return (
|
|
96
|
+
<ContainerContext.Consumer>
|
|
97
|
+
{size => (
|
|
98
|
+
<View style={{width: size.width}}>
|
|
99
|
+
<View
|
|
100
|
+
style={{
|
|
101
|
+
paddingHorizontal: Spacing.S,
|
|
102
|
+
width: '100%',
|
|
103
|
+
alignItems: 'center',
|
|
104
|
+
}}>
|
|
105
|
+
{this.temp.map((item, i) => this.renderDayRow(item, i))}
|
|
106
|
+
</View>
|
|
107
|
+
</View>
|
|
108
|
+
)}
|
|
109
|
+
</ContainerContext.Consumer>
|
|
110
|
+
);
|
|
111
|
+
}
|
|
112
|
+
return <View />;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
@@ -1,55 +1,70 @@
|
|
|
1
|
-
|
|
2
|
-
import
|
|
3
|
-
import {Dimensions, FlatList, Platform} from 'react-native';
|
|
1
|
+
import React, {Component, useCallback} from 'react';
|
|
2
|
+
import {FlatList, Platform} from 'react-native';
|
|
4
3
|
import moment from 'moment';
|
|
4
|
+
import Moment from 'moment';
|
|
5
5
|
import Month from './Month';
|
|
6
|
-
import style from './Day/style';
|
|
7
6
|
import LunarDateConverter from './LunarDateConverter';
|
|
8
|
-
import {
|
|
7
|
+
import {MonthListProps, MonthListState} from './types';
|
|
8
|
+
import {ContainerContext} from './index';
|
|
9
|
+
import {scaleSize, Spacing} from '@momo-kits/foundation';
|
|
9
10
|
|
|
10
|
-
const ITEM_WIDTH = Dimensions.get('window').width - scaleSize(24);
|
|
11
11
|
const MAX_RENDER_PER_BATCH = Platform.OS === 'android' ? 1 : 12;
|
|
12
12
|
|
|
13
13
|
const converter = new LunarDateConverter();
|
|
14
|
-
export default class MonthList extends Component
|
|
15
|
-
|
|
14
|
+
export default class MonthList extends Component<
|
|
15
|
+
MonthListProps,
|
|
16
|
+
MonthListState
|
|
17
|
+
> {
|
|
18
|
+
currentDate;
|
|
19
|
+
data;
|
|
20
|
+
currentScrollIndex;
|
|
21
|
+
list;
|
|
22
|
+
heightStyle;
|
|
23
|
+
holidays;
|
|
24
|
+
currentKey: any;
|
|
25
|
+
|
|
26
|
+
constructor(props: MonthListProps) {
|
|
16
27
|
super(props);
|
|
17
|
-
// this.state = {
|
|
18
|
-
// // data: [],
|
|
19
|
-
// isDoubleDateMode: props.isDoubleDateMode
|
|
20
|
-
// };
|
|
21
28
|
this.currentDate = moment();
|
|
22
29
|
this.data = this.getMonthList();
|
|
23
30
|
this.currentScrollIndex = this.getIndexOfMonth(
|
|
24
31
|
moment(props.selectedDate),
|
|
25
32
|
this.data,
|
|
26
33
|
);
|
|
27
|
-
this.list = React.createRef();
|
|
34
|
+
this.list = React.createRef<FlatList>();
|
|
28
35
|
this.heightStyle = {};
|
|
29
36
|
this.holidays = props.holidays;
|
|
30
37
|
}
|
|
31
38
|
|
|
32
|
-
renderMonth = (
|
|
33
|
-
|
|
34
|
-
|
|
39
|
+
renderMonth = (data: {
|
|
40
|
+
item: {dateList: any; date: moment.Moment};
|
|
41
|
+
index: number;
|
|
42
|
+
}) => {
|
|
43
|
+
const {isDoubleDateMode, disabledDays, priceList, isShowLunar} = this.props;
|
|
44
|
+
const {item, index} = data;
|
|
45
|
+
|
|
35
46
|
const keyMonth = moment(item.date)?.format('YYYY-MM');
|
|
36
|
-
const priceListDate = priceList?.[keyMonth]
|
|
47
|
+
const priceListDate = priceList?.[keyMonth];
|
|
37
48
|
|
|
38
49
|
return (
|
|
39
50
|
<Month
|
|
40
|
-
containerWidth={containerWidth}
|
|
41
|
-
disabledWeekend={disabledWeekend}
|
|
42
51
|
{...this.props}
|
|
43
52
|
key={index}
|
|
44
53
|
month={item.date || {}}
|
|
45
54
|
dateList={item.dateList || []}
|
|
46
55
|
priceListDate={priceListDate}
|
|
56
|
+
isShowLunar={isShowLunar}
|
|
47
57
|
isDoubleDateMode={isDoubleDateMode}
|
|
58
|
+
disabledDays={disabledDays}
|
|
48
59
|
/>
|
|
49
60
|
);
|
|
50
61
|
};
|
|
51
62
|
|
|
52
|
-
checkRange = (
|
|
63
|
+
checkRange = (
|
|
64
|
+
date: moment.Moment,
|
|
65
|
+
start: moment.Moment,
|
|
66
|
+
end: moment.Moment,
|
|
67
|
+
) => {
|
|
53
68
|
if (!date || !start) return false;
|
|
54
69
|
if (!end) {
|
|
55
70
|
return date.year() === start.year() && date.month() === start.month();
|
|
@@ -66,17 +81,20 @@ export default class MonthList extends Component {
|
|
|
66
81
|
);
|
|
67
82
|
};
|
|
68
83
|
|
|
69
|
-
shouldUpdate = (
|
|
84
|
+
shouldUpdate = (
|
|
85
|
+
month: {date: any; dateList?: any[]},
|
|
86
|
+
props?: MonthListProps,
|
|
87
|
+
) => {
|
|
70
88
|
if (!props) return false;
|
|
71
89
|
const {startDate, endDate} = props;
|
|
72
90
|
const {startDate: curStartDate, endDate: curEndDate} = this.props;
|
|
73
91
|
const {date} = month;
|
|
74
92
|
const next = this.checkRange(date, startDate, endDate);
|
|
75
93
|
const prev = this.checkRange(date, curStartDate, curEndDate);
|
|
76
|
-
return
|
|
94
|
+
return prev || next;
|
|
77
95
|
};
|
|
78
96
|
|
|
79
|
-
convertLunarToSolar(date) {
|
|
97
|
+
convertLunarToSolar(date: moment.Moment) {
|
|
80
98
|
return date
|
|
81
99
|
? converter.SolarToLunar({
|
|
82
100
|
solarDay: date.date(),
|
|
@@ -86,7 +104,7 @@ export default class MonthList extends Component {
|
|
|
86
104
|
: {};
|
|
87
105
|
}
|
|
88
106
|
|
|
89
|
-
findHoliday = date => {
|
|
107
|
+
findHoliday = (date: Moment.Moment) => {
|
|
90
108
|
const {holidays} = this.props;
|
|
91
109
|
if (date && holidays && holidays.length > 0) {
|
|
92
110
|
const day = date.date();
|
|
@@ -96,15 +114,15 @@ export default class MonthList extends Component {
|
|
|
96
114
|
return null;
|
|
97
115
|
};
|
|
98
116
|
|
|
99
|
-
checkHoliday = (date
|
|
100
|
-
const holiday = this.findHoliday(date
|
|
117
|
+
checkHoliday = (date: moment.Moment) => {
|
|
118
|
+
const holiday = this.findHoliday(date);
|
|
101
119
|
return {
|
|
102
120
|
isSolarHoliday: !!(holiday && !holiday.lunar),
|
|
103
121
|
isLunarHoliday: !!(holiday && holiday.lunar),
|
|
104
122
|
};
|
|
105
123
|
};
|
|
106
124
|
|
|
107
|
-
getDayList = date => {
|
|
125
|
+
getDayList = (date: moment.Moment) => {
|
|
108
126
|
let dayList;
|
|
109
127
|
const month = date.month();
|
|
110
128
|
let weekday = date.isoWeekday();
|
|
@@ -144,10 +162,10 @@ export default class MonthList extends Component {
|
|
|
144
162
|
);
|
|
145
163
|
};
|
|
146
164
|
|
|
147
|
-
getMonthList = props => {
|
|
165
|
+
getMonthList = (props?: MonthListProps) => {
|
|
148
166
|
const minDate = moment((props || this.props).minDate).date(1);
|
|
149
167
|
const maxDate = moment((props || this.props).maxDate);
|
|
150
|
-
const monthList = [];
|
|
168
|
+
const monthList: {date: moment.Moment; dateList: any[]}[] = [];
|
|
151
169
|
if (!maxDate || !minDate) return monthList;
|
|
152
170
|
while (
|
|
153
171
|
maxDate > minDate ||
|
|
@@ -157,18 +175,21 @@ export default class MonthList extends Component {
|
|
|
157
175
|
const month = {
|
|
158
176
|
date: d,
|
|
159
177
|
dateList: this.getDayList(d),
|
|
178
|
+
shouldUpdate: false,
|
|
160
179
|
};
|
|
161
180
|
month.shouldUpdate = this.shouldUpdate(month, props);
|
|
162
181
|
monthList.push(month);
|
|
163
182
|
minDate.add(1, 'month');
|
|
164
183
|
}
|
|
184
|
+
|
|
165
185
|
return monthList;
|
|
166
186
|
};
|
|
167
187
|
|
|
168
|
-
getIndexOfMonth = (month, data) =>
|
|
169
|
-
data.findIndex(item => item.date.isSame(month, 'month'));
|
|
188
|
+
getIndexOfMonth = (month: moment.Moment, data: any[]) => {
|
|
189
|
+
return data.findIndex(item => item.date.isSame(month, 'month'));
|
|
190
|
+
};
|
|
170
191
|
|
|
171
|
-
getCurrentVisibleMonth = info => {
|
|
192
|
+
getCurrentVisibleMonth = (info: {changed: any}) => {
|
|
172
193
|
const {changed} = info;
|
|
173
194
|
const {onScrollCalendar} = this.props;
|
|
174
195
|
if (changed && changed.length > 0) {
|
|
@@ -180,10 +201,9 @@ export default class MonthList extends Component {
|
|
|
180
201
|
this.data && this.data[index] && this.data[index].dateList
|
|
181
202
|
? {
|
|
182
203
|
height:
|
|
183
|
-
(
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
10,
|
|
204
|
+
(scaleSize(48) * this.data[index].dateList.length) / 7 +
|
|
205
|
+
Spacing.L * 2 +
|
|
206
|
+
Spacing.XS,
|
|
187
207
|
}
|
|
188
208
|
: {};
|
|
189
209
|
} catch (e) {
|
|
@@ -200,9 +220,10 @@ export default class MonthList extends Component {
|
|
|
200
220
|
}
|
|
201
221
|
};
|
|
202
222
|
|
|
203
|
-
keyExtractor = item
|
|
223
|
+
keyExtractor = (item: {date: Moment.Moment}) =>
|
|
224
|
+
`${item.date.month() + 1}/${item.date.year()}`;
|
|
204
225
|
|
|
205
|
-
scrollToMonth = month => {
|
|
226
|
+
scrollToMonth = (month: moment.Moment) => {
|
|
206
227
|
const index = this.getIndexOfMonth(month, this.data);
|
|
207
228
|
if (this.list.current && index !== -1) {
|
|
208
229
|
this.list.current.scrollToIndex({
|
|
@@ -212,39 +233,49 @@ export default class MonthList extends Component {
|
|
|
212
233
|
}
|
|
213
234
|
};
|
|
214
235
|
|
|
215
|
-
getItemLayout = (data, index) => ({
|
|
216
|
-
length:
|
|
217
|
-
offset:
|
|
236
|
+
getItemLayout = (data: any, index: number, width: number) => ({
|
|
237
|
+
length: width,
|
|
238
|
+
offset: width * index,
|
|
218
239
|
index,
|
|
219
240
|
});
|
|
220
241
|
|
|
242
|
+
componentDidMount() {
|
|
243
|
+
setTimeout(() => {
|
|
244
|
+
this.scrollToMonth(this.currentDate);
|
|
245
|
+
}, 500);
|
|
246
|
+
}
|
|
247
|
+
|
|
221
248
|
render() {
|
|
222
249
|
const {priceList} = this.props;
|
|
223
250
|
return (
|
|
224
|
-
<
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
251
|
+
<ContainerContext.Consumer>
|
|
252
|
+
{size => (
|
|
253
|
+
<FlatList
|
|
254
|
+
extraData={priceList}
|
|
255
|
+
style={this.heightStyle}
|
|
256
|
+
pagingEnabled
|
|
257
|
+
horizontal
|
|
258
|
+
ref={this.list}
|
|
259
|
+
data={this.data}
|
|
260
|
+
renderItem={this.renderMonth}
|
|
261
|
+
showsHorizontalScrollIndicator={false}
|
|
262
|
+
keyExtractor={this.keyExtractor}
|
|
263
|
+
onViewableItemsChanged={this.getCurrentVisibleMonth}
|
|
264
|
+
onScrollToIndexFailed={() => {}}
|
|
265
|
+
scrollEnabled
|
|
266
|
+
initialNumToRender={3}
|
|
267
|
+
maxToRenderPerBatch={MAX_RENDER_PER_BATCH}
|
|
268
|
+
windowSize={1}
|
|
269
|
+
initialScrollIndex={this.currentScrollIndex}
|
|
270
|
+
getItemLayout={(data, index) =>
|
|
271
|
+
this.getItemLayout(data, index, size.width)
|
|
272
|
+
}
|
|
273
|
+
viewabilityConfig={{
|
|
274
|
+
itemVisiblePercentThreshold: 50,
|
|
275
|
+
}}
|
|
276
|
+
/>
|
|
277
|
+
)}
|
|
278
|
+
</ContainerContext.Consumer>
|
|
248
279
|
);
|
|
249
280
|
}
|
|
250
281
|
}
|
|
@@ -2,11 +2,24 @@ import React from 'react';
|
|
|
2
2
|
import {TouchableWithoutFeedback, View} from 'react-native';
|
|
3
3
|
import Moment from 'moment';
|
|
4
4
|
import Util from './Util';
|
|
5
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
ApplicationContext,
|
|
7
|
+
Colors,
|
|
8
|
+
Radius,
|
|
9
|
+
Spacing,
|
|
10
|
+
Text,
|
|
11
|
+
} from '@momo-kits/foundation';
|
|
12
|
+
import {TabHeaderProps, TabHeaderState} from './types';
|
|
13
|
+
|
|
14
|
+
export default class TabHeader extends React.Component<
|
|
15
|
+
TabHeaderProps,
|
|
16
|
+
TabHeaderState
|
|
17
|
+
> {
|
|
18
|
+
label;
|
|
19
|
+
defaultDate;
|
|
6
20
|
|
|
7
|
-
export default class TabHeader extends React.Component {
|
|
8
21
|
static contextType = ApplicationContext;
|
|
9
|
-
constructor(props) {
|
|
22
|
+
constructor(props: TabHeaderProps) {
|
|
10
23
|
super(props);
|
|
11
24
|
this.state = {
|
|
12
25
|
active: props.activeTab,
|
|
@@ -17,19 +30,17 @@ export default class TabHeader extends React.Component {
|
|
|
17
30
|
|
|
18
31
|
onChangeTab = () => {
|
|
19
32
|
const {onChangeTab, id} = this.props;
|
|
20
|
-
|
|
21
|
-
onChangeTab(id);
|
|
22
|
-
}
|
|
33
|
+
onChangeTab?.(id);
|
|
23
34
|
};
|
|
24
35
|
|
|
25
|
-
updateView = (date, activeTab) => {
|
|
36
|
+
updateView = (date: Moment.Moment, activeTab: boolean) => {
|
|
26
37
|
this.setState({
|
|
27
38
|
date: date ? Moment(date) : '',
|
|
28
39
|
active: activeTab,
|
|
29
40
|
});
|
|
30
41
|
};
|
|
31
42
|
|
|
32
|
-
setActiveTab = active => {
|
|
43
|
+
setActiveTab = (active: boolean) => {
|
|
33
44
|
this.setState({active});
|
|
34
45
|
};
|
|
35
46
|
|
|
@@ -52,10 +63,17 @@ export default class TabHeader extends React.Component {
|
|
|
52
63
|
return (
|
|
53
64
|
<TouchableWithoutFeedback disabled={disabled} onPress={this.onChangeTab}>
|
|
54
65
|
<View
|
|
55
|
-
style={
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
66
|
+
style={[
|
|
67
|
+
{
|
|
68
|
+
flex: 1,
|
|
69
|
+
padding: Spacing.S,
|
|
70
|
+
borderRadius: Radius.S,
|
|
71
|
+
},
|
|
72
|
+
active &&
|
|
73
|
+
!disabled && {
|
|
74
|
+
backgroundColor: theme.colors.background.surface,
|
|
75
|
+
},
|
|
76
|
+
]}>
|
|
59
77
|
<Text typography={'description_s'} color={Colors.black_12}>
|
|
60
78
|
{translate(label)}
|
|
61
79
|
</Text>
|