Files
aurora-admin/.design_library/kole-ui-mobile/components/mobile-popover.json
T
aurora-admin f1fbfc2ddb
Regression / regression (push) Canceled after 0s
feat(品牌标识): 几何 K 图标(favicon/顶栏标记/theme-color) + 并行会话成果入库
## 品牌标识(本次会话)

起因:品牌此前没有任何图形标识 —— 唯一 favicon 是内联 data-URI 里的字母「A」,
那是 v2.0.0「Aurora Admin → Kole UI」改名漏掉的一处(PC 顶栏也是「A」,
移动端站已是「K」;移动端文档站则完全没有 favicon)。

- 几何:24 网格三个互不接触的笔画(竖 + 两斜),圆头描边;
  描边 2.25 → 16px 标签页尺寸下正好 1.5px = 规范原文「描边1.5px」
- 取色分两套(刻意):favicon 硬编码品牌蓝/白(渲染在浏览器标签栏,不继承 kole-dark);
  顶栏标记走 currentColor(实测暗色下自动转 rgb(20,22,28))
- 新增 theme-color 双条(light #FFFFFF / dark #1C1F26,取 --kole-color-card-bg)
- 修 site/app.js hero 标语 KOLE ADMIN → KOLE UI(改名变形残留)
- 移动端 7 个模板补 favicon(此前计数 0)

验收:门禁 9 条全 OK(site-routing/site-routes/mobile-docs/mobile-site/isolation/
theme/nav/i18n/icons);PC 回归 1464/1464 · 移动端 807/807,各连跑 8 次一致;
两端 favicon 405 字节逐字节一致;PC 站控制台错误 1→0。

## 并行会话成果(本次一并入库)

- 图标系统:2576 图标(TDesign/Element Plus,MIT)+ 11 端注入 + 5 个构建门禁工具
  + IconPreview 预览页 + ICON-SPEC.md 冻结规格
- 移动端平台:47 组件 × 6 端 + 文档站 53 页 + 隔离门禁
- PC 组件:103 个大后台组件 / 组件11 批次
- uni-app:PC 端试点 + 移动端端实现 + 真实编译验证

## 工程

- .gitignore 补 .scratch/ 与 .zcode-preexisting-*.txt(会话中间产物,实测 9.1MB,不入库)
- CHANGELOG 补品牌标识条目
- ROADMAP 登 S8-P4(品牌标识任务包 + og:image/apple-touch-icon 未做部分)
2026-09-21 10:05:48 +08:00

240 lines
8.5 KiB
JSON
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{
"schemaVersion": 1,
"sourceKind": "authored-spec",
"provenance": "authored-in-repo",
"specFile": "spec/移动端规格.md",
"specSection": "41 · 弹出气泡 Popover",
"confidence": "high",
"slug": "mobile-popover",
"name": "弹出气泡 Popover",
"semanticTypeCandidates": [
"popover",
"tooltip",
"hint-bubble"
],
"variantDimensions": [
{
"name": "placement",
"values": [
"top",
"bottom",
"left",
"right"
]
},
{
"name": "arrow",
"values": [
"false",
"true"
]
}
],
"representativeVariants": [
{
"placement": "top",
"arrow": "true",
"label": "上方气泡(带箭头)"
},
{
"placement": "bottom",
"arrow": "true",
"label": "下方气泡(最常用)"
},
{
"placement": "left",
"arrow": "true",
"label": "左侧气泡"
},
{
"placement": "right",
"arrow": "false",
"label": "右侧不带箭头"
}
],
"anatomy": {
"popover": "根元素,position: relative 的包一层,气泡在其中绝对定位(因此永远贴着自己的触发器)",
"trigger": "触发器(原生 button),热区 ≥44px,写 aria-expanded 与 aria-haspopup",
"panel": "气泡面板,按 placement 贴着触发器的某一侧;role=\"dialog\" 并带 aria-label",
"title / text": "标题与正文,可选",
"箭头": "arrow=true 时由纯 CSS 三角(border 拼出,无图片、无 hex)指向触发器"
},
"structurePatterns": {
"placement": "top / bottom / left / right(气泡相对触发器出现在哪一侧)",
"arrow": "false 不带三角 / true 三角指向触发器",
"状态类": "is-open 展开(触发器同步 aria-expanded=true)"
},
"usageHints": [
"在某个元素的旁边弹出一小块说明或轻量操作(运费规则、字段解释、更多操作),说完就收",
"触屏没有悬停:桌面端移开鼠标就收起,触屏必须显式给一条关闭路径(点击气泡之外)",
"气泡是相对某个触发元素定位的,不是铺满视口的浮层 —— 这是它与轻提示 / 遮罩层的根本区别",
"一次轻点触发器展开 / 收起,同一个按钮负责开与关",
"边缘空间不足时的翻转(flip)由宿主决定:把 placement 换成对侧即可,组件不做自动测量"
],
"doNotInvent": [
"基于可用空间的自动翻转与自动方位选择(placement 由宿主决定)",
"悬停触发(触屏没有悬停;桌面端若需要,由宿主包装)",
"气泡内的表单校验与提交流程",
"气泡之间的互斥开关(哪个开着由宿主管理)"
],
"unknowns": [
"是否需要在气泡贴近视口边缘时自动夹在边界内(当前只做静态定位)",
"role=\"dialog\" 对纯文字说明类气泡是否过重(当前统一用 dialog + aria-label)",
"点击外部关闭是否需要区分「点了另一个气泡」的情况"
],
"interaction": [
"一次轻点触发器展开 / 收起,同一个按钮负责开与关",
"点击外部关闭:落点不在「气泡或触发器」之内时收起;气泡没有遮罩可依赖,靠文档级 pointerdown 判定",
"uni-app 端没有 document,改用铺满视口的透明捕获层(层级低于面板)",
"不响应长按、双击与拖动;气泡自身不消费纵向滚动",
"气泡与触发器之间留 --kole-m-popover-gap(默认 8px)的间隙,避免气泡盖住触发器的按下反馈",
"开合动效 120ms(--kole-duration-fast),减少动态偏好下瞬时切换"
],
"accessibility": [
"触发器是原生 button,带 aria-expanded(读屏能播报「已展开 / 已折叠」)与 aria-haspopup",
"面板 role=\"dialog\" + aria-label:名称取 title,为空时退回触发器文字,保证读屏不会读到一个匿名对话框",
"弹出时不移动焦点(气泡是补充说明而非中断式浮层)",
"气泡不因展开而隐藏任何内容:关闭后触发器仍在原地可再次打开"
],
"api": {
"source": "implementation",
"note": "props / events / slots 为 6 端实现的公共接口(说明文字取自规格对应小节)。字段名与各端源码逐名核对:node tools/verify-mobile-docs.mjs",
"requiredNote": "「必传」按严格定义:实现里**没有默认值**时才为 Y(本门禁逐条核对 props 与各端源码的默认值,防止契约与实现脱节)。",
"props": [
{
"name": "open",
"type": "boolean",
"default": "false",
"desc": "状态 open:气泡展开可见(规格 §41.4)",
"required": false
},
{
"name": "placement",
"type": "'top' | 'bottom' | 'left' | 'right'",
"default": "'bottom'",
"desc": "变体 placement:气泡相对触发器出现在哪一侧(规格 §41.3)",
"required": false
},
{
"name": "triggerText",
"type": "string",
"default": "''",
"desc": "触发器文字,同时作为面板 aria-label 的兜底名称(规格 §41.2 trigger)",
"required": false
},
{
"name": "title",
"type": "string",
"default": "''",
"desc": "标题,可选;同时作为面板的 aria-label(规格 §41.2 title)",
"required": false
},
{
"name": "text",
"type": "string",
"default": "''",
"desc": "正文文字,可选(规格 §41.2 text)",
"required": false
},
{
"name": "arrow",
"type": "boolean",
"default": "true",
"desc": "变体 arrow:是否渲染指向触发器的小三角(规格 §41.3)",
"required": false
},
{
"name": "closeOnOutside",
"type": "boolean",
"default": "true",
"desc": "落点在气泡与触发器之外时是否关闭(规格 §41.5)",
"required": false
}
],
"events": [
{
"name": "toggle",
"params": "—",
"desc": "点击触发器时触发;是否展开由宿主决定(受控)(规格 §41.5)"
},
{
"name": "close",
"params": "—",
"desc": "落点在气泡与触发器之外、且 closeOnOutside=true 时触发(规格 §41.5)"
}
],
"slots": [
{
"name": "default",
"desc": "气泡内容(放在 title / text 之后,用于自定义内容)"
}
]
},
"variantClasses": {
"placement": {
"top": [
".kole-m-popover__panel--top"
],
"bottom": [
".kole-m-popover__panel--bottom"
],
"left": [
".kole-m-popover__panel--left"
],
"right": [
".kole-m-popover__panel--right"
]
},
"arrow": {
"false": [],
"true": [
".kole-m-popover__panel--arrow"
]
}
},
"demos": [
{
"id": "placements",
"group": "01 组件类型",
"title": "四个方向",
"desc": "上方 / 下方 / 左侧 / 右侧:气泡各自相对自己的触发器定位,所以四个可以同页并列而互不影响。",
"variant": "placement=top|bottom|left|right"
},
{
"id": "arrow",
"group": "01 组件类型",
"title": "无箭头",
"desc": "arrow=false:省掉三角,仅靠位置表达归属,适合小屏上空间紧张的场景。",
"variant": "arrow=false"
},
{
"id": "title",
"group": "02 组件状态",
"title": "带标题",
"desc": "title 给出这条气泡在说什么,正文再补一句;标题同时作为面板的 aria-label 供读屏播报。",
"variant": "title 非空"
},
{
"id": "outside",
"group": "02 组件状态",
"title": "点击外部关闭",
"desc": "气泡没有遮罩可依赖,落点在气泡与触发器之外时收起;触屏上这是唯一的隐式关闭路径。",
"variant": "closeOnOutside=true"
}
],
"related": [
{
"slug": "mobile-popup",
"why": "需要铺满视口、带方向位移与标题栏的浮层时用弹出层;气泡只贴着触发器,不覆盖整屏"
},
{
"slug": "mobile-toast",
"why": "只是短暂告知结果、不需要贴着某个元素时用轻提示;气泡会一直停在触发器旁边等用户处理"
},
{
"slug": "mobile-dialog",
"why": "需要用户确认或输入的中断式浮层用对话框,气泡不该承载需要决策的内容"
}
]
}