051 Calendar · 日历
用途
在页面中直接显示一个月份,用于选择单个日期。支持今日标记、不可选日期与周起始日配置。
最小示例
day := core.Date{Year: 2026, Month: time.October, Day: 5}
view := func(c *ui.Context) {
core.Use(c, core.Settings{})
if datetime.Calendar(c, &day, datetime.CalendarOptions{WeekStart: datetime.WeekStartMonday}).Changed() {
fmt.Println("chosen", day)
}
}
ui.Render(view, 400, 300, 1)参数
func Calendar(c *ui.Context, value *Date, opts CalendarOptions) DateTimeResult,返回值的 Element 字段是组件元素。
| 字段 | 类型 | 默认值 | 含义 |
|---|---|---|---|
Min | Date | 零值 | 最早可选日期;零值不限制。 |
Max | Date | 零值 | 最晚可选日期;零值不限制。 |
DisableDate | func(Date) bool | nil | 返回 true 的日期不可选,显示删除线。 |
WeekStart | WeekStart | WeekStartLocale | 首列星期:跟随语言(zh-CN 周一、en-US 周日),或 WeekStartSunday/WeekStartMonday/WeekStartSaturday。 |
Today | Date | 零值(系统时钟) | 标记为今天的日期:加粗并在下方绘制菱形。 |
Disabled | bool | false | 禁用整个日历:不能翻页、不能选择,退出 Tab 序列。 |
Label | string | 内置“日历” | 辅助技术读出的名称。 |
状态
默认、悬停、按下、聚焦(键盘焦点环)、选中(酒红填充 + 内嵌细框 + 单选语义)、今日(加粗 + 菱形)、不可选(删除线并由 MyGo 置灰)、非本月(弱化文字)、禁用。
事件
Calendar(...).Changed() 在用户选择了与原值不同的日期的那一帧返回 true,*value 已更新。翻月不触发事件。
键盘操作
- Tab:进入日期格,落在已选日期或上次聚焦的日期。
- ←/→:前后一天;↑/↓:前后一周(自动跳过不可选日期,最多 31 天)。
- PageUp/PageDown:上/下一月;Shift+PageUp/PageDown:上/下一年。
- Home/End:本月第一天/最后一天。
- Enter/Space:选择当前日期。
限制
- 不可选日期不能获得焦点;若方向键 31 天内找不到可选日期,视图会翻页但焦点停在原处。
- MyGo 的
ui.Calendar固定周一起始、只有英文且不支持禁用日期(ui/date.go:85-160),因此本组件基于RadioBase自绘网格,不复用ui.Calendar。 - 日期与时间值不带时区:
Date、YearMonth、TimeOfDay只保存日历字段,组件内部计算不做 UTC 转换。 Today为零值时读取c.Now()(系统本地时区);需要固定“今天”(测试、跨时区应用)时显式传入。- 无障碍:MyGo v0.2.10 没有公开设置弹出按钮展开状态(
expanded)、数值范围(hasRange/accRange)与值(accValue)的接口,这些字段只在 MyGo 内部组件中赋值(ui/element.go:286-295,例如 ui/base.go:297、ui/indicators.go:61)。因此触发器只能声明为RolePopUpButton而无法报告展开状态;时间段以Description读出当前值与范围,错误通过Error()关联。

