- Gallery
- Forms & Input
- Date Range Picker
PremiumNew
Date Range Picker
A date range selector with preset ranges and custom date selection.
Forms & Inputdaterangepickercalendarfilter
Dependencies
Other dependencies:
@/components/ui/button@/components/ui/card@/components/ui/popover@/components/ui/calendar@/components/ui/separator
How to use this component
Copy the code below into your project. Make sure you have the required shadcn/ui dependencies installed. Then import and use the component in your pages or layouts.
Code
1"use client";23import { useState } from 'react';4import { Button } from '@/components/ui/button';5import { Card } from '@/components/ui/card';6import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover';7import { Calendar } from '@/components/ui/calendar';8import { Separator } from '@/components/ui/separator';9import { CalendarDays } from 'lucide-react';10import { format } from 'date-fns';1112export default function DateRangePicker() {13 const [open, setOpen] = useState(false);14 const [selectedRange, setSelectedRange] = useState('Last 7 days');15 const [startDate, setStartDate] = useState<Date | undefined>(new Date(Date.now() - 7 * 24 * 60 * 60 * 1000));16 const [endDate, setEndDate] = useState<Date | undefined>(new Date());1718 const presets = [19 { label: 'Today', range: 'Today' },20 { label: 'Last 7 days', range: 'Last 7 days' },21 { label: 'Last 30 days', range: 'Last 30 days' },22 { label: 'This month', range: 'This month' },23 { label: 'This year', range: 'This year' }24 ];2526 const handlePresetClick = (preset: typeof presets[0]) => {27 setSelectedRange(preset.range);28 const now = new Date();29 setEndDate(now);30 31 switch (preset.range) {32 case 'Today':33 setStartDate(now);34 break;35 case 'Last 7 days':36 setStartDate(new Date(now.getTime() - 7 * 24 * 60 * 60 * 1000));37 break;38 case 'Last 30 days':39 setStartDate(new Date(now.getTime() - 30 * 24 * 60 * 60 * 1000));40 break;41 case 'This month':42 setStartDate(new Date(now.getFullYear(), now.getMonth(), 1));43 break;44 case 'This year':45 setStartDate(new Date(now.getFullYear(), 0, 1));46 break;47 }48 };4950 return (51 <Popover open={open} onOpenChange={setOpen}>52 <PopoverTrigger asChild>53 <Button variant="outline" className="w-full justify-start text-left font-normal">54 <CalendarDays className="mr-2 h-4 w-4" />55 {startDate && endDate ? (56 <span>57 {format(startDate, 'MMM dd, yyyy')} - {format(endDate, 'MMM dd, yyyy')}58 </span>59 ) : (60 <span>Pick a date range</span>61 )}62 </Button>63 </PopoverTrigger>64 <PopoverContent className="w-auto p-0" align="start">65 <Card className="border-0 shadow-none">66 <CardContent className="p-0">67 <div className="flex">68 <div className="w-40 border-r p-3 space-y-1">69 {presets.map(preset => (70 <Button71 key={preset.range}72 variant={selectedRange === preset.range ? 'secondary' : 'ghost'}73 className="w-full justify-start text-sm"74 onClick={() => handlePresetClick(preset)}75 >76 {preset.label}77 </Button>78 ))}79 </div>80 <div className="p-4 min-w-[280px]">81 <div className="space-y-4">82 <div>83 <p className="text-sm font-medium mb-2">Start Date</p>84 <Calendar85 mode="single"86 selected={startDate}87 onSelect={setStartDate}88 className="rounded-md border"89 />90 </div>91 <Separator />92 <div>93 <p className="text-sm font-medium mb-2">End Date</p>94 <Calendar95 mode="single"96 selected={endDate}97 onSelect={setEndDate}98 className="rounded-md border"99 />100 </div>101 </div>102 </div>103 </div>104 <Separator />105 <div className="flex justify-end gap-2 p-3">106 <Button variant="outline" size="sm" onClick={() => setOpen(false)}>107 Cancel108 </Button>109 <Button size="sm" onClick={() => setOpen(false)}>110 Apply111 </Button>112 </div>113 </CardContent>114 </Card>115 </PopoverContent>116 </Popover>117 );118}