Type error w/ Dates & shadcnui
Type error: Type '(event: Date | ChangeEvent<Element>) => void' is not assignable to type 'SelectSingleEventHandler'.
Types of parameters 'event' and 'day' are incompatible.
Type 'Date | undefined' is not assignable to type 'Date | ChangeEvent<Element>'.
Type 'undefined' is not assignable to type 'Date | ChangeEvent<Element>'.
Type error: Type '(event: Date | ChangeEvent<Element>) => void' is not assignable to type 'SelectSingleEventHandler'.
Types of parameters 'event' and 'day' are incompatible.
Type 'Date | undefined' is not assignable to type 'Date | ChangeEvent<Element>'.
Type 'undefined' is not assignable to type 'Date | ChangeEvent<Element>'.
Solution:Jump to solution
fixed, just had to switch from
onSelect={field.onChange}
to onSelect={field.onChange as unknown as SelectSingleEventHandler | undefined}
and the build ran2 Replies
Rendered out field
Calendar component
zod form stuff
<div className="grid grid-cols-2 gap-3">
<FormField
control={form.control}
name="dob"
render={({ field }) => (
<FormItem className="flex flex-col">
<FormLabel>Date of Birth</FormLabel>
<Popover>
<PopoverTrigger asChild>
<FormControl>
<Button
variant={"outline"}
className={cn(
"w-[240px] pl-3 text-left font-normal",
!field.value && "text-muted-foreground"
)}
>
{field.value ? (
format(field.value, "PPP")
) : (
<span>Pick a date</span>
)}
<CalendarIcon className="ml-auto h-4 w-4 opacity-50" />
</Button>
</FormControl>
</PopoverTrigger>
<PopoverContent className="w-auto p-0" align="start">
<Calendar
mode="single"
required={false}
selected={field.value}
onSelect={field.onChange}
captionLayout="dropdown-buttons"
fromYear={1995}
toYear={new Date().getFullYear()}
disabled={(date) =>
date > new Date() || date < new Date("1900-01-01")
}
initialFocus
/>
</PopoverContent>
</Popover>
<FormMessage />
</FormItem>
)}
/>
<div className="grid grid-cols-2 gap-3">
<FormField
control={form.control}
name="dob"
render={({ field }) => (
<FormItem className="flex flex-col">
<FormLabel>Date of Birth</FormLabel>
<Popover>
<PopoverTrigger asChild>
<FormControl>
<Button
variant={"outline"}
className={cn(
"w-[240px] pl-3 text-left font-normal",
!field.value && "text-muted-foreground"
)}
>
{field.value ? (
format(field.value, "PPP")
) : (
<span>Pick a date</span>
)}
<CalendarIcon className="ml-auto h-4 w-4 opacity-50" />
</Button>
</FormControl>
</PopoverTrigger>
<PopoverContent className="w-auto p-0" align="start">
<Calendar
mode="single"
required={false}
selected={field.value}
onSelect={field.onChange}
captionLayout="dropdown-buttons"
fromYear={1995}
toYear={new Date().getFullYear()}
disabled={(date) =>
date > new Date() || date < new Date("1900-01-01")
}
initialFocus
/>
</PopoverContent>
</Popover>
<FormMessage />
</FormItem>
)}
/>
"use client";
import * as React from "react";
import { ChevronLeft, ChevronRight } from "lucide-react";
import { DayPicker } from "react-day-picker";
import { cn } from "@/lib/utils";
import { buttonVariants } from "@/components/ui/button";
export type CalendarProps = React.ComponentProps<typeof DayPicker>;
const 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: "hidden",
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"
),
dropdown_month:
"grid grid-cols-2 -space-x-5 border rounded-md bg-white shadow-md",
dropdown_year:
"grid grid-cols-2 -space-x-5 border rounded-md bg-white shadow-md",
dropdown:
"flex flex-col border hover:bg-gray-200 hover:cursor-pointer border-black rounded-md bg-white shadow-md",
caption_dropdowns: "flex flex-col space-x-2",
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={{
IconLeft: ({ ...props }) => <ChevronLeft className="h-4 w-4" />,
IconRight: ({ ...props }) => <ChevronRight className="h-4 w-4" />,
}}
{...props}
/>
);
};
Calendar.displayName = "Calendar";
export { Calendar };
"use client";
import * as React from "react";
import { ChevronLeft, ChevronRight } from "lucide-react";
import { DayPicker } from "react-day-picker";
import { cn } from "@/lib/utils";
import { buttonVariants } from "@/components/ui/button";
export type CalendarProps = React.ComponentProps<typeof DayPicker>;
const 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: "hidden",
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"
),
dropdown_month:
"grid grid-cols-2 -space-x-5 border rounded-md bg-white shadow-md",
dropdown_year:
"grid grid-cols-2 -space-x-5 border rounded-md bg-white shadow-md",
dropdown:
"flex flex-col border hover:bg-gray-200 hover:cursor-pointer border-black rounded-md bg-white shadow-md",
caption_dropdowns: "flex flex-col space-x-2",
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={{
IconLeft: ({ ...props }) => <ChevronLeft className="h-4 w-4" />,
IconRight: ({ ...props }) => <ChevronRight className="h-4 w-4" />,
}}
{...props}
/>
);
};
Calendar.displayName = "Calendar";
export { Calendar };
const formSchema = z.object({
playerFirstName: z.string().min(1, {
message: "You need to provide a first name!",
}),
playerLastName: z.string().min(1, {
message: "You need to provide a last name!",
}),
dob: z.date({
required_error: "A date of birth is required.",
}),
playerEmail: z.string().email({
message: "You need to provide a valid email!",
}),
playerPhoneNumber: z.string().min(1, {
message: "You need to provide a phone number!",
}),
parentFirstName: z.string().min(1, {
message: "You need to provide a first name!",
}),
parentLastName: z.string().min(1, {
message: "You need to provide a last name!",
}),
parentEmail: z.string().email({
message: "You need to provide a valid email!",
}),
parentPhoneNumber: z.string().min(1, {
message: "You need to provide a phone number!",
}),
playerBattingHand: z.enum(["Left", "Right", "Switch"]),
playerThrowingHand: z.enum(["Left", "Right"]),
playerPositions: z.array(z.enum(["C", "1B", "2B", "3B", "SS", "OF", "P"])),
playerAgeGroup: z.string({
required_error: "You need to select an age group!",
}),
playerHighSchool: z.string().optional(), // Only render if player is in high school?
message: z.string().optional(),
});
const formSchema = z.object({
playerFirstName: z.string().min(1, {
message: "You need to provide a first name!",
}),
playerLastName: z.string().min(1, {
message: "You need to provide a last name!",
}),
dob: z.date({
required_error: "A date of birth is required.",
}),
playerEmail: z.string().email({
message: "You need to provide a valid email!",
}),
playerPhoneNumber: z.string().min(1, {
message: "You need to provide a phone number!",
}),
parentFirstName: z.string().min(1, {
message: "You need to provide a first name!",
}),
parentLastName: z.string().min(1, {
message: "You need to provide a last name!",
}),
parentEmail: z.string().email({
message: "You need to provide a valid email!",
}),
parentPhoneNumber: z.string().min(1, {
message: "You need to provide a phone number!",
}),
playerBattingHand: z.enum(["Left", "Right", "Switch"]),
playerThrowingHand: z.enum(["Left", "Right"]),
playerPositions: z.array(z.enum(["C", "1B", "2B", "3B", "SS", "OF", "P"])),
playerAgeGroup: z.string({
required_error: "You need to select an age group!",
}),
playerHighSchool: z.string().optional(), // Only render if player is in high school?
message: z.string().optional(),
});
const form = useForm<z.infer<typeof formSchema>>({
resolver: zodResolver(formSchema),
defaultValues: {
// Player Info
playerFirstName: "",
playerLastName: "",
dob: new Date(),
playerEmail: "",
playerPhoneNumber: "",
// Parent Info
parentFirstName: "",
parentLastName: "",
parentEmail: "",
parentPhoneNumber: "",
// Player Details
playerBattingHand: "Right",
playerThrowingHand: "Right",
playerPositions: [],
playerAgeGroup: "",
playerHighSchool: "",
message: "",
},
});
const form = useForm<z.infer<typeof formSchema>>({
resolver: zodResolver(formSchema),
defaultValues: {
// Player Info
playerFirstName: "",
playerLastName: "",
dob: new Date(),
playerEmail: "",
playerPhoneNumber: "",
// Parent Info
parentFirstName: "",
parentLastName: "",
parentEmail: "",
parentPhoneNumber: "",
// Player Details
playerBattingHand: "Right",
playerThrowingHand: "Right",
playerPositions: [],
playerAgeGroup: "",
playerHighSchool: "",
message: "",
},
});
Solution
fixed, just had to switch from
onSelect={field.onChange}
to onSelect={field.onChange as unknown as SelectSingleEventHandler | undefined}
and the build ran