You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

116 lines
3.4 KiB
TypeScript

import React from 'react';
import { addDays, isSameDay } from 'date-fns';
import { WeekProps } from '../../../types/calendar';
import { Day } from '../Day';
import { getDateVariations } from '../../../utils/dateUtils';
import styles from './Week.module.scss';
import classNames from 'classnames';
export const Week: React.FC<WeekProps> = ({
startDate,
headerStyle,
monthCutoff,
referenceMonth,
weekendDays = [6, 0],
dateRange,
onDateSelect,
onDateHover,
size = 'l',
fontProportion = 100,
magnify = false,
activeColors,
activeDates = [],
colorScheme,
locale
}) => {
const allDays = Array.from({ length: 7 }, (_, i) => {
const date = addDays(startDate, i);
const isOtherMonth = date.getMonth() !== referenceMonth;
let variations = getDateVariations(date, dateRange, weekendDays, i);
// Check if this date is active
const isActive = activeDates.some(activeDate => isSameDay(activeDate, date));
if (isActive) {
variations = [...variations, 'active'] as typeof variations;
}
const wrapperClasses = classNames(
styles.Week__DayWrapper,
{
[styles['Week__DayWrapper--rangeStart']]: variations.includes('rangeStart'),
[styles['Week__DayWrapper--rangeEnd']]: variations.includes('rangeEnd'),
[styles['Week__DayWrapper--selected']]: variations.includes('selected'),
[styles['Week__DayWrapper--selecting']]: variations.includes('selecting'),
[styles['Week__DayWrapper--rowStart']]: variations.includes('rowStart'),
[styles['Week__DayWrapper--rowEnd']]: variations.includes('rowEnd')
}
);
if (monthCutoff && isOtherMonth) {
if (monthCutoff === 'truncate') {
return null;
}
return (
<div className={wrapperClasses} key={i}>
<Day
date={date}
headerStyle={headerStyle}
isOtherMonth={true}
variations={variations}
onSelect={onDateSelect ? () => onDateSelect(date) : undefined}
onHover={onDateHover ? () => onDateHover(date) : undefined}
size={size}
fontProportion={fontProportion}
magnify={magnify}
activeColors={activeColors}
colorScheme={colorScheme}
locale={locale}
/>
</div>
);
}
return (
<div className={wrapperClasses} key={i}>
<Day
date={date}
headerStyle={headerStyle}
variations={variations}
onSelect={onDateSelect ? () => onDateSelect(date) : undefined}
onHover={onDateHover ? () => onDateHover(date) : undefined}
size={size}
fontProportion={fontProportion}
magnify={magnify}
activeColors={activeColors}
colorScheme={colorScheme}
locale={locale}
/>
</div>
);
});
const firstValidIndex = allDays.findIndex(Boolean);
const lastValidIndex = allDays.length - [...allDays].reverse().findIndex(Boolean) - 1;
if (monthCutoff === 'truncate') {
const truncatedDays = Array.from({ length: 7 }, (_, i) => {
if (i < firstValidIndex || i > lastValidIndex) {
return <div key={i} className={styles.Week__EmptyCell} />;
}
return allDays[i];
});
return (
<div className={styles.Week__Container}>
{truncatedDays}
</div>
);
}
return (
<div className={styles.Week__Container}>
{allDays}
</div>
);
};