shadcn-ui / ui

Beautifully designed components that you can copy and paste into your apps. Accessible. Customizable. Open Source.
https://ui.shadcn.com
MIT License
71.1k stars 4.28k forks source link

Calendar mode="range" (Regarding month and year selection) #2365

Closed Sandeep13-web closed 3 months ago

Sandeep13-web commented 9 months ago

Is there any way to change year in the calendar? If i want to select a range suppose from 2021 to 2024 then it's a bit lengthy process since we need to keep clicking back into it. If there is any way please let me know. Thankyou.

tinncdev commented 9 months ago

you can set numberOfMonths={36} (see reference) to show all 36 months across 3 years at once

or better just show 2 range calendar like [first month] ... [last month] if there's no additional info in the month between.

Sandeep13-web commented 9 months ago

What i want is i want is to be able to change the year with ease as well. Supppose when i open the range picker, i am in todays date (Jan 10,2024). But i want the 'from' (being in state date ({from: ... , to: ..}) to be selected in the year 2021. Then to achieve this right now i have to keep clicking the navigation button. What i want is easy changeable year.

tinncdev commented 9 months ago

That job belongs to the underline library react-day-picker

I think you should disable the default (month) navigation and manage it by your own component state with the library navigation api https://react-day-picker.js.org/basics/navigation

Something like this

export type CalendarYearViewProps = {
  initialDate: Date;
};

export default function CalendarYearView(props: CalendarYearViewProps) {
  const [date, setDate] = useState<Date>(props.initialDate);

  const goToPreviousYear = () => {
    setDate(sub(date, { years: 1 }));
  };

  const goToNextYear = () => {
    setDate(add(date, { years: 1 }));
  };

  return (
    <div>
      <div className="flex justify-between py-4">
        <Button onClick={goToPreviousYear}>Previous year</Button>
        <Button onClick={goToNextYear}>Next year</Button>
      </div>
      <Calendar
        month={date}
        numberOfMonths={12}
        disableNavigation
      />
    </div>
  );
}
alamenai commented 8 months ago

You may need to pass fromYear, toYear and captionLayout props:

Example

   <Popover>
      <PopoverTrigger asChild>
        <Button
          variant={"outline"}
          className={cn(
            "w-[280px] justify-start text-left font-normal",
            !date && "text-muted-foreground"
          )}
        >
          <CalendarIcon className="mr-2 h-4 w-4" />
          {date ? format(date, "PPP") : <span>Pick a date</span>}
        </Button>
      </PopoverTrigger>
      <PopoverContent className="w-auto p-0">
        <Calendar
          mode="single"
          selected={date}
          onSelect={setDate}
          initialFocus
          fromYear={2023}
          toYear={2030}
          captionLayout="dropdown"
        />
        <Calendar
          mode="single"
          selected={date}
          onSelect={setDate}
          initialFocus
          fromYear={2023}
          toYear={2030}
          captionLayout="dropdown"
        />
      </PopoverContent>
    </Popover>
josefonte commented 7 months ago

i was looking for a solution similar to this. i tried to code it myself but i can't achieve the desired functionality. any tips?

image
shadcn commented 3 months ago

This issue has been automatically closed because it received no activity for a while. If you think it was closed by accident, please leave a comment. Thank you.