@dayflow/core 1.0.7 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.ja.md +325 -90
- package/README.md +319 -78
- package/README.zh.md +324 -89
- package/dist/components/common/CalendarHeader.d.ts +4 -0
- package/dist/components/common/ColorPicker.d.ts +1 -0
- package/dist/components/common/DefaultEventDetailPanel.d.ts +1 -1
- package/dist/components/common/MobileEventDrawer.d.ts +12 -0
- package/dist/components/common/MobileSearchDialog.d.ts +14 -0
- package/dist/components/common/QuickCreateEventPopup.d.ts +10 -0
- package/dist/components/common/SearchDrawer.d.ts +13 -0
- package/dist/components/common/SearchResultsList.d.ts +11 -0
- package/dist/components/common/ViewHeader.d.ts +0 -2
- package/dist/components/mobileEventDrawer/DefaultMobileEventDrawer.d.ts +3 -0
- package/dist/components/mobileEventDrawer/components/Switch.d.ts +7 -0
- package/dist/components/mobileEventDrawer/components/TimePickerWheel.d.ts +7 -0
- package/dist/components/mobileEventDrawer/index.d.ts +3 -0
- package/dist/components/monthView/MultiDayEvent.d.ts +7 -2
- package/dist/components/monthView/WeekComponent.d.ts +5 -3
- package/dist/components/monthView/util.d.ts +1 -1
- package/dist/components/search/MobileSearchDialog.d.ts +14 -0
- package/dist/components/search/SearchDrawer.d.ts +13 -0
- package/dist/components/search/SearchResultsList.d.ts +11 -0
- package/dist/components/sidebar/components/CalendarList.d.ts +2 -0
- package/dist/components/sidebar/components/SidebarHeader.d.ts +0 -1
- package/dist/components/weekView/CalendarEvent.d.ts +7 -2
- package/dist/core/CalendarApp.d.ts +15 -1
- package/dist/core/DayFlowCalendar.d.ts +3 -0
- package/dist/hooks/virtualScroll/useVirtualMonthScroll.d.ts +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.esm.js +1 -1
- package/dist/index.js +1 -1
- package/dist/locale/types.d.ts +1 -1
- package/dist/styles/classNames.d.ts +9 -9
- package/dist/styles.css +464 -32
- package/dist/types/core.d.ts +38 -0
- package/dist/types/dragIndicator.d.ts +5 -3
- package/dist/types/event.d.ts +2 -0
- package/dist/types/hook.d.ts +7 -7
- package/dist/types/index.d.ts +1 -0
- package/dist/types/mobileEvent.d.ts +21 -0
- package/dist/types/monthView.d.ts +1 -0
- package/dist/types/plugin.d.ts +6 -4
- package/dist/types/search.d.ts +35 -0
- package/dist/utils/compareUtils.d.ts +5 -0
- package/dist/utils/eventUtils.d.ts +7 -0
- package/dist/utils/helpers.d.ts +2 -1
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/searchUtils.d.ts +35 -0
- package/dist/views/MonthView.d.ts +0 -2
- package/dist/views/WeekView.d.ts +0 -2
- package/package.json +1 -1
package/README.zh.md
CHANGED
|
@@ -1,148 +1,383 @@
|
|
|
1
1
|
# DayFlow
|
|
2
2
|
|
|
3
|
-
[English](README.md) | **中文** | [日本語](README.ja.md)
|
|
3
|
+
[English](README.md) | **中文** | [日本語](README.ja.md) | [快速开始 & 贡献](CONTRIBUTING.md)
|
|
4
4
|
|
|
5
|
-
一个灵活且功能丰富的 React
|
|
5
|
+
一个灵活且功能丰富的 React 日历组件库,支持拖拽、多视图和插件架构。
|
|
6
6
|
|
|
7
7
|
[](https://www.npmjs.com/package/@dayflow/core)
|
|
8
8
|
[](https://github.com/dayflow-js/dayflow/pulls)
|
|
9
9
|
[](https://github.com/dayflow-js/dayflow/blob/main/LICENSE)
|
|
10
|
-
[](https://discord.gg/
|
|
10
|
+
[](https://discord.gg/9vdFZKJqBb)
|
|
11
11
|
|
|
12
|
-
## 🗓️
|
|
12
|
+
## 🗓️ 功能特性
|
|
13
13
|
|
|
14
|
-
### ✨
|
|
14
|
+
### ✨ 月视图、周视图、日视图及多种视图类型
|
|
15
15
|
|
|
16
|
-
| 月视图
|
|
17
|
-
|
|
16
|
+
| 月视图 | 周视图 |
|
|
17
|
+
|------------------------------------------|----------------------------------------|
|
|
18
18
|
|  |  |
|
|
19
19
|
|
|
20
|
-
| 日视图
|
|
21
|
-
|
|
20
|
+
| 日视图 | 事件堆叠层级 |
|
|
21
|
+
|---------------------------------------|------------------------------------------|
|
|
22
22
|
|  |  |
|
|
23
23
|
|
|
24
|
-
### 🤩
|
|
24
|
+
### 🤩 默认面板(提供多种事件详情面板选项)
|
|
25
25
|
|
|
26
|
-
|
|
|
27
|
-
|
|
28
|
-
| 
|
|
26
|
+
| 详情弹窗 | 详情对话框 |
|
|
27
|
+
|-------------------------------------|--------------------------------------|
|
|
28
|
+
|  |  |
|
|
29
29
|
|
|
30
|
-
|
|
30
|
+
## 快速开始
|
|
31
31
|
|
|
32
|
-
|
|
32
|
+
官方网站:
|
|
33
33
|
|
|
34
|
-
https://github.
|
|
34
|
+
https://dayflow-js.github.io/calendar/
|
|
35
35
|
|
|
36
|
-
|
|
36
|
+
### 安装
|
|
37
37
|
|
|
38
|
-
|
|
38
|
+
```bash
|
|
39
|
+
npm install @dayflow/core lucide-react
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
整个 **DayFlow** 应用通过 `useCalendarApp` hook 创建,它返回一个 **`calendar`** 对象。
|
|
43
|
+
|
|
44
|
+
该对象随后通过 `DayFlowCalendar` UI 组件进行渲染。
|
|
39
45
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
46
|
+
```tsx
|
|
47
|
+
'use client';
|
|
48
|
+
|
|
49
|
+
import {
|
|
50
|
+
useCalendarApp,
|
|
51
|
+
DayFlowCalendar,
|
|
52
|
+
createMonthView,
|
|
53
|
+
createEvent,
|
|
54
|
+
createAllDayEvent,
|
|
55
|
+
createTimedEvent,
|
|
56
|
+
} from '@dayflow/core';
|
|
57
|
+
import '@dayflow/core/dist/styles.css';
|
|
58
|
+
|
|
59
|
+
// 本地定时事件(无时区复杂性)
|
|
60
|
+
const meeting = createEvent({
|
|
61
|
+
id: '1',
|
|
62
|
+
title: 'Team Meeting',
|
|
63
|
+
start: new Date(2024, 9, 15, 10, 0), // 2024年10月15日 10:00
|
|
64
|
+
end: new Date(2024, 9, 15, 11, 0), // 2024年10月15日 11:00
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
// 全天事件
|
|
68
|
+
const holiday = createAllDayEvent(
|
|
69
|
+
'2',
|
|
70
|
+
'Tech Conference',
|
|
71
|
+
new Date(2024, 9, 20)
|
|
72
|
+
);
|
|
73
|
+
|
|
74
|
+
// 快速创建定时事件
|
|
75
|
+
const lunch = createTimedEvent(
|
|
76
|
+
'3',
|
|
77
|
+
'Lunch Break',
|
|
78
|
+
new Date(2024, 9, 15, 12, 0), // 12:00
|
|
79
|
+
new Date(2024, 9, 15, 13, 0) // 13:00
|
|
80
|
+
);
|
|
81
|
+
|
|
82
|
+
export default function MyCalendar() {
|
|
83
|
+
const calendar = useCalendarApp({
|
|
84
|
+
views: [createMonthView()],
|
|
85
|
+
events: [],
|
|
86
|
+
calendars: [],
|
|
87
|
+
defaultView: 'month',
|
|
88
|
+
initialDate: new Date(),
|
|
89
|
+
});
|
|
49
90
|
|
|
50
|
-
|
|
91
|
+
return <DayFlowCalendar calendar={calendar} />;
|
|
92
|
+
}
|
|
93
|
+
```
|
|
51
94
|
|
|
52
|
-
|
|
95
|
+
- **views**: 日历视图数组。目前 DayFlow 提供四个内置工厂函数:
|
|
96
|
+
`createMonthView`、`createWeekView`、`createDayView` 和 `createYearView`(开发中)。
|
|
97
|
+
视图的顺序决定了标签页的顺序(年 / 月 / 周 / 日)。
|
|
98
|
+
- **events**: 日历的核心数据。可以使用内置助手函数
|
|
99
|
+
`createEvent`、`createAllDayEvent` 和 `createTimedEvent` 创建事件,具体取决于事件类型。
|
|
53
100
|
|
|
54
|
-
|
|
55
|
-
- **全天区域**:专属全天事件栏
|
|
56
|
-
- **事件堆叠**:智能调度堆叠层级
|
|
57
|
-
- **侧边栏**:自带日历管理侧栏
|
|
101
|
+
---
|
|
58
102
|
|
|
59
|
-
|
|
103
|
+
## `useCalendarApp` 配置选项
|
|
60
104
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
105
|
+
| 选项 | 类型 | 默认值 | 描述 | 必填 |
|
|
106
|
+
|---|---|---|---|---|
|
|
107
|
+
| `views` | `CalendarView[]` | — | 注册的视图定义(如 `createMonthView()`)。至少需要一个视图 | ✅ |
|
|
108
|
+
| `plugins` | `CalendarPlugin[]` | `[]` | 可选插件(拖拽支持、键盘快捷键等)。每个插件在安装时都会接收 app 实例 | ❌ |
|
|
109
|
+
| `events` | `Event[]` | `[]` | 初始事件数据。后续使用 `addEvent` / `updateEvent` 进行修改 | ❌ |
|
|
110
|
+
| `callbacks` | `CalendarCallbacks` | `{}` | 视图、日期或事件变更时触发的生命周期钩子 — 适用于 API 同步 | ❌ |
|
|
111
|
+
| `defaultView` | `ViewType` | `ViewType.WEEK` | 加载时的初始视图;必须存在于 `views` 中 | ❌ |
|
|
112
|
+
| `initialDate` | `Date` | `new Date()` | 初始聚焦日期(也用于初始化可视范围计算) | ❌ |
|
|
113
|
+
| `switcherMode` | `'buttons' \| 'select'` | `'buttons'` | 控制头部内置视图切换器的渲染方式 | ❌ |
|
|
114
|
+
| `calendars` | `CalendarType[]` | `[]` | 注册日历分类(工作、个人等)及其颜色和可见性 | ❌ |
|
|
115
|
+
| `defaultCalendar` | `string` | 第一个可见日历 | 创建新事件时使用的日历 ID | ❌ |
|
|
116
|
+
| `theme` | `ThemeConfig` | `{ mode: 'light' }` | 全局主题模式和可选的 token 覆盖 | ❌ |
|
|
117
|
+
| `locale` | `string \| Locale` | `'en-US'` | 国际化 (i18n)。支持语言代码(如 `'zh'`)或 Locale 对象 | ❌ |
|
|
118
|
+
| `useSidebar` | `boolean \| SidebarConfig` | `false` | 启用内置侧边栏或自定义宽度、折叠状态及渲染器 | ❌ |
|
|
119
|
+
| `useEventDetailDialog` | `boolean` | `false` | 使用模态对话框代替内联面板显示事件详情 | ❌ |
|
|
66
120
|
|
|
67
|
-
|
|
121
|
+
## 回调函数
|
|
68
122
|
|
|
69
|
-
|
|
70
|
-
- **点击事件**:随时获取事件点击反馈
|
|
71
|
-
- **拖拽缩放**:移动与调整长度一气呵成
|
|
72
|
-
- **颜色选择器**:内置颜色选择 UI
|
|
123
|
+
`callbacks` 充当 DayFlow 与后端或外部状态管理之间的桥梁。
|
|
73
124
|
|
|
74
|
-
|
|
125
|
+
它们通常用于数据库或 API 的 CRUD 操作。
|
|
75
126
|
|
|
76
|
-
|
|
77
|
-
- **TypeScript First**:所有 API 提供类型定义
|
|
78
|
-
- **插件体系**:事件插件与拖拽插件可扩展
|
|
79
|
-
- **Temporal API**:使用 Modern Temporal 处理时间
|
|
127
|
+
示例包括:
|
|
80
128
|
|
|
81
|
-
|
|
129
|
+
- `onViewChange(view)`: 视图切换后触发(用于分析或 URL 同步)
|
|
130
|
+
- `onDateChange(date)`: 聚焦日期变更时触发
|
|
131
|
+
- `onVisibleMonthChange(date)`: 可视月份变更时触发(用于预加载数据)
|
|
132
|
+
- `onEventCreate / Update / Delete`: 连接事件 CRUD 与后端
|
|
133
|
+
- `onCalendarCreate / Update / Delete`: 同步日历列表变更
|
|
134
|
+
- `onCalendarMerge(sourceId, targetId)`: 合并两个日历时触发
|
|
135
|
+
- `onRender`: 渲染周期结束后触发,适用于性能监控
|
|
82
136
|
|
|
83
|
-
```
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
137
|
+
```tsx
|
|
138
|
+
const calendar = useCalendarApp({
|
|
139
|
+
views: [createDayView(), createWeekView(), createMonthView()],
|
|
140
|
+
events,
|
|
141
|
+
calendars: customCalendarTypes,
|
|
142
|
+
defaultCalendar: 'work',
|
|
143
|
+
plugins: [dragPlugin],
|
|
144
|
+
theme: { mode: 'auto' },
|
|
145
|
+
useSidebar: sidebarConfig,
|
|
146
|
+
callbacks: {
|
|
147
|
+
onCalendarUpdate: async calendar => {
|
|
148
|
+
console.log('update calendar:', calendar);
|
|
149
|
+
},
|
|
150
|
+
onCalendarDelete: async calendar => {
|
|
151
|
+
console.log('delete calendar:', calendar);
|
|
152
|
+
},
|
|
153
|
+
onCalendarCreate: async calendar => {
|
|
154
|
+
// await server API call
|
|
155
|
+
console.log('create calendar:', calendar);
|
|
156
|
+
},
|
|
157
|
+
onCalendarMerge: async (sourceId, targetId) => {
|
|
158
|
+
console.log('merge calendar:', sourceId, targetId);
|
|
159
|
+
},
|
|
160
|
+
},
|
|
161
|
+
});
|
|
89
162
|
```
|
|
90
163
|
|
|
91
|
-
|
|
164
|
+
---
|
|
165
|
+
|
|
166
|
+
## 事件详情管理
|
|
92
167
|
|
|
93
|
-
|
|
94
|
-
- `react-dom` >= 18.0.0
|
|
95
|
-
- `lucide-react` >= 0.400.0
|
|
168
|
+
DayFlow 包含一个默认的事件详情面板,支持编辑:
|
|
96
169
|
|
|
97
|
-
|
|
170
|
+
- 标题
|
|
171
|
+
- 时间范围
|
|
172
|
+
- 备注
|
|
173
|
+
|
|
174
|
+
您还可以传递 `meta` 对象来存储自定义字段,如 **会议链接**、**地点** 等。
|
|
175
|
+
|
|
176
|
+
<img width="536" height="323" alt="image" src="https://github.com/user-attachments/assets/7a599105-460e-4f83-8418-92bcd0ff8c2a" />
|
|
177
|
+
|
|
178
|
+
通过向 `DayFlowCalendar` 传递 `useEventDetailDialog`,可以将详情面板启用为模态对话框:
|
|
98
179
|
|
|
99
180
|
```tsx
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
181
|
+
<DayFlowCalendar calendar={calendar} useEventDetailDialog={true} />
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
<img width="1476" height="1108" alt="image" src="https://github.com/user-attachments/assets/c9f1e231-f8d1-4006-8ff1-942bb7491934" />
|
|
185
|
+
|
|
186
|
+
---
|
|
187
|
+
|
|
188
|
+
### 自定义事件详情面板 / 对话框
|
|
189
|
+
|
|
190
|
+
对于完全自定义的 UI,您可以通过以下方式提供自己的组件来替换默认详情面板或对话框:
|
|
191
|
+
|
|
192
|
+
- `customDetailPanelContent`
|
|
193
|
+
- `customEventDetailDialog`
|
|
194
|
+
|
|
195
|
+
```tsx
|
|
196
|
+
<DayFlowCalendar
|
|
197
|
+
calendar={calendar}
|
|
198
|
+
customEventDetailDialog={CustomDialog} // Modal dialog
|
|
199
|
+
customDetailPanelContent={CustomContent} // Floating panel
|
|
200
|
+
/>
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
查看文档了解详情:
|
|
204
|
+
|
|
205
|
+
- **自定义事件详情对话框**
|
|
206
|
+
https://dayflow-js.github.io/calendar/docs-zh/features/custom-detail-dialog
|
|
207
|
+
- **自定义事件详情面板**
|
|
208
|
+
https://dayflow-js.github.io/calendar/docs-zh/features/custom-detail-panel
|
|
209
|
+
|
|
210
|
+
---
|
|
211
|
+
|
|
212
|
+
## 侧边栏
|
|
103
213
|
|
|
104
|
-
|
|
214
|
+
DayFlow 内置了强大的侧边栏。
|
|
215
|
+
|
|
216
|
+
您可以:
|
|
217
|
+
|
|
218
|
+
- 从侧边栏拖拽日历以创建事件
|
|
219
|
+
|
|
220
|
+

|
|
221
|
+
|
|
222
|
+
- 合并、删除和重新着色日历
|
|
223
|
+
|
|
224
|
+
<img width="540" height="423" alt="image" src="https://github.com/user-attachments/assets/257a8671-e645-43fe-861e-613030f6c46e" />
|
|
225
|
+
|
|
226
|
+
- 使用预设颜色或通过颜色选择器选择自定义颜色
|
|
227
|
+
|
|
228
|
+
<img width="872" height="708" alt="image" src="https://github.com/user-attachments/assets/bfda7cde-281e-4c23-86d6-910b13e7bc63" />
|
|
229
|
+
|
|
230
|
+
```tsx
|
|
231
|
+
const calendar = useCalendarApp({
|
|
232
|
+
views: [createMonthView(), createWeekView(), createDayView()],
|
|
233
|
+
plugins: [createDragPlugin()],
|
|
234
|
+
events,
|
|
235
|
+
calendars,
|
|
236
|
+
defaultView: ViewType.WEEK,
|
|
237
|
+
useSidebar: {
|
|
238
|
+
enabled: true,
|
|
239
|
+
width: 280,
|
|
240
|
+
},
|
|
241
|
+
});
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
---
|
|
245
|
+
|
|
246
|
+
### `useSidebar` 配置
|
|
247
|
+
|
|
248
|
+
| 属性 | 类型 | 描述 | 默认值 |
|
|
249
|
+
|---|---|---|---|
|
|
250
|
+
| `enabled` | `boolean` | 侧边栏是否启用。 | `true` |
|
|
251
|
+
| `width` | `number \| string` | 侧边栏宽度(如 `240` 或 `'20%'`)。 | `'240px'` |
|
|
252
|
+
| `initialCollapsed` | `boolean` | 侧边栏默认是否折叠。 | `false` |
|
|
253
|
+
| `render` | `(props: CalendarSidebarRenderProps) => React.ReactNode` | 侧边栏 UI 的完全覆盖。 | - |
|
|
254
|
+
| `createCalendarMode` | `'inline' \| 'modal'` | 创建新日历的模式:`inline`(列表内直接编辑)或 `modal`(弹出对话框)。 | `'inline'` |
|
|
255
|
+
| `renderCalendarContextMenu` | `(calendar: CalendarType, onClose: () => void) => React.ReactNode` | 日历项右键菜单的自定义渲染器。 | - |
|
|
256
|
+
| `renderCreateCalendarDialog` | `(props: CreateCalendarDialogProps) => React.ReactNode` | 日历创建对话框的自定义渲染器(用于 `modal` 模式)。 | - |
|
|
257
|
+
|
|
258
|
+
|
|
259
|
+
---
|
|
260
|
+
|
|
261
|
+
### 自定义侧边栏
|
|
262
|
+
|
|
263
|
+
如果您的项目已有侧边栏设计,可以使用 `useSidebar.render` 完全自定义它。
|
|
264
|
+
|
|
265
|
+
该渲染函数接收实时日历状态和与 DayFlow 核心交互的辅助方法。
|
|
266
|
+
|
|
267
|
+
**`CalendarSidebarRenderProps` 实现了您的自定义侧边栏与 DayFlow 核心之间的通信。**
|
|
268
|
+
|
|
269
|
+
```tsx
|
|
270
|
+
import type { CalendarSidebarRenderProps } from '@dayflow/core';
|
|
271
|
+
|
|
272
|
+
const CustomSidebar = ({
|
|
273
|
+
app,
|
|
274
|
+
calendars,
|
|
275
|
+
toggleCalendarVisibility,
|
|
276
|
+
toggleAll,
|
|
277
|
+
isCollapsed,
|
|
278
|
+
setCollapsed,
|
|
279
|
+
}: CalendarSidebarRenderProps) => {
|
|
280
|
+
if (isCollapsed) {
|
|
281
|
+
return <button onClick={() => setCollapsed(false)}>Expand Sidebar</button>;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
return (
|
|
285
|
+
<aside className="flex h-full flex-col gap-4 p-4">
|
|
286
|
+
<header className="flex items-center justify-between">
|
|
287
|
+
<h3 className="text-sm font-semibold">Calendars</h3>
|
|
288
|
+
<div className="space-x-2">
|
|
289
|
+
<button onClick={() => toggleAll(true)}>Show All</button>
|
|
290
|
+
<button onClick={() => toggleAll(false)}>Hide All</button>
|
|
291
|
+
</div>
|
|
292
|
+
</header>
|
|
293
|
+
<ul className="space-y-2">
|
|
294
|
+
{calendars.map(calendar => (
|
|
295
|
+
<li key={calendar.id} className="flex items-center gap-2 text-sm">
|
|
296
|
+
<input
|
|
297
|
+
type="checkbox"
|
|
298
|
+
checked={calendar.isVisible}
|
|
299
|
+
onChange={() =>
|
|
300
|
+
toggleCalendarVisibility(calendar.id, !calendar.isVisible)
|
|
301
|
+
}
|
|
302
|
+
/>
|
|
303
|
+
<span
|
|
304
|
+
className="h-2.5 w-2.5 rounded-full"
|
|
305
|
+
style={{ backgroundColor: calendar.colors.eventColor }}
|
|
306
|
+
/>
|
|
307
|
+
{calendar.name}
|
|
308
|
+
</li>
|
|
309
|
+
))}
|
|
310
|
+
</ul>
|
|
311
|
+
<section className="rounded-xl border border-slate-200 p-3 text-xs">
|
|
312
|
+
<p>Current date: {app.getCurrentDate().toDateString()}</p>
|
|
313
|
+
<p>Total events: {app.getEvents().length}</p>
|
|
314
|
+
</section>
|
|
315
|
+
</aside>
|
|
316
|
+
);
|
|
317
|
+
};
|
|
318
|
+
|
|
319
|
+
const calendar = useCalendarApp({
|
|
320
|
+
/* ... */
|
|
321
|
+
useSidebar: {
|
|
322
|
+
enabled: true,
|
|
323
|
+
width: 320,
|
|
324
|
+
render: props => <CustomSidebar {...props} />,
|
|
325
|
+
},
|
|
326
|
+
});
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
---
|
|
330
|
+
|
|
331
|
+
## 深色模式
|
|
332
|
+
|
|
333
|
+
DayFlow Calendar 原生支持全视图、侧边栏、事件卡片和对话框的深色模式。
|
|
334
|
+
|
|
335
|
+
<img width="1103" height="729" alt="image" src="https://github.com/user-attachments/assets/03c542d4-4b1b-4b99-9590-08c7be7f85df" />
|
|
336
|
+
|
|
337
|
+
您可以在 **light**(浅色)、**dark**(深色)或 **auto**(跟随系统)之间切换。
|
|
338
|
+
|
|
339
|
+
```tsx
|
|
340
|
+
import { DayFlowCalendar, useCalendarApp } from '@dayflow/core';
|
|
341
|
+
|
|
342
|
+
function MyCalendar() {
|
|
105
343
|
const calendar = useCalendarApp({
|
|
106
|
-
|
|
107
|
-
|
|
344
|
+
theme: {
|
|
345
|
+
mode: 'dark', // 'light' | 'dark' | 'auto'
|
|
346
|
+
},
|
|
108
347
|
});
|
|
109
348
|
|
|
110
349
|
return <DayFlowCalendar calendar={calendar} />;
|
|
111
350
|
}
|
|
112
351
|
```
|
|
113
352
|
|
|
114
|
-
|
|
353
|
+
---
|
|
115
354
|
|
|
116
|
-
##
|
|
355
|
+
## 视图切换模式
|
|
117
356
|
|
|
118
|
-
|
|
357
|
+
`switcherMode` 选项控制头部视图切换器的渲染方式。
|
|
119
358
|
|
|
120
|
-
|
|
121
|
-
- 🎫 **活动管理**:会议日程、活动日历、展会安排
|
|
122
|
-
- 🏢 **项目排期**:任务规划、时间线视图
|
|
123
|
-
- 💼 **企业应用**:会议室、资源预约、可用性管理
|
|
359
|
+
DayFlow 提供两种内置模式:
|
|
124
360
|
|
|
125
|
-
|
|
361
|
+
- **`buttons`**: 水平按钮标签(默认,适合桌面端)
|
|
126
362
|
|
|
127
|
-
|
|
128
|
-
- ✅ **拖拽缩放**
|
|
129
|
-
- ✅ **虚拟滚动**
|
|
130
|
-
- ✅ **插件体系**
|
|
131
|
-
- ✅ **React 18+ Hooks 架构**
|
|
132
|
-
- ✅ **Tailwind CSS 友好**
|
|
363
|
+
<img width="2190" height="406" alt="image" src="https://github.com/user-attachments/assets/a4be37bc-90ac-4872-afa0-589e3d1f7e9b" />
|
|
133
364
|
|
|
134
|
-
|
|
365
|
+
- **`select`**: 下拉菜单(节省空间,适合移动端)
|
|
135
366
|
|
|
136
|
-
|
|
367
|
+
<img width="2186" height="420" alt="image" src="https://github.com/user-attachments/assets/28e321ae-6c56-441a-a9fc-ddcfa504c920" />
|
|
137
368
|
|
|
138
|
-
|
|
369
|
+
---
|
|
139
370
|
|
|
140
|
-
|
|
371
|
+
## 贡献
|
|
141
372
|
|
|
142
|
-
|
|
373
|
+
欢迎贡献!请随意提交 Pull Request。
|
|
143
374
|
|
|
144
|
-
|
|
375
|
+
## Bug 反馈
|
|
145
376
|
|
|
146
|
-
|
|
377
|
+
如果您发现 Bug,请在 [GitHub Issues](https://github.com/dayflow-js/dayflow/issues) 上提交 issue。
|
|
378
|
+
|
|
379
|
+
## 支持
|
|
380
|
+
|
|
381
|
+
如有问题和支持需求,请在 GitHub 上打开 issue 或加入 discord。
|
|
147
382
|
|
|
148
|
-
|
|
383
|
+
---
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import { EventDetailPanelProps } from '../../types
|
|
2
|
+
import { EventDetailPanelProps } from '../../types';
|
|
3
3
|
import { CalendarApp } from '@/core';
|
|
4
4
|
interface DefaultEventDetailPanelProps extends EventDetailPanelProps {
|
|
5
5
|
app?: CalendarApp;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Event } from '@/types';
|
|
3
|
+
import { CalendarApp } from '@/core';
|
|
4
|
+
interface MobileEventDrawerProps {
|
|
5
|
+
isOpen: boolean;
|
|
6
|
+
onClose: () => void;
|
|
7
|
+
onSave: (event: Event) => void;
|
|
8
|
+
draftEvent: Event | null;
|
|
9
|
+
app: CalendarApp;
|
|
10
|
+
}
|
|
11
|
+
export declare const MobileEventDrawer: React.FC<MobileEventDrawerProps>;
|
|
12
|
+
export {};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { CalendarSearchEvent } from '../../types/search';
|
|
3
|
+
interface MobileSearchDialogProps {
|
|
4
|
+
isOpen: boolean;
|
|
5
|
+
onClose: () => void;
|
|
6
|
+
keyword: string;
|
|
7
|
+
onSearchChange: (value: string) => void;
|
|
8
|
+
results: CalendarSearchEvent[];
|
|
9
|
+
loading: boolean;
|
|
10
|
+
onResultClick?: (event: CalendarSearchEvent) => void;
|
|
11
|
+
emptyText?: string | Record<string, string>;
|
|
12
|
+
}
|
|
13
|
+
declare const MobileSearchDialog: React.FC<MobileSearchDialogProps>;
|
|
14
|
+
export default MobileSearchDialog;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { CalendarApp } from '../../types';
|
|
3
|
+
interface QuickCreateEventPopupProps {
|
|
4
|
+
app: CalendarApp;
|
|
5
|
+
anchorRef: React.RefObject<HTMLElement>;
|
|
6
|
+
onClose: () => void;
|
|
7
|
+
isOpen: boolean;
|
|
8
|
+
}
|
|
9
|
+
export declare const QuickCreateEventPopup: React.FC<QuickCreateEventPopupProps>;
|
|
10
|
+
export {};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { CalendarSearchEvent } from '../../types/search';
|
|
3
|
+
interface SearchDrawerProps {
|
|
4
|
+
isOpen: boolean;
|
|
5
|
+
onClose: () => void;
|
|
6
|
+
loading: boolean;
|
|
7
|
+
results: CalendarSearchEvent[];
|
|
8
|
+
keyword: string;
|
|
9
|
+
onResultClick?: (event: CalendarSearchEvent) => void;
|
|
10
|
+
emptyText?: string | Record<string, string>;
|
|
11
|
+
}
|
|
12
|
+
declare const SearchDrawer: React.FC<SearchDrawerProps>;
|
|
13
|
+
export default SearchDrawer;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { CalendarSearchEvent } from '../../types/search';
|
|
3
|
+
interface SearchResultsListProps {
|
|
4
|
+
loading: boolean;
|
|
5
|
+
results: CalendarSearchEvent[];
|
|
6
|
+
keyword: string;
|
|
7
|
+
onResultClick?: (event: CalendarSearchEvent) => void;
|
|
8
|
+
emptyText?: string | Record<string, string>;
|
|
9
|
+
}
|
|
10
|
+
declare const SearchResultsList: React.FC<SearchResultsListProps>;
|
|
11
|
+
export default SearchResultsList;
|
|
@@ -20,8 +20,6 @@ interface ViewHeaderProps {
|
|
|
20
20
|
customSubtitle?: string;
|
|
21
21
|
/** Whether to show TodayBox (default determined by viewType: day=false, week/month=true) */
|
|
22
22
|
showTodayBox?: boolean;
|
|
23
|
-
/** ViewSwitcher mode (default: 'select') */
|
|
24
|
-
switcherMode?: ViewSwitcherMode;
|
|
25
23
|
/** Sticky year for Year view (optional, only for Year view) */
|
|
26
24
|
stickyYear?: number | null;
|
|
27
25
|
/** Push-away offset for sticky year (in pixels) */
|
|
@@ -19,8 +19,13 @@ interface MultiDayEventProps {
|
|
|
19
19
|
isDragging: boolean;
|
|
20
20
|
isResizing?: boolean;
|
|
21
21
|
isSelected?: boolean;
|
|
22
|
-
onMoveStart: (e: React.MouseEvent<HTMLDivElement, MouseEvent>, event: Event) => void;
|
|
23
|
-
onResizeStart?: (e: React.MouseEvent<HTMLDivElement, MouseEvent>, event: Event, direction: string) => void;
|
|
22
|
+
onMoveStart: (e: React.MouseEvent<HTMLDivElement, MouseEvent> | React.TouchEvent<HTMLDivElement>, event: Event) => void;
|
|
23
|
+
onResizeStart?: (e: React.MouseEvent<HTMLDivElement, MouseEvent> | React.TouchEvent<HTMLDivElement>, event: Event, direction: string) => void;
|
|
24
|
+
onEventLongPress?: (eventId: string) => void;
|
|
25
|
+
isMobile?: boolean;
|
|
26
|
+
isDraggable?: boolean;
|
|
27
|
+
isEditable?: boolean;
|
|
28
|
+
viewable?: boolean;
|
|
24
29
|
}
|
|
25
30
|
export declare const MultiDayEvent: React.NamedExoticComponent<MultiDayEventProps>;
|
|
26
31
|
export default MultiDayEvent;
|
|
@@ -29,15 +29,16 @@ interface WeekComponentProps {
|
|
|
29
29
|
calendarRef: React.RefObject<HTMLDivElement>;
|
|
30
30
|
onEventUpdate: (updatedEvent: Event) => void;
|
|
31
31
|
onEventDelete: (eventId: string) => void;
|
|
32
|
-
onMoveStart
|
|
33
|
-
onCreateStart
|
|
34
|
-
onResizeStart
|
|
32
|
+
onMoveStart?: (e: React.MouseEvent<HTMLDivElement, MouseEvent> | React.TouchEvent<HTMLDivElement>, event: Event) => void;
|
|
33
|
+
onCreateStart?: (e: React.MouseEvent | React.TouchEvent, targetDate: Date) => void;
|
|
34
|
+
onResizeStart?: (e: React.MouseEvent<HTMLDivElement, MouseEvent> | React.TouchEvent<HTMLDivElement>, event: Event, direction: string) => void;
|
|
35
35
|
onDetailPanelOpen: () => void;
|
|
36
36
|
onMoreEventsClick?: (date: Date) => void;
|
|
37
37
|
onChangeView?: (view: ViewType) => void;
|
|
38
38
|
onSelectDate?: (date: Date) => void;
|
|
39
39
|
selectedEventId?: string | null;
|
|
40
40
|
onEventSelect?: (eventId: string | null) => void;
|
|
41
|
+
onEventLongPress?: (eventId: string) => void;
|
|
41
42
|
detailPanelEventId?: string | null;
|
|
42
43
|
onDetailPanelToggle?: (eventId: string | null) => void;
|
|
43
44
|
customDetailPanelContent?: EventDetailContentRenderer;
|
|
@@ -46,6 +47,7 @@ interface WeekComponentProps {
|
|
|
46
47
|
onCalendarDragOver?: (e: React.DragEvent) => void;
|
|
47
48
|
calendarSignature?: string;
|
|
48
49
|
app: CalendarApp;
|
|
50
|
+
enableTouch?: boolean;
|
|
49
51
|
}
|
|
50
52
|
declare const WeekComponent: React.NamedExoticComponent<WeekComponentProps>;
|
|
51
53
|
export default WeekComponent;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Event } from '@/types';
|
|
2
2
|
import { MultiDayEventSegment } from '@/components/monthView/WeekComponent';
|
|
3
|
-
export declare const getEventIcon: (event: Event) => import("react/jsx-runtime").JSX.Element;
|
|
3
|
+
export declare const getEventIcon: (event: Event) => string | number | Iterable<import("react").ReactNode> | import("react/jsx-runtime").JSX.Element | null;
|
|
4
4
|
export declare const analyzeMultiDayEventsForWeek: (events: Event[], weekStart: Date) => MultiDayEventSegment[];
|
|
5
5
|
export declare const analyzeMultiDayRegularEvent: (event: Event, weekStart: Date) => {
|
|
6
6
|
dayIndex: number;
|