diff --git a/apps/www/__registry__/default/example/calendar-form.tsx b/apps/www/__registry__/default/example/calendar-form.tsx index 3fec57d8313..0918fe8c747 100644 --- a/apps/www/__registry__/default/example/calendar-form.tsx +++ b/apps/www/__registry__/default/example/calendar-form.tsx @@ -83,7 +83,7 @@ export default function CalendarForm() { disabled={(date) => date > new Date() || date < new Date("1900-01-01") } - initialFocus + autoFocus /> diff --git a/apps/www/__registry__/default/example/date-picker-demo.tsx b/apps/www/__registry__/default/example/date-picker-demo.tsx index d34cbe67763..0495c45fe28 100644 --- a/apps/www/__registry__/default/example/date-picker-demo.tsx +++ b/apps/www/__registry__/default/example/date-picker-demo.tsx @@ -31,12 +31,7 @@ export default function DatePickerDemo() { - + ) diff --git a/apps/www/__registry__/default/example/date-picker-form.tsx b/apps/www/__registry__/default/example/date-picker-form.tsx index c54442546ee..fd38b45e06d 100644 --- a/apps/www/__registry__/default/example/date-picker-form.tsx +++ b/apps/www/__registry__/default/example/date-picker-form.tsx @@ -83,7 +83,7 @@ export default function DatePickerForm() { disabled={(date) => date > new Date() || date < new Date("1900-01-01") } - initialFocus + autoFocus /> diff --git a/apps/www/__registry__/default/example/date-picker-with-range.tsx b/apps/www/__registry__/default/example/date-picker-with-range.tsx index 4d88bcf0834..6c0e6c58faa 100644 --- a/apps/www/__registry__/default/example/date-picker-with-range.tsx +++ b/apps/www/__registry__/default/example/date-picker-with-range.tsx @@ -51,7 +51,7 @@ export default function DatePickerWithRange({ date > new Date() || date < new Date("1900-01-01") } - initialFocus + autoFocus /> diff --git a/apps/www/content/docs/components/calendar.mdx b/apps/www/content/docs/components/calendar.mdx index 730f4e4c0b8..1c0c431cf94 100644 --- a/apps/www/content/docs/components/calendar.mdx +++ b/apps/www/content/docs/components/calendar.mdx @@ -3,14 +3,14 @@ title: Calendar description: A date field component that allows users to enter and edit date. component: true links: - doc: https://react-day-picker.js.org + doc: https://daypicker.dev --- ## About -The `Calendar` component is built on top of [React DayPicker](https://react-day-picker.js.org). +The `Calendar` component is built on top of [React DayPicker](https://daypicker.dev). ## Installation @@ -35,7 +35,7 @@ npx shadcn-ui@latest add calendar Install the following dependencies: ```bash -npm install react-day-picker date-fns +npm install react-day-picker@^9.0 ``` Add the `Button` component to your project. @@ -73,7 +73,7 @@ return ( ) ``` -See the [React DayPicker](https://react-day-picker.js.org) documentation for more information. +See the [React DayPicker](https://daypicker.dev) documentation for more information. ## Date Picker @@ -84,3 +84,58 @@ You can use the `` component to build a date picker. See the [Date Pic ### Form + + +## Changelog + +### 2024-08-01 `react-day-picker` v9 Support + +We upgraded the component to use `react-day-picker` [v9](https://daypicker.dev/upgrading) + + + **Note:** You are not required to update your code if you want to stick with v8 + + + + +Update to the latest version of `react-day-picker`. + +```bash +npm install react-day-picker@9 +``` + +Update `calendar.tsx` + +```bash +npx shadcn-ui@latest add calendar --overwrite +``` + +Update `initialFocus` prop `autoFocus` + +```diff showLineNumbers title="calendar-demo.tsx" {5-6} + +``` + +Update `fromDate` and `toDate` props `startMonth` and `endMonth` + +```diff showLineNumbers title="calendar-demo.tsx" {5-8} + +``` + +Refer to the [DayPicker upgrade guide](https://daypicker.dev/upgrading) for more information. + + diff --git a/apps/www/content/docs/components/date-picker.mdx b/apps/www/content/docs/components/date-picker.mdx index 040dbf89591..4faaee0a3e8 100644 --- a/apps/www/content/docs/components/date-picker.mdx +++ b/apps/www/content/docs/components/date-picker.mdx @@ -48,19 +48,14 @@ export function DatePickerDemo() { - + ) } ``` -See the [React DayPicker](https://react-day-picker.js.org) documentation for more information. +See the [React DayPicker](https://daypicker.dev) documentation for more information. ## Examples diff --git a/apps/www/package.json b/apps/www/package.json index c8e385174b2..65bbc160aae 100644 --- a/apps/www/package.json +++ b/apps/www/package.json @@ -71,7 +71,7 @@ "next-contentlayer2": "^0.4.6", "next-themes": "^0.2.1", "react": "^18.2.0", - "react-day-picker": "^8.7.1", + "react-day-picker": "^9.0.5", "react-dom": "^18.2.0", "react-hook-form": "^7.44.2", "react-resizable-panels": "^2.0.22", diff --git a/apps/www/pages/api/components.json b/apps/www/pages/api/components.json index 24a93c7d6c3..028e5675147 100644 --- a/apps/www/pages/api/components.json +++ b/apps/www/pages/api/components.json @@ -83,7 +83,7 @@ }, { "name": "calendar", - "dependencies": ["react-day-picker", "date-fns"], + "dependencies": ["react-day-picker@^9.0"], "registryDependencies": ["button"], "files": [ { diff --git a/apps/www/public/registry/index.json b/apps/www/public/registry/index.json index 5d7aca8c26d..24e9eadd1de 100644 --- a/apps/www/public/registry/index.json +++ b/apps/www/public/registry/index.json @@ -79,8 +79,7 @@ { "name": "calendar", "dependencies": [ - "react-day-picker@8.10.1", - "date-fns" + "react-day-picker@^9.0" ], "registryDependencies": [ "button" @@ -470,4 +469,4 @@ ], "type": "components:ui" } -] \ No newline at end of file +] diff --git a/apps/www/public/registry/styles/default/calendar.json b/apps/www/public/registry/styles/default/calendar.json index 39f3dff8770..59f11105b87 100644 --- a/apps/www/public/registry/styles/default/calendar.json +++ b/apps/www/public/registry/styles/default/calendar.json @@ -1,8 +1,7 @@ { "name": "calendar", "dependencies": [ - "react-day-picker@8.10.1", - "date-fns" + "react-day-picker@^9.0" ], "registryDependencies": [ "button" @@ -10,8 +9,8 @@ "files": [ { "name": "calendar.tsx", - "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { ChevronLeft, ChevronRight } from \"lucide-react\"\nimport { DayPicker } from \"react-day-picker\"\n\nimport { cn } from \"@/lib/utils\"\nimport { buttonVariants } from \"@/registry/default/ui/button\"\n\nexport type CalendarProps = React.ComponentProps\n\nfunction Calendar({\n className,\n classNames,\n showOutsideDays = true,\n ...props\n}: CalendarProps) {\n return (\n ,\n IconRight: ({ ...props }) => ,\n }}\n {...props}\n />\n )\n}\nCalendar.displayName = \"Calendar\"\n\nexport { Calendar }\n" + "content": "\"use client\"\n\nimport { ChevronDown, ChevronLeft, ChevronRight, ChevronUp } from \"lucide-react\"\nimport { DayPicker, type DayPickerProps } from \"react-day-picker\"\n\nimport { cn } from \"@/lib/utils\"\nimport { Button, buttonVariants } from \"@/registry/default/ui/button\"\n\nexport type CalendarProps = DayPickerProps\n\nfunction Calendar({\n className,\n classNames,\n showOutsideDays = true,\n ...props\n}: CalendarProps) {\n return (\n \n )\n },\n Chevron({ orientation, disabled, className }) {\n const Component =\n orientation === \"left\"\n ? ChevronLeft\n : orientation === \"right\"\n ? ChevronRight\n : orientation === \"up\"\n ? ChevronUp\n : ChevronDown\n\n return (\n \n )\n },\n }}\n {...props}\n />\n )\n}\nCalendar.displayName = \"Calendar\"\n\nexport { Calendar }\n" } ], "type": "components:ui" -} \ No newline at end of file +} diff --git a/apps/www/public/registry/styles/new-york/calendar.json b/apps/www/public/registry/styles/new-york/calendar.json index 2c13e2ba392..eab7381eb7a 100644 --- a/apps/www/public/registry/styles/new-york/calendar.json +++ b/apps/www/public/registry/styles/new-york/calendar.json @@ -1,8 +1,7 @@ { "name": "calendar", "dependencies": [ - "react-day-picker@8.10.1", - "date-fns" + "react-day-picker@^9.0" ], "registryDependencies": [ "button" @@ -10,8 +9,8 @@ "files": [ { "name": "calendar.tsx", - "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { ChevronLeftIcon, ChevronRightIcon } from \"@radix-ui/react-icons\"\nimport { DayPicker } from \"react-day-picker\"\n\nimport { cn } from \"@/lib/utils\"\nimport { buttonVariants } from \"@/registry/new-york/ui/button\"\n\nexport type CalendarProps = React.ComponentProps\n\nfunction Calendar({\n className,\n classNames,\n showOutsideDays = true,\n ...props\n}: CalendarProps) {\n return (\n .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\"\n : \"[&:has([aria-selected])]:rounded-md\"\n ),\n day: cn(\n buttonVariants({ variant: \"ghost\" }),\n \"h-8 w-8 p-0 font-normal aria-selected:opacity-100\"\n ),\n day_range_start: \"day-range-start\",\n day_range_end: \"day-range-end\",\n day_selected:\n \"bg-primary text-primary-foreground hover:bg-primary hover:text-primary-foreground focus:bg-primary focus:text-primary-foreground\",\n day_today: \"bg-accent text-accent-foreground\",\n day_outside:\n \"day-outside text-muted-foreground opacity-50 aria-selected:bg-accent/50 aria-selected:text-muted-foreground aria-selected:opacity-30\",\n day_disabled: \"text-muted-foreground opacity-50\",\n day_range_middle:\n \"aria-selected:bg-accent aria-selected:text-accent-foreground\",\n day_hidden: \"invisible\",\n ...classNames,\n }}\n components={{\n IconLeft: ({ ...props }) => ,\n IconRight: ({ ...props }) => ,\n }}\n {...props}\n />\n )\n}\nCalendar.displayName = \"Calendar\"\n\nexport { Calendar }\n" + "content": "\"use client\"\n\nimport { ChevronDown, ChevronLeft, ChevronRight, ChevronUp } from \"lucide-react\"\nimport { DayPicker, type DayPickerProps } from \"react-day-picker\"\n\nimport { cn } from \"@/lib/utils\"\nimport { buttonVariants } from \"@/registry/new-york/ui/button\"\n\nexport type CalendarProps = DayPickerProps\n\nfunction Calendar({\n className,\n classNames,\n showOutsideDays = true,\n ...props\n}: CalendarProps) {\n return (\n .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\"\n : \"[&:has([aria-selected])]:rounded-md\"\n ),\n day_button: buttonVariants({\n variant: \"ghost\",\n className: \"h-8 w-8 p-0 font-normal aria-selected:opacity-100\",\n }),\n range_start: \"day-range-start\",\n\n range_middle:\n \"aria-selected:bg-accent aria-selected:text-accent-foreground\",\n range_end: \"day-range-end\",\n selected:\n \"bg-primary text-primary-foreground hover:bg-primary hover:text-primary-foreground focus:bg-primary focus:text-primary-foreground\",\n outside:\n \"day-outside text-muted-foreground opacity-50 aria-selected:bg-accent/50 aria-selected:text-muted-foreground aria-selected:opacity-30\",\n disabled: \"text-muted-foreground opacity-50\",\n hidden: \"invisible\",\n ...classNames,\n }}\n components={{\n Chevron({ orientation, disabled, className }) {\n const Component =\n orientation === \"left\"\n ? ChevronLeft\n : orientation === \"right\"\n ? ChevronRight\n : orientation === \"up\"\n ? ChevronUp\n : ChevronDown\n\n return (\n \n )\n },\n }}\n {...props}\n />\n )\n}\nCalendar.displayName = \"Calendar\"\n\nexport { Calendar }\n" } ], "type": "components:ui" -} \ No newline at end of file +} diff --git a/apps/www/registry/default/example/calendar-form.tsx b/apps/www/registry/default/example/calendar-form.tsx index 3fec57d8313..0918fe8c747 100644 --- a/apps/www/registry/default/example/calendar-form.tsx +++ b/apps/www/registry/default/example/calendar-form.tsx @@ -83,7 +83,7 @@ export default function CalendarForm() { disabled={(date) => date > new Date() || date < new Date("1900-01-01") } - initialFocus + autoFocus /> diff --git a/apps/www/registry/default/example/calendar-react-hook-form.tsx b/apps/www/registry/default/example/calendar-react-hook-form.tsx index 3fec57d8313..0918fe8c747 100644 --- a/apps/www/registry/default/example/calendar-react-hook-form.tsx +++ b/apps/www/registry/default/example/calendar-react-hook-form.tsx @@ -83,7 +83,7 @@ export default function CalendarForm() { disabled={(date) => date > new Date() || date < new Date("1900-01-01") } - initialFocus + autoFocus /> diff --git a/apps/www/registry/default/example/date-picker-demo.tsx b/apps/www/registry/default/example/date-picker-demo.tsx index d34cbe67763..0495c45fe28 100644 --- a/apps/www/registry/default/example/date-picker-demo.tsx +++ b/apps/www/registry/default/example/date-picker-demo.tsx @@ -31,12 +31,7 @@ export default function DatePickerDemo() { - + ) diff --git a/apps/www/registry/default/example/date-picker-form.tsx b/apps/www/registry/default/example/date-picker-form.tsx index c54442546ee..fd38b45e06d 100644 --- a/apps/www/registry/default/example/date-picker-form.tsx +++ b/apps/www/registry/default/example/date-picker-form.tsx @@ -83,7 +83,7 @@ export default function DatePickerForm() { disabled={(date) => date > new Date() || date < new Date("1900-01-01") } - initialFocus + autoFocus /> diff --git a/apps/www/registry/default/example/date-picker-with-range.tsx b/apps/www/registry/default/example/date-picker-with-range.tsx index 4d88bcf0834..6c0e6c58faa 100644 --- a/apps/www/registry/default/example/date-picker-with-range.tsx +++ b/apps/www/registry/default/example/date-picker-with-range.tsx @@ -51,7 +51,7 @@ export default function DatePickerWithRange({ +export type CalendarProps = DayPickerProps function Calendar({ className, @@ -20,42 +19,83 @@ function Calendar({ showOutsideDays={showOutsideDays} className={cn("p-3", className)} classNames={{ - months: "flex flex-col sm:flex-row space-y-4 sm:space-x-4 sm:space-y-0", + months: + "relative flex flex-col sm:flex-row space-y-4 sm:space-x-4 sm:space-y-0", month: "space-y-4", - caption: "flex justify-center pt-1 relative items-center", - caption_label: "text-sm font-medium", - nav: "space-x-1 flex items-center", - nav_button: cn( - buttonVariants({ variant: "outline" }), - "h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100" + nav: "flex items-center justify-between absolute w-full z-10 px-1", + button_previous: cn( + buttonVariants({ + variant: "outline", + className: + "h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100", + }) ), - nav_button_previous: "absolute left-1", - nav_button_next: "absolute right-1", - table: "w-full border-collapse space-y-1", - head_row: "flex", - head_cell: - "text-muted-foreground rounded-md w-9 font-normal text-[0.8rem]", - row: "flex w-full mt-2", - cell: "h-9 w-9 text-center text-sm p-0 relative [&:has([aria-selected].day-range-end)]:rounded-r-md [&:has([aria-selected].day-outside)]:bg-accent/50 [&:has([aria-selected])]:bg-accent first:[&:has([aria-selected])]:rounded-l-md last:[&:has([aria-selected])]:rounded-r-md focus-within:relative focus-within:z-20", - day: cn( - buttonVariants({ variant: "ghost" }), - "h-9 w-9 p-0 font-normal aria-selected:opacity-100" + button_next: cn( + buttonVariants({ + variant: "outline", + className: + "h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100", + }) ), - day_range_end: "day-range-end", - 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 opacity-50 aria-selected:bg-accent/50 aria-selected:text-muted-foreground aria-selected:opacity-30", - day_disabled: "text-muted-foreground opacity-50", - day_range_middle: - "aria-selected:bg-accent aria-selected:text-accent-foreground", - day_hidden: "invisible", + month_caption: "flex justify-center items-center h-7", + caption_label: "text-sm font-medium", + month_grid: "border-collapse space-y-1", + weekdays: "flex", + weekday: "text-muted-foreground w-9 font-normal text-xs", + weeks: "", + week: "flex mt-2", + day: "p-0", + outside: "bg-accent/40", + range_middle: "bg-accent last:rounded-e-md first:rounded-s-md", + range_start: "bg-accent rounded-s-md", + range_end: "bg-accent rounded-e-md", ...classNames, }} components={{ - IconLeft: ({ ...props }) => , - IconRight: ({ ...props }) => , + DayButton({ day, modifiers, className, ...buttonProps }) { + return ( + - + ) diff --git a/apps/www/registry/new-york/example/date-picker-form.tsx b/apps/www/registry/new-york/example/date-picker-form.tsx index 0b27f9f67ea..c402bf3bbe9 100644 --- a/apps/www/registry/new-york/example/date-picker-form.tsx +++ b/apps/www/registry/new-york/example/date-picker-form.tsx @@ -83,7 +83,7 @@ export default function DatePickerForm() { disabled={(date) => date > new Date() || date < new Date("1900-01-01") } - initialFocus + autoFocus /> diff --git a/apps/www/registry/new-york/example/date-picker-with-range.tsx b/apps/www/registry/new-york/example/date-picker-with-range.tsx index 2d987288472..1cc2106d81e 100644 --- a/apps/www/registry/new-york/example/date-picker-with-range.tsx +++ b/apps/www/registry/new-york/example/date-picker-with-range.tsx @@ -51,7 +51,7 @@ export default function DatePickerWithRange({ +export type CalendarProps = DayPickerProps function Calendar({ className, @@ -20,48 +19,85 @@ function Calendar({ showOutsideDays={showOutsideDays} className={cn("p-3", className)} classNames={{ - months: "flex flex-col sm:flex-row space-y-4 sm:space-x-4 sm:space-y-0", + months: + "relative flex flex-col sm:flex-row space-y-4 sm:space-x-4 sm:space-y-0", month: "space-y-4", - caption: "flex justify-center pt-1 relative items-center", - caption_label: "text-sm font-medium", - nav: "space-x-1 flex items-center", - nav_button: cn( - buttonVariants({ variant: "outline" }), - "h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100" - ), - nav_button_previous: "absolute left-1", - nav_button_next: "absolute right-1", - table: "w-full border-collapse space-y-1", - head_row: "flex", - head_cell: - "text-muted-foreground rounded-md w-8 font-normal text-[0.8rem]", - row: "flex w-full mt-2", - cell: 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" + nav: "flex items-center justify-between absolute w-full z-10 px-1", + button_previous: cn( + buttonVariants({ + variant: "outline", + className: + "h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100", + }) ), - day: cn( - buttonVariants({ variant: "ghost" }), - "h-8 w-8 p-0 font-normal aria-selected:opacity-100" + button_next: cn( + buttonVariants({ + variant: "outline", + className: + "h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100", + }) ), - day_range_start: "day-range-start", - day_range_end: "day-range-end", - 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 opacity-50 aria-selected:bg-accent/50 aria-selected:text-muted-foreground aria-selected:opacity-30", - day_disabled: "text-muted-foreground opacity-50", - day_range_middle: - "aria-selected:bg-accent aria-selected:text-accent-foreground", - day_hidden: "invisible", + month_caption: "flex justify-center items-center h-7", + caption_label: "text-sm font-medium", + month_grid: "border-collapse space-y-1", + weekdays: "flex", + weekday: "text-muted-foreground w-9 font-normal text-xs", + weeks: "", + week: "flex mt-2", + day: "p-0", + outside: "bg-accent/40", + range_middle: "bg-accent last:rounded-e-md first:rounded-s-md", + range_start: "bg-accent rounded-s-md", + range_end: "bg-accent rounded-e-md", ...classNames, }} components={{ - IconLeft: ({ ...props }) => , - IconRight: ({ ...props }) => , + DayButton({ day, modifiers, className, ...buttonProps }) { + return ( +