Capítulo 33 de 108
Não é um componente próprio: é o padrão de composição entre Popover e Calendar para criar um seletor de data (ou data+hora) acionado por um input/botão.
Popover > PopoverTrigger (geralmente um Button via render) > PopoverContent > Calendar. Não existe <DatePicker> root.Button) como trigger, preservando comportamento de acessibilidade do Popover.data-[empty=true]:text-muted-foreground).format(date, "PPP")).setOpen(false) dentro de onSelect).Date.const [date, setDate] = React.useState<Date>()
<Popover>
<PopoverTrigger
render={
<Button variant="outline" data-empty={!date}
className="justify-start text-left font-normal data-[empty=true]:text-muted-foreground" />
}
>
<CalendarIcon />
{date ? format(date, "PPP") : <span>Pick a date</span>}
</PopoverTrigger>
<PopoverContent className="w-auto p-0">
<Calendar mode="single" selected={date} onSelect={setDate} />
</PopoverContent>
</Popover>
const [date, setDate] = React.useState<DateRange | undefined>({
from: new Date(new Date().getFullYear(), 0, 20),
to: addDays(new Date(new Date().getFullYear(), 0, 20), 20),
})
<Calendar mode="range" defaultMonth={date?.from} selected={date} onSelect={setDate} numberOfMonths={2} />
from e to estão preenchidos.<Calendar
mode="single"
selected={date}
defaultMonth={date}
captionLayout="dropdown"
onSelect={(date) => {
setDate(date)
setOpen(false)
}}
/>
<InputGroupInput
value={value}
onChange={(e) => {
const date = new Date(e.target.value)
setValue(e.target.value)
if (isValidDate(date)) { setDate(date); setMonth(date) }
}}
onKeyDown={(e) => {
if (e.key === "ArrowDown") { e.preventDefault(); setOpen(true) }
}}
/>
<DatePicker> pronto: não existe; a composição Popover+Calendar é a API pretendida.open/onOpenChange quando o UX exige fechar ao selecionar: sem controle explícito do estado open, o popover permanece aberto após onSelect.data-empty + data-[empty=true]: é o idiom para estilizar estado vazio do trigger sem lógica condicional de className.onSelect, não comportamento built-in.<Input type="time">), e natural language (via chrono-node).dir tanto no Button/trigger quanto no PopoverContent e no Calendar, além de trocar locale do date-fns e do react-day-picker.