@cleartrip/ct-design-calendar 4.0.0 → 5.0.0

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.
Files changed (119) hide show
  1. package/dist/Arrow/LeftArrow.d.ts +3 -0
  2. package/dist/Arrow/LeftArrow.d.ts.map +1 -0
  3. package/dist/Arrow/RightArrow.d.ts +3 -0
  4. package/dist/Arrow/RightArrow.d.ts.map +1 -0
  5. package/dist/BaseCalendar.d.ts +4 -0
  6. package/dist/BaseCalendar.d.ts.map +1 -0
  7. package/dist/Calendar.d.ts +4 -0
  8. package/dist/Calendar.d.ts.map +1 -0
  9. package/dist/Calendar.native.d.ts +4 -0
  10. package/dist/Calendar.native.d.ts.map +1 -0
  11. package/dist/CalendarBody/LazyMonthList.d.ts +4 -0
  12. package/dist/CalendarBody/LazyMonthList.d.ts.map +1 -0
  13. package/dist/CalendarBody/PlaceholderMonth.d.ts +5 -0
  14. package/dist/CalendarBody/PlaceholderMonth.d.ts.map +1 -0
  15. package/dist/CalendarBody/index.d.ts +4 -0
  16. package/dist/CalendarBody/index.d.ts.map +1 -0
  17. package/dist/CalendarDayElements/CalendarDate.d.ts +4 -0
  18. package/dist/CalendarDayElements/CalendarDate.d.ts.map +1 -0
  19. package/dist/CalendarDayElements/CalendarDot.d.ts +4 -0
  20. package/dist/CalendarDayElements/CalendarDot.d.ts.map +1 -0
  21. package/dist/CalendarDayElements/CalendarDotWrapper.d.ts +5 -0
  22. package/dist/CalendarDayElements/CalendarDotWrapper.d.ts.map +1 -0
  23. package/dist/CalendarDayElements/CalendarRange.d.ts +4 -0
  24. package/dist/CalendarDayElements/CalendarRange.d.ts.map +1 -0
  25. package/dist/CalendarDayElements/index.d.ts +4 -0
  26. package/dist/CalendarDayElements/index.d.ts.map +1 -0
  27. package/dist/CalendarDayElements/useForceRerender.d.ts +5 -0
  28. package/dist/CalendarDayElements/useForceRerender.d.ts.map +1 -0
  29. package/dist/CalendarMonth/CalendarMonthBody.d.ts +4 -0
  30. package/dist/CalendarMonth/CalendarMonthBody.d.ts.map +1 -0
  31. package/dist/CalendarMonth/CalendarMonthFooter.d.ts +5 -0
  32. package/dist/CalendarMonth/CalendarMonthFooter.d.ts.map +1 -0
  33. package/dist/CalendarMonth/CalendarMonthHeader.d.ts +4 -0
  34. package/dist/CalendarMonth/CalendarMonthHeader.d.ts.map +1 -0
  35. package/dist/CalendarMonth/index.d.ts +12 -0
  36. package/dist/CalendarMonth/index.d.ts.map +1 -0
  37. package/dist/Caption/index.d.ts +4 -0
  38. package/dist/Caption/index.d.ts.map +1 -0
  39. package/dist/DayPicker.d.ts +62 -0
  40. package/dist/DayPicker.d.ts.map +1 -0
  41. package/dist/Footer/CheckinCheckout.d.ts +11 -0
  42. package/dist/Footer/CheckinCheckout.d.ts.map +1 -0
  43. package/dist/Footer/LongWeekend.d.ts +5 -0
  44. package/dist/Footer/LongWeekend.d.ts.map +1 -0
  45. package/dist/Footer/constants.d.ts +7 -0
  46. package/dist/Footer/constants.d.ts.map +1 -0
  47. package/dist/Footer/index.d.ts +14 -0
  48. package/dist/Footer/index.d.ts.map +1 -0
  49. package/dist/WeekDays.d.ts +3 -0
  50. package/dist/WeekDays.d.ts.map +1 -0
  51. package/dist/constants.d.ts +13 -0
  52. package/dist/constants.d.ts.map +1 -0
  53. package/dist/ct-design-calendar.browser.cjs.js +2 -0
  54. package/dist/ct-design-calendar.browser.cjs.js.map +1 -0
  55. package/dist/ct-design-calendar.browser.esm.js +2 -0
  56. package/dist/ct-design-calendar.browser.esm.js.map +1 -0
  57. package/dist/ct-design-calendar.cjs.js +67 -0
  58. package/dist/ct-design-calendar.cjs.js.map +1 -0
  59. package/dist/ct-design-calendar.esm.js +61 -0
  60. package/dist/ct-design-calendar.esm.js.map +1 -0
  61. package/dist/ct-design-calendar.umd.js +70 -0
  62. package/dist/ct-design-calendar.umd.js.map +1 -0
  63. package/dist/event/EventEmitter/index.d.ts +10 -0
  64. package/dist/event/EventEmitter/index.d.ts.map +1 -0
  65. package/dist/event/EventEmitter/type.d.ts +10 -0
  66. package/dist/event/EventEmitter/type.d.ts.map +1 -0
  67. package/dist/event/constants.d.ts +6 -0
  68. package/dist/event/constants.d.ts.map +1 -0
  69. package/dist/event/index.d.ts +8 -0
  70. package/dist/event/index.d.ts.map +1 -0
  71. package/dist/globalStyle.d.ts +2 -0
  72. package/dist/globalStyle.d.ts.map +1 -0
  73. package/dist/index.d.ts +4 -0
  74. package/dist/index.d.ts.map +1 -0
  75. package/dist/style.d.ts +2 -0
  76. package/dist/style.d.ts.map +1 -0
  77. package/dist/styles.d.ts +570 -0
  78. package/dist/styles.d.ts.map +1 -0
  79. package/dist/type.d.ts +58 -0
  80. package/dist/type.d.ts.map +1 -0
  81. package/dist/util.d.ts +22 -0
  82. package/dist/util.d.ts.map +1 -0
  83. package/package.json +32 -5
  84. package/src/Arrow/LeftArrow.tsx +13 -0
  85. package/src/Arrow/RightArrow.tsx +13 -0
  86. package/src/BaseCalendar.tsx +189 -0
  87. package/src/Calendar.native.tsx +99 -0
  88. package/src/Calendar.tsx +13 -0
  89. package/src/CalendarBody/LazyMonthList.tsx +45 -0
  90. package/src/CalendarBody/PlaceholderMonth.tsx +20 -0
  91. package/src/CalendarBody/index.tsx +159 -0
  92. package/src/CalendarDayElements/CalendarDate.tsx +34 -0
  93. package/src/CalendarDayElements/CalendarDot.tsx +11 -0
  94. package/src/CalendarDayElements/CalendarDotWrapper.tsx +17 -0
  95. package/src/CalendarDayElements/CalendarRange.tsx +54 -0
  96. package/src/CalendarDayElements/index.tsx +77 -0
  97. package/src/CalendarDayElements/useForceRerender.ts +14 -0
  98. package/src/CalendarMonth/CalendarMonthBody.tsx +39 -0
  99. package/src/CalendarMonth/CalendarMonthFooter.tsx +70 -0
  100. package/src/CalendarMonth/CalendarMonthHeader.tsx +15 -0
  101. package/src/CalendarMonth/index.tsx +43 -0
  102. package/src/Caption/index.tsx +39 -0
  103. package/src/DayPicker.tsx +324 -0
  104. package/src/Footer/CheckinCheckout.tsx +196 -0
  105. package/src/Footer/LongWeekend.tsx +98 -0
  106. package/src/Footer/constants.ts +7 -0
  107. package/src/Footer/index.tsx +84 -0
  108. package/src/WeekDays.tsx +20 -0
  109. package/src/constants.ts +54 -0
  110. package/src/event/EventEmitter/index.ts +34 -0
  111. package/src/event/EventEmitter/type.ts +10 -0
  112. package/src/event/constants.ts +5 -0
  113. package/src/event/index.tsx +21 -0
  114. package/src/globalStyle.ts +351 -0
  115. package/src/index.ts +3 -0
  116. package/src/style.ts +333 -0
  117. package/src/styles.ts +167 -0
  118. package/src/type.ts +66 -0
  119. package/src/util.ts +114 -0
@@ -0,0 +1,11 @@
1
+ import { memo } from 'react';
2
+
3
+ import { View } from 'react-native';
4
+
5
+ import { staticCalendarDotStyle } from '../styles';
6
+
7
+ export const CalendarDot = () => {
8
+ return <View style={staticCalendarDotStyle?.root} />;
9
+ };
10
+
11
+ export default memo(CalendarDot);
@@ -0,0 +1,17 @@
1
+ import { memo } from 'react';
2
+
3
+ import { View } from 'react-native';
4
+
5
+ import { staticCalendarDotStyle } from '../styles';
6
+ import CalendarDot from './CalendarDot';
7
+
8
+ const CalendarDotWrapper = ({ showDot }: { showDot: boolean }) => {
9
+ if (!showDot) return null;
10
+ return (
11
+ <View style={staticCalendarDotStyle.wrapper}>
12
+ <CalendarDot />
13
+ </View>
14
+ );
15
+ };
16
+
17
+ export default memo(CalendarDotWrapper);
@@ -0,0 +1,54 @@
1
+ import { memo } from 'react';
2
+
3
+ import { useForceRerender } from './useForceRerender';
4
+ import { useSubEvent } from '../event';
5
+ import { View } from 'react-native';
6
+
7
+ import { staticCalendarRangeStyles } from '../styles';
8
+ import { ICalendarRangeProps } from '../type';
9
+
10
+ const CalendarRange: React.FC<ICalendarRangeProps> = ({ getSelectedDates, date }) => {
11
+ const { forceRerender } = useForceRerender();
12
+
13
+ const getSingleRange = (selectedDates: string[]) => {
14
+ return selectedDates.filter((x) => x).length === 2 && date > selectedDates[0] && date < selectedDates[1];
15
+ };
16
+
17
+ const getLeftGrayed = (selectedDates: string[]) => {
18
+ return selectedDates.filter((x) => x).length === 2 && date === selectedDates[0];
19
+ };
20
+
21
+ const getRightGrayed = (selectedDates: string[]) => {
22
+ return selectedDates.filter((x) => x).length === 2 && date === selectedDates[1];
23
+ };
24
+
25
+ useSubEvent('SELECTED_DATES', ({ oldDates, newDates }: { oldDates: string[]; newDates: string[] }) => {
26
+ if (
27
+ getSingleRange(oldDates) !== getSingleRange(newDates) ||
28
+ getLeftGrayed(oldDates) !== getLeftGrayed(newDates) ||
29
+ getRightGrayed(oldDates) !== getRightGrayed(newDates)
30
+ ) {
31
+ forceRerender();
32
+ }
33
+ });
34
+
35
+ return (
36
+ <View style={staticCalendarRangeStyles?.root}>
37
+ {getSingleRange(getSelectedDates()) ? (
38
+ <View style={staticCalendarRangeStyles?.fullGrayed} />
39
+ ) : getLeftGrayed(getSelectedDates()) ? (
40
+ <>
41
+ <View style={staticCalendarRangeStyles?.halfNeutral} />
42
+ <View style={staticCalendarRangeStyles?.halfGrayed} />
43
+ </>
44
+ ) : getRightGrayed(getSelectedDates()) ? (
45
+ <>
46
+ <View style={staticCalendarRangeStyles?.halfGrayed} />
47
+ <View style={staticCalendarRangeStyles?.halfNeutral} />
48
+ </>
49
+ ) : null}
50
+ </View>
51
+ );
52
+ };
53
+
54
+ export default memo(CalendarRange);
@@ -0,0 +1,77 @@
1
+ import { memo } from 'react';
2
+
3
+ import { useForceRerender } from './useForceRerender';
4
+ import { useSubEvent } from '../event';
5
+ import { useNativeMergeStyles, useStyles } from '@cleartrip/ct-design-style-manager';
6
+ import { TouchableOpacity, ViewStyle } from 'react-native';
7
+
8
+ import CalendarRange from './CalendarRange';
9
+ import { formattedDate, getDateDifference, TODAY_DATE } from '../util';
10
+ import CalendarDate from './CalendarDate';
11
+ import { getSelectedDateStyles, staticCalendarDateWrapperStyles } from '../styles';
12
+ import { ICalendarDateWrapperProps } from '../type';
13
+
14
+ const CalendarDateWrapper: React.FC<ICalendarDateWrapperProps> = ({
15
+ year,
16
+ month,
17
+ day,
18
+ idxx,
19
+ getSelectedDates,
20
+ handleDateClicked,
21
+ calendarDotsList,
22
+ }) => {
23
+ const date = formattedDate(year, month, day);
24
+ const { forceRerender } = useForceRerender();
25
+
26
+ const isDisabled = (oldDates: string[]) => {
27
+ if (date < TODAY_DATE) {
28
+ return true;
29
+ }
30
+ if (oldDates.filter((x) => x).length === 1) {
31
+ const selectedDate = oldDates[0];
32
+ if (date < selectedDate || getDateDifference(date, selectedDate) > 30) {
33
+ return true;
34
+ }
35
+ }
36
+ return false;
37
+ };
38
+
39
+ useSubEvent('SELECTED_DATES', ({ oldDates, newDates }: { oldDates: string[]; newDates: string[] }) => {
40
+ if (oldDates.includes(date) !== newDates.includes(date) || isDisabled(oldDates) !== isDisabled(newDates)) {
41
+ forceRerender();
42
+ }
43
+ });
44
+
45
+ const dynamicCalendarDateStyles = useStyles(
46
+ (theme) => {
47
+ return {
48
+ root: getSelectedDateStyles(theme, isDisabled(getSelectedDates())),
49
+ };
50
+ },
51
+ [isDisabled(getSelectedDates())],
52
+ );
53
+
54
+ const touchableOpacityStyles = useNativeMergeStyles(
55
+ [dynamicCalendarDateStyles?.root, staticCalendarDateWrapperStyles?.root],
56
+ [dynamicCalendarDateStyles?.root],
57
+ );
58
+
59
+ return (
60
+ <TouchableOpacity
61
+ key={`day_${idxx}`}
62
+ style={touchableOpacityStyles as ViewStyle}
63
+ onPress={() => handleDateClicked(date)}
64
+ activeOpacity={1}
65
+ >
66
+ <CalendarRange getSelectedDates={getSelectedDates} date={date} />
67
+ <CalendarDate
68
+ day={day}
69
+ date={date}
70
+ isSelected={getSelectedDates().includes(date)}
71
+ calendarDotsList={calendarDotsList}
72
+ />
73
+ </TouchableOpacity>
74
+ );
75
+ };
76
+
77
+ export default memo(CalendarDateWrapper);
@@ -0,0 +1,14 @@
1
+ import { useCallback, useState } from 'react';
2
+
3
+ export function useForceRerender() {
4
+ const [_, set_] = useState(false);
5
+
6
+ const forceRerender = useCallback(() => {
7
+ set_((x) => !x);
8
+ }, [set_]);
9
+
10
+ return {
11
+ forceState: _,
12
+ forceRerender,
13
+ };
14
+ }
@@ -0,0 +1,39 @@
1
+ import { View } from 'react-native';
2
+
3
+ import { getWeekRow } from '../util';
4
+ import CalendarDateWrapper from '../CalendarDayElements';
5
+ import { staticCalendarMonthBodyStyles } from '../styles';
6
+ import { ICalendarMonthBodyProps } from '../type';
7
+
8
+ const CalendarMonthBody: React.FC<ICalendarMonthBodyProps> = ({
9
+ month,
10
+ year,
11
+ getSelectedDates,
12
+ handleDateClicked,
13
+ calendarDotsList,
14
+ }) => {
15
+ const weekRow = getWeekRow(parseInt(year), parseInt(month));
16
+
17
+ return weekRow.map((week, idx) => {
18
+ return (
19
+ <View key={`week_${idx}`} style={staticCalendarMonthBodyStyles?.root}>
20
+ {week.map((day, idxx) => {
21
+ return (
22
+ <CalendarDateWrapper
23
+ key={`day_${idxx}`}
24
+ year={year}
25
+ month={month}
26
+ day={day?.toString() || ''}
27
+ idxx={idxx}
28
+ getSelectedDates={getSelectedDates}
29
+ handleDateClicked={handleDateClicked}
30
+ calendarDotsList={calendarDotsList}
31
+ />
32
+ );
33
+ })}
34
+ </View>
35
+ );
36
+ });
37
+ };
38
+
39
+ export default CalendarMonthBody;
@@ -0,0 +1,70 @@
1
+ import { memo, useState } from 'react';
2
+
3
+ import Animated, { Easing, useAnimatedStyle, useSharedValue, withSpring, withTiming } from 'react-native-reanimated';
4
+ import { ChevronDown } from '@cleartrip/ct-design-icons';
5
+ import { Text, TouchableOpacity, View } from 'react-native';
6
+
7
+ import { ELEMENTS_HEIGHT } from '../util';
8
+ import { staticCalendarMonthFooterStyles } from '../styles';
9
+ import CalendarDot from '../CalendarDayElements/CalendarDot';
10
+
11
+ const CalendarMonthFooter = ({ holidays = [] }: { holidays: string[] }) => {
12
+ const [expanded, setExpanded] = useState(false);
13
+ const height = useSharedValue(0);
14
+ const rotation = useSharedValue(0);
15
+
16
+ const toggleAccordion = () => {
17
+ setExpanded((prev) => !prev);
18
+ height.value = expanded ? 0 : holidays.length * ELEMENTS_HEIGHT.HOLIDAY;
19
+ rotation.value = withTiming(expanded ? 0 : 180, {
20
+ duration: 300,
21
+ easing: Easing.ease,
22
+ });
23
+ };
24
+
25
+ const animatedStyle = useAnimatedStyle(() => {
26
+ return {
27
+ height: withSpring(height.value, {
28
+ damping: 20,
29
+ stiffness: 90,
30
+ }),
31
+ overflow: 'hidden',
32
+ gap: 4,
33
+ };
34
+ });
35
+
36
+ // @ts-ignore
37
+ const arrowStyle = useAnimatedStyle(() => {
38
+ return {
39
+ transform: [
40
+ {
41
+ rotate: `${rotation.value}deg`,
42
+ },
43
+ ],
44
+ };
45
+ });
46
+ if (holidays.length)
47
+ return (
48
+ <View style={staticCalendarMonthFooterStyles?.root}>
49
+ <TouchableOpacity onPress={toggleAccordion} style={staticCalendarMonthFooterStyles?.headingContainer}>
50
+ <CalendarDot />
51
+ <Text style={staticCalendarMonthFooterStyles?.heading}>{holidays.length} Holidays</Text>
52
+ <Animated.View style={arrowStyle}>
53
+ <ChevronDown width={16} height={16} />
54
+ </Animated.View>
55
+ </TouchableOpacity>
56
+
57
+ <View style={staticCalendarMonthFooterStyles.listContainer}>
58
+ <Animated.View style={animatedStyle}>
59
+ {holidays.map((holiday, index) => (
60
+ <Text key={index} style={staticCalendarMonthFooterStyles?.listItem}>
61
+ {holiday}
62
+ </Text>
63
+ ))}
64
+ </Animated.View>
65
+ </View>
66
+ </View>
67
+ );
68
+ };
69
+
70
+ export default memo(CalendarMonthFooter);
@@ -0,0 +1,15 @@
1
+ import { memo } from 'react';
2
+
3
+ import { Text, TextStyle } from 'react-native';
4
+
5
+ import { IMonthListObj } from '../type';
6
+ import { staticCalendarMonthHeaderStyles } from '../styles';
7
+ import { MONTHS } from '../util';
8
+
9
+ const MonthHeader: React.FC<IMonthListObj> = ({ month, year }) => {
10
+ return (
11
+ <Text style={staticCalendarMonthHeaderStyles.root as TextStyle}>{`${MONTHS[parseInt(month) - 1]} ${year}`}</Text>
12
+ );
13
+ };
14
+
15
+ export default memo(MonthHeader);
@@ -0,0 +1,43 @@
1
+ import { memo } from 'react';
2
+
3
+ import { View } from 'react-native';
4
+
5
+ import CalendarMonthFooter from './CalendarMonthFooter';
6
+ import CalendarMonthHeader from './CalendarMonthHeader';
7
+ import CalendarMonthBody from './CalendarMonthBody';
8
+
9
+ interface ICalendarDatesProps {
10
+ year: string;
11
+ month: string;
12
+ onLayout: () => void;
13
+ holidayList: Record<string, Record<string, string[]>>;
14
+ calendarDotsList: string[];
15
+ getSelectedDates: () => string[];
16
+ handleDateClicked: (date: string) => void;
17
+ }
18
+
19
+ const CalendarDates: React.FC<ICalendarDatesProps> = ({
20
+ year,
21
+ month,
22
+ onLayout,
23
+ holidayList,
24
+ calendarDotsList,
25
+ getSelectedDates,
26
+ handleDateClicked,
27
+ }) => {
28
+ return (
29
+ <View onLayout={onLayout}>
30
+ <CalendarMonthHeader month={month} year={year} />
31
+ <CalendarMonthBody
32
+ month={month}
33
+ year={year}
34
+ handleDateClicked={handleDateClicked}
35
+ getSelectedDates={getSelectedDates}
36
+ calendarDotsList={calendarDotsList}
37
+ />
38
+ <CalendarMonthFooter holidays={holidayList?.[year]?.[parseInt(month) - 1] || []} />
39
+ </View>
40
+ );
41
+ };
42
+
43
+ export default memo(CalendarDates);
@@ -0,0 +1,39 @@
1
+ import React from 'react';
2
+ import { CaptionProps, useDayPicker } from 'react-day-picker';
3
+ import { Container } from '@cleartrip/ct-design-container';
4
+ import { Typography } from '@cleartrip/ct-design-typography';
5
+ import { makeStyles } from '@cleartrip/ct-design-style-manager';
6
+
7
+ const styles = makeStyles((theme) => ({
8
+ outerContainer: {
9
+ display: 'flex',
10
+ flexDirection: 'row',
11
+ marginTop: theme.spacing[10],
12
+ marginBottom: theme.spacing[4],
13
+ },
14
+ innerContainer: {
15
+ width: '100%',
16
+ display: 'flex',
17
+ justifyContent: 'center',
18
+ },
19
+ typography: {
20
+ fontWeight: 600,
21
+ },
22
+ }));
23
+
24
+ export const Caption = (props: CaptionProps): React.JSX.Element => {
25
+ const {
26
+ locale,
27
+ formatters: { formatCaption },
28
+ } = useDayPicker();
29
+
30
+ return (
31
+ <Container styleConfig={{ root: [styles.outerContainer] }}>
32
+ <Container styleConfig={{ root: [styles.innerContainer] }}>
33
+ <Typography variant='B1' styleConfig={{ root: [styles.typography] }}>
34
+ {formatCaption(props.displayMonth, { locale })}
35
+ </Typography>
36
+ </Container>
37
+ </Container>
38
+ );
39
+ };