{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "retro-date-range-picker",
  "title": "RetroDateRangePicker",
  "description": "A Mac OS 9 styled date range picker with two inline text inputs, en-dash separator, calendar icon trigger, and a two-month popover calendar for range selection.",
  "dependencies": [
    "date-fns",
    "react-day-picker"
  ],
  "registryDependencies": [
    "https://nostalgia-ui.com/r/nostalgia-theme.json",
    "https://nostalgia-ui.com/r/retro-popover.json",
    "https://nostalgia-ui.com/r/retro-calendar.json",
    "https://nostalgia-ui.com/r/retro-date-picker.json"
  ],
  "files": [
    {
      "path": "registry/new-york/ui/retro-date-range-picker.tsx",
      "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { format, parse, isValid } from \"date-fns\"\nimport type { DateRange } from \"react-day-picker\"\n\nimport { cn } from \"@/lib/utils\"\nimport { CalendarIcon } from \"@/registry/new-york/ui/retro-date-picker\"\nimport { RetroCalendar } from \"@/registry/new-york/ui/retro-calendar\"\nimport {\n  RetroPopover,\n  RetroPopoverTrigger,\n  RetroPopoverContent,\n} from \"@/registry/new-york/ui/retro-popover\"\n\n// Spread rather than a literal `asChild` attribute: the shadcn CLI rewrites\n// literal `asChild` to Base UI's `render` prop in base-* projects, which\n// breaks these Radix-based components.\nconst AS_CHILD = { asChild: true } as const\n\ninterface RetroDateRangePickerProps {\n  /** The selected date range (controlled) */\n  value?: DateRange\n  /** Callback when the date range changes */\n  onChange?: (range: DateRange | undefined) => void\n  /** Placeholder text for each field */\n  placeholder?: { from?: string; to?: string }\n  /** Whether the picker is disabled */\n  disabled?: boolean\n  /** Number of months to display (default 2) */\n  numberOfMonths?: number\n  /** Additional class names */\n  className?: string\n}\n\nconst DATE_FORMAT = \"MM/dd/yyyy\"\n\nconst RetroDateRangePicker = React.forwardRef<\n  HTMLDivElement,\n  RetroDateRangePickerProps\n>(function RetroDateRangePicker(\n  {\n    value,\n    onChange,\n    placeholder,\n    disabled = false,\n    numberOfMonths = 2,\n    className,\n  },\n  ref\n) {\n  const [open, setOpen] = React.useState(false)\n  const [internalRange, setInternalRange] = React.useState<\n    DateRange | undefined\n  >(undefined)\n  const [fromInput, setFromInput] = React.useState(\"\")\n  const [toInput, setToInput] = React.useState(\"\")\n\n  const isControlled = value !== undefined\n  const selectedRange = isControlled ? value : internalRange\n\n  // Depend on timestamps (not object identity) so an inline `value` prop\n  // doesn't reset the inputs on every parent render while the user types.\n  const fromTime = selectedRange?.from?.getTime()\n  const toTime = selectedRange?.to?.getTime()\n\n  // Sync input text with range\n  React.useEffect(() => {\n    setFromInput(fromTime !== undefined ? format(new Date(fromTime), DATE_FORMAT) : \"\")\n  }, [fromTime])\n  React.useEffect(() => {\n    setToInput(toTime !== undefined ? format(new Date(toTime), DATE_FORMAT) : \"\")\n  }, [toTime])\n\n  function commitRange(range: DateRange | undefined) {\n    if (!isControlled) {\n      setInternalRange(range)\n    }\n    onChange?.(range)\n  }\n\n  function handleCalendarSelect(range: DateRange | undefined) {\n    commitRange(range)\n    // Close when both dates are selected\n    if (range?.from && range?.to) {\n      setOpen(false)\n    }\n  }\n\n  function parseInput(text: string): Date | undefined {\n    if (text.trim() === \"\") return undefined\n    const parsed = parse(text, DATE_FORMAT, new Date())\n    if (isValid(parsed) && parsed.getFullYear() > 1900 && parsed.getFullYear() < 2100) {\n      return parsed\n    }\n    return undefined\n  }\n\n  function handleFromCommit() {\n    const parsed = parseInput(fromInput)\n    if (parsed) {\n      if (parsed.getTime() === fromTime) {\n        setFromInput(format(parsed, DATE_FORMAT))\n        return\n      }\n      commitRange({ from: parsed, to: selectedRange?.to })\n    } else if (fromInput.trim() === \"\") {\n      if (fromTime === undefined) return\n      commitRange(\n        selectedRange?.to ? { from: undefined, to: selectedRange.to } : undefined\n      )\n    } else {\n      setFromInput(selectedRange?.from ? format(selectedRange.from, DATE_FORMAT) : \"\")\n    }\n  }\n\n  function handleToCommit() {\n    const parsed = parseInput(toInput)\n    if (parsed) {\n      if (parsed.getTime() === toTime) {\n        setToInput(format(parsed, DATE_FORMAT))\n        return\n      }\n      commitRange({ from: selectedRange?.from, to: parsed })\n    } else if (toInput.trim() === \"\") {\n      if (toTime === undefined) return\n      commitRange(\n        selectedRange?.from ? { from: selectedRange.from, to: undefined } : undefined\n      )\n    } else {\n      setToInput(selectedRange?.to ? format(selectedRange.to, DATE_FORMAT) : \"\")\n    }\n  }\n\n  const inputClasses = cn(\n    \"h-[24px] w-[110px] px-[5px]\",\n    \"font-[family-name:var(--os9-font-sans)] text-[11px] text-os9-black\",\n    \"border border-os9-black bg-os9-white\",\n    \"shadow-[inset_1px_1px_0_var(--os9-gray-700),inset_-1px_-1px_0_var(--os9-white)]\",\n    \"outline-none transition-none\",\n    \"focus:shadow-[0_2px_0_0_var(--os9-focus),2px_0_0_0_var(--os9-focus),0_-2px_0_0_var(--os9-focus),-2px_0_0_0_var(--os9-focus),0_0_0_1px_var(--os9-focus)]\",\n    \"disabled:cursor-not-allowed disabled:opacity-50 disabled:bg-os9-gray-200 disabled:text-os9-gray-600\"\n  )\n\n  return (\n    <RetroPopover open={open} onOpenChange={setOpen}>\n      <div\n        ref={ref}\n        className={cn(\"inline-flex items-center gap-0\", className)}\n      >\n        {/* From date input */}\n        <input\n          type=\"text\"\n          value={fromInput}\n          onChange={(e) => setFromInput(e.target.value)}\n          onBlur={handleFromCommit}\n          onKeyDown={(e) => e.key === \"Enter\" && handleFromCommit()}\n          placeholder={placeholder?.from ?? \"MM/DD/YYYY\"}\n          disabled={disabled}\n          aria-label=\"Start date\"\n          className={inputClasses}\n        />\n\n        {/* Separator */}\n        <span\n          className={cn(\n            \"inline-flex items-center justify-center\",\n            \"h-[24px] w-[28px]\",\n            \"font-[family-name:var(--os9-font-sans)] text-[11px] text-os9-gray-700\",\n            \"select-none\"\n          )}\n        >\n          &ndash;\n        </span>\n\n        {/* To date input */}\n        <input\n          type=\"text\"\n          value={toInput}\n          onChange={(e) => setToInput(e.target.value)}\n          onBlur={handleToCommit}\n          onKeyDown={(e) => e.key === \"Enter\" && handleToCommit()}\n          placeholder={placeholder?.to ?? \"MM/DD/YYYY\"}\n          disabled={disabled}\n          aria-label=\"End date\"\n          className={inputClasses}\n        />\n\n        {/* Calendar trigger */}\n        <RetroPopoverTrigger {...AS_CHILD}>\n          <button\n            type=\"button\"\n            disabled={disabled}\n            aria-label=\"Choose date range\"\n            className={cn(\n              \"inline-flex items-center justify-center\",\n              \"h-[24px] w-[28px] p-0 -ml-px\",\n              \"border border-os9-black bg-os9-gray-300\",\n              \"shadow-[inset_1px_1px_0_var(--os9-white),inset_-1px_-1px_0_var(--os9-gray-700)]\",\n              \"cursor-pointer select-none transition-none\",\n              \"active:shadow-[inset_1px_1px_0_var(--os9-gray-700),inset_-1px_-1px_0_var(--os9-white)]\",\n              \"focus-visible:os9-focus-ring\",\n              \"disabled:pointer-events-none disabled:opacity-50\"\n            )}\n          >\n            <CalendarIcon />\n          </button>\n        </RetroPopoverTrigger>\n      </div>\n      <RetroPopoverContent className=\"w-auto p-0\" align=\"start\">\n        <RetroCalendar\n          mode=\"range\"\n          selected={selectedRange}\n          onSelect={handleCalendarSelect}\n          numberOfMonths={numberOfMonths}\n          defaultMonth={selectedRange?.from}\n          autoFocus\n        />\n      </RetroPopoverContent>\n    </RetroPopover>\n  )\n})\nRetroDateRangePicker.displayName = \"RetroDateRangePicker\"\n\nexport { RetroDateRangePicker }\nexport type { RetroDateRangePickerProps }\n",
      "type": "registry:ui"
    }
  ],
  "type": "registry:ui"
}