Calendar
Une grille de dates pour la sélection simple, de plage et multiple, avec des mois qui défilent, des aperçus de plage et des jours à taille tactile.
| Su | Mo | Tu | We | Th | Fr | Sa |
|---|---|---|---|---|---|---|
pnpm dlx shadcn@latest add https://hextaui.com/r/calendar.jsonAjoute le composant, les tokens de thème HextaUI et les composants HextaUI dont il dépend.
Ajoutez les tokens de thème à votre CSS global, si ce n’est pas déjà fait.
Installez les dépendances.
pnpm add react-day-picker @base-ui/react @tabler/icons-react class-variance-authority cnCopiez et collez le code suivant dans votre projet.
components/ui/calendar.tsx components/ui/button.tsx lib/motion.ts Mettez à jour les chemins d’import selon la configuration de votre projet.
Calendar enveloppe le <DayPicker /> de react-day-picker : toutes les props de DayPicker fonctionnent comme documenté sur daypicker.dev. HextaUI ajoute le style, les transitions de mois, un aperçu de plage et un today compatible avec l’hydratation.
Plage
Avec mode="range", après le premier clic, survoler ou mettre le focus sur un jour affiche un aperçu de la plage que le prochain clic sélectionnera. numberOfMonths affiche les mois côte à côte, empilés sur les écrans étroits.
Limites de la plage
min et max limitent la longueur de la plage en jours. Avec excludeDisabled, une plage qui inclurait un jour désactivé repart de zéro.
Multiple
mode="multiple" bascule les jours individuellement. max plafonne le nombre de jours sélectionnables.
Listes déroulantes du mois et de l’année
captionLayout="dropdown" remplace la légende par des select natifs, ce qui offre aux téléphones leur propre sélecteur. Définissez startMonth et endMonth pour borner les années.
Bornée
La navigation s’arrête à startMonth et endMonth, et disabled bloque les jours en dehors de la fenêtre. useToday() fournit un today utilisable sans risque pendant le rendu serveur.
Mois contrôlé
Passez month et onMonthChange pour piloter le mois visible. Les sauts glissent dans le sens du déplacement et la hauteur s’adapte en douceur entre 5 et 6 lignes de semaines.
Numéros de semaine
showWeekNumber ajoute une colonne de semaines. ISOWeek utilise la numérotation ISO, commençant le lundi. showOutsideDays={false} masque les jours des autres mois.
Aujourd’hui fixe
Passez today pour figer le jour mis en évidence, pour les tests ou un autre fuseau horaire. animate={false} désactive les transitions de mois.
Dans une sheet
Dans une sheet, un popover ou une boîte de dialogue, le calendrier abandonne son propre fond et se fond dans la surface.
De droite à gauche
Passez une locale de react-day-picker/locale et dir="rtl". Les flèches, la navigation et le sens du glissement s’inversent. Dans un DirectionProvider dir="rtl", la direction est détectée automatiquement.
Placez le focus sur un jour, puis utilisez ces touches. Dépasser le mois visible change de mois.
| Touche | Action |
|---|---|
| ←→ | Jour précédent ou suivant. Inversé dans les mises en page de droite à gauche. |
| ↑↓ | Le même jour de la semaine précédente ou suivante. |
| Shift←→ | Mois précédent ou suivant. |
| Shift↑↓ | Année précédente ou suivante. |
| Page UpPage Down | Mois précédent ou suivant. |
| ShiftPage UpPage Down | Année précédente ou suivante. |
| Home | Premier jour de la semaine. |
| End | Dernier jour de la semaine. |
| EnterSpace | Sélectionne le jour ayant le focus. |
- Le mois est une grille. Chaque jour est un bouton avec une étiquette de date complète, et les jours sélectionnés définissent
aria-selected. - Les changements de mois au clavier sautent le glissement et ne font que se fondre, pour que le focus ne se retrouve jamais sous une grille en mouvement.
- Avec la réduction des animations, les changements de mois se fondent et le changement de hauteur est instantané.
- Sur écran tactile, les cellules de jour passent à 44 px.
Accepte toutes les props de <DayPicker />. Les valeurs par défaut ci-dessous diffèrent de celles de DayPicker ou sont ajoutées par HextaUI.
| Prop | Type | Par défaut |
|---|---|---|
modeSans mode, les jours ne sont pas sélectionnables. | "single" | "multiple" | "range" | – |
selectedCorrespond au mode. | Date | Date[] | DateRange | – |
onSelect | (selected, triggerDate, modifiers, event) => void | – |
requiredEmpêche de désélectionner la dernière sélection. | boolean | – |
minNombre minimal de jours dans une plage, ou sélectionnés en mode multiple. | number | – |
maxNombre maximal de jours dans une plage, ou sélectionnés en mode multiple. | number | – |
excludeDisabledMode plage. | boolean | – |
disabled | Matcher | Matcher[] | – |
monthMois contrôlé. | Date | – |
defaultMonth | Date | – |
onMonthChange | (month: Date) => void | – |
startMonth | Date | – |
endMonth | Date | – |
numberOfMonths | number | 1 |
captionLayout | "label" | "dropdown" | "dropdown-months" | "dropdown-years" | "label" |
navLayoutValeur par défaut de HextaUI. Les flèches se placent de part et d’autre de la légende. | "around" | "after" | "around" |
showOutsideDaysValeur par défaut de HextaUI. | boolean | true |
animateTransitions de glissement du mois et de hauteur. Valeur par défaut de HextaUI. | boolean | true |
buttonVariantVariante des boutons précédent et suivant. | Button variant | "ghost" |
showWeekNumber | boolean | false |
ISOWeek | boolean | false |
weekStartsOn | 0 | 1 | 2 | 3 | 4 | 5 | 6 | – |
fixedWeeks | boolean | false |
todayPar défaut, le jour actuel du client, synchronisé à travers minuit et l’hydratation. | Date | – |
timeZone | string | – |
locale | Partial<DayPickerLocale> | – |
dir | "ltr" | "rtl" | – |
footer | ReactNode | – |
| Attribut | Description |
|---|---|
data-slot="calendar" | Ciblez la racine du calendrier en CSS. |
--cell-size | Taille des cellules de jour. 36 px, ou 44 px sur écran tactile. |
--cell-radius | Rayon des coins des cellules et des boutons de jour. |
data-slot="calendar-day" | Cellules de jour. Portent data-selected, data-disabled, data-outside, data-today, data-hidden et data-focused. |
data-preview | Sur les cellules de jour : début, milieu ou fin de l’aperçu de la plage survolée. |
data-range-middle | Sur les cellules de jour dans une plage sélectionnée. |
Le bouton dans chaque jour. Passez le vôtre à components={{ DayButton }} et réutilisez celui-ci pour conserver le style.
| Attribut | Description |
|---|---|
data-slot="calendar-day-button" | Ciblez les boutons de jour en CSS. |
data-day | La date ISO, comme 2026-10-03. |
data-today | Présent sur aujourd’hui, hors jours extérieurs. |
data-selected-single | Sélectionné en dehors d’une plage. |
data-range-start | Premier jour de la plage. |
data-range-middle | Un jour dans la plage. |
data-range-end | Dernier jour de la plage. |
Retourne aujourd’hui sous forme de Date côté client et undefined pendant le rendu serveur : les bornes construites à partir de lui ne provoquent donc jamais de désaccord d’hydratation. Il se met à jour à minuit. Consultez le guide de useToday.
- ButtonDes boutons dans toutes les variantes et tailles, avec un flux de chargement, de succès et d’erreur intégré qui évite le spinner pour les requêtes rapides.
- MotionLes courbes d’easing, les durées et la vérification de réduction des animations utilisées par chaque composant, ainsi que des hooks pour les morphs de taille et les surlignages glissants.
- useTodayLa date du jour, qui change à minuit et au retour de l’onglet, sans désaccord d’hydratation.
- CheckboxUne case à cocher dont la coche se dessine, avec des parents indéterminés, des groupes et des libellés qui partagent son survol.
- ComboboxUn select filtrable avec chips, groupes et résultats asynchrones, dans un popup qui se redimensionne pendant la saisie.
- Date pickerUn bouton qui ouvre un calendrier dans un popover, ou une bottom sheet sur mobile, pour des dates simples et des plages.