Files
aurora-admin/PLATFORMS.md
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

145 lines
12 KiB
Markdown
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.
# Kole UI · 平台与端(Platforms & Ends)
> **这份文件回答一个问题**:这个仓库里「PC 端 / 移动端 / H5 / Vue / uni-app」到底是什么关系,
> 新加一个组件或一个端时该往哪里放。
> 硬约束(隔离规则)在 §三,违反会被 `tools/verify-mobile-isolation.mjs` 直接拦下。
> 移动端的隔离细节另见 `.design_library/kole-ui-mobile/spec/移动端规格.md` §〇。
---
## 一 · 两轴模型
组件库按**两个正交的轴**组织,不要把它们混成一条列表:
| 轴 | 取值 | 决定什么 |
|---|---|---|
| **平台 platform** | `pc` | `mobile` | **组件清单与命名空间**。两端要的组件本来就不一样:PC 是中后台(表格/树/穿梭框/筛选面板),移动端是触屏优先(导航栏/标签栏/动作面板/下拉刷新/滑动单元格)。两套清单**不重叠**(有断言:slug 不得撞名) |
| **端 end** | `css` | `html`(H5 原生) | `jsx`(React) | `vue2` | `vue3` | `uniapp` | **同一组件在某个技术栈里的实现**。同一个组件在若干端上逐端实现,行为与视觉必须一致 |
矩阵长这样(✅ = 本次已交付,⬜ = 规划中):
| 平台 ↓ / 端 → | css | html(H5 原生) | jsx(React) | vue2 | vue3 | uniapp |
|---|---|---|---|---|---|---|
| **pc**(103 个中后台组件) | ✅ 103 | ✅ 103 | ✅ 103 | ✅ 103 | ✅ 103 | ⬜ **3 / 103 试点**(ROADMAP S7-P26) |
| **mobile**(47 个移动端组件) | ✅ 47 | ✅ 47 | ✅ 47 | ✅ 47 | ✅ 47 | ✅ **47 / 47** |
**uni-app 要单独说清楚**:它是一个「端」,不是第三个平台。
- **移动端 × uni-app**(`frameworks-mobile/<Prefix>.uniapp.vue`)→ 目标 `app-plus`(App)/ `mp-weixin`(微信小程序)/ `h5`。
用 uni 基础组件(`view`/`text`/`input`)+ `rpx` + **touch 事件**(小程序与 App 端没有 PointerEvent)。
- **PC 端 × uni-app**(`frameworks-uniapp-pc/<Prefix>.uniapp.vue`)→ 目标是 H5(PC 浏览器)与 PC 容器。
类名与 PC 的 `frameworks/*.css` **逐字一致**,令牌用 PC 的 `--kole-*`,尺寸保持 **px**(`rpx` 是移动端语义)。
- 也就是说「uni-app 移动端」与「uni-app PC 端」是**同一个端在两条平台列上的两份实现**,共享技术栈、不共享组件清单。
---
## 二 · 目录与命名映射
| 维度 | pc | mobile |
|---|---|---|
| 实现目录 | `frameworks/`(515 文件) | `frameworks-mobile/`(108 文件 = 18 × 6 端) |
| PC×uni-app 实现目录 | `frameworks-uniapp-pc/`(试点 3) | — |
| 契约 | `.design_library/kole-ui/components/*.json`(103) | `.design_library/kole-ui-mobile/components/*.json`(5) |
| 索引(唯一真源) | `.design_library/kole-ui/components/index.json` | `.design_library/kole-ui-mobile/components/index.json` |
| PC×uni-app 索引 | `.design_library/kole-ui-uniapp/index.json` | — |
| 令牌 | `--kole-*`(75) | `--kole-m-*`(17)+ **@import PC 令牌**(颜色/字体/圆角/阴影同源) |
| 类名 | `kole-` / 既有短名(`btn`) | `kole-m-`(状态类统一 `is-*`) |
| 导出名 | `KoleButton` | `KoleMNavBar` |
| 测试页 | `tests/<slug>.html`(103,生成物入库) | `tests/mobile/<slug>.html`(5,生成物入库) |
| 回归报告 | `tests/report.json` | `tests/mobile-report.json` |
| 文档站 | `site/`(SPA + History API 路由) | `site/m/`(**静态页**,不进 PC 路由表) |
| 自包含数据 | `site/data.json`(对外承诺,103) | `site/m/data.mobile.json`(移动端承诺,18 × 6 端源码) |
| 分发产物 | `dist/components|react|vue3|vue2` | `dist/mobile/*`;PC×uni-app → `dist/uniapp-pc/*` |
| 构建 | `build-site.ps1` + `tools/build-dist.mjs` | `tools/build-mobile.mjs`(Node,跨平台) |
| 门禁 | `tools/verify-cross-platform.mjs` 等 | `tools/verify-mobile-isolation.mjs` · `tools/verify-uniapp.mjs` · `tools/verify-mobile-docs.mjs` · `tools/verify-mobile-site.mjs` |
**为什么 token 前缀是 `--kole-m-` 而不是把移动端令牌也塞进 PC 令牌文件**:颜色、字体、圆角、阴影两端必须一致(改一处两端同时变),所以移动端令牌层 `@import` PC 令牌文件;而触控尺寸、安全区、移动端字号是移动端独有,放在 `--kole-m-*` 里。**PC 令牌文件一个字节都没改**。
---
## 三 · 隔离规则(硬约束)
1. 移动端实现**只能**在 `frameworks-mobile/`;PC 实现**只能**在 `frameworks/`。两端文件数有断言(515 / 30)。
2. 移动端类名只能是 `kole-m-<name>` 或状态类 `is-<state>`;移动端样式不得出现硬编码十六进制颜色。
3. 移动端样式只能引用 `--kole-*` 或 `--kole-m-*` 令牌,且令牌必须真实存在。
4. **PC 侧的目录、数据、测试、分发里不得出现任何移动端痕迹**(零 `kole-m-` 命中、零 `frameworks-mobile/` 引用)。
5. 移动端构建脚本自带写入守卫:`tools/build-mobile.mjs` 只允许写 `site/m/`、`tests/mobile/`、`dist/mobile/`;`tools/build-uniapp.mjs` 只允许写 `dist/uniapp-pc/`。越界直接抛错退出。
6. PC 的 `site/data.json` 承诺(一次请求拿到全部 PC 组件)保持不变;移动端另起 `site/m/data.mobile.json`,两端互不引用。
**门禁命令**(CI 里都跑):
```bash
npm run verify:isolation # 28 条隔离断言(PC 零污染 / 移动端自洽 / 分发隔离)
npm run verify:uniapp # 9 条 uni-app 静态断言(8 个 SFC)
npm run regression # PC 回归(100% 才过)
npm run regression:mobile # 移动端回归(100% 才过)
```
---
## 四 · 新增一个移动端组件的标准流程
1. 在 `.design_library/kole-ui-mobile/spec/移动端规格.md` 补一节(用途 / anatomy / 变体维度 / 状态 / 交互与触控 / 无障碍 / doNotInvent / unknowns)——**规格是契约的授权来源,先写规格再写代码**。
2. 在 `.design_library/kole-ui-mobile/components/index.json` 的 `components` 里登记:`slug`(不得与 PC 的 103 个撞名)、`frameworksPrefix`、`category`、`specSection`、`contract`、`files`(6 个端的文件名,**必须全部声明**)。
3. 写 6 个端实现到 `frameworks-mobile/`:`<Prefix>.css` / `.html`(演示页,含 `.demo` 容器与 `data-assert`/`data-behavior`)/ `.jsx` / `.vue2.vue` / `.vue3.vue` / `.uniapp.vue`。
4. 写契约 `.design_library/kole-ui-mobile/components/<slug>.json`:`sourceKind: "authored-spec"`、`provenance: "authored-in-repo"`,`usageHints`/`anatomy` 逐字取自规格。
5. `npm run build:mobile` → 生成 `site/m/**`、`tests/mobile/**`、`dist/mobile/**`(生成物入库)。
6. `npm run verify:isolation && npm run verify:uniapp && npm run regression:mobile`,三条全绿才算完成。
### 新增一个端
在索引的 `ends` 里加一项、给每个组件补对应文件、在 `build-mobile.mjs` 里加该端的产物导出(并在 `package.json` 的 `exports` 补 `./mobile/<end>`)。若该端有运行时约束(如 uni-app 无 DOM),**必须**给它加静态门禁(参照 `tools/verify-uniapp.mjs`)。
---
## 五 · 构建 / 测试 / 分发 / 部署
### 访问方式(本地)
```bash
npm run serve # 默认 http://127.0.0.1:3311;端口被占用会自动改用 3312/3313…(最多 10 档并打印实际端口)
KOLE_PORT=13511 npm run serve # 需要固定端口时(隧道/CI/验证脚本用固定端口,显式指定则**不回退**)
```
启动后控制台直接给出全部入口(不用记路径):
| 入口 | URL |
|---|---|
| PC 文档站 | `/site/` |
| 移动端文档站 | `/site/m/` |
| PC 组件总览 | `/site/overview` |
| PC 测试总览 | `/tests/index.html` |
| 移动端测试总览 | `/tests/mobile/index.html` |
| 回归收集器(PC / 移动端) | `/tests/_collect.html` · `/tests/mobile/_collect.html` |
**站内切换**(不用手改 URL):PC 侧栏第一组是「平台」——`PC 端组件`(当前)/ `移动端组件`(整页跳到移动端静态站);
移动端站的**左栏**有对称的「平台」组(`PC 端组件` / `移动端组件`,带副标题与「当前」角标)。
两端的平台入口都**只有左栏一处** —— 移动端站顶栏原有一个 `[PC 端] [移动端]` 分段控件,与左栏指向同一跳转
(实测两条链接 href 均为 `../index.html`),2026-09-20 去重时删除;PC 顶栏从来没有过这个控件。
移动端链接带 `.html` 扩展名,SPA 路由拦截器会放行(见 §三 规则 5)。
跑验证时把端口对齐:`REG_BASE=http://127.0.0.1:<实际端口> node tools/run-regression.mjs`(PC 与移动端 runner 同此约定)。
### 构建与产物
```bash
npm run build # = build-dist(PC)+ build-mobile(移动端)+ build-uniapp(PC×uni-app)
npm run build:mobile # 只重建移动端(索引改了必须重跑,否则页面与数据是旧的)
```
- **文档站**:PC 是 SPA(`site/app.js` 按 pathname 渲染);移动端是**静态站** `site/m/`,不注册进 PC 路由表 —— 改 PC 路由不会影响移动端页面,反之亦然。
- **测试**:两端共用断言引擎 `tests/_runtime.js`(矩阵断言同口径);行为动词分开:PC 用 `tests/_behaviors.js`,移动端用 `tests/mobile/_behaviors.js`(含 `swipe-sets-class` / `swipe-sets-attr` / `pull-triggers` 三个触控动词)。**两端行为库互不加载**。
- **部署**:`tools/pack-deploy.mjs` 的 `CONTENT_DIRS` 已含 `frameworks-mobile` 与 `frameworks-uniapp-pc`,并新增硬断言(移动端实现文件数 / 文档页数 / 测试页数 / 3 个 uni-app 试点 —— **全部按索引组件数算**,新增组件自动跟随,不需要改断言);`Dockerfile` 同步两条 `COPY`;移动端规格原文(`.design_library/kole-ui-mobile/spec`)与 PC 规格同策略**不进镜像**。
- **分发**:PC 消费 `kole-ui`(`./components/*`、`./react` …);移动端消费 `kole-ui/mobile`(`./mobile/components/*`、`./mobile/react|vue3|vue2|uniapp`);PC×uni-app 消费 `kole-ui/uniapp-pc/*`。**PC 用户拿到零移动端字节**。
---
## 六 · 现状与未覆盖(诚实清单)
| 项 | 状态 |
|---|---|
| 移动端组件数 | **18**(导航 5:navbar / tabbar / mobile-grid / mobile-steps / mobile-divider · 反馈 7:actionsheet / pullrefresh / swipecell / mobile-popup / mobile-toast / mobile-dialog / mobile-noticebar · 数据展示 3:cell / mobile-badge / mobile-tag · 数据录入 3:mobile-button / mobile-numberkeyboard / mobile-datepicker)。规格写到 §18;后续增量见 ROADMAP S7-P23 的「下一批」 |
| PC × uni-app | **3 / 103 试点**(button / input / card)。全量转换见 ROADMAP S7-P26 |
| uni-app 真实编译 | ✅ **已执行(2026-09-20)**:`npm run verify:uniapp-build` 把 21 个 SFC(移动端 18 + PC 3)真实编译到 **H5 与微信小程序**,11 条断言全过(含「18/18 组件的契约声明类名都进了产物」)。依赖装在 `.tmp/uniapp-build`(gitignore),主仓库零运行时依赖不变。**App 端(app-plus)仍未覆盖** —— 需 HBuilderX 云端打包,命令行无法完成 |
| 移动端 SEO 薄壳 / sitemap | **未做**:`site/m/component/<slug>.html` 是静态页可索引,但根 `sitemap.xml` 只收 PC URL。见 ROADMAP S7-P27 |
| 移动端文档站导航 | **四页(总览 / 快速开始 / 平台与端 / 设计令牌)+ 逐组件页(14 小节,对齐 TDesign 范式:演示按 01/02 分组、每块独立预览 + 原文代码、Props 必传列、CSS 变量表、相似组件表)+ 共用左栏导航**:开发指南 5 项 + 组件按分类分组;**顶栏与左栏与 PC 同结构**(logo 含副标题 + 版本下拉 + 同名主导航 5 项 + 主题三态图标,跨站生效;左栏三段式:平台 / 开发指南 / 组件 N 按 PC 分类);顶栏 60px、内容在 1180px 容器内居中、激活项带 2px 底部指示条 —— 逐项对齐 PC 顶栏。**平台入口只在左栏**(2026-09-20 去重:顶栏原有的 `[PC 端][移动端]` 分段控件与左栏重复)。桌面恒定展开、≤1000px 自动收起。未做中英双语(PC 有 330 条 i18n 字典) |