in packages/react/src/components/CalendarDayGrid/CalendarDayGrid.base.tsx [117:273]
function useWeekCornerStyles(props: ICalendarDayGridProps) {
/**
*
* Section for setting the rounded corner styles on individual day cells. Individual day cells need different
* corners to be rounded depending on which date range type and where the cell is located in the current grid.
* If we just round all of the corners, there isn't a good overlap and we get gaps between contiguous day boxes
* in Edge browser.
*
*/
const getWeekCornerStyles = (
classNames: IProcessedStyleSet<ICalendarDayGridStyles>,
initialWeeks: IDayInfo[][],
): IWeekCorners => {
const weekCornersStyled: { [key: string]: string } = {};
/* need to handle setting all of the corners on arbitrarily shaped blobs
__
__|A |
|B |C |__
|D |E |F |
in this case, A needs top left rounded, top right rounded
B needs top left rounded
C doesn't need any rounding
D needs bottom left rounded
E doesn't need any rounding
F needs top right rounding
*/
// cut off the animation transition weeks
const weeks = initialWeeks.slice(1, initialWeeks.length - 1);
// if there's an item above, lose both top corners. Item below, lose both bottom corners, etc.
weeks.forEach((week: IDayInfo[], weekIndex: number) => {
week.forEach((day: IDayInfo, dayIndex: number) => {
const above =
weeks[weekIndex - 1] &&
weeks[weekIndex - 1][dayIndex] &&
isInSameHoverRange(
weeks[weekIndex - 1][dayIndex].originalDate,
day.originalDate,
weeks[weekIndex - 1][dayIndex].isSelected,
day.isSelected,
);
const below =
weeks[weekIndex + 1] &&
weeks[weekIndex + 1][dayIndex] &&
isInSameHoverRange(
weeks[weekIndex + 1][dayIndex].originalDate,
day.originalDate,
weeks[weekIndex + 1][dayIndex].isSelected,
day.isSelected,
);
const left =
weeks[weekIndex][dayIndex - 1] &&
isInSameHoverRange(
weeks[weekIndex][dayIndex - 1].originalDate,
day.originalDate,
weeks[weekIndex][dayIndex - 1].isSelected,
day.isSelected,
);
const right =
weeks[weekIndex][dayIndex + 1] &&
isInSameHoverRange(
weeks[weekIndex][dayIndex + 1].originalDate,
day.originalDate,
weeks[weekIndex][dayIndex + 1].isSelected,
day.isSelected,
);
const style = [];
style.push(calculateRoundedStyles(classNames, above, below, left, right));
style.push(calculateBorderStyles(classNames, above, below, left, right));
weekCornersStyled[weekIndex + '_' + dayIndex] = style.join(' ');
});
});
return weekCornersStyled;
};
const calculateRoundedStyles = (
classNames: IProcessedStyleSet<ICalendarDayGridStyles>,
above: boolean,
below: boolean,
left: boolean,
right: boolean,
): string => {
const style = [];
const roundedTopLeft = !above && !left;
const roundedTopRight = !above && !right;
const roundedBottomLeft = !below && !left;
const roundedBottomRight = !below && !right;
if (roundedTopLeft) {
style.push(getRTL() ? classNames.topRightCornerDate : classNames.topLeftCornerDate);
}
if (roundedTopRight) {
style.push(getRTL() ? classNames.topLeftCornerDate : classNames.topRightCornerDate);
}
if (roundedBottomLeft) {
style.push(getRTL() ? classNames.bottomRightCornerDate : classNames.bottomLeftCornerDate);
}
if (roundedBottomRight) {
style.push(getRTL() ? classNames.bottomLeftCornerDate : classNames.bottomRightCornerDate);
}
return style.join(' ');
};
const calculateBorderStyles = (
classNames: IProcessedStyleSet<ICalendarDayGridStyles>,
above: boolean,
below: boolean,
left: boolean,
right: boolean,
): string => {
const style = [];
if (!above) {
style.push(classNames.datesAbove);
}
if (!below) {
style.push(classNames.datesBelow);
}
if (!left) {
style.push(getRTL() ? classNames.datesRight : classNames.datesLeft);
}
if (!right) {
style.push(getRTL() ? classNames.datesLeft : classNames.datesRight);
}
return style.join(' ');
};
const isInSameHoverRange = (date1: Date, date2: Date, date1Selected: boolean, date2Selected: boolean): boolean => {
const { dateRangeType, firstDayOfWeek, workWeekDays } = props;
// The hover state looks weird with non-contiguous days in work week view. In work week, show week hover state
const dateRangeHoverType = dateRangeType === DateRangeType.WorkWeek ? DateRangeType.Week : dateRangeType;
// we do not pass daysToSelectInDayView because we handle setting those styles dyanamically in onMouseOver
const dateRange = getDateRangeArray(date1, dateRangeHoverType, firstDayOfWeek, workWeekDays);
if (date1Selected !== date2Selected) {
// if one is selected and the other is not, they can't be in the same range
return false;
} else if (date1Selected && date2Selected) {
// if they're both selected at the same time they must be in the same range
return true;
}
// otherwise, both must be unselected, so check the dateRange
return dateRange.filter((date: Date) => date.getTime() === date2.getTime()).length > 0;
};
return [getWeekCornerStyles, calculateRoundedStyles] as const;
}