Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Upgrade react-day-picker to v9 #4371

Open
wants to merge 17 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion apps/www/__registry__/default/example/calendar-form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ export default function CalendarForm() {
disabled={(date) =>
date > new Date() || date < new Date("1900-01-01")
}
initialFocus
autoFocus
/>
</PopoverContent>
</Popover>
Expand Down
7 changes: 1 addition & 6 deletions apps/www/__registry__/default/example/date-picker-demo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,7 @@ export default function DatePickerDemo() {
</Button>
</PopoverTrigger>
<PopoverContent className="w-auto p-0">
<Calendar
mode="single"
selected={date}
onSelect={setDate}
initialFocus
/>
<Calendar mode="single" selected={date} onSelect={setDate} autoFocus />
</PopoverContent>
</Popover>
)
Expand Down
2 changes: 1 addition & 1 deletion apps/www/__registry__/default/example/date-picker-form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ export default function DatePickerForm() {
disabled={(date) =>
date > new Date() || date < new Date("1900-01-01")
}
initialFocus
autoFocus
/>
</PopoverContent>
</Popover>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ export default function DatePickerWithRange({
</PopoverTrigger>
<PopoverContent className="w-auto p-0" align="start">
<Calendar
initialFocus
autoFocus
mode="range"
defaultMonth={date?.from}
selected={date}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ export function CalendarDateRangePicker({
</PopoverTrigger>
<PopoverContent className="w-auto p-0" align="end">
<Calendar
initialFocus
autoFocus
mode="range"
defaultMonth={date?.from}
selected={date}
Expand Down
2 changes: 1 addition & 1 deletion apps/www/app/(app)/examples/forms/account/account-form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ export function AccountForm() {
disabled={(date) =>
date > new Date() || date < new Date("1900-01-01")
}
initialFocus
autoFocus
/>
</PopoverContent>
</Popover>
Expand Down
63 changes: 59 additions & 4 deletions apps/www/content/docs/components/calendar.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -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
---

<ComponentPreview name="calendar-demo" />

## 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

Expand All @@ -35,7 +35,7 @@ npx shadcn-ui@latest add calendar
<Step>Install the following dependencies:</Step>

```bash
npm install react-day-picker date-fns
npm install react-day-picker@^9.0
```

<Step>Add the `Button` component to your project.</Step>
Expand Down Expand Up @@ -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

Expand All @@ -84,3 +84,58 @@ You can use the `<Calendar>` component to build a date picker. See the [Date Pic
### Form

<ComponentPreview name="calendar-form" />


## Changelog

### 2024-08-01 `react-day-picker` v9 Support

We upgraded the component to use `react-day-picker` [v9](https://daypicker.dev/upgrading)

<Callout className="mt-6">
**Note:** You are not required to update your code if you want to stick with v8
</Callout>

<Steps>

<Step>Update to the latest version of `react-day-picker`.</Step>

```bash
npm install react-day-picker@9
```

<Step>Update `calendar.tsx`</Step>

```bash
npx shadcn-ui@latest add calendar --overwrite
```

<Step>Update `initialFocus` prop `autoFocus`</Step>

```diff showLineNumbers title="calendar-demo.tsx" {5-6}
<Calendar
mode="single"
selected={date}
onSelect={setDate}
- initialFocus
+ autoFocus
/>
```

<Step>Update `fromDate` and `toDate` props `startMonth` and `endMonth`</Step>

```diff showLineNumbers title="calendar-demo.tsx" {5-8}
<Calendar
mode="single"
selected={date}
onSelect={setDate}
- fromDate={new Date(2010, 11, 03)}
+ startMonth={new Date(2010, 11)}
- toDate={new Date(2030, 5, 10)}
+ endMonth={new Date(2030, 5)}
/>
```

Refer to the [DayPicker upgrade guide](https://daypicker.dev/upgrading) for more information.

</Steps>
9 changes: 2 additions & 7 deletions apps/www/content/docs/components/date-picker.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -48,19 +48,14 @@ export function DatePickerDemo() {
</Button>
</PopoverTrigger>
<PopoverContent className="w-auto p-0">
<Calendar
mode="single"
selected={date}
onSelect={setDate}
initialFocus
/>
<Calendar mode="single" selected={date} onSelect={setDate} autoFocus />
</PopoverContent>
</Popover>
)
}
```

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

Expand Down
2 changes: 1 addition & 1 deletion apps/www/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
2 changes: 1 addition & 1 deletion apps/www/pages/api/components.json
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@
},
{
"name": "calendar",
"dependencies": ["react-day-picker", "date-fns"],
"dependencies": ["react-day-picker@^9.0"],
"registryDependencies": ["button"],
"files": [
{
Expand Down
5 changes: 2 additions & 3 deletions apps/www/public/registry/index.json
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,7 @@
{
"name": "calendar",
"dependencies": [
"[email protected]",
"date-fns"
"react-day-picker@^9.0"
],
"registryDependencies": [
"button"
Expand Down Expand Up @@ -470,4 +469,4 @@
],
"type": "components:ui"
}
]
]
7 changes: 3 additions & 4 deletions apps/www/public/registry/styles/default/calendar.json
Original file line number Diff line number Diff line change
@@ -1,17 +1,16 @@
{
"name": "calendar",
"dependencies": [
"[email protected]",
"date-fns"
"react-day-picker@^9.0"
],
"registryDependencies": [
"button"
],
"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<typeof DayPicker>\n\nfunction Calendar({\n className,\n classNames,\n showOutsideDays = true,\n ...props\n}: CalendarProps) {\n return (\n <DayPicker\n showOutsideDays={showOutsideDays}\n className={cn(\"p-3\", className)}\n classNames={{\n months: \"flex flex-col sm:flex-row space-y-4 sm:space-x-4 sm:space-y-0\",\n month: \"space-y-4\",\n caption: \"flex justify-center pt-1 relative items-center\",\n caption_label: \"text-sm font-medium\",\n nav: \"space-x-1 flex items-center\",\n nav_button: cn(\n buttonVariants({ variant: \"outline\" }),\n \"h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100\"\n ),\n nav_button_previous: \"absolute left-1\",\n nav_button_next: \"absolute right-1\",\n table: \"w-full border-collapse space-y-1\",\n head_row: \"flex\",\n head_cell:\n \"text-muted-foreground rounded-md w-9 font-normal text-[0.8rem]\",\n row: \"flex w-full mt-2\",\n 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\",\n day: cn(\n buttonVariants({ variant: \"ghost\" }),\n \"h-9 w-9 p-0 font-normal aria-selected:opacity-100\"\n ),\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 }) => <ChevronLeft className=\"h-4 w-4\" />,\n IconRight: ({ ...props }) => <ChevronRight className=\"h-4 w-4\" />,\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 <DayPicker\n showOutsideDays={showOutsideDays}\n className={cn(\"p-3\", className)}\n classNames={{\n months: \"relative\",\n month: \"space-y-4\",\n nav: \"flex items-center justify-between absolute w-full z-10 px-1\",\n button_previous: cn(\n buttonVariants({\n variant: \"outline\",\n className:\n \"h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100\",\n })\n ),\n button_next: cn(\n buttonVariants({\n variant: \"outline\",\n className:\n \"h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100\",\n })\n ),\n month_caption: \"flex justify-center items-center h-7\",\n caption_label: \"text-sm font-medium\",\n month_grid: \"border-collapse space-y-1\",\n weekdays: \"flex\",\n weekday: \"text-muted-foreground w-9 font-normal text-xs\",\n weeks: \"\",\n week: \"flex mt-2\",\n day: \"p-0\",\n range_middle: \"bg-accent last:rounded-e-md first:rounded-s-md\",\n range_start: \"bg-accent rounded-s-md\",\n range_end: \"bg-accent rounded-e-md\",\n ...classNames,\n }}\n components={{\n DayButton({ day, modifiers, className, ...buttonProps }) {\n return (\n <Button\n variant={\"ghost\"}\n className={cn(\n className,\n \"h-9 w-9 p-0 font-normal\",\n modifiers?.today && \"bg-accent text-accent-foreground\",\n modifiers?.selected &&\n \"bg-primary text-primary-foreground hover:bg-primary hover:text-primary-foreground focus:bg-primary focus:text-primary-foreground\",\n modifiers?.outside &&\n \"text-muted-foreground opacity-50 pointer-events-none\",\n modifiers.outside &&\n modifiers.selected &&\n \"bg-accent text-muted-foreground opacity-50\",\n modifiers?.disabled && \"opacity-50 text-muted-foreground\",\n modifiers?.hidden && \"invisible\",\n modifiers.range_middle && \"bg-accent text-accent-foreground hover:bg-accent hover:text-accent-foreground rounded-none last:rounded-e-md first:rounded-s-md\",\n )}\n {...buttonProps}\n aria-selected={modifiers.selected || buttonProps[\"aria-selected\"]}\n aria-disabled={modifiers.disabled || buttonProps[\"aria-disabled\"]}\n aria-hidden={modifiers.hidden || buttonProps[\"aria-hidden\"]}\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 <Component\n className={cn(\"w-4 h-4\", className)}\n aria-disabled={disabled}\n />\n )\n },\n }}\n {...props}\n />\n )\n}\nCalendar.displayName = \"Calendar\"\n\nexport { Calendar }\n"
}
],
"type": "components:ui"
}
}
7 changes: 3 additions & 4 deletions apps/www/public/registry/styles/new-york/calendar.json
Original file line number Diff line number Diff line change
@@ -1,17 +1,16 @@
{
"name": "calendar",
"dependencies": [
"[email protected]",
"date-fns"
"react-day-picker@^9.0"
],
"registryDependencies": [
"button"
],
"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<typeof DayPicker>\n\nfunction Calendar({\n className,\n classNames,\n showOutsideDays = true,\n ...props\n}: CalendarProps) {\n return (\n <DayPicker\n showOutsideDays={showOutsideDays}\n className={cn(\"p-3\", className)}\n classNames={{\n months: \"flex flex-col sm:flex-row space-y-4 sm:space-x-4 sm:space-y-0\",\n month: \"space-y-4\",\n caption: \"flex justify-center pt-1 relative items-center\",\n caption_label: \"text-sm font-medium\",\n nav: \"space-x-1 flex items-center\",\n nav_button: cn(\n buttonVariants({ variant: \"outline\" }),\n \"h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100\"\n ),\n nav_button_previous: \"absolute left-1\",\n nav_button_next: \"absolute right-1\",\n table: \"w-full border-collapse space-y-1\",\n head_row: \"flex\",\n head_cell:\n \"text-muted-foreground rounded-md w-8 font-normal text-[0.8rem]\",\n row: \"flex w-full mt-2\",\n cell: cn(\n \"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\",\n props.mode === \"range\"\n ? \"[&: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\"\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 }) => <ChevronLeftIcon className=\"h-4 w-4\" />,\n IconRight: ({ ...props }) => <ChevronRightIcon className=\"h-4 w-4\" />,\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 <DayPicker\n showOutsideDays={showOutsideDays}\n className={cn(\"p-3\", className)}\n classNames={{\n months: \"flex flex-col sm:flex-row space-y-4 sm:space-x-4 sm:space-y-0\",\n month: \"space-y-4\",\n month_caption: \"flex justify-center pt-1 relative items-center\",\n caption_label: \"text-sm font-medium\",\n nav: \"space-x-1 flex items-center\",\n button_previous: buttonVariants({\n variant: \"outline\",\n className:\n \"size-7 bg-transparent p-0 opacity-50 hover:opacity-100 absolute start-1\",\n }),\n button_next: buttonVariants({\n variant: \"outline\",\n className:\n \"size-7 bg-transparent p-0 opacity-50 hover:opacity-100 absolute end-1\",\n }),\n month_grid: \"w-full border-collapse space-y-1\",\n weekdays: \"flex\",\n weekday:\n \"text-muted-foreground rounded-md w-8 font-normal text-[0.8rem]\",\n week: \"flex w-full mt-2\",\n today: \"bg-accent text-accent-foreground\",\n day: cn(\n \"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\",\n props.mode === \"range\"\n ? \"[&: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\"\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 <Component\n className={cn(\"size-4\", className)}\n aria-disabled={disabled}\n />\n )\n },\n }}\n {...props}\n />\n )\n}\nCalendar.displayName = \"Calendar\"\n\nexport { Calendar }\n"
}
],
"type": "components:ui"
}
}
2 changes: 1 addition & 1 deletion apps/www/registry/default/example/calendar-form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ export default function CalendarForm() {
disabled={(date) =>
date > new Date() || date < new Date("1900-01-01")
}
initialFocus
autoFocus
/>
</PopoverContent>
</Popover>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ export default function CalendarForm() {
disabled={(date) =>
date > new Date() || date < new Date("1900-01-01")
}
initialFocus
autoFocus
/>
</PopoverContent>
</Popover>
Expand Down
Loading