React Kalender mit Terminen: Monat, Woche, Tag

Du brauchst einen React Kalender mit Terminen: die Termine einer Praxis, die Meetings eines Teams, die Woche eines Außendienstlers. Ein Monatsraster mit ein paar farbigen Chips ist schnell gebaut. Dann kommen die echten Daten. Zwei Termine überschneiden sich um 9:30, ein Kongress läuft über vier Tage, jemand zieht einen Besuch auf Freitag und das Speichern schlägt fehl, und auf dem Smartphone besteht die Wochenansicht aus sieben Spalten mit je 50px Breite. Dieser Guide zeigt, was ein Terminkalender können muss, welche Props in der Calendar View von Wingo UI zählen, wie du Termine lädst und speicherst und was du am Smartphone zeigst.
Was muss ein React Kalender mit Terminen können?
Sechs Dinge:
- Monats-, Wochen-, Tages- und Agenda-Ansicht, mit Zurück, Heute und Weiter und einem Titel, der sagt, welchen Zeitraum du gerade siehst.
- Überlappende Termine nebeneinander im Wochen- und Tagesraster und mehrtägige Termine als ein Balken über die Monatszellen.
- Details per Klick: Uhrzeit, Ort, Teilnehmer, dazu dein eigener Status oder Links.
- Verschieben und Ändern der Dauer per Drag, mit Einrasten auf einen Slot und einem Rückweg für Änderungen, die der Server ablehnt.
- Auswahl freier Zeiten, um einen Termin anzulegen.
- Ein Smartphone-Layout als Liste, denn ein Zeitraster passt dort nicht.
Wenn deine Frage lautet „Welcher Raum, welches Auto oder welche Person ist um 10 Uhr frei?“, brauchst du stattdessen eine Ressourcen-Timeline mit Ressourcen als Zeilen. Das ist eine andere Komponente, und der Guide zum React Resource Scheduler behandelt sie. Ein Terminkalender beantwortet die Frage „Was steht in meinem Kalender?“.
Hat shadcn/ui einen Kalender mit Terminen?
Nein. Der Calendar von shadcn (opens in a new tab) ist ein Date Picker auf Basis von React DayPicker: einzelne Tage, Zeiträume, Dropdowns für Monat und Jahr. Ein Zeitraster für Woche oder Tag hat er nicht. Wer nach einem shadcn Calendar mit Terminen sucht, meint meist eines von zwei verschiedenen Dingen, und beides gibt es in Wingo UI:
- Ein Date Picker, der Termine als Punkte zeigt, damit du belegte Tage siehst, bevor du einen auswählst. Das ist der Calendar. Sein Prop
eventsnimmt{ date, tone?, color?, label? }und zeichnet bis zu drei Punkte unter einen Tag; Screenreader lesen die Labels vor. - Ein React Event Calendar, der Termine in einem Zeitraster anordnet. Das ist die Calendar View, um die es im Rest dieses Beitrags geht.
Wie schneiden React-Terminkalender im Vergleich ab?
react-big-calendar, FullCalendar und Mantine Schedule sind die kostenlosen Optionen unter MIT, und die Calendar View von Wingo UI ist die Pro-Option, die du als Quellcode installierst. Diese Namen tauchen auf, wenn du nach „react kalender monat woche tag“ oder einer React Big Calendar Alternative suchst. Versionen und Fakten stammen aus der Doku, dem Repository und npm des jeweiligen Projekts, Stand Oktober 2026.
FullCalendar ist die bessere Wahl, wenn du vom selben Anbieter auch Ressourcen-Timelines brauchst und bereit bist, für Premium zu zahlen. react-big-calendar ist eine solide kostenlose Standardwahl, wenn du sein CSS gern selbst anpasst. Mantine Schedule lohnt sich, wenn deine App schon auf Mantine läuft. Die Calendar View passt in eine Codebasis mit Tailwind und shadcn-Stil, in der du jede Zeile lesen und ändern willst.
Welche Props braucht die Calendar View?
Nur eins: events. Jeder Termin ist { id, title, start: Date, end: Date }, dazu optional allDay, tone oder color, location, description, attendees, editable und meta.
Die beiden Termine am Vormittag überschneiden sich, also legt das Wochenraster sie in zwei Spalten, und der Kongress erscheint als ein Balken über drei Monatszellen (bei ganztägigen Terminen ist ein Ende um Mitternacht Ortszeit exklusiv). Die Props, die du danach am häufigsten änderst:
viewsunddefaultView: Der Umschalter zeigt standardmäßig Monat, Woche, Tag und Agenda; bei einer einzigen Ansicht verschwindet er.dayStartHour,dayEndHour,scrollToHour(standardmäßig 8) undhourHeight(48px, auf Touchscreens mindestens 56px).slotMinutes: 15, 30 oder 60, das Raster für Verschieben, Ändern der Dauer und Auswahl.hideWeekends,showWeekNumbers,maxEventsPerDay(3 Zeilen pro Monatszelle; ein vollerer Tag zeigt zwei Chips und „+N more“).toolbarActionsfür einen Button „Neuer Termin“,labelsfür jeden Text,variantfürsurface,outlineoderplain.
Die Demo unten öffnet im Wochenraster. Zieh mit Maus oder Stift einen Termin auf eine andere Stunde und dann seine Unterkante nach unten, um ihn zu verlängern.
$ npx wingo-ui@latest add calendar-viewWie lade ich die Termine für den sichtbaren Zeitraum?
Steuer view und date selbst (kontrolliert) und lade neu, sobald sich eins davon ändert. getVisibleRange(view, date, weekStartsOn, agendaDays) gibt den ersten und den letzten sichtbaren Tag als Mitternacht Ortszeit zurück, beide inklusive. Zwei Details sind wichtig. Dort steht weekStartsOn standardmäßig auf Montag, während der Kalender der Locale folgt (Sonntag bei en-US), also übergib denselben Wert. Und das Ende ist der letzte Tag um Mitternacht, frag also bis zur nächsten Mitternacht ab, sonst fehlen dir die Termine dieses Tags.
loading zeigt einen dünnen Balken unter der Toolbar, während die aktuellen Termine sichtbar bleiben. Wenn du eine Woche weiterblätterst, blitzt also kein leeres Raster auf.
Wie speichere ich das Verschieben per Drag?
Der Kalender zeigt die Änderung in dem Moment, in dem du loslässt, und ruft dann onEventChange(event, { start, end, allDay }) auf. Gibst du false zurück, springt der Termin sofort zurück; so lehnt das Beispiel oben ein Verschieben in die Vergangenheit ab. Für das Speichern auf dem Server aktualisierst du deine Termine, schickst die Anfrage und stellst das vorherige Array wieder her, wenn sie scheitert. Ein neues events-Array verwirft die optimistische Kopie des Kalenders, das Zurücksetzen reicht also. Der Snapshot ist nur sicher, solange immer nur ein Speichervorgang läuft; wenn sich Verschiebungen überlappen können, lad nach einem Fehler lieber den Zeitraum neu.
onSlotSelect macht freie Zeit auswählbar: Klick auf einen Slot für eine Stunde, oder zieh im Raster nach unten für einen Zeitraum mit einem Platzhalter „New event“. Im Monat klickst du auf einen Tag oder ziehst über mehrere Tage für einen ganztägigen Zeitraum. Öffnest du den neuen Termin direkt nach dem Anlegen über openEventId, siehst du sofort seine Details, und dort können deine eigenen Buttons zum Umbenennen oder Löschen sitzen (siehe meta unten).
Einzelne Termine sperrst du mit editable: false, etwa eine bestätigte Operation, die nur der Empfang verschieben darf.
Wie funktioniert ein React Event Calendar auf dem Smartphone?
Er wird zur Liste. Ist der Kalender schmaler als 576px, wechseln Monat und Woche zu der mobileView, die du festlegst:
"agenda"(Standard): die Tage dieses Monats oder dieser Woche als Sticky-Überschriften über 56px hohen Zeilen mit Uhrzeit, Farbbalken, Titel und Ort. Sie startet beim heutigen Tag."day": der gewählte Tag als Zeitraster; wisch nach links oder rechts, um den Tag zu wechseln."month": ein kompakter Monat mit bis zu drei Punkten pro Tag und den Terminen des gewählten Tags darunter, ebenfalls mit Wischen.
Der Wechsel ist eine Container Query auf dem Kalender selbst. Ein schmales Seitenpanel am Desktop bekommt also ebenfalls das Smartphone-Layout, und beide Layouts stehen im Server-HTML. layout="mobile" erzwingt es, zum Beispiel in einem Smartphone-Rahmen. Bei einem Viewport unter 768px öffnen sich die Termindetails als Bottom Sheet statt als Popover, aus den Gründen im Guide zum React Bottom Sheet.
$ npx wingo-ui@latest add calendar-viewAuf Touchscreens ist das Ziehen von Terminen deaktiviert, denn ein Drag, der auf einem Termin beginnt, würde mit dem Scrollen der Seite kollidieren. Wenn deine Nutzer am Smartphone Termine verschieben, gib ihnen einen Button in den Details. Das meta jedes Termins erscheint am Ende des Popovers oder Sheets mit den Details:
openRescheduleForm ist dein eigenes Formular, zum Beispiel ein Drawer mit einem Feld für Datum und Uhrzeit. Derselbe Button hilft auch allen, die per Tastatur arbeiten, wie der nächste Abschnitt zeigt.
Wie mache ich einen Terminkalender barrierefrei?
Gib jeder Aktion einen Weg ohne Ziehen. Das Monatsraster ist ein einziger Tab-Stopp: Pfeiltasten springen um einen Tag oder eine Woche, Home und End gehen an den Anfang oder das Ende der Woche, PageUp und PageDown wechseln den Monat (mit Shift das Jahr), Enter öffnet die Termine des Tags, und Tab geht weiter zu den Terminen an diesem Tag. In Woche, Tag und Agenda sind Termine Buttons in zeitlicher Reihenfolge, vorgelesen als Titel und Zeitspanne. Escape schließt die Details und gibt den Fokus an den Termin zurück. Der Titel in der Toolbar ist eine Live Region, ein Screenreader hört also nach Zurück oder Weiter den neuen Zeitraum.
Ein Termin lässt sich im Raster nicht per Tastatur verschieben (Enter öffnet die Details), ein Grund mehr für einen Button zum Verschieben in meta. WCAG 2.2 2.5.7 Dragging Movements (opens in a new tab) verlangt für jede Ziehbewegung eine Alternative mit einem einzelnen Zeiger, und dieser Button ist sie. Bei reduzierter Bewegung ersetzen Überblendungen die Schiebeanimationen zwischen den Zeiträumen.
Was sind die typischen Fallstricke?
- Strings statt Dates. JSON liefert ISO-Strings. Wandle
startundendbeim Laden mitnew Date()um, so wietoEventoben. - Ende ganztägiger Termine. Ein ganztägiger Termin, der um Mitternacht Ortszeit endet, endet am Tag davor. Ein dreitägiger Kongress ab dem 22. endet also um Mitternacht am 25. Liegt das Ende auf oder vor dem Start, gilt der Termin als 30 Minuten lang, mit einer Warnung im Development-Modus.
- Unterschiedliche Wochenanfänge. Übergib
getVisibleRangeund dem Kalender dasselbeweekStartsOn, sonst wird ein Sonntag bei en-US nicht geladen. - Hydration. Ohne
defaultDateoderdaterendert der Server den Tag des ersten Termins, und der Browser springt nach dem Mount auf heute, damit das HTML übereinstimmt. Ein kontrolliertesdate, das wie im Beispiel zum Laden mitnew Date()startet, wird auf dem Server und noch einmal im Browser berechnet. Kurz vor Mitternacht oder über Zeitzonen hinweg können die beiden auf verschiedene Tage fallen. Starte mit einem festen Datum oder setz es in einem Effect auf heute. - Sehr volle Tage. Jeder überlappende Termin bekommt eine eigene Spalte. Ein Tag mit Dutzenden paralleler Buchungen zerfällt also in Spalten, die zu schmal zum Lesen sind. Zeig solche Daten in einer Data Table mit Filtern oder teil sie nach Ressource auf.
Wie füge ich ihn meinem Projekt hinzu?
Führ npx wingo-ui@latest add calendar-view aus (oder calendar für den Date Picker). Die CLI kopiert den Quellcode nach components/ui, fügt die Teile hinzu, die er nutzt, etwa Popover, Avatar und Button, und installiert @dnd-kit/core, date-fns, motion und lucide-react. Calendar View und Calendar sind beide Pro-Komponenten (Preise). Wenn du einen Zeitraum auswählen statt Termine zeigen willst, lies den Guide zum React Date Range Picker. Weitere Deep Dives zu einzelnen Komponenten findest du in der Kategorie Komponenten-Guides, und der Guide zu React-Formularkomponenten behandelt die Felder, die du in das Formular zum Verschieben einbaust.
Häufige Fragen
Welche React Kalender-Komponente mit Terminen ist die beste?
Unter den kostenlosen npm-Paketen stehen react-big-calendar und die Standard-Edition von FullCalendar beide unter MIT und bringen Monats-, Wochen-, Tages- und Agenda- oder Listenansicht mit. Mantine Schedule passt zu Apps, die schon auf Mantine laufen, und die Calendar View von Wingo UI passt, wenn du den Quellcode im eigenen Repo und ein fertiges Smartphone-Layout willst.
Hat shadcn/ui einen Kalender mit Terminen?
Der Calendar von shadcn ist ein Date Picker auf Basis von React DayPicker, mit Auswahl einzelner Tage und Zeiträume, aber ohne Zeitraster für Woche oder Tag. Für Termine brauchst du einen eigenen Event-Kalender, der die Termine in einem Raster zeigt.
Was ist eine gute Alternative zu react-big-calendar?
FullCalendar kommt im Funktionsumfang am nächsten heran, und seine Standard-Edition ist unter MIT kostenlos. Wenn du einen Kalender als Quellcode mit Tailwind-Tokens, einer Agenda am Smartphone und Verschieben per Drag willst, ist die Calendar View von Wingo UI eine Pro-Alternative.
Wie speichere ich das Verschieben per Drag in einem React Kalender?
Aktualisier deine Termine sofort, schick den neuen Start und das neue Ende an den Server und setz das alte Array zurück, wenn die Anfrage scheitert. In der Calendar View bekommt onEventChange den Termin und seine neuen Zeiten, und wenn du false zurückgibst, springt der Termin sofort zurück.
Wie sollte ein Terminkalender auf dem Smartphone aussehen?
Ein Wochenraster mit sieben Spalten passt nicht auf 390px. Zeig deshalb eine Agenda-Liste nach Tagen, einen einzelnen Tag oder einen kompakten Monat mit Punkten und den Terminen des gewählten Tags darunter. Details zum Termin öffnest du als Bottom Sheet statt als Popover.
- Kalender
- Terminplanung
- Drag and Drop
- Mobile UI
- React


