DayFlowCalendar

DayFlowCalendar 是日历组件的核心容器,负责渲染当前选中的视图、处理整体布局,并集成可选 UI 元素(如侧边栏和事件详情弹窗)。配合 useCalendarApp 和视图工厂函数,您可以用最少的代码快速构建功能完整的日历应用。

基础用法

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

该组件接收来自 useCalendarAppcalendar 对象,读取当前激活的视图,并渲染对应的视图组件。可以在 DayFlowCalendar 外部放置工具栏或其他自定义 UI,该组件本身已内置:

  • 可选日历侧边栏(通过 createSidebarPlugin 插件添加)
  • 事件详情弹窗支持(可通过 useEventDetailDialog 或自定义渲染器驱动)
  • 日历切换或视图变更时的自动布局更新

属性说明

属性名类型说明必填
calendarUseCalendarAppReturnuseCalendarApp 的返回结果,提供状态管理、视图注册、侧边栏配置等能力必填
collapsedSafeAreaLeftnumber侧边栏折叠时的左内边距(px),用于兼容 Mac 红绿灯按钮区域可选
searchCalendarSearchProps内置搜索功能的配置项可选

搜索配置

search 属性允许您自定义内置搜索的行为。默认情况下,它会在本地搜索事件的标题和描述。

<DayFlowCalendar
  calendar={calendar}
  search={{
    debounceDelay: 500,
    emptyText: '未找到相关事件',
    onSearch: async keyword => {
      // 自定义异步搜索(例如从 API 获取)
      return fetch(`/api/search?q=${keyword}`).then(res => res.json());
    },
  }}
/>
<template>
  <DayFlowCalendar
    :calendar="calendar"
    :search="{
      debounceDelay: 500,
      emptyText: '未找到相关事件',
      onSearch: async (keyword) => {
        // 自定义异步搜索(例如从 API 获取)
        return fetch(`/api/search?q=${keyword}`).then(res => res.json());
      }
    }"
  />
</template>

<script setup>
  import { DayFlowCalendar } from '@dayflow/vue';
</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 = ...
  searchConfig = {
    debounceDelay: 500,
    emptyText: '未找到相关事件',
    onSearch: async (keyword: string) => {
      // 自定义异步搜索(例如从 API 获取)
      return fetch(`/api/search?q=${keyword}`).then(res => res.json());
    }
  };
}
<script>
  import { DayFlowCalendar } from '@dayflow/svelte';

  const searchConfig = {
    debounceDelay: 500,
    emptyText: '未找到相关事件',
    onSearch: async (keyword) => {
      // 自定义异步搜索(例如从 API 获取)
      return fetch(`/api/search?q=${keyword}`).then(res => res.json());
    }
  };
</script>

<DayFlowCalendar {calendar} search={searchConfig} />

Search Props

选项描述
debounceDelay触发搜索前的防抖延迟时间(毫秒)。
onSearch基于关键词获取结果的异步函数。
customSearch使用自定义逻辑在本地过滤事件的同步函数。
onResultClick点击搜索结果时的回调。包含一个 defaultAction 回调用于触发内置的跳转逻辑(跳转到事件日期、高亮该事件并在移动端自动关闭搜索界面)。如果不调用 defaultAction(),则需要自行处理所有的跳转和 UI 状态切换。
emptyText未找到结果时显示的文本。
timeFormat搜索结果显示的时间格式('12h''24h')。如果在 useCalendarApp 中配置了全局 timeFormat,将优先采用全局配置。

侧边栏配置

侧边栏通过安装并添加 @dayflow/plugin-sidebar 插件来启用:

import { DayFlowCalendar, useCalendarApp, createWeekView } from '@dayflow/react';
import { createSidebarPlugin } from '@dayflow/plugin-sidebar';

function App() {
  const calendar = useCalendarApp({
    views: [createWeekView()],
    plugins: [
      createSidebarPlugin({
        width: 280,
        initialCollapsed: false,
        createCalendarMode: 'modal', // 'inline' 或 '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', // 'inline' 或 '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', // 'inline' 或 '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', // 'inline' 或 'modal'
      }),
    ],
  });
</script>

<DayFlowCalendar {calendar} />
  • 当添加 createSidebarPlugin() 插件后,会渲染默认侧边栏,包含日历筛选器和全选控制功能
  • 可以自定义宽度、默认折叠状态,或通过 renderrenderSidebarHeader 提供自定义渲染器。renderSidebarHeader 允许您在保留侧边栏整体布局的同时,仅替换头部区域(标题和折叠按钮)

事件详情展示

DayFlow 提供三种事件详情展示方式:

  1. 默认面板模式useEventDetailDialogfalse(默认值)时,打开事件详情会显示内置浮动面板 DefaultEventDetailPanel。桌面端默认通过双击打开(eventDetailTrigger: 'dbClick'),也可以设置 eventDetailTrigger: 'click' 改为单击打开;触摸端始终轻触打开。
  2. 弹窗模式 — 在 useCalendarApp 中设置 useEventDetailDialog: true 可启用内置居中模态框。使用 eventDetailDialog 插槽可替换为您自定义的弹窗 UI。
  3. 完全关闭 — 若您的应用通过回调或全局状态管理事件详情,可在 useCalendarApp 中设置 useEventDetailPanel: false 来完全隐藏浮动面板。
// 隐藏内置面板 — 在其他地方使用自定义模态框
const calendar = useCalendarApp({
  // ...
  useEventDetailPanel: false,
});

return <DayFlowCalendar calendar={calendar} />;
<template>
  <DayFlowCalendar :calendar="calendar" />
</template>

<script setup>
  import { DayFlowCalendar, useCalendarApp } from '@dayflow/vue';

  // 隐藏内置面板 — 在其他地方使用自定义模态框
  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 {
  // 隐藏内置面板 — 在其他地方使用自定义模态框
  calendar = {
    // ...
    useEventDetailPanel: false,
  };
}
<script>
  import { DayFlowCalendar, useCalendarApp } from '@dayflow/svelte';

  // 隐藏内置面板 — 在其他地方使用自定义模态框
  const calendar = useCalendarApp({
    // ...
    useEventDetailPanel: false,
  });
</script>

<DayFlowCalendar {calendar} />
// 自定义面板内容(保留默认面板框架)
<DayFlowCalendar
  calendar={calendar}
  eventDetailContent={({ event, onClose }) => (
    <div className='p-4'>
      <h2>{event.title}</h2>
      <button onClick={onClose}>关闭</button>
    </div>
  )}
/>
<!-- 自定义面板内容(保留默认面板框架) -->
<template>
  <DayFlowCalendar :calendar="calendar">
    <template #eventDetailContent="{ event, onClose }">
      <div class="p-4">
        <h2>{{ event.title }}</h2>
        <button @click="onClose">关闭</button>
      </div>
    </template>
  </DayFlowCalendar>
</template>

<script setup>
  import { DayFlowCalendar } from '@dayflow/vue';
</script>
import { Component } from '@angular/core';
import { DayFlowCalendarModule } from '@dayflow/angular';

@Component({
  selector: 'app-root',
  standalone: true,
  imports: [DayFlowCalendarModule],
  template: `
    <!-- 自定义面板内容(保留默认面板框架) -->
    <dayflow-calendar
      [calendar]="calendar"
      [eventDetailContent]="detailTemplate"
    >
    </dayflow-calendar>

    <ng-template #detailTemplate let-args>
      <div class="p-4">
        <h2>{{ args.event.title }}</h2>
        <button (click)="args.onClose()">关闭</button>
      </div>
    </ng-template>
  `
})
export class AppComponent {
  // calendar = ...
}
<!-- App.svelte -->
<script lang="ts">
  import { DayFlowCalendar } from '@dayflow/svelte';
  import CustomDetailPanel from './CustomDetailPanel.svelte';
</script>

<!-- 自定义面板内容(保留默认面板框架) -->
<DayFlowCalendar {calendar} eventDetailContent={CustomDetailPanel} />

<!-- CustomDetailPanel.svelte -->
<script lang="ts">
  import type { EventDetailContentProps } from '@dayflow/core';
  let { event, onClose } = $props<EventDetailContentProps>();
</script>

<div class="p-4">
  <h2>{event.title}</h2>
  <button onclick={onClose}>关闭</button>
</div>
// 自定义弹窗(需要在 useCalendarApp 中设置 useEventDetailDialog: true)
<DayFlowCalendar
  calendar={calendar}
  eventDetailDialog={({ event, isOpen, onClose }) => (
    <MyDialog isOpen={isOpen} onClose={onClose}>
      <EventForm event={event} />
    </MyDialog>
  )}
/>
<!-- 自定义弹窗(需要在 useCalendarApp 中设置 useEventDetailDialog: true) -->
<template>
  <DayFlowCalendar :calendar="calendar">
    <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>
import { Component } from '@angular/core';
import { DayFlowCalendarModule } from '@dayflow/angular';
import { MyDialogComponent } from './my-dialog.component';
import { EventFormComponent } from './event-form.component';

@Component({
  selector: 'app-root',
  standalone: true,
  imports: [DayFlowCalendarModule, MyDialogComponent, EventFormComponent],
  template: `
    <!-- 自定义弹窗(需要在 useCalendarApp 中设置 useEventDetailDialog: true) -->
    <dayflow-calendar
      [calendar]="calendar"
      [eventDetailDialog]="dialogTemplate"
    >
    </dayflow-calendar>

    <ng-template #dialogTemplate let-args>
      <my-dialog [isOpen]="args.isOpen" (close)="args.onClose()">
        <event-form [event]="args.event"></event-form>
      </my-dialog>
    </ng-template>
  `
})
export class AppComponent {
  // calendar = ...
}
<!-- App.svelte -->
<script lang="ts">
  import { DayFlowCalendar } from '@dayflow/svelte';
  import CustomDetailDialog from './CustomDetailDialog.svelte';
</script>

<!-- 自定义弹窗(需要在 useCalendarApp 中设置 useEventDetailDialog: true) -->
<DayFlowCalendar {calendar} eventDetailDialog={CustomDetailDialog} />

<!-- CustomDetailDialog.svelte -->
<script lang="ts">
  import type { EventDetailDialogProps } from '@dayflow/core';
  import MyDialog from './MyDialog.svelte';
  import EventForm from './EventForm.svelte';
  let { event, isOpen, onClose } = $props<EventDetailDialogProps>();
</script>

<MyDialog {isOpen} onclose={onClose}>
  <EventForm {event} />
</MyDialog>

总而言之,DayFlowCalendar 承担了协调层的职责——处理整体布局、侧边栏集成和事件详情逻辑,专注于配置 useCalendarApp 和构建周边的产品体验。

相关文档

On this page