Last active
July 27, 2024 21:36
-
-
Save tsulatsitamim/90cae8a4ef6afccf8bf6ff150c798493 to your computer and use it in GitHub Desktop.
Shadcn Month Picker
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { Dispatch, SetStateAction, useState } from "react" | |
import { Popover, PopoverContent, PopoverTrigger } from "@components/ui/popover" | |
import { Button } from "@components/ui/button" | |
import { CalendarIcon, ChevronLeft } from "lucide-react" | |
const months = new Array(12) | |
.fill(0) | |
.map((_, i) => | |
new Intl.DateTimeFormat("id-ID", { month: "short" }).format( | |
new Date(2000, i, 1) | |
) | |
) | |
export const MonthPicker = ({ | |
selected, | |
onChange, | |
}: { | |
selected?: Date | |
onChange: Dispatch<SetStateAction<Date>> | |
}) => { | |
const [isOpen, setIsOpen] = useState(false) | |
const [currentYear, setCurrentYear] = useState( | |
selected?.getFullYear() || new Date().getFullYear() | |
) | |
return ( | |
<Popover open={isOpen} onOpenChange={setIsOpen}> | |
<PopoverTrigger asChild> | |
<Button | |
variant={"outline"} | |
className="w-full pl-3 text-left font-normal" | |
> | |
{selected ? ( | |
new Intl.DateTimeFormat("id-ID", { | |
year: "numeric", | |
month: "long", | |
}).format(selected) | |
) : ( | |
<span>Pick a month</span> | |
)} | |
<CalendarIcon className="ml-2 h-4 w-4 opacity-50" /> | |
</Button> | |
</PopoverTrigger> | |
<PopoverContent className="w-auto p-0 mr-5" align="start"> | |
<div className="p-3"> | |
<div className="mb-2 flex justify-between items-center"> | |
<button | |
onClick={() => setCurrentYear(currentYear - 1)} | |
className="p-2 hover:bg-primary hover:text-primary-foreground rounded" | |
> | |
<ChevronLeft className="h-4 w-4"></ChevronLeft> | |
</button> | |
<div className="font-medium text-center">{currentYear}</div> | |
<button | |
onClick={() => setCurrentYear(currentYear + 1)} | |
className="p-2 hover:bg-primary hover:text-primary-foreground rounded rotate-180" | |
> | |
<ChevronLeft className="h-4 w-4"></ChevronLeft> | |
</button> | |
</div> | |
<div className="grid grid-cols-3 gap-0.5"> | |
{months.map((month, i) => ( | |
<div key={month}> | |
<button | |
className={`w-full text-sm rounded py-2 px-4 hover:bg-primary/90 hover:text-primary-foreground ${ | |
currentYear === selected?.getFullYear() && | |
i === selected?.getMonth() && | |
"bg-primary text-primary-foreground" | |
}`} | |
onClick={() => { | |
onChange(new Date(currentYear, i, 1)) | |
setIsOpen(false) | |
}} | |
> | |
{month} | |
</button> | |
</div> | |
))} | |
</div> | |
</div> | |
</PopoverContent> | |
</Popover> | |
) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment