@ticatec/topside-elements 1.0.5 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +24 -0
- package/dist/app_layout/ClassicLayout.svelte +0 -3
- package/dist/app_layout/HeaderLayout.svelte +0 -1
- package/dist/app_layout/SidebarLayout.svelte +0 -2
- package/dist/data_table/DataTable.svelte +153 -12
- package/dist/data_table/DataTable.svelte.d.ts +22 -2
- package/dist/data_table/README.md +119 -38
- package/dist/data_table/README_CN.md +119 -38
- package/dist/data_table/index.d.ts +5 -0
- package/dist/data_table/index.js +2 -0
- package/dist/data_table/lib/IndicatorColumn.d.ts +2 -1
- package/dist/data_table/lib/RowExpansion.d.ts +84 -0
- package/dist/data_table/lib/RowExpansion.js +43 -0
- package/dist/data_table/parts/ActionsPanel.svelte +4 -0
- package/dist/data_table/parts/ActionsPanel.svelte.d.ts +2 -0
- package/dist/data_table/parts/ActionsRow.svelte +8 -1
- package/dist/data_table/parts/ActionsRow.svelte.d.ts +2 -0
- package/dist/data_table/parts/ContentPanel.svelte +9 -1
- package/dist/data_table/parts/ContentPanel.svelte.d.ts +4 -0
- package/dist/data_table/parts/DataRow.svelte +13 -2
- package/dist/data_table/parts/DataRow.svelte.d.ts +2 -0
- package/dist/data_table/parts/FixedColumnsPanel.svelte +11 -2
- package/dist/data_table/parts/FixedColumnsPanel.svelte.d.ts +6 -1
- package/dist/data_table/parts/FixedRow.svelte +19 -2
- package/dist/data_table/parts/FixedRow.svelte.d.ts +4 -0
- package/docs/components/README.md +1 -1
- package/docs/components/data-table/README.md +53 -1
- package/package.json +1 -1
|
@@ -55,6 +55,7 @@ import type { DataColumn, ActionsColumn, IndicatorColumn, RowAction } from "@tic
|
|
|
55
55
|
| `style` | `string` | `""` | 附加 CSS 样式 |
|
|
56
56
|
| `summaryLabel` | `string` | i18n `dataTable.summaryLabel`(合计) | 合计行标签,传空串不显示 |
|
|
57
57
|
| `summaryValues` | `Record<string, any> \| null` | `null` | 外部合计值(按 field),优先于本地计算,用于分页时显示服务端全量合计 |
|
|
58
|
+
| `rowExpansion` | `RowExpansion \| null` | `null` | 行展开配置(展开区组件、是否显示图标、单击 / 双击触发等),见[行展开](#行展开) |
|
|
58
59
|
|
|
59
60
|
## 类型
|
|
60
61
|
|
|
@@ -134,7 +135,28 @@ interface IndicatorColumn {
|
|
|
134
135
|
width: number; // 列宽(像素)
|
|
135
136
|
selectable?: boolean; // 行是否可选择
|
|
136
137
|
showRowNo?: boolean; // 是否显示行号
|
|
137
|
-
|
|
138
|
+
/** @deprecated 请改用 DataTable 的 rowExpansion 属性 */
|
|
139
|
+
buildInlineComponent?: (data: any) => Promise<any>;
|
|
140
|
+
}
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
### RowExpansion
|
|
144
|
+
|
|
145
|
+
```typescript
|
|
146
|
+
interface RowExpansion<T = any> {
|
|
147
|
+
build: (data: T) => Promise<Component> | Component; // 展开区组件生成器(可异步)
|
|
148
|
+
showToggle?: boolean; // 指示列是否显示展开图标,默认 true(需配置 indicatorColumn)
|
|
149
|
+
trigger?: 'click' | 'dblclick'; // 整行单击 / 双击切换展开,默认不设置
|
|
150
|
+
isExpandable?: (data: T) => boolean; // 哪些行允许展开
|
|
151
|
+
onExpandChange?: (data: T | null) => void; // 展开 / 收起回调
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
// 展开区组件收到的属性:data(行数据)与 context
|
|
155
|
+
interface RowExpandContext<T = any> {
|
|
156
|
+
data: T;
|
|
157
|
+
collapse: () => void; // 关闭当前展开行
|
|
158
|
+
actions: Array<RowAction<T>>; // 本行的行动作(来自 actionsColumn.getActions)
|
|
159
|
+
invoke: (label: string) => Promise<boolean>; // 按 label 执行行动作
|
|
138
160
|
}
|
|
139
161
|
```
|
|
140
162
|
|
|
@@ -486,60 +508,36 @@ interface RowAction {
|
|
|
486
508
|
import OrderDetails from "./OrderDetails.svelte";
|
|
487
509
|
|
|
488
510
|
const columns = [
|
|
489
|
-
{
|
|
490
|
-
{
|
|
491
|
-
{
|
|
511
|
+
{ title: "订单ID", field: "orderId", width: 120 },
|
|
512
|
+
{ title: "客户", field: "customer", width: 150 },
|
|
513
|
+
{ title: "总计", field: "total", width: 100, align: "right",
|
|
492
514
|
formatter: (value) => `¥${value?.toFixed(2) ?? '0.00'}`
|
|
493
515
|
},
|
|
494
|
-
{
|
|
495
|
-
{ text: "日期", field: "orderDate", width: 120 }
|
|
516
|
+
{ title: "状态", field: "status", width: 120, align: "center" }
|
|
496
517
|
];
|
|
497
518
|
|
|
498
|
-
const indicatorColumn = {
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
519
|
+
const indicatorColumn = { width: 50 };
|
|
520
|
+
|
|
521
|
+
const rowExpansion = {
|
|
522
|
+
build: async (orderData) => {
|
|
523
|
+
// 可以先请求明细再决定展开区组件
|
|
524
|
+
await new Promise(resolve => setTimeout(resolve, 300));
|
|
505
525
|
return OrderDetails;
|
|
506
526
|
}
|
|
507
527
|
};
|
|
508
|
-
|
|
509
|
-
const orders = [
|
|
510
|
-
{
|
|
511
|
-
orderId: "ORD-001",
|
|
512
|
-
customer: "张伟",
|
|
513
|
-
total: 2999.99,
|
|
514
|
-
status: "已发货",
|
|
515
|
-
orderDate: "2024-01-15",
|
|
516
|
-
items: [
|
|
517
|
-
{ product: "笔记本电脑", quantity: 1, price: 2999.99 }
|
|
518
|
-
]
|
|
519
|
-
},
|
|
520
|
-
{
|
|
521
|
-
orderId: "ORD-002",
|
|
522
|
-
customer: "李娜",
|
|
523
|
-
total: 1499.98,
|
|
524
|
-
status: "处理中",
|
|
525
|
-
orderDate: "2024-01-14",
|
|
526
|
-
items: [
|
|
527
|
-
{ product: "鼠标", quantity: 2, price: 249.99 },
|
|
528
|
-
{ product: "键盘", quantity: 1, price: 999.99 }
|
|
529
|
-
]
|
|
530
|
-
}
|
|
531
|
-
];
|
|
532
528
|
</script>
|
|
533
529
|
|
|
534
530
|
<DataTable
|
|
535
531
|
{columns}
|
|
536
532
|
list={orders}
|
|
537
533
|
{indicatorColumn}
|
|
538
|
-
|
|
534
|
+
{rowExpansion}
|
|
539
535
|
emptyText="未找到订单"
|
|
540
536
|
/>
|
|
541
537
|
```
|
|
542
538
|
|
|
539
|
+
更多触发方式与展开区内关闭 / 调用行动作见下文[行展开](#行展开)。
|
|
540
|
+
|
|
543
541
|
### 带有冻结列的表格
|
|
544
542
|
|
|
545
543
|
```svelte
|
|
@@ -862,6 +860,89 @@ const columns: DataColumn[] = [
|
|
|
862
860
|
|
|
863
861
|
合计行背景色可用 CSS 变量 `--topside-data-table-summary-bg` 覆盖(默认同表头)。
|
|
864
862
|
|
|
863
|
+
## 行展开
|
|
864
|
+
|
|
865
|
+
通过 `rowExpansion` 配置。同一时间只展开一行;展开区组件收到 `data`(行数据)与 `context`(`RowExpandContext`)两个属性。
|
|
866
|
+
|
|
867
|
+
### 触发方式
|
|
868
|
+
|
|
869
|
+
```svelte
|
|
870
|
+
<script>
|
|
871
|
+
import DataTable from "@ticatec/topside-elements/DataTable";
|
|
872
|
+
import OrderDetails from "./OrderDetails.svelte";
|
|
873
|
+
|
|
874
|
+
let table;
|
|
875
|
+
|
|
876
|
+
const rowExpansion = {
|
|
877
|
+
build: async (order) => OrderDetails,
|
|
878
|
+
showToggle: false, // 不在指示列显示展开图标(默认 true)
|
|
879
|
+
trigger: 'dblclick', // 双击行切换;'click' 为单击(点到按钮 / 链接 / 输入框不会触发)
|
|
880
|
+
isExpandable: (order) => order.items?.length > 0,
|
|
881
|
+
onExpandChange: (order) => console.log('expanded:', order) // 收起时为 null
|
|
882
|
+
};
|
|
883
|
+
|
|
884
|
+
const actionsColumn = {
|
|
885
|
+
width: 120,
|
|
886
|
+
getActions: (order) => [
|
|
887
|
+
{ label: '编辑', handler: () => edit(order) },
|
|
888
|
+
// 操作列按钮通过组件方法控制展开
|
|
889
|
+
{ label: '明细', handler: () => table.toggleRowExpand(order) }
|
|
890
|
+
]
|
|
891
|
+
};
|
|
892
|
+
</script>
|
|
893
|
+
|
|
894
|
+
<DataTable bind:this={table} {columns} {list} {rowExpansion} {actionsColumn} />
|
|
895
|
+
<button onclick={() => table.expandRow(list[0])}>展开第一行</button>
|
|
896
|
+
<button onclick={() => table.collapseRow()}>收起</button>
|
|
897
|
+
```
|
|
898
|
+
|
|
899
|
+
组件方法(`bind:this` 后调用,按行数据对象匹配):
|
|
900
|
+
|
|
901
|
+
| 方法 | 说明 |
|
|
902
|
+
|------|------|
|
|
903
|
+
| `expandRow(data)` | 展开指定行(已展开 / 不允许展开 / 找不到时忽略),返回 Promise |
|
|
904
|
+
| `collapseRow(data?)` | 收起指定行;不传参数收起当前展开行 |
|
|
905
|
+
| `toggleRowExpand(data)` | 切换指定行,返回 Promise |
|
|
906
|
+
| `isRowExpanded(data)` | 该行是否展开 |
|
|
907
|
+
| `getExpandedRow()` | 当前展开行的数据,没有为 `null` |
|
|
908
|
+
|
|
909
|
+
### 在自定义单元格里触发
|
|
910
|
+
|
|
911
|
+
自定义 `render` 组件或 `ActionCell` 不需要拿到表格实例:在行内任意元素上派发事件即可,DataTable 会定位到所在行。
|
|
912
|
+
|
|
913
|
+
```svelte
|
|
914
|
+
<!-- OrderNoCell.svelte -->
|
|
915
|
+
<script>
|
|
916
|
+
import { requestRowToggle } from "@ticatec/topside-elements/DataTable";
|
|
917
|
+
let { data } = $props();
|
|
918
|
+
</script>
|
|
919
|
+
|
|
920
|
+
<a href="#" onclick={(e) => { e.preventDefault(); requestRowToggle(e.currentTarget); }}>{data.orderId}</a>
|
|
921
|
+
```
|
|
922
|
+
|
|
923
|
+
可用的助手:`requestRowExpand(el)`、`requestRowCollapse(el)`、`requestRowToggle(el)`;也可以自己派发 `ROW_EXPAND_EVENT`(`topside-row-expand`,`detail: { expanded?: boolean }`,需要 `bubbles: true`)。没有配置 `rowExpansion` 时这些请求被忽略。
|
|
924
|
+
|
|
925
|
+
### 展开区内关闭 / 调用行动作
|
|
926
|
+
|
|
927
|
+
```svelte
|
|
928
|
+
<!-- OrderDetails.svelte -->
|
|
929
|
+
<script>
|
|
930
|
+
let { data, context } = $props();
|
|
931
|
+
</script>
|
|
932
|
+
|
|
933
|
+
<div>
|
|
934
|
+
{#each context.actions as action}
|
|
935
|
+
<button disabled={action.disabled} onclick={() => action.handler(data)}>{action.label}</button>
|
|
936
|
+
{/each}
|
|
937
|
+
<button onclick={() => context.invoke('编辑')}>编辑</button>
|
|
938
|
+
<button onclick={() => context.collapse()}>关闭</button>
|
|
939
|
+
</div>
|
|
940
|
+
```
|
|
941
|
+
|
|
942
|
+
`context.actions` 即 `actionsColumn.getActions(data)` 的结果(没有 `actionsColumn` 时为空数组);嵌套很深的子组件也可以用 `requestRowCollapse(el)` 关闭所在行。
|
|
943
|
+
|
|
944
|
+
> 兼容:旧写法 `indicatorColumn.buildInlineComponent` 仍然有效,等价于 `rowExpansion = { build }`。
|
|
945
|
+
|
|
865
946
|
## 样式
|
|
866
947
|
|
|
867
948
|
DataTable 组件通过 CSS 自定义属性和类支持广泛的样式定制:
|
|
@@ -8,8 +8,13 @@ import type DataColumn from "./lib/DataColumn";
|
|
|
8
8
|
import type { SummaryKind, SummaryFn, ColumnRender, ColumnRenderObject } from "./lib/DataColumn";
|
|
9
9
|
import type { CellAction, GetCellAction, ActionCellProps } from "./lib/CellAction";
|
|
10
10
|
import ActionCell from "./parts/ActionCell.svelte";
|
|
11
|
+
import type RowExpansion from "./lib/RowExpansion";
|
|
12
|
+
import type { RowExpandTrigger, RowExpandContext, RowExpandRequest, BuildInlineComponent, IsRowExpandable } from "./lib/RowExpansion";
|
|
13
|
+
import { ROW_EXPAND_EVENT, requestRowExpand, requestRowCollapse, requestRowToggle } from "./lib/RowExpansion";
|
|
11
14
|
export default DataTable;
|
|
12
15
|
export { ActionCell };
|
|
16
|
+
export { ROW_EXPAND_EVENT, requestRowExpand, requestRowCollapse, requestRowToggle };
|
|
17
|
+
export type { RowExpansion, RowExpandTrigger, RowExpandContext, RowExpandRequest, BuildInlineComponent, IsRowExpandable };
|
|
13
18
|
export type { ActionsColumn, IndicatorColumn, FormatCellFn, CellHint, DataColumn, ColumnRender, ColumnRenderObject };
|
|
14
19
|
export type { RowAction, GetRowActions, ActionHandler, CellAction, GetCellAction, ActionCellProps };
|
|
15
20
|
export type { SummaryKind, SummaryFn };
|
package/dist/data_table/index.js
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import DataTable from "./DataTable.svelte";
|
|
2
2
|
import ActionCell from "./parts/ActionCell.svelte";
|
|
3
|
+
import { ROW_EXPAND_EVENT, requestRowExpand, requestRowCollapse, requestRowToggle } from "./lib/RowExpansion";
|
|
3
4
|
export default DataTable;
|
|
4
5
|
export { ActionCell };
|
|
6
|
+
export { ROW_EXPAND_EVENT, requestRowExpand, requestRowCollapse, requestRowToggle };
|
|
@@ -8,7 +8,8 @@ export default interface IndicatorColumn {
|
|
|
8
8
|
*/
|
|
9
9
|
selectable?: boolean;
|
|
10
10
|
/**
|
|
11
|
-
*
|
|
11
|
+
* @deprecated 请改用 DataTable 的 `rowExpansion` 属性(`{ build, showToggle, trigger, ... }`)。
|
|
12
|
+
* 保留兼容:等价于 rowExpansion = { build: buildInlineComponent }。
|
|
12
13
|
*/
|
|
13
14
|
buildInlineComponent?: (data: any) => Promise<any>;
|
|
14
15
|
/**
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import type { Component } from "svelte";
|
|
2
|
+
import type RowAction from "./RowAction";
|
|
3
|
+
/**
|
|
4
|
+
* 行展开触发方式(作用在整行上):
|
|
5
|
+
* - 'click' 单击行切换展开 / 收起
|
|
6
|
+
* - 'dblclick' 双击行切换展开 / 收起
|
|
7
|
+
* 不设置时只能通过指示列图标、组件方法(expandRow / collapseRow / toggleRowExpand)
|
|
8
|
+
* 或行内派发的 DOM 事件(requestRowExpand / requestRowCollapse)来控制。
|
|
9
|
+
*/
|
|
10
|
+
export type RowExpandTrigger = 'click' | 'dblclick';
|
|
11
|
+
/**
|
|
12
|
+
* 构建展开区组件:返回一个 Svelte 组件(可异步,如先请求明细再决定组件)。
|
|
13
|
+
* 组件会收到 `data`(行数据)和 `context`(RowExpandContext)两个属性。
|
|
14
|
+
*/
|
|
15
|
+
export type BuildInlineComponent<T = any> = (data: T) => Promise<Component<any>> | Component<any>;
|
|
16
|
+
/** 判定某行是否允许展开 */
|
|
17
|
+
export type IsRowExpandable<T = any> = (data: T) => boolean;
|
|
18
|
+
/**
|
|
19
|
+
* 传给展开区组件的上下文
|
|
20
|
+
*/
|
|
21
|
+
export interface RowExpandContext<T = any> {
|
|
22
|
+
/** 行数据 */
|
|
23
|
+
data: T;
|
|
24
|
+
/** 关闭当前展开行 */
|
|
25
|
+
collapse: () => void;
|
|
26
|
+
/** 本行的行动作(取自 actionsColumn.getActions(data),没有 actionsColumn 时为空数组) */
|
|
27
|
+
actions: Array<RowAction<T>>;
|
|
28
|
+
/** 按 label 执行一个行动作;找不到时返回 false */
|
|
29
|
+
invoke: (label: string) => Promise<boolean>;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* DataTable 行展开配置(`rowExpansion` 属性)
|
|
33
|
+
*/
|
|
34
|
+
export default interface RowExpansion<T = any> {
|
|
35
|
+
/** 展开区组件生成器 */
|
|
36
|
+
build: BuildInlineComponent<T>;
|
|
37
|
+
/**
|
|
38
|
+
* 是否在指示列显示展开 / 收起图标,默认 true。
|
|
39
|
+
* 需要同时配置 indicatorColumn;设为 false 时只靠 trigger / 方法 / 事件触发。
|
|
40
|
+
*/
|
|
41
|
+
showToggle?: boolean;
|
|
42
|
+
/** 整行触发方式(单击 / 双击),默认不设置 */
|
|
43
|
+
trigger?: RowExpandTrigger;
|
|
44
|
+
/** 判定某行是否允许展开,默认所有行都可以 */
|
|
45
|
+
isExpandable?: IsRowExpandable<T>;
|
|
46
|
+
/** 展开状态变化回调:展开时为该行数据,收起时为 null */
|
|
47
|
+
onExpandChange?: (data: T | null) => void;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* 行内元素(render cell / ActionCell / 操作列 / 展开区)请求切换展开状态时派发的 DOM 事件名。
|
|
51
|
+
* 事件冒泡到所在行,由 DataTable 定位行并处理;detail 见 RowExpandRequest。
|
|
52
|
+
*/
|
|
53
|
+
export declare const ROW_EXPAND_EVENT = "topside-row-expand";
|
|
54
|
+
export interface RowExpandRequest {
|
|
55
|
+
/** true 展开、false 收起、undefined 切换 */
|
|
56
|
+
expanded?: boolean;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* 在行内任意元素上调用:请求展开所在行。
|
|
60
|
+
* 典型用法:自定义单元格组件里 `onclick={(e) => requestRowExpand(e.currentTarget)}`
|
|
61
|
+
*/
|
|
62
|
+
export declare const requestRowExpand: (target: EventTarget | null | undefined) => boolean;
|
|
63
|
+
/** 在行内任意元素(包括展开区内部)上调用:请求收起所在行 */
|
|
64
|
+
export declare const requestRowCollapse: (target: EventTarget | null | undefined) => boolean;
|
|
65
|
+
/** 在行内任意元素上调用:切换所在行的展开状态 */
|
|
66
|
+
export declare const requestRowToggle: (target: EventTarget | null | undefined) => boolean;
|
|
67
|
+
/** 事件是否发生在交互元素内部(按钮、链接、输入框……) */
|
|
68
|
+
export declare const isInteractiveTarget: (e: Event) => boolean;
|
|
69
|
+
/**
|
|
70
|
+
* 内部使用:DataTable 传给各行组件的事件处理器
|
|
71
|
+
* @internal
|
|
72
|
+
*/
|
|
73
|
+
export interface RowEventHandlers<R = any> {
|
|
74
|
+
onRowClick: (row: R, e: MouseEvent) => void;
|
|
75
|
+
onRowDblClick: (row: R, e: MouseEvent) => void;
|
|
76
|
+
onExpandRequest: (row: R, e: Event) => void;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* 内部使用的 Svelte action:在行容器上监听 ROW_EXPAND_EVENT。
|
|
80
|
+
* @internal
|
|
81
|
+
*/
|
|
82
|
+
export declare const onRowExpandRequest: (node: HTMLElement, handler: (e: Event) => void) => {
|
|
83
|
+
destroy(): void;
|
|
84
|
+
};
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 行内元素(render cell / ActionCell / 操作列 / 展开区)请求切换展开状态时派发的 DOM 事件名。
|
|
3
|
+
* 事件冒泡到所在行,由 DataTable 定位行并处理;detail 见 RowExpandRequest。
|
|
4
|
+
*/
|
|
5
|
+
export const ROW_EXPAND_EVENT = 'topside-row-expand';
|
|
6
|
+
const dispatch = (target, expanded) => {
|
|
7
|
+
if (!target)
|
|
8
|
+
return false;
|
|
9
|
+
return target.dispatchEvent(new CustomEvent(ROW_EXPAND_EVENT, {
|
|
10
|
+
bubbles: true,
|
|
11
|
+
composed: true,
|
|
12
|
+
cancelable: true,
|
|
13
|
+
detail: { expanded }
|
|
14
|
+
}));
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* 在行内任意元素上调用:请求展开所在行。
|
|
18
|
+
* 典型用法:自定义单元格组件里 `onclick={(e) => requestRowExpand(e.currentTarget)}`
|
|
19
|
+
*/
|
|
20
|
+
export const requestRowExpand = (target) => dispatch(target, true);
|
|
21
|
+
/** 在行内任意元素(包括展开区内部)上调用:请求收起所在行 */
|
|
22
|
+
export const requestRowCollapse = (target) => dispatch(target, false);
|
|
23
|
+
/** 在行内任意元素上调用:切换所在行的展开状态 */
|
|
24
|
+
export const requestRowToggle = (target) => dispatch(target);
|
|
25
|
+
/** 行级触发时忽略来自这些元素内部的点击(它们有自己的行为) */
|
|
26
|
+
const INTERACTIVE_SELECTOR = 'a, button, input, select, textarea, label, [role="button"], [contenteditable="true"]';
|
|
27
|
+
/** 事件是否发生在交互元素内部(按钮、链接、输入框……) */
|
|
28
|
+
export const isInteractiveTarget = (e) => {
|
|
29
|
+
const el = e.target;
|
|
30
|
+
return !!el && typeof el.closest === 'function' && el.closest(INTERACTIVE_SELECTOR) != null;
|
|
31
|
+
};
|
|
32
|
+
/**
|
|
33
|
+
* 内部使用的 Svelte action:在行容器上监听 ROW_EXPAND_EVENT。
|
|
34
|
+
* @internal
|
|
35
|
+
*/
|
|
36
|
+
export const onRowExpandRequest = (node, handler) => {
|
|
37
|
+
node.addEventListener(ROW_EXPAND_EVENT, handler);
|
|
38
|
+
return {
|
|
39
|
+
destroy() {
|
|
40
|
+
node.removeEventListener(ROW_EXPAND_EVENT, handler);
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
};
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
import { onDestroy, onMount } from "svelte";
|
|
6
6
|
import i18nRes from "../../i18nRes";
|
|
7
7
|
import type { VirtualWindow } from "../lib/virtualWindow";
|
|
8
|
+
import type { RowEventHandlers } from "../lib/RowExpansion";
|
|
8
9
|
|
|
9
10
|
interface Props {
|
|
10
11
|
actionsColumn: ActionsColumn;
|
|
@@ -18,6 +19,7 @@
|
|
|
18
19
|
vwindow?: VirtualWindow | null;
|
|
19
20
|
/** 与数据区的合计行对齐(操作列这一格留空) */
|
|
20
21
|
showSummary?: boolean;
|
|
22
|
+
rowEvents?: RowEventHandlers<TableRow> | null;
|
|
21
23
|
}
|
|
22
24
|
|
|
23
25
|
let {
|
|
@@ -30,6 +32,7 @@
|
|
|
30
32
|
headerHeight,
|
|
31
33
|
vwindow = null,
|
|
32
34
|
showSummary = false,
|
|
35
|
+
rowEvents = null,
|
|
33
36
|
}: Props = $props();
|
|
34
37
|
|
|
35
38
|
// Virtual scrolling: same shared window as the other panels.
|
|
@@ -89,6 +92,7 @@
|
|
|
89
92
|
width={actionsColumn.width}
|
|
90
93
|
align={actionsColumn.align}
|
|
91
94
|
actions={actionsColumn.getActions(row.data)}
|
|
95
|
+
{rowEvents}
|
|
92
96
|
/>
|
|
93
97
|
{#if row == expandRow}
|
|
94
98
|
<div class="inline-panel" style="height: {inlineRowHeight ?? 0}px"> </div>
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type ActionsColumn from "../lib/ActionsColumn";
|
|
2
2
|
import type TableRow from "./TableRow";
|
|
3
3
|
import type { VirtualWindow } from "../lib/virtualWindow";
|
|
4
|
+
import type { RowEventHandlers } from "../lib/RowExpansion";
|
|
4
5
|
interface Props {
|
|
5
6
|
actionsColumn: ActionsColumn;
|
|
6
7
|
scrollTop?: number;
|
|
@@ -13,6 +14,7 @@ interface Props {
|
|
|
13
14
|
vwindow?: VirtualWindow | null;
|
|
14
15
|
/** 与数据区的合计行对齐(操作列这一格留空) */
|
|
15
16
|
showSummary?: boolean;
|
|
17
|
+
rowEvents?: RowEventHandlers<TableRow> | null;
|
|
16
18
|
}
|
|
17
19
|
declare const ActionsPanel: import("svelte").Component<Props, {}, "scrollTop">;
|
|
18
20
|
type ActionsPanel = ReturnType<typeof ActionsPanel>;
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
import { onDestroy, onMount, tick } from "svelte";
|
|
6
6
|
import utils from "../../overlay/common/utils";
|
|
7
7
|
import PopupMenu from "./PopupMenu.svelte";
|
|
8
|
+
import { onRowExpandRequest, type RowEventHandlers } from "../lib/RowExpansion";
|
|
8
9
|
|
|
9
10
|
interface Props {
|
|
10
11
|
row: TableRow;
|
|
@@ -14,9 +15,10 @@
|
|
|
14
15
|
width: number;
|
|
15
16
|
rowHeight?: number;
|
|
16
17
|
align?: 'left' | 'center';
|
|
18
|
+
rowEvents?: RowEventHandlers<TableRow> | null;
|
|
17
19
|
}
|
|
18
20
|
|
|
19
|
-
let { row, actions, alternative, parentRect, width, rowHeight, align }: Props = $props();
|
|
21
|
+
let { row, actions, alternative, parentRect, width, rowHeight, align, rowEvents = null }: Props = $props();
|
|
20
22
|
|
|
21
23
|
let actionList = $state<Array<RowAction>>([]);
|
|
22
24
|
let popupList = $state<Array<RowAction>>([]);
|
|
@@ -82,10 +84,15 @@
|
|
|
82
84
|
let style = $derived(rowHeight == null ? '' : `height: ${rowHeight}px`);
|
|
83
85
|
</script>
|
|
84
86
|
|
|
87
|
+
<!-- 行级单击 / 双击展开是鼠标快捷方式;键盘用户通过指示列图标(可聚焦)操作 -->
|
|
88
|
+
<!-- svelte-ignore a11y_click_events_have_key_events, a11y_no_static_element_interactions -->
|
|
85
89
|
<div
|
|
86
90
|
class="data-row"
|
|
87
91
|
class:alternative
|
|
88
92
|
style="position: relative; display: block; padding: 0 4px; width: {width}px; {style}"
|
|
93
|
+
onclick={(e) => rowEvents?.onRowClick(row, e)}
|
|
94
|
+
ondblclick={(e) => rowEvents?.onRowDblClick(row, e)}
|
|
95
|
+
use:onRowExpandRequest={(e) => rowEvents?.onExpandRequest(row, e)}
|
|
89
96
|
>
|
|
90
97
|
<div class="action-cell" bind:this={cell} style={align == 'center' ? 'margin: 0 auto' : ''}>
|
|
91
98
|
{#each actionList as action (action)}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type RowAction from "../lib/RowAction";
|
|
2
2
|
import type TableRow from "./TableRow";
|
|
3
|
+
import { type RowEventHandlers } from "../lib/RowExpansion";
|
|
3
4
|
interface Props {
|
|
4
5
|
row: TableRow;
|
|
5
6
|
actions: Array<RowAction>;
|
|
@@ -8,6 +9,7 @@ interface Props {
|
|
|
8
9
|
width: number;
|
|
9
10
|
rowHeight?: number;
|
|
10
11
|
align?: 'left' | 'center';
|
|
12
|
+
rowEvents?: RowEventHandlers<TableRow> | null;
|
|
11
13
|
}
|
|
12
14
|
declare const ActionsRow: import("svelte").Component<Props, {}, "">;
|
|
13
15
|
type ActionsRow = ReturnType<typeof ActionsRow>;
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
import { OrderDirection } from "../lib/OrderDirection";
|
|
9
9
|
import type { GetRowFontStyle } from "../../types";
|
|
10
10
|
import type { VirtualWindow } from "../lib/virtualWindow";
|
|
11
|
+
import { onRowExpandRequest, type RowEventHandlers, type RowExpandContext } from "../lib/RowExpansion";
|
|
11
12
|
|
|
12
13
|
interface Props {
|
|
13
14
|
columns: Array<DataColumn>;
|
|
@@ -35,6 +36,9 @@
|
|
|
35
36
|
viewportHeight?: number;
|
|
36
37
|
/** 合计行各列文字;null 不显示 */
|
|
37
38
|
summary?: Array<string> | null;
|
|
39
|
+
/** 传给展开区组件的上下文(collapse / actions) */
|
|
40
|
+
expandContext?: RowExpandContext | null;
|
|
41
|
+
rowEvents?: RowEventHandlers<TableRow> | null;
|
|
38
42
|
}
|
|
39
43
|
|
|
40
44
|
let {
|
|
@@ -60,6 +64,8 @@
|
|
|
60
64
|
vwindow = null,
|
|
61
65
|
viewportHeight = $bindable(0),
|
|
62
66
|
summary = null,
|
|
67
|
+
expandContext = null,
|
|
68
|
+
rowEvents = null,
|
|
63
69
|
}: Props = $props();
|
|
64
70
|
|
|
65
71
|
let scrollLeft = $state(0);
|
|
@@ -172,6 +178,7 @@
|
|
|
172
178
|
{row}
|
|
173
179
|
{columns}
|
|
174
180
|
alternative={idx % 2 == 1}
|
|
181
|
+
{rowEvents}
|
|
175
182
|
/>
|
|
176
183
|
{#if row == expandRow && inlineComponent}
|
|
177
184
|
{@const InlineComp = inlineComponent}
|
|
@@ -179,9 +186,10 @@
|
|
|
179
186
|
class="expand-data-row"
|
|
180
187
|
bind:clientHeight={inlineRowHeight}
|
|
181
188
|
style="position: relative; box-sizing: content-box; width: 100%; height: auto"
|
|
189
|
+
use:onRowExpandRequest={(e) => rowEvents?.onExpandRequest(row, e)}
|
|
182
190
|
>
|
|
183
191
|
<div class="inline-panel">
|
|
184
|
-
<InlineComp data={row.data} />
|
|
192
|
+
<InlineComp data={row.data} context={expandContext} />
|
|
185
193
|
</div>
|
|
186
194
|
</div>
|
|
187
195
|
{/if}
|
|
@@ -4,6 +4,7 @@ import UniDataTable, { type OnWidthChange } from "../UniDataTable";
|
|
|
4
4
|
import { OrderDirection } from "../lib/OrderDirection";
|
|
5
5
|
import type { GetRowFontStyle } from "../../types";
|
|
6
6
|
import type { VirtualWindow } from "../lib/virtualWindow";
|
|
7
|
+
import { type RowEventHandlers, type RowExpandContext } from "../lib/RowExpansion";
|
|
7
8
|
interface Props {
|
|
8
9
|
columns: Array<DataColumn>;
|
|
9
10
|
rows: Array<TableRow>;
|
|
@@ -30,6 +31,9 @@ interface Props {
|
|
|
30
31
|
viewportHeight?: number;
|
|
31
32
|
/** 合计行各列文字;null 不显示 */
|
|
32
33
|
summary?: Array<string> | null;
|
|
34
|
+
/** 传给展开区组件的上下文(collapse / actions) */
|
|
35
|
+
expandContext?: RowExpandContext | null;
|
|
36
|
+
rowEvents?: RowEventHandlers<TableRow> | null;
|
|
33
37
|
}
|
|
34
38
|
declare const ContentPanel: import("svelte").Component<Props, {}, "scrollTop" | "viewportHeight" | "rows" | "inlineRowHeight" | "tabWidth">;
|
|
35
39
|
type ContentPanel = ReturnType<typeof ContentPanel>;
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
import DataCell from "./DataCell.svelte";
|
|
4
4
|
import type TableRow from "./TableRow";
|
|
5
5
|
import type { RowFontStyle } from "../../types";
|
|
6
|
+
import { onRowExpandRequest, type RowEventHandlers } from "../lib/RowExpansion";
|
|
6
7
|
|
|
7
8
|
interface Props {
|
|
8
9
|
columns: Array<DataColumn>;
|
|
@@ -10,9 +11,10 @@
|
|
|
10
11
|
alternative: boolean;
|
|
11
12
|
rowHeight?: number;
|
|
12
13
|
fontStyle?: RowFontStyle;
|
|
14
|
+
rowEvents?: RowEventHandlers<TableRow> | null;
|
|
13
15
|
}
|
|
14
16
|
|
|
15
|
-
let { columns, row, alternative, rowHeight, fontStyle }: Props = $props();
|
|
17
|
+
let { columns, row, alternative, rowHeight, fontStyle, rowEvents = null }: Props = $props();
|
|
16
18
|
|
|
17
19
|
const getRowStyle = (rh: number | undefined, fs: RowFontStyle | undefined): string => {
|
|
18
20
|
let rs = '';
|
|
@@ -34,7 +36,16 @@
|
|
|
34
36
|
let style = $derived(getRowStyle(rowHeight, fontStyle));
|
|
35
37
|
</script>
|
|
36
38
|
|
|
37
|
-
|
|
39
|
+
<!-- 行级单击 / 双击展开是鼠标快捷方式;键盘用户通过指示列图标(可聚焦)操作。本元素 aria-hidden,无需 a11y 忽略 -->
|
|
40
|
+
<div
|
|
41
|
+
class="data-row"
|
|
42
|
+
{style}
|
|
43
|
+
class:alternative
|
|
44
|
+
aria-hidden="true"
|
|
45
|
+
onclick={(e) => rowEvents?.onRowClick(row, e)}
|
|
46
|
+
ondblclick={(e) => rowEvents?.onRowDblClick(row, e)}
|
|
47
|
+
use:onRowExpandRequest={(e) => rowEvents?.onExpandRequest(row, e)}
|
|
48
|
+
>
|
|
38
49
|
{#each columns as col, idx (idx)}
|
|
39
50
|
<DataCell colIdx={idx} data={row.data} column={col} />
|
|
40
51
|
{/each}
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import type DataColumn from "../lib/DataColumn";
|
|
2
2
|
import type TableRow from "./TableRow";
|
|
3
3
|
import type { RowFontStyle } from "../../types";
|
|
4
|
+
import { type RowEventHandlers } from "../lib/RowExpansion";
|
|
4
5
|
interface Props {
|
|
5
6
|
columns: Array<DataColumn>;
|
|
6
7
|
row: TableRow;
|
|
7
8
|
alternative: boolean;
|
|
8
9
|
rowHeight?: number;
|
|
9
10
|
fontStyle?: RowFontStyle;
|
|
11
|
+
rowEvents?: RowEventHandlers<TableRow> | null;
|
|
10
12
|
}
|
|
11
13
|
declare const DataRow: import("svelte").Component<Props, {}, "">;
|
|
12
14
|
type DataRow = ReturnType<typeof DataRow>;
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
import { OrderDirection } from "../lib/OrderDirection";
|
|
13
13
|
import type { VirtualWindow } from "../lib/virtualWindow";
|
|
14
14
|
import type { TableSummary } from "../lib/summary";
|
|
15
|
+
import type { RowEventHandlers, IsRowExpandable } from "../lib/RowExpansion";
|
|
15
16
|
|
|
16
17
|
interface Props {
|
|
17
18
|
fixedCols?: Array<DataColumn>;
|
|
@@ -33,6 +34,10 @@
|
|
|
33
34
|
vwindow?: VirtualWindow | null;
|
|
34
35
|
/** 合计行;null 不显示 */
|
|
35
36
|
summary?: TableSummary | null;
|
|
37
|
+
/** 是否在指示列显示展开 / 收起图标(由 DataTable 根据 rowExpansion 决定) */
|
|
38
|
+
expandable?: boolean;
|
|
39
|
+
isExpandable?: IsRowExpandable<TableRow>;
|
|
40
|
+
rowEvents?: RowEventHandlers<TableRow> | null;
|
|
36
41
|
}
|
|
37
42
|
|
|
38
43
|
let {
|
|
@@ -47,12 +52,15 @@
|
|
|
47
52
|
orderColumn,
|
|
48
53
|
orderDirection,
|
|
49
54
|
selectedRows = $bindable([]),
|
|
50
|
-
expandRow =
|
|
55
|
+
expandRow = null,
|
|
51
56
|
rowHeight,
|
|
52
57
|
headerHeight,
|
|
53
58
|
inlineRowHeight = 0,
|
|
54
59
|
vwindow = null,
|
|
55
60
|
summary = null,
|
|
61
|
+
expandable = false,
|
|
62
|
+
isExpandable = () => true,
|
|
63
|
+
rowEvents = null,
|
|
56
64
|
}: Props = $props();
|
|
57
65
|
|
|
58
66
|
// Virtual scrolling: same shared window as the other panels, so all three
|
|
@@ -63,7 +71,6 @@
|
|
|
63
71
|
let selectionMode = $state<SelectionMode>(SelectionMode.None);
|
|
64
72
|
|
|
65
73
|
let selectable = $derived(indicatorColumn?.selectable == true);
|
|
66
|
-
let expandable = $derived(indicatorColumn?.buildInlineComponent != null);
|
|
67
74
|
|
|
68
75
|
// Track selected indices internally to avoid $state proxy identity issues
|
|
69
76
|
let selectedIndices = $state<Set<number>>(new Set());
|
|
@@ -162,6 +169,8 @@
|
|
|
162
169
|
{expandRow}
|
|
163
170
|
{rowHeight}
|
|
164
171
|
{expandable}
|
|
172
|
+
{isExpandable}
|
|
173
|
+
{rowEvents}
|
|
165
174
|
{onRowExpand}
|
|
166
175
|
{onRowSelectChange}
|
|
167
176
|
{indicatorColumn}
|
|
@@ -5,6 +5,7 @@ import type DataColumn from "../lib/DataColumn";
|
|
|
5
5
|
import { OrderDirection } from "../lib/OrderDirection";
|
|
6
6
|
import type { VirtualWindow } from "../lib/virtualWindow";
|
|
7
7
|
import type { TableSummary } from "../lib/summary";
|
|
8
|
+
import type { RowEventHandlers, IsRowExpandable } from "../lib/RowExpansion";
|
|
8
9
|
interface Props {
|
|
9
10
|
fixedCols?: Array<DataColumn>;
|
|
10
11
|
indicatorColumn?: IndicatorColumn | null;
|
|
@@ -25,7 +26,11 @@ interface Props {
|
|
|
25
26
|
vwindow?: VirtualWindow | null;
|
|
26
27
|
/** 合计行;null 不显示 */
|
|
27
28
|
summary?: TableSummary | null;
|
|
29
|
+
/** 是否在指示列显示展开 / 收起图标(由 DataTable 根据 rowExpansion 决定) */
|
|
30
|
+
expandable?: boolean;
|
|
31
|
+
isExpandable?: IsRowExpandable<TableRow>;
|
|
32
|
+
rowEvents?: RowEventHandlers<TableRow> | null;
|
|
28
33
|
}
|
|
29
|
-
declare const FixedColumnsPanel: import("svelte").Component<Props, {}, "scrollTop" | "
|
|
34
|
+
declare const FixedColumnsPanel: import("svelte").Component<Props, {}, "scrollTop" | "selectedRows">;
|
|
30
35
|
type FixedColumnsPanel = ReturnType<typeof FixedColumnsPanel>;
|
|
31
36
|
export default FixedColumnsPanel;
|