Skip to content

Commit efa2b40

Browse files
committed
feat(interaction): 支持禁用刷选功能
1 parent eb02845 commit efa2b40

File tree

12 files changed

+211
-93
lines changed

12 files changed

+211
-93
lines changed

packages/s2-core/__tests__/unit/interaction/root-spec.ts

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,17 @@ import {
1111
S2Options,
1212
SpreadSheet,
1313
MergedCell,
14+
InteractionName,
15+
DataCellClick,
16+
RowColumnClick,
17+
RowTextClick,
18+
MergedCellClick,
19+
HoverEvent,
20+
BrushSelection,
21+
RowColumnResize,
22+
DataCellMultiSelection,
23+
ShiftMultiSelection,
24+
BaseEvent,
1425
} from '@/index';
1526
import { Store } from '@/common/store';
1627
import { mergeCell, unmergeCell } from '@/utils/interaction/merge-cell';
@@ -194,6 +205,91 @@ describe('RootInteraction Tests', () => {
194205
expect(rootInteraction.eventController.domEventListeners).toBeFalsy();
195206
});
196207

208+
test('should register default interaction', () => {
209+
expect(rootInteraction.interactions.size).toEqual(9);
210+
Object.keys(InteractionName).forEach((key) => {
211+
expect(
212+
rootInteraction.interactions.has(InteractionName[key]),
213+
).toBeTruthy();
214+
});
215+
216+
// 保证对应的交互实例注册正确
217+
expect(
218+
rootInteraction.interactions.get(InteractionName.DATA_CELL_CLICK),
219+
).toBeInstanceOf(DataCellClick);
220+
expect(
221+
rootInteraction.interactions.get(InteractionName.ROW_COLUMN_CLICK),
222+
).toBeInstanceOf(RowColumnClick);
223+
expect(
224+
rootInteraction.interactions.get(InteractionName.ROW_TEXT_CLICK),
225+
).toBeInstanceOf(RowTextClick);
226+
expect(
227+
rootInteraction.interactions.get(InteractionName.MERGED_CELLS_CLICK),
228+
).toBeInstanceOf(MergedCellClick);
229+
expect(
230+
rootInteraction.interactions.get(InteractionName.HOVER),
231+
).toBeInstanceOf(HoverEvent);
232+
expect(
233+
rootInteraction.interactions.get(InteractionName.BRUSH_SELECTION),
234+
).toBeInstanceOf(BrushSelection);
235+
expect(
236+
rootInteraction.interactions.get(InteractionName.COL_ROW_RESIZE),
237+
).toBeInstanceOf(RowColumnResize);
238+
expect(
239+
rootInteraction.interactions.get(
240+
InteractionName.DATA_CELL_MULTI_SELECTION,
241+
),
242+
).toBeInstanceOf(DataCellMultiSelection);
243+
expect(
244+
rootInteraction.interactions.get(
245+
InteractionName.COL_ROW_SHIFT_MULTI_SELECTION,
246+
),
247+
).toBeInstanceOf(ShiftMultiSelection);
248+
});
249+
250+
test('should register custom interaction', () => {
251+
class MyInteraction extends BaseEvent {
252+
bindEvents() {}
253+
}
254+
255+
const customInteraction = {
256+
key: 'customInteraction',
257+
interaction: MyInteraction,
258+
};
259+
260+
mockSpreadSheetInstance.options.interaction.customInteractions = [
261+
customInteraction,
262+
];
263+
264+
rootInteraction = new RootInteraction(mockSpreadSheetInstance);
265+
expect(rootInteraction.interactions.size).toEqual(10);
266+
expect(
267+
rootInteraction.interactions.has(customInteraction.key),
268+
).toBeTruthy();
269+
expect(
270+
rootInteraction.interactions.get(customInteraction.key),
271+
).toBeInstanceOf(MyInteraction);
272+
});
273+
274+
test('should disable brush and resize interaction by options', () => {
275+
mockSpreadSheetInstance.options = {
276+
interaction: {
277+
brushSelection: false,
278+
resize: false,
279+
},
280+
} as S2Options;
281+
282+
rootInteraction = new RootInteraction(mockSpreadSheetInstance);
283+
expect(rootInteraction.interactions.size).toEqual(7);
284+
expect(
285+
rootInteraction.interactions.has(InteractionName.BRUSH_SELECTION),
286+
).toBeFalsy();
287+
[...rootInteraction.interactions.values()].forEach((interaction) => {
288+
expect(interaction).not.toBeInstanceOf(BrushSelection);
289+
expect(interaction).not.toBeInstanceOf(RowColumnResize);
290+
});
291+
});
292+
197293
describe('RootInteraction Change State', () => {
198294
test('should update cell style when update interaction state', () => {
199295
const cells = [mockCell, mockCell, mockCell];

packages/s2-core/__tests__/unit/utils/merge-spec.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ describe('merge test', () => {
116116
},
117117
autoResetSheetStyle: true,
118118
resize: true,
119+
brushSelection: true,
119120
},
120121
frozenRowHeader: true,
121122
showSeriesNumber: false,

packages/s2-core/src/common/constant/options.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ export const DEFAULT_OPTIONS: Readonly<S2Options> = {
5959
},
6060
autoResetSheetStyle: true,
6161
resize: true,
62+
brushSelection: true,
6263
},
6364
showSeriesNumber: false,
6465
scrollReachNodeField: {},

packages/s2-core/src/common/interface/s2Options.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ export interface InteractionOptions {
4949
readonly scrollSpeedRatio?: ScrollRatio;
5050
// enable resize area, default set to all enable
5151
readonly resize?: boolean | ResizeActiveOptions;
52+
// enable mouse drag brush selection
53+
readonly brushSelection?: boolean;
5254
/** ***********CUSTOM INTERACTION HOOKS**************** */
5355
// register custom interactions
5456
customInteractions?: CustomInteraction[];

packages/s2-core/src/interaction/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,4 @@ export * from './data-cell-multi-selection';
55
export * from './event-controller';
66
export * from './root';
77
export * from './row-column-resize';
8+
export * from './shift-multi-selection';

packages/s2-core/src/interaction/root.ts

Lines changed: 55 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -237,55 +237,65 @@ export class RootInteraction {
237237
hideColumns(this.spreadsheet, hiddenColumnFields, true);
238238
}
239239

240-
/**
241-
* 注册交互(组件按自己的场景写交互,继承此方法注册)
242-
* @param options
243-
*/
240+
private getDefaultInteractions() {
241+
const { resize, brushSelection } = this.spreadsheet.options.interaction;
242+
return [
243+
{
244+
key: InteractionName.DATA_CELL_CLICK,
245+
interaction: DataCellClick,
246+
},
247+
{
248+
key: InteractionName.ROW_COLUMN_CLICK,
249+
interaction: RowColumnClick,
250+
},
251+
{
252+
key: InteractionName.ROW_TEXT_CLICK,
253+
interaction: RowTextClick,
254+
},
255+
{
256+
key: InteractionName.MERGED_CELLS_CLICK,
257+
interaction: MergedCellClick,
258+
},
259+
{
260+
key: InteractionName.HOVER,
261+
interaction: HoverEvent,
262+
enable: !isMobile(),
263+
},
264+
{
265+
key: InteractionName.BRUSH_SELECTION,
266+
interaction: BrushSelection,
267+
enable: !isMobile() && brushSelection,
268+
},
269+
{
270+
key: InteractionName.COL_ROW_RESIZE,
271+
interaction: RowColumnResize,
272+
enable: !isMobile() && resize,
273+
},
274+
{
275+
key: InteractionName.DATA_CELL_MULTI_SELECTION,
276+
interaction: DataCellMultiSelection,
277+
enable: !isMobile(),
278+
},
279+
{
280+
key: InteractionName.COL_ROW_SHIFT_MULTI_SELECTION,
281+
interaction: ShiftMultiSelection,
282+
enable: !isMobile(),
283+
},
284+
];
285+
}
286+
244287
private registerInteractions() {
245-
this.interactions.clear();
288+
const { customInteractions } = this.spreadsheet.options.interaction;
246289

247-
this.interactions.set(
248-
InteractionName.DATA_CELL_CLICK,
249-
new DataCellClick(this.spreadsheet),
250-
);
251-
this.interactions.set(
252-
InteractionName.ROW_COLUMN_CLICK,
253-
new RowColumnClick(this.spreadsheet),
254-
);
255-
this.interactions.set(
256-
InteractionName.ROW_TEXT_CLICK,
257-
new RowTextClick(this.spreadsheet),
258-
);
259-
this.interactions.set(
260-
InteractionName.MERGED_CELLS_CLICK,
261-
new MergedCellClick(this.spreadsheet),
262-
);
263-
this.interactions.set(
264-
InteractionName.HOVER,
265-
new HoverEvent(this.spreadsheet),
266-
);
290+
this.interactions.clear();
267291

268-
if (!isMobile()) {
269-
this.interactions.set(
270-
InteractionName.BRUSH_SELECTION,
271-
new BrushSelection(this.spreadsheet),
272-
);
273-
this.interactions.set(
274-
InteractionName.COL_ROW_RESIZE,
275-
new RowColumnResize(this.spreadsheet),
276-
);
277-
this.interactions.set(
278-
InteractionName.DATA_CELL_MULTI_SELECTION,
279-
new DataCellMultiSelection(this.spreadsheet),
280-
);
281-
this.interactions.set(
282-
InteractionName.COL_ROW_SHIFT_MULTI_SELECTION,
283-
new ShiftMultiSelection(this.spreadsheet),
284-
);
285-
}
292+
const defaultInteractions = this.getDefaultInteractions();
293+
defaultInteractions.forEach(({ key, interaction: Interaction, enable }) => {
294+
if (enable !== false) {
295+
this.interactions.set(key, new Interaction(this.spreadsheet));
296+
}
297+
});
286298

287-
const customInteractions =
288-
this.spreadsheet.options?.interaction.customInteractions;
289299
if (!isEmpty(customInteractions)) {
290300
forEach(customInteractions, (customInteraction: CustomInteraction) => {
291301
const CustomInteractionClass = customInteraction.interaction;

packages/s2-core/src/interaction/row-column-resize.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ import {
2121
RESIZE_START_GUIDE_LINE_ID,
2222
RESIZE_END_GUIDE_LINE_ID,
2323
S2Event,
24-
CORNER_MAX_WIDTH_RATIO,
2524
ResizeDirectionType,
2625
ResizeAreaEffect,
2726
} from '@/common/constant';

packages/s2-react/__tests__/unit/utils/options-spec.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ describe('Options Tests', () => {
3838
},
3939
autoResetSheetStyle: true,
4040
resize: true,
41+
brushSelection: true,
4142
},
4243
frozenRowHeader: true,
4344
showSeriesNumber: false,

packages/s2-react/playground/index.tsx

Lines changed: 47 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -456,7 +456,9 @@ function MainLayout() {
456456
</Button>
457457
</Popover>
458458
</Space>
459-
<Space style={{ margin: '20px 0', display: 'flex' }}>
459+
<Space
460+
style={{ marginTop: 20, display: 'flex', flexWrap: 'wrap' }}
461+
>
460462
<Switch
461463
checkedChildren="渲染组件"
462464
unCheckedChildren="卸载组件"
@@ -527,24 +529,6 @@ function MainLayout() {
527529
defaultChecked={adaptive}
528530
onChange={setAdaptive}
529531
/>
530-
<Tooltip title="开启后,点击空白处,按下ESC键, 取消高亮, 清空选中单元格, 等交互样式">
531-
<Switch
532-
checkedChildren="自动重置交互样式开"
533-
unCheckedChildren="自动重置交互样式关"
534-
defaultChecked={
535-
mergedOptions?.interaction?.autoResetSheetStyle
536-
}
537-
onChange={(checked) => {
538-
updateOptions({
539-
interaction: {
540-
autoResetSheetStyle: checked,
541-
},
542-
});
543-
}}
544-
/>
545-
</Tooltip>
546-
</Space>
547-
<Space size="middle">
548532
<Switch
549533
checkedChildren="显示序号"
550534
unCheckedChildren="不显示序号"
@@ -567,30 +551,6 @@ function MainLayout() {
567551
checked={showTotals}
568552
onChange={setShowTotals}
569553
/>
570-
<Switch
571-
checkedChildren="选中聚光灯开"
572-
unCheckedChildren="选中聚光灯关"
573-
checked={mergedOptions.interaction.selectedCellsSpotlight}
574-
onChange={(checked) => {
575-
updateOptions({
576-
interaction: {
577-
selectedCellsSpotlight: checked,
578-
},
579-
});
580-
}}
581-
/>
582-
<Switch
583-
checkedChildren="hover十字器开"
584-
unCheckedChildren="hover十字器关"
585-
checked={mergedOptions.interaction.hoverHighlight}
586-
onChange={(checked) => {
587-
updateOptions({
588-
interaction: {
589-
hoverHighlight: checked,
590-
},
591-
});
592-
}}
593-
/>
594554
<Switch
595555
checkedChildren="默认actionIcons"
596556
unCheckedChildren="自定义actionIcons"
@@ -621,6 +581,50 @@ function MainLayout() {
621581
/>
622582
</Space>
623583
</Collapse.Panel>
584+
<Collapse.Panel header="交互配置" key="interaction">
585+
<Space>
586+
<Switch
587+
checkedChildren="选中聚光灯开"
588+
unCheckedChildren="选中聚光灯关"
589+
checked={mergedOptions.interaction.selectedCellsSpotlight}
590+
onChange={(checked) => {
591+
updateOptions({
592+
interaction: {
593+
selectedCellsSpotlight: checked,
594+
},
595+
});
596+
}}
597+
/>
598+
<Switch
599+
checkedChildren="hover十字器开"
600+
unCheckedChildren="hover十字器关"
601+
checked={mergedOptions.interaction.hoverHighlight}
602+
onChange={(checked) => {
603+
updateOptions({
604+
interaction: {
605+
hoverHighlight: checked,
606+
},
607+
});
608+
}}
609+
/>
610+
<Tooltip title="开启后,点击空白处,按下ESC键, 取消高亮, 清空选中单元格, 等交互样式">
611+
<Switch
612+
checkedChildren="自动重置交互样式开"
613+
unCheckedChildren="自动重置交互样式关"
614+
defaultChecked={
615+
mergedOptions?.interaction?.autoResetSheetStyle
616+
}
617+
onChange={(checked) => {
618+
updateOptions({
619+
interaction: {
620+
autoResetSheetStyle: checked,
621+
},
622+
});
623+
}}
624+
/>
625+
</Tooltip>
626+
</Space>
627+
</Collapse.Panel>
624628
<Collapse.Panel header="宽高调整热区配置" key="resize">
625629
<ResizeConfig setOptions={setOptions} setThemeCfg={setThemeCfg} />
626630
</Collapse.Panel>

packages/s2-react/src/components/sheets/strategy-sheet/index.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ const getStrategySheetOptions: GetStrategySheetOptions = (
2626
},
2727
interaction: {
2828
autoResetSheetStyle: true,
29+
// 趋势分析表不开启刷选
30+
brushSelection: false,
2931
},
3032
tooltip: {
3133
operation: {

0 commit comments

Comments
 (0)