iter(g115): 新增月历组件 calendar

This commit is contained in:
HIsheR
2026-10-26 14:08:58 +08:00
parent b4ab92ed98
commit c2900a4852
15 changed files with 378 additions and 26 deletions
+8
View File
@@ -1276,6 +1276,14 @@
"acceptance": "npm run changelog 重新生成(301 提交),changelog:check 与提交史一致;npm run check 全绿",
"notes": "自补:发版前刷新步骤;本条为本次唤起收尾轮",
"status": "done"
},
{
"id": "g115",
"title": "新增月历组件 calendar",
"motivation": "排期表、值班表、日程页需要「整月网格一直看得见」,datePicker 只能弹层选一天且收起来就没了;调用方要自己算月初留白、当月天数、今天与选中的标记,还要补键盘漫游,一写就是一百多行重复逻辑",
"acceptance": "新增 calendar(props)(< 200 行):value/month 信号、marker 每日标记(文案同时进 aria-label)、onSelect / onMonthChange;月初留白与天数计算抽到 dateKit.ts,datePicker 改为共用同一份(消除两处日期工具);组件 59→60,types/index/css/manifest/docs/README/AGENTS/ARCHITECTURE/demo 同步;npm run check 全绿",
"notes": "自补:组件补充 + 派生语义单一来源(日期工具下沉 dateKit)",
"status": "open"
}
]
}
+45 -2
View File
@@ -1,6 +1,6 @@
{
"$schema": "ui-arch-registry-index/0.1",
"generatedAt": "2026-10-26T06:06:20.403Z",
"generatedAt": "2026-10-26T06:08:45.187Z",
"repoRoot": ".",
"packages": [
{
@@ -202,7 +202,8 @@
"affix(props, ...children):固钉,滚过 offset 后内容转 fixed 贴顶、外层保留占位高度,固定后宽度随容器自适应",
"multiSelect(props):多选下拉,标签式回显 + 可搜索弹层,点选不收起便于连续多选,max 到限后未选项禁用",
"anchor(props):锚点导航,竖排区块链接,滚动时按目标位置高亮当前区块(aria-current 同步),点击按 offset 偏移量平滑定位并回写 hash;container 可指定内滚容器",
"popconfirm(props, trigger):二次确认气泡,挂在任意触发器上,就地确认危险操作;确定后先收起再回调,取消 / 点外部 / Esc 走 onCancel,展开即聚焦「取消」"
"popconfirm(props, trigger):二次确认气泡,挂在任意触发器上,就地确认危险操作;确定后先收起再回调,取消 / 点外部 / Esc 走 onCancel,展开即聚焦「取消」",
"calendar(props):月历,整月网格内嵌页面(排期 / 值班 / 日程),每日可带 marker 标记文案,方向键漫游 + Enter 选中,翻月走 onMonthChange"
],
"keyTypes": [
"ButtonProps",
@@ -2989,6 +2990,48 @@
"点确定先收起弹层再触发 onConfirm,回调里可以放心同步改数据;取消、点外部、Esc 一律走 onCancel",
"展开时焦点自动落在「取消」上,误按回车不会执行危险操作;需要外部控制开合时传 open 信号"
]
},
{
"id": "calendar",
"title": "月历 Calendar",
"demo": "sec-calendar",
"props": [
{
"n": "value",
"t": "Signal<string>",
"d": "选中日期(YYYY-MM-DD)信号;不传则内部维护"
},
{
"n": "month",
"t": "Signal<string>",
"d": "展示月份(YYYY-MM);不传则内部维护,初始跟随 value 或今天"
},
{
"n": "marker",
"t": "(date: string) => string | null",
"k": 1,
"d": "每日标记:返回文案即渲染小徽标(如「3 项」),同时写进 aria-label;返回 null 不标记"
},
{
"n": "onSelect",
"t": "(date: string) => void",
"k": 1,
"d": "选中日期回调(点击或 Enter / 空格)"
},
{
"n": "onMonthChange",
"t": "(month: string) => void",
"k": 1,
"d": "翻月回调,参数为 YYYY-MM(可在此拉取当月数据)"
}
],
"example": "const day = signal(''); calendar({ value: day, marker: (d) => (d === '2026-10-26' ? '2 项' : null), onSelect: (d) => toast.info(d) })",
"steps": [
"把 calendar 放在页面容器里即可,它自带标题行(月份 + 上下月箭头)、星期表头与 6 行网格",
"选中日期用 value 信号双向绑定;不传则组件内部维护,onSelect 里拿字符串自己处理",
"需要显示每天有几件事就传 marker:返回非空文案即渲染小徽标,并拼进 aria-label 让读屏也听得到",
"键盘:Tab 进入网格一次,←→ 逐日、↑↓ 逐周、Enter / 空格 选中;跨月会自动翻页并交接焦点"
]
}
]
},