Date Field
Campo para digitar uma data (DateField) ou um horário (TimeField) por segmentos, sem ambiguidade de formato.
'use client';
import { I18nProvider } from 'react-aria-components';
import { DateField } from '@/components/ui/date-field';
export default function DateFieldDemo() {
return (
<I18nProvider locale="pt-BR">
<DateField label="Data de nascimento" description="Formato dd/mm/aaaa." className="w-72" />
</I18nProvider>
);
}Instalação
npx shadcn@latest add @lenstech/date-fieldUso
import { I18nProvider } from "react-aria-components"
import { DateField, TimeField } from "@/components/ui/date-field"<I18nProvider locale="pt-BR">
<DateField label="Data de nascimento" name="nascimento" />
</I18nProvider>Cada parte da data (dia, mês, ano) é um segmento: o usuário digita os números ou usa as setas ↑/↓ para ajustar.
O formato segue o idioma — em pt-BR, dd/mm/aaaa.
Datas são CalendarDate, não Date
O valor é um objeto do pacote @internationalized/date, não um Date do JavaScript:
DateFieldsem hora →CalendarDate; comgranularity="hour"/"minute"→CalendarDateTime(ouZonedDateTime, se o valor tiver fuso).TimeField→Time(new Time(14, 30)).- Criar:
parseDate("2026-10-15"),today(getLocalTimeZone()),parseDateTime("2026-10-15T09:00"). - Enviar para a API:
valor.toString()→"2026-10-15"(ISO). - Converter para
Date:valor.toDate(getLocalTimeZone()).
Em formulários com name, o valor enviado já é a string ISO.
Exemplos
Horário (TimeField)
TimeField usa Time e aceita minValue/maxValue — útil para horário de atendimento ou agendamento.
'use client';
import { Time } from '@internationalized/date';
import { I18nProvider } from 'react-aria-components';
import { TimeField } from '@/components/ui/date-field';
export default function DateFieldTime() {
return (
<I18nProvider locale="pt-BR">
<TimeField
label="Horário do atendimento"
defaultValue={new Time(14, 30)}
minValue={new Time(8)}
maxValue={new Time(18)}
description="Das 08:00 às 18:00."
className="w-72"
/>
</I18nProvider>
);
}Data e hora
Use granularity para incluir hora e minuto. Com um ZonedDateTime, o fuso horário aparece como segmento.
'use client';
import { parseDateTime, parseZonedDateTime } from '@internationalized/date';
import { I18nProvider } from 'react-aria-components';
import { DateField } from '@/components/ui/date-field';
export default function DateFieldGranularity() {
return (
<I18nProvider locale="pt-BR">
<div className="flex w-72 flex-col gap-6">
{/* CalendarDateTime: data + hora, sem fuso horário */}
<DateField
label="Início da manutenção"
granularity="minute"
defaultValue={parseDateTime('2026-10-12T22:00')}
/>
{/* ZonedDateTime: data + hora com fuso (o fuso aparece como segmento) */}
<DateField
label="Publicação agendada"
granularity="minute"
defaultValue={parseZonedDateTime('2026-10-15T09:00[America/Sao_Paulo]')}
/>
</div>
</I18nProvider>
);
}Validação
isRequired, minValue e maxValue validam automaticamente; validate permite regras próprias.
A mensagem de erro aparece abaixo do campo. Clique em Salvar nota para ver a validação do primeiro campo.
'use client';
import { getLocalTimeZone, today } from '@internationalized/date';
import { I18nProvider } from 'react-aria-components';
import { Button } from '@/components/ui/button';
import { DateField } from '@/components/ui/date-field';
import { Form } from '@/components/ui/form';
export default function DateFieldValidation() {
const hoje = today(getLocalTimeZone());
return (
<I18nProvider locale="pt-BR">
<Form className="w-72 gap-4" onSubmit={(e) => e.preventDefault()}>
{/* Validação nativa: aparece ao enviar o formulário */}
<DateField
label="Data de emissão da nota"
name="emissao"
isRequired
maxValue={hoje}
description="Obrigatória; não pode ser uma data futura."
/>
{/* Validação personalizada em tempo real */}
<DateField
label="Vencimento"
name="vencimento"
defaultValue={hoje.subtract({ days: 3 })}
validationBehavior="aria"
validate={(value) => (value && value.compare(hoje) < 0 ? 'O vencimento não pode ser no passado.' : null)}
/>
<Button type="submit" className="self-start">
Salvar nota
</Button>
</Form>
</I18nProvider>
);
}Quando usar
- Use quando o usuário já sabe a data: nascimento, emissão de nota, data de admissão.
- Não use quando ele precisa olhar o calendário para escolher (agendamentos, períodos) — use
Date Picker. - Não use um
Inputde texto com máscara para datas: oDateFieldé acessível, valida e não confunde dd/mm com mm/dd.
API
DateField
Aceita todas as props do DateField do React Aria, mais:
Prop
Type
TimeField
Aceita todas as props do TimeField do React Aria, mais label, description
e errorMessage. O valor é um Time (ou CalendarDateTime/ZonedDateTime, se precisar da data junto).
DateInput
Entrada segmentada usada internamente por DateField, TimeField e DatePicker. Use-a para montar campos personalizados.
Prop
Type