Skip to content

Year selection when range selected broken. #19

@relentlessreforged

Description

@relentlessreforged

When calendar mode is set to "Range" and both start and end date selected, selecting a year to navigate to in the year selector throws error getMonth() does not exist on selected. . Issue is the "selected" can be a date or an array of dates depending on mode. Here is the code in question.

goToMonth(
                  new Date(
                    displayYears.from + i,
                    (selected as Date | undefined)?.getMonth() ?? 0. 
                  )
                )

A sample solution would be to introduce a generic for type safety on the hook, then to check for type of selection during the attempt to get the month. For example.

function YearGrid<T extends DayPickerProps>({
  className,
  displayYears,
  startMonth,
  endMonth,
  setNavView,
  navView,
  ...props
}: {
  className?: string;
  displayYears: { from: number; to: number };
  startMonth?: Date;
  endMonth?: Date;
  setNavView: React.Dispatch<React.SetStateAction<NavView>>;
  navView: NavView;
} & React.HTMLAttributes<HTMLDivElement>) {
  const { goToMonth, selected } = useDayPicker<T>();

  return (
    <div className={cn("grid grid-cols-4 gap-y-2", className)} {...props}>
      {Array.from(
        { length: displayYears.to - displayYears.from + 1 },
        (_, i) => {
          const isBefore =
            differenceInCalendarDays(
              new Date(displayYears.from + i, 11, 31),
              startMonth!,
            ) < 0;

          const isAfter =
            differenceInCalendarDays(
              new Date(displayYears.from + i, 0, 0),
              endMonth!,
            ) > 0;

          const isDisabled = isBefore || isAfter;
          return (
            <Button
              key={i}
              className={cn(
                "h-7 w-full text-sm font-normal text-foreground",
                displayYears.from + i === new Date().getFullYear() &&
                  "bg-accent font-medium text-accent-foreground",
              )}
              variant="ghost"
              onClick={() => {
                setNavView("days");

                const endDate =
                  Array.isArray(selected) && selected.length > 0
                    ? selected[0]
                    : selected;

                const month = endDate instanceof Date ? endDate.getMonth() : 0;
                goToMonth(new Date(displayYears.from + i, month));
              }}
              disabled={navView === "years" ? isDisabled : undefined}
            >
              {displayYears.from + i}
            </Button>
          );
        },
      )}
    </div>
  );
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions