Skip to content

Commit

Permalink
feat: headerActionIcons 支持细粒度配置 & 修复异步渲染导致无法获取实例的问题 (#2301)
Browse files Browse the repository at this point in the history
* feat: headerActionIcons 支持细粒度配置 & 修复异步渲染导致无法获取实例的问题

* test: fix
  • Loading branch information
lijinke666 authored Aug 31, 2023
1 parent 735dea7 commit b2d6f1f
Show file tree
Hide file tree
Showing 30 changed files with 617 additions and 347 deletions.
297 changes: 297 additions & 0 deletions packages/s2-core/__tests__/spreadsheet/header-action-icons-spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,297 @@
import { get, pick } from 'lodash';
import { type SpreadSheet, type S2Options, OriginEventType } from '../../src';
import { createFederatedMouseEvent, createPivotSheet } from '../util/helpers';

const s2Options: S2Options = {
width: 600,
height: 400,
};

describe('HeaderActionIcons Tests', () => {
let s2: SpreadSheet;

beforeEach(async () => {
s2 = createPivotSheet(s2Options);
await s2.render();
});

afterEach(() => {
s2.destroy();
});

test('should render custom header action icons', async () => {
const rowCellDisplayConditionFn = jest.fn();
const colCellDisplayConditionFn = jest.fn();
const cornerCellDisplayConditionFn = jest.fn();

s2.setOptions({
headerActionIcons: [
{
icons: ['Plus'],
belongsCell: 'rowCell',
displayCondition: rowCellDisplayConditionFn,
},
{
icons: ['Trend'],
belongsCell: 'colCell',
displayCondition: colCellDisplayConditionFn,
},
{
icons: ['Minus'],
belongsCell: 'cornerCell',
displayCondition: cornerCellDisplayConditionFn,
},
],
});

await s2.render(false);

[
...s2.facet.getRowCells(),
...s2.facet.getColCells(),
...s2.facet.getCornerCells(),
].forEach((cell) => {
expect(cell.getActionIcons()).toHaveLength(1);
});

expect(rowCellDisplayConditionFn).toHaveBeenCalled();
expect(colCellDisplayConditionFn).toHaveBeenCalled();
expect(cornerCellDisplayConditionFn).toHaveBeenCalled();
});

test('should custom icon fill color', async () => {
s2.setOptions({
headerActionIcons: [
{
icons: [
{
name: 'Plus',
position: 'right',
fill: 'red',
},
],
belongsCell: 'rowCell',
},
],
});

await s2.render(false);

s2.facet.getRowCells().forEach((cell) => {
expect(get(cell.getActionIcons()[0], 'cfg.fill')).toEqual('red');
});
});

test('should default hide icon', async () => {
const innerDefaultHide = jest.fn(() => true);
const defaultHide = jest.fn(() => false);

s2.setOptions({
headerActionIcons: [
{
icons: [
{
name: 'Plus',
position: 'right',
defaultHide: innerDefaultHide,
},
],
belongsCell: 'rowCell',
defaultHide,
},
],
});

await s2.render(false);

s2.facet.getRowCells().forEach((cell) => {
expect(cell.getActionIcons()[0].parsedStyle.visibility).toEqual('hidden');
});

expect(innerDefaultHide).toHaveBeenCalled();
expect(defaultHide).not.toHaveBeenCalled();
});

test('should not render icons by displayCondition', async () => {
const innerDisplayCondition = jest.fn(() => false);
const displayCondition = jest.fn(() => true);

s2.setOptions({
headerActionIcons: [
{
icons: [
{
name: 'Plus',
position: 'right',
displayCondition: innerDisplayCondition,
},
],
belongsCell: 'rowCell',
displayCondition,
},
],
});

await s2.render(false);

s2.facet.getRowCells().forEach((cell) => {
expect(cell.getActionIcons()).toBeEmpty();
});

expect(innerDisplayCondition).toHaveBeenCalled();
expect(displayCondition).not.toHaveBeenCalled();
});

test('should render multiple custom position', async () => {
s2.setOptions({
headerActionIcons: [
{
icons: [
{
name: 'Plus',
position: 'right',
},
{
name: 'Trend',
position: 'left',
},
],
belongsCell: 'rowCell',
},
],
});

await s2.render(false);

const positions = s2.facet.getRowCells().map((cell) => {
return cell
.getActionIcons()
.map((icon) => pick(icon.iconImageShape.attributes, ['x', 'y']));
});

expect(positions).toMatchInlineSnapshot(`
Array [
Array [
Object {
"x": 9,
"y": 24.5,
},
Object {
"x": 51,
"y": 24.5,
},
],
Array [
Object {
"x": 158,
"y": 9.5,
},
Object {
"x": 200,
"y": 9.5,
},
],
Array [
Object {
"x": 158,
"y": 39.5,
},
Object {
"x": 200,
"y": 39.5,
},
],
]
`);
});

test('should not render icons by displayCondition1', async () => {
const onPlusClick = jest.fn();
const onPlusHover = jest.fn();
const onTrendClick = jest.fn();
const onTrendHover = jest.fn();

const onClick = jest.fn();
const onHover = jest.fn();

s2.setOptions({
headerActionIcons: [
{
icons: [
{
name: 'Plus',
position: 'right',
onClick: onPlusClick,
onHover: onPlusHover,
},
{
name: 'Trend',
position: 'right',
onClick: onTrendClick,
onHover: onTrendHover,
},
],
belongsCell: 'rowCell',
onClick,
onHover,
},
],
});

await s2.render(false);

const events = [onTrendClick, onTrendHover, onClick, onHover];

const plusIcon = s2.facet.getRowCells()[0].getActionIcons()[0];

plusIcon.dispatchEvent(
createFederatedMouseEvent(s2, OriginEventType.CLICK),
);

events.forEach((fn) => {
expect(fn).not.toHaveBeenCalled();
});

expect(onPlusClick).toHaveBeenCalledTimes(1);
});

test('should render default right position', async () => {
s2.setOptions({
headerActionIcons: [
{
icons: ['Trend'],
belongsCell: 'rowCell',
},
],
});

await s2.render(false);

const positions = s2.facet
.getRowCells()
.map((cell) => pick(cell.getActionIcons()[0], ['cfg.x', 'cfg.y']));

expect(positions).toMatchInlineSnapshot(`
Array [
Object {
"cfg": Object {
"x": 37,
"y": 24.5,
},
},
Object {
"cfg": Object {
"x": 186,
"y": 9.5,
},
},
Object {
"cfg": Object {
"x": 186,
"y": 39.5,
},
},
]
`);
});
});
4 changes: 2 additions & 2 deletions packages/s2-core/src/cell/base-cell.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ import {
CellClipBox,
CellBorderPosition,
type InteractionStateTheme,
type FullyIconName,
type HeaderActionNameOptions,
type IconPosition,
type InternalFullyTheme,
type InternalFullyCellTheme,
Expand Down Expand Up @@ -607,7 +607,7 @@ export abstract class BaseCell<T extends SimpleBBox> extends Group {
};
}

public getIconConditionResult(): FullyIconName | undefined {
public getIconConditionResult(): HeaderActionNameOptions | undefined {
const iconCondition = this.findFieldCondition(
this.conditions?.icon,
) as IconCondition;
Expand Down
4 changes: 2 additions & 2 deletions packages/s2-core/src/cell/data-cell.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {
import {
CellBorderPosition,
CellClipBox,
type FullyIconName,
type HeaderActionNameOptions,
type IconCondition,
type InteractionStateTheme,
} from '../common/interface';
Expand Down Expand Up @@ -241,7 +241,7 @@ export class DataCell extends BaseCell<ViewMeta> {
// 此时 name 是什么值都无所谓,因为后面会根据 mappingResult 来决定
name: '',
position: getIconPosition(iconCondition),
} as FullyIconName);
} as HeaderActionNameOptions);

this.groupedIcons = groupIconsByPosition([], iconCfg);
}
Expand Down
Loading

0 comments on commit b2d6f1f

Please sign in to comment.