useDateRangePicker

Hook pour la sélection de plage de dates avec un calendrier à deux mois, un aperçu au survol et des plages prédéfinies.

Importation

import { useDateRangePicker } from "react-date-range-picker-headless";

Utilisation

import { useState } from "react";
import { useDateRangePicker } from "react-date-range-picker-headless";
function MyDateRangePicker() {
const [range, setRange] = useState<{ start: Date | null; end: Date | null }>({
start: null,
end: null,
});
const picker = useDateRangePicker({
value: range,
onChange: setRange,
presets: [
{
label: "7 derniers jours",
value: () => {
const end = new Date();
const start = new Date();
start.setDate(start.getDate() - 6);
return { start, end };
},
},
],
});
return (
<div ref={picker.containerRef}>
<button onClick={picker.handleToggle}>
{picker.displayValue || picker.locale.rangePlaceholder}
</button>
{picker.isOpen && (
<div ref={picker.popupRef} onKeyDown={picker.handleKeyDown}>
{/* Deux calendriers côte à côte */}
{[picker.leftCalendar, picker.rightCalendar].map((cal, calIdx) => (
<div key={calIdx}>
<span>{picker.locale.formatMonthYear(cal.month)}</span>
{cal.weeks.flat().map((day, i) => {
if (!day) return <span key={i} />;
const dp = picker.getDayProps(day, cal.month);
return (
<button
key={i}
onClick={() => picker.handleDateClick(day)}
onMouseEnter={() => picker.handleDateHover(day)}
onMouseLeave={() => picker.handleDateHover(null)}
>
{dp.day}
</button>
);
})}
</div>
))}
{/* Préréglages */}
{picker.presets.map((preset, i) => (
<button
key={i}
onClick={() => picker.handlePresetClick(preset)}
style={{ fontWeight: i === picker.activePresetIndex ? "bold" : "normal" }}
>
{preset.label}
</button>
))}
<button onClick={picker.handleConfirm}>{picker.locale.confirm}</button>
</div>
)}
</div>
);
}

Options

OptionTypeDéfautDescription
value{ start: Date | null; end: Date | null }Requis. Valeur de la plage actuelle.
onChange(value: { start: Date | null; end: Date | null }) => voidRequis. Appelé lorsque la plage change.
maxDaysnumberNombre maximum de jours autorisés dans une plage (inclus).
minDaysnumberNombre minimum de jours requis dans une plage (inclus).
presetsDateRangePreset[]Préréglages de plage de dates prédéfinis (par ex. “7 derniers jours”, “Ce mois-ci”).
allowSingleDateInRangebooleantrueLorsque false, empêche la sélection d’une plage où le début est égal à la fin.
minDateDateDate la plus précoce sélectionnable.
maxDateDateDate la plus tardive sélectionnable.
localePartial<Locale>DEFAULT_LOCALESurcharger les chaînes de la locale.
initialMonthDateMois initial à afficher.
sizeDatePickerSizeTransmission à l’interface utilisateur.
weekStartsOnWeekDay"sunday"Premier jour de la semaine.
isDateUnavailable(date: Date) => booleanFonction personnalisée pour désactiver des dates spécifiques.
displayFormatstringChaîne de format personnalisée pour la valeur affichée.
openbooleanÉtat d’ouverture contrôlé.
initialOpenbooleanfalseÉtat d’ouverture initial (non contrôlé).
onOpenChange(open: boolean) => voidCallback lorsque l’état d’ouverture change.
requiredbooleanfalseLorsque true, handleClear est une opération sans effet.
todayDatenew Date()Surcharger la date d’aujourd’hui.
onMonthChange(month: Date) => voidCallback lorsque le mois affiché change.
disablePastbooleanfalseDésactiver toutes les dates avant aujourd’hui.
disableFuturebooleanfalseDésactiver toutes les dates après aujourd’hui.
showOutsideDaysbooleanfalseAfficher les jours des mois adjacents.
highlightDatesDate[]Tableau de dates à surligner.
shouldCloseOnSelectbooleanfalseConfirmation automatique lorsque la date de fin est sélectionnée.
numberOfMonthsnumber2Nombre de mois de calendrier à afficher.
captionLayoutCaptionLayout"buttons"Mode de disposition de la légende.
fromYearnumbercurrent year - 100Année de début pour le menu déroulant.
toYearnumbercurrent year + 10Année de fin pour le menu déroulant.

Valeurs de retour

NomTypeDescription
isOpenbooleanIndique si la popup est ouverte.
tempStartDateDate | nullDate de début temporaire (avant confirmation).
tempEndDateDate | nullDate de fin temporaire (avant confirmation).
hoveredDateDate | nullDate actuellement survolée (pour l’aperçu de la plage).
leftMonthDateMois affiché du calendrier de gauche.
rightMonthDateMois affiché du calendrier de droite.
localeLocaleObjet de la locale résolue.
leftCalendarCalendarMonthDonnées du calendrier pour le panneau de gauche.
rightCalendarCalendarMonthDonnées du calendrier pour le panneau de droite.
calendarsCalendarMonth[]Tableau de tous les mois du calendrier.
getDayProps(date: Date, referenceMonth?: Date) => DayPropsCalcule les indicateurs pour une cellule de jour du calendrier. Passez referenceMonth pour que la détection des jours extérieurs fonctionne correctement dans les dispositions multi-mois.
displayValuestringChaîne formatée de la plage confirmée.
hasValuebooleanIndique si une plage est actuellement confirmée.
canConfirmbooleanIndique si la sélection actuelle est valide pour la confirmation.
handleDateClick(date: Date) => voidGère le clic sur une cellule de jour. Le premier clic définit le début, le second la fin.
handleDateHover(date: Date | null) => voidGère le survol de la souris pour l’aperçu de la plage.
handlePrevMonth() => voidNavigue les deux calendriers d’un mois en arrière.
handleNextMonth() => voidNavigue les deux calendriers d’un mois en avant.
handleOpen() => voidOuvre la popup.
handleClose() => voidFerme la popup.
handleToggle() => voidBascule l’état de la popup.
handleConfirm() => voidConfirme la sélection et ferme.
handleCancel() => voidAnnule et revient à la valeur précédente.
handleClear() => voidEfface la plage (sans effet si required).
handleGoToToday() => voidNavigue vers le mois d’aujourd’hui.
containerRefRefObject<HTMLDivElement | null>Attacher à l’élément conteneur pour la détection des clics extérieurs.
popupRefRefObject<HTMLDivElement | null>Attacher à l’élément de la popup.
focusedDateDate | nullDate focalisée au clavier.
handleKeyDown(e: KeyboardEvent<HTMLElement>) => voidGestionnaire de navigation au clavier.
presetsDateRangePreset[]Le tableau des préréglages (transmis pour le rendu).
handlePresetClick(preset: DateRangePreset) => voidApplique une plage prédéfinie.
activePresetIndexnumberIndex du préréglage correspondant actuellement (-1 si aucun).
yearsnumber[]Tableau des années pour le mode déroulant.
monthsnumber[]Indices des mois pour le mode déroulant.
handleYearSelect(year: number, calendarIndex?: number) => voidDéfinit l’année affichée.
handleMonthSelect(month: number, calendarIndex?: number) => voidDéfinit le mois affiché.

Comportements clés

Flux de sélection de plage

  1. Le premier clic définit la date de début (la date de fin est effacée)
  2. Le deuxième clic définit la date de fin (échange automatiquement si avant le début)
  3. Le troisième clic réinitialise et commence une nouvelle plage

Aperçu au survol

Tant que l’utilisateur a sélectionné une date de début mais pas encore de date de fin, handleDateHover met à jour hoveredDate. La fonction getDayProps utilise cela pour calculer isInHoverRange et isHoverTarget, vous permettant d’afficher un aperçu de la plage potentielle.

Préréglages

Les préréglages peuvent être des objets statiques ou des fonctions de fabrique :

const presets = [
{ label: "Aujourd'hui", value: { start: new Date(), end: new Date() } },
{
label: "30 derniers jours",
value: () => {
const end = new Date();
const start = new Date();
start.setDate(start.getDate() - 29);
return { start, end };
},
},
];

activePresetIndex renvoie l’index du préréglage qui correspond à la sélection actuelle, ou -1 si aucun ne correspond.

maxDays / minDays

Lorsque maxDays est défini, les dates au-delà de la plage autorisée à partir de la date de début sont automatiquement désactivées. Lorsque minDays est défini, les dates trop proches de la date de début sont désactivées.

shouldCloseOnSelect

Pour les sélecteurs de plage, shouldCloseOnSelect déclenche la confirmation automatique lorsque la date de fin est sélectionnée (et non la date de début).