Calendar
Uma grade de datas para seleção única, de intervalo e múltipla, com meses deslizantes, prévias de intervalo e dias com tamanho adequado ao toque.
| Su | Mo | Tu | We | Th | Fr | Sa |
|---|---|---|---|---|---|---|
pnpm dlx shadcn@latest add https://hextaui.com/r/calendar.jsonAdiciona o componente, os tokens de tema do HextaUI e quaisquer componentes do HextaUI dos quais ele depende.
Adicione os tokens de tema ao seu CSS global, se ainda não o fez.
Instale as dependências.
pnpm add react-day-picker @base-ui/react @tabler/icons-react class-variance-authority cnCopie e cole o código a seguir no seu projeto.
components/ui/calendar.tsx components/ui/button.tsx lib/motion.ts Atualize os caminhos de importação para corresponder à configuração do seu projeto.
Calendar envolve o <DayPicker /> do react-day-picker, então toda prop do DayPicker funciona como documentado em daypicker.dev. O HextaUI adiciona estilo, transições de mês, uma prévia de intervalo e um today seguro para hidratação.
Intervalo
Com mode="range", depois do primeiro clique, passar o mouse ou focar um dia mostra uma prévia do intervalo que o próximo clique selecionará. numberOfMonths exibe meses lado a lado, empilhados em telas estreitas.
Limites do intervalo
min e max limitam o tamanho do intervalo em dias. Com excludeDisabled, um intervalo que incluiria um dia desativado recomeça.
Múltiplo
mode="multiple" alterna dias individuais. max limita quantos podem ser selecionados.
Dropdowns de mês e ano
captionLayout="dropdown" substitui a legenda por selects nativos, então os celulares ganham o próprio seletor. Defina startMonth e endMonth para limitar os anos.
Limitado
A navegação para em startMonth e endMonth, e disabled bloqueia os dias fora da janela. useToday() fornece um today que é seguro de usar durante a renderização no servidor.
Mês controlado
Passe month e onMonthChange para controlar o mês visível. Saltos deslizam na direção do deslocamento e a altura se ajusta suavemente entre linhas de 5 e 6 semanas.
Números de semana
showWeekNumber adiciona uma coluna de semana. ISOWeek usa a numeração ISO, começando na segunda-feira. showOutsideDays={false} oculta os dias de outros meses.
Today fixo
Passe today para fixar o dia destacado, em testes ou outro fuso horário. animate={false} desativa as transições de mês.
Dentro de uma sheet
Dentro de um sheet, popover ou diálogo, o calendário abre mão do próprio fundo e se mistura com a superfície.
Da direita para a esquerda
Passe um locale de react-day-picker/locale e dir="rtl". As setas, a navegação e a direção do deslize são todas espelhadas. Dentro de um DirectionProvider com dir="rtl", a direção é detectada automaticamente.
Foque um dia e use estas teclas. Passar do mês visível muda o mês.
| Tecla | Ação |
|---|---|
| ←→ | Dia anterior ou seguinte. Invertido em layouts da direita para a esquerda. |
| ↑↓ | O mesmo dia da semana anterior ou seguinte. |
| Shift←→ | Mês anterior ou seguinte. |
| Shift↑↓ | Ano anterior ou seguinte. |
| Page UpPage Down | Mês anterior ou seguinte. |
| ShiftPage UpPage Down | Ano anterior ou seguinte. |
| Home | Primeiro dia da semana. |
| End | Último dia da semana. |
| EnterSpace | Seleciona o dia em foco. |
- O mês é uma grade. Cada dia é um botão com um rótulo de data completo, e os dias selecionados definem
aria-selected. - Mudanças de mês feitas pelo teclado pulam o deslize e apenas fazem fade, para que o foco nunca se mova sob uma grade em movimento.
- Com movimento reduzido, as mudanças de mês aparecem com fade e a mudança de altura é instantânea.
- Em telas sensíveis ao toque, as células de dia crescem para 44px.
Aceita todas as props de <DayPicker />. Os padrões abaixo diferem dos do DayPicker ou são adicionados pelo HextaUI.
| Prop | Tipo | Padrão |
|---|---|---|
modeSem um mode, os dias não são selecionáveis. | "single" | "multiple" | "range" | – |
selectedCorresponde ao mode. | Date | Date[] | DateRange | – |
onSelect | (selected, triggerDate, modifiers, event) => void | – |
requiredImpede desmarcar a última seleção. | boolean | – |
minMínimo de dias em um intervalo, ou selecionados no modo multiple. | number | – |
maxMáximo de dias em um intervalo, ou selecionados no modo multiple. | number | – |
excludeDisabledModo de intervalo. | boolean | – |
disabled | Matcher | Matcher[] | – |
monthMês controlado. | Date | – |
defaultMonth | Date | – |
onMonthChange | (month: Date) => void | – |
startMonth | Date | – |
endMonth | Date | – |
numberOfMonths | number | 1 |
captionLayout | "label" | "dropdown" | "dropdown-months" | "dropdown-years" | "label" |
navLayoutPadrão do HextaUI. As setas ficam em cada lado da legenda. | "around" | "after" | "around" |
showOutsideDaysPadrão do HextaUI. | boolean | true |
animateTransições de deslize e de altura do mês. Padrão do HextaUI. | boolean | true |
buttonVariantVariant dos botões de anterior e seguinte. | Button variant | "ghost" |
showWeekNumber | boolean | false |
ISOWeek | boolean | false |
weekStartsOn | 0 | 1 | 2 | 3 | 4 | 5 | 6 | – |
fixedWeeks | boolean | false |
todayO padrão é o today do cliente, mantido em sincronia na virada da meia-noite e na hidratação. | Date | – |
timeZone | string | – |
locale | Partial<DayPickerLocale> | – |
dir | "ltr" | "rtl" | – |
footer | ReactNode | – |
| Atributo | Descrição |
|---|---|
data-slot="calendar" | Seleciona a raiz do calendário no CSS. |
--cell-size | Tamanho da célula de dia. 36px, ou 44px em telas sensíveis ao toque. |
--cell-radius | Raio dos cantos das células e dos botões de dia. |
data-slot="calendar-day" | Células de dia. Carregam data-selected, data-disabled, data-outside, data-today, data-hidden e data-focused. |
data-preview | Nas células de dia: início, meio ou fim da prévia do intervalo sob o mouse. |
data-range-middle | Nas células de dia dentro de um intervalo selecionado. |
O botão dentro de cada dia. Passe o seu para components={{ DayButton }} e reutilize este para manter o estilo.
| Atributo | Descrição |
|---|---|
data-slot="calendar-day-button" | Seleciona os botões de dia no CSS. |
data-day | A data ISO, como 2026-10-03. |
data-today | Presente em today, excluindo os dias de fora. |
data-selected-single | Selecionado fora de um intervalo. |
data-range-start | Primeiro dia do intervalo. |
data-range-middle | Um dia dentro do intervalo. |
data-range-end | Último dia do intervalo. |
Retorna today como um Date no cliente e undefined durante a renderização no servidor, então limites construídos a partir dele nunca causam divergência de hidratação. Atualiza à meia-noite. Veja o guia do useToday.
- ButtonBotões em todas as variantes e tamanhos, com um fluxo integrado de carregamento, sucesso e erro que dispensa o spinner em requisições rápidas.
- MotionAs curvas de easing, as durações e a verificação de movimento reduzido com que todo componente anima, além de hooks para transformações de tamanho e destaques deslizantes.
- useTodayA data de hoje, que se atualiza à meia-noite e quando a aba volta, sem divergência de hidratação.
- CheckboxUma caixa de seleção cujo check é desenhado na tela, com pais indeterminados, grupos e rótulos que compartilham seu hover.
- ComboboxUm select filtrável com chips, grupos e resultados assíncronos, em um popup que se redimensiona conforme você digita.
- Date pickerUm botão que abre um calendário em um popover, ou em um bottom sheet no celular, para datas únicas e intervalos.