u
This commit is contained in:
1 parent
e7c84a82a2
commit
025d3232c4
65 files changed
+9838
-9111
No files matched your search
@@ -203,16 +203,7 @@ const App = {
|
||||
title: '金额',
|
||||
width: 120,
|
||||
align: 'right',
|
||||
// 展示:千分位 + ¥ 前缀。**小数位不写在这里**,统一由 editor.precision 给
|
||||
format: { thousands: true, prefix: '¥' },
|
||||
editor: {
|
||||
type: 'number',
|
||||
// 精度:两位小数。超出即 error(红底 + 左侧竖条 + 悬停浮层「最多 2 位小数」),
|
||||
// 且**不改数据** —— E2E 用它验「输多了只标红、值原样保留」
|
||||
precision: 2,
|
||||
// 金额必须 > 0:让「校验态全表可见」在 E2E 里有可断言的 error 数据
|
||||
validate: (v: unknown) => Number(v) > 0 || '金额必须大于 0',
|
||||
},
|
||||
editor: { type: 'input', inputType: 'number' },
|
||||
},
|
||||
{
|
||||
dataIndex: 'status',
|
||||
@@ -224,8 +215,7 @@ const App = {
|
||||
{ label: '启用', value: 1 },
|
||||
{ label: '停用', value: 0 },
|
||||
],
|
||||
// 按行禁用:enabled=0 的那一行状态不许改 —— 用来锁「动态灰底」这条视觉
|
||||
// (e2e 断言第 2 行灰、第 1 行不灰,且都**不需要先进入编辑行**)
|
||||
// 按行禁用:enabled=0 的那一行状态不许改(fms 的 editor.disabled 语义)
|
||||
disabled: (row: { enabled?: number }) => row.enabled === 0,
|
||||
},
|
||||
},
|
||||
@@ -233,11 +223,7 @@ const App = {
|
||||
{
|
||||
dataIndex: 'remark',
|
||||
title: '备注',
|
||||
editor: {
|
||||
type: 'text',
|
||||
// 备注非空:提供 warning 级校验(金额是 error,这里是 warning,两级都有样例)
|
||||
validateWarning: (v: unknown) => String(v ?? '').length > 0 || '建议填写备注',
|
||||
},
|
||||
editor: { type: 'input' },
|
||||
},
|
||||
{ dataIndex: 'op', title: '操作', width: 140, resizable: false, actions: [
|
||||
{ label: '编辑', onClick: () => {} },
|
||||
@@ -256,8 +242,8 @@ const App = {
|
||||
// 路径只能在这种「行数多到会虚拟化」的表上复现(见 e2e/table.spec.ts 的键盘跳格用例)
|
||||
const bigTableColumns = [
|
||||
{ dataIndex: 'id', title: 'ID', width: 80 },
|
||||
{ dataIndex: 'name', title: '名称', width: 200, editor: { type: 'text' } },
|
||||
{ dataIndex: 'value', title: '数值', width: 140, align: 'right', editor: { type: 'number' } },
|
||||
{ dataIndex: 'name', title: '名称', width: 200, editor: { type: 'input' } },
|
||||
{ dataIndex: 'value', title: '数值', width: 140, align: 'right', editor: { type: 'input', inputType: 'number' } },
|
||||
]
|
||||
const bigTableData = Array.from({ length: 5000 }, (_, i) => ({
|
||||
id: i + 1,
|
||||
@@ -266,11 +252,10 @@ const App = {
|
||||
}))
|
||||
|
||||
/**
|
||||
* 纯展示表(列上**都没有** `editor`)—— 「不可改灰底」门控的宿主。
|
||||
* 纯展示表(列上**都没有** `editor`)。
|
||||
*
|
||||
* 灰底的语义是「这一格现在改不了」,只有**旁边存在可改的格子**时才是信息。
|
||||
* 这类表若逐格铺灰,整张表看上去就是「禁用状态」(文档里 6/7 张 demo 正是纯展示表)。
|
||||
* 判据在 G3Table 的 editableColumnsExist / shouldMarkReadonly,见那边注释。
|
||||
* ⚠️ fms-vue 的 fms-table 没有「不可改灰底」这套视觉(那是旧版 G3Table 的自有能力),
|
||||
* 所以本表与其它表的差别只剩「没有编辑器」。
|
||||
*/
|
||||
const plainColumns = [
|
||||
{ dataIndex: 'code', title: '编号', width: 120 },
|
||||
@@ -282,29 +267,23 @@ const App = {
|
||||
{ code: 'A-002', name: '纯展示行 2', remark: '这一列也不可编辑' },
|
||||
])
|
||||
|
||||
/* ---- Table:固定列 + 校验态(几何回归用例的宿主)---- */
|
||||
/* ---- Table:固定列 + 受控当前行 ---- */
|
||||
/**
|
||||
* 为什么单独造一份数据:
|
||||
* 「校验未通过的格子刚好在固定列上」这个组合出过一次**只有真浏览器才量得出**的
|
||||
* 位移 —— 校验态样式给 td 的 `position: relative` 覆盖了库的固定列定位,
|
||||
* 内联的 `left: 200px` 于是从「sticky 吸附偏移」变成普通相对位移,
|
||||
* 整格被推开「前面所有左固定列宽度之和」。happy-dom 没有布局引擎,锁不住这类问题。
|
||||
* 固定列的宿主:列宽总和顶出视口,制造必须横向滚动的场景。
|
||||
*
|
||||
* 两个刻意之处:
|
||||
* · 第 2 行名称为空 → 固定列上必然出现一个 error 格;
|
||||
* · 列宽总和(1680px)超过视口宽度 → 必须横向滚动,固定列才有「固定」可言。
|
||||
* 配置只有列上的 `fixed`,但有三条硬约束:
|
||||
* · `fixed: 'left'` 的列排在最前面、`'right'` 的排在最后面;
|
||||
* · 固定列必须写 `width`(左固定列的吸附位移由「它左侧固定列宽度累加」算出);
|
||||
* · 总列宽要超过容器宽,否则固定与不固定看不出区别。
|
||||
*/
|
||||
const fixedTableColumns = [
|
||||
{ dataIndex: 'code', title: '编号(左固定)', width: 200, fixed: 'left' },
|
||||
{
|
||||
dataIndex: 'name',
|
||||
title: '名称(校验列)',
|
||||
title: '名称',
|
||||
width: 200,
|
||||
fixed: 'left',
|
||||
editor: {
|
||||
type: 'text',
|
||||
validate: (v: unknown) => String(v ?? '').length > 0 || '名称不能为空',
|
||||
},
|
||||
editor: { type: 'input' },
|
||||
},
|
||||
// 填充列:把总宽顶出视口,否则固定列与普通列长得一模一样
|
||||
...Array.from({ length: 6 }, (_, i) => ({
|
||||
@@ -318,7 +297,6 @@ const App = {
|
||||
Object.fromEntries(Array.from({ length: 6 }, (_, k) => [`extra${k}`, `填充值 ${k + 1}-${row}`]))
|
||||
const fixedTableData = [
|
||||
{ id: 1, code: 'A-001', name: '正常行', remark: '已归档', ...fixedRowFillers(1) },
|
||||
// 空名称 → 这一格必然处于 error 态
|
||||
{ id: 2, code: 'A-002', name: '', remark: '待复核', ...fixedRowFillers(2) },
|
||||
]
|
||||
/**
|
||||
@@ -331,32 +309,16 @@ const App = {
|
||||
const fixedActiveKey = ref<string | null>(null)
|
||||
|
||||
/**
|
||||
* 日期编辑器(`editor.type = 'date'`)的宿主。
|
||||
* 日期列(**只读展示**)。
|
||||
*
|
||||
* 刻意**单独一张小表**,而不是往 table-wrap 里加列:那张表的列序被 Tab 跳格用例
|
||||
* 逐格锁着(amount → status → enabled → remark 的顺位),插一列就要连带改一串断言。
|
||||
*
|
||||
* 两列刻意配不同格式,覆盖 `format` 的两种用法:
|
||||
* · 开航日 —— 默认 `YYYY-MM-DD`(面板选到「日」为止),并配必填校验;
|
||||
* · 截单日 —— `'YYYY-MM-DD HH:mm'`,面板会多出时间列、选完要点「确定」才提交。
|
||||
* ⚠️ fms-vue 的 fms-table 没有 date 编辑器,所以本组件也没有 —— `editor.type`
|
||||
* 只有 input / select / checkbox。这里保留两列纯粹是让「含日期字符串的列」
|
||||
* 在真实密度下正常渲染,不再挂编辑器。
|
||||
*/
|
||||
const dateTableColumns = ref<G3TableColumn<TableRow>[]>([
|
||||
{ dataIndex: 'bookingNo', title: '订舱号', width: 120 },
|
||||
{
|
||||
dataIndex: 'etd',
|
||||
title: '开航日',
|
||||
width: 150,
|
||||
editor: {
|
||||
type: 'date',
|
||||
validate: (v: unknown) => String(v ?? '').length > 0 || '请选择开航日',
|
||||
},
|
||||
},
|
||||
{
|
||||
dataIndex: 'docClose',
|
||||
title: '截单日',
|
||||
width: 180,
|
||||
editor: { type: 'date', format: 'YYYY-MM-DD HH:mm' },
|
||||
},
|
||||
{ dataIndex: 'etd', title: '开航日', width: 150 },
|
||||
{ dataIndex: 'docClose', title: '截单日', width: 180 },
|
||||
])
|
||||
const dateTableData = ref<TableRow[]>([
|
||||
{ id: 1, bookingNo: 'BK001', etd: '2026-03-15', docClose: '2026-03-12 18:00' },
|
||||
@@ -366,18 +328,19 @@ const App = {
|
||||
])
|
||||
|
||||
/**
|
||||
* 键盘行为的宿主:三列分别覆盖「单行 text」「单行 number」「多行 textarea」。
|
||||
* 键盘行为的宿主:三列都是**单行**编辑器。
|
||||
*
|
||||
* 单行与多行的 Enter 语义**不同**(确认下移 vs 换行),所以必须有一列 textarea
|
||||
* 才能把这条区分锁住 —— table-wrap 里没有多行编辑器。
|
||||
* 表格编辑器没有 `textarea`(见 `src/table/types.ts` 里 `TableEditor.type` 的说明:
|
||||
* 行高放不下多行正文),所以这里不存在「多行 Enter 换行」那种分支 ——
|
||||
* Enter 一律是「确认 + 下移」,上下键一律归表格导航。
|
||||
*/
|
||||
const keysTableColumns = ref<G3TableColumn<TableRow>[]>([
|
||||
{ dataIndex: 'code', title: '编号', width: 130, editor: { type: 'text' } },
|
||||
{ dataIndex: 'qty', title: '数量', width: 110, align: 'right', editor: { type: 'number' } },
|
||||
{ dataIndex: 'note', title: '备注(多行)', width: 260, editor: { type: 'textarea' } },
|
||||
{ dataIndex: 'code', title: '编号', width: 130, editor: { type: 'input' } },
|
||||
{ dataIndex: 'qty', title: '数量', width: 110, align: 'right', editor: { type: 'input', inputType: 'number' } },
|
||||
{ dataIndex: 'note', title: '备注', width: 260, editor: { type: 'input' } },
|
||||
])
|
||||
const keysTableData = ref<TableRow[]>([
|
||||
{ id: 1, code: 'K-001', qty: 12, note: '第一行' },
|
||||
{ id: 1, code: 'K-001', qty: 12, note: '备注一' },
|
||||
{ id: 2, code: 'K-002', qty: 34, note: '' },
|
||||
{ id: 3, code: 'K-003', qty: 56, note: '' },
|
||||
])
|
||||
@@ -704,9 +667,7 @@ const App = {
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- 大数据量(5000 行):纵向虚拟滚动应当开启;容器限高以产生滚动。
|
||||
顺带开斑马纹:纵向虚拟时库改取 nth-child(odd)(DOM 首行≈偶数数据行),
|
||||
冻结列的条纹叠色必须跟着同一套 nth-child 走(见 _overrides.scss 的 stripe 段)。 -->
|
||||
<!-- 大数据量(5000 行):纵向虚拟滚动应当开启;容器限高以产生滚动。 -->
|
||||
<div data-testid="table-big-wrap" style="height: 360px; margin-top: 16px">
|
||||
<G3Table
|
||||
data-testid="table-big"
|
||||
@@ -714,7 +675,6 @@ const App = {
|
||||
:data-source="bigTableData"
|
||||
:seq="false"
|
||||
:row-height="30"
|
||||
stripe
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -728,24 +688,23 @@ const App = {
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- 固定列 + 校验态 + 受控当前行:几何与「点格进编辑要高亮」的回归宿主 -->
|
||||
<!-- 固定列 + 受控当前行 -->
|
||||
<div data-testid="table-fixed-wrap" style="height: 240px; margin-top: 16px">
|
||||
<G3Table
|
||||
data-testid="table-fixed"
|
||||
:columns="fixedTableColumns"
|
||||
:data-source="fixedTableData"
|
||||
:active-row-key="fixedActiveKey"
|
||||
fixed-col-shadow
|
||||
@row-click="(_, row) => (fixedActiveKey = String(row.id))"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- 纯展示表(列上都没有 editor):不该铺「不可改」灰底 -->
|
||||
<!-- 纯展示表(列上都没有 editor) -->
|
||||
<div data-testid="table-plain-wrap" style="height: 200px; margin-top: 16px">
|
||||
<G3Table data-testid="table-plain" :columns="plainColumns" :data-source="plainData" />
|
||||
</div>
|
||||
|
||||
<!-- 关闭编辑(editable: false),但列上声明了 editor:同样不该铺灰底 -->
|
||||
<!-- 关闭编辑(editable: false),但列上声明了 editor -->
|
||||
<div data-testid="table-noedit-wrap" style="height: 200px; margin-top: 16px">
|
||||
<G3Table
|
||||
data-testid="table-noedit"
|
||||
@@ -755,14 +714,8 @@ const App = {
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- 斑马纹(stripe):固定列(序号列)也要跟着上条纹。
|
||||
用纯展示列(没有 editor)当宿主,避免「不可改灰底」盖住条纹干扰断言。 -->
|
||||
<div data-testid="table-stripe-wrap" style="height: 200px; margin-top: 16px">
|
||||
<G3Table data-testid="table-stripe" :columns="plainColumns" :data-source="plainData" stripe />
|
||||
</div>
|
||||
|
||||
<!-- 日期编辑器(editor.type = 'date'):点格即弹日历,值始终是字符串。
|
||||
刻意单独一张表:table-wrap 的列序被 Tab 跳格用例逐格锁着,往它里面加列会连带改一堆断言。 -->
|
||||
<!-- 日期列(只读展示):fms 没有 date 编辑器,见 dateTableColumns 的说明。 -->
|
||||
<div data-testid="table-date-wrap" style="height: 220px; margin-top: 16px">
|
||||
<G3Table
|
||||
data-testid="table-date"
|
||||
@@ -772,15 +725,14 @@ const App = {
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- 键盘行为的宿主:Enter 下移 / 多行换行 / 方向键归输入框。
|
||||
同样单独一张表(理由同上),行高给足让 textarea 有地方显示多行。 -->
|
||||
<!-- 键盘行为的宿主:Enter 下移 / 左右键到边界切格 / 上下键切行。
|
||||
同样单独一张表(理由同上)。三列都是单行编辑器 —— 表格没有 textarea。 -->
|
||||
<div data-testid="table-keys-wrap" style="height: 260px; margin-top: 16px">
|
||||
<G3Table
|
||||
data-testid="table-keys"
|
||||
:columns="keysTableColumns"
|
||||
:data-source="keysTableData"
|
||||
:seq="false"
|
||||
:row-height="64"
|
||||
/>
|
||||
</div>
|
||||
</section>
|
||||
@@ -788,4 +740,4 @@ const App = {
|
||||
`,
|
||||
}
|
||||
|
||||
createApp(App).mount('#app')
|
||||
createApp(App).mount('#app')
|
||||
Reference in new issue
Block a user