{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "date-range-picker",
  "type": "registry:ui",
  "description": "Date range picker with presets, dual calendars, and customizable options",
  "dependencies": [
    "date-fns",
    "react-day-picker",
    "lucide-react"
  ],
  "registryDependencies": [
    "utils",
    "button",
    "calendar",
    "popover"
  ],
  "files": [
    {
      "path": "registry/default/ui/date-range-picker.tsx",
      "content": "import * as React from 'react'\nimport { format, subDays, startOfMonth, endOfMonth, subMonths } from 'date-fns'\nimport { CalendarIcon } from 'lucide-react'\nimport type { DateRange } from 'react-day-picker'\nimport { cn } from '@/lib/utils'\nimport { Button } from '@/components/ui/button'\nimport { Calendar } from '@/components/ui/calendar'\nimport {\n  Popover,\n  PopoverContent,\n  PopoverTrigger,\n} from '@/components/ui/popover'\n\nexport interface DateRangePickerPreset {\n  label: string\n  value: DateRange\n}\n\nexport interface DateRangePickerProps {\n  value?: DateRange\n  defaultValue?: DateRange\n  onChange?: (range: DateRange | undefined) => void\n  numberOfMonths?: 1 | 2\n  presets?: DateRangePickerPreset[]\n  showPresets?: boolean\n  minDate?: Date\n  maxDate?: Date\n  disabled?: boolean\n  placeholder?: string\n  align?: 'start' | 'center' | 'end'\n  className?: string\n}\n\nconst getDefaultPresets = (): DateRangePickerPreset[] => {\n  const today = new Date()\n  const lastMonth = subMonths(today, 1)\n\n  return [\n    {\n      label: 'Today',\n      value: { from: today, to: today },\n    },\n    {\n      label: 'Last 7 days',\n      value: { from: subDays(today, 6), to: today },\n    },\n    {\n      label: 'Last 30 days',\n      value: { from: subDays(today, 29), to: today },\n    },\n    {\n      label: 'This month',\n      value: { from: startOfMonth(today), to: today },\n    },\n    {\n      label: 'Last month',\n      value: { from: startOfMonth(lastMonth), to: endOfMonth(lastMonth) },\n    },\n  ]\n}\n\nconst DateRangePicker = React.forwardRef<HTMLButtonElement, DateRangePickerProps>(\n  (\n    {\n      value: controlledValue,\n      defaultValue,\n      onChange,\n      numberOfMonths = 2,\n      presets,\n      showPresets = true,\n      minDate,\n      maxDate,\n      disabled = false,\n      placeholder = 'Pick a date range',\n      align = 'start',\n      className,\n    },\n    ref\n  ) => {\n    const [open, setOpen] = React.useState(false)\n    const [uncontrolledValue, setUncontrolledValue] = React.useState<DateRange | undefined>(defaultValue)\n\n    const isControlled = controlledValue !== undefined\n    const selectedRange = isControlled ? controlledValue : uncontrolledValue\n\n    const resolvedPresets = presets ?? getDefaultPresets()\n\n    const handleSelect = (range: DateRange | undefined) => {\n      if (!isControlled) {\n        setUncontrolledValue(range)\n      }\n      onChange?.(range)\n    }\n\n    const handlePresetClick = (preset: DateRangePickerPreset) => {\n      handleSelect(preset.value)\n    }\n\n    const isPresetSelected = (preset: DateRangePickerPreset) => {\n      if (!selectedRange?.from || !selectedRange?.to) return false\n      if (!preset.value.from || !preset.value.to) return false\n\n      return (\n        format(selectedRange.from, 'yyyy-MM-dd') === format(preset.value.from, 'yyyy-MM-dd') &&\n        format(selectedRange.to, 'yyyy-MM-dd') === format(preset.value.to, 'yyyy-MM-dd')\n      )\n    }\n\n    const formatDateRange = (range: DateRange) => {\n      if (!range.from) return placeholder\n      if (!range.to) return format(range.from, 'LLL dd, y')\n      return `${format(range.from, 'LLL dd, y')} - ${format(range.to, 'LLL dd, y')}`\n    }\n\n    // Use single month on mobile\n    const [isMobile, setIsMobile] = React.useState(false)\n\n    React.useEffect(() => {\n      const checkMobile = () => {\n        setIsMobile(window.innerWidth < 640)\n      }\n      checkMobile()\n      window.addEventListener('resize', checkMobile)\n      return () => window.removeEventListener('resize', checkMobile)\n    }, [])\n\n    const effectiveNumberOfMonths = isMobile ? 1 : numberOfMonths\n\n    return (\n      <Popover open={open} onOpenChange={setOpen}>\n        <PopoverTrigger asChild>\n          <Button\n            ref={ref}\n            variant=\"outline\"\n            disabled={disabled}\n            className={cn(\n              'w-full justify-start text-left font-normal',\n              !selectedRange && 'text-muted-foreground',\n              className\n            )}\n          >\n            <CalendarIcon className=\"mr-2 h-4 w-4 shrink-0\" />\n            <span className=\"truncate\">\n              {selectedRange ? formatDateRange(selectedRange) : placeholder}\n            </span>\n          </Button>\n        </PopoverTrigger>\n        <PopoverContent\n          className={cn(\n            'w-auto p-0 overflow-hidden',\n            'shadow-[8px_8px_0px_hsl(var(--shadow-color))]',\n            'animate-in fade-in-0 zoom-in-95 duration-200',\n            'max-w-[calc(100vw-2rem)]',\n            'max-h-[calc(100vh-4rem)] overflow-auto'\n          )}\n          align={align}\n          sideOffset={4}\n        >\n          <div className={cn(\n            'flex',\n            // Stack vertically on mobile\n            isMobile && showPresets ? 'flex-col' : 'flex-row'\n          )}>\n            {/* Presets sidebar/header */}\n            {showPresets && resolvedPresets.length > 0 && (\n              <div className={cn(\n                'p-3 bg-muted/30',\n                isMobile\n                  ? 'border-b-3 border-foreground'\n                  : 'min-w-[130px] border-r-3 border-foreground'\n              )}>\n                <p className=\"mb-2 text-xs font-bold uppercase tracking-wide text-muted-foreground\">\n                  Presets\n                </p>\n                <div className={cn(\n                  isMobile\n                    ? 'flex flex-wrap gap-1'\n                    : 'space-y-1'\n                )}>\n                  {resolvedPresets.map((preset) => (\n                    <button\n                      key={preset.label}\n                      type=\"button\"\n                      onClick={() => handlePresetClick(preset)}\n                      className={cn(\n                        'text-left text-sm transition-all duration-150',\n                        'hover:bg-muted',\n                        isMobile\n                          ? 'px-2 py-1 border-2 border-foreground text-xs'\n                          : 'w-full px-3 py-2',\n                        isPresetSelected(preset) && 'bg-accent font-medium shadow-[2px_2px_0px_hsl(var(--shadow-color))]'\n                      )}\n                    >\n                      {preset.label}\n                    </button>\n                  ))}\n                </div>\n              </div>\n            )}\n\n            {/* Calendar(s) */}\n            <div className=\"p-3\">\n              <Calendar\n                mode=\"range\"\n                defaultMonth={selectedRange?.from}\n                selected={selectedRange}\n                onSelect={handleSelect}\n                numberOfMonths={effectiveNumberOfMonths}\n                disabled={(date) => {\n                  if (minDate && date < minDate) return true\n                  if (maxDate && date > maxDate) return true\n                  return false\n                }}\n                className=\"border-0 shadow-none\"\n              />\n            </div>\n          </div>\n        </PopoverContent>\n      </Popover>\n    )\n  }\n)\nDateRangePicker.displayName = 'DateRangePicker'\n\nexport { DateRangePicker, getDefaultPresets }\nexport type { DateRange }\n",
      "type": "registry:ui",
      "target": "components/ui/date-range-picker.tsx"
    }
  ]
}