-
Star
(167)
You must be signed in to star a gist -
Fork
(26)
You must be signed in to fork a gist
-
-
Save mjbalcueva/1fbcb1be9ef68a82c14d778b686a04fa to your computer and use it in GitHub Desktop.
"use client" | |
import * as React from "react" | |
import { buttonVariants } from "@/components/ui/button" | |
import { ScrollArea } from "@/components/ui/scroll-area" | |
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select" | |
import { cn } from "@/lib/utils" | |
import { ChevronLeft, ChevronRight } from "lucide-react" | |
import { DayPicker, DropdownProps } from "react-day-picker" | |
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-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", | |
caption_dropdowns: "flex justify-center gap-1", | |
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-9 font-normal text-[0.8rem]", | |
row: "flex w-full mt-2", | |
cell: "text-center text-sm p-0 relative [&: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"), | |
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: "text-muted-foreground opacity-50", | |
day_disabled: "text-muted-foreground opacity-50", | |
day_range_middle: "aria-selected:bg-accent aria-selected:text-accent-foreground", | |
day_hidden: "invisible", | |
...classNames, | |
}} | |
components={{ | |
Dropdown: ({ value, onChange, children, ...props }: DropdownProps) => { | |
const options = React.Children.toArray(children) as React.ReactElement<React.HTMLProps<HTMLOptionElement>>[] | |
const selected = options.find((child) => child.props.value === value) | |
const handleChange = (value: string) => { | |
const changeEvent = { | |
target: { value }, | |
} as React.ChangeEvent<HTMLSelectElement> | |
onChange?.(changeEvent) | |
} | |
return ( | |
<Select | |
value={value?.toString()} | |
onValueChange={(value) => { | |
handleChange(value) | |
}} | |
> | |
<SelectTrigger className="pr-1.5 focus:ring-0"> | |
<SelectValue>{selected?.props?.children}</SelectValue> | |
</SelectTrigger> | |
<SelectContent position="popper"> | |
<ScrollArea className="h-80"> | |
{options.map((option, id: number) => ( | |
<SelectItem key={`${option.props.value}-${id}`} value={option.props.value?.toString() ?? ""}> | |
{option.props.children} | |
</SelectItem> | |
))} | |
</ScrollArea> | |
</SelectContent> | |
</Select> | |
) | |
}, | |
IconLeft: ({ ...props }) => <ChevronLeft className="h-4 w-4" />, | |
IconRight: ({ ...props }) => <ChevronRight className="h-4 w-4" />, | |
}} | |
{...props} | |
/> | |
) | |
} | |
Calendar.displayName = "Calendar" | |
export { Calendar } |
/* add this snippet in your globals.css file */ | |
.rdp-vhidden { | |
@apply hidden; | |
} |
"use client" | |
import * as React from "react" | |
import { Button } from "@/components/ui/button" | |
import { Calendar } from "@/components/ui/calendar" | |
import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover" | |
import { cn } from "@/lib/utils" | |
import { format } from "date-fns" | |
import { CalendarIcon } from "lucide-react" | |
export function SampleDatePicker() { | |
const [date, setDate] = React.useState<Date>() | |
return ( | |
<Popover> | |
<PopoverTrigger asChild> | |
<Button | |
variant={"outline"} | |
className={cn("w-[240px] 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 align="start" className=" w-auto p-0"> | |
<Calendar | |
mode="single" | |
captionLayout="dropdown-buttons" | |
selected={date} | |
onSelect={setDate} | |
fromYear={1960} | |
toYear={2030} | |
/> | |
</PopoverContent> | |
</Popover> | |
) | |
} |
working fine for me
https://shadcn-datetime-picker.vercel.app/datetime-picker (Take a look 👀 )
Still there is any issue the year and month dropdown not get selected according to the date value we are setting
My selected data is July 6th, 2016 but dropdowns are selected to like current date only.
To solve your issue, in the Calendar component you have to use the defaultMonth prop with the value of the selected date
Hi thanks for the information issue is fixed I missed defaultMonth prop with the value.
Thank you
Is there a version of it, that works with react-day-picker v9?
Thank you!
@Maliksidk19 you mean this
here is mine, see 👁️ the difference.
Is there a version of it, that works with react-day-picker v9?
I have managed to make it work in Next.js 15.1.3, with react 19, shadcn 2.1.8 and react-day-picker 9.5.0
Calendar component call
<PopoverContent className="w-auto p-0" align="start">
<Calendar
mode="single"
captionLayout="dropdown"
selected={field.value ?? new Date()}
onSelect={field.onChange}
endMonth={new Date()}
disabled={{
after: new Date(),
before: new Date(1900, 0),
}}
/>
</PopoverContent>
calendar.tsx
"use client";
import * as React from "react";
import { ChevronLeft, ChevronRight } from "lucide-react";
import { DayPicker, DropdownProps } from "react-day-picker";
import { cn } from "@/lib/utils";
import { buttonVariants } from "@/components/ui/button";
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from "./select";
import { ScrollArea } from "./scroll-area";
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={{
month: "space-y-4",
months: "flex flex-col sm:flex-row space-y-4 sm:space-y-0 relative",
month_caption: "flex justify-center pt-1 relative items-center",
month_grid: "w-full border-collapse space-y-1",
// TEST
dropdowns: "flex justify-center gap-1",
nav: "flex items-center justify-between absolute inset-x-0 top-2",
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",
),
// TEST
weeks: "w-full border-collapse space-y-",
weekdays: "flex",
weekday:
"text-muted-foreground rounded-md w-9 font-normal text-[0.8rem]",
week: "flex w-full mt-2",
day_button:
"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",
),
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",
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",
range_middle:
"aria-selected:bg-accent aria-selected:text-accent-foreground",
hidden: "invisible",
...classNames,
}}
components={{
Dropdown: ({ value, onChange, options }: DropdownProps) => {
const selected = options?.find((child) => child.value === value);
const handleChange = (value: string) => {
const changeEvent = {
target: { value },
} as React.ChangeEvent<HTMLSelectElement>;
onChange?.(changeEvent);
};
return (
<Select
value={value?.toString()}
onValueChange={(value) => {
handleChange(value);
}}
>
<SelectTrigger className="pr-1.5 focus:ring-0">
<SelectValue>{selected?.label}</SelectValue>
</SelectTrigger>
<SelectContent position="popper">
<ScrollArea className="h-80">
{options?.map((option, id: number) => (
<SelectItem
key={`${option.value}-${id}`}
value={option.value?.toString() ?? ""}
>
{option.label}
</SelectItem>
))}
</ScrollArea>
</SelectContent>
</Select>
);
},
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 };
A small change, instead of adding to the CSS file
.rdp-vhidden { @apply hidden; }Apply the Tailwind selector directly in the component declaration:
<DayPicker 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", month: "space-y-4", //... vhidden: "vhidden hidden", // Add this line //.. }}
Thank you very much
Is there a version of it, that works with react-day-picker v9?
here you have my version of the calendar with react-day-picker v.9
Is there a version of it, that works with react-day-picker v9?
here you have my version of the calendar with react-day-picker v.9
Thanks a lot! Works perfectly.
I can share you one of a component which works too : https://gist.github.com/maxgfr/94b00cfc2a8bb4031f36e52b0923b56d
Shadcn datetime picker is now updated to work with [email protected], react@19 and [email protected] without any issue
https://shadcn-datetime-picker.vercel.app/datetime-picker
@Mr-Vipi (I have used your react-day-picker v9 calendae component code and changed it a bit) Thanks ✨
Thank you.. awesome.