@momo-kits/calendar 0.169.4 → 0.169.5
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 +2 -0
- package/CalendarPro.tsx +38 -33
- package/ContainerContext.ts +1 -0
- package/Day.tsx +10 -8
- package/HeaderControl.tsx +12 -10
- package/LunarDateConverter.ts +33 -35
- package/Month.tsx +16 -15
- package/MonthList.tsx +21 -21
- package/TabHeader.tsx +4 -2
- package/Util.ts +48 -32
- package/index.tsx +15 -24
- package/package.json +1 -1
- package/styles.ts +3 -7
package/CalendarHeader.tsx
CHANGED
|
@@ -13,6 +13,7 @@ type SwitchReturnSelectionProps = {
|
|
|
13
13
|
onChange: () => void;
|
|
14
14
|
};
|
|
15
15
|
|
|
16
|
+
/** Round-trip switch row above the date tabs; renders nothing when `hidden`. */
|
|
16
17
|
export const SwitchReturnSelection: React.FC<
|
|
17
18
|
SwitchReturnSelectionProps
|
|
18
19
|
> = props => {
|
|
@@ -48,6 +49,7 @@ type HeaderPanelProps = {
|
|
|
48
49
|
selectedDate: moment.Moment;
|
|
49
50
|
};
|
|
50
51
|
|
|
52
|
+
/** Departure and return tabs in double-date mode, else one departure tab. */
|
|
51
53
|
export const HeaderPanel: React.FC<HeaderPanelProps> = props => {
|
|
52
54
|
const { theme } = useContext(ApplicationContext);
|
|
53
55
|
const {
|
package/CalendarPro.tsx
CHANGED
|
@@ -28,6 +28,18 @@ import {
|
|
|
28
28
|
import { ContainerContext } from './ContainerContext';
|
|
29
29
|
import styles from './styles';
|
|
30
30
|
|
|
31
|
+
/** Holidays to list: lunar-only ones are hidden while lunar dates are off. */
|
|
32
|
+
const getVisibleHolidays = (holidays: Holidays[], showLunar: boolean) => {
|
|
33
|
+
if (showLunar) {
|
|
34
|
+
return holidays;
|
|
35
|
+
}
|
|
36
|
+
return holidays.filter(item => !item.lunar || item.mixedLabel);
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Weekday row, month list, lunar toggle and holiday list of `Calendar`, which
|
|
41
|
+
* drives the selection through `setDoubleDateAndTabIndex`.
|
|
42
|
+
*/
|
|
31
43
|
const CalendarPro = forwardRef<CalendarProRef, CalendarProProps>(
|
|
32
44
|
(
|
|
33
45
|
{
|
|
@@ -55,7 +67,7 @@ const CalendarPro = forwardRef<CalendarProRef, CalendarProProps>(
|
|
|
55
67
|
const headerControlRef = useRef<HeaderControlRef>(null);
|
|
56
68
|
const monthListRef = useRef<MonthListRef>(null);
|
|
57
69
|
|
|
58
|
-
//
|
|
70
|
+
// An invalid bound falls back to 12 months from the other one (or today).
|
|
59
71
|
const [minDate, maxDate] = useMemo(() => {
|
|
60
72
|
let max = moment(propMaxDate);
|
|
61
73
|
let min = moment(propMinDate);
|
|
@@ -72,7 +84,6 @@ const CalendarPro = forwardRef<CalendarProRef, CalendarProProps>(
|
|
|
72
84
|
return [min, max];
|
|
73
85
|
}, [propMinDate, propMaxDate]);
|
|
74
86
|
|
|
75
|
-
// State
|
|
76
87
|
const [startDate, setStartDate] = useState<Moment>(propStartDate);
|
|
77
88
|
const [endDate, setEndDate] = useState<Moment | null>(propEndDate || null);
|
|
78
89
|
const [showLunar, setShowLunar] = useState<boolean>(!!propIsShowLunar);
|
|
@@ -94,7 +105,7 @@ const CalendarPro = forwardRef<CalendarProRef, CalendarProProps>(
|
|
|
94
105
|
},
|
|
95
106
|
}));
|
|
96
107
|
|
|
97
|
-
//
|
|
108
|
+
// Follow the isShowLunar prop, except right after the user toggled it.
|
|
98
109
|
useEffect(() => {
|
|
99
110
|
if (ownUpdate) {
|
|
100
111
|
setOwnUpdate(false);
|
|
@@ -103,7 +114,6 @@ const CalendarPro = forwardRef<CalendarProRef, CalendarProProps>(
|
|
|
103
114
|
}
|
|
104
115
|
}, [ownUpdate, propIsShowLunar, showLunar]);
|
|
105
116
|
|
|
106
|
-
// Scroll to initial selected date on mount or when it changes
|
|
107
117
|
useEffect(() => {
|
|
108
118
|
const timer = setTimeout(() => {
|
|
109
119
|
monthListRef.current?.scrollToMonth(propSelectedDate);
|
|
@@ -111,7 +121,6 @@ const CalendarPro = forwardRef<CalendarProRef, CalendarProProps>(
|
|
|
111
121
|
return () => clearTimeout(timer);
|
|
112
122
|
}, [propSelectedDate]);
|
|
113
123
|
|
|
114
|
-
// Handlers
|
|
115
124
|
const onChooseDay = (day: Moment) => {
|
|
116
125
|
if (isDoubleDateMode) {
|
|
117
126
|
if (tabSelected === 1) {
|
|
@@ -132,11 +141,8 @@ const CalendarPro = forwardRef<CalendarProRef, CalendarProProps>(
|
|
|
132
141
|
};
|
|
133
142
|
|
|
134
143
|
const executeProcessAfterScrollCalendar = (date: Moment, key: string) => {
|
|
135
|
-
// get sorted array of holidays directly
|
|
136
144
|
const allHolidays = Util.getHolidaysInMonth(moment(date));
|
|
137
|
-
const filtered = showLunar
|
|
138
|
-
? allHolidays
|
|
139
|
-
: allHolidays.filter(item => !item.lunar || item.mixedLabel);
|
|
145
|
+
const filtered = getVisibleHolidays(allHolidays, showLunar);
|
|
140
146
|
headerControlRef.current?.onUpdateInfo({ date });
|
|
141
147
|
headerRef.current = date.clone().startOf('month');
|
|
142
148
|
setHolidays(allHolidays);
|
|
@@ -157,9 +163,7 @@ const CalendarPro = forwardRef<CalendarProRef, CalendarProProps>(
|
|
|
157
163
|
const onToggleLunar = () => {
|
|
158
164
|
setOwnUpdate(true);
|
|
159
165
|
const next = !showLunar;
|
|
160
|
-
const filtered = next
|
|
161
|
-
? holidays
|
|
162
|
-
: holidays.filter(item => !item.lunar || item.mixedLabel);
|
|
166
|
+
const filtered = getVisibleHolidays(holidays, next);
|
|
163
167
|
onCallbackCalendar?.('lunar', next);
|
|
164
168
|
setShowLunar(next);
|
|
165
169
|
setTemp(filtered);
|
|
@@ -186,7 +190,6 @@ const CalendarPro = forwardRef<CalendarProRef, CalendarProProps>(
|
|
|
186
190
|
}
|
|
187
191
|
};
|
|
188
192
|
|
|
189
|
-
// Determine price list format
|
|
190
193
|
let priceListFormat = priceList?.outbound;
|
|
191
194
|
if (isDoubleDateMode && tabSelected !== 0) {
|
|
192
195
|
priceListFormat = priceList?.inbound;
|
|
@@ -208,23 +211,25 @@ const CalendarPro = forwardRef<CalendarProRef, CalendarProProps>(
|
|
|
208
211
|
<View style={styles.blueSeperator} />
|
|
209
212
|
<View>
|
|
210
213
|
<View style={styles.viewDay}>
|
|
211
|
-
{[1, 2, 3, 4, 5, 6, 7].map(dayIdx =>
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
214
|
+
{[1, 2, 3, 4, 5, 6, 7].map(dayIdx => {
|
|
215
|
+
let dayColor = theme.colors.text.default;
|
|
216
|
+
if (dayIdx >= 6) {
|
|
217
|
+
dayColor = theme.colors.error.primary;
|
|
218
|
+
}
|
|
219
|
+
return (
|
|
220
|
+
<Text
|
|
221
|
+
key={dayIdx}
|
|
222
|
+
color={dayColor}
|
|
223
|
+
typography="label_s_medium"
|
|
224
|
+
style={[
|
|
225
|
+
styles.textDay,
|
|
226
|
+
{ width: (size.width - Spacing.S * 2) / 7 },
|
|
227
|
+
]}
|
|
228
|
+
>
|
|
229
|
+
{translate?.(Util.mapWeeKDate(dayIdx))}
|
|
230
|
+
</Text>
|
|
231
|
+
);
|
|
232
|
+
})}
|
|
228
233
|
</View>
|
|
229
234
|
<MonthList
|
|
230
235
|
ref={monthListRef}
|
|
@@ -265,9 +270,9 @@ const CalendarPro = forwardRef<CalendarProRef, CalendarProProps>(
|
|
|
265
270
|
nestedScrollEnabled
|
|
266
271
|
>
|
|
267
272
|
{temp.map((item, idx) => {
|
|
268
|
-
const
|
|
269
|
-
|
|
270
|
-
}`;
|
|
273
|
+
const day = item.day > 9 ? item.day : `0${item.day}`;
|
|
274
|
+
const month = item.month > 9 ? item.month : `0${item.month}`;
|
|
275
|
+
const labelDate = `${day}/${month}`;
|
|
271
276
|
const labelHoliday = (showLunar && item.mixedLabel) || item.label;
|
|
272
277
|
const labelHighlight = showLunar ? item.highlight || '' : '';
|
|
273
278
|
return (
|
package/ContainerContext.ts
CHANGED
package/Day.tsx
CHANGED
|
@@ -12,6 +12,10 @@ import { DayProps } from './types';
|
|
|
12
12
|
import { ContainerContext } from './ContainerContext';
|
|
13
13
|
import styles from './styles';
|
|
14
14
|
|
|
15
|
+
/**
|
|
16
|
+
* One day cell: solar date with optional lunar date and price, highlighted as
|
|
17
|
+
* the start, end or inside of the selected range.
|
|
18
|
+
*/
|
|
15
19
|
const Day: React.FC<DayProps> = props => {
|
|
16
20
|
const {
|
|
17
21
|
startDate,
|
|
@@ -46,15 +50,13 @@ const Day: React.FC<DayProps> = props => {
|
|
|
46
50
|
return <View style={[styles.dayContainer, { width: itemWidth }]} />;
|
|
47
51
|
}
|
|
48
52
|
|
|
49
|
-
const
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
(date.isBefore(maxDate, 'day') || date.isSame(maxDate, 'day'));
|
|
53
|
+
const isAfterMin = date.isSameOrAfter(minDate, 'day');
|
|
54
|
+
const isBeforeMax = date.isSameOrBefore(maxDate, 'day');
|
|
55
|
+
const isValid = !isDisabled && isAfterMin && isBeforeMax;
|
|
53
56
|
|
|
54
|
-
const
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
date.isBefore(endDate, 'day');
|
|
57
|
+
const isAfterStart = date.isAfter(startDate, 'day');
|
|
58
|
+
const isBeforeEnd = date.isBefore(endDate, 'day');
|
|
59
|
+
const isMid = isDoubleDateMode && isAfterStart && isBeforeEnd;
|
|
58
60
|
|
|
59
61
|
const isStart = date.isSame(startDate, 'day');
|
|
60
62
|
const isStartPart = !!(isStart && endDate);
|
package/HeaderControl.tsx
CHANGED
|
@@ -5,20 +5,21 @@ import React, {
|
|
|
5
5
|
useImperativeHandle,
|
|
6
6
|
useState,
|
|
7
7
|
} from 'react';
|
|
8
|
-
import {TouchableOpacity, View} from 'react-native';
|
|
8
|
+
import { TouchableOpacity, View } from 'react-native';
|
|
9
9
|
import moment from 'moment';
|
|
10
|
-
import {ApplicationContext, Icon, Text} from '@momo-kits/foundation';
|
|
10
|
+
import { ApplicationContext, Icon, Text } from '@momo-kits/foundation';
|
|
11
11
|
|
|
12
12
|
import Util from './Util';
|
|
13
|
-
import {HeaderControlProps, HeaderControlRef} from './types';
|
|
13
|
+
import { HeaderControlProps, HeaderControlRef } from './types';
|
|
14
14
|
import styles from './styles';
|
|
15
15
|
|
|
16
|
+
/** Month title between previous/next arrows; `onUpdateInfo` sets the month. */
|
|
16
17
|
const HeaderControl: ForwardRefRenderFunction<
|
|
17
18
|
HeaderControlRef,
|
|
18
19
|
HeaderControlProps
|
|
19
|
-
> = ({onPressBackArrow, onPressNextArrow, selectedDate}, ref) => {
|
|
20
|
-
const {translate} = useContext(ApplicationContext);
|
|
21
|
-
const [info, setInfo] = useState<{date: moment.Moment}>({
|
|
20
|
+
> = ({ onPressBackArrow, onPressNextArrow, selectedDate }, ref) => {
|
|
21
|
+
const { translate } = useContext(ApplicationContext);
|
|
22
|
+
const [info, setInfo] = useState<{ date: moment.Moment }>({
|
|
22
23
|
date: moment(selectedDate || new Date()),
|
|
23
24
|
});
|
|
24
25
|
|
|
@@ -26,14 +27,15 @@ const HeaderControl: ForwardRefRenderFunction<
|
|
|
26
27
|
onUpdateInfo,
|
|
27
28
|
}));
|
|
28
29
|
|
|
29
|
-
const onUpdateInfo = (
|
|
30
|
+
const onUpdateInfo = (
|
|
31
|
+
date: React.SetStateAction<{ date: moment.Moment }>,
|
|
32
|
+
) => {
|
|
30
33
|
setInfo(date);
|
|
31
34
|
};
|
|
32
35
|
|
|
33
36
|
if (info && info.date) {
|
|
34
|
-
const
|
|
35
|
-
|
|
36
|
-
)}/${info.date.year()}`;
|
|
37
|
+
const monthKey = Util.mapMonth(info.date.month() + 1) || '';
|
|
38
|
+
const headerFormat = `${translate?.(monthKey)}/${info.date.year()}`;
|
|
37
39
|
return (
|
|
38
40
|
<View style={styles.headerControlContainer}>
|
|
39
41
|
<TouchableOpacity onPress={onPressBackArrow}>
|
package/LunarDateConverter.ts
CHANGED
|
@@ -11,6 +11,20 @@ function Solar(this: any) {
|
|
|
11
11
|
this.solarYear = 0;
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
+
/** Day number of March 1 of `year` in the March-based count of `SolarToInt`. */
|
|
15
|
+
const daysBeforeYear = (year: number) => {
|
|
16
|
+
return (
|
|
17
|
+
365 * year +
|
|
18
|
+
parseInt(String(year / 4), 10) -
|
|
19
|
+
parseInt(String(year / 100), 10) +
|
|
20
|
+
parseInt(String(year / 400), 10)
|
|
21
|
+
);
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Table-based solar ↔ lunar date converter, used with `new`.
|
|
26
|
+
* Supports years from 1900 to the end of its tables and throws outside them.
|
|
27
|
+
*/
|
|
14
28
|
function LunarSolarConverter(this: any) {
|
|
15
29
|
this.lunar_month_days = [
|
|
16
30
|
1887, 0x1694, 0x16aa, 0x4ad5, 0xab6, 0xc4b7, 0x4ae, 0xa56, 0xb52a, 0x1d2a,
|
|
@@ -73,18 +87,12 @@ function LunarSolarConverter(this: any) {
|
|
|
73
87
|
0x107c53, 0x107e48,
|
|
74
88
|
];
|
|
75
89
|
|
|
76
|
-
/**
|
|
77
|
-
* @return {number}
|
|
78
|
-
*/
|
|
79
90
|
this.GetBitInt = function (data: number, length: number, shift: number) {
|
|
80
91
|
// eslint-disable-next-line no-bitwise -- unpacks bit-packed lunar table data
|
|
81
92
|
return (data & (((1 << length) - 1) << shift)) >> shift;
|
|
82
93
|
};
|
|
83
94
|
|
|
84
|
-
|
|
85
|
-
/**
|
|
86
|
-
* @return {number}
|
|
87
|
-
*/
|
|
95
|
+
/** Day number of a Gregorian date; inaccurate before Oct 1582. */
|
|
88
96
|
this.SolarToInt = function (y: number, m: number, d: number) {
|
|
89
97
|
m = (m + 9) % 12;
|
|
90
98
|
y = parseInt(String(y), 10) - parseInt(String(m / 10), 10);
|
|
@@ -98,22 +106,13 @@ function LunarSolarConverter(this: any) {
|
|
|
98
106
|
);
|
|
99
107
|
};
|
|
100
108
|
|
|
109
|
+
/** Gregorian date of a day number from `SolarToInt`. */
|
|
101
110
|
this.SolarFromInt = function (g: number) {
|
|
102
111
|
let y = parseInt(String((10000 * g + 14780) / 3652425), 10);
|
|
103
|
-
let ddd =
|
|
104
|
-
g -
|
|
105
|
-
(365 * y +
|
|
106
|
-
parseInt(String(y / 4), 10) -
|
|
107
|
-
parseInt(String(y / 100), 10) +
|
|
108
|
-
parseInt(String(y / 400), 10));
|
|
112
|
+
let ddd = g - daysBeforeYear(y);
|
|
109
113
|
if (ddd < 0) {
|
|
110
114
|
y--;
|
|
111
|
-
ddd =
|
|
112
|
-
g -
|
|
113
|
-
(365 * y +
|
|
114
|
-
parseInt(String(y / 4), 10) -
|
|
115
|
-
parseInt(String(y / 100), 10) +
|
|
116
|
-
parseInt(String(y / 400), 10));
|
|
115
|
+
ddd = g - daysBeforeYear(y);
|
|
117
116
|
}
|
|
118
117
|
const mi = parseInt(String((100 * ddd + 52) / 3060), 10);
|
|
119
118
|
const mm = ((mi + 2) % 12) + 1;
|
|
@@ -133,15 +132,15 @@ function LunarSolarConverter(this: any) {
|
|
|
133
132
|
lunarMonth: number;
|
|
134
133
|
lunarDay: number;
|
|
135
134
|
}) {
|
|
136
|
-
|
|
135
|
+
const firstTableYear = this.lunar_month_days[0];
|
|
137
136
|
const minLunarYear = 1900;
|
|
138
|
-
|
|
139
|
-
const maxLunarYear = this.lunar_month_days[0] + this.lunar_month_days.length - 1;
|
|
137
|
+
const maxLunarYear = firstTableYear + this.lunar_month_days.length - 1;
|
|
140
138
|
if (lunar.lunarYear < minLunarYear || lunar.lunarYear > maxLunarYear) {
|
|
141
|
-
throw new Error(
|
|
139
|
+
throw new Error(
|
|
140
|
+
`LunarToSolar: year ${lunar.lunarYear} out of supported range ${minLunarYear}-${maxLunarYear}`,
|
|
141
|
+
);
|
|
142
142
|
}
|
|
143
|
-
const days =
|
|
144
|
-
this.lunar_month_days[lunar.lunarYear - this.lunar_month_days[0]];
|
|
143
|
+
const days = this.lunar_month_days[lunar.lunarYear - firstTableYear];
|
|
145
144
|
const leap = this.GetBitInt(days, 4, 13);
|
|
146
145
|
let offset = 0;
|
|
147
146
|
let loopend = leap;
|
|
@@ -171,19 +170,19 @@ function LunarSolarConverter(this: any) {
|
|
|
171
170
|
solarMonth: number;
|
|
172
171
|
solarDay: number;
|
|
173
172
|
}) {
|
|
174
|
-
// year range check: only support solar dates from 1900
|
|
175
173
|
const minSolarYear = 1900;
|
|
176
|
-
// using converter data, maximum supported solar year
|
|
177
174
|
const maxSolarYear = this.solar_1_1[0] + this.solar_1_1.length - 1;
|
|
178
175
|
if (solar.solarYear < minSolarYear || solar.solarYear > maxSolarYear) {
|
|
179
|
-
throw new Error(
|
|
176
|
+
throw new Error(
|
|
177
|
+
`SolarToLunar: year ${solar.solarYear} out of supported range ${minSolarYear}-${maxSolarYear}`,
|
|
178
|
+
);
|
|
180
179
|
}
|
|
181
180
|
// @ts-ignore
|
|
182
181
|
const lunar = new Lunar();
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
182
|
+
const { solarYear, solarMonth, solarDay } = solar;
|
|
183
|
+
let index = solarYear - this.solar_1_1[0];
|
|
184
|
+
// eslint-disable-next-line no-bitwise -- packs date to compare with solar_1_1 table
|
|
185
|
+
const data = (solarYear << 9) | (solarMonth << 5) | solarDay;
|
|
187
186
|
if (this.solar_1_1[index] > data) {
|
|
188
187
|
index--;
|
|
189
188
|
}
|
|
@@ -191,9 +190,8 @@ function LunarSolarConverter(this: any) {
|
|
|
191
190
|
const y = this.GetBitInt(solar11, 12, 9);
|
|
192
191
|
const m = this.GetBitInt(solar11, 4, 5);
|
|
193
192
|
const d = this.GetBitInt(solar11, 5, 0);
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
this.SolarToInt(y, m, d);
|
|
193
|
+
const dayNumber = this.SolarToInt(solarYear, solarMonth, solarDay);
|
|
194
|
+
let offset = dayNumber - this.SolarToInt(y, m, d);
|
|
197
195
|
|
|
198
196
|
const days = this.lunar_month_days[index];
|
|
199
197
|
const leap = this.GetBitInt(days, 4, 13);
|
package/Month.tsx
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
|
-
import React, {useContext, useMemo} from 'react';
|
|
2
|
-
import {View} from 'react-native';
|
|
3
|
-
import moment, {Moment} from 'moment';
|
|
1
|
+
import React, { useContext, useMemo } from 'react';
|
|
2
|
+
import { View } from 'react-native';
|
|
3
|
+
import moment, { Moment } from 'moment';
|
|
4
4
|
import Day from './Day';
|
|
5
|
-
import {useScaleSize} from '@momo-kits/foundation';
|
|
6
|
-
import {MonthProps} from './types';
|
|
7
|
-
import {ContainerContext} from './ContainerContext';
|
|
5
|
+
import { useScaleSize } from '@momo-kits/foundation';
|
|
6
|
+
import { MonthProps } from './types';
|
|
7
|
+
import { ContainerContext } from './ContainerContext';
|
|
8
8
|
import styles from './styles';
|
|
9
9
|
|
|
10
|
+
/** One month as rows of 7 `Day` cells; `dateList` is padded to whole weeks. */
|
|
10
11
|
const Month: React.FC<MonthProps> = ({
|
|
11
12
|
dateList,
|
|
12
13
|
holidays,
|
|
@@ -49,26 +50,26 @@ const Month: React.FC<MonthProps> = ({
|
|
|
49
50
|
const size = useContext(ContainerContext);
|
|
50
51
|
const scaledHeight = useScaleSize(48);
|
|
51
52
|
|
|
52
|
-
//
|
|
53
|
-
const disabledSet = useMemo(
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
);
|
|
53
|
+
// YYYY-MM-DD set so each day cell is an O(1) lookup.
|
|
54
|
+
const disabledSet = useMemo(() => {
|
|
55
|
+
const keys = (disabledDays || []).map(d => moment(d).format('YYYY-MM-DD'));
|
|
56
|
+
return new Set(keys);
|
|
57
|
+
}, [disabledDays]);
|
|
57
58
|
|
|
58
59
|
if (!month) {
|
|
59
60
|
return <View />;
|
|
60
61
|
}
|
|
61
62
|
|
|
62
63
|
return (
|
|
63
|
-
<View style={{width: size.width}}>
|
|
64
|
+
<View style={{ width: size.width }}>
|
|
64
65
|
<View style={styles.monthRows}>
|
|
65
66
|
{rows.map((dayList, rowIndex) => (
|
|
66
67
|
<View
|
|
67
68
|
key={`row${rowIndex}`}
|
|
68
|
-
style={[styles.monthRow, {height: scaledHeight}]}
|
|
69
|
+
style={[styles.monthRow, { height: scaledHeight }]}
|
|
70
|
+
>
|
|
69
71
|
{dayList.map((item, i) => {
|
|
70
|
-
const {isEmpty, date: dateMoment, lunarDate} = item;
|
|
71
|
-
// compute key for price/disabled only if not empty
|
|
72
|
+
const { isEmpty, date: dateMoment, lunarDate } = item;
|
|
72
73
|
const hasDate = !isEmpty && dateMoment;
|
|
73
74
|
const keyDay = hasDate ? dateMoment.format('YYYY-MM-DD') : '';
|
|
74
75
|
const priceInfo = keyDay ? priceListDate?.[keyDay] : undefined;
|
package/MonthList.tsx
CHANGED
|
@@ -26,6 +26,14 @@ const MAX_RENDER_PER_BATCH = Platform.OS === 'android' ? 1 : 12;
|
|
|
26
26
|
// @ts-ignore
|
|
27
27
|
const converter = new LunarDateConverter();
|
|
28
28
|
|
|
29
|
+
const isSameMonth = (a: Moment, b: Moment) => {
|
|
30
|
+
return a.year() === b.year() && a.month() === b.month();
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Horizontally paged months from `minDate` to `maxDate`; reports the visible
|
|
35
|
+
* month through `onScrollCalendar` and `scrollToMonth` pages to a month.
|
|
36
|
+
*/
|
|
29
37
|
const MonthList = forwardRef<MonthListRef, MonthListProps>((props, ref) => {
|
|
30
38
|
const {
|
|
31
39
|
selectedDate,
|
|
@@ -59,10 +67,7 @@ const MonthList = forwardRef<MonthListRef, MonthListProps>((props, ref) => {
|
|
|
59
67
|
const months: { date: Moment; dateList: any[] }[] = [];
|
|
60
68
|
const mMin = moment(minDate).date(1);
|
|
61
69
|
const mMax = moment(maxDate);
|
|
62
|
-
while (
|
|
63
|
-
mMax > mMin ||
|
|
64
|
-
(mMax.year() === mMin.year() && mMax.month() === mMin.month())
|
|
65
|
-
) {
|
|
70
|
+
while (mMax > mMin || isSameMonth(mMax, mMin)) {
|
|
66
71
|
const d = moment(mMin);
|
|
67
72
|
const dayList: any[] = [];
|
|
68
73
|
const monthIdx = d.month();
|
|
@@ -109,8 +114,7 @@ const MonthList = forwardRef<MonthListRef, MonthListProps>((props, ref) => {
|
|
|
109
114
|
[selectedDate, getIndexOfMonth],
|
|
110
115
|
);
|
|
111
116
|
|
|
112
|
-
//
|
|
113
|
-
// rotation), so remember the offset and move back onto the same month
|
|
117
|
+
// Paging keeps the pixel offset on resize (fold, rotation); re-snap it.
|
|
114
118
|
const scrollOffset = useRef(Math.max(currentScrollIndex, 0) * size.width);
|
|
115
119
|
const pageWidth = useRef(size.width);
|
|
116
120
|
|
|
@@ -128,20 +132,17 @@ const MonthList = forwardRef<MonthListRef, MonthListProps>((props, ref) => {
|
|
|
128
132
|
});
|
|
129
133
|
}, [size.width]);
|
|
130
134
|
|
|
131
|
-
const onScroll = useCallback(
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
},
|
|
135
|
-
[],
|
|
136
|
-
);
|
|
135
|
+
const onScroll = useCallback((e: NativeSyntheticEvent<NativeScrollEvent>) => {
|
|
136
|
+
scrollOffset.current = e.nativeEvent.contentOffset.x;
|
|
137
|
+
}, []);
|
|
137
138
|
|
|
138
139
|
const scrollToMonth = useCallback(
|
|
139
140
|
(month: Moment) => {
|
|
140
141
|
const idx = getIndexOfMonth(month);
|
|
141
142
|
if (listRef.current && idx !== -1) {
|
|
142
143
|
const offset = idx * pageWidth.current;
|
|
143
|
-
|
|
144
|
-
|
|
144
|
+
const isAtTarget = Math.abs(offset - scrollOffset.current) < 1;
|
|
145
|
+
targetIndex.current = isAtTarget ? null : idx;
|
|
145
146
|
listRef.current.scrollToIndex({ index: idx, animated: true });
|
|
146
147
|
}
|
|
147
148
|
},
|
|
@@ -152,7 +153,9 @@ const MonthList = forwardRef<MonthListRef, MonthListProps>((props, ref) => {
|
|
|
152
153
|
|
|
153
154
|
const onViewableItemsChanged = useRef(({ changed }: { changed: any[] }) => {
|
|
154
155
|
const visible = changed.find(token => token.isViewable);
|
|
155
|
-
|
|
156
|
+
// Ignore months passed while animating to a scrollToMonth target.
|
|
157
|
+
const isScrollingToTarget = targetIndex.current !== null;
|
|
158
|
+
if (isScrollingToTarget && visible?.index !== targetIndex.current) {
|
|
156
159
|
return;
|
|
157
160
|
}
|
|
158
161
|
targetIndex.current = null;
|
|
@@ -161,12 +164,9 @@ const MonthList = forwardRef<MonthListRef, MonthListProps>((props, ref) => {
|
|
|
161
164
|
if (onScrollCalendarRef.current && item && currentKey.current !== key) {
|
|
162
165
|
currentKey.current = key;
|
|
163
166
|
try {
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
Spacing.L * 2 +
|
|
168
|
-
Spacing.XS,
|
|
169
|
-
});
|
|
167
|
+
const rowHeight = scaledHeight48Ref.current;
|
|
168
|
+
const rowsHeight = (rowHeight * item.dateList.length) / 7;
|
|
169
|
+
setHeightStyle({ height: rowsHeight + Spacing.L * 2 + Spacing.XS });
|
|
170
170
|
} catch {
|
|
171
171
|
setHeightStyle({});
|
|
172
172
|
}
|
package/TabHeader.tsx
CHANGED
|
@@ -11,6 +11,7 @@ import styles from './styles';
|
|
|
11
11
|
import { ApplicationContext, Text } from '@momo-kits/foundation';
|
|
12
12
|
import { TabHeaderProps, TabHeaderRef } from './types';
|
|
13
13
|
|
|
14
|
+
/** Date tab with a label and the chosen date, updated through `updateView`. */
|
|
14
15
|
const TabHeader = forwardRef<TabHeaderRef, TabHeaderProps>((props, ref) => {
|
|
15
16
|
const { label, disabled, id, onChangeTab } = props;
|
|
16
17
|
const { theme, translate } = useContext(ApplicationContext);
|
|
@@ -27,8 +28,9 @@ const TabHeader = forwardRef<TabHeaderRef, TabHeaderProps>((props, ref) => {
|
|
|
27
28
|
setActiveTab: setActive,
|
|
28
29
|
}));
|
|
29
30
|
|
|
30
|
-
const weekday = (day: Moment.Moment) =>
|
|
31
|
-
translate?.(Util.WEEKDAYSFROMMOMENT[day.day()]);
|
|
31
|
+
const weekday = (day: Moment.Moment) => {
|
|
32
|
+
return translate?.(Util.WEEKDAYSFROMMOMENT[day.day()]);
|
|
33
|
+
};
|
|
32
34
|
const isHighlighted = active && !disabled;
|
|
33
35
|
|
|
34
36
|
const formattedDate = date ? date.format('DD/MM/YYYY') : '';
|
package/Util.ts
CHANGED
|
@@ -1,30 +1,41 @@
|
|
|
1
1
|
import moment from 'moment';
|
|
2
2
|
import LunarDateConverter from './LunarDateConverter';
|
|
3
3
|
import holiday from './holidayData';
|
|
4
|
-
import {Holidays} from './types';
|
|
4
|
+
import { Holidays } from './types';
|
|
5
5
|
|
|
6
6
|
// @ts-ignore
|
|
7
7
|
const converter = new LunarDateConverter();
|
|
8
8
|
|
|
9
|
+
/** Moment as the `{ solarDay, solarMonth, solarYear }` converter input. */
|
|
9
10
|
const Solar = (momentDate: moment.Moment) => ({
|
|
10
11
|
solarDay: momentDate.date(),
|
|
11
12
|
solarMonth: momentDate.month() + 1,
|
|
12
13
|
solarYear: momentDate.year(),
|
|
13
14
|
});
|
|
14
15
|
|
|
15
|
-
const
|
|
16
|
-
|
|
16
|
+
const padTwoDigits = (value: number) => {
|
|
17
|
+
return value < 10 ? `0${value}` : `${value}`;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
const formatYYYYMMDD = (dd: number, mm: number, yyyy: any) => {
|
|
21
|
+
return `${yyyy}-${padTwoDigits(mm)}-${padTwoDigits(dd)}`;
|
|
22
|
+
};
|
|
17
23
|
|
|
18
|
-
const formatDDMM = (dd: number, mm: number) =>
|
|
19
|
-
`${dd
|
|
24
|
+
const formatDDMM = (dd: number, mm: number) => {
|
|
25
|
+
return `${padTwoDigits(dd)}/${padTwoDigits(mm)}`;
|
|
26
|
+
};
|
|
20
27
|
|
|
28
|
+
/**
|
|
29
|
+
* Groups holidays by DD/MM; a solar and a lunar holiday on the same day merge
|
|
30
|
+
* into one entry whose `mixedLabel` names both.
|
|
31
|
+
*/
|
|
21
32
|
const groupHolidaysByDate = (
|
|
22
|
-
holidays: Holidays[]
|
|
23
|
-
): {[key: string]: Holidays} => {
|
|
24
|
-
const groupedHolidays: {[key: string]: Holidays} = {};
|
|
33
|
+
holidays: Holidays[],
|
|
34
|
+
): { [key: string]: Holidays } => {
|
|
35
|
+
const groupedHolidays: { [key: string]: Holidays } = {};
|
|
25
36
|
if (holidays && holidays.length > 0) {
|
|
26
37
|
holidays.forEach(item => {
|
|
27
|
-
const {day, month, lunar, label} = item;
|
|
38
|
+
const { day, month, lunar, label } = item;
|
|
28
39
|
const key = formatDDMM(day, month);
|
|
29
40
|
let holidaysObj = { ...(groupedHolidays[key] || item) };
|
|
30
41
|
if (groupedHolidays[key]) {
|
|
@@ -49,28 +60,32 @@ const groupHolidaysByDate = (
|
|
|
49
60
|
return groupedHolidays;
|
|
50
61
|
};
|
|
51
62
|
|
|
52
|
-
/**
|
|
53
|
-
* Sort and group holidays by date, return sorted array of unique Holidays.
|
|
54
|
-
*/
|
|
63
|
+
/** Sorts holidays by date (in place) and merges those on the same day. */
|
|
55
64
|
const sortByDate = (arr: Holidays[]): Holidays[] => {
|
|
56
65
|
if (arr && arr.length > 1) {
|
|
57
|
-
arr.sort((a, b) =>
|
|
58
|
-
a.month !== b.month
|
|
59
|
-
|
|
66
|
+
arr.sort((a, b) => {
|
|
67
|
+
if (a.month !== b.month) {
|
|
68
|
+
return a.month - b.month;
|
|
69
|
+
}
|
|
70
|
+
return a.day - b.day;
|
|
71
|
+
});
|
|
60
72
|
}
|
|
61
|
-
//
|
|
73
|
+
// "DD/MM" keys aren't integer-like, so Object.values keeps the sorted order.
|
|
62
74
|
const grouped = groupHolidaysByDate(arr);
|
|
63
75
|
return Object.values(grouped);
|
|
64
76
|
};
|
|
65
77
|
|
|
78
|
+
/** Weekday/month i18n keys and holiday lookup for the calendar. */
|
|
66
79
|
const Utils = {
|
|
67
80
|
WEEKDAYSFROMMOMENT: ['sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat'],
|
|
68
81
|
|
|
82
|
+
/** i18n key of a weekday, 1 = Monday … 7 = Sunday. */
|
|
69
83
|
mapWeeKDate(i: number) {
|
|
70
84
|
const date = ['', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat', 'sun'];
|
|
71
85
|
return date[i];
|
|
72
86
|
},
|
|
73
87
|
|
|
88
|
+
/** i18n key of a month, 1 = January. */
|
|
74
89
|
mapMonth(i: number) {
|
|
75
90
|
const month = new Map([
|
|
76
91
|
[1, 'jan'],
|
|
@@ -89,9 +104,7 @@ const Utils = {
|
|
|
89
104
|
return month.get(i);
|
|
90
105
|
},
|
|
91
106
|
|
|
92
|
-
/**
|
|
93
|
-
* Get sorted list of holidays within the given month.
|
|
94
|
-
*/
|
|
107
|
+
/** Solar and lunar holidays in the month of `headerInfo`, sorted by date. */
|
|
95
108
|
getHolidaysInMonth(headerInfo: moment.Moment): Holidays[] {
|
|
96
109
|
if (headerInfo) {
|
|
97
110
|
const startDate = moment(headerInfo).startOf('month');
|
|
@@ -103,12 +116,11 @@ const Utils = {
|
|
|
103
116
|
const maxYear = maxLunarDate.lunarYear;
|
|
104
117
|
const currentYear = minYear !== maxYear ? [minYear, maxYear] : minYear;
|
|
105
118
|
|
|
106
|
-
// Handle Solar holidays
|
|
107
119
|
// @ts-ignore
|
|
108
120
|
if (holiday.solar[headerInfo.month() + 1]) {
|
|
109
121
|
// @ts-ignore
|
|
110
122
|
holiday.solar[headerInfo.month() + 1].forEach(
|
|
111
|
-
(date: {month: number; day: any}) => {
|
|
123
|
+
(date: { month: number; day: any }) => {
|
|
112
124
|
const dateAsMoment = moment({
|
|
113
125
|
year: headerInfo.year(),
|
|
114
126
|
month: date.month - 1,
|
|
@@ -117,11 +129,11 @@ const Utils = {
|
|
|
117
129
|
if (dateAsMoment.isBetween(startDate, endDate, 'day', '[]')) {
|
|
118
130
|
holidays.push(date);
|
|
119
131
|
}
|
|
120
|
-
}
|
|
132
|
+
},
|
|
121
133
|
);
|
|
122
134
|
}
|
|
123
135
|
|
|
124
|
-
holiday.lunar.forEach((item: {lunarDay: any; lunarMonth: any}) => {
|
|
136
|
+
holiday.lunar.forEach((item: { lunarDay: any; lunarMonth: any }) => {
|
|
125
137
|
if (currentYear instanceof Array) {
|
|
126
138
|
const solar1 = converter.LunarToSolar({
|
|
127
139
|
lunarDay: item.lunarDay,
|
|
@@ -134,14 +146,20 @@ const Utils = {
|
|
|
134
146
|
lunarYear: currentYear[1],
|
|
135
147
|
});
|
|
136
148
|
const solar1AsMoment = moment(
|
|
137
|
-
formatYYYYMMDD(
|
|
149
|
+
formatYYYYMMDD(
|
|
150
|
+
solar1.solarDay,
|
|
151
|
+
solar1.solarMonth,
|
|
152
|
+
solar1.solarYear,
|
|
153
|
+
),
|
|
138
154
|
);
|
|
139
155
|
const solar2AsMoment = moment(
|
|
140
|
-
formatYYYYMMDD(
|
|
156
|
+
formatYYYYMMDD(
|
|
157
|
+
solar2.solarDay,
|
|
158
|
+
solar2.solarMonth,
|
|
159
|
+
solar2.solarYear,
|
|
160
|
+
),
|
|
141
161
|
);
|
|
142
|
-
if (
|
|
143
|
-
solar1AsMoment.isBetween(startDate, endDate, 'day', '[]')
|
|
144
|
-
) {
|
|
162
|
+
if (solar1AsMoment.isBetween(startDate, endDate, 'day', '[]')) {
|
|
145
163
|
holidays.push({
|
|
146
164
|
...item,
|
|
147
165
|
day: solar1.solarDay,
|
|
@@ -163,11 +181,9 @@ const Utils = {
|
|
|
163
181
|
lunarYear: currentYear,
|
|
164
182
|
});
|
|
165
183
|
const solarAsMoment = moment(
|
|
166
|
-
formatYYYYMMDD(solar.solarDay, solar.solarMonth, solar.solarYear)
|
|
184
|
+
formatYYYYMMDD(solar.solarDay, solar.solarMonth, solar.solarYear),
|
|
167
185
|
);
|
|
168
|
-
if (
|
|
169
|
-
solarAsMoment.isBetween(startDate, endDate, 'day', '[]')
|
|
170
|
-
) {
|
|
186
|
+
if (solarAsMoment.isBetween(startDate, endDate, 'day', '[]')) {
|
|
171
187
|
holidays.push({
|
|
172
188
|
...item,
|
|
173
189
|
day: solar.solarDay,
|
package/index.tsx
CHANGED
|
@@ -16,19 +16,21 @@ import styles from './styles';
|
|
|
16
16
|
|
|
17
17
|
const DOUBLE = 'doubleDate';
|
|
18
18
|
|
|
19
|
+
/**
|
|
20
|
+
* Calendar with single or round-trip (`mode="doubleDate"`) selection, lunar
|
|
21
|
+
* dates, holidays and prices. Dates default to one year around today.
|
|
22
|
+
*/
|
|
19
23
|
const Calendar: React.FC<CalendarProps> = props => {
|
|
20
24
|
const { theme } = useContext(ApplicationContext);
|
|
21
25
|
const scaledHeight48 = useScaleSize(48);
|
|
22
26
|
const scaledHeight34 = useScaleSize(34);
|
|
23
27
|
|
|
24
|
-
// derive defaults for date bounds
|
|
25
28
|
const currentDate = new Date();
|
|
26
29
|
const minDateDefault = new Date(currentDate);
|
|
27
30
|
const maxDateDefault = new Date(currentDate);
|
|
28
31
|
minDateDefault.setFullYear(minDateDefault.getFullYear() - 1);
|
|
29
32
|
maxDateDefault.setFullYear(maxDateDefault.getFullYear() + 1);
|
|
30
33
|
|
|
31
|
-
// destructure all Calendar props
|
|
32
34
|
const {
|
|
33
35
|
mode,
|
|
34
36
|
id,
|
|
@@ -72,37 +74,31 @@ const Calendar: React.FC<CalendarProps> = props => {
|
|
|
72
74
|
const tabSelected = useRef<number>(id || 0);
|
|
73
75
|
|
|
74
76
|
const calendarPicker = useRef<CalendarProRef>(null);
|
|
75
|
-
// hold refs to TabHeader instances
|
|
76
77
|
const cellHeader1 = useRef<TabHeaderRef>(null);
|
|
77
78
|
const cellHeader2 = useRef<TabHeaderRef>(null);
|
|
78
79
|
const cellHeaderSingle = useRef<TabHeaderRef>(null);
|
|
79
80
|
|
|
80
|
-
// Initialize view on mount
|
|
81
81
|
useEffect(() => {
|
|
82
82
|
tabSelected.current = id || 0;
|
|
83
83
|
if (mode === DOUBLE) {
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
) {
|
|
84
|
+
const header1 = cellHeader1.current;
|
|
85
|
+
const header2 = cellHeader2.current;
|
|
86
|
+
const picker = calendarPicker.current;
|
|
87
|
+
if (header1 && header2 && picker) {
|
|
89
88
|
const start = doubleDate.current.first;
|
|
90
89
|
const end = doubleDate.current.second;
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
doubleDate.current.first,
|
|
95
|
-
doubleDate.current.second,
|
|
96
|
-
tabSelected.current,
|
|
97
|
-
);
|
|
90
|
+
header1.updateView(start, tabSelected.current === 0);
|
|
91
|
+
header2.updateView(end, tabSelected.current === 1);
|
|
92
|
+
picker.setDoubleDateAndTabIndex(start, end, tabSelected.current);
|
|
98
93
|
}
|
|
99
94
|
} else {
|
|
100
95
|
calendarPicker.current?.setDoubleDateAndTabIndex(selectedDate);
|
|
101
96
|
}
|
|
102
97
|
}, []);
|
|
103
98
|
|
|
104
|
-
const onLayout = (e: LayoutChangeEvent) =>
|
|
99
|
+
const onLayout = (e: LayoutChangeEvent) => {
|
|
105
100
|
setContainerWidth(e.nativeEvent.layout.width);
|
|
101
|
+
};
|
|
106
102
|
|
|
107
103
|
const onChangeTab = (tabId: number) => {
|
|
108
104
|
onChangeTabProp?.(tabId);
|
|
@@ -120,20 +116,16 @@ const Calendar: React.FC<CalendarProps> = props => {
|
|
|
120
116
|
const { onDateChange, onCTAStateChange } = props;
|
|
121
117
|
if (!cellHeader1.current || !cellHeader2.current || !calendarPicker.current)
|
|
122
118
|
return;
|
|
123
|
-
// set first date and reset second
|
|
124
119
|
doubleDate.current.first = selectedDate;
|
|
125
120
|
doubleDate.current.second = null;
|
|
126
121
|
tabSelected.current = 1;
|
|
127
|
-
// update headers
|
|
128
122
|
cellHeader1.current.updateView(selectedDate, false);
|
|
129
123
|
cellHeader2.current.updateView(null, true);
|
|
130
|
-
// update calendar
|
|
131
124
|
calendarPicker.current.setDoubleDateAndTabIndex(
|
|
132
125
|
doubleDate.current.first,
|
|
133
126
|
doubleDate.current.second,
|
|
134
127
|
tabSelected.current,
|
|
135
128
|
);
|
|
136
|
-
// notify parent
|
|
137
129
|
onDateChange?.({ first: doubleDate.current.first!, second: null });
|
|
138
130
|
onCTAStateChange?.(false);
|
|
139
131
|
};
|
|
@@ -142,7 +134,7 @@ const Calendar: React.FC<CalendarProps> = props => {
|
|
|
142
134
|
const { onDateChange, onCTAStateChange } = props;
|
|
143
135
|
if (!cellHeader1.current || !cellHeader2.current || !calendarPicker.current)
|
|
144
136
|
return;
|
|
145
|
-
//
|
|
137
|
+
// A date before the first one restarts the range.
|
|
146
138
|
if (selectedDate.isBefore(doubleDate.current.first!, 'day')) {
|
|
147
139
|
doubleDate.current.first = selectedDate;
|
|
148
140
|
doubleDate.current.second = null;
|
|
@@ -157,7 +149,6 @@ const Calendar: React.FC<CalendarProps> = props => {
|
|
|
157
149
|
onDateChange?.({ first: doubleDate.current.first!, second: null });
|
|
158
150
|
onCTAStateChange?.(false);
|
|
159
151
|
} else {
|
|
160
|
-
// valid second date
|
|
161
152
|
doubleDate.current.second = selectedDate;
|
|
162
153
|
tabSelected.current = 0;
|
|
163
154
|
cellHeader2.current.updateView(selectedDate, false);
|
|
@@ -189,7 +180,7 @@ const Calendar: React.FC<CalendarProps> = props => {
|
|
|
189
180
|
}
|
|
190
181
|
};
|
|
191
182
|
|
|
192
|
-
//
|
|
183
|
+
// Skip the mount run so the initial doubleDate props are kept.
|
|
193
184
|
const didMount = useRef(false);
|
|
194
185
|
|
|
195
186
|
useEffect(() => {
|
package/package.json
CHANGED
package/styles.ts
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
import {StyleSheet} from 'react-native';
|
|
2
|
-
import {Colors, Radius, Spacing} from '@momo-kits/foundation';
|
|
1
|
+
import { StyleSheet } from 'react-native';
|
|
2
|
+
import { Colors, Radius, Spacing } from '@momo-kits/foundation';
|
|
3
3
|
|
|
4
4
|
export default StyleSheet.create({
|
|
5
|
-
//calendar
|
|
6
5
|
viewPanel: {
|
|
7
6
|
flexDirection: 'row',
|
|
8
7
|
marginHorizontal: Spacing.M,
|
|
@@ -30,8 +29,7 @@ export default StyleSheet.create({
|
|
|
30
29
|
width: '100%',
|
|
31
30
|
},
|
|
32
31
|
|
|
33
|
-
|
|
34
|
-
row: {flexDirection: 'row'},
|
|
32
|
+
row: { flexDirection: 'row' },
|
|
35
33
|
txtMonthLunar: {
|
|
36
34
|
marginRight: Spacing.S,
|
|
37
35
|
},
|
|
@@ -69,7 +67,6 @@ export default StyleSheet.create({
|
|
|
69
67
|
backgroundColor: Colors.blue_05,
|
|
70
68
|
},
|
|
71
69
|
|
|
72
|
-
//headerControl
|
|
73
70
|
txtHeader: {
|
|
74
71
|
textAlign: 'center',
|
|
75
72
|
},
|
|
@@ -82,7 +79,6 @@ export default StyleSheet.create({
|
|
|
82
79
|
padding: Spacing.S,
|
|
83
80
|
},
|
|
84
81
|
|
|
85
|
-
//day
|
|
86
82
|
dayContainer: {
|
|
87
83
|
borderRadius: Radius.XS,
|
|
88
84
|
alignItems: 'center',
|