Die Komponente DayFlowCalendar
DayFlowCalendar ist die übergeordnete Komponente: Sie rendert die aktive Ansicht, kümmert sich um das Layout und bindet optionale UI-Elemente wie die Seitenleiste oder den Termindetail-Dialog ein. Zusammen mit useCalendarApp und den Factory-Funktionen für Ansichten erhalten Sie mit sehr wenig Code einen voll funktionsfähigen Kalender.
Grundlegende Verwendung
import {
DayFlowCalendar,
useCalendarApp,
createWeekView,
ViewType,
} from '@dayflow/react';
import { createSidebarPlugin } from '@dayflow/plugin-sidebar';
import '@dayflow/core/dist/styles.css';
export function CalendarDemo() {
const calendar = useCalendarApp({
views: [createWeekView()],
defaultView: ViewType.WEEK,
initialDate: new Date(),
events: [],
plugins: [createSidebarPlugin()],
});
return <DayFlowCalendar calendar={calendar} />;
}<template>
<DayFlowCalendar :calendar="calendar" />
</template>
<script setup>
import { DayFlowCalendar, useCalendarApp } from '@dayflow/vue';
import { createWeekView, ViewType } from '@dayflow/core';
import { createSidebarPlugin } from '@dayflow/plugin-sidebar';
import '@dayflow/core/dist/styles.css';
const calendar = useCalendarApp({
views: [createWeekView()],
defaultView: ViewType.WEEK,
initialDate: new Date(),
events: [],
plugins: [createSidebarPlugin()],
});
</script>import { Component } from '@angular/core';
import { createWeekView, ViewType } from '@dayflow/core';
import { createSidebarPlugin } from '@dayflow/plugin-sidebar';
import { DayFlowCalendarModule } from '@dayflow/angular';
import '@dayflow/core/dist/styles.css';
@Component({
selector: 'app-root',
standalone: true,
imports: [DayFlowCalendarModule],
template: `
<dayflow-calendar [calendar]="calendar"></dayflow-calendar>
`
})
export class AppComponent {
calendar = {
views: [createWeekView()],
defaultView: ViewType.WEEK,
initialDate: new Date(),
events: [],
plugins: [createSidebarPlugin()],
};
}<script>
import { DayFlowCalendar, useCalendarApp } from '@dayflow/svelte';
import { createWeekView, ViewType } from '@dayflow/core';
import { createSidebarPlugin } from '@dayflow/plugin-sidebar';
import '@dayflow/core/dist/styles.css';
const calendar = useCalendarApp({
views: [createWeekView()],
defaultView: ViewType.WEEK,
initialDate: new Date(),
events: [],
plugins: [createSidebarPlugin()],
});
</script>
<DayFlowCalendar {calendar} />Die Komponente erhält das calendar-Objekt von useCalendarApp, liest die aktive Ansicht aus und rendert die passende Ansichtskomponente. Eine eigene Toolbar oder UI können Sie daneben platzieren – Folgendes ist aber bereits enthalten:
- eine optionale Kalender-Seitenleiste (wird über
createSidebarPluginhinzugefügt), - Unterstützung für den Termindetail-Dialog (gesteuert über
useEventDetailDialogoder einen eigenen Renderer), - automatische Layout-Aktualisierung, wenn Kalender ein- oder ausgeblendet werden oder die Ansicht wechselt.
Props
| Prop | Typ | Erforderlich | Beschreibung |
|---|---|---|---|
calendar | UseCalendarAppReturn | Erforderlich | Ergebnis von useCalendarApp. Liefert Zustand, registrierte Ansichten, Seitenleisten-Konfiguration und Kalenderaktionen. |
collapsedSafeAreaLeft | number | Optional | Linker Innenabstand (px) bei eingeklappter Seitenleiste, etwa um Platz für die Fensterbuttons unter macOS zu lassen. |
search | CalendarSearchProps | Optional | Konfiguration der integrierten Suche. |
Die Anpassung über Slots (Termininhalt, Inhalt des Detailbereichs, Detaildialog, Farbwähler usw.) erfolgt über framework-eigene Slots und nicht über Props. Die vollständige Liste finden Sie unter Content Slots.
Suchkonfiguration
Mit der Prop search passen Sie das Verhalten der integrierten Suche an. Standardmäßig durchsucht sie lokal Titel und Beschreibungen der Termine.
<DayFlowCalendar
calendar={calendar}
search={{
debounceDelay: 500,
emptyText: 'No events found',
onSearch: async keyword => {
// Custom async search (e.g., from an API)
return fetch(`/api/search?q=${keyword}`).then(res => res.json());
},
}}
/><template>
<DayFlowCalendar
:calendar="calendar"
:search="{
debounceDelay: 500,
emptyText: 'No events found',
onSearch: handleSearch,
}"
/>
</template>
<script setup>
import { DayFlowCalendar } from '@dayflow/vue';
const handleSearch = async (keyword) => {
// Custom async search (e.g., from an API)
return fetch(`/api/search?q=${keyword}`).then(res => res.json());
};
</script>import { Component } from '@angular/core';
import { DayFlowCalendarModule } from '@dayflow/angular';
@Component({
selector: 'app-root',
standalone: true,
imports: [DayFlowCalendarModule],
template: `
<dayflow-calendar
[calendar]="calendar"
[search]="searchConfig"
>
</dayflow-calendar>
`
})
export class AppComponent {
calendar = {
// ... calendar app config
};
searchConfig = {
debounceDelay: 500,
emptyText: 'No events found',
onSearch: async (keyword: string) => {
return fetch(`/api/search?q=${keyword}`).then(res => res.json());
}
};
}<script>
import { DayFlowCalendar } from '@dayflow/svelte';
const handleSearch = async (keyword) => {
return fetch(`/api/search?q=${keyword}`).then(res => res.json());
};
</script>
<DayFlowCalendar
{calendar}
search={{
debounceDelay: 500,
emptyText: 'No events found',
onSearch: handleSearch,
}}
/>Such-Props
| Option | Beschreibung |
|---|---|
debounceDelay | Wartezeit in Millisekunden, bevor die Suche ausgelöst wird. |
onSearch | Asynchrone Funktion, die Ergebnisse zu einem Suchbegriff lädt. |
customSearch | Synchrone Funktion, um Termine lokal nach eigener Logik zu filtern. |
onResultClick | Optionaler Callback, der beim Klick auf ein Suchergebnis ausgelöst wird. Er enthält den Callback defaultAction für die integrierte Navigation (zum Termindatum springen, Termin hervorheben und die Such-UI auf Mobilgeräten schließen). Rufen Sie defaultAction() nicht auf, müssen Sie Navigation und UI-Zustand selbst übernehmen. |
emptyText | Text, der angezeigt wird, wenn es keine Treffer gibt. |
timeFormat | Zeitformat für die Anzeige der Suchergebnisse ('12h' oder '24h'). Ist in useCalendarApp ein globales timeFormat gesetzt, hat dieses Vorrang. |
Verhalten der Seitenleiste
Die Seitenleiste fügen Sie hinzu, indem Sie das Plugin @dayflow/plugin-sidebar installieren:
import { createSidebarPlugin } from '@dayflow/plugin-sidebar';
const calendar = useCalendarApp({
views: [createWeekView()],
plugins: [
createSidebarPlugin({
width: 280,
initialCollapsed: false,
createCalendarMode: 'modal', // 'inline' or 'modal'
}),
],
});
return <DayFlowCalendar calendar={calendar} />;<template>
<DayFlowCalendar :calendar="calendar" />
</template>
<script setup>
import { DayFlowCalendar, useCalendarApp } from '@dayflow/vue';
import { createWeekView } from '@dayflow/core';
import { createSidebarPlugin } from '@dayflow/plugin-sidebar';
const calendar = useCalendarApp({
views: [createWeekView()],
plugins: [
createSidebarPlugin({
width: 280,
initialCollapsed: false,
createCalendarMode: 'modal',
}),
],
});
</script>import { Component } from '@angular/core';
import { createWeekView } from '@dayflow/core';
import { createSidebarPlugin } from '@dayflow/plugin-sidebar';
import { DayFlowCalendarModule } from '@dayflow/angular';
@Component({
selector: 'app-root',
standalone: true,
imports: [DayFlowCalendarModule],
template: `
<dayflow-calendar [calendar]="calendar"></dayflow-calendar>
`
})
export class AppComponent {
calendar = {
views: [createWeekView()],
plugins: [
createSidebarPlugin({
width: 280,
initialCollapsed: false,
createCalendarMode: 'modal',
}),
],
};
}<script>
import { DayFlowCalendar, useCalendarApp } from '@dayflow/svelte';
import { createWeekView } from '@dayflow/core';
import { createSidebarPlugin } from '@dayflow/plugin-sidebar';
const calendar = useCalendarApp({
views: [createWeekView()],
plugins: [
createSidebarPlugin({
width: 280,
initialCollapsed: false,
createCalendarMode: 'modal',
}),
],
});
</script>
<DayFlowCalendar {calendar} />- Sobald
createSidebarPlugin()zu den Plugins hinzugefügt wird, erscheint die Standard-Seitenleiste (DefaultCalendarSidebar) mit Kalenderfiltern und Schaltern zum Ein- und Ausblenden aller Kalender. - Breite, voreingestellter Einklappzustand und Erstellungsmodus (
createCalendarMode) lassen sich anpassen; alternativ liefern Sie überrenderoderrenderSidebarHeadereinen eigenen Renderer. Dieser erhältCalendarSidebarRenderProps(beirender) bzw.SidebarHeaderSlotArgs(beirenderSidebarHeader), sodass Sie die mitgelieferten Callbacks und Daten weiterverwenden können.
Darstellung von Termindetails
DayFlow bietet dafür drei Varianten:
- Panel-Modus (Standard) – steht
useEventDetailDialogauffalse(Voreinstellung), erscheint beim Öffnen der Termindetails das eingebaute schwebendeDefaultEventDetailPanel. Am Desktop öffnet es sich per Doppelklick (eventDetailTrigger: 'dbClick') oder per Einfachklick, wenn SieeventDetailTrigger: 'click'setzen. Bei Touch-Eingabe genügt stets ein Tippen. - Dialog-Modus – setzen Sie
useEventDetailDialog: trueinuseCalendarApp, um das eingebaute zentrierte Modal zu aktivieren. Über den SloteventDetailDialogersetzen Sie es durch einen eigenen Dialog. - Ganz abschalten – setzen Sie
useEventDetailPanel: falseinuseCalendarApp, um das schwebende Panel zu unterdrücken, wenn Sie eigene, über App-Callbacks gesteuerte Termindialoge verwenden.
// Suppress the built-in panel — use your own modal triggered elsewhere
const calendar = useCalendarApp({
...
useEventDetailPanel: false,
});
return <DayFlowCalendar calendar={calendar} />;<template>
<DayFlowCalendar :calendar="calendar" />
</template>
<script setup>
import { DayFlowCalendar, useCalendarApp } from '@dayflow/vue';
// Suppress the built-in panel — use your own modal triggered elsewhere
const calendar = useCalendarApp({
...
useEventDetailPanel: false,
});
</script>import { Component } from '@angular/core';
import { DayFlowCalendarModule } from '@dayflow/angular';
@Component({
selector: 'app-root',
standalone: true,
imports: [DayFlowCalendarModule],
template: `
<dayflow-calendar [calendar]="calendar"></dayflow-calendar>
`
})
export class AppComponent {
// Suppress the built-in panel — use your own modal triggered elsewhere
calendar = {
...
useEventDetailPanel: false,
};
}<script>
import { DayFlowCalendar, useCalendarApp } from '@dayflow/svelte';
// Suppress the built-in panel — use your own modal triggered elsewhere
const calendar = useCalendarApp({
...
useEventDetailPanel: false,
});
</script>
<DayFlowCalendar {calendar} />// Custom panel content (keeps the default panel chrome)
<DayFlowCalendar
calendar={calendar}
eventDetailContent={({ event, onClose }) => (
<div className='p-4'>
<h2>{event.title}</h2>
<button onClick={onClose}>Close</button>
</div>
)}
/><template>
<DayFlowCalendar :calendar="calendar">
<!-- Custom panel content (keeps the default panel chrome) -->
<template #eventDetailContent="{ event, onClose }">
<div class="p-4">
<h2>{{ event.title }}</h2>
<button @click="onClose()">Close</button>
</div>
</template>
</DayFlowCalendar>
</template>
<script setup>
import { DayFlowCalendar } from '@dayflow/vue';
</script><!-- Custom panel content (keeps the default panel chrome) -->
<dayflow-calendar
[calendar]="calendar"
[eventDetailContent]="detailContent"
>
</dayflow-calendar>
<ng-template #detailContent let-args>
<div class="p-4">
<h2>{{ args.event.title }}</h2>
<button (click)="args.onClose()">Close</button>
</div>
</ng-template><DayFlowCalendar {calendar} eventDetailContent={CustomDetailContent} />
<!-- CustomDetailContent.svelte -->
<script lang="ts">
import type { EventDetailContentSlotArgs } from '@dayflow/core';
let { event, onClose } = $props<EventDetailContentSlotArgs>();
</script>
<div class="p-4">
<h2>{event.title}</h2>
<button onclick={onClose}>Close</button>
</div>// Custom dialog (requires useEventDetailDialog: true in useCalendarApp)
<DayFlowCalendar
calendar={calendar}
eventDetailDialog={({ event, isOpen, onClose }) => (
<MyDialog isOpen={isOpen} onClose={onClose}>
<EventForm event={event} />
</MyDialog>
)}
/><template>
<DayFlowCalendar :calendar="calendar">
<!-- Custom dialog -->
<template #eventDetailDialog="{ event, isOpen, onClose }">
<MyDialog :isOpen="isOpen" @close="onClose()">
<EventForm :event="event" />
</MyDialog>
</template>
</DayFlowCalendar>
</template>
<script setup>
import { DayFlowCalendar } from '@dayflow/vue';
import MyDialog from './MyDialog.vue';
import EventForm from './EventForm.vue';
</script><!-- Custom dialog -->
<dayflow-calendar
[calendar]="calendar"
[eventDetailDialog]="dialog"
>
</dayflow-calendar>
<ng-template #dialog let-args>
<my-dialog [isOpen]="args.isOpen" (close)="args.onClose()">
<event-form [event]="args.event"></event-form>
</my-dialog>
</ng-template><DayFlowCalendar {calendar} eventDetailDialog={MyCustomDialog} />
<!-- MyCustomDialog.svelte -->
<script lang="ts">
import type { EventDetailDialogSlotArgs } from '@dayflow/core';
import MyDialog from './MyDialog.svelte';
import EventForm from './EventForm.svelte';
let { event, isOpen, onClose } = $props<EventDetailDialogSlotArgs>();
</script>
<MyDialog {isOpen} {onClose}>
<EventForm {event} />
</MyDialog>Kurz gesagt: DayFlowCalendar übernimmt die Orchestrierung – Layout, Anbindung der Seitenleiste und das Innenleben der Termindetails – damit Sie sich auf die Konfiguration von useCalendarApp und das übrige Produkterlebnis konzentrieren können.