ui icon indicating copy to clipboard operation
ui copied to clipboard

[bug]: react-day-picker 9.0.0 release screws up Calendar component

Open gregpr07 opened this issue 1 year ago • 37 comments

Describe the bug

CleanShot 2024-07-21 at 17 46 51@2x

Currently, the component looks like this.

Fix: You can currently fix this by downgrading react-day-picker to version 8.^

Affected component/components

Calendar, Date Picker, ...

How to reproduce

  1. Install Calendar component

Codesandbox/StackBlitz link

No response

Logs

No response

System Info

Browsers

Before submitting

  • [X] I've made research efforts and searched the documentation
  • [X] I've searched for existing issues

gregpr07 avatar Jul 21 '24 15:07 gregpr07

Easiest solution right now is to downgrade to 8.10.1. The react-day-picker team has already been notified of this issue in the v9.0.0 release announcement

Cheveniko avatar Jul 21 '24 16:07 Cheveniko

Here are my adjusted styles for the Calendar component: https://github.com/grzegorzpokorski/calendar-shadcnnui/blob/main/src/components/ui/calendar.tsx. Maybe someone will have more time to review them and improve.

The most intriguing aspect is the change in the structure of this component, particularly the navigation between months. I am not sure if the current design is appropriate (playing with z-index).

grzegorzpokorski avatar Jul 21 '24 17:07 grzegorzpokorski

Here are my adjusted styles for the Calendar component: https://github.com/grzegorzpokorski/calendar-shadcnnui/blob/main/src/components/ui/calendar.tsx. Maybe someone will have more time to review them and improve.

The most intriguing aspect is the change in the structure of this component, particularly the navigation between months. I am not sure if the current design is appropriate (playing with z-index).

OK, I'm using your code. When making adjustments to my code and not finding another solution for positioning the navigation buttons, I used the z-index

efgomes avatar Jul 21 '24 19:07 efgomes

same bug ((

NamorAgro avatar Jul 23 '24 09:07 NamorAgro

Easiest solution right now is to downgrade to 8.10.1. The react-day-picker team has already been notified of this issue in the v9.0.0 release announcement

npx [email protected] add calendar gives error, no such version matching

NamorAgro avatar Jul 23 '24 09:07 NamorAgro

Easiest solution right now is to downgrade to 8.10.1. The react-day-picker team has already been notified of this issue in the v9.0.0 release announcement

npx [email protected] add calendar gives error, no such version matching

The dependency is on react-day-picker. Go to your package.json and set the 8.10.1 there and then run npm install

olsio avatar Jul 23 '24 09:07 olsio

fixed here https://github.com/shadcn-ui/ui/pull/4421

flixlix avatar Jul 26 '24 13:07 flixlix

While waiting for the update, you can try this.

https://shadcn-datetime-picker-pro.vercel.app/ https://github.com/huybuidac/shadcn-datetime-picker

image

huybuidac avatar Oct 18 '24 07:10 huybuidac

Any update when the latest version of react-day-picker will be supported?

kamami avatar Oct 29 '24 12:10 kamami

any update on this?

kulterryan avatar Jan 27 '25 09:01 kulterryan

It will never get fixed. There are 850 open PRs with zero movement on maintenance. So you can only fix it for your own project and move on. I stopped contributing a while back. Nothing gets accepted.

olsio avatar Jan 27 '25 09:01 olsio

Half a year and 9.*.* still mess styles of 8.*.*

AnatoliiCubex avatar Jan 30 '25 11:01 AnatoliiCubex

Hi everyone! 👋

I’m excited to share an extension library I’ve built for shadcn/ui, which includes a DatePicker reusable component. The calendar styling is updated and fixed, supporting "react-day-picker": ^9. It also supports additional features like Dropdown Layout.

You can check out the DatePicker component here: https://ui-x.junwen-k.dev/docs/components/date-picker

It also supports segmented date inputs using timescape. 🚀

The library also includes other handy components designed to enhance developer productivity. If you find it helpful, I’d be thrilled if you could leave a star—it really helps others discover the project. I’d love to hear your feedback or suggestions, so feel free to share your thoughts! 😊

junwen-k avatar Feb 03 '25 14:02 junwen-k

I found something here: https://date-picker.luca-felix.com/ The guy did a beautiful job. I hope it helps you too.

rylder avatar Feb 04 '25 19:02 rylder

I found something here: https://date-picker.luca-felix.com/ The guy did a beautiful job. I hope it helps you too.

Have you try this one https://shadcn-datetime-picker-pro.vercel.app?

huybuidac avatar Feb 05 '25 03:02 huybuidac

I found something here: https://date-picker.luca-felix.com/ The guy did a beautiful job. I hope it helps you too.

Have you try this one https://shadcn-datetime-picker-pro.vercel.app?

I took a look, but I just needed the calendar styles corrected. I already have my DatePicker component and just wanted to fix the style compatibility issue. At another time, I will certainly test your component in my applications.

rylder avatar Feb 05 '25 12:02 rylder

I found something here: https://date-picker.luca-felix.com/ The guy did a beautiful job. I hope it helps you too.

This is also the recommendation in the docs.

tylerbecks avatar Feb 14 '25 18:02 tylerbecks

I think we might get lucky and get an official fix as collateral. I think they are working on a tailwind 4 migration and will touch all the components.

olsio avatar Feb 15 '25 14:02 olsio

How long its going to take ? None of above solution are working.

rahulcse1 avatar Apr 02 '25 20:04 rahulcse1

How long its going to take ? None of above solution are working.

For now, I used his approach: https://date-picker.luca-felix.com/

Thanks you @rylder and @tylerbecks for the comments: https://github.com/shadcn-ui/ui/issues/4366#issuecomment-2634864152 https://github.com/shadcn-ui/ui/issues/4366#issuecomment-2659984116

fekete965 avatar Apr 03 '25 11:04 fekete965

How long its going to take ? None of above solution are working.

For now, I used his approach: https://date-picker.luca-felix.com/

Thanks you @rylder and @tylerbecks for the comments: #4366 (comment) #4366 (comment)

The year selection for the range input does not seem to be working.

kamami avatar Apr 03 '25 15:04 kamami

` import * as React from "react"; import { ChevronLeft, ChevronRight } from "lucide-react"; import { DayPicker } from "react-day-picker";

import { cn } from "@/lib/utils";

export type CalendarProps = React.ComponentProps<typeof DayPicker>;

function Calendar({ className, classNames, showOutsideDays = true, ...props }: CalendarProps) { return ( <DayPicker showOutsideDays={showOutsideDays} className={cn("p-3", className)} classNames={{ months: "flex flex-col sm:flex-row space-y-4 sm:space-y-0", month: "space-y-4 ", month_caption: "flex justify-center pt-1 relative items-center", caption_label: "text-sm font-medium", // nav: "space-x-1 flex items-center", button_next: cn( "inline-flex items-center justify-center gap-2 rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0 border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground h-9 px-4 py-2", "h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100", "absolute right-5 z-50" ), button_previous: cn( "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0 border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground h-9 px-4 py-2", "h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100", "absolute left-5 z-50" ), month_grid: "w-full border-collapse space-y-1", weekdays: "flex", weekday: "text-muted-foreground rounded-md w-8 font-normal text-[0.8rem]", week: "flex w-full mt-2", day: cn( "relative p-0 text-center text-sm focus-within:relative focus-within:z-20 [&:has([aria-selected])]:bg-accent [&:has([aria-selected].day-outside)]:bg-accent/50 [&:has([aria-selected].day-range-end)]:rounded-r-md", props.mode === "range" ? "[&:has(>.day-range-end)]:rounded-r-md [&:has(>.day-range-start)]:rounded-l-md first:[&:has([aria-selected])]:rounded-l-md last:[&:has([aria-selected])]:rounded-r-md" : "[&:has([aria-selected])]:rounded-md" ), day_button: cn( "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0 hover:bg-accent hover:text-accent-foreground", "h-8 w-8 p-0 font-normal aria-selected:opacity-100" ), range_start: "day-range-start", range_end: "day-range-end", selected: "bg-primary text-primary-foreground hover:bg-primary hover:text-primary-foreground focus:bg-primary focus:text-primary-foreground", today: "bg-accent text-accent-foreground", outside: "day-outside text-muted-foreground aria-selected:bg-accent/50 aria-selected:text-muted-foreground", disabled: "text-muted-foreground opacity-50", range_middle: "aria-selected:bg-accent aria-selected:text-accent-foreground", hidden: "invisible", ...classNames, }} components={{ Chevron: (props) => { if (props.orientation === "left") { return ( <ChevronLeft className={cn("h-4 w-4", className)} {...props} /> ); } return ( <ChevronRight className={cn("h-4 w-4", className)} {...props} /> ); }, }} {...props} /> ); } Calendar.displayName = "Calendar";

export { Calendar }; `

here is a code to fix the Calendar component

ha280 avatar Apr 04 '25 19:04 ha280

bing bong it's April 420 blaze it coming up

daveycodez avatar Apr 05 '25 21:04 daveycodez

Here are my adjusted styles for the Calendar component: https://github.com/grzegorzpokorski/calendar-shadcnnui/blob/main/src/components/ui/calendar.tsx. Maybe someone will have more time to review them and improve.

The most intriguing aspect is the change in the structure of this component, particularly the navigation between months. I am not sure if the current design is appropriate (playing with z-index).

Thanks mate

rlawrence89 avatar Apr 06 '25 20:04 rlawrence89

import * as React from "react"; import { ChevronLeft, ChevronRight } from "lucide-react"; import { DayPicker } from "react-day-picker";

import { cn } from "@/lib/utils";

export type CalendarProps = React.ComponentProps;

function Calendar({ className, classNames, showOutsideDays = true, ...props }: CalendarProps) { return ( <DayPicker showOutsideDays={showOutsideDays} className={cn("p-3", className)} classNames={{ months: "flex flex-col sm:flex-row space-y-4 sm:space-y-0", month: "space-y-4 ", month_caption: "flex justify-center pt-1 relative items-center", caption_label: "text-sm font-medium", // nav: "space-x-1 flex items-center", button_next: cn( "inline-flex items-center justify-center gap-2 rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0 border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground h-9 px-4 py-2", "h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100", "absolute right-5 z-50" ), button_previous: cn( "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0 border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground h-9 px-4 py-2", "h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100", "absolute left-5 z-50" ), month_grid: "w-full border-collapse space-y-1", weekdays: "flex", weekday: "text-muted-foreground rounded-md w-8 font-normal text-[0.8rem]", week: "flex w-full mt-2", day: cn( "relative p-0 text-center text-sm focus-within:relative focus-within:z-20 [&:has([aria-selected])]:bg-accent [&:has([aria-selected].day-outside)]:bg-accent/50 [&:has([aria-selected].day-range-end)]:rounded-r-md", props.mode === "range" ? "[&:has(>.day-range-end)]:rounded-r-md [&:has(>.day-range-start)]:rounded-l-md first:[&:has([aria-selected])]:rounded-l-md last:[&:has([aria-selected])]:rounded-r-md" : "[&:has([aria-selected])]:rounded-md" ), day_button: cn( "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0 hover:bg-accent hover:text-accent-foreground", "h-8 w-8 p-0 font-normal aria-selected:opacity-100" ), range_start: "day-range-start", range_end: "day-range-end", selected: "bg-primary text-primary-foreground hover:bg-primary hover:text-primary-foreground focus:bg-primary focus:text-primary-foreground", today: "bg-accent text-accent-foreground", outside: "day-outside text-muted-foreground aria-selected:bg-accent/50 aria-selected:text-muted-foreground", disabled: "text-muted-foreground opacity-50", range_middle: "aria-selected:bg-accent aria-selected:text-accent-foreground", hidden: "invisible", ...classNames, }} components={{ Chevron: (props) => { if (props.orientation === "left") { return ( <ChevronLeft className={cn("h-4 w-4", className)} {...props} /> ); } return ( <ChevronRight className={cn("h-4 w-4", className)} {...props} /> ); }, }} {...props} /> ); } Calendar.displayName = "Calendar";

export { Calendar };

Thank you bro, it works for me

imjatinx avatar Apr 16 '25 05:04 imjatinx

I managed to make styles work also for date range picker or multiple months with the current react-day-picker v9.6.7.

Image

This is the code I use:

import { buttonVariants } from "@/components/ui/button";
import { cn } from "@/lib/utils";
import { ChevronLeft, ChevronRight } from "lucide-react";
import type { ComponentProps } from "react";
import { DayPicker } from "react-day-picker";

export type CalendarProps = ComponentProps<typeof DayPicker>;

function Calendar({ className, classNames, showOutsideDays = true, ...props }: CalendarProps) {
  return (
    <DayPicker
      showOutsideDays={showOutsideDays}
      className={cn("p-3", className)}
      classNames={{
        month: "space-y-4",
        months: "flex flex-col sm:flex-row space-y-4 sm:space-y-0 relative gap-2",
        month_caption: "flex justify-center pt-1 relative items-center",
        month_grid: "w-full border-collapse space-y-1",
        caption_label: "text-sm font-medium",
        nav: "flex items-center justify-between absolute inset-x-0",
        button_previous: cn(buttonVariants({ variant: "outline" }), "h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100 z-10"),
        button_next: cn(buttonVariants({ variant: "outline" }), "h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100 z-10"),
        weeks: "w-full border-collapse",
        weekdays: "flex",
        weekday: "text-muted-foreground rounded-md w-9 font-normal text-[0.8rem]",
        week: "flex w-full mt-2",
        day: "h-9 w-9 p-0 font-normal aria-selected:opacity-100 rounded-none first:aria-selected:rounded-l-md last:aria-selected:rounded-r-md",
        day_button: cn(
          buttonVariants({ variant: "ghost" }),
          "h-9 w-9 text-center text-sm p-0 relative focus-within:relative focus-within:z-20",
        ),
        range_start:
          "day-range-start !bg-accent rounded-l-md [&>button]:bg-primary [&>button]:text-primary-foreground [&>button]:hover:bg-primary [&>button]:hover:text-primary-foreground",
        range_end:
          "day-range-end !bg-accent rounded-r-md [&>button]:bg-primary [&>button]:text-primary-foreground [&>button]:hover:bg-primary [&>button]:hover:text-primary-foreground",
        range_middle: "aria-selected:bg-accent aria-selected:text-accent-foreground",
        day_selected:
          "bg-primary text-primary-foreground hover:bg-primary hover:text-primary-foreground focus:bg-primary focus:text-primary-foreground",
        day_today: "bg-accent text-accent-foreground",
        day_outside: "day-outside text-muted-foreground aria-selected:text-muted-foreground",
        day_disabled: "text-muted-foreground opacity-50",
        day_hidden: "invisible",
        selected:
          "bg-primary text-primary-foreground hover:bg-primary hover:text-primary-foreground focus:bg-primary focus:text-primary-foreground",
        today: "bg-accent text-accent-foreground",
        outside:
          "day-outside text-muted-foreground opacity-50 !aria-selected:bg-accent/50 !aria-selected:text-muted-foreground !aria-selected:opacity-30",
        disabled: "text-muted-foreground opacity-50",
        hidden: "invisible",
        ...classNames,
      }}
      components={{
        Chevron: ({ ...props }) =>
          props.orientation === "left" ? <ChevronLeft {...props} className="h-4 w-4" /> : <ChevronRight {...props} className="h-4 w-4" />,
      }}
      {...props}
    />
  );
}
Calendar.displayName = "Calendar";

export { Calendar };

jkuri avatar Apr 21 '25 13:04 jkuri

Thanks @jkuri ! I did some small tweaks to make it work for both range and single mode. And also I removed deprecated classes.

         range_end:
           "day-range-end !bg-accent rounded-r-md [&>button]:bg-primary [&>button]:text-primary-foreground [&>button]:hover:bg-primary [&>button]:hover:text-primary-foreground",
         range_middle: "aria-selected:bg-accent aria-selected:text-accent-foreground",
-        day_selected:
-          "bg-primary text-primary-foreground hover:bg-primary hover:text-primary-foreground focus:bg-primary focus:text-primary-foreground",
-        day_today: "bg-accent text-accent-foreground",
-        day_outside: "day-outside text-muted-foreground aria-selected:text-muted-foreground",
-        day_disabled: "text-muted-foreground opacity-50",
-        day_hidden: "invisible",
-        selected:
-          "bg-primary text-primary-foreground hover:bg-primary hover:text-primary-foreground focus:bg-primary focus:text-primary-foreground",
-        today: "bg-accent text-accent-foreground",
+        selected: cn(
+          props.mode === "range"
+            ? "bg-primary hover:bg-primary hover:text-primary-foreground focus:bg-primary focus:text-primary-foreground"
+            : "[&>button]:focus:bg-primary [&>button]:focus:text-primary-foreground",
+        ),
+        today: "bg-accent text-accent-foreground !rounded-md",
         outside:
           "day-outside text-muted-foreground opacity-50 !aria-selected:bg-accent/50 !aria-selected:text-muted-foreground !aria-selected:opacity-30",
         disabled: "text-muted-foreground opacity-50",

Complete file looks like this:

import { buttonVariants } from "@/components/ui/button";
import { cn } from "@/lib/utils";
import { ChevronLeft, ChevronRight } from "lucide-react";
import type { ComponentProps } from "react";
import { DayPicker } from "react-day-picker";

export type CalendarProps = ComponentProps<typeof DayPicker>;

function Calendar({ className, classNames, showOutsideDays = true, ...props }: CalendarProps) {
  return (
    <DayPicker
      showOutsideDays={showOutsideDays}
      className={cn("p-3", className)}
      classNames={{
        month: "space-y-4",
        months: "flex flex-col sm:flex-row space-y-4 sm:space-y-0 relative gap-2",
        month_caption: "flex justify-center pt-1 relative items-center",
        month_grid: "w-full border-collapse space-y-1",
        caption_label: "text-sm font-medium",
        nav: "flex items-center justify-between absolute inset-x-0",
        button_previous: cn(buttonVariants({ variant: "outline" }), "h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100 z-10"),
        button_next: cn(buttonVariants({ variant: "outline" }), "h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100 z-10"),
        weeks: "w-full border-collapse",
        weekdays: "flex",
        weekday: "text-muted-foreground rounded-md w-9 font-normal text-[0.8rem]",
        week: "flex w-full mt-2",
        day: "h-9 w-9 p-0 font-normal aria-selected:opacity-100 rounded-none first:aria-selected:rounded-l-md last:aria-selected:rounded-r-md",
        day_button: cn(
          buttonVariants({ variant: "ghost" }),
          "h-9 w-9 text-center text-sm p-0 relative focus-within:relative focus-within:z-20",
        ),
        range_start:
          "day-range-start !bg-accent rounded-l-md [&>button]:bg-primary [&>button]:text-primary-foreground [&>button]:hover:bg-primary [&>button]:hover:text-primary-foreground",
        range_end:
          "day-range-end !bg-accent rounded-r-md [&>button]:bg-primary [&>button]:text-primary-foreground [&>button]:hover:bg-primary [&>button]:hover:text-primary-foreground",
        range_middle: "aria-selected:bg-accent aria-selected:text-accent-foreground",
        selected: cn(
          props.mode === "range"
            ? "bg-primary hover:bg-primary hover:text-primary-foreground focus:bg-primary focus:text-primary-foreground"
            : "[&>button]:focus:bg-primary [&>button]:focus:text-primary-foreground",
        ),
        today: "bg-accent text-accent-foreground !rounded-md",
        outside:
          "day-outside text-muted-foreground opacity-50 !aria-selected:bg-accent/50 !aria-selected:text-muted-foreground !aria-selected:opacity-30",
        disabled: "text-muted-foreground opacity-50",
        hidden: "invisible",
        ...classNames,
      }}
      components={{
        Chevron: ({ ...props }) =>
          props.orientation === "left" ? <ChevronLeft {...props} className="h-4 w-4" /> : <ChevronRight {...props} className="h-4 w-4" />,
      }}
      {...props}
    />

  );
}
Calendar.displayName = "Calendar";

export { Calendar };

BramMeerten avatar May 05 '25 07:05 BramMeerten

Thanks @jkuri ! I did some small tweaks to make it work for both range and single mode. And also I removed deprecated classes.

     range_end:
       "day-range-end !bg-accent rounded-r-md [&>button]:bg-primary [&>button]:text-primary-foreground [&>button]:hover:bg-primary [&>button]:hover:text-primary-foreground",
     range_middle: "aria-selected:bg-accent aria-selected:text-accent-foreground",
  •    day_selected:
    
  •      "bg-primary text-primary-foreground hover:bg-primary hover:text-primary-foreground focus:bg-primary focus:text-primary-foreground",
    
  •    day_today: "bg-accent text-accent-foreground",
    
  •    day_outside: "day-outside text-muted-foreground aria-selected:text-muted-foreground",
    
  •    day_disabled: "text-muted-foreground opacity-50",
    
  •    day_hidden: "invisible",
    
  •    selected:
    
  •      "bg-primary text-primary-foreground hover:bg-primary hover:text-primary-foreground focus:bg-primary focus:text-primary-foreground",
    
  •    today: "bg-accent text-accent-foreground",
    
  •    selected: cn(
    
  •      props.mode === "range"
    
  •        ? "bg-primary hover:bg-primary hover:text-primary-foreground focus:bg-primary focus:text-primary-foreground"
    
  •        : "[&>button]:focus:bg-primary [&>button]:focus:text-primary-foreground",
    
  •    ),
    
  •    today: "bg-accent text-accent-foreground !rounded-md",
       outside:
         "day-outside text-muted-foreground opacity-50 !aria-selected:bg-accent/50 !aria-selected:text-muted-foreground !aria-selected:opacity-30",
       disabled: "text-muted-foreground opacity-50",
    

Complete file looks like this:

import { buttonVariants } from "@/components/ui/button"; import { cn } from "@/lib/utils"; import { ChevronLeft, ChevronRight } from "lucide-react"; import type { ComponentProps } from "react"; import { DayPicker } from "react-day-picker";

export type CalendarProps = ComponentProps<typeof DayPicker>;

function Calendar({ className, classNames, showOutsideDays = true, ...props }: CalendarProps) { return ( <DayPicker showOutsideDays={showOutsideDays} className={cn("p-3", className)} classNames={{ month: "space-y-4", months: "flex flex-col sm:flex-row space-y-4 sm:space-y-0 relative gap-2", month_caption: "flex justify-center pt-1 relative items-center", month_grid: "w-full border-collapse space-y-1", caption_label: "text-sm font-medium", nav: "flex items-center justify-between absolute inset-x-0", button_previous: cn(buttonVariants({ variant: "outline" }), "h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100 z-10"), button_next: cn(buttonVariants({ variant: "outline" }), "h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100 z-10"), weeks: "w-full border-collapse", weekdays: "flex", weekday: "text-muted-foreground rounded-md w-9 font-normal text-[0.8rem]", week: "flex w-full mt-2", day: "h-9 w-9 p-0 font-normal aria-selected:opacity-100 rounded-none first:aria-selected:rounded-l-md last:aria-selected:rounded-r-md", day_button: cn( buttonVariants({ variant: "ghost" }), "h-9 w-9 text-center text-sm p-0 relative focus-within:relative focus-within:z-20", ), range_start: "day-range-start !bg-accent rounded-l-md [&>button]:bg-primary [&>button]:text-primary-foreground [&>button]:hover:bg-primary [&>button]:hover:text-primary-foreground", range_end: "day-range-end !bg-accent rounded-r-md [&>button]:bg-primary [&>button]:text-primary-foreground [&>button]:hover:bg-primary [&>button]:hover:text-primary-foreground", range_middle: "aria-selected:bg-accent aria-selected:text-accent-foreground", selected: cn( props.mode === "range" ? "bg-primary hover:bg-primary hover:text-primary-foreground focus:bg-primary focus:text-primary-foreground" : "[&>button]:focus:bg-primary [&>button]:focus:text-primary-foreground", ), today: "bg-accent text-accent-foreground !rounded-md", outside: "day-outside text-muted-foreground opacity-50 !aria-selected:bg-accent/50 !aria-selected:text-muted-foreground !aria-selected:opacity-30", disabled: "text-muted-foreground opacity-50", hidden: "invisible", ...classNames, }} components={{ Chevron: ({ ...props }) => props.orientation === "left" ? <ChevronLeft {...props} className="h-4 w-4" /> : <ChevronRight {...props} className="h-4 w-4" />, }} {...props} />

); } Calendar.displayName = "Calendar";

export { Calendar };

Thanks @jkuri ! I did some small tweaks to make it work for both range and single mode. And also I removed deprecated classes.

     range_end:
       "day-range-end !bg-accent rounded-r-md [&>button]:bg-primary [&>button]:text-primary-foreground [&>button]:hover:bg-primary [&>button]:hover:text-primary-foreground",
     range_middle: "aria-selected:bg-accent aria-selected:text-accent-foreground",
  •    day_selected:
    
  •      "bg-primary text-primary-foreground hover:bg-primary hover:text-primary-foreground focus:bg-primary focus:text-primary-foreground",
    
  •    day_today: "bg-accent text-accent-foreground",
    
  •    day_outside: "day-outside text-muted-foreground aria-selected:text-muted-foreground",
    
  •    day_disabled: "text-muted-foreground opacity-50",
    
  •    day_hidden: "invisible",
    
  •    selected:
    
  •      "bg-primary text-primary-foreground hover:bg-primary hover:text-primary-foreground focus:bg-primary focus:text-primary-foreground",
    
  •    today: "bg-accent text-accent-foreground",
    
  •    selected: cn(
    
  •      props.mode === "range"
    
  •        ? "bg-primary hover:bg-primary hover:text-primary-foreground focus:bg-primary focus:text-primary-foreground"
    
  •        : "[&>button]:focus:bg-primary [&>button]:focus:text-primary-foreground",
    
  •    ),
    
  •    today: "bg-accent text-accent-foreground !rounded-md",
       outside:
         "day-outside text-muted-foreground opacity-50 !aria-selected:bg-accent/50 !aria-selected:text-muted-foreground !aria-selected:opacity-30",
       disabled: "text-muted-foreground opacity-50",
    

Complete file looks like this:

import { buttonVariants } from "@/components/ui/button"; import { cn } from "@/lib/utils"; import { ChevronLeft, ChevronRight } from "lucide-react"; import type { ComponentProps } from "react"; import { DayPicker } from "react-day-picker";

export type CalendarProps = ComponentProps<typeof DayPicker>;

function Calendar({ className, classNames, showOutsideDays = true, ...props }: CalendarProps) { return ( <DayPicker showOutsideDays={showOutsideDays} className={cn("p-3", className)} classNames={{ month: "space-y-4", months: "flex flex-col sm:flex-row space-y-4 sm:space-y-0 relative gap-2", month_caption: "flex justify-center pt-1 relative items-center", month_grid: "w-full border-collapse space-y-1", caption_label: "text-sm font-medium", nav: "flex items-center justify-between absolute inset-x-0", button_previous: cn(buttonVariants({ variant: "outline" }), "h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100 z-10"), button_next: cn(buttonVariants({ variant: "outline" }), "h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100 z-10"), weeks: "w-full border-collapse", weekdays: "flex", weekday: "text-muted-foreground rounded-md w-9 font-normal text-[0.8rem]", week: "flex w-full mt-2", day: "h-9 w-9 p-0 font-normal aria-selected:opacity-100 rounded-none first:aria-selected:rounded-l-md last:aria-selected:rounded-r-md", day_button: cn( buttonVariants({ variant: "ghost" }), "h-9 w-9 text-center text-sm p-0 relative focus-within:relative focus-within:z-20", ), range_start: "day-range-start !bg-accent rounded-l-md [&>button]:bg-primary [&>button]:text-primary-foreground [&>button]:hover:bg-primary [&>button]:hover:text-primary-foreground", range_end: "day-range-end !bg-accent rounded-r-md [&>button]:bg-primary [&>button]:text-primary-foreground [&>button]:hover:bg-primary [&>button]:hover:text-primary-foreground", range_middle: "aria-selected:bg-accent aria-selected:text-accent-foreground", selected: cn( props.mode === "range" ? "bg-primary hover:bg-primary hover:text-primary-foreground focus:bg-primary focus:text-primary-foreground" : "[&>button]:focus:bg-primary [&>button]:focus:text-primary-foreground", ), today: "bg-accent text-accent-foreground !rounded-md", outside: "day-outside text-muted-foreground opacity-50 !aria-selected:bg-accent/50 !aria-selected:text-muted-foreground !aria-selected:opacity-30", disabled: "text-muted-foreground opacity-50", hidden: "invisible", ...classNames, }} components={{ Chevron: ({ ...props }) => props.orientation === "left" ? <ChevronLeft {...props} className="h-4 w-4" /> : <ChevronRight {...props} className="h-4 w-4" />, }} {...props} />

); } Calendar.displayName = "Calendar";

export { Calendar };

worked for me

jalvch10 avatar May 14 '25 04:05 jalvch10

I managed to make styles work also for date range picker or multiple months with the current react-day-picker v9.6.7.

Image

This is the code I use:

Just curious how were you able to figure out how to change the styles? @jkuri

vonner04 avatar May 17 '25 17:05 vonner04

I managed to make styles work also for date range picker or multiple months with the current react-day-picker v9.6.7. Image This is the code I use:

Just curious how were you able to figure out how to change the styles? @jkuri

@vonner04 I checked the source of the react-day-picker latest version.

jkuri avatar May 17 '25 17:05 jkuri