Created
May 6, 2023 21:54
-
-
Save Makisuo/be41d5d9a2b7fa1c8d82b8c4452f20ca to your computer and use it in GitHub Desktop.
Shadcn Combopicker
This file contains hidden or 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
"use client"; | |
import { useState } from "react"; | |
import { format } from "date-fns"; | |
import { CalendarIcon, Check } from "lucide-react"; | |
import { | |
Select, | |
SelectContent, | |
SelectItem, | |
SelectTrigger, | |
SelectValue | |
} from "@/components/ui/select"; | |
import { CustomDatePicker } from "./CustomDatePicker"; | |
type Interval = { | |
name: string; | |
interval: string; | |
}; | |
const intervals: Interval[] = [ | |
{ name: "Last 24 hours", interval: "24h" }, | |
{ name: "Last 7 days", interval: "7d" }, | |
{ name: "Last 14 days", interval: "14d" }, | |
{ name: "Last 30 days", interval: "30d" }, | |
{ name: "Last 3 months", interval: "3m" }, | |
{ name: "Last 6 months", interval: "6m" }, | |
{ name: "Last 12 months", interval: "1y" } | |
]; | |
export const DatePicker = () => { | |
const [value, setValue] = useState(intervals[0].interval); | |
const [dateRange, setDateRange] = useState<{ from: Date; to: Date } | undefined>( | |
undefined | |
); | |
return ( | |
<Select | |
value={value} | |
onValueChange={(value) => { | |
setDateRange(undefined); | |
setValue(value); | |
}} | |
> | |
<SelectTrigger> | |
<CalendarIcon className="mr-2 h-4 w-4" /> | |
{dateRange ? ( | |
<> | |
{format(dateRange.from, "LLL dd, y")} - {format(dateRange.to, "LLL dd, y")} | |
</> | |
) : ( | |
<SelectValue placeholder="Select a plan" /> | |
)} | |
</SelectTrigger> | |
<SelectContent> | |
{intervals.map((interval) => ( | |
<SelectItem | |
value={interval.interval} | |
key={interval.name} | |
> | |
<p className="font-medium">{interval.name}</p> | |
</SelectItem> | |
))} | |
<div className="relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none hover:bg-accent hover:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50"> | |
{value === "custom" && ( | |
<span className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center"> | |
<Check className="h-4 w-4" /> | |
</span> | |
)} | |
<CustomDatePicker | |
onSave={(dateRange) => { | |
setDateRange(dateRange); | |
setValue("custom"); | |
}} | |
></CustomDatePicker> | |
</div> | |
</SelectContent> | |
</Select> | |
); | |
}; |
This file contains hidden or 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
"use client"; | |
import { useState } from "react"; | |
import { subDays } from "date-fns"; | |
import { DateRange } from "react-day-picker"; | |
import { cn } from "@/lib/utils"; | |
import { Button } from "@/components/ui/button"; | |
import { Calendar } from "@/components/ui/calendar"; | |
import { | |
Dialog, | |
DialogClose, | |
DialogContent, | |
DialogTrigger | |
} from "@/components/ui/dialog"; | |
interface CustomDatePickerProps { | |
className?: string; | |
onSave?: (data: { from: Date; to: Date }) => void; | |
} | |
export function CustomDatePicker({ className, onSave }: CustomDatePickerProps) { | |
const [date, setDate] = useState<DateRange | undefined>({ | |
from: subDays(new Date(), 20), | |
to: new Date() | |
}); | |
return ( | |
<div className={cn("grid gap-2", className)}> | |
<Dialog> | |
<DialogTrigger asChild> | |
<p className="font-medium">Custom</p> | |
</DialogTrigger> | |
<DialogContent className="w-auto sm:max-w-[1024px]"> | |
<div className="flex flex-col gap-2"> | |
<Calendar | |
initialFocus | |
mode="range" | |
defaultMonth={date?.from} | |
selected={date} | |
onSelect={setDate} | |
numberOfMonths={2} | |
/> | |
<div className="flex w-full flex-row justify-end gap-2"> | |
<DialogClose asChild> | |
<Button variant="secondary">Cancel</Button> | |
</DialogClose> | |
<DialogClose asChild> | |
<Button | |
disabled={!date || !date.from || !date.to} | |
onClick={() => { | |
if (onSave && date && date.from && date.to) { | |
onSave(date as any); | |
} | |
}} | |
> | |
Save | |
</Button> | |
</DialogClose> | |
</div> | |
</div> | |
</DialogContent> | |
</Dialog> | |
</div> | |
); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment