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
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>
|
|
);
|
|
};
|