diff --git a/packages/s2-core/src/cell/corner-cell.ts b/packages/s2-core/src/cell/corner-cell.ts index 2e387caf0c..2da4553ce9 100644 --- a/packages/s2-core/src/cell/corner-cell.ts +++ b/packages/s2-core/src/cell/corner-cell.ts @@ -24,6 +24,7 @@ import { getResizeAreaAttrs, shouldAddResizeArea, } from '../utils/interaction/resize'; +import { isMobile } from '../utils/is-mobile'; import { HeaderCell } from './header-cell'; export class CornerCell extends HeaderCell { @@ -55,6 +56,19 @@ export class CornerCell extends HeaderCell { this.update(); } + private onTreeIconClick(isCollapsed: boolean) { + if (isMobile()) { + return; + } + + this.emitCollapseEvent(isCollapsed); + } + + private emitCollapseEvent(isCollapsed: boolean) { + this.spreadsheet.facet.resetScrollY(); + this.spreadsheet.emit(S2Event.ROW_CELL_ALL_COLLAPSED__PRIVATE, isCollapsed); + } + /** * 绘制折叠展开的 icon */ @@ -73,23 +87,26 @@ export class CornerCell extends HeaderCell { values(collapseFields!).filter(Boolean).length === rootRowNodes.length || rootRowNodes.every((node) => node.isCollapsed); const isCollapsed = isAllCollapsed; + const { offsetXY, offsetWH } = this.getActionIconOffset(size); this.treeIcon = renderTreeIcon({ group: this, iconCfg: { - x: area.x, - y: this.getIconPosition().y, - width: size, - height: size, + x: area.x - offsetXY, + y: this.getIconPosition().y - offsetXY, + width: size + offsetWH, + height: size + offsetWH, fill, }, isCollapsed, onClick: () => { - this.spreadsheet.facet.resetScrollY(); - this.spreadsheet.emit( - S2Event.ROW_CELL_ALL_COLLAPSED__PRIVATE, - isCollapsed, - ); + this.onTreeIconClick(isCollapsed); + }, + onTouchEnd: () => { + /** + * 移动端时,绑定展开、收起事件 + */ + this.emitCollapseEvent(isCollapsed); }, }); } diff --git a/packages/s2-core/src/cell/header-cell.ts b/packages/s2-core/src/cell/header-cell.ts index 553d543048..c473627b80 100644 --- a/packages/s2-core/src/cell/header-cell.ts +++ b/packages/s2-core/src/cell/header-cell.ts @@ -43,6 +43,7 @@ import { } from '../utils/cell/header-cell'; import { findFieldCondition } from '../utils/condition/condition'; import { renderIcon } from '../utils/g-renders'; +import { isMobile } from '../utils/is-mobile'; import { getSortTypeIcon } from '../utils/sort-action'; export abstract class HeaderCell< @@ -519,4 +520,20 @@ export abstract class HeaderCell< public getActionIcons() { return this.actionIcons || []; } + + protected getActionIconOffset(iconSize: number) { + let offsetXY = 0; + let offsetWH = 0; + + // 移动端的时候,将icon变大,从而增加触发交互的面积 + if (isMobile()) { + offsetXY = iconSize / 4; + offsetWH = iconSize / 2; + } + + return { + offsetXY, + offsetWH, + }; + } } diff --git a/packages/s2-core/src/cell/row-cell.ts b/packages/s2-core/src/cell/row-cell.ts index 1fe344d7b0..ba62eb4b3d 100644 --- a/packages/s2-core/src/cell/row-cell.ts +++ b/packages/s2-core/src/cell/row-cell.ts @@ -155,28 +155,28 @@ export class RowCell extends HeaderCell { const iconX = x + contentIndent; const iconY = this.getIconPosition().y; + const { offsetXY, offsetWH } = this.getActionIconOffset(size); this.treeIcon = renderTreeIcon({ group: this, iconCfg: { - x: iconX, - y: iconY, - width: size!, - height: size!, + x: iconX - offsetXY, + y: iconY - offsetXY, + width: size + offsetWH, + height: size + offsetWH, fill, }, isCollapsed, onClick: () => { this.onTreeIconClick(); }, - }); - - // 移动端, 点击热区为整个单元格 - if (isMobile()) { - this.addEventListener('click', () => { + onTouchEnd: () => { + /** + * 移动端时,绑定展开、收起事件 + */ this.emitCollapseEvent(); - }); - } + }, + }); } protected drawTreeLeafNodeAlignDot() { diff --git a/packages/s2-core/src/utils/g-renders.ts b/packages/s2-core/src/utils/g-renders.ts index a97f9b3189..77fb2c9a74 100644 --- a/packages/s2-core/src/utils/g-renders.ts +++ b/packages/s2-core/src/utils/g-renders.ts @@ -130,8 +130,9 @@ export function renderTreeIcon(options: { isCollapsed?: boolean | null; iconCfg: Omit; onClick?: () => void; + onTouchEnd?: () => void; }) { - const { group, iconCfg, isCollapsed, onClick } = options; + const { group, iconCfg, isCollapsed, onClick, onTouchEnd } = options; const iconShape = renderIcon(group, { ...iconCfg, name: isCollapsed ? 'Plus' : 'Minus', @@ -142,5 +143,9 @@ export function renderTreeIcon(options: { iconShape.addEventListener('click', onClick); } + if (isFunction(onTouchEnd)) { + iconShape.addEventListener('touchend', onTouchEnd); + } + return iconShape; }