Skip to content

Instantly share code, notes, and snippets.

@tsulatsitamim
Last active July 27, 2024 21:36
Show Gist options
  • Save tsulatsitamim/90cae8a4ef6afccf8bf6ff150c798493 to your computer and use it in GitHub Desktop.
Save tsulatsitamim/90cae8a4ef6afccf8bf6ff150c798493 to your computer and use it in GitHub Desktop.
Shadcn Month Picker
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