@canvas-components/list-table 0.3.15 → 0.3.16

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/README.md CHANGED
@@ -26,14 +26,69 @@
26
26
  显式传入 `pagination.pageSize` 时以受控值为准。外部负责请求的封装(如 WWISuperTable)应在首次请求前读取缓存,初始化自己的分页状态,避免只改变显示值而请求条数不一致:
27
27
 
28
28
  ```ts
29
- import { getListTableStoredPageSize } from '@canvas-components/list-table';
29
+ import { getListTableStoredPageSize } from "@canvas-components/list-table";
30
30
 
31
- const initialPageSize = explicitPageSize ?? getListTableStoredPageSize(storageKey) ?? 10;
31
+ const initialPageSize =
32
+ explicitPageSize ?? getListTableStoredPageSize(storageKey) ?? 10;
32
33
  // 将 initialPageSize 用于首次请求和受控 pagination.pageSize。
33
34
  ```
34
35
 
35
36
  该读取方法也由 `@canvas-components/react-list-table` 导出。
36
37
 
38
+ ## 分区 CSS 样式
39
+
40
+ 原生 `ListTable` 和 `ReactListTable` 均支持 `styles`。Canvas 区域通过 CSS 属性映射到绘制参数,不创建单元格 DOM,不注入全局样式。
41
+
42
+ ```ts
43
+ styles: {
44
+ cell: { fontSize: '14px', padding: '2px 12px', borderColor: '#d9e1ec' },
45
+ header: { backgroundColor: '#f0f9ff', color: '#075985', fontWeight: 700, textAlign: 'center' },
46
+ body: { color: '#334155' },
47
+ summary: { backgroundColor: '#f0fdf4', color: '#166534', textAlign: 'right' },
48
+ activeCell: { backgroundColor: '#fef3c7', borderColor: '#d97706', borderWidth: '2px' },
49
+ activeRow: { backgroundColor: '#e0e7ff', color: '#3730a3' },
50
+ scrollVertical: { width: '14px', color: '#94a3b8', backgroundColor: '#f1f5f9', borderRadius: 4 },
51
+ scrollHorizontal: { height: '12px', color: '#64748b', backgroundColor: '#f8fafc' },
52
+ pagination: {
53
+ root: { backgroundColor: '#f8fafc', color: '#334155', fontSize: '14px' },
54
+ total: { color: '#64748b' },
55
+ pageItem: { borderRadius: 4 },
56
+ activePageItem: { backgroundColor: '#1677ff', color: '#fff' },
57
+ sizeChanger: { width: 140 },
58
+ quickJumperInput: { width: 64 },
59
+ },
60
+ }
61
+ ```
62
+
63
+ - `cell` 是表头、表体和汇总单元格的通用默认值;分区覆盖通用值,列级 `headerStyle` / `cellStyle` / `summaryStyle` 优先。
64
+ - Canvas 分区支持 `backgroundColor`、`color`、`fontSize`、`fontWeight`、`fontFamily`、`textAlign`、`verticalAlign`、`padding`、`paddingInline`、`paddingBlock`、`borderColor`、`borderWidth`。长度只支持非负数字或 `px`,`padding` 支持一值或“上下 左右”两值;不支持百分比、`em` 或 DOM 布局属性。
65
+ - `activeCell` 支持背景、文字和边框,`activeRow` 支持背景与文字;仅改变已有选中状态的绘制,不改变选择模式。校验错误提示仍优先。
66
+ - 滚动条 `color` 对应滑块、`backgroundColor` 对应槽色;纵轴 `width`、横轴 `height` 对应厚度。显式 `scrollbar.vertical/horizontal: false` 仍禁止对应轴显示。
67
+ - `pagination` 按节点直接应用 DOM CSS,使用 camelCase 属性名,数字长度按 React DOM 规则处理;仅影响当前实例。通过原生 UI 回调自行渲染分页器时,从 `PaginationConfig.styles` 读取并应用样式。当前分页占位高度仍由表格密度决定,避免设置超出该高度的高度或纵向间距。
68
+
69
+ 分页器支持以下节点:
70
+
71
+ | 节点 | 作用 |
72
+ | --------------------------- | ---------------------------------------------------- |
73
+ | `root` | 分页器根容器,颜色、字体等可向内部继承 |
74
+ | `total` | 总条数文本 |
75
+ | `pages` | 页码列表容器 |
76
+ | `pageItem` | 普通页码按钮;简易模式下为页码文本 |
77
+ | `activePageItem` | 当前页按钮,叠加并覆盖 `pageItem` |
78
+ | `prevButton` / `nextButton` | 上一页 / 下一页按钮 |
79
+ | `prevIcon` / `nextIcon` | 上一页 / 下一页箭头,通过 `borderColor` 设置箭头颜色 |
80
+ | `ellipsis` | 页码省略号 |
81
+ | `sizeChanger` | 分页尺寸选择控件,不包含弹出选项面板 |
82
+ | `quickJumper` | 快速跳转区域容器 |
83
+ | `quickJumperText` | “跳至”和“页”文本 |
84
+ | `quickJumperInput` | 跳转输入控件外框,可设置宽度、背景与边框 |
85
+
86
+ 节点样式优先于默认样式;未配置节点保持原样。独立使用 `ReactPagination` 时也支持同名 `styles`,其中 `styles.root` 优先于 `style`。
87
+
88
+ - 更新或移除 `styles` 后即时生效;不额外持久化 `styles` 对象,已有列配置缓存中的对齐设置仍优先。嵌套子表格的独立内容样式仍通过其列/内容配置指定。
89
+
90
+ 文档站“主题”示例增加了“启用分区 CSS 样式”开关,可切换验证。
91
+
37
92
  ## 安装方法
38
93
 
39
94
  ```bash
package/dist/index.cjs CHANGED
@@ -71,6 +71,87 @@ var DebugManager = class {
71
71
  console.info(`[ListTable Debug] ${label}`, payload);
72
72
  }
73
73
  };
74
+
75
+ // src/services/table-styles-service.ts
76
+ function resolveStylePixels(value) {
77
+ if (typeof value === "string" && !/^\s*\d+(?:\.\d+)?(?:px)?\s*$/.test(value))
78
+ return void 0;
79
+ const number = typeof value === "string" ? parseFloat(value) : value;
80
+ return number != null && Number.isFinite(number) && number >= 0 ? number : void 0;
81
+ }
82
+ function resolveCanvasCellStyle(style) {
83
+ if (!style) return void 0;
84
+ const padding = typeof style.padding === "string" ? style.padding.trim().split(/\s+/) : [style.padding];
85
+ const result = {
86
+ backgroundColor: style.backgroundColor,
87
+ color: style.color,
88
+ fontSize: resolveStylePixels(style.fontSize),
89
+ fontWeight: style.fontWeight == null ? void 0 : String(style.fontWeight),
90
+ fontFamily: style.fontFamily,
91
+ textAlign: style.textAlign,
92
+ verticalAlign: style.verticalAlign,
93
+ paddingInline: resolveStylePixels(style.paddingInline) ?? (padding.length <= 2 ? resolveStylePixels(padding[1] ?? padding[0]) : void 0),
94
+ paddingBlock: resolveStylePixels(style.paddingBlock) ?? (padding.length <= 2 ? resolveStylePixels(padding[0]) : void 0),
95
+ borderColor: style.borderColor,
96
+ borderWidth: resolveStylePixels(style.borderWidth)
97
+ };
98
+ return Object.fromEntries(
99
+ Object.entries(result).filter(([, value]) => value !== void 0)
100
+ );
101
+ }
102
+ function resolveListTableStyleOptions(options) {
103
+ const styles = options.styles;
104
+ if (!styles) return options;
105
+ const cell = resolveCanvasCellStyle(styles.cell) ?? {};
106
+ const header = { ...cell, ...resolveCanvasCellStyle(styles.header) };
107
+ const body = { ...cell, ...resolveCanvasCellStyle(styles.body) };
108
+ const summary = { ...cell, ...resolveCanvasCellStyle(styles.summary) };
109
+ const mapColumns = (columns) => columns.map((column) => ({
110
+ ...column,
111
+ align: column.align ?? (column.cellStyle?.textAlign ?? body.textAlign),
112
+ headerAlign: column.headerAlign ?? (column.headerStyle?.textAlign ?? column.align ?? header.textAlign),
113
+ cellStyle: { ...body, ...column.cellStyle },
114
+ headerStyle: { ...header, ...column.headerStyle },
115
+ summaryStyle: { ...summary, ...column.summaryStyle },
116
+ children: column.children ? mapColumns(column.children) : void 0
117
+ }));
118
+ const scrollbar = { ...options.scrollbar };
119
+ for (const axis of ["vertical", "horizontal"]) {
120
+ const style = axis === "vertical" ? styles.scrollVertical : styles.scrollHorizontal;
121
+ if (!style || scrollbar[axis] === false) continue;
122
+ const mapped = {
123
+ thumbColor: style.color,
124
+ trackColor: style.backgroundColor,
125
+ thickness: resolveStylePixels(
126
+ axis === "vertical" ? style.width : style.height
127
+ ),
128
+ thumbRadius: resolveStylePixels(style.borderRadius)
129
+ };
130
+ scrollbar[axis] = {
131
+ ...scrollbar[axis],
132
+ ...Object.fromEntries(
133
+ Object.entries(mapped).filter(([, value]) => value !== void 0)
134
+ )
135
+ };
136
+ }
137
+ return {
138
+ ...options,
139
+ columns: mapColumns(options.columns),
140
+ scrollbar,
141
+ theme: {
142
+ ...options.theme,
143
+ ...cell.borderColor ? { borderColor: cell.borderColor } : {},
144
+ ...cell.fontSize != null ? { fontSize: cell.fontSize } : {},
145
+ ...cell.fontFamily ? { fontFamily: cell.fontFamily } : {},
146
+ ...body.color ? { textColor: body.color } : {},
147
+ ...header.backgroundColor ? { headerBackgroundColor: header.backgroundColor } : {},
148
+ ...header.color ? { headerTextColor: header.color } : {},
149
+ ...body.backgroundColor ? { backgroundColor: body.backgroundColor } : {},
150
+ activeCellStyle: resolveCanvasCellStyle(styles.activeCell),
151
+ activeRowStyle: resolveCanvasCellStyle(styles.activeRow)
152
+ }
153
+ };
154
+ }
74
155
  function resolveColumnKey(column) {
75
156
  return column.key?.trim() || utils.stringifyDataIndex(column.dataIndex);
76
157
  }
@@ -693,6 +774,7 @@ function normalizeColumn(column, depth, parentKey) {
693
774
  moneyFormat: column.moneyFormat,
694
775
  dataFormat: column.dataFormat,
695
776
  headerStyle: column.headerStyle,
777
+ summaryStyle: column.summaryStyle,
696
778
  summary: column.summary,
697
779
  summaryTitle: column.summaryTitle,
698
780
  meta: column.meta,
@@ -7203,10 +7285,11 @@ function roundRectPath(ctx, x, y, width, height, radius) {
7203
7285
  }
7204
7286
 
7205
7287
  // src/rendering/primitives/draw-grid.ts
7206
- function drawGridRect(ctx, rect, theme, borderColor = theme.borderColor) {
7288
+ function drawGridRect(ctx, rect, theme, borderColor = theme.borderColor, borderWidth = 1) {
7289
+ if (borderWidth <= 0) return;
7207
7290
  ctx.save();
7208
7291
  ctx.strokeStyle = borderColor;
7209
- ctx.lineWidth = 1;
7292
+ ctx.lineWidth = borderWidth;
7210
7293
  ctx.beginPath();
7211
7294
  const showTop = rect.y > 0;
7212
7295
  const showLeft = rect.x > 0;
@@ -7238,7 +7321,8 @@ function resolveHeaderTextLayout(params) {
7238
7321
  allowActions,
7239
7322
  hasFilter,
7240
7323
  contentInsetStart = 0,
7241
- contentInsetEnd = 0
7324
+ contentInsetEnd = 0,
7325
+ paddingInline = HEADER_TEXT_PADDING
7242
7326
  } = params;
7243
7327
  const contentRect = {
7244
7328
  x: rect.x + contentInsetStart,
@@ -7260,11 +7344,11 @@ function resolveHeaderTextLayout(params) {
7260
7344
  contentRect,
7261
7345
  contentVisibleRect,
7262
7346
  align,
7263
- HEADER_TEXT_PADDING
7347
+ paddingInline
7264
7348
  );
7265
7349
  const baseLayout = {
7266
7350
  align,
7267
- maxWidth: Math.max(contentVisibleRect.width - HEADER_TEXT_PADDING * 2, 12),
7351
+ maxWidth: Math.max(contentVisibleRect.width - paddingInline * 2, 12),
7268
7352
  x: baseX
7269
7353
  };
7270
7354
  if (!allowActions || !actionVisibilityState.visible || align === "left") {
@@ -7276,10 +7360,10 @@ function resolveHeaderTextLayout(params) {
7276
7360
  trailingInset: contentInsetEnd
7277
7361
  });
7278
7362
  const textRight = Math.min(
7279
- contentVisibleRect.x + contentVisibleRect.width - HEADER_TEXT_PADDING,
7280
- actionLayout.startX - HEADER_TEXT_PADDING
7363
+ contentVisibleRect.x + contentVisibleRect.width - paddingInline,
7364
+ actionLayout.startX - paddingInline
7281
7365
  );
7282
- const textLeft = contentVisibleRect.x + HEADER_TEXT_PADDING;
7366
+ const textLeft = contentVisibleRect.x + paddingInline;
7283
7367
  if (align === "center") {
7284
7368
  const centeredWidth = Math.max(
7285
7369
  Math.min(baseX - textLeft, textRight - baseX) * 2,
@@ -7414,9 +7498,15 @@ function drawHeaderCell(params, cell, clipRect) {
7414
7498
  const isRangeSelected = isHeaderCellInRange(params.rangeHighlight, cell);
7415
7499
  ctx.fillStyle = isSelected || isRangeSelected ? theme.selectionBackgroundColor : cell.node.style?.backgroundColor ?? theme.headerBackgroundColor;
7416
7500
  ctx.fillRect(rect.x, rect.y, rect.width, rect.height);
7417
- drawGridRect(ctx, rect, theme);
7501
+ drawGridRect(
7502
+ ctx,
7503
+ rect,
7504
+ theme,
7505
+ cell.node.style?.borderColor,
7506
+ cell.node.style?.borderWidth
7507
+ );
7418
7508
  ctx.fillStyle = cell.node.style?.color ?? theme.headerTextColor;
7419
- ctx.font = `${theme.headerFontWeight} ${theme.fontSize}px ${theme.fontFamily}`;
7509
+ ctx.font = `${cell.node.style?.fontWeight ?? theme.headerFontWeight} ${cell.node.style?.fontSize ?? theme.fontSize}px ${cell.node.style?.fontFamily ?? theme.fontFamily}`;
7420
7510
  ctx.textBaseline = "middle";
7421
7511
  const visibleRect = clipRect ? intersectRects(rect, clipRect) : rect;
7422
7512
  if (!visibleRect) {
@@ -7448,6 +7538,7 @@ function drawHeaderCell(params, cell, clipRect) {
7448
7538
  allowActions: cell.node.children.length === 0,
7449
7539
  hasFilter: params.filterableColumnKeys.has(cell.node.key),
7450
7540
  contentWidth: measureHeaderContentWidth(ctx, titleContent),
7541
+ paddingInline: cell.node.style?.paddingInline,
7451
7542
  contentInsetStart: resolveHeaderContentInsetStart({
7452
7543
  columnKey: cell.node.key,
7453
7544
  hasChildren: cell.node.children.length > 0,
@@ -7459,7 +7550,7 @@ function drawHeaderCell(params, cell, clipRect) {
7459
7550
  const textY = resolveHeaderContentCenterY(
7460
7551
  rect,
7461
7552
  titleContent,
7462
- theme.fontSize,
7553
+ cell.node.style?.fontSize ?? theme.fontSize,
7463
7554
  cell.node.style?.paddingBlock ?? params.defaultPaddingBlock ?? resolveDensityPaddingBlock(cell.height),
7464
7555
  cell.node.style?.verticalAlign
7465
7556
  );
@@ -8121,6 +8212,11 @@ function drawSummarySegment(params, columns, clipRect, defaultTitleColumnKey) {
8121
8212
  function drawSummaryCell(ctx, rect, column, theme, summaryValues, selectedHeaderKey, summarySelected, rangeHighlight, clipRect, descriptors, inlineContentInset, defaultTitleColumnKey, textSelection) {
8122
8213
  ctx.save();
8123
8214
  const cellClip = clipRect ? intersectRects2(rect, clipRect) : rect;
8215
+ const style = column.summaryStyle;
8216
+ const fontSize = style?.fontSize ?? theme.fontSize;
8217
+ const paddingInline = style?.paddingInline ?? 12;
8218
+ const paddingBlock = style?.paddingBlock ?? 0;
8219
+ const textY = style?.verticalAlign === "top" ? rect.y + paddingBlock + fontSize / 2 : style?.verticalAlign === "bottom" ? rect.y + rect.height - paddingBlock - fontSize / 2 : rect.y + rect.height / 2;
8124
8220
  if (!cellClip) {
8125
8221
  ctx.restore();
8126
8222
  return;
@@ -8130,9 +8226,9 @@ function drawSummaryCell(ctx, rect, column, theme, summaryValues, selectedHeader
8130
8226
  column.leafIndex,
8131
8227
  (rangeHighlight ?? EMPTY_RANGE_HIGHLIGHT2).selectedColumnRange
8132
8228
  );
8133
- ctx.fillStyle = summarySelected || isHeaderColumnSelected || isColumnRangeSelected ? theme.selectionBackgroundColor : theme.headerBackgroundColor;
8229
+ ctx.fillStyle = summarySelected || isHeaderColumnSelected || isColumnRangeSelected ? theme.selectionBackgroundColor : style?.backgroundColor ?? theme.headerBackgroundColor;
8134
8230
  ctx.fillRect(rect.x, rect.y, rect.width, rect.height);
8135
- drawGridRect(ctx, rect, theme);
8231
+ drawGridRect(ctx, rect, theme, style?.borderColor, style?.borderWidth);
8136
8232
  const resolvedDisplayValue = resolveSummaryCellDisplayValue(
8137
8233
  column,
8138
8234
  summaryValues?.get(column.key),
@@ -8143,10 +8239,10 @@ function drawSummaryCell(ctx, rect, column, theme, summaryValues, selectedHeader
8143
8239
  ctx.beginPath();
8144
8240
  ctx.rect(cellClip.x, cellClip.y, cellClip.width, cellClip.height);
8145
8241
  ctx.clip();
8146
- ctx.fillStyle = theme.headerTextColor;
8147
- ctx.font = `600 ${theme.fontSize}px ${theme.fontFamily}`;
8242
+ ctx.fillStyle = style?.color ?? theme.headerTextColor;
8243
+ ctx.font = `${style?.fontWeight ?? "600"} ${fontSize}px ${style?.fontFamily ?? theme.fontFamily}`;
8148
8244
  ctx.textBaseline = "middle";
8149
- const align = column.align ?? "left";
8245
+ const align = style?.textAlign ?? column.align ?? "left";
8150
8246
  ctx.textAlign = align;
8151
8247
  const contentInsetStart = column.key === inlineContentInset?.columnKey ? inlineContentInset.width : 0;
8152
8248
  const contentRect = {
@@ -8159,16 +8255,16 @@ function drawSummaryCell(ctx, rect, column, theme, summaryValues, selectedHeader
8159
8255
  rect: contentRect,
8160
8256
  visibleRect,
8161
8257
  align,
8162
- padding: 12
8258
+ padding: paddingInline
8163
8259
  });
8164
8260
  const displayText = resolveSummaryDisplayText(ctx, {
8165
8261
  text: resolvedDisplayValue,
8166
8262
  visibleRect,
8167
- padding: 12
8263
+ padding: paddingInline
8168
8264
  });
8169
8265
  const textWidth = ctx.measureText(displayText).width;
8170
8266
  const textOriginX = textX - (align === "right" ? textWidth : align === "center" ? textWidth / 2 : 0);
8171
- const textTop = rect.y + (rect.height - theme.fontSize) / 2;
8267
+ const textTop = textY - fontSize / 2;
8172
8268
  const fragmentKey = `summary:${column.key}`;
8173
8269
  drawSelectableTextSelectionBackground({
8174
8270
  ctx,
@@ -8176,14 +8272,14 @@ function drawSummaryCell(ctx, rect, column, theme, summaryValues, selectedHeader
8176
8272
  textSelection,
8177
8273
  textOriginX,
8178
8274
  textTop,
8179
- textHeight: theme.fontSize,
8275
+ textHeight: fontSize,
8180
8276
  rowIndex: Number.MAX_SAFE_INTEGER,
8181
8277
  columnKey: column.key,
8182
8278
  contentIndex: 0,
8183
8279
  fragmentKey,
8184
8280
  color: theme.textSelectionBackgroundColor ?? "#99c2ff"
8185
8281
  });
8186
- ctx.fillText(displayText, textX, rect.y + rect.height / 2);
8282
+ ctx.fillText(displayText, textX, textY);
8187
8283
  textDescriptor = {
8188
8284
  rowIndex: Number.MAX_SAFE_INTEGER,
8189
8285
  contentIndex: 0,
@@ -8196,7 +8292,7 @@ function drawSummaryCell(ctx, rect, column, theme, summaryValues, selectedHeader
8196
8292
  x: textOriginX,
8197
8293
  y: textTop,
8198
8294
  width: textWidth,
8199
- height: theme.fontSize
8295
+ height: fontSize
8200
8296
  },
8201
8297
  cellClip
8202
8298
  ) ?? void 0,
@@ -10957,6 +11053,25 @@ function normalizeCellContents(contents) {
10957
11053
  }
10958
11054
  return [normalizeCellContentItem(contents)];
10959
11055
  }
11056
+ function applyCellTextStyle(contents, column) {
11057
+ const { color, fontSize, fontWeight, fontFamily } = column.cellStyle ?? {};
11058
+ if (color == null && fontSize == null && fontWeight == null && fontFamily == null)
11059
+ return contents;
11060
+ return contents.map((content) => ({
11061
+ ...content,
11062
+ style: {
11063
+ ...color != null ? { color } : {},
11064
+ ...fontSize != null ? { fontSize } : {},
11065
+ ...fontWeight != null ? { fontWeight } : {},
11066
+ ...fontFamily != null ? { fontFamily } : {},
11067
+ ..."color" in content && content.color != null ? { color: content.color } : {},
11068
+ ..."textColor" in content && content.textColor != null ? { color: content.textColor } : {},
11069
+ ..."fontSize" in content && content.fontSize != null ? { fontSize: content.fontSize } : {},
11070
+ ..."fontWeight" in content && content.fontWeight != null ? { fontWeight: content.fontWeight } : {},
11071
+ ...content.style
11072
+ }
11073
+ }));
11074
+ }
10960
11075
  function normalizeDrawableCellContents(contents) {
10961
11076
  return contents.filter(
10962
11077
  (content) => content.visible !== false && content.style?.display !== "none"
@@ -11130,7 +11245,10 @@ function drawBodyCellContents(params) {
11130
11245
  skipNestedTableOuterBorders,
11131
11246
  defaultRowHeight
11132
11247
  } = params;
11133
- const contents = normalizeDrawableCellContents(params.contents);
11248
+ const contents = applyCellTextStyle(
11249
+ normalizeDrawableCellContents(params.contents),
11250
+ column
11251
+ );
11134
11252
  if (contents.length === 0) {
11135
11253
  return void 0;
11136
11254
  }
@@ -11365,7 +11483,10 @@ function appendClippedContentDescriptors(descriptors, itemDescriptors, visibleRe
11365
11483
  }
11366
11484
  function measureBodyCellContentsHeight(params) {
11367
11485
  const { ctx, column, theme } = params;
11368
- const contents = normalizeDrawableCellContents(params.contents);
11486
+ const contents = applyCellTextStyle(
11487
+ normalizeDrawableCellContents(params.contents),
11488
+ column
11489
+ );
11369
11490
  if (contents.length === 0) {
11370
11491
  return 0;
11371
11492
  }
@@ -11395,7 +11516,10 @@ function measureBodyCellContentsHeight(params) {
11395
11516
  }
11396
11517
  function measureBodyCellContentsWidth(params) {
11397
11518
  const { ctx, column, theme } = params;
11398
- const contents = normalizeDrawableCellContents(params.contents);
11519
+ const contents = applyCellTextStyle(
11520
+ normalizeDrawableCellContents(params.contents),
11521
+ column
11522
+ );
11399
11523
  if (contents.length === 0) {
11400
11524
  return 0;
11401
11525
  }
@@ -20324,7 +20448,9 @@ var ListTableEventController = class {
20324
20448
  event.clientX,
20325
20449
  event.clientY
20326
20450
  );
20327
- const result = this.host.resolvePointerHit(position.x, position.y);
20451
+ const result = this.host.resolvePointerHit(position.x, position.y, {
20452
+ excludeKinds: ["resize-handle"]
20453
+ });
20328
20454
  const rawContextResult = typeof result.hitRowIndex === "number" ? { ...result, rowIndex: result.hitRowIndex } : result;
20329
20455
  const bodyRows = this.resolveBodyRows();
20330
20456
  const contextResult = hydrateBodyContentHitResult({
@@ -24286,13 +24412,22 @@ function drawSegmentRows(params, segment, columns, startRowIndex, endRowIndex, r
24286
24412
  collapseConfig: params.collapseConfig
24287
24413
  }) : [];
24288
24414
  const cellDescriptorStartIndex = params.descriptors.length;
24415
+ const activeStyle = isSelected || isSelectedCellRange ? params.theme.activeCellStyle : isRangeHighlighted ? params.theme.activeRowStyle : void 0;
24416
+ const styledColumn = activeStyle ? {
24417
+ ...cell.column,
24418
+ cellStyle: { ...cell.column.cellStyle, ...activeStyle }
24419
+ } : cell.column;
24420
+ const cellTheme = activeStyle?.backgroundColor ? {
24421
+ ...params.theme,
24422
+ selectionBackgroundColor: activeStyle.backgroundColor
24423
+ } : params.theme;
24289
24424
  const cellTooltip = drawBodyCell(
24290
24425
  ctx,
24291
24426
  rect,
24292
24427
  cell.record,
24293
24428
  cell.sourceRowIndex,
24294
- cell.column,
24295
- params.theme,
24429
+ styledColumn,
24430
+ cellTheme,
24296
24431
  params.rowBackgroundColor,
24297
24432
  params.striped === true,
24298
24433
  isHovered,
@@ -24339,11 +24474,12 @@ function drawSegmentRows(params, segment, columns, startRowIndex, endRowIndex, r
24339
24474
  }
24340
24475
  ctx.restore();
24341
24476
  }
24342
- function drawActiveCellBorder(ctx, rect) {
24343
- const inset = 0.5;
24477
+ function drawActiveCellBorder(ctx, rect, borderColor = ACTIVE_CELL_BORDER_COLOR, borderWidth = 1) {
24478
+ if (borderWidth <= 0) return;
24479
+ const inset = borderWidth / 2;
24344
24480
  ctx.save();
24345
- ctx.strokeStyle = ACTIVE_CELL_BORDER_COLOR;
24346
- ctx.lineWidth = 1;
24481
+ ctx.strokeStyle = borderColor;
24482
+ ctx.lineWidth = borderWidth;
24347
24483
  ctx.strokeRect(
24348
24484
  rect.x + inset,
24349
24485
  rect.y + inset,
@@ -25011,7 +25147,13 @@ function drawBodyCell(ctx, rect, record, rowIndex, column, theme, rowBackgroundC
25011
25147
  validationMessage
25012
25148
  );
25013
25149
  }
25014
- drawGridRect(ctx, rect, theme, theme.borderColor);
25150
+ drawGridRect(
25151
+ ctx,
25152
+ rect,
25153
+ theme,
25154
+ column.cellStyle?.borderColor ?? theme.borderColor,
25155
+ column.cellStyle?.borderWidth
25156
+ );
25015
25157
  ctx.restore();
25016
25158
  return validationMessage ? {
25017
25159
  text: validationMessage,
@@ -28524,6 +28666,7 @@ function renderListTablePagination(params) {
28524
28666
  return;
28525
28667
  }
28526
28668
  const paginationConfig = {
28669
+ styles: options.styles?.pagination,
28527
28670
  mode: paginationOptions.mode,
28528
28671
  current: state.currentPage,
28529
28672
  total: getPaginationTotal(options, total),
@@ -29271,6 +29414,7 @@ function drawActiveCellOverlay(params) {
29271
29414
  return;
29272
29415
  }
29273
29416
  const { ctx, layout } = params;
29417
+ if (params.borderWidth === 0) return;
29274
29418
  if (layout.rangeSegments?.length) {
29275
29419
  layout.rangeSegments.forEach((segment) => {
29276
29420
  ctx.save();
@@ -29282,8 +29426,8 @@ function drawActiveCellOverlay(params) {
29282
29426
  segment.clipRect.height
29283
29427
  );
29284
29428
  ctx.clip();
29285
- ctx.strokeStyle = "#1677ff";
29286
- ctx.lineWidth = 1;
29429
+ ctx.strokeStyle = params.borderColor ?? "#1677ff";
29430
+ ctx.lineWidth = params.borderWidth ?? 1;
29287
29431
  ctx.beginPath();
29288
29432
  ctx.moveTo(segment.startX, segment.startY);
29289
29433
  if (segment.controlX != null && segment.controlY != null) {
@@ -29305,7 +29449,13 @@ function drawActiveCellOverlay(params) {
29305
29449
  ctx.beginPath();
29306
29450
  ctx.rect(clipRect.x, clipRect.y, clipRect.width, clipRect.height);
29307
29451
  ctx.clip();
29308
- drawRangeHighlightBorder(ctx, rect, { omitLeft, omitRight });
29452
+ drawRangeHighlightBorder(
29453
+ ctx,
29454
+ rect,
29455
+ { omitLeft, omitRight },
29456
+ params.borderColor,
29457
+ params.borderWidth
29458
+ );
29309
29459
  ctx.restore();
29310
29460
  });
29311
29461
  }
@@ -29319,7 +29469,12 @@ function drawActiveCellOverlay(params) {
29319
29469
  layout.clipRect.height
29320
29470
  );
29321
29471
  ctx.clip();
29322
- drawActiveCellBorder(ctx, layout.rect);
29472
+ drawActiveCellBorder(
29473
+ ctx,
29474
+ layout.rect,
29475
+ params.borderColor,
29476
+ params.borderWidth
29477
+ );
29323
29478
  ctx.restore();
29324
29479
  }
29325
29480
  }
@@ -29417,10 +29572,7 @@ function removeRangeSegmentsAtSharedLayerBoundaries(segments, ranges) {
29417
29572
  return;
29418
29573
  }
29419
29574
  const top = Math.max(left.y, right.y);
29420
- const bottom = Math.min(
29421
- left.y + left.height,
29422
- right.y + right.height
29423
- );
29575
+ const bottom = Math.min(left.y + left.height, right.y + right.height);
29424
29576
  if (bottom > top) {
29425
29577
  sharedBoundaries.push({ x: boundary, top, bottom });
29426
29578
  }
@@ -29610,10 +29762,10 @@ function subtractCoveredIntervals(start, end, coveredIntervals) {
29610
29762
  ([currentStart, currentEnd]) => currentEnd > currentStart
29611
29763
  );
29612
29764
  }
29613
- function drawRangeHighlightBorder(ctx, rect, edges = {}) {
29765
+ function drawRangeHighlightBorder(ctx, rect, edges = {}, borderColor = "#1677ff", borderWidth = 1) {
29614
29766
  ctx.save();
29615
- ctx.strokeStyle = "#1677ff";
29616
- ctx.lineWidth = 1;
29767
+ ctx.strokeStyle = borderColor;
29768
+ ctx.lineWidth = borderWidth;
29617
29769
  const left = rect.x + 0.5;
29618
29770
  const top = rect.y + 0.5;
29619
29771
  const right = rect.x + Math.max(rect.width - 0.5, 0);
@@ -29909,6 +30061,8 @@ function executeListTableRenderPipeline(params) {
29909
30061
  );
29910
30062
  drawActiveCellOverlay({
29911
30063
  ctx,
30064
+ borderColor: theme.activeCellStyle?.borderColor,
30065
+ borderWidth: theme.activeCellStyle?.borderWidth,
29912
30066
  layout: resolveActiveCellOverlayLayout({
29913
30067
  descriptors,
29914
30068
  selection,
@@ -30663,6 +30817,7 @@ function resolvePaginationSignature(params) {
30663
30817
  paginationConfig ? "enabled" : "disabled",
30664
30818
  paginationConfig?.mode ?? "",
30665
30819
  paginationConfig?.total ?? params.total,
30820
+ JSON.stringify(params.options.styles?.pagination ?? null),
30666
30821
  params.total > 0 ? "nonempty" : "empty",
30667
30822
  params.currentPage,
30668
30823
  params.pageSize,
@@ -32568,6 +32723,7 @@ var ListTableCore = class {
32568
32723
  /** 由 assembleListTableCoreControllers 在构造阶段挂载。 */
32569
32724
  __publicField(this, "renderController");
32570
32725
  __publicField(this, "debugManager");
32726
+ options = resolveListTableStyleOptions(options);
32571
32727
  this.container = container;
32572
32728
  this.options = options;
32573
32729
  applyInitialColumnVisibility(options.columns);
@@ -32622,6 +32778,7 @@ var ListTableCore = class {
32622
32778
  * @param options 新配置。
32623
32779
  */
32624
32780
  updateOptions(options) {
32781
+ options = resolveListTableStyleOptions(options);
32625
32782
  this.animationController.stopCarouselScroll();
32626
32783
  const host = this.asAssemblyHost();
32627
32784
  const shouldResetColumnConfig = shouldPersistIncomingColumnConfig(