Date picker
Ein Button, der einen Kalender in einem Popover öffnet, auf Smartphones als Bottom Sheet, für einzelne Daten und Zeiträume.
pnpm dlx shadcn@latest add https://hextaui.com/r/date-picker.jsonFügt die Komponente, die HextaUI-Theme-Tokens und alle HextaUI-Komponenten hinzu, von denen sie abhängt.
Füge die Theme-Tokens zu deinem globalen CSS hinzu, falls du das noch nicht getan hast.
Installiere die Abhängigkeiten.
pnpm add @base-ui/react @tabler/icons-react class-variance-authority cn react-day-pickerKopiere den folgenden Code und füge ihn in dein Projekt ein.
components/ui/date-picker.tsx components/ui/calendar.tsx components/ui/popover.tsx components/ui/sheet.tsx components/ui/button.tsx lib/motion.ts Passe die Importpfade an dein Projekt-Setup an.
Auf Bildschirmen unter 640 px öffnet sich der Kalender statt in einem Popover in einem Bottom Sheet, damit die Tage groß genug zum Antippen bleiben.
Kontrolliert
Übergib value und onValueChange. Geleerte Werte sind null. Der Kalender öffnet sich immer im Monat des ausgewählten Datums, und das Wählen eines Tages schließt ihn und gibt den Fokus an den Button zurück.
Range
<DateRangePicker /> zeigt auf größeren Bildschirmen zwei Monate. Der erste Klick beginnt immer einen neuen Bereich, auch wenn bereits einer gesetzt ist, und der zweite Klick beendet ihn in beliebiger Reihenfolge und schließt den Picker.
Deaktivierte Tage
Übergib einen beliebigen react-day-picker-Matcher als calendarProps.disabled. Hier können nur künftige Werktage gewählt werden.
Dropdowns für Monat und Jahr
Setze für weit entfernte Daten wie einen Geburtstag captionLayout: "dropdown" mit startMonth und endMonth. Beschrifte den Trigger mit einem <label />, das auf seine id zeigt.
In einem Formular
Mit name wird ein einzelnes Datum als 2026-10-14 gesendet und ein Bereich als 2026-10-20/2026-10-24. Leere Picker senden einen leeren String.
Deaktiviert
Ein deaktivierter Trigger kann trotzdem einen Wert anzeigen.
Schmaler Container
Der Trigger wird nie breiter als sein Container. Lange Labels werden gekürzt, statt umzubrechen.
In einem Sheet
Der Picker liegt über dem Sheet, und Escape schließt nur den Picker.
Rechts nach links
Übergib locale für das Trigger-Label und in calendarProps eine react-day-picker-Locale mit dir: "rtl" für den Kalender. Die Pfeiltasten folgen der Richtung.
| Taste | Aktion |
|---|---|
| EnterSpace | Am Trigger: öffnet den Picker und fokussiert den ausgewählten Tag oder heute. Auf einem Tag: wählt ihn aus. |
| ←→ | Wechselt zum vorherigen oder nächsten Tag. |
| ↑↓ | Wechselt zum selben Tag der vorherigen oder nächsten Woche. |
| Page UpPage Down | Wechselt zum vorherigen oder nächsten Monat. |
| ShiftPage Up | Wechselt zum vorherigen Jahr. Shift+Bild ab wechselt zum nächsten. |
| HomeEnd | Wechselt zum Anfang oder Ende der Woche. |
| Esc | Schließt den Picker und gibt den Fokus an den Trigger zurück. |
- Das Popover wird mit
titlebeschriftet, und das Bottom Sheet zeigt ihn als Überschrift. Übersetze ihn zusammen mitplaceholder. - Der Trigger hat kein eigenes sichtbares Label. Kombiniere ihn mit einem
<label />oder übergibaria-label. - Deaktivierte Tage werden von der Tastatur übersprungen und als nicht verfügbar angesagt.
Beide Picker teilen die Props unten und rendern einen <Button />-Trigger mit einem <Calendar /> in einem Popover oder Bottom Sheet.
| Prop | Typ | Standard |
|---|---|---|
value | Date | null | – |
defaultValue | Date | null | null |
onValueChange | (value: Date | null) => void | – |
placeholder | string | "Pick a date" |
titleZugänglicher Name des Popovers, Überschrift des Sheets. | string | "Select a date" |
open | boolean | – |
defaultOpen | boolean | false |
onOpenChange | (open: boolean) => void | – |
localeFormatiert das Trigger-Label mit Intl.DateTimeFormat. Übergib in calendarProps eine react-day-picker-Locale, um auch den Kalender zu übersetzen. | string | "en-US" |
clearableFügt unter dem Kalender einen Löschen-Button hinzu, sobald ein Wert vorhanden ist. | boolean | false |
clearLabel | string | "Clear" |
nameRendert ein verstecktes Input, damit der Wert mit seinem Formular gesendet wird. | string | – |
calendarPropsWird an den Kalender weitergegeben, außer mode, selected, onSelect, required, numberOfMonths und autoFocus. Nutze es für deaktivierte Tage, captionLayout, startMonth, endMonth, locale und dir. | CalendarProps | – |
variantDer Trigger ist ein Button und akzeptiert auch dessen übrige Props. | Button variant | "outline" |
disabled | boolean | false |
classNameWird auf den Trigger angewendet, der standardmäßig w-60 ist. | string | – |
| Prop | Typ | Standard |
|---|---|---|
value | { from: Date; to?: Date } | null | – |
defaultValue | { from: Date; to?: Date } | null | null |
onValueChangeWird aufgerufen, sobald der zweite Tag gewählt ist. | (value: DateRange | null) => void | – |
placeholder | string | "Pick a date range" |
title | string | "Select dates" |
open | boolean | – |
defaultOpen | boolean | false |
onOpenChange | (open: boolean) => void | – |
localeFormatiert das Trigger-Label mit Intl.DateTimeFormat. Übergib in calendarProps eine react-day-picker-Locale, um auch den Kalender zu übersetzen. | string | "en-US" |
clearableFügt unter dem Kalender einen Löschen-Button hinzu, sobald ein Wert vorhanden ist. | boolean | false |
clearLabel | string | "Clear" |
nameRendert ein verstecktes Input, damit der Wert mit seinem Formular gesendet wird. | string | – |
calendarPropsWird an den Kalender weitergegeben, außer mode, selected, onSelect, required, numberOfMonths und autoFocus. Nutze es für deaktivierte Tage, captionLayout, startMonth, endMonth, locale und dir. | CalendarProps | – |
variantDer Trigger ist ein Button und akzeptiert auch dessen übrige Props. | Button variant | "outline" |
disabled | boolean | false |
classNameWird auf den Trigger angewendet, der standardmäßig w-60 ist. | string | – |
| Attribut | Beschreibung |
|---|---|
data-slot="date-picker-trigger" | Der Trigger-Button. |
data-empty | Vorhanden am Trigger, solange kein Wert vorhanden ist. Zeigt den Platzhalter in gedämpftem Text. |
data-popup-open | Vorhanden am Trigger, solange der Picker geöffnet ist. |
data-slot="date-picker-content" | Umschließt den Kalender im Popover oder Sheet. |
data-slot="date-picker-clear" | Der Löschen-Button. |
- ButtonButtons in allen Varianten und Größen, mit eingebautem Lade-, Erfolgs- und Fehlerablauf, der den Spinner bei schnellen Anfragen überspringt.
- CalendarEin Datumsraster für Einzel-, Bereichs- und Mehrfachauswahl, mit gleitenden Monaten, Bereichsvorschau und Tagen in Touch-Größe.
- PopoverEin schwebendes Panel, das an einem Trigger verankert ist, sich sanft mit seinem Inhalt in der Größe ändert und der Richtung des Triggers folgt.
- SheetEin Panel, das von jeder Kante hereingleitet, mit Wischen zum Schließen, Scroll-Sperre und gestapelter Verschachtelung.
- CheckboxEine Checkbox, deren Häkchen sich einzeichnet, mit unbestimmten übergeordneten Elementen, Gruppen und Labels, die ihren Hover teilen.
- ComboboxEin filterbares Select mit Chips, Gruppen und asynchronen Ergebnissen, in einem Popup, das sich beim Tippen anpasst.
In Blocks verwendet
Blocks, die auf Date picker aufbauen.