Composant DayFlowCalendar

DayFlowCalendar est le composant de haut niveau qui affiche la vue active, gère la mise en page et raccorde les éléments d'interface optionnels comme la barre latérale ou la boîte de dialogue de détail d'un événement. Associez-le à useCalendarApp et aux fonctions de création de vues pour obtenir un calendrier pleinement fonctionnel avec très peu de code.

Utilisation de base

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} />

Le composant reçoit l'objet calendar renvoyé par useCalendarApp, lit la vue active et affiche le composant de vue correspondant. Vous pouvez placer votre propre barre d'outils ou interface à côté de DayFlowCalendar, mais celui-ci intègre déjà :

  • une barre latérale de calendriers optionnelle (ajoutée via createSidebarPlugin) ;
  • la prise en charge de la boîte de dialogue de détail d'un événement (pilotée par useEventDetailDialog ou un rendu personnalisé) ;
  • la mise à jour automatique de la mise en page lorsque des calendriers sont activés ou que la vue change.

Props

PropTypeObligatoireDescription
calendarUseCalendarAppReturnObligatoireRésultat de useCalendarApp. Fournit l'état, les vues enregistrées, la configuration de la barre latérale et les actions du calendrier.
collapsedSafeAreaLeftnumberFacultatifMarge intérieure gauche (px) lorsque la barre latérale est repliée, par exemple pour laisser la place aux boutons de fenêtre de macOS.
searchCalendarSearchPropsFacultatifConfiguration de la recherche intégrée.

La personnalisation par slots (contenu de l'événement, contenu du panneau de détail, boîte de dialogue de détail, sélecteur de couleur, etc.) passe par les slots natifs de chaque framework, et non par des props. Consultez Content Slots pour la liste complète.

Configuration de la recherche

La prop search vous permet de personnaliser le comportement de la recherche intégrée. Par défaut, elle effectue une recherche locale dans les titres et les descriptions des événements.

<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,
  }}
/>

Props de recherche

OptionDescription
debounceDelayDélai d'attente en millisecondes avant de déclencher la recherche.
onSearchFonction asynchrone qui récupère les résultats à partir d'un mot-clé.
customSearchFonction synchrone pour filtrer les événements localement avec votre propre logique.
onResultClickCallback facultatif déclenché lors du clic sur un résultat. Il fournit un callback defaultAction qui exécute la navigation intégrée (aller à la date de l'événement, le mettre en évidence et fermer l'interface de recherche sur mobile). Si vous n'appelez pas defaultAction(), vous devez gérer vous-même la navigation et l'état de l'interface.
emptyTextTexte affiché lorsqu'aucun résultat n'est trouvé.
timeFormatFormat d'heure utilisé pour l'affichage des résultats ('12h' ou '24h'). Si un timeFormat global est défini dans useCalendarApp, il prévaut sur ce réglage.

Comportement de la barre latérale

La barre latérale s'ajoute en installant le plugin @dayflow/plugin-sidebar :

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} />
  • Lorsque createSidebarPlugin() est ajouté aux plugins, la barre latérale par défaut (DefaultCalendarSidebar) s'affiche avec les filtres de calendrier et les contrôles « tout afficher / tout masquer ».
  • Vous pouvez personnaliser la largeur, l'état replié par défaut, le mode de création (createCalendarMode), ou fournir votre propre rendu via render ou renderSidebarHeader. Votre fonction de rendu reçoit CalendarSidebarRenderProps (pour render) ou SidebarHeaderSlotArgs (pour renderSidebarHeader), ce qui vous permet de réutiliser ses callbacks et ses données.

Affichage du détail d'un événement

DayFlow propose trois options pour le détail d'un événement :

  1. Mode panneau (par défaut) : lorsque useEventDetailDialog vaut false (valeur par défaut), l'ouverture du détail d'un événement affiche le panneau flottant intégré DefaultEventDetailPanel. Sur ordinateur, il s'ouvre au double-clic (eventDetailTrigger: 'dbClick') ou au simple clic si vous définissez eventDetailTrigger: 'click'. Au toucher, un simple appui suffit toujours.
  2. Mode boîte de dialogue : définissez useEventDetailDialog: true dans useCalendarApp pour activer la fenêtre modale centrée intégrée. Utilisez le slot eventDetailDialog pour la remplacer par votre propre interface.
  3. Tout désactiver : définissez useEventDetailPanel: false dans useCalendarApp pour supprimer le panneau flottant si vous gérez déjà vos propres fenêtres modales via les callbacks de l'application.
// 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>

En résumé, DayFlowCalendar prend en charge la couche d'orchestration — mise en page, intégration de la barre latérale et plomberie du détail des événements — pour que vous puissiez vous concentrer sur la configuration de useCalendarApp et sur le reste de votre produit.

Dans cette page