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

配置概览

选项类型必需默认值描述
viewsCalendarView[]必填注册视图定义(例如 createMonthView())。至少需要一个视图
pluginsCalendarPlugin[]可选[]安装可选插件(拖拽辅助、快捷键等)。每个插件在安装期间接收 app 实例
eventsEvent[]可选[]初始事件数据。之后使用 addEvent/updateEvent 来修改状态
callbacksCalendarCallbacks可选{}在视图、日期或事件更改时触发的生命周期钩子——非常适合与 API 同步
defaultViewViewType可选ViewType.WEEK首先加载的视图;必须存在于 views
initialDateDate可选new Date()起始焦点日期(也初始化可见月份计算)
timeZonestring可选用户系统时区所有视图共享的全局显示/编辑时区
switcherMode'buttons' | 'select'可选'buttons'控制内置视图切换器在标题中的渲染方式
calendarsCalendarType[]可选[]注册日历类别(工作、个人等)及其颜色和可见性
defaultCalendarstring可选第一个可见日历创建新事件时使用的 ID
themeThemeConfig可选{ mode: 'light' }设置全局主题模式和可选的令牌覆盖
localestring | Locale可选'en-US'设置国际化(i18n)的语言环境。支持语言代码(如 'zh')或 Locale 对象。
useEventDetailDialogboolean可选false启用默认模态详情对话框而不是内联面板
useCalendarHeaderboolean可选true启用默认页眉(true)或隐藏页眉(false)。自定义页眉请使用 DayFlowCalendar 上的 calendarHeader 插槽
readOnlyboolean | ReadOnlyConfig可选false禁用内置修改 UI。可以是布尔值,也可以是用于细粒度控制(拖拽/查看)的配置对象。程序化事件 API 仍然可用
customMobileEventRendererMobileEventRenderer可选用于替换默认移动端事件抽屉/对话框的自定义组件
allDaySortComparatorAllDaySortComparator可选按日历分组,且跨天全天事件优先控制所有视图中全天事件行顺序的自定义比较函数。传入后会完全覆盖默认顺序

核心选项说明

视图(必选)

  • 每个视图都是一个包含 typecomponentconfigCalendarView
  • 推荐使用内置工厂 createDayView/createWeekView/createMonthView/createYearView
  • defaultView 必须存在于 views 列表,否则初始化会报错

事件

  • events 数组会注入到内部状态,之后通过 calendar.addEvent / updateEvent / deleteEvent 来维护
  • 事件的 start/end 支持 PlainDatePlainDateTimeZonedDateTime,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):视图切换后触发,可用于埋点或同步 URL
  • onDateChange(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 属性:

属性类型必填说明
idstring唯一标识符(如 'work''personal')。
namestring界面中显示的名称。
colorsCalendarColors浅色模式颜色配置(见下表)。
darkColorsCalendarColors深色模式颜色配置;未提供时回退到 colors
descriptionstring可选的描述文字。
iconstring显示在日历名称旁的 Emoji 或图标名。
isVisibleboolean是否显示该日历的事件,默认为 true
isDefaultboolean标记为系统默认日历。
readOnlyboolean禁用该日历事件的拖拽、调整大小和编辑操作。
sourcestring来源标签(如 'Google Calendar''iCloud')。
subscription{ url, status, meta? }ICS / 远程日历的订阅元数据。

CalendarColors 属性:

属性类型说明
eventColorstring事件背景色(通常为半透明)。
eventSelectedColorstring事件选中时的背景色。
lineColorstring强调色 / 边框颜色。
textColorstring事件文字颜色。

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 上的 customDetailPanelContentcustomEventDetailDialog 配合使用,可替换 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 返回的对象同时公开状态(currentViewcurrentDateevents)和操作。与 DayFlowCalendar、您自己的工具栏和侧面板共享相同的实例以保持所有内容同步。

相关文档

On this page