From 02d2e9643b6baede653930e1570daab015ab2b59 Mon Sep 17 00:00:00 2001 From: stone Date: Tue, 3 Jan 2023 11:14:43 +0800 Subject: [PATCH] =?UTF-8?q?fix=20:=20=E4=BF=AE=E5=A4=8D=E7=82=B9=E5=87=BB?= =?UTF-8?q?=E8=A1=8C=E5=88=97=E5=A4=B4=E6=97=A0=E6=B3=95=E6=95=B4=E8=A1=8C?= =?UTF-8?q?=E9=AB=98=E4=BA=AE=E7=9A=84=E9=97=AE=E9=A2=98=20(#2025)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix: 修复点击行列头无法整行高亮的问题 * test: 添加修复点击行列头无法整行高亮的问题的单测 * docs: 完善 selectedCellHighlight 相关文档 * docs: 完善 selectedCellHighlight 相关文档 Co-authored-by: zishang --- .../__tests__/unit/cell/data-cell-spec.ts | 85 ++++++++++++++++++- packages/s2-core/src/cell/data-cell.ts | 3 +- packages/s2-core/src/cell/header-cell.ts | 3 +- packages/s2-core/src/utils/cell/data-cell.ts | 1 + s2-site/docs/common/interaction.zh.md | 20 ++--- .../manual/advanced/interaction/basic.zh.md | 16 +++- 6 files changed, 113 insertions(+), 15 deletions(-) diff --git a/packages/s2-core/__tests__/unit/cell/data-cell-spec.ts b/packages/s2-core/__tests__/unit/cell/data-cell-spec.ts index 25431e1a63..38132819a5 100644 --- a/packages/s2-core/__tests__/unit/cell/data-cell-spec.ts +++ b/packages/s2-core/__tests__/unit/cell/data-cell-spec.ts @@ -3,7 +3,15 @@ import { find, get } from 'lodash'; import { createPivotSheet, createTableSheet } from 'tests/util/helpers'; import { renderText } from '@/utils/g-renders'; import { DataCell } from '@/cell'; -import { GuiIcon, type Formatter, type ViewMeta } from '@/common'; +import { + GuiIcon, + type Formatter, + type ViewMeta, + S2Event, + type OriginalEvent, + type S2CellType, + CellTypes, +} from '@/common'; import { EXTRA_FIELD, VALUE_FIELD } from '@/common/constant/basic'; import { DEFAULT_FONT_COLOR, @@ -368,4 +376,79 @@ describe('Data Cell Tests', () => { table.render(); }); }); + + describe('Data Cell Interaction', () => { + let s2: SpreadSheet; + + beforeEach(() => { + s2 = createPivotSheet({ + showSeriesNumber: true, + interaction: { + enableCopy: true, + }, + }); + s2.render(); + }); + const emitEvent = (type: S2Event, event: Partial) => { + s2.emit(type, { + originalEvent: event, + preventDefault() {}, + stopPropagation() {}, + ...event, + } as any); + }; + + test('should be highlight entire row data cells when the row header is clicked', () => { + const allRowCells = s2.interaction.getAllRowHeaderCells(); + const mockCell = allRowCells[0]; + s2.getCell = jest.fn().mockReturnValue(mockCell); + + emitEvent(S2Event.ROW_CELL_CLICK, { + x: 2, + y: 2, + }); + + const interactedCells = s2.interaction.getInteractedCells(); + const firstRowCell = find(interactedCells, (cell: S2CellType) => { + return cell.cellType === CellTypes.ROW_CELL; + }); + expect(interactedCells.length).toBe(7); + expect(firstRowCell.getMeta().id).toBe(mockCell.getMeta().id); + }); + + test('should be highlight entire column data cells when the column header is clicked', () => { + const allColumnCells = s2.interaction.getAllColHeaderCells(); + const mockCell = allColumnCells[0]; + s2.getCell = jest.fn().mockReturnValue(mockCell); + + emitEvent(S2Event.COL_CELL_CLICK, { + x: mockCell.getMeta().x + 5, + y: mockCell.getMeta().y + 5, + }); + + const interactedCells = s2.interaction.getInteractedCells(); + const firstColCell = find(interactedCells, (cell: S2CellType) => { + return cell.cellType === CellTypes.COL_CELL; + }); + expect(interactedCells.length).toBe(8); + expect(firstColCell.getMeta().id).toBe(mockCell.getMeta().id); + }); + + test('should be highlight data cell when the data cell is clicked', () => { + const allDataCells = s2.interaction.getAllCells(); + const mockCell = allDataCells[0]; + s2.getCell = jest.fn().mockReturnValue(mockCell); + + emitEvent(S2Event.DATA_CELL_CLICK, { + x: mockCell.getMeta().x + 5, + y: mockCell.getMeta().y + 5, + }); + + const activeCells = s2.interaction.getInteractedCells(); + + expect(activeCells.length).toBe(1); + expect(activeCells[0].getActualText()).toBe('1'); + expect(activeCells[0].getMeta().id).toBe(mockCell.getMeta().id); + }); + }); }); diff --git a/packages/s2-core/src/cell/data-cell.ts b/packages/s2-core/src/cell/data-cell.ts index a5d26857d8..9ce9a34a0e 100644 --- a/packages/s2-core/src/cell/data-cell.ts +++ b/packages/s2-core/src/cell/data-cell.ts @@ -141,7 +141,8 @@ export class DataCell extends BaseCell { public update() { const stateName = this.spreadsheet.interaction.getCurrentStateName(); - const cells = this.spreadsheet.interaction.getCells([CellTypes.DATA_CELL]); + // 获取当前 interaction 记录的 Cells 元信息列表,不仅仅是数据单元格,也可能是行头或者列头。 + const cells = this.spreadsheet.interaction.getCells(); if (stateName === InteractionStateName.ALL_SELECTED) { this.updateByState(InteractionStateName.SELECTED); diff --git a/packages/s2-core/src/cell/header-cell.ts b/packages/s2-core/src/cell/header-cell.ts index e495e57283..0e639007dd 100644 --- a/packages/s2-core/src/cell/header-cell.ts +++ b/packages/s2-core/src/cell/header-cell.ts @@ -325,7 +325,7 @@ export abstract class HeaderCell extends BaseCell { } } - protected handleSelect(cells: Array, nodes: Node[]) { + protected handleSelect(cells: CellMeta[], nodes: Node[]) { if (includeCell(cells, this)) { this.updateByState(InteractionStateName.SELECTED); } @@ -387,7 +387,6 @@ export abstract class HeaderCell extends BaseCell { CellTypes.COL_CELL, CellTypes.ROW_CELL, ]); - if (!first(cells)) { return; } diff --git a/packages/s2-core/src/utils/cell/data-cell.ts b/packages/s2-core/src/utils/cell/data-cell.ts index c55df14e95..6982d05cf6 100644 --- a/packages/s2-core/src/utils/cell/data-cell.ts +++ b/packages/s2-core/src/utils/cell/data-cell.ts @@ -113,6 +113,7 @@ export const updateBySelectedCellsHighlight = ( s2.interaction.getSelectedCellHighlight(); const isRowCell = dataCell.cellType === CellTypes.ROW_CELL; + // 高亮序号 const showSNWhenRowHeaderHighlight = s2.isTableMode() && s2.options.showSeriesNumber && rowHeader && isRowCell; diff --git a/s2-site/docs/common/interaction.zh.md b/s2-site/docs/common/interaction.zh.md index 148f73c2f9..e1df7dc325 100644 --- a/s2-site/docs/common/interaction.zh.md +++ b/s2-site/docs/common/interaction.zh.md @@ -5,12 +5,12 @@ order: 5 ## Interaction -| 参数 | 说明 | 类型 | 默认值 | 必选 | -| -------- | ----------- | -------------- | -------- | ---------------- | -| linkFields | 标记字段为链接样式,用于外链跳转 | `string[]` \| (meta: [Node](/docs/api/basic-class/node) \| ViewMeta) => boolean | | | -| selectedCellsSpotlight | 是否开启选中高亮聚光灯效果 | `boolean` | `false` | | +| 参数 | 说明 | 类型 | 默认值 | 必选 | +| -------- | ----------- |-------------------------------------------| -------- | ---------------- | +| linkFields | 标记字段为链接样式,用于外链跳转 | `string[]` \ | (meta: [Node](/docs/api/basic-class/node) \| ViewMeta) => boolean | | | +| selectedCellsSpotlight | 是否开启选中高亮聚光灯效果 | `boolean` | `false` | | | hoverHighlight | 鼠标悬停时高亮当前单元格,以及所对应的行头,列头 | `boolean` | `true` | | -| hoverFocus | 鼠标悬停在当前单元格超过默认 800ms 后,保持当前高亮,显示 tooltip,悬停时间通过设置 `duration` 来控制 | `boolean \| {duration: number}` | `true` | | +| hoverFocus | 鼠标悬停在当前单元格超过默认 800ms 后,保持当前高亮,显示 tooltip,悬停时间通过设置 `duration` 来控制 | `boolean \ | {duration: number}` | `true` | | | hiddenColumnFields | 用于配置默认隐藏的列,透视表需要配置列头唯一 id, 明细表配置列头 field 字段即可 | `string[]` | | | | enableCopy | 是否允许复制 | `boolean` | `false` | | | copyWithHeader | 复制数据是否带表头信息 | `boolean` | `false` | | @@ -18,14 +18,14 @@ order: 5 | customInteractions | 自定义交互 [详情](/docs/manual/advanced/interaction/custom) | [CustomInteraction[]](#custominteraction) | | | | scrollSpeedRatio | 用于控制滚动速率,分水平和垂直两个方向,默认为 1 | [ScrollSpeedRatio](#scrollspeedratio) | | | | autoResetSheetStyle | 用于控制点击表格外区域和按下 esc 键时是否重置交互状态 | `boolean` | `true` | | -| resize | 用于控制 resize 热区是否显示 | `boolean` \| [ResizeInteractionOptions](#resizeinteractionoptions) | `true` | | -| brushSelection | 是否允许单元格(包含行头,列头,数值单元格)刷选。行头,列头刷选只支持透视表 | `boolean` \| [BrushSelection](#brushSelection) | `true` | | 1.29.0 后支持 [BrushSelection](#brushSelection) | +| resize | 用于控制 resize 热区是否显示 | `boolean` \ | [ResizeInteractionOptions](#resizeinteractionoptions) | `true` | | +| brushSelection | 是否允许单元格(包含行头,列头,数值单元格)刷选。行头,列头刷选只支持透视表 | `boolean` \ | [BrushSelection](#brushSelection) | `true` | | 1.29.0 后支持 [BrushSelection](#brushSelection) | | multiSelection | 是否允许多选 (包含行头,列头,数值单元格) | `boolean` | `true` | | | rangeSelection | 是否允许区间快捷多选 | `boolean` | `true` | | -| scrollbarPosition | 用于控制滚动条展示在内容区边缘还是画布边缘 | `content \| canvas` | `content` | | +| scrollbarPosition | 用于控制滚动条展示在内容区边缘还是画布边缘 | `content \ | canvas` | `content` | | | eventListenerOptions | 事件监听函数 `addEventListener` 的 [可选项配置](https://developer.mozilla.org/zh-CN/docs/Web/API/EventTarget/addEventListener), 可控制事件从冒泡阶段还是捕获阶段触发 | `false` | | -| selectedCellHighlight | 选中格子后的高亮行为
rowHeader:是否高亮选中格子所在行头
colHeader:是否高亮选中格子所在列头
rowCells:是否高亮选中格子所在行
colCells:是否高亮选中格子所在列
true:同{rowHeader: true, colHeader: true} | `boolean | { rowHeader?: boolean, colHeader?: boolean, rowCells?: boolean, colCells?: boolean }` | | `false` | | -| overscrollBehavior | 控制滚动至边界的行为,可禁用浏览器的默认滚动行为。[详情](/docs/manual/advanced/interaction/basic/#修改滚动至边界行为) | `auto \| contain \| none \| null` | `auto` | +| selectedCellHighlight | 选中格子后的高亮行为
rowHeader:是否高亮选中格子所在行头
colHeader:是否高亮选中格子所在列头
rowCells:是否高亮选中格子所在行
colCells:是否高亮选中格子所在列
true:同{rowHeader: true, colHeader: true} | `boolean \| { rowHeader?: boolean, colHeader?: boolean, rowCells?: boolean, colCells?: boolean }` | | `false` | | +| overscrollBehavior | 控制滚动至边界的行为,可禁用浏览器的默认滚动行为。[详情](/docs/manual/advanced/interaction/basic/#修改滚动至边界行为) | `auto \ | contain \| none \| null` | `auto` | ### CustomInteraction diff --git a/s2-site/docs/manual/advanced/interaction/basic.zh.md b/s2-site/docs/manual/advanced/interaction/basic.zh.md index 7d9c21409d..6330dbac9a 100644 --- a/s2-site/docs/manual/advanced/interaction/basic.zh.md +++ b/s2-site/docs/manual/advanced/interaction/basic.zh.md @@ -185,11 +185,25 @@ const s2Options = { preview ```ts +// selectedCellHighlight 的类型为 boolean | { rowHeader: boolean, colHeader: boolean, rowCells: boolean, colCells: boolean } +// 当 selectedCellHighlight 为 boolean 时 const s2Options = { interaction: { - selectedCellHighlight: true // 默认 false + selectedCellHighlight: true // 默认 false, 当 selectedCellsSpotlight 为 true 时,会高亮 rowHeader 和 colHeader (兼容未拓展类型前的设计) } }; + +// 同时还可以分别配置 selectedCellHighlight 中 header 和 cells 的高亮 +const S2Options = { + interaction: { + selectedCellHighlight: { + rowHeader: true, // 选中单元格时,高亮行头 + colHeader: true, // 选中单元格时,高亮列头 + rowCells: false, // 选中单元格时,高亮当前行 + colCells: false, // 选中单元格时,高亮当前列 + }, + }, +}; ``` ### 悬停聚焦