import XDate from 'xdate';
import React, { useRef, useMemo, useCallback, useContext } from 'react';
import { View } from 'react-native';
import isEqual from 'lodash/isEqual';
import omit from 'lodash/omit';
import { getPartialWeekDates, getWeekDates, sameMonth } from '../dateutils';
import { parseDate, toMarkingFormat } from '../interface';
import { getState } from '../day-state-manager';
import { extractDayProps } from '../componentUpdater';
import styleConstructor from './style';
import { CalendarProps } from '../calendar';
import Day from '../calendar/day/index';
import { CalendarContextProps } from './Context';
import { CustomDayContext } from '../../Day';
export type WeekProps = CalendarProps & {
context?: CalendarContextProps;
};
function arePropsEqual(prevProps: WeekProps, nextProps: WeekProps) {
const {
context: prevContext,
markedDates: prevMarkings,
...prevOthers
} = prevProps;
const {
context: nextContext,
markedDates: nextMarkings,
...nextOthers
} = nextProps;
return (
isEqual(prevContext, nextContext) &&
isEqual(prevMarkings, nextMarkings) &&
isEqual(
omit(prevOthers, ['customHeaderTitle']),
omit(nextOthers, ['customHeaderTitle'])
)
);
}
const Week = React.memo((props: WeekProps) => {
const {
theme,
current,
firstDay,
hideExtraDays,
markedDates,
onDayPress,
onDayLongPress,
style: propsStyle,
numberOfDays = 1,
timelineLeftInset,
testID,
} = props;
const style = useRef(styleConstructor(theme));
const disableDaySelection = useMemo(() => {
return !!numberOfDays && numberOfDays > 1;
}, [numberOfDays]);
const getWeek = useCallback(
(date?: string) => {
if (date) {
return getWeekDates(date, firstDay);
}
},
[firstDay]
);
const partialWeekStyle = useMemo(() => {
return [style.current.partialWeek, { paddingLeft: timelineLeftInset }];
}, [timelineLeftInset]);
const dayProps = extractDayProps(props);
const currXdate = useMemo(() => parseDate(current), [current]);
const { highlightDay } = useContext(CustomDayContext);
const renderDay = (day: XDate, id: number) => {
// hide extra days
if (current && hideExtraDays) {
if (!sameMonth(day, currXdate)) {
return ;
}
}
const dayString = toMarkingFormat(day);
return (
);
};
const renderWeek = () => {
const dates =
numberOfDays > 1
? getPartialWeekDates(current, numberOfDays)
: getWeek(highlightDay ?? current);
const week: JSX.Element[] = [];
if (dates) {
// @ts-ignore
const todayIndex = dates?.indexOf(parseDate(new Date())) || -1;
const sliced = dates.slice(todayIndex, numberOfDays);
const datesToRender =
numberOfDays > 1 && todayIndex > -1 ? sliced : dates;
datesToRender.forEach((day: XDate | string, id: number) => {
const d = day instanceof XDate ? day : new XDate(day);
week.push(renderDay(d, id));
}, this);
}
return week;
};
return (
1 ? partialWeekStyle : undefined,
propsStyle,
]}
>
{renderWeek()}
);
}, arePropsEqual);
export default Week;
Week.displayName = 'Week';