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} />该组件接收来自 useCalendarApp 的 calendar 对象,读取当前激活的视图,并渲染对应的视图组件。可以在 DayFlowCalendar 外部放置工具栏或其他自定义 UI,该组件本身已内置:
- 可选日历侧边栏(通过
createSidebarPlugin插件添加) - 事件详情弹窗支持(可通过
useEventDetailDialog或自定义渲染器驱动) - 日历切换或视图变更时的自动布局更新
属性说明
| 属性名 | 类型 | 说明 | 必填 |
|---|---|---|---|
calendar | UseCalendarAppReturn | useCalendarApp 的返回结果,提供状态管理、视图注册、侧边栏配置等能力 | 必填 |
collapsedSafeAreaLeft | number | 侧边栏折叠时的左内边距(px),用于兼容 Mac 红绿灯按钮区域 | 可选 |
search | CalendarSearchProps | 内置搜索功能的配置项 | 可选 |
搜索配置
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()插件后,会渲染默认侧边栏,包含日历筛选器和全选控制功能 - 可以自定义宽度、默认折叠状态,或通过
render或renderSidebarHeader提供自定义渲染器。renderSidebarHeader允许您在保留侧边栏整体布局的同时,仅替换头部区域(标题和折叠按钮)
事件详情展示
DayFlow 提供三种事件详情展示方式:
- 默认面板模式 —
useEventDetailDialog为false(默认值)时,打开事件详情会显示内置浮动面板DefaultEventDetailPanel。桌面端默认通过双击打开(eventDetailTrigger: 'dbClick'),也可以设置eventDetailTrigger: 'click'改为单击打开;触摸端始终轻触打开。 - 弹窗模式 — 在
useCalendarApp中设置useEventDetailDialog: true可启用内置居中模态框。使用eventDetailDialog插槽可替换为您自定义的弹窗 UI。 - 完全关闭 — 若您的应用通过回调或全局状态管理事件详情,可在
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 和构建周边的产品体验。
相关文档
- useCalendarApp - 日历应用 hook
- 快速开始 - 设置指南
- 视图 - 可用视图