PILOT // NEXTUI
DateRangePicker
Dropdown date range selector with preset intervals (7, 14, 30, 90 days). Displays the computed date range in the trigger button and closes on route change. Client component.
$
Or install the base component for free:
Live Preview
Usage
TSX
<DateRangePicker />Source
TSX
'use client'
import { useState, useEffect } from 'react'
import { usePathname } from 'next/navigation'
import type * as React from 'react'
import { cn } from '@/lib/utils'
const RANGES = [
{ label: 'Last 7 days', value: '7d' },
{ label: 'Last 14 days', value: '14d' },
{ label: 'Last 30 days', value: '30d' },
{ label: 'Last 90 days', value: '90d' },
]
function getDisplay(value: string): string {
const days = parseInt(value)
const end = new Date()
const start = new Date()
start.setDate(end.getDate() - (days - 1))
const fmt = (d: Date) => d.toLocaleDateString('en-US', { month: 'short', day: 'numeric', year: 'numeric' })
return `${fmt(start)} \u2013 ${fmt(end)}`
}
export function DateRangePicker(): React.JSX.Element {
const [open, setOpen] = useState(false)
const [active, setActive] = useState(RANGES[0])
const pathname = usePathname()
useEffect(() => { setOpen(false) }, [pathname])
function select(range: typeof RANGES[number]) {
setActive(range)
setOpen(false)
}
return (
<div className="pilot-dropdown-wrap">
<button
type="button"
className="pilot-btn pilot-btn-ghost pilot-daterange-btn"
aria-expanded={open}
onClick={() => setOpen((v) => !v)}
>
<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
<rect x="3" y="4" width="18" height="18" rx="2" ry="2" />
<line x1="16" y1="2" x2="16" y2="6" />
<line x1="8" y1="2" x2="8" y2="6" />
<line x1="3" y1="10" x2="21" y2="10" />
</svg>
{getDisplay(active.value)}
<svg className={cn('pilot-daterange-chevron', { open })} width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
<polyline points="6 9 12 15 18 9" />
</svg>
</button>
{open && (
<>
<div className="pilot-dropdown-overlay" onClick={() => setOpen(false)} aria-hidden="true" />
<div className="pilot-dropdown pilot-daterange-menu" role="listbox" aria-label="Select date range">
{RANGES.map((r) => (
<button
key={r.value}
type="button"
role="option"
aria-selected={active.value === r.value}
className={cn('pilot-daterange-option', { active: active.value === r.value })}
onClick={() => select(r)}
>
<span className="pilot-daterange-option-label">{r.label}</span>
<span className="pilot-daterange-option-display">{getDisplay(r.value)}</span>
{active.value === r.value && (
<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
<polyline points="20 6 9 17 4 12" />
</svg>
)}
</button>
))}
</div>
</>
)}
</div>
)
}
Works withNext.js 15React 19Tailwind v4TypeScript 5
More from PILOT // NEXT
Button
Dashboard button with primary, secondary, and ghost variants in three sizes. Handles disabled links by rendering an aria-disabled span instead of a Link.
View sourceNo preview
CopyField
Read-only code field with a one-click copy-to-clipboard button. Shows a checkmark and "Copied!" confirmation for 2 seconds after copying. Client component.
View sourceNo preview