@momo-kits/calendar 0.169.8 → 0.169.9
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 +41 -35
- package/HeaderControl.tsx +2 -4
- package/LunarDateConverter.ts +16 -9
- package/MonthList.tsx +20 -16
- package/TabHeader.tsx +6 -4
- package/Util.ts +6 -6
- package/index.tsx +19 -17
- package/package.json +1 -1
package/CalendarPro.tsx
CHANGED
|
@@ -28,9 +28,14 @@ import {
|
|
|
28
28
|
import { ContainerContext } from './ContainerContext';
|
|
29
29
|
import styles from './styles';
|
|
30
30
|
|
|
31
|
+
const DEFAULT_RANGE_MONTHS = 12;
|
|
32
|
+
const SCROLL_TO_SELECTED_DELAY = 500;
|
|
33
|
+
const WEEKDAYS = [1, 2, 3, 4, 5, 6, 7];
|
|
34
|
+
const FIRST_WEEKEND_DAY = 6;
|
|
35
|
+
|
|
31
36
|
/** Holidays to list: lunar-only ones are hidden while lunar dates are off. */
|
|
32
|
-
const getVisibleHolidays = (holidays: Holidays[],
|
|
33
|
-
if (
|
|
37
|
+
const getVisibleHolidays = (holidays: Holidays[], isLunarShown: boolean) => {
|
|
38
|
+
if (isLunarShown) {
|
|
34
39
|
return holidays;
|
|
35
40
|
}
|
|
36
41
|
return holidays.filter(item => !item.lunar || item.mixedLabel);
|
|
@@ -67,31 +72,31 @@ const CalendarPro = forwardRef<CalendarProRef, CalendarProProps>(
|
|
|
67
72
|
const headerControlRef = useRef<HeaderControlRef>(null);
|
|
68
73
|
const monthListRef = useRef<MonthListRef>(null);
|
|
69
74
|
|
|
70
|
-
// An invalid bound falls back to
|
|
75
|
+
// An invalid bound falls back to a year from the other one (or today).
|
|
71
76
|
const [minDate, maxDate] = useMemo(() => {
|
|
72
77
|
let max = moment(propMaxDate);
|
|
73
78
|
let min = moment(propMinDate);
|
|
74
79
|
const maxValid = max.isValid();
|
|
75
80
|
const minValid = min.isValid();
|
|
76
81
|
if (!maxValid && !minValid) {
|
|
77
|
-
max = moment().add(
|
|
82
|
+
max = moment().add(DEFAULT_RANGE_MONTHS, 'months');
|
|
78
83
|
min = moment();
|
|
79
84
|
} else if (!maxValid && minValid) {
|
|
80
|
-
max = min.clone().add(
|
|
85
|
+
max = min.clone().add(DEFAULT_RANGE_MONTHS, 'months');
|
|
81
86
|
} else if (maxValid && !minValid) {
|
|
82
|
-
min = max.clone().subtract(
|
|
87
|
+
min = max.clone().subtract(DEFAULT_RANGE_MONTHS, 'months');
|
|
83
88
|
}
|
|
84
89
|
return [min, max];
|
|
85
90
|
}, [propMinDate, propMaxDate]);
|
|
86
91
|
|
|
87
92
|
const [startDate, setStartDate] = useState<Moment>(propStartDate);
|
|
88
93
|
const [endDate, setEndDate] = useState<Moment | null>(propEndDate || null);
|
|
89
|
-
const [
|
|
94
|
+
const [isLunarShown, setIsLunarShown] = useState(!!propIsShowLunar);
|
|
90
95
|
const [tabSelected, setTabSelected] = useState<number>(0);
|
|
91
96
|
const [holidays, setHolidays] = useState<Holidays[]>([]);
|
|
92
97
|
const [temp, setTemp] = useState<any[]>([]);
|
|
93
98
|
const [headerKey, setHeaderKey] = useState<string>('');
|
|
94
|
-
const [
|
|
99
|
+
const [isOwnUpdate, setIsOwnUpdate] = useState(false);
|
|
95
100
|
|
|
96
101
|
useImperativeHandle(ref, () => ({
|
|
97
102
|
setDoubleDateAndTabIndex: (
|
|
@@ -107,21 +112,21 @@ const CalendarPro = forwardRef<CalendarProRef, CalendarProProps>(
|
|
|
107
112
|
|
|
108
113
|
// Follow the isShowLunar prop, except right after the user toggled it.
|
|
109
114
|
useEffect(() => {
|
|
110
|
-
if (
|
|
111
|
-
|
|
112
|
-
} else if (propIsShowLunar !==
|
|
113
|
-
|
|
115
|
+
if (isOwnUpdate) {
|
|
116
|
+
setIsOwnUpdate(false);
|
|
117
|
+
} else if (propIsShowLunar !== isLunarShown) {
|
|
118
|
+
setIsLunarShown(!!propIsShowLunar);
|
|
114
119
|
}
|
|
115
|
-
}, [
|
|
120
|
+
}, [isOwnUpdate, propIsShowLunar, isLunarShown]);
|
|
116
121
|
|
|
117
122
|
useEffect(() => {
|
|
118
123
|
const timer = setTimeout(() => {
|
|
119
124
|
monthListRef.current?.scrollToMonth(propSelectedDate);
|
|
120
|
-
},
|
|
125
|
+
}, SCROLL_TO_SELECTED_DELAY);
|
|
121
126
|
return () => clearTimeout(timer);
|
|
122
127
|
}, [propSelectedDate]);
|
|
123
128
|
|
|
124
|
-
const
|
|
129
|
+
const handleChooseDay = (day: Moment) => {
|
|
125
130
|
if (isDoubleDateMode) {
|
|
126
131
|
if (tabSelected === 1) {
|
|
127
132
|
if (startDate && day >= startDate) {
|
|
@@ -142,7 +147,7 @@ const CalendarPro = forwardRef<CalendarProRef, CalendarProProps>(
|
|
|
142
147
|
|
|
143
148
|
const executeProcessAfterScrollCalendar = (date: Moment, key: string) => {
|
|
144
149
|
const allHolidays = Util.getHolidaysInMonth(moment(date));
|
|
145
|
-
const filtered = getVisibleHolidays(allHolidays,
|
|
150
|
+
const filtered = getVisibleHolidays(allHolidays, isLunarShown);
|
|
146
151
|
headerControlRef.current?.onUpdateInfo({ date });
|
|
147
152
|
headerRef.current = date.clone().startOf('month');
|
|
148
153
|
setHolidays(allHolidays);
|
|
@@ -150,7 +155,7 @@ const CalendarPro = forwardRef<CalendarProRef, CalendarProProps>(
|
|
|
150
155
|
setHeaderKey(key);
|
|
151
156
|
};
|
|
152
157
|
|
|
153
|
-
const
|
|
158
|
+
const handleScrollCalendar = (info: {
|
|
154
159
|
date: Moment;
|
|
155
160
|
key: string;
|
|
156
161
|
currentIndex: number;
|
|
@@ -160,16 +165,16 @@ const CalendarPro = forwardRef<CalendarProRef, CalendarProProps>(
|
|
|
160
165
|
}
|
|
161
166
|
};
|
|
162
167
|
|
|
163
|
-
const
|
|
164
|
-
|
|
165
|
-
const next = !
|
|
168
|
+
const handleToggleLunar = () => {
|
|
169
|
+
setIsOwnUpdate(true);
|
|
170
|
+
const next = !isLunarShown;
|
|
166
171
|
const filtered = getVisibleHolidays(holidays, next);
|
|
167
172
|
onCallbackCalendar?.('lunar', next);
|
|
168
|
-
|
|
173
|
+
setIsLunarShown(next);
|
|
169
174
|
setTemp(filtered);
|
|
170
175
|
};
|
|
171
176
|
|
|
172
|
-
const
|
|
177
|
+
const handlePressBackArrow = () => {
|
|
173
178
|
const prev = headerRef.current
|
|
174
179
|
.clone()
|
|
175
180
|
.startOf('month')
|
|
@@ -181,7 +186,7 @@ const CalendarPro = forwardRef<CalendarProRef, CalendarProProps>(
|
|
|
181
186
|
}
|
|
182
187
|
};
|
|
183
188
|
|
|
184
|
-
const
|
|
189
|
+
const handlePressNextArrow = () => {
|
|
185
190
|
const next = headerRef.current.clone().startOf('month').add(1, 'months');
|
|
186
191
|
if (next.isSameOrBefore(maxDate, 'month')) {
|
|
187
192
|
headerRef.current = next;
|
|
@@ -205,15 +210,15 @@ const CalendarPro = forwardRef<CalendarProRef, CalendarProProps>(
|
|
|
205
210
|
<HeaderControl
|
|
206
211
|
ref={headerControlRef}
|
|
207
212
|
selectedDate={propSelectedDate}
|
|
208
|
-
onPressBackArrow={
|
|
209
|
-
onPressNextArrow={
|
|
213
|
+
onPressBackArrow={handlePressBackArrow}
|
|
214
|
+
onPressNextArrow={handlePressNextArrow}
|
|
210
215
|
/>
|
|
211
216
|
<View style={styles.blueSeperator} />
|
|
212
217
|
<View>
|
|
213
218
|
<View style={styles.viewDay}>
|
|
214
|
-
{
|
|
219
|
+
{WEEKDAYS.map(dayIdx => {
|
|
215
220
|
let dayColor = theme.colors.text.default;
|
|
216
|
-
if (dayIdx >=
|
|
221
|
+
if (dayIdx >= FIRST_WEEKEND_DAY) {
|
|
217
222
|
dayColor = theme.colors.error.primary;
|
|
218
223
|
}
|
|
219
224
|
return (
|
|
@@ -223,7 +228,7 @@ const CalendarPro = forwardRef<CalendarProRef, CalendarProProps>(
|
|
|
223
228
|
typography="label_s_medium"
|
|
224
229
|
style={[
|
|
225
230
|
styles.textDay,
|
|
226
|
-
{ width: (size.width - Spacing.S * 2) /
|
|
231
|
+
{ width: (size.width - Spacing.S * 2) / WEEKDAYS.length },
|
|
227
232
|
]}
|
|
228
233
|
>
|
|
229
234
|
{translate?.(Util.mapWeeKDate(dayIdx))}
|
|
@@ -237,9 +242,9 @@ const CalendarPro = forwardRef<CalendarProRef, CalendarProProps>(
|
|
|
237
242
|
maxDate={maxDate}
|
|
238
243
|
startDate={startDate!}
|
|
239
244
|
endDate={endDate!}
|
|
240
|
-
onChoose={
|
|
241
|
-
onScrollCalendar={
|
|
242
|
-
isShowLunar={!isOffLunar &&
|
|
245
|
+
onChoose={handleChooseDay}
|
|
246
|
+
onScrollCalendar={handleScrollCalendar}
|
|
247
|
+
isShowLunar={!isOffLunar && isLunarShown}
|
|
243
248
|
isDoubleDateMode={isDoubleDateMode}
|
|
244
249
|
tabSelected={tabSelected}
|
|
245
250
|
holidays={holidays}
|
|
@@ -257,8 +262,8 @@ const CalendarPro = forwardRef<CalendarProRef, CalendarProProps>(
|
|
|
257
262
|
]}
|
|
258
263
|
>
|
|
259
264
|
<CheckBox
|
|
260
|
-
onChange={
|
|
261
|
-
value={
|
|
265
|
+
onChange={handleToggleLunar}
|
|
266
|
+
value={isLunarShown}
|
|
262
267
|
label={translate?.('showLunar')}
|
|
263
268
|
/>
|
|
264
269
|
</View>
|
|
@@ -273,8 +278,9 @@ const CalendarPro = forwardRef<CalendarProRef, CalendarProProps>(
|
|
|
273
278
|
const day = item.day > 9 ? item.day : `0${item.day}`;
|
|
274
279
|
const month = item.month > 9 ? item.month : `0${item.month}`;
|
|
275
280
|
const labelDate = `${day}/${month}`;
|
|
276
|
-
const
|
|
277
|
-
const
|
|
281
|
+
const shownMixedLabel = isLunarShown && item.mixedLabel;
|
|
282
|
+
const labelHoliday = shownMixedLabel || item.label;
|
|
283
|
+
const labelHighlight = isLunarShown ? item.highlight || '' : '';
|
|
278
284
|
return (
|
|
279
285
|
<View style={styles.row} key={idx.toString()}>
|
|
280
286
|
<Text
|
package/HeaderControl.tsx
CHANGED
|
@@ -24,12 +24,10 @@ const HeaderControl: ForwardRefRenderFunction<
|
|
|
24
24
|
});
|
|
25
25
|
|
|
26
26
|
useImperativeHandle(ref, () => ({
|
|
27
|
-
onUpdateInfo,
|
|
27
|
+
onUpdateInfo: updateInfo,
|
|
28
28
|
}));
|
|
29
29
|
|
|
30
|
-
const
|
|
31
|
-
date: React.SetStateAction<{ date: moment.Moment }>,
|
|
32
|
-
) => {
|
|
30
|
+
const updateInfo = (date: React.SetStateAction<{ date: moment.Moment }>) => {
|
|
33
31
|
setInfo(date);
|
|
34
32
|
};
|
|
35
33
|
|
package/LunarDateConverter.ts
CHANGED
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
const MIN_YEAR = 1900;
|
|
2
|
+
const LONG_MONTH_DAYS = 30;
|
|
3
|
+
const SHORT_MONTH_DAYS = 29;
|
|
4
|
+
const MAX_MONTHS_WITH_LEAP = 13;
|
|
5
|
+
|
|
6
|
+
/** Lunar date record that `SolarToLunar` fills; used with `new`. */
|
|
1
7
|
function Lunar(this: any) {
|
|
2
8
|
this.isleap = false;
|
|
3
9
|
this.lunarDay = 0;
|
|
@@ -5,6 +11,7 @@ function Lunar(this: any) {
|
|
|
5
11
|
this.lunarYear = 0;
|
|
6
12
|
}
|
|
7
13
|
|
|
14
|
+
/** Solar date record that `SolarFromInt` fills; used with `new`. */
|
|
8
15
|
function Solar(this: any) {
|
|
9
16
|
this.solarDay = 0;
|
|
10
17
|
this.solarMonth = 0;
|
|
@@ -133,11 +140,10 @@ function LunarSolarConverter(this: any) {
|
|
|
133
140
|
lunarDay: number;
|
|
134
141
|
}) {
|
|
135
142
|
const firstTableYear = this.lunar_month_days[0];
|
|
136
|
-
const minLunarYear = 1900;
|
|
137
143
|
const maxLunarYear = firstTableYear + this.lunar_month_days.length - 1;
|
|
138
|
-
if (lunar.lunarYear <
|
|
144
|
+
if (lunar.lunarYear < MIN_YEAR || lunar.lunarYear > maxLunarYear) {
|
|
139
145
|
throw new Error(
|
|
140
|
-
`LunarToSolar: year ${lunar.lunarYear} out of supported range ${
|
|
146
|
+
`LunarToSolar: year ${lunar.lunarYear} out of supported range ${MIN_YEAR}-${maxLunarYear}`,
|
|
141
147
|
);
|
|
142
148
|
}
|
|
143
149
|
const days = this.lunar_month_days[lunar.lunarYear - firstTableYear];
|
|
@@ -152,7 +158,8 @@ function LunarSolarConverter(this: any) {
|
|
|
152
158
|
}
|
|
153
159
|
}
|
|
154
160
|
for (let i = 0; i < loopend; i++) {
|
|
155
|
-
|
|
161
|
+
const isLongMonth = this.GetBitInt(days, 1, 12 - i) === 1;
|
|
162
|
+
offset += isLongMonth ? LONG_MONTH_DAYS : SHORT_MONTH_DAYS;
|
|
156
163
|
}
|
|
157
164
|
offset += lunar.lunarDay;
|
|
158
165
|
|
|
@@ -170,11 +177,10 @@ function LunarSolarConverter(this: any) {
|
|
|
170
177
|
solarMonth: number;
|
|
171
178
|
solarDay: number;
|
|
172
179
|
}) {
|
|
173
|
-
const minSolarYear = 1900;
|
|
174
180
|
const maxSolarYear = this.solar_1_1[0] + this.solar_1_1.length - 1;
|
|
175
|
-
if (solar.solarYear <
|
|
181
|
+
if (solar.solarYear < MIN_YEAR || solar.solarYear > maxSolarYear) {
|
|
176
182
|
throw new Error(
|
|
177
|
-
`SolarToLunar: year ${solar.solarYear} out of supported range ${
|
|
183
|
+
`SolarToLunar: year ${solar.solarYear} out of supported range ${MIN_YEAR}-${maxSolarYear}`,
|
|
178
184
|
);
|
|
179
185
|
}
|
|
180
186
|
// @ts-ignore
|
|
@@ -200,8 +206,9 @@ function LunarSolarConverter(this: any) {
|
|
|
200
206
|
let lunarM = 1;
|
|
201
207
|
offset += 1;
|
|
202
208
|
|
|
203
|
-
for (let i = 0; i <
|
|
204
|
-
const
|
|
209
|
+
for (let i = 0; i < MAX_MONTHS_WITH_LEAP; i++) {
|
|
210
|
+
const isLongMonth = this.GetBitInt(days, 1, 12 - i) === 1;
|
|
211
|
+
const dm = isLongMonth ? LONG_MONTH_DAYS : SHORT_MONTH_DAYS;
|
|
205
212
|
if (offset > dm) {
|
|
206
213
|
lunarM++;
|
|
207
214
|
offset -= dm;
|
package/MonthList.tsx
CHANGED
|
@@ -22,13 +22,13 @@ import Month from './Month';
|
|
|
22
22
|
import { MonthListProps, MonthListRef } from './types';
|
|
23
23
|
|
|
24
24
|
const MAX_RENDER_PER_BATCH = Platform.OS === 'android' ? 1 : 12;
|
|
25
|
+
const ROW_HEIGHT = 48;
|
|
26
|
+
const DAYS_PER_WEEK = 7;
|
|
25
27
|
|
|
26
28
|
// @ts-ignore
|
|
27
29
|
const converter = new LunarDateConverter();
|
|
28
30
|
|
|
29
|
-
/**
|
|
30
|
-
* True when `a` and `b` fall in the same month of the same year.
|
|
31
|
-
*/
|
|
31
|
+
/** Whether both moments fall in the same month of the same year. */
|
|
32
32
|
const isSameMonth = (a: Moment, b: Moment) => {
|
|
33
33
|
return a.year() === b.year() && a.month() === b.month();
|
|
34
34
|
};
|
|
@@ -56,15 +56,15 @@ const MonthList = forwardRef<MonthListRef, MonthListProps>((props, ref) => {
|
|
|
56
56
|
} = props;
|
|
57
57
|
|
|
58
58
|
const size = useContext(ContainerContext);
|
|
59
|
-
const
|
|
59
|
+
const scaledRowHeight = useScaleSize(ROW_HEIGHT);
|
|
60
60
|
const listRef = useRef<FlatList>(null);
|
|
61
61
|
const currentKey = useRef<string | null>(null);
|
|
62
62
|
const targetIndex = useRef<number | null>(null);
|
|
63
63
|
const [heightStyle, setHeightStyle] = useState({});
|
|
64
64
|
const onScrollCalendarRef = useRef(onScrollCalendar);
|
|
65
65
|
onScrollCalendarRef.current = onScrollCalendar;
|
|
66
|
-
const
|
|
67
|
-
|
|
66
|
+
const scaledRowHeightRef = useRef(scaledRowHeight);
|
|
67
|
+
scaledRowHeightRef.current = scaledRowHeight;
|
|
68
68
|
|
|
69
69
|
const data = useMemo(() => {
|
|
70
70
|
const months: { date: Moment; dateList: any[] }[] = [];
|
|
@@ -96,9 +96,10 @@ const MonthList = forwardRef<MonthListRef, MonthListProps>((props, ref) => {
|
|
|
96
96
|
}
|
|
97
97
|
cursor.subtract(1, 'days');
|
|
98
98
|
weekday = cursor.isoWeekday();
|
|
99
|
-
if (weekday !==
|
|
99
|
+
if (weekday !== DAYS_PER_WEEK) {
|
|
100
|
+
const trailingDays = DAYS_PER_WEEK - weekday;
|
|
100
101
|
dayList.push(
|
|
101
|
-
...new Array(
|
|
102
|
+
...new Array(trailingDays).fill(0).map(() => ({ isEmpty: true })),
|
|
102
103
|
);
|
|
103
104
|
}
|
|
104
105
|
months.push({ date: d, dateList: dayList });
|
|
@@ -135,9 +136,12 @@ const MonthList = forwardRef<MonthListRef, MonthListProps>((props, ref) => {
|
|
|
135
136
|
});
|
|
136
137
|
}, [size.width]);
|
|
137
138
|
|
|
138
|
-
const
|
|
139
|
-
|
|
140
|
-
|
|
139
|
+
const handleScroll = useCallback(
|
|
140
|
+
(e: NativeSyntheticEvent<NativeScrollEvent>) => {
|
|
141
|
+
scrollOffset.current = e.nativeEvent.contentOffset.x;
|
|
142
|
+
},
|
|
143
|
+
[],
|
|
144
|
+
);
|
|
141
145
|
|
|
142
146
|
const scrollToMonth = useCallback(
|
|
143
147
|
(month: Moment) => {
|
|
@@ -154,7 +158,7 @@ const MonthList = forwardRef<MonthListRef, MonthListProps>((props, ref) => {
|
|
|
154
158
|
|
|
155
159
|
useImperativeHandle(ref, () => ({ scrollToMonth }));
|
|
156
160
|
|
|
157
|
-
const
|
|
161
|
+
const handleViewableChange = useRef(({ changed }: { changed: any[] }) => {
|
|
158
162
|
const visible = changed.find(token => token.isViewable);
|
|
159
163
|
// Ignore months passed while animating to a scrollToMonth target.
|
|
160
164
|
const isScrollingToTarget = targetIndex.current !== null;
|
|
@@ -167,8 +171,8 @@ const MonthList = forwardRef<MonthListRef, MonthListProps>((props, ref) => {
|
|
|
167
171
|
if (onScrollCalendarRef.current && item && currentKey.current !== key) {
|
|
168
172
|
currentKey.current = key;
|
|
169
173
|
try {
|
|
170
|
-
const rowHeight =
|
|
171
|
-
const rowsHeight = (rowHeight * item.dateList.length) /
|
|
174
|
+
const rowHeight = scaledRowHeightRef.current;
|
|
175
|
+
const rowsHeight = (rowHeight * item.dateList.length) / DAYS_PER_WEEK;
|
|
172
176
|
setHeightStyle({ height: rowsHeight + Spacing.L * 2 + Spacing.XS });
|
|
173
177
|
} catch {
|
|
174
178
|
setHeightStyle({});
|
|
@@ -256,7 +260,7 @@ const MonthList = forwardRef<MonthListRef, MonthListProps>((props, ref) => {
|
|
|
256
260
|
showsHorizontalScrollIndicator={false}
|
|
257
261
|
keyExtractor={keyExtractor}
|
|
258
262
|
onScrollToIndexFailed={() => {}}
|
|
259
|
-
onScroll={
|
|
263
|
+
onScroll={handleScroll}
|
|
260
264
|
onScrollBeginDrag={() => {
|
|
261
265
|
targetIndex.current = null;
|
|
262
266
|
}}
|
|
@@ -264,7 +268,7 @@ const MonthList = forwardRef<MonthListRef, MonthListProps>((props, ref) => {
|
|
|
264
268
|
initialNumToRender={3}
|
|
265
269
|
maxToRenderPerBatch={MAX_RENDER_PER_BATCH}
|
|
266
270
|
windowSize={1}
|
|
267
|
-
onViewableItemsChanged={
|
|
271
|
+
onViewableItemsChanged={handleViewableChange}
|
|
268
272
|
initialScrollIndex={currentScrollIndex}
|
|
269
273
|
getItemLayout={getItemLayout}
|
|
270
274
|
viewabilityConfig={viewabilityConfig}
|
package/TabHeader.tsx
CHANGED
|
@@ -15,7 +15,9 @@ import { TabHeaderProps, TabHeaderRef } from './types';
|
|
|
15
15
|
const TabHeader = forwardRef<TabHeaderRef, TabHeaderProps>((props, ref) => {
|
|
16
16
|
const { label, disabled, id, onChangeTab } = props;
|
|
17
17
|
const { theme, translate } = useContext(ApplicationContext);
|
|
18
|
-
const [
|
|
18
|
+
const [isActive, setIsActive] = useState<boolean | undefined>(
|
|
19
|
+
props.activeTab,
|
|
20
|
+
);
|
|
19
21
|
const [date, setDate] = useState<Moment.Moment | undefined>(
|
|
20
22
|
props.date ? Moment(props.date) : undefined,
|
|
21
23
|
);
|
|
@@ -23,15 +25,15 @@ const TabHeader = forwardRef<TabHeaderRef, TabHeaderProps>((props, ref) => {
|
|
|
23
25
|
useImperativeHandle(ref, () => ({
|
|
24
26
|
updateView: (nextDate, activeTab) => {
|
|
25
27
|
setDate(nextDate ? Moment(nextDate) : undefined);
|
|
26
|
-
|
|
28
|
+
setIsActive(activeTab);
|
|
27
29
|
},
|
|
28
|
-
setActiveTab:
|
|
30
|
+
setActiveTab: setIsActive,
|
|
29
31
|
}));
|
|
30
32
|
|
|
31
33
|
const weekday = (day: Moment.Moment) => {
|
|
32
34
|
return translate?.(Util.WEEKDAYSFROMMOMENT[day.day()]);
|
|
33
35
|
};
|
|
34
|
-
const isHighlighted =
|
|
36
|
+
const isHighlighted = isActive && !disabled;
|
|
35
37
|
|
|
36
38
|
const formattedDate = date ? date.format('DD/MM/YYYY') : '';
|
|
37
39
|
const dayOfWeek = date ? `${weekday(date)}, ` : '';
|
package/Util.ts
CHANGED
|
@@ -13,17 +13,17 @@ const Solar = (momentDate: moment.Moment) => ({
|
|
|
13
13
|
solarYear: momentDate.year(),
|
|
14
14
|
});
|
|
15
15
|
|
|
16
|
-
/**
|
|
16
|
+
/** Two-digit day or month: 7 → `07`. */
|
|
17
17
|
const padTwoDigits = (value: number) => {
|
|
18
18
|
return value < 10 ? `0${value}` : `${value}`;
|
|
19
19
|
};
|
|
20
20
|
|
|
21
|
-
/** `YYYY-MM-DD
|
|
22
|
-
const formatYYYYMMDD = (dd: number, mm: number, yyyy:
|
|
21
|
+
/** `YYYY-MM-DD` string that `moment()` parses as a local date. */
|
|
22
|
+
const formatYYYYMMDD = (dd: number, mm: number, yyyy: any) => {
|
|
23
23
|
return `${yyyy}-${padTwoDigits(mm)}-${padTwoDigits(dd)}`;
|
|
24
24
|
};
|
|
25
25
|
|
|
26
|
-
/**
|
|
26
|
+
/** `DD/MM` key that groups holidays by day. */
|
|
27
27
|
const formatDDMM = (dd: number, mm: number) => {
|
|
28
28
|
return `${padTwoDigits(dd)}/${padTwoDigits(mm)}`;
|
|
29
29
|
};
|
|
@@ -123,7 +123,7 @@ const Utils = {
|
|
|
123
123
|
if (holiday.solar[headerInfo.month() + 1]) {
|
|
124
124
|
// @ts-ignore
|
|
125
125
|
holiday.solar[headerInfo.month() + 1].forEach(
|
|
126
|
-
(date: { month: number; day:
|
|
126
|
+
(date: { month: number; day: any }) => {
|
|
127
127
|
const dateAsMoment = moment({
|
|
128
128
|
year: headerInfo.year(),
|
|
129
129
|
month: date.month - 1,
|
|
@@ -136,7 +136,7 @@ const Utils = {
|
|
|
136
136
|
);
|
|
137
137
|
}
|
|
138
138
|
|
|
139
|
-
holiday.lunar.forEach(item => {
|
|
139
|
+
holiday.lunar.forEach((item: { lunarDay: any; lunarMonth: any }) => {
|
|
140
140
|
if (currentYear instanceof Array) {
|
|
141
141
|
const solar1 = converter.LunarToSolar({
|
|
142
142
|
lunarDay: item.lunarDay,
|
package/index.tsx
CHANGED
|
@@ -15,6 +15,8 @@ import { ContainerContext } from './ContainerContext';
|
|
|
15
15
|
import styles from './styles';
|
|
16
16
|
|
|
17
17
|
const DOUBLE = 'doubleDate';
|
|
18
|
+
const DAY_HEIGHT = 34;
|
|
19
|
+
const PRICE_DAY_HEIGHT = 48;
|
|
18
20
|
|
|
19
21
|
/**
|
|
20
22
|
* Calendar with single or round-trip (`mode="doubleDate"`) selection, lunar
|
|
@@ -22,8 +24,8 @@ const DOUBLE = 'doubleDate';
|
|
|
22
24
|
*/
|
|
23
25
|
const Calendar: React.FC<CalendarProps> = props => {
|
|
24
26
|
const { theme } = useContext(ApplicationContext);
|
|
25
|
-
const
|
|
26
|
-
const
|
|
27
|
+
const scaledPriceDayHeight = useScaleSize(PRICE_DAY_HEIGHT);
|
|
28
|
+
const scaledDayHeight = useScaleSize(DAY_HEIGHT);
|
|
27
29
|
|
|
28
30
|
const currentDate = new Date();
|
|
29
31
|
const minDateDefault = new Date(currentDate);
|
|
@@ -36,7 +38,7 @@ const Calendar: React.FC<CalendarProps> = props => {
|
|
|
36
38
|
id,
|
|
37
39
|
doubleDate: initDoubleDate,
|
|
38
40
|
selectedDate: initialSelectedDate,
|
|
39
|
-
onChangeTab
|
|
41
|
+
onChangeTab,
|
|
40
42
|
onCallbackCalendar,
|
|
41
43
|
isOffLunar,
|
|
42
44
|
isHideHoliday,
|
|
@@ -96,12 +98,12 @@ const Calendar: React.FC<CalendarProps> = props => {
|
|
|
96
98
|
}
|
|
97
99
|
}, []);
|
|
98
100
|
|
|
99
|
-
const
|
|
101
|
+
const handleLayout = (e: LayoutChangeEvent) => {
|
|
100
102
|
setContainerWidth(e.nativeEvent.layout.width);
|
|
101
103
|
};
|
|
102
104
|
|
|
103
|
-
const
|
|
104
|
-
|
|
105
|
+
const handleChangeTab = (tabId: number) => {
|
|
106
|
+
onChangeTab?.(tabId);
|
|
105
107
|
tabSelected.current = tabId;
|
|
106
108
|
cellHeader1.current?.setActiveTab(tabId === 0);
|
|
107
109
|
cellHeader2.current?.setActiveTab(tabId === 1);
|
|
@@ -181,17 +183,17 @@ const Calendar: React.FC<CalendarProps> = props => {
|
|
|
181
183
|
};
|
|
182
184
|
|
|
183
185
|
// Skip the mount run so the initial doubleDate props are kept.
|
|
184
|
-
const
|
|
186
|
+
const hasMounted = useRef(false);
|
|
185
187
|
|
|
186
188
|
useEffect(() => {
|
|
187
|
-
if (
|
|
189
|
+
if (hasMounted.current) {
|
|
188
190
|
updateView();
|
|
189
191
|
} else {
|
|
190
|
-
|
|
192
|
+
hasMounted.current = true;
|
|
191
193
|
}
|
|
192
194
|
}, [selectedDate]);
|
|
193
195
|
|
|
194
|
-
const
|
|
196
|
+
const handleDateChange = (date: moment.Moment) => setSelectedDate(date);
|
|
195
197
|
|
|
196
198
|
const updateHeaderView = () => {
|
|
197
199
|
const { onDateChange, onCTAStateChange } = props;
|
|
@@ -231,12 +233,12 @@ const Calendar: React.FC<CalendarProps> = props => {
|
|
|
231
233
|
});
|
|
232
234
|
};
|
|
233
235
|
|
|
234
|
-
const
|
|
236
|
+
const hasModeMounted = useRef(false);
|
|
235
237
|
useEffect(() => {
|
|
236
|
-
if (
|
|
238
|
+
if (hasModeMounted.current) {
|
|
237
239
|
updateHeaderView();
|
|
238
240
|
} else {
|
|
239
|
-
|
|
241
|
+
hasModeMounted.current = true;
|
|
240
242
|
}
|
|
241
243
|
}, [isDoubleDateMode]);
|
|
242
244
|
|
|
@@ -244,10 +246,10 @@ const Calendar: React.FC<CalendarProps> = props => {
|
|
|
244
246
|
<ContainerContext.Provider
|
|
245
247
|
value={{
|
|
246
248
|
width: containerWidth,
|
|
247
|
-
height: priceList ?
|
|
249
|
+
height: priceList ? scaledPriceDayHeight : scaledDayHeight,
|
|
248
250
|
}}
|
|
249
251
|
>
|
|
250
|
-
<View onLayout={
|
|
252
|
+
<View onLayout={handleLayout} style={[style, styles.scrollView]}>
|
|
251
253
|
<View
|
|
252
254
|
style={[
|
|
253
255
|
{
|
|
@@ -269,7 +271,7 @@ const Calendar: React.FC<CalendarProps> = props => {
|
|
|
269
271
|
cellHeader1={cellHeader1}
|
|
270
272
|
cellHeader2={cellHeader2}
|
|
271
273
|
cellHeaderSingle={cellHeaderSingle}
|
|
272
|
-
onChangeTab={
|
|
274
|
+
onChangeTab={handleChangeTab}
|
|
273
275
|
headerFrom={props.headerFrom}
|
|
274
276
|
headerTo={props.headerTo}
|
|
275
277
|
firstDate={doubleDate.current.first}
|
|
@@ -282,7 +284,7 @@ const Calendar: React.FC<CalendarProps> = props => {
|
|
|
282
284
|
ref={calendarPicker}
|
|
283
285
|
startDate={doubleDate.current.first!}
|
|
284
286
|
endDate={doubleDate.current.second!}
|
|
285
|
-
onDateChange={
|
|
287
|
+
onDateChange={handleDateChange}
|
|
286
288
|
isDoubleDateMode={isDoubleDateMode}
|
|
287
289
|
selectedDate={selectedDate}
|
|
288
290
|
isShowLunar={isShowLunar}
|