@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/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
- /* eslint-disable react/no-did-update-set-state */
2
- import React, {Component} from 'react';
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 {scaleSize} from '@momo-kits/foundation';
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
- constructor(props) {
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 = ({item, index}) => {
33
- const {isDoubleDateMode, priceList, disabledWeekend, containerWidth} =
34
- this.props;
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]?.day;
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 = (date, start, end) => {
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 = (month, props) => {
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 !!(prev || next);
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, holidays) => {
100
- const holiday = this.findHoliday(date, holidays);
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
- (style.containerDayHeight *
184
- this.data[index].dateList.length) /
185
- 7 +
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 => `${item.date.month() + 1}/${item.date.year()}`;
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: ITEM_WIDTH,
217
- offset: ITEM_WIDTH * index,
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
- <FlatList
225
- extraData={priceList}
226
- style={this.heightStyle}
227
- horizontal
228
- pagingEnabled
229
- ref={this.list}
230
- data={this.data}
231
- renderItem={this.renderMonth}
232
- showsHorizontalScrollIndicator={false}
233
- keyExtractor={this.keyExtractor}
234
- onViewableItemsChanged={this.getCurrentVisibleMonth}
235
- onScrollToIndexFailed={() => {}}
236
- // removeClippedSubviews
237
- scrollEnabled
238
- initialNumToRender={1}
239
- maxToRenderPerBatch={MAX_RENDER_PER_BATCH}
240
- windowSize={3}
241
- contentContainerStyle={{paddingTop: 5}}
242
- initialScrollIndex={this.currentScrollIndex}
243
- getItemLayout={this.getItemLayout}
244
- viewabilityConfig={{
245
- itemVisiblePercentThreshold: 50,
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 {ApplicationContext, Colors, Text} from '@momo-kits/foundation';
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
- if (onChangeTab) {
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
- flex: 1,
57
- backgroundColor: theme.colors.background.surface,
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>