diff --git a/CHANGELOG.md b/CHANGELOG.md index a665be8..60998f4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,205 @@ ## [Unreleased] +### 变更 · CSS 端接线为样式底座:H5 端单一样式真源 | S9-P7 + +- 103 个组件中 92 个此前已由演示页 `` 消费组件 CSS;本轮把剩余 **11 页** + (Button / Card / Dropdown / EmployeeCard / Input / Modal / Segmented / Select / Table / Tree / TreeTable) + 的内联组件样式并入 `frameworks/.css`,演示页改为「markup + link CSS(+ 交互 JS)」, + 内联只保留演示脚手架。CSS 端文件自本轮起是组件样式的**唯一权威**, + v1.4.0 遗留的「框架 CSS + 页面内联」双份维护不再需要。 +- 值冲突按 components.css 规范层裁决(令牌优先、逻辑属性优先,裁决表见 ROADMAP S9-P7); + 接线顺带修复两处内联版渲染缺陷:Select 触发器缺 `position: relative`(caret 此前锚定错误)、 + Table / TreeTable 选择列未按契约居中。 +- 移动端 47/47 此前已全部接线,本轮未改动。 +- 全局导入形态随本轮重建刷新:`dist/tokens/tokens.css` + `dist/components/index.css` + (103 组件聚合,令牌之后引入即可);单组件 = `dist/components/.css`。 + PLATFORMS.md 已把 `css` 列重定义为「样式层/交付物」。 + +### 新增 · 代码块 JS↔TS 切换 + 逐端专属内容齐备 + 组合场景 | S10 + +> 用户反馈三点:① 代码块上方的切换器与顶栏技术栈选择器重复,且切出来的内容**实际一模一样**; +> ② 不同组件讲的内容雷同;③ 预览「表现得不好」,希望能看到组件**配合**展示(卡片外壳、登录样例)。 +> 本轮把三条都落到可验证产物上。 + +- **代码块切换器改为 JS ↔ TS**(`site/app.js` 的 `codeForms`):端由顶栏决定, + 块内只在该端的 JavaScript / TypeScript 两种写法之间切换。原先的四端 tab 与顶栏功能重复 + (实测 `button/react` 页面上重复出现 5 组同样的 tab)。 + H5 / CSS 端交付静态标记与类名,没有可标注的类型面,故只给单一形态、不显示切换器。 +- **597 段 TypeScript 形态**(`site/examples/*.json` 的 `code.tsx` / `code.vue3ts` / `code.vue2ts`, + 199 示例 × 3 端):由 `tools/gen-ts-variants.mjs` 生成,原则是**只标注、不重构**—— + 在既有 JS 片段上插入类型标注与泛型参数,不移动、不重排任何结构。 + 首版曾尝试把同构标签提炼成「类型化规格数组 + 遍历渲染」,产出更"TS 味", + 但实测生成了大量坏代码(`return (const cities = …)`、缺闭合标签的 Vue 模板、`Vue.extend({ … };` 少括号), + 且**全部通过了原门禁**——判据只查结构性规则,查不出「代码结构被破坏」。 + 因此新增 `tools/check-ts-quality.mjs`:对 597 段做**真实编译**(esbuild 验 tsx 与 script 段、 + vue-template-compiler 验 Vue 2 模板),当前 0 失败。 +- **逐端专属内容 515 份齐备**(`site/end-content/..json`,103 组件 × 5 端): + 此前只有 197 份,缺的时候页面回退显示同一句「本端的专属用法说明尚未提供」—— + 这正是「不同组件内容雷同」的直接来源。缺额由 `tools/gen-end-content.mjs` 从事实包补齐, + 取料只认该端实现源码解析出的 API(`consumedApi`),不引入契约 `dims`(那是设计词汇层)。 +- **组合场景 103 份**(`site/scenes/.json` + 预览产物 `site/scenes/.html`): + 组件页新增「组合场景」一节,讲该组件与别的组件**配合**出现的形态(表单卡片里的字段、 + 列表页卡片与工具条、工具条触发的确认流、详情卡片里的内容等)。 + 门禁 `tools/verify-scenes.mjs` 的第一条就是**组件必须是场景主角**: + `markup.html` 必须用到该组件自己 CSS 里的类名——直接把「外面做卡片、主要部分仍是该组件」编码成判据。 + 协作者取自组件族的真实耦合关系,外壳类 `ksc-*` 与四端标记由 `tools/gen-scenes.mjs` 生成。 + +### 修复 · 非 H5 端的示例预览整片 403(路径基准错误) + +`site/app.js` 的 `endPreviewSrc` 把逐端预渲染产物的地址写成 `../end-preview/..html`, +在 `/site/` 基址下解析到仓库根 `/end-preview/`,而产物实际在 `site/end-preview/`—— +实测 `button/react` 页 5 个示例 iframe **全部 403**,只拿到错误页(body 长度 93)。 +产物本身没问题:`frameworks/` 部署在站点上一级,而 `end-preview/` 在 `site/` 内部, +两者基准不同,不能照抄同一个前缀。改为相对站点根的 `end-preview/…`。 + +### 修复 · 逐端预览渲染的是空组件(预览「表现不好」的根因) + +`tools/build-end-preview.mjs` 只给开关型/数据型组件传初始 props,纯展示组件因此渲染成空壳: +Button 的产物是 ``, +305 份产物里 **68 份文本为空、79 份不足 6 字符**——示例卡片里看到的就是一个没有文字的按钮。 +修法:从 `site/examples/.json` 的**第一个固化的示例**反推该端的真实初始 props +(只取字符串字面量 / 裸布尔 / 数字,`{表达式}` 与数组对象型 prop 一律跳过, +避免把字符串塞进 `data` 导致 `nodes.forEach is not a function`)。 +`button.react` 的产物由空壳变为「主按钮(点击切加载态)」。 + +### 修复 · 组件页在 h5 端请求了不存在的 end-content 文件 + +`endKey()` 直接把路由端名拼进文件名,h5 页会去取 `button.h5.json`(磁盘上是 `button.html.json`), +404 后长期走兜底文案——实测 `verify-site-routes` 抓到 37 条控制台报错。 +改为经 `END_IMPL_KIND` 映射(它本就是「端 → 该端实现文件键」的定义)。 + +### 修复 · 若干门禁假红与真缺陷(都是本轮实测发现的) + +- `tools/verify-component-page.mjs`:示例代码断言原本假定「代码块是四端 tab」, + 已改为断言**只出现本端的 JS/TS 形态**、切换器不出现别的端名、TS 形态确实含类型标注; + 另外补了强缓存清理(示例正文用 `force-cache` 取,产物重写后门禁会拿到上一版而假红)。 +- `tools/verify-examples.mjs`:新增两条判据——Vue 2 模板**根元素带 `v-for`** 会编译失败 + (`Cannot use v-for on stateful component root element`,`alert-ex-2` 实例已修)、 + TS 专属标记的识别补上 `Record<…>` 与 `JSX.Element`(原判据只认 `: void|string|…`,把合法写法判成「无标记」)。 +- `site/logger.js`:不再把浏览器对 ResizeObserver 的提示(`loop completed with undelivered notifications`) + 记为页面错误——它没有 error 对象、不影响渲染,而本站示例/场景 iframe 正是靠 ResizeObserver + 做高度自适应,这条噪声会随帧数线性增长(实测 37 条)并淹没真实报错。 +- `site/style.css`:组合场景代码区补深底浅字(原先继承默认黑字,在深底上对比度 1.04:1)、 + 补 `overflow: auto`(320px 下顶出整页 `overflow=263px`);端标识胶囊 `.ex-end` 补独立配色。 +- `site/app.js`:end-content 异步渲染后补跑表格包裹(`.kole-doc-table`)—— + 该节走自己的回调、不在既有的两处刷新点上,实测导致「所有 table 都被包裹」这条**间歇失败**。 +- `.dockerignore`:排除 `site/end-content/_facts`(4.7MB 构建期事实包,站点从不 fetch 它, + 且内嵌 `frameworks/` 源码全文)。内容文件 `site/end-content/*.json` 照常发布。 + +### 验证 + +| 门禁 | 结果 | +|---|---| +| PC 回归 `tools/run-regression.mjs` | **100%(1464/1464,103 页)· 连跑八次一致** | +| 移动端回归 | 100%(807/807,47 页) | +| `verify:examples --require-ts` | 15 项通过(199 示例 / 796 片段) | +| `verify:scenes` | 9 项通过(103 份场景) | +| `verify:end-content` | 8 项通过(515 份内容) | +| `check-ts-quality`(真实编译) | 597 段 · 0 失败 | +| `verify-component-page` | 110 项通过(连跑 4 次一致) | +| `verify:i18n` / `verify:theme` / `verify:site-routes` / `smoke:site` / `verify:playground` / `verify:nav` / `verify:templates` / `verify:api-docs` / `verify:isolation` | 全部通过 | +| 零运行时依赖 | `zero-dep OK` | + +### 修复 · 组件页「调用代码」是空壳(生成器兜底 → 真实三端调用代码)|ROADMAP S9-P6 + +> 103 个组件页此前展示的 jsx / vue3 / vue2 代码块,大量是生成器兜底的零信息量骨架: +> 例如 icon 页 7 个使用场景的三种端代码**逐字完全相同**,都只有 +> `import { KoleIcon } from 'kole-ui/react';` 加一句 ``。 +> 根因不在文档层:演示页把真实用法写在内联脚本里(`fill('row-size', TIERS.map(...))`), +> 而构建期生成器只读静态标记,于是走「策略 3」兜底输出最小骨架;门禁只校验「片段非空 + prop 可溯源」—— +> **空话成了唯一永不失败的解**。 + +- **修复**:新增固化层。`site/examples/.json` 顶层带 `curated: true` 时,`precompute.mjs` + 保留其 `code` / `source` / `notes`,预览层(`html` / `preview`)仍以本次生成为准(演示页改结构不会让产物失真)。 + 103 个组件的 199 个示例、597 段三端片段改写为可照抄的真实调用,逐条依据演示页脚本的实参, + `notes` 记录「文件:行 + 实参」出处。 +- **新增门禁**:`npm run verify:examples` 由 9 条增至 **13 条** —— 同组件同端片段不得跨示例逐字重复; + 有 props/slots 的组件不得交零属性无内容骨架;`source` 不得是生成器兜底态 `api-derived`; + Vue2 片段必须是可编译形态(模板恰好一个根元素、无 `