{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "date-picker",
  "title": "Date Picker",
  "description": "Date field that opens a Calendar in a Popover. Controlled or uncontrolled via value/defaultValue and onValueChange; formats the selected date with date-fns and shows a placeholder when empty.",
  "dependencies": [
    "date-fns@^4.4.0",
    "lucide-react@^1.23.0"
  ],
  "registryDependencies": [
    "@ai2/button",
    "@ai2/calendar",
    "@ai2/popover",
    "@ai2/tokens"
  ],
  "files": [
    {
      "path": "registry/ai2/ui/date-picker.tsx",
      "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { format, type Locale } from \"date-fns\"\nimport { Calendar as CalendarIcon } from \"lucide-react\"\n\nimport { cn } from \"@/lib/utils\"\nimport { Button } from \"@/registry/ai2/ui/button\"\nimport { Calendar } from \"@/registry/ai2/ui/calendar\"\nimport {\n  Popover,\n  PopoverContent,\n  PopoverTrigger,\n} from \"@/registry/ai2/ui/popover\"\n\ninterface DatePickerProps\n  extends Omit<React.ComponentProps<typeof Button>, \"value\" | \"defaultValue\" | \"onChange\"> {\n  value?: Date\n  defaultValue?: Date\n  onValueChange?: (date: Date | undefined) => void\n  placeholder?: string\n  /** date-fns locale for the trigger label; also forwarded to the calendar. */\n  locale?: Locale\n  /** date-fns format string for the trigger label. */\n  formatStr?: string\n  /** Extra props forwarded to the inner Calendar (e.g. disabled matchers, startMonth). */\n  calendarProps?: Omit<\n    React.ComponentProps<typeof Calendar>,\n    \"mode\" | \"selected\" | \"onSelect\"\n  >\n}\n\nfunction DatePicker(allProps: DatePickerProps) {\n  const {\n    value,\n    defaultValue,\n    onValueChange,\n    placeholder = \"Pick a date\",\n    locale,\n    formatStr = \"PPP\",\n    calendarProps,\n    className,\n    disabled,\n    ...props\n  } = allProps\n  const [open, setOpen] = React.useState(false)\n  const [internal, setInternal] = React.useState<Date | undefined>(defaultValue)\n  // The controlled split looks at whether the prop is PRESENT: clearing with\n  // value={undefined} was impossible under `value ?? internal` (2026-07-11\n  // audit R27).\n  const controlled = \"value\" in allProps\n  const date = controlled ? value : internal\n\n  const select = (next: Date | undefined) => {\n    if (!controlled) setInternal(next)\n    onValueChange?.(next)\n    setOpen(false)\n  }\n\n  return (\n    <Popover open={open} onOpenChange={setOpen}>\n      <PopoverTrigger asChild>\n        <Button\n          variant=\"outline\"\n          disabled={disabled}\n          data-slot=\"date-picker-trigger\"\n          data-empty={!date}\n          className={cn(\n            \"w-56 justify-start gap-2 font-normal\",\n            !date && \"text-muted-foreground\",\n            className\n          )}\n          {...props}\n        >\n          <CalendarIcon className=\"size-4\" />\n          <span className=\"truncate\">\n            {date ? format(date, formatStr, { locale }) : placeholder}\n          </span>\n        </Button>\n      </PopoverTrigger>\n      <PopoverContent className=\"w-auto p-0\" align=\"start\">\n        <Calendar\n          mode=\"single\"\n          locale={locale}\n          {...calendarProps}\n          selected={date}\n          onSelect={select}\n          autoFocus\n        />\n      </PopoverContent>\n    </Popover>\n  )\n}\n\nexport { DatePicker, type DatePickerProps }\n",
      "type": "registry:ui"
    }
  ],
  "docs": "Single-date picker composed from Calendar + Popover + Button. Read the value from onValueChange; pass defaultValue for uncontrolled use.",
  "categories": [
    "form"
  ],
  "type": "registry:ui"
}