useCalendarApp
useCalendarApp(config: CalendarAppConfig) 是 DayFlow 的"中控台"。通过一个配置对象即可完成视图注册、事件注入、主题/侧边栏/对话框开关,以及与外部系统同步的回调设置。下面依次拆解常用选项与实践技巧。
快速开始
import {
useCalendarApp,
DayFlowCalendar,
createMonthView,
createWeekView,
ViewType,
} from '@dayflow/react'; // or '@dayflow/vue', '@dayflow/svelte', '@dayflow/angular'
import '@dayflow/core/dist/styles.css';
export function TeamCalendar() {
const calendar = useCalendarApp({
views: [createMonthView(), createWeekView()],
defaultView: ViewType.MONTH,
initialDate: new Date(),
events: [],
});
return <DayFlowCalendar calendar={calendar} />;
}配置概览
| 选项 | 类型 | 必需 | 默认值 | 描述 |
|---|---|---|---|---|
views | CalendarView[] | 必填 | — | 注册视图定义(例如 createMonthView())。至少需要一个视图 |
plugins | CalendarPlugin[] | 可选 | [] | 安装可选插件(拖拽辅助、快捷键等)。每个插件在安装期间接收 app 实例 |
events | Event[] | 可选 | [] | 初始事件数据。之后使用 addEvent/updateEvent 来修改状态 |
callbacks | CalendarCallbacks | 可选 | {} | 在视图、日期或事件更改时触发的生命周期钩子——非常适合与 API 同步 |
defaultView | ViewType | 可选 | ViewType.WEEK | 首先加载的视图;必须存在于 views 中 |
initialDate | Date | 可选 | new Date() | 起始焦点日期(也初始化可见月份计算) |
timeZone | string | 可选 | 用户系统时区 | 所有视图共享的全局显示/编辑时区 |
switcherMode | 'buttons' | 'select' | 可选 | 'buttons' | 控制内置视图切换器在标题中的渲染方式 |
calendars | CalendarType[] | 可选 | [] | 注册日历类别(工作、个人等)及其颜色和可见性 |
defaultCalendar | string | 可选 | 第一个可见日历 | 创建新事件时使用的 ID |
theme | ThemeConfig | 可选 | { mode: 'light' } | 设置全局主题模式和可选的令牌覆盖 |
locale | string | Locale | 可选 | 'en-US' | 设置国际化(i18n)的语言环境。支持语言代码(如 'zh')或 Locale 对象。 |
useEventDetailDialog | boolean | 可选 | false | 启用默认模态详情对话框而不是内联面板 |
useCalendarHeader | boolean | 可选 | true | 启用默认页眉(true)或隐藏页眉(false)。自定义页眉请使用 DayFlowCalendar 上的 calendarHeader 插槽 |
readOnly | boolean | ReadOnlyConfig | 可选 | false | 禁用内置修改 UI。可以是布尔值,也可以是用于细粒度控制(拖拽/查看)的配置对象。程序化事件 API 仍然可用 |
customMobileEventRenderer | MobileEventRenderer | 可选 | — | 用于替换默认移动端事件抽屉/对话框的自定义组件 |
allDaySortComparator | AllDaySortComparator | 可选 | 按日历分组,且跨天全天事件优先 | 控制所有视图中全天事件行顺序的自定义比较函数。传入后会完全覆盖默认顺序 |
核心选项说明
视图(必选)
- 每个视图都是一个包含
type、component、config的CalendarView - 推荐使用内置工厂
createDayView/createWeekView/createMonthView/createYearView defaultView必须存在于views列表,否则初始化会报错
事件
events数组会注入到内部状态,之后通过calendar.addEvent/updateEvent/deleteEvent来维护- 事件的
start/end支持PlainDate、PlainDateTime、ZonedDateTime,helper 已经帮你转换
插件
- 插件在
install(app)阶段获取到日历实例,可注册拖拽、快捷键、统计等能力 - 通过
calendar.app.getPlugin('drag')等方式可以在别处访问插件 API - 可以同时安装多个插件,它们彼此独立
import { createDragPlugin } from '@dayflow/plugin-drag';
import { createEventsPlugin } from '@dayflow/core';
const dragPlugin = createDragPlugin({
enableDrag: true,
enableResize: true,
enableCreate: true,
});
const eventsPlugin = createEventsPlugin({
enableValidation: true,
maxEventsPerDay: 100,
});
const calendar = useCalendarApp({
views: [createWeekView(), createMonthView()],
plugins: [dragPlugin, eventsPlugin],
});回调
callbacks 是连接后端或其他状态管理的桥梁,例如:
onViewChange(view):视图切换后触发,可用于埋点或同步 URLonDateChange(date):当前聚焦日期变化onVisibleRangeChange(start, end, reason):可见日期范围每次变化时触发,无需额外计算即可进行更精准的数据拉取onEventCreate/Update/Delete:与服务端 CRUD 对接onEventDoubleClick(event, e):当事件被双击时触发,常用于自定义弹出层锚点;可使用e.currentTarget作为锚点,返回false可阻止 DayFlow 默认详情面板/对话框打开onMoreEventsClick(date):当月视图中的"+ X 更多"链接被点击时触发onCalendarCreate/onCalendarUpdate/onCalendarDelete:日历增删改的回调,用于同步日历列表onCalendarMerge(sourceId, targetId):合并两个日历时触发(例如将"工作"合并到"个人")onRender:一次渲染完成后触发,适合性能监控
默认视图 & 初始日期
- 单视图日历务必显式设置
defaultView initialDate可从路由、用户偏好或服务器数据中读取,以保持多端一致
timeZone
timeZone用来定义 Day、Week、Month、Year 共用的主显示/编辑时区。- 不传时,DayFlow 会默认使用当前用户设备的系统时区。
- 切换
timeZone只会重新投影视图,不会因为切换时区本身触发事件数据写回。 - 编辑类回调返回的仍然是 canonical event;DayFlow 不会把当前 UI 投影时区下的临时显示值直接当成最终持久化数据。
- Day / Week 的
secondaryTimeZone仍然只是辅助显示时间轴,不会替代全局主时区。
switcherMode
'buttons':横向按钮,桌面端常用'select':下拉选择,占用空间小,适合移动端或视图较多的场景
calendars 与 defaultCalendar
- 用
calendars声明不同的日历类别(工作/个人…)及颜色 - 不指定
defaultCalendar时会使用第一个可见日历
CalendarType 属性:
| 属性 | 类型 | 必填 | 说明 |
|---|---|---|---|
id | string | 是 | 唯一标识符(如 'work'、'personal')。 |
name | string | 是 | 界面中显示的名称。 |
colors | CalendarColors | 是 | 浅色模式颜色配置(见下表)。 |
darkColors | CalendarColors | 否 | 深色模式颜色配置;未提供时回退到 colors。 |
description | string | 否 | 可选的描述文字。 |
icon | string | 否 | 显示在日历名称旁的 Emoji 或图标名。 |
isVisible | boolean | 否 | 是否显示该日历的事件,默认为 true。 |
isDefault | boolean | 否 | 标记为系统默认日历。 |
readOnly | boolean | 否 | 禁用该日历事件的拖拽、调整大小和编辑操作。 |
source | string | 否 | 来源标签(如 'Google Calendar'、'iCloud')。 |
subscription | { url, status, meta? } | 否 | ICS / 远程日历的订阅元数据。 |
CalendarColors 属性:
| 属性 | 类型 | 说明 |
|---|---|---|
eventColor | string | 事件背景色(通常为半透明)。 |
eventSelectedColor | string | 事件选中时的背景色。 |
lineColor | string | 强调色 / 边框颜色。 |
textColor | string | 事件文字颜色。 |
theme
theme 控制全局配色与明暗模式:
const calendar = useCalendarApp({
theme: {
mode: 'dark', // 'light' | 'dark' | 'auto'
},
});主题模式:
'light':浅色模式,浅色背景和深色文本(默认)'dark':深色模式,深色背景和浅色文本'auto':自动跟随系统主题偏好
编程式主题更改:
// 获取当前主题
const currentTheme = calendar.app.getTheme();
// 设置主题
calendar.app.setTheme('dark');
// 订阅主题更改
calendar.app.subscribeThemeChange(theme => {
console.log('主题已更改为:', theme);
});自定义深色模式颜色:
为每个日历类型定义浅色和深色模式的不同颜色:
const calendars = [
{
id: 'work',
name: '工作',
colors: {
// 浅色模式颜色
lineColor: '#0066cc',
eventColor: '#e6f2ff',
eventSelectedColor: '#cce4ff',
textColor: '#003d7a',
},
darkColors: {
// 深色模式颜色
lineColor: '#4da6ff',
eventColor: '#1a3d5c',
eventSelectedColor: '#2a5a8a',
textColor: '#b3d9ff',
},
},
];更多细节见 深色模式。
locale
locale 选项用于设置日历的语言和区域设置。
- 字符串代码: 使用
'en-US'、'ja'、'zh'、'de'、'fr'、'es'、'ko'等语言代码。 - Locale 对象: 传递导入的
Locale对象(以获得类型安全)或自定义对象(用于未支持的语言)。
// 使用字符串代码
const calendar = useCalendarApp({
locale: 'zh',
});
// 使用内置 Locale 对象
import { zh } from '@dayflow/core';
const calendar = useCalendarApp({
locale: zh,
});
// 使用自定义 Locale 对象
const customLocale = {
code: 'it',
messages: { today: 'Oggi', ... }
};
const calendar = useCalendarApp({
locale: customLocale,
});useEventDetailDialog
true:启用默认模态对话框(DefaultEventDetailDialog)。- 与
DayFlowCalendar上的customDetailPanelContent或customEventDetailDialog配合使用,可替换 UI 同时保留内部状态机。
useCalendarHeader
true(默认):渲染内置日历头部。false:完全隐藏头部。
如需渲染自定义头部,请使用 DayFlowCalendar 上的 calendarHeader 插槽。详见 Calendar Header。
readOnly
true:禁用内置修改 UI(拖拽、创建、编辑)。ReadOnlyConfig:细粒度控制:draggable:是否允许拖拽。viewable:是否允许打开事件详情。
calendar.addEvent()、calendar.updateEvent()、calendar.deleteEvent()、calendar.applyEventsChanges()等程序化 API 在只读模式下仍然可用。- 如果您有自定义 UI,建议使用
calendar.canMutateFromUI()来决定是否显示创建、编辑、删除入口。 - 详见 只读模式。
customMobileEventRenderer
- 允许使用您自己的组件替换移动端的默认事件编辑抽屉。
- 详见侧边栏插件。
allDaySortComparator
控制所有视图(日、周、月、年)中全天事件的行排列顺序。
默认情况下,DayFlow 会:
- 按
calendarId的首次出现顺序对全天事件分组 - 让跨天全天事件排在单天全天事件之前
- 尽量让同一日历下的全天事件保持相邻
只有当你确实想完全接管最终顺序时,才需要传入 allDaySortComparator。一旦传入,该比较函数的结果会直接作为最终排序结果。
传入比较函数可完全自定义排序——接收两个 Event 对象,与 JavaScript 的 Array.sort 用法相同:
const calendar = useCalendarApp({
allDaySortComparator: (a, b) => a.title.localeCompare(b.title),
});可直接使用的导出辅助函数(从 @dayflow/core 导出):
| 辅助函数 | 行为 |
|---|---|
sortAllDayByTitle | 按标题字母顺序排序全天事件,并完全覆盖默认分组逻辑 |
import { sortAllDayByTitle } from '@dayflow/core';
const calendar = useCalendarApp({
allDaySortComparator: sortAllDayByTitle,
});使用 updateConfig 在运行时更改排序:
calendar.app.updateConfig({ allDaySortComparator: sortAllDayByTitle });
// 恢复默认的按日历分组排序
calendar.app.updateConfig({ allDaySortComparator: undefined });高级配置示例
import {
useCalendarApp,
DayFlowCalendar,
createMonthView,
createWeekView,
ViewType,
} from '@dayflow/react'; // or '@dayflow/vue', '@dayflow/svelte', '@dayflow/angular'
import { createSidebarPlugin } from '@dayflow/plugin-sidebar';
import '@dayflow/core/dist/styles.css';
const calendars = [
{
id: 'work',
name: '工作',
colors: {
eventColor: '#2563eb',
eventSelectedColor: '#1d4ed8',
lineColor: '#1e40af',
textColor: '#ffffff',
},
},
{
id: 'personal',
name: '个人',
colors: {
eventColor: '#f97316',
eventSelectedColor: '#ea580c',
lineColor: '#c2410c',
textColor: '#ffffff',
},
},
];
export function AdvancedCalendar() {
const calendar = useCalendarApp({
views: [createMonthView(), createWeekView()],
defaultView: ViewType.WEEK,
initialDate: new Date('2024-10-01'),
events: [],
calendars,
defaultCalendar: 'work',
switcherMode: 'select',
callbacks: {
onEventUpdate: event => api.events.update(event),
onVisibleRangeChange: (start, end, reason) =>
preloadVisibleRange(start, end, reason),
},
plugins: [
createSidebarPlugin({
width: 280,
initialCollapsed: false,
}),
],
useEventDetailDialog: true,
});
return <DayFlowCalendar calendar={calendar} />;
}提示:
useCalendarApp返回的对象同时公开状态(currentView、currentDate、events)和操作。与DayFlowCalendar、您自己的工具栏和侧面板共享相同的实例以保持所有内容同步。
相关文档
- DayFlowCalendar - 主要 UI 组件
- 快速开始 - 设置指南
- 事件 - 事件管理
- 视图 - 可用视图