💄(react) add styling for range selection on a cell

Integrate new styling classes for grid-cells to facilitate range selection
in the DatePicker component. This implementation improves the visual
representation and user experience of selecting a range. In addition,
outside-month cells are now hidden, to avoid having a range selection
that contains outside-month cells.
This commit is contained in:
Lebaud Antoine
2023-06-14 19:38:17 +02:00
committed by aleb_the_flash
parent 87ec3a5061
commit 2886f0c992
9 changed files with 178 additions and 66 deletions

View File

@@ -4,41 +4,87 @@ import { useCalendarCell } from "@react-aria/calendar";
import {
CalendarDate,
getLocalTimeZone,
isSameDay,
isToday,
} from "@internationalized/date";
import { CalendarState } from "@react-stately/calendar";
import { CalendarState, RangeCalendarState } from "@react-stately/calendar";
import { Button } from ":/components/Button";
interface CalendarCellProps {
state: CalendarState;
state: CalendarState | RangeCalendarState;
date: CalendarDate;
}
const isRangeCalendar = (object: any): object is RangeCalendarState => {
return object?.highlightedRange;
};
export const CalendarCell = ({ state, date }: CalendarCellProps) => {
const ref = useRef<HTMLButtonElement>(null);
const { cellProps, buttonProps, isSelected, formattedDate } = useCalendarCell(
{ date },
state,
ref
);
const {
cellProps,
buttonProps,
isSelected,
formattedDate,
isOutsideVisibleRange,
isDisabled,
} = useCalendarCell({ date }, state, ref);
const isSelectionEnd =
isRangeCalendar(state) && isSameDay(date, state?.highlightedRange?.end);
const isSelectionStart =
isRangeCalendar(state) && isSameDay(date, state?.highlightedRange?.start);
const isWithinHighlightedRange =
isRangeCalendar(state) &&
state?.highlightedRange?.start <= date &&
state?.highlightedRange?.end >= date;
return (
<td {...cellProps}>
<Button
size="small"
color={isSelected ? "primary" : "tertiary"}
className={classNames("c__calendar__wrapper__grid__week-row__button", {
"c__calendar__wrapper__grid__week-row__button--selected": isSelected,
"c__calendar__wrapper__grid__week-row__button--today": isToday(
date,
getLocalTimeZone()
),
<div
hidden={isOutsideVisibleRange}
className={classNames({
"c__calendar__wrapper__grid__week-row__background--range--disabled":
isWithinHighlightedRange && isDisabled,
"c__calendar__wrapper__grid__week-row__background--range":
isWithinHighlightedRange,
"c__calendar__wrapper__grid__week-row__background--range--end":
isSelectionEnd,
"c__calendar__wrapper__grid__week-row__background--range--start":
isSelectionStart,
})}
disabled={!!cellProps["aria-disabled"]}
{...buttonProps}
ref={ref}
>
{formattedDate}
</Button>
<Button
size="small"
color={
(
isRangeCalendar(state)
? isSelectionStart || isSelectionEnd
: isSelected
)
? "primary"
: "tertiary"
}
className={classNames(
"c__calendar__wrapper__grid__week-row__button",
{
"c__calendar__wrapper__grid__week-row__button--selected":
isSelected,
"c__calendar__wrapper__grid__week-row__button--today": isToday(
date,
getLocalTimeZone()
),
}
)}
disabled={isDisabled}
{...buttonProps}
ref={ref}
>
{formattedDate}
</Button>
</div>
</td>
);
};