From fa168b9a1c0c9add204302e7cb658940759f39ce Mon Sep 17 00:00:00 2001 From: ui-arch-bot Date: Fri, 23 Oct 2026 16:58:52 +0800 Subject: [PATCH] =?UTF-8?q?iter:=20d16=20dataTable=20=E8=90=BD=E5=9C=B0?= =?UTF-8?q?=E5=88=97=E5=AE=BD=20width?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .ua/backlog.json | 8 ++++++++ .ua/index.json | 5 +++-- .ua/iterations.log | 1 + apps/demo/main.ts | 6 +++--- llms-full.txt | 17 +++++++++-------- packages/skin/ui/src/dataTable.ts | 10 +++++++++- packages/skin/ui/ua.manifest.json | 3 ++- 7 files changed, 35 insertions(+), 15 deletions(-) diff --git a/.ua/backlog.json b/.ua/backlog.json index 0e7c796..7e789c7 100644 --- a/.ua/backlog.json +++ b/.ua/backlog.json @@ -176,6 +176,14 @@ "acceptance": "packages/tools/cli/ua.manifest.json(type: tooling)描述 index/list/info/docs/style/verify/mcp 七个子命令与约定,索引包数变 5;AGENTS.md 与 ARCHITECTURE.md 的组件数改成 27;llms.txt / llms-full.txt 重新生成且 CLI 段落可读;npm run check 全绿", "status": "done", "notes": "tooling 类型在 ORDER 表外,排序自然落到末尾(??9 兜底),无需改 CLI 排序逻辑;CLI 清单 docs.components 留空,故不参与 verify 的组件级校验;顺带确认 docs 生成对无组件包不报错" + }, + { + "id": "d16", + "title": "dataTable 落地内核已定义的列宽 width", + "motivation": "table-core 的 ColumnDef 声明了 width?: number | 'flex',但皮肤层从未消费,列宽完全靠浏览器猜;契约与实现脱节", + "acceptance": "dataTable 渲染 colgroup:数字 width 落成固定像素 ,'flex' 或不设交给自适应,选择列固定 44px;demo 表格演示 name 160 / age 100 / city flex;manifest 列定义说明与手把手同步;npm run check 全绿", + "status": "done", + "notes": "用 colgroup 而非逐 th 设宽,保证表头与表体一致且不入侵单元格渲染;未开 table-layout:fixed(nowrap 内容会被裁),宽高仍由内容兜底;pinned 固定列仍未消费(多列 sticky 偏移需测量),留作后续条目" } ] } diff --git a/.ua/index.json b/.ua/index.json index feb55c9..136ac65 100644 --- a/.ua/index.json +++ b/.ua/index.json @@ -1,6 +1,6 @@ { "$schema": "ui-arch-registry-index/0.1", - "generatedAt": "2026-10-23T08:57:12.133Z", + "generatedAt": "2026-10-23T08:58:43.429Z", "repoRoot": ".", "packages": [ { @@ -1223,7 +1223,7 @@ "n": "columns", "t": "ColumnDef[]", "r": 1, - "d": "列定义:内核字段 { key, header?, sortable? } + 皮肤字段 { align?: left|center|right, format?: (value, row) => string }" + "d": "列定义:内核字段 { key, header?, sortable?, width? } + 皮肤字段 { align?, format? };width 数字为固定像素,'flex' 自适应" }, { "n": "filterKey", @@ -1258,6 +1258,7 @@ "准备行数据,确保每行有唯一 id(跨页选择与刷新不丢行靠它)", "定义 columns:sortable: true 的列表头可点击排序(升 → 降 → 取消循环),标记箭头 ↑↓↕", "列展示细节用皮肤字段:align 控制表头与单元格对齐,format(value, row) 返回纯文本(走 textContent,不需要转义)", + "列宽用内核字段 width:数字(像素)固定该列,'flex' 或不设则按内容自适应", "selectable: true 开启行选择:表头全选框带 indeterminate 半选态,工具栏显示已选计数", "选中行用低视觉比重样式(淡色底 + 弱化文字),选择状态存 rowKey,跨页不丢失", "工具栏输入框即筛选,输入即时过滤并回第 1 页;无匹配时显示空状态行", diff --git a/.ua/iterations.log b/.ua/iterations.log index 5ea7de8..f520720 100644 --- a/.ua/iterations.log +++ b/.ua/iterations.log @@ -20,3 +20,4 @@ {"time": "2026-10-23T16:55:55+08:00", "id": "d13", "result": "done", "summary": "dataTable 列定义新增皮肤层 TableColumn(align + format),内核 ColumnDef 不变;表头/单元格共用对齐类,format 走 textContent;demo/manifest/llms 同步,check 全绿"} {"time": "2026-10-23T16:56:36+08:00", "id": "d14", "result": "done", "summary": "新增抽屉 drawer:open 信号驱动侧滑、placement/width 可配、footer 操作区、遮罩/×/Esc 关闭并聚焦首元素;demo/manifest/llms 同步,check 全绿"} {"time": "2026-10-23T16:57:22+08:00", "id": "d15", "result": "done", "summary": "CLI 包补 ua.manifest.json(type: tooling,七个子命令 + 约定),注册表 5 包;修正 AGENTS/ARCHITECTURE 过期组件数 17→27;check 全绿"} +{"time": "2026-10-23T16:58:51+08:00", "id": "d16", "result": "done", "summary": "dataTable 消费内核列宽 width:colgroup 固定像素 / flex 自适应,选择列 44px;demo 三列演示宽档;manifest/llms 同步,check 全绿"} diff --git a/apps/demo/main.ts b/apps/demo/main.ts index 04f0516..9adbe9a 100644 --- a/apps/demo/main.ts +++ b/apps/demo/main.ts @@ -386,9 +386,9 @@ const content = h( selectable: true, loading: tableLoading, columns: [ - { key: 'name', header: '姓名', sortable: true }, - { key: 'age', header: '年龄', sortable: true, align: 'right', format: (v) => `${v} 岁` }, - { key: 'city', header: '城市', align: 'center' }, + { key: 'name', header: '姓名', sortable: true, width: 160 }, + { key: 'age', header: '年龄', sortable: true, align: 'right', width: 100, format: (v) => `${v} 岁` }, + { key: 'city', header: '城市', align: 'center', width: 'flex' }, ], pageSize: 5, }), h('div', { class: 'row' }, switchButton({ label: '加载态', checked: tableLoading }))), diff --git a/llms-full.txt b/llms-full.txt index aac0838..34be8cc 100644 --- a/llms-full.txt +++ b/llms-full.txt @@ -1,6 +1,6 @@ # @ui-arch 组件库 Agent 文档(无图形版) -> 自动生成于 2026-10-23T08:57:12.133Z,数据源:各包 ua.manifest.json,勿手改。人类版文档站:apps/docs/index.html。 +> 自动生成于 2026-10-23T08:58:43.429Z,数据源:各包 ua.manifest.json,勿手改。人类版文档站:apps/docs/index.html。 > 组件 = 普通函数,传 props 返回 DOM;状态用 signal 双向绑定:读 signal() 写 signal(v)。 ## 快速上手 @@ -687,7 +687,7 @@ const name = signal(''); const f = form({ onSubmit: submit }, [formItem({ label: 参数: - data(必填):T[] —— 全量行数据,每行须含 id 字段作 rowKey -- columns(必填):ColumnDef[] —— 列定义:内核字段 { key, header?, sortable? } + 皮肤字段 { align?: left|center|right, format?: (value, row) => string } +- columns(必填):ColumnDef[] —— 列定义:内核字段 { key, header?, sortable?, width? } + 皮肤字段 { align?, format? };width 数字为固定像素,'flex' 自适应 - filterKey:string —— 工具栏筛选的列;缺省取第一列 - pageSize(默认 5):number —— 每页行数;缺省 5 - selectable(默认 false):boolean —— 启用行选择列:全选三态(含半选)、行 checkbox、已选计数;缺省 false @@ -705,12 +705,13 @@ dataTable({ data: users, selectable: true, columns: [{ key: 'name', header: '姓 1. 准备行数据,确保每行有唯一 id(跨页选择与刷新不丢行靠它) 2. 定义 columns:sortable: true 的列表头可点击排序(升 → 降 → 取消循环),标记箭头 ↑↓↕ 3. 列展示细节用皮肤字段:align 控制表头与单元格对齐,format(value, row) 返回纯文本(走 textContent,不需要转义) -4. selectable: true 开启行选择:表头全选框带 indeterminate 半选态,工具栏显示已选计数 -5. 选中行用低视觉比重样式(淡色底 + 弱化文字),选择状态存 rowKey,跨页不丢失 -6. 工具栏输入框即筛选,输入即时过滤并回第 1 页;无匹配时显示空状态行 -7. 表头粘性固定(滚动容器 max-height 420px),斑马纹 + 悬停高亮由 CSS 提供 -8. 数据在途时传 loading(布尔或信号):表格体换成骨架行、筛选与翻页禁用,返回后置回 false 即恢复 -9. 需要独立分页器联动时传 page 信号:const page = signal(1),dataTable({ page }) 与 pagination({ page }) 共用 +4. 列宽用内核字段 width:数字(像素)固定该列,'flex' 或不设则按内容自适应 +5. selectable: true 开启行选择:表头全选框带 indeterminate 半选态,工具栏显示已选计数 +6. 选中行用低视觉比重样式(淡色底 + 弱化文字),选择状态存 rowKey,跨页不丢失 +7. 工具栏输入框即筛选,输入即时过滤并回第 1 页;无匹配时显示空状态行 +8. 表头粘性固定(滚动容器 max-height 420px),斑马纹 + 悬停高亮由 CSS 提供 +9. 数据在途时传 loading(布尔或信号):表格体换成骨架行、筛选与翻页禁用,返回后置回 false 即恢复 +10. 需要独立分页器联动时传 page 信号:const page = signal(1),dataTable({ page }) 与 pagination({ page }) 共用 现场演示:apps/docs/demo.html#sec-table diff --git a/packages/skin/ui/src/dataTable.ts b/packages/skin/ui/src/dataTable.ts index 638bce5..fe1cd60 100644 --- a/packages/skin/ui/src/dataTable.ts +++ b/packages/skin/ui/src/dataTable.ts @@ -132,6 +132,14 @@ export function dataTable(props: DataTableProps): H }); }); + // —— 列宽:数字落成 固定宽度,'flex' 或未设置交给浏览器自适应 —— + const colgroup = h( + 'colgroup', + null, + selectable ? h('col', { style: 'width:44px' }) : null, + ...props.columns.map((col) => (typeof col.width === 'number' ? h('col', { style: `width:${col.width}px` }) : h('col'))), + ); + const filterInput = textField({ placeholder: `筛选 ${filterKey}…`, disabled: props.loading, // 加载中禁止筛选,避免与在途结果竞争 @@ -150,7 +158,7 @@ export function dataTable(props: DataTableProps): H filterInput, selectable ? h('span', { class: 'ua-sel-count' }, () => (selectedCount() ? `已选 ${selectedCount()} 行` : '')) : null, ), - h('div', { class: 'ua-table-scroll' }, h('table', null, h('thead', null, h('tr', null, selectable ? headCheck : null, ...props.columns.map(th))), tbody)), + h('div', { class: 'ua-table-scroll' }, h('table', null, colgroup, h('thead', null, h('tr', null, selectable ? headCheck : null, ...props.columns.map(th))), tbody)), h( 'div', { class: 'ua-pager' }, diff --git a/packages/skin/ui/ua.manifest.json b/packages/skin/ui/ua.manifest.json index 489ca7d..0f11661 100644 --- a/packages/skin/ui/ua.manifest.json +++ b/packages/skin/ui/ua.manifest.json @@ -1094,7 +1094,7 @@ "n": "columns", "t": "ColumnDef[]", "r": 1, - "d": "列定义:内核字段 { key, header?, sortable? } + 皮肤字段 { align?: left|center|right, format?: (value, row) => string }" + "d": "列定义:内核字段 { key, header?, sortable?, width? } + 皮肤字段 { align?, format? };width 数字为固定像素,'flex' 自适应" }, { "n": "filterKey", @@ -1129,6 +1129,7 @@ "准备行数据,确保每行有唯一 id(跨页选择与刷新不丢行靠它)", "定义 columns:sortable: true 的列表头可点击排序(升 → 降 → 取消循环),标记箭头 ↑↓↕", "列展示细节用皮肤字段:align 控制表头与单元格对齐,format(value, row) 返回纯文本(走 textContent,不需要转义)", + "列宽用内核字段 width:数字(像素)固定该列,'flex' 或不设则按内容自适应", "selectable: true 开启行选择:表头全选框带 indeterminate 半选态,工具栏显示已选计数", "选中行用低视觉比重样式(淡色底 + 弱化文字),选择状态存 rowKey,跨页不丢失", "工具栏输入框即筛选,输入即时过滤并回第 1 页;无匹配时显示空状态行",