@ticatec/topside-elements 1.0.1 → 1.0.3

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 CHANGED
@@ -1,5 +1,13 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.0.3
4
+
5
+ ### 变更
6
+ - **Split 分割线外观**:线条默认 1px(`width`,原 2px);新增 `hitSize`(不占布局的感应区,默认 8px,靠近即可悬停 / 拖动)、`color`、`gripColor`、`gripSize`、`gripLength`;悬停 / 拖动 / 键盘聚焦时中间淡入深色稍粗的把手,取代原来整条加深。新令牌 `--topside-divider-grip-color`(亮 `#94A3B8` / 暗 `#8a8a8a`)。
7
+
8
+ ### 文档
9
+ - 重新生成 `docs/components`(Split、DataTable / ConciseDataTable 合计行相关属性)。
10
+
3
11
  ## 1.0.0 — 首个公开版本
4
12
 
5
13
  ### 新增
@@ -13,6 +13,7 @@
13
13
  import type { GetRowFontStyle } from "../types";
14
14
  import { computeVirtualWindow } from "./lib/virtualWindow";
15
15
  import { buildTableSummary } from "./lib/summary";
16
+ import { isSameColumn } from "./lib/TableUtils";
16
17
  import i18nRes from "../i18nRes";
17
18
 
18
19
  interface Props {
@@ -170,7 +171,7 @@
170
171
 
171
172
  const onCellClick = (col: DataColumn) => {
172
173
  if (col.compareFunction != null) {
173
- if (col.field === orderColumn?.field) {
174
+ if (isSameColumn(col, orderColumn)) {
174
175
  orderDirection = orderDirection == OrderDirection.Ascending
175
176
  ? OrderDirection.Descending
176
177
  : OrderDirection.Ascending;
@@ -200,7 +201,7 @@
200
201
  {onRowExpand}
201
202
  bind:selectedRows
202
203
  {orderDirection}
203
- orderColumn={orderColumn as DataColumn}
204
+ {orderColumn}
204
205
  {onCellClick}
205
206
  {indicatorColumn}
206
207
  bind:expandRow
@@ -220,7 +221,7 @@
220
221
  <ContentPanel
221
222
  columns={dataColumns}
222
223
  {orderDirection}
223
- orderColumn={orderColumn as DataColumn}
224
+ {orderColumn}
224
225
  {onWidthChange}
225
226
  {onCellClick}
226
227
  {tabWidth}
@@ -73,7 +73,7 @@ interface DataColumn {
73
73
  escapeHTML?: boolean; // Whether to escape HTML in content
74
74
  href?: HrefBuilder; // Link builder function
75
75
  hint?: CellHint; // Tooltip/hint function
76
- render?: any; // Custom Svelte component renderer
76
+ render?: ColumnRender; // Custom Svelte component renderer (component or { component, props })
77
77
  visible?: boolean; // Column visibility
78
78
  resizable?: boolean; // Whether column is resizable
79
79
  compareFunction?: CompareFunction; // Sorting comparison function
@@ -82,6 +82,41 @@ interface DataColumn {
82
82
  }
83
83
  ```
84
84
 
85
+ ### ColumnRender
86
+
87
+ ```typescript
88
+ type ColumnRender<Props extends Record<string, any> = Record<string, any>> =
89
+ | Component<any>
90
+ | ColumnRenderObject<Props>;
91
+
92
+ interface ColumnRenderObject<Props extends Record<string, any> = Record<string, any>> {
93
+ component: Component<any>; // Svelte 5 component
94
+ props?: Props; // Extra props passed to component (component also receives row `data`)
95
+ }
96
+ ```
97
+
98
+ ### ActionCell and CellAction
99
+
100
+ `ActionCell` is a built-in single button action cell component that can be placed in any column (unlike `actionsColumn`, which is docked at the end of the table):
101
+
102
+ ```typescript
103
+ interface CellAction<T = any> {
104
+ label: string; // Button text
105
+ type?: ButtonType; // Semantic style ('primary', 'secondary', etc.)
106
+ icon?: string; // Optional icon
107
+ tooltip?: string; // Hover tooltip
108
+ disabled?: boolean; // Disabled state
109
+ handler: (data: T) => void | Promise<void>; // Click handler
110
+ }
111
+
112
+ type GetCellAction<T = any> = (data: T) => CellAction<T> | undefined;
113
+
114
+ interface ActionCellProps<T = any> {
115
+ data?: T; // Injected automatically by DataTable
116
+ getAction: GetCellAction<T>; // Returns action definition; returning undefined hides the button
117
+ }
118
+ ```
119
+
85
120
  ### ActionsColumn
86
121
 
87
122
  ```typescript
@@ -320,6 +355,129 @@ interface RowAction {
320
355
  <DataTable {columns} list={userData} rowHeight={50} />
321
356
  ```
322
357
 
358
+ ### Custom Cell Rendering with render (Custom Components & ActionCell)
359
+
360
+ `DataColumn.render` supports two ways to render custom cell content:
361
+ 1. **Pass a Svelte component directly**: The component automatically receives the current row data `{ data }`.
362
+ 2. **Pass a `{ component, props }` configuration object**: The component receives all specified `props` along with `{ data }`.
363
+
364
+ #### 1. Creating and Using Custom Components
365
+
366
+ For example, a status badge component `StatusBadge.svelte`:
367
+
368
+ ```svelte
369
+ <!-- StatusBadge.svelte -->
370
+ <script lang="ts">
371
+ interface Props {
372
+ data: any; // Row data injected automatically by DataTable
373
+ theme?: string; // Custom prop passed from column definition
374
+ }
375
+
376
+ let { data, theme = "info" }: Props = $props();
377
+ </script>
378
+
379
+ <span class="status-badge {theme}">
380
+ {data.statusName ?? data.status}
381
+ </span>
382
+ ```
383
+
384
+ Using the custom component in column definitions:
385
+
386
+ ```svelte
387
+ <script>
388
+ import DataTable from "@ticatec/topside-elements/data_table";
389
+ import UserAvatar from "./UserAvatar.svelte";
390
+ import StatusBadge from "./StatusBadge.svelte";
391
+
392
+ const columns = [
393
+ // Method 1: Component directly
394
+ {
395
+ title: "Avatar",
396
+ width: 70,
397
+ render: UserAvatar
398
+ },
399
+ // Method 2: Configuration object with extra props
400
+ {
401
+ title: "Status",
402
+ width: 120,
403
+ render: {
404
+ component: StatusBadge,
405
+ props: { theme: "success" }
406
+ }
407
+ }
408
+ ];
409
+ </script>
410
+ ```
411
+
412
+ #### 2. Using Built-in ActionCell for Action Columns
413
+
414
+ `ActionCell` allows rendering single button actions in any column position with full dynamic control over label, style, and visibility based on row data:
415
+
416
+ ```svelte
417
+ <script>
418
+ import DataTable, { ActionCell } from "@ticatec/topside-elements/data_table";
419
+
420
+ const columns = [
421
+ {
422
+ title: "Service Code",
423
+ field: "code",
424
+ width: 150
425
+ },
426
+ {
427
+ title: "Service Name",
428
+ field: "name",
429
+ width: 200
430
+ },
431
+ {
432
+ title: "Modules",
433
+ width: 100,
434
+ render: {
435
+ component: ActionCell,
436
+ props: {
437
+ getAction: (row) => ({
438
+ label: "Manage",
439
+ handler: (data) => openModules(data)
440
+ })
441
+ }
442
+ }
443
+ },
444
+ {
445
+ title: "Status Action",
446
+ width: 100,
447
+ render: {
448
+ component: ActionCell,
449
+ props: {
450
+ getAction: (row) => {
451
+ // Return undefined to hide the action button
452
+ if (row.locked) return undefined;
453
+ return {
454
+ label: row.enabled ? "Disable" : "Enable",
455
+ type: row.enabled ? "danger" : "primary",
456
+ handler: (data) => toggleService(data)
457
+ };
458
+ }
459
+ }
460
+ }
461
+ }
462
+ ];
463
+
464
+ const list = [
465
+ { code: "AUTH", name: "Auth Service", enabled: true, locked: false },
466
+ { code: "SYS", name: "Core Kernel", enabled: true, locked: true }
467
+ ];
468
+
469
+ function openModules(item) {
470
+ console.log("Manage modules:", item.code);
471
+ }
472
+
473
+ function toggleService(item) {
474
+ console.log("Toggle status:", item.code);
475
+ }
476
+ </script>
477
+
478
+ <DataTable {columns} {list} />
479
+ ```
480
+
323
481
  ### Table with Inline Row Expansion
324
482
 
325
483
  ```svelte
@@ -73,7 +73,7 @@ interface DataColumn {
73
73
  escapeHTML?: boolean; // 是否转义 HTML 内容
74
74
  href?: HrefBuilder; // 链接生成函数
75
75
  hint?: CellHint; // 工具提示/提示函数
76
- render?: any; // 自定义 Svelte 组件渲染器
76
+ render?: ColumnRender; // 自定义 Svelte 组件渲染器(可为组件或 { component, props } 配置对象)
77
77
  visible?: boolean; // 列可见性
78
78
  resizable?: boolean; // 列是否可调整大小
79
79
  compareFunction?: CompareFunction; // 排序比较函数
@@ -82,6 +82,41 @@ interface DataColumn {
82
82
  }
83
83
  ```
84
84
 
85
+ ### ColumnRender
86
+
87
+ ```typescript
88
+ type ColumnRender<Props extends Record<string, any> = Record<string, any>> =
89
+ | Component<any>
90
+ | ColumnRenderObject<Props>;
91
+
92
+ interface ColumnRenderObject<Props extends Record<string, any> = Record<string, any>> {
93
+ component: Component<any>; // Svelte 5 组件
94
+ props?: Props; // 传递给组件的额外属性(组件会自动接收当前行数据 `data`)
95
+ }
96
+ ```
97
+
98
+ ### ActionCell 与 CellAction
99
+
100
+ `ActionCell` 是预置的单元格操作按钮组件,可在任意列中使用(不受 `actionsColumn` 只能固定在最右侧的限制):
101
+
102
+ ```typescript
103
+ interface CellAction<T = any> {
104
+ label: string; // 按钮显示文本
105
+ type?: ButtonType; // 语义样式(如 'primary' | 'secondary' 等)
106
+ icon?: string; // 前缀图标
107
+ tooltip?: string; // 悬停提示
108
+ disabled?: boolean; // 是否禁用
109
+ handler: (data: T) => void | Promise<void>; // 点击回调函数
110
+ }
111
+
112
+ type GetCellAction<T = any> = (data: T) => CellAction<T> | undefined;
113
+
114
+ interface ActionCellProps<T = any> {
115
+ data?: T; // 自动由 DataTable 注入当前行数据
116
+ getAction: GetCellAction<T>; // 返回该单元格操作,返回 undefined 则不显示按钮
117
+ }
118
+ ```
119
+
85
120
  ### ActionsColumn
86
121
 
87
122
  ```typescript
@@ -320,6 +355,129 @@ interface RowAction {
320
355
  <DataTable {columns} list={userData} rowHeight={50} />
321
356
  ```
322
357
 
358
+ ### 使用 render 自定义单元格(自定义组件与 ActionCell)
359
+
360
+ `DataColumn.render` 支持两种方式自定义单元格内容:
361
+ 1. **直接传入自定义 Svelte 组件**:组件将自动接收当前行的数据 `{ data }`。
362
+ 2. **传入 `{ component, props }` 配置对象**:组件接收 `props` 中的所有自定义属性,同时自动注入 `{ data }`。
363
+
364
+ #### 1. 编写与使用自定义组件
365
+
366
+ 例如定义一个状态徽标组件 `StatusBadge.svelte`:
367
+
368
+ ```svelte
369
+ <!-- StatusBadge.svelte -->
370
+ <script lang="ts">
371
+ interface Props {
372
+ data: any; // DataTable 自动注入的当前行数据
373
+ theme?: string; // 通过 props 传入的自定义属性
374
+ }
375
+
376
+ let { data, theme = "info" }: Props = $props();
377
+ </script>
378
+
379
+ <span class="status-badge {theme}">
380
+ {data.statusName ?? data.status}
381
+ </span>
382
+ ```
383
+
384
+ 在表格列中使用自定义组件:
385
+
386
+ ```svelte
387
+ <script>
388
+ import DataTable from "@ticatec/topside-elements/data_table";
389
+ import UserAvatar from "./UserAvatar.svelte";
390
+ import StatusBadge from "./StatusBadge.svelte";
391
+
392
+ const columns = [
393
+ // 方式一:直接传入组件
394
+ {
395
+ title: "头像",
396
+ width: 70,
397
+ render: UserAvatar
398
+ },
399
+ // 方式二:传入配置对象(可附带额外 props)
400
+ {
401
+ title: "状态",
402
+ width: 120,
403
+ render: {
404
+ component: StatusBadge,
405
+ props: { theme: "success" }
406
+ }
407
+ }
408
+ ];
409
+ </script>
410
+ ```
411
+
412
+ #### 2. 使用内置 ActionCell 渲染操作列
413
+
414
+ `ActionCell` 是预置的操作按钮组件,可在任意列中渲染单按钮操作,支持基于行数据动态设置按钮文本、类型,或通过返回 `undefined` 条件隐藏按钮:
415
+
416
+ ```svelte
417
+ <script>
418
+ import DataTable, { ActionCell } from "@ticatec/topside-elements/data_table";
419
+
420
+ const columns = [
421
+ {
422
+ title: "服务编码",
423
+ field: "code",
424
+ width: 150
425
+ },
426
+ {
427
+ title: "服务名称",
428
+ field: "name",
429
+ width: 200
430
+ },
431
+ {
432
+ title: "模块管理",
433
+ width: 100,
434
+ render: {
435
+ component: ActionCell,
436
+ props: {
437
+ getAction: (row) => ({
438
+ label: "管理",
439
+ handler: (data) => openModules(data)
440
+ })
441
+ }
442
+ }
443
+ },
444
+ {
445
+ title: "状态操作",
446
+ width: 100,
447
+ render: {
448
+ component: ActionCell,
449
+ props: {
450
+ getAction: (row) => {
451
+ // 返回 undefined 时不渲染按钮
452
+ if (row.locked) return undefined;
453
+ return {
454
+ label: row.enabled ? "禁用" : "启用",
455
+ type: row.enabled ? "danger" : "primary",
456
+ handler: (data) => toggleStatus(data)
457
+ };
458
+ }
459
+ }
460
+ }
461
+ }
462
+ ];
463
+
464
+ const list = [
465
+ { code: "AUTH", name: "认证服务", enabled: true, locked: false },
466
+ { code: "SYS", name: "系统内核", enabled: true, locked: true }
467
+ ];
468
+
469
+ function openModules(item) {
470
+ console.log("管理服务模块:", item.code);
471
+ }
472
+
473
+ function toggleStatus(item) {
474
+ console.log("切换服务状态:", item.code);
475
+ }
476
+ </script>
477
+
478
+ <DataTable {columns} {list} />
479
+ ```
480
+
323
481
  ### 带有内联行扩展的表格
324
482
 
325
483
  ```svelte
@@ -5,11 +5,11 @@ import type IndicatorColumn from "./lib/IndicatorColumn";
5
5
  import type RowAction from "./lib/RowAction";
6
6
  import type { GetRowActions, ActionHandler } from "./lib/RowAction";
7
7
  import type DataColumn from "./lib/DataColumn";
8
- import type { SummaryKind, SummaryFn } from "./lib/DataColumn";
9
- import type { CellAction } from "./lib/CellAction";
8
+ import type { SummaryKind, SummaryFn, ColumnRender, ColumnRenderObject } from "./lib/DataColumn";
9
+ import type { CellAction, GetCellAction, ActionCellProps } from "./lib/CellAction";
10
10
  import ActionCell from "./parts/ActionCell.svelte";
11
11
  export default DataTable;
12
12
  export { ActionCell };
13
- export type { ActionsColumn, IndicatorColumn, FormatCellFn, CellHint, DataColumn };
14
- export type { RowAction, GetRowActions, ActionHandler, CellAction };
13
+ export type { ActionsColumn, IndicatorColumn, FormatCellFn, CellHint, DataColumn, ColumnRender, ColumnRenderObject };
14
+ export type { RowAction, GetRowActions, ActionHandler, CellAction, GetCellAction, ActionCellProps };
15
15
  export type { SummaryKind, SummaryFn };
@@ -7,3 +7,10 @@ export type CellAction<T = any> = RowAction<T>;
7
7
  * 获取单元格动作;返回 undefined 表示该单元格没有动作
8
8
  */
9
9
  export type GetCellAction<T = any> = (data: T) => CellAction<T> | undefined;
10
+ /**
11
+ * ActionCell 组件的属性类型
12
+ */
13
+ export interface ActionCellProps<T = any> {
14
+ data?: T;
15
+ getAction: GetCellAction<T>;
16
+ }
@@ -2,10 +2,29 @@ import type { CellHint, FormatCellFn } from "./FormatCellFn";
2
2
  import type { HrefBuilder } from "./HrefLink";
3
3
  import type { CompareFn } from "./CompareFn";
4
4
  import type { GetCellStyle } from "../../types";
5
+ import type { Component } from "svelte";
5
6
  /** 内置聚合方式;'label' 表示该列在合计行里显示合计标签("合计") */
6
7
  export type SummaryKind = 'sum' | 'avg' | 'count' | 'min' | 'max';
7
8
  /** 自定义聚合:values 为本列各行的字段值,rows 为当前全部行数据 */
8
9
  export type SummaryFn = (values: Array<any>, rows: Array<any>) => any;
10
+ /**
11
+ * 自定义单元格渲染器对象配置
12
+ */
13
+ export interface ColumnRenderObject<Props extends Record<string, any> = Record<string, any>> {
14
+ /**
15
+ * 自定义 Svelte 单元格组件。
16
+ * 组件会接收 `props` 中传入的属性,并自动接收当前行的数据 `data`。
17
+ */
18
+ component: Component<any>;
19
+ /**
20
+ * 传递给自定义组件的额外属性
21
+ */
22
+ props?: Props;
23
+ }
24
+ /**
25
+ * 自定义单元格渲染器:支持直接传入 Svelte 组件,或传入包含 { component, props } 的配置对象
26
+ */
27
+ export type ColumnRender<Props extends Record<string, any> = Record<string, any>> = Component<any> | ColumnRenderObject<Props>;
9
28
  export default interface DataColumn {
10
29
  /**
11
30
  * 列头文字(与 ConciseListTable 的 Column.title 统一)
@@ -50,9 +69,9 @@ export default interface DataColumn {
50
69
  */
51
70
  hint?: CellHint;
52
71
  /**
53
- * 渲染器
72
+ * 自定义单元格渲染器(可为 Svelte 组件或 `{ component, props }` 配置对象)
54
73
  */
55
- render?: any;
74
+ render?: ColumnRender;
56
75
  /**
57
76
  *
58
77
  */
@@ -1,4 +1,13 @@
1
+ import type DataColumn from "./DataColumn";
2
+ /**
3
+ * 根据字段名获取对于的值,支持"."嵌套获取
4
+ * @param data
5
+ * @param field
6
+ */
7
+ export declare const extractFieldValue: (data: any, field?: string) => any;
8
+ export declare const isSameColumn: (a?: DataColumn | null, b?: DataColumn | null) => boolean;
1
9
  declare const _default: {
2
10
  extractFieldValue: (data: any, field?: string) => any;
11
+ isSameColumn: (a?: DataColumn | null, b?: DataColumn | null) => boolean;
3
12
  };
4
13
  export default _default;
@@ -3,7 +3,7 @@
3
3
  * @param data
4
4
  * @param field
5
5
  */
6
- const extractFieldValue = (data, field) => {
6
+ export const extractFieldValue = (data, field) => {
7
7
  let v = data;
8
8
  if (field != null) {
9
9
  let attrs = field.split(".");
@@ -13,6 +13,14 @@ const extractFieldValue = (data, field) => {
13
13
  }
14
14
  return v;
15
15
  };
16
+ export const isSameColumn = (a, b) => {
17
+ if (!a || !b)
18
+ return false;
19
+ if (a === b)
20
+ return true;
21
+ return a.field != null && b.field != null && a.field === b.field;
22
+ };
16
23
  export default {
17
- extractFieldValue
24
+ extractFieldValue,
25
+ isSameColumn
18
26
  };
@@ -17,7 +17,7 @@
17
17
  </script>
18
18
 
19
19
  {#if action}
20
- <div style="width: 100; overflow: hidden;">
20
+ <div style="width: 100%; overflow: hidden;">
21
21
  <TextButton type={action.type ?? 'primary'} outer={false} label={action.label} onclick={handleClick} />
22
22
  </div>
23
23
  {/if}
@@ -12,7 +12,7 @@
12
12
  interface Props {
13
13
  columns: Array<DataColumn>;
14
14
  rows: Array<TableRow>;
15
- orderColumn: DataColumn;
15
+ orderColumn?: DataColumn | null;
16
16
  orderDirection: OrderDirection;
17
17
  getRowFontStyle?: GetRowFontStyle;
18
18
  emptyText?: string | null;
@@ -7,7 +7,7 @@ import type { VirtualWindow } from "../lib/virtualWindow";
7
7
  interface Props {
8
8
  columns: Array<DataColumn>;
9
9
  rows: Array<TableRow>;
10
- orderColumn: DataColumn;
10
+ orderColumn?: DataColumn | null;
11
11
  orderDirection: OrderDirection;
12
12
  getRowFontStyle?: GetRowFontStyle;
13
13
  emptyText?: string | null;
@@ -22,8 +22,15 @@
22
22
  <div class="data-cell {colClass}" {style} bind:this={cell}>
23
23
  <div class="vertical-center">
24
24
  {#if column.render}
25
- {@const Render = column.render.component}
26
- <Render {...column.render.props} {data} />
25
+ {@const Render = typeof column.render === 'object' && column.render !== null && 'component' in column.render
26
+ ? column.render.component
27
+ : column.render}
28
+ {@const renderProps = typeof column.render === 'object' && column.render !== null && 'props' in column.render
29
+ ? column.render.props
30
+ : undefined}
31
+ {#if Render}
32
+ <Render {...renderProps} {data} />
33
+ {/if}
27
34
  {:else if column.href}
28
35
  <HrefCell {data} href={column.href} />
29
36
  {:else}
@@ -22,7 +22,7 @@
22
22
  onWidthChange?: OnWidthChange;
23
23
  onRowExpand?: OnRowExpand;
24
24
  onCellClick?: (col: DataColumn) => any;
25
- orderColumn?: DataColumn;
25
+ orderColumn?: DataColumn | null;
26
26
  orderDirection?: OrderDirection;
27
27
  selectedRows?: Array<any>;
28
28
  expandRow?: TableRow | null;
@@ -14,7 +14,7 @@ interface Props {
14
14
  onWidthChange?: OnWidthChange;
15
15
  onRowExpand?: OnRowExpand;
16
16
  onCellClick?: (col: DataColumn) => any;
17
- orderColumn?: DataColumn;
17
+ orderColumn?: DataColumn | null;
18
18
  orderDirection?: OrderDirection;
19
19
  selectedRows?: Array<any>;
20
20
  expandRow?: TableRow | null;
@@ -3,6 +3,7 @@
3
3
  import type { IndicatorColumn } from "..";
4
4
  import { type OnSelectAll, SelectionMode, type OnWidthChange } from "../UniDataTable";
5
5
  import { OrderDirection } from "../lib/OrderDirection";
6
+ import { isSameColumn } from "../lib/TableUtils";
6
7
  import i18nRes from "../../i18nRes";
7
8
 
8
9
  interface Props {
@@ -12,7 +13,7 @@
12
13
  rowHeight?: number;
13
14
  headerHeight?: number;
14
15
  onCellClick?: (col: DataColumn) => any;
15
- orderColumn?: DataColumn;
16
+ orderColumn?: DataColumn | null;
16
17
  orderDirection?: OrderDirection;
17
18
  selectionMode?: SelectionMode;
18
19
  onToggleSelectAll?: OnSelectAll;
@@ -124,13 +125,13 @@
124
125
  onkeydown={handleHeaderKeyDown(column)}
125
126
  role={column.compareFunction != null ? 'button' : undefined}
126
127
  tabindex={column.compareFunction != null ? 0 : undefined}
127
- aria-sort={column.field === orderColumn?.field
128
+ aria-sort={isSameColumn(column, orderColumn)
128
129
  ? (orderDirection === OrderDirection.Ascending ? 'ascending' : 'descending')
129
130
  : undefined}
130
131
  class="vertical-center"
131
132
  >
132
133
  <span>{column.title}</span>
133
- {#if column.field === orderColumn?.field}
134
+ {#if isSameColumn(column, orderColumn)}
134
135
  <i
135
136
  style="margin-left: 2px; font-size: 12px; position: absolute; top: 0; right: 4px"
136
137
  class={orderDirection === OrderDirection.Ascending
@@ -9,7 +9,7 @@ interface Props {
9
9
  rowHeight?: number;
10
10
  headerHeight?: number;
11
11
  onCellClick?: (col: DataColumn) => any;
12
- orderColumn?: DataColumn;
12
+ orderColumn?: DataColumn | null;
13
13
  orderDirection?: OrderDirection;
14
14
  selectionMode?: SelectionMode;
15
15
  onToggleSelectAll?: OnSelectAll;
@@ -2,6 +2,7 @@
2
2
  import { OrderDirection } from "../lib/OrderDirection";
3
3
  import { type OnWidthChange } from "../UniDataTable";
4
4
  import type DataColumn from "../lib/DataColumn";
5
+ import { isSameColumn } from "../lib/TableUtils";
5
6
 
6
7
  interface Props {
7
8
  scrollLeft?: number;
@@ -10,7 +11,7 @@
10
11
  width?: number;
11
12
  whitespace?: boolean;
12
13
  onCellClick?: (col: DataColumn) => any;
13
- orderColumn?: DataColumn;
14
+ orderColumn?: DataColumn | null;
14
15
  orderDirection?: OrderDirection;
15
16
  headerHeight?: number;
16
17
  }
@@ -82,13 +83,13 @@
82
83
  onkeydown={handleHeaderKeyDown(col)}
83
84
  role={col.compareFunction != null ? 'button' : undefined}
84
85
  tabindex={col.compareFunction != null ? 0 : undefined}
85
- aria-sort={col.field === orderColumn?.field
86
+ aria-sort={isSameColumn(col, orderColumn)
86
87
  ? (orderDirection === OrderDirection.Ascending ? 'ascending' : 'descending')
87
88
  : undefined}
88
89
  class="vertical-center"
89
90
  >
90
91
  <span>{col.title}</span>
91
- {#if col.field === orderColumn?.field}
92
+ {#if isSameColumn(col, orderColumn)}
92
93
  <i
93
94
  style="margin-left: 2px; font-size: 12px; position: absolute; top: 0; right: 4px"
94
95
  class={orderDirection === OrderDirection.Ascending
@@ -8,7 +8,7 @@ interface Props {
8
8
  width?: number;
9
9
  whitespace?: boolean;
10
10
  onCellClick?: (col: DataColumn) => any;
11
- orderColumn?: DataColumn;
11
+ orderColumn?: DataColumn | null;
12
12
  orderDirection?: OrderDirection;
13
13
  headerHeight?: number;
14
14
  }