Regression / regression (push) Canceled after 0s
本提交含两条并行工作线,因互相咬合(package.json scripts、regression.yml、 npm run build 链)无法按文件干净拆分,故合并为一次自洽提交。 ## 详情页减重(本轮主任务:修复「AI 干太重」) - 导航收敛:宽屏只用右侧目录、≤1200px 只用页内 sticky 导航,纯 CSS 媒体查询 实现(不引入 JS 宽度监听)。此前两套导航同时可见,active 状态互相打架。 - 入口去重:标题区由「查看示例/在线测试/契约 JSON」三个减为「在线测试」一个; 契约 JSON 归入实现资源;删除示例底部重复的「在线测试」。 - 示例工具栏:删除与目录锚点重复的示例下拉选择器;「全部展开代码」只在 示例数 >1 时出现(103 个组件里 49 个仅 1 个示例,此前恒显示)。 - 重复文案:示例区两句同义导语合并为一句。 - 首页 CTA 由 5 个减为 2 个(浏览组件/快速开始),测试总览入口挂到已有的 通过率统计卡上,不再另占 Hero 按钮。 - 统一详情取数:抽出 fetchDetail/loadDetail 作为 details/*.json 的唯一路径, FAQ 不再自行 fetch 一遍,与组件页共用缓存与失败兜底。 ## i18n - 删除 12 组重复键(含整段 FAQ 说明),字典 604 → 585 唯一键。 - 删除本次改动产生的 6 个死键。 - verify-i18n.mjs 新增 `unique dictionary keys` 断言:重复键在对象字面量里 是静默的后值覆盖,此前无从发现;现由门禁拦住。 ## 文档事实修正(实测为准) - TESTING/CONTRIBUTING:79 → 103 组件;旧断言数改为回指 tests/report.json。 - PLATFORMS:移动端 108 文件/18 端 → 282 文件/47 端;契约 5 → 47; 令牌 17 → 15;uni-app SFC 21 → 50。 - AGENTS:断言 1405/18 页 → 1464/103 页(PC)、807/47 页(移动端)。 - package.json:YOUR-ACCOUNT 占位 → gitea 实址与 kole-ui.mymoyu.top。 ## 品牌标识(并行会话成果,一并入库) - brand-mark.json 收归真源,build:brand 生成 favicon 与单色 SVG; PC 与移动端共用资产,verify:brand 24 条断言。 - regression.yml 增加 verify:brand 步骤。 ## 门禁与验收 新增工具:verify-component-page.mjs(86 条真实浏览器断言,随详情页改造同步 更新为「只允许一套导航可见」)、verify-brand-mark.mjs、lib/i18n-dead-keys.mjs (只读诊断)。 回归:PC 100%(1464/1464,103 页,N/A 50)· 移动端 100%(807/807,47 页)。 门禁:component-page 86 · i18n 17 · brand 24 · routes all · smoke all · theme OK · isolation 31 · nav all · examples 9 · api-docs 10 · mobile-docs 12。 已知未做:i18n 另有约 44 条历史死键(非本次产生),已记为 ROADMAP S8-P6; 顶栏与悬浮区的两个主题入口为刻意设计(verify-theme 断言其互斥),未删。
145 lines
12 KiB
Markdown
145 lines
12 KiB
Markdown
# 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 文件 = 103 × 5 端) | `frameworks-mobile/`(282 文件 = 47 × 6 端) |
|
||
| PC×uni-app 实现目录 | `frameworks-uniapp-pc/`(试点 3) | — |
|
||
| 契约 | `.design_library/kole-ui/components/*.json`(103) | `.design_library/kole-ui-mobile/components/*.json`(47) |
|
||
| 索引(唯一真源) | `.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-*`(15)+ **@import PC 令牌**(颜色/字体/圆角/阴影同源) |
|
||
| 类名 | `kole-` / 既有短名(`btn`) | `kole-m-`(状态类统一 `is-*`) |
|
||
| 导出名 | `KoleButton` | `KoleMNavBar` |
|
||
| 测试页 | `tests/<slug>.html`(103,生成物入库) | `tests/mobile/<slug>.html`(47,生成物入库) |
|
||
| 回归报告 | `tests/report.json` | `tests/mobile-report.json` |
|
||
| 文档站 | `site/`(SPA + History API 路由) | `site/m/`(**静态页**,不进 PC 路由表) |
|
||
| 自包含数据 | `site/data.json`(对外承诺,103) | `site/m/data.mobile.json`(移动端承诺,47 × 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 用户拿到零移动端字节**。
|
||
|
||
---
|
||
|
||
## 六 · 现状与未覆盖(诚实清单)
|
||
|
||
| 项 | 状态 |
|
||
|---|---|
|
||
| 移动端组件数 | **47**(导航 6 · 反馈 12 · 通用 5 · 数据展示 8 · 数据录入 16)。权威清单见 `.design_library/kole-ui-mobile/components/index.json`(47 项)与 `frameworks-mobile/`(282 文件 = 47 × 6 端) |
|
||
| PC × uni-app | **3 / 103 试点**(button / input / card)。全量转换见 ROADMAP S7-P26 |
|
||
| uni-app 真实编译 | ✅ **已执行**:`npm run verify:uniapp-build` 把 50 个 SFC(移动端 47 + PC 3)真实编译到 **H5 与微信小程序**,含「契约声明的类名都进了产物」断言。依赖装在 `.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 字典) |
|