Skip to content

Commit 8a709e7

Browse files
authored
fix: only show Cell Selection drag handle w/using mixed/cell selection (#2242)
1 parent f46993f commit 8a709e7

File tree

9 files changed

+54
-48
lines changed

9 files changed

+54
-48
lines changed

packages/common/src/core/slickCore.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -444,7 +444,7 @@ export class SlickDragExtendHandle {
444444
cssClass = 'slick-drag-replace-handle';
445445

446446
constructor(gridUid: string) {
447-
this.id = gridUid + '_drag_replace_handle';
447+
this.id = `${gridUid}_drag_replace_handle`;
448448
}
449449

450450
removeEl(): void {
@@ -455,7 +455,7 @@ export class SlickDragExtendHandle {
455455
if (activeCellNode) {
456456
const dragReplaceEl = document.createElement('div');
457457
dragReplaceEl.classList.add('slick-drag-replace-handle');
458-
dragReplaceEl.setAttribute('id', this.id);
458+
dragReplaceEl.id = this.id;
459459
activeCellNode.appendChild(dragReplaceEl);
460460
}
461461
}

packages/common/src/core/slickGrid.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3271,7 +3271,10 @@ export class SlickGrid<TData = any, C extends Column<TData> = Column<TData>, O e
32713271
protected handleSelectedRangesChanged(e: SlickEventData, ranges: SlickRange[]): void {
32723272
const ne = e.getNativeEvent<CustomEvent>();
32733273
const selectionMode: CellSelectionMode = ne?.detail?.selectionMode ?? '';
3274-
const addDragHandle = !!ne?.detail?.addDragHandle;
3274+
let addDragHandle = !!ne?.detail?.addDragHandle;
3275+
3276+
const selectionType = this.getSelectionModel()?.getOptions()?.selectionType;
3277+
addDragHandle = selectionType === 'cell' || selectionType === 'mixed';
32753278

32763279
// drag and replace functionality
32773280
const prevSelectedRanges = this.selectedRanges.slice(0);
@@ -4052,7 +4055,9 @@ export class SlickGrid<TData = any, C extends Column<TData> = Column<TData>, O e
40524055
applyHtmlToElement(cellDiv, cellResult as string | HTMLElement, this._options);
40534056

40544057
// add drag-to-replace handle
4055-
if (row === this.selectionBottomRow && cell === this.selectionRightCell && this._options.showCellSelection) {
4058+
const selectionType = this.getSelectionModel()?.getOptions()?.selectionType;
4059+
const addDragHandle = selectionType === 'cell' || selectionType === 'mixed';
4060+
if (row === this.selectionBottomRow && cell === this.selectionRightCell && this._options.showCellSelection && addDragHandle) {
40564061
this.dragReplaceEl.createEl(cellDiv);
40574062
}
40584063
}
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
import type { SlickEvent, SlickRange } from '../core/slickCore.js';
22
import type { SlickPlugin } from '../interfaces/index.js';
33

4-
export type SelectionModel = SlickPlugin & {
4+
export type SelectionModel<T = any> = SlickPlugin & {
55
refreshSelections: () => void;
66
onSelectedRangesChanged: SlickEvent<SlickRange[]>;
7+
getOptions: () => T;
78
getSelectedRanges: () => SlickRange[];
89
setSelectedRanges: (ranges: SlickRange[], caller?: string, selectionMode?: string) => void;
910
};

packages/common/src/extensions/__tests__/slickCellSelectionModel.spec.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ describe('CellSelectionModel Plugin', () => {
141141
plugin.init(gridStub);
142142

143143
expect(plugin.cellRangeSelector).toBeTruthy();
144-
expect(plugin.addonOptions).toEqual({ selectActiveCell: true });
144+
expect(plugin.getOptions()).toEqual({ selectActiveCell: true });
145145
expect(registerSpy).toHaveBeenCalledWith(plugin.cellRangeSelector);
146146
});
147147

@@ -152,7 +152,7 @@ describe('CellSelectionModel Plugin', () => {
152152
plugin.init(gridStub);
153153

154154
expect(plugin.cellRangeSelector).toBeTruthy();
155-
expect(plugin.addonOptions).toEqual({ selectActiveCell: false });
155+
expect(plugin.getOptions()).toEqual({ selectActiveCell: false });
156156
expect(registerSpy).toHaveBeenCalledWith(plugin.cellRangeSelector);
157157
});
158158

@@ -164,7 +164,7 @@ describe('CellSelectionModel Plugin', () => {
164164
plugin.init(gridStub);
165165

166166
expect(plugin.cellRangeSelector).toBeTruthy();
167-
expect(plugin.addonOptions).toEqual({ selectActiveCell: true, cellRangeSelector: mockCellRangeSelector });
167+
expect(plugin.getOptions()).toEqual({ selectActiveCell: true, cellRangeSelector: mockCellRangeSelector });
168168
expect(registerSpy).toHaveBeenCalledWith(plugin.cellRangeSelector);
169169
});
170170

packages/common/src/extensions/__tests__/slickHybridSelectionModel.spec.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ describe('Row Selection Model Plugin', () => {
148148
it('should create the plugin and initialize it', () => {
149149
plugin.init(gridStub);
150150

151-
expect(plugin.addonOptions).toEqual({
151+
expect(plugin.getOptions()).toEqual({
152152
autoScrollWhenDrag: true,
153153
cellRangeSelector: expect.any(SlickCellRangeSelector),
154154
dragToSelect: false,
@@ -179,7 +179,7 @@ describe('Row Selection Model Plugin', () => {
179179
plugin = new SlickHybridSelectionModel({ selectActiveRow: false });
180180
plugin.init(gridStub);
181181

182-
expect(plugin.addonOptions).toEqual({
182+
expect(plugin.getOptions()).toEqual({
183183
autoScrollWhenDrag: true,
184184
cellRangeSelector: expect.any(SlickCellRangeSelector),
185185
dragToSelect: false,
@@ -196,7 +196,7 @@ describe('Row Selection Model Plugin', () => {
196196
plugin = new SlickHybridSelectionModel({ selectActiveRow: true });
197197
plugin.init(gridStub);
198198

199-
expect(plugin.addonOptions).toEqual({
199+
expect(plugin.getOptions()).toEqual({
200200
autoScrollWhenDrag: true,
201201
cellRangeSelector: expect.any(SlickCellRangeSelector),
202202
dragToSelect: false,
@@ -636,7 +636,7 @@ describe('Row Selection Model Plugin', () => {
636636
describe('with Selector', () => {
637637
beforeEach(() => {
638638
plugin.activeSelectionIsRow = true;
639-
plugin.addonOptions.dragToSelect = true;
639+
plugin.getOptions().dragToSelect = true;
640640
});
641641

642642
afterEach(() => {
@@ -669,7 +669,7 @@ describe('Row Selection Model Plugin', () => {
669669
vi.spyOn(gridStub, 'getColumns').mockReturnValueOnce(mockColumns);
670670
const setSelectedRangeSpy = vi.spyOn(plugin, 'setSelectedRanges');
671671

672-
plugin.addonOptions.cellRangeSelector = new SlickCellRangeSelector({
672+
plugin.getOptions().cellRangeSelector = new SlickCellRangeSelector({
673673
selectionCss: {
674674
border: 'none',
675675
} as CSSStyleDeclaration,
@@ -808,7 +808,7 @@ describe('Cell Selection Model Plugin', () => {
808808
plugin.init(gridStub);
809809

810810
expect(plugin.getCellRangeSelector()).toBeTruthy();
811-
expect(plugin.addonOptions).toEqual({
811+
expect(plugin.getOptions()).toEqual({
812812
autoScrollWhenDrag: true,
813813
cellRangeSelector: expect.any(SlickCellRangeSelector),
814814
dragToSelect: false,
@@ -829,7 +829,7 @@ describe('Cell Selection Model Plugin', () => {
829829
plugin.init(gridStub);
830830

831831
expect(plugin.getCellRangeSelector()).toBeTruthy();
832-
expect(plugin.addonOptions).toEqual({
832+
expect(plugin.getOptions()).toEqual({
833833
autoScrollWhenDrag: true,
834834
cellRangeSelector: expect.any(SlickCellRangeSelector),
835835
dragToSelect: false,
@@ -854,7 +854,7 @@ describe('Cell Selection Model Plugin', () => {
854854
plugin.init(gridStub);
855855

856856
expect(plugin.getCellRangeSelector()).toBeTruthy();
857-
expect(plugin.addonOptions).toEqual({
857+
expect(plugin.getOptions()).toEqual({
858858
autoScrollWhenDrag: true,
859859
cellRangeSelector: mockCellRangeSelector,
860860
dragToSelect: false,

packages/common/src/extensions/__tests__/slickRowSelectionModel.spec.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ describe('SlickRowSelectionModel Plugin', () => {
123123
it('should create the plugin and initialize it', () => {
124124
plugin.init(gridStub);
125125

126-
expect(plugin.addonOptions).toEqual({
126+
expect(plugin.getOptions()).toEqual({
127127
autoScrollWhenDrag: true,
128128
cellRangeSelector: undefined,
129129
dragToSelect: false,
@@ -135,7 +135,7 @@ describe('SlickRowSelectionModel Plugin', () => {
135135
plugin = new SlickRowSelectionModel({ selectActiveRow: false });
136136
plugin.init(gridStub);
137137

138-
expect(plugin.addonOptions).toEqual({
138+
expect(plugin.getOptions()).toEqual({
139139
autoScrollWhenDrag: true,
140140
cellRangeSelector: undefined,
141141
dragToSelect: false,
@@ -147,7 +147,7 @@ describe('SlickRowSelectionModel Plugin', () => {
147147
plugin = new SlickRowSelectionModel({ selectActiveRow: true });
148148
plugin.init(gridStub);
149149

150-
expect(plugin.addonOptions).toEqual({
150+
expect(plugin.getOptions()).toEqual({
151151
autoScrollWhenDrag: true,
152152
cellRangeSelector: undefined,
153153
dragToSelect: false,
@@ -418,7 +418,7 @@ describe('SlickRowSelectionModel Plugin', () => {
418418

419419
describe('with Selector', () => {
420420
beforeEach(() => {
421-
plugin.addonOptions.dragToSelect = true;
421+
plugin.getOptions().dragToSelect = true;
422422
});
423423

424424
afterEach(() => {
@@ -450,7 +450,7 @@ describe('SlickRowSelectionModel Plugin', () => {
450450
vi.spyOn(gridStub, 'getColumns').mockReturnValueOnce(mockColumns);
451451
const setSelectedRangeSpy = vi.spyOn(plugin, 'setSelectedRanges');
452452

453-
plugin.addonOptions.cellRangeSelector = new SlickCellRangeSelector({
453+
plugin.getOptions().cellRangeSelector = new SlickCellRangeSelector({
454454
selectionCss: {
455455
border: 'none',
456456
} as CSSStyleDeclaration,

packages/common/src/extensions/slickCellSelectionModel.ts

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,15 @@ export interface CellSelectionModelOption {
1111

1212
export type CellSelectionMode = 'SEL' | 'REP';
1313

14-
export class SlickCellSelectionModel implements SelectionModel {
14+
export class SlickCellSelectionModel implements SelectionModel<CellSelectionModelOption | undefined> {
1515
onSelectedRangesChanged: SlickEvent<SlickRange[]>;
1616
pluginName: 'CellSelectionModel' = 'CellSelectionModel' as const;
1717

18-
protected _addonOptions?: CellSelectionModelOption;
1918
protected _cachedPageRowCount = 0;
2019
protected _eventHandler: SlickEventHandler;
2120
protected _dataView?: CustomDataView | SlickDataView;
2221
protected _grid!: SlickGrid;
22+
protected _options?: CellSelectionModelOption;
2323
protected _prevSelectedRow?: number;
2424
protected _prevKeyDown = '';
2525
protected _ranges: SlickRange[] = [];
@@ -37,11 +37,7 @@ export class SlickCellSelectionModel implements SelectionModel {
3737
? new SlickCellRangeSelector({ selectionCss: { border: '2px solid black' } as CSSStyleDeclaration })
3838
: options.cellRangeSelector;
3939

40-
this._addonOptions = options;
41-
}
42-
43-
get addonOptions(): CellSelectionModelOption | undefined {
44-
return this._addonOptions;
40+
this._options = options;
4541
}
4642

4743
get cellRangeSelector(): SlickCellRangeSelector {
@@ -54,7 +50,7 @@ export class SlickCellSelectionModel implements SelectionModel {
5450

5551
init(grid: SlickGrid): void {
5652
this._grid = grid;
57-
if (this._addonOptions === undefined || this._addonOptions.cellRangeSelector === undefined) {
53+
if (this._options === undefined || this._options.cellRangeSelector === undefined) {
5854
this._selector = new SlickCellRangeSelector({
5955
selectionCss: { border: `2px solid ${this._grid.getOptions().darkMode ? 'white' : 'black'}` } as CSSStyleDeclaration,
6056
});
@@ -63,7 +59,7 @@ export class SlickCellSelectionModel implements SelectionModel {
6359
if (grid.hasDataView()) {
6460
this._dataView = grid.getData<CustomDataView | SlickDataView>();
6561
}
66-
this._addonOptions = { ...this._defaults, ...this._addonOptions } as CellSelectionModelOption;
62+
this._options = { ...this._defaults, ...this._options } as CellSelectionModelOption;
6763

6864
// add PubSub instance to all SlickEvent
6965
const pubSub = grid.getPubSubService();
@@ -95,6 +91,10 @@ export class SlickCellSelectionModel implements SelectionModel {
9591
this._selector?.dispose();
9692
}
9793

94+
getOptions(): CellSelectionModelOption | undefined {
95+
return this._options;
96+
}
97+
9898
getSelectedRanges(): SlickRange[] {
9999
return this._ranges;
100100
}
@@ -164,9 +164,9 @@ export class SlickCellSelectionModel implements SelectionModel {
164164
const isCellDefined = isDefined(args.cell);
165165
const isRowDefined = isDefined(args.row);
166166

167-
if (this._addonOptions?.selectActiveCell && isRowDefined && isCellDefined) {
167+
if (this._options?.selectActiveCell && isRowDefined && isCellDefined) {
168168
this.setSelectedRanges([new SlickRange(args.row, args.cell)]);
169-
} else if (!this._addonOptions?.selectActiveCell || (!isRowDefined && !isCellDefined)) {
169+
} else if (!this._options?.selectActiveCell || (!isRowDefined && !isCellDefined)) {
170170
// clear the previous selection once the cell changes
171171
this.setSelectedRanges([]);
172172
}

packages/common/src/extensions/slickHybridSelectionModel.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import type { GridOption, HybridSelectionModelOption, SelectionModel } from '../
66
import type { CustomDataView, OnActiveCellChangedEventArgs } from '../interfaces/index.js';
77
import { SlickCellRangeSelector } from './slickCellRangeSelector.js';
88

9-
export class SlickHybridSelectionModel implements SelectionModel {
9+
export class SlickHybridSelectionModel implements SelectionModel<HybridSelectionModelOption> {
1010
// hybrid selection model is CellSelectionModel except when selecting
1111
// specific columns, which behave as RowSelectionModel
1212

@@ -46,10 +46,6 @@ export class SlickHybridSelectionModel implements SelectionModel {
4646
this._options = { ...this._defaults, ...options };
4747
}
4848

49-
get addonOptions(): HybridSelectionModelOption {
50-
return this._options;
51-
}
52-
5349
get eventHandler(): SlickEventHandler {
5450
return this._eventHandler;
5551
}
@@ -68,7 +64,7 @@ export class SlickHybridSelectionModel implements SelectionModel {
6864
init(grid: SlickGrid): void {
6965
this._grid = grid;
7066
this._options = { ...this._defaults, ...this._options };
71-
this._selector = this.addonOptions.cellRangeSelector;
67+
this._selector = this._options.cellRangeSelector;
7268

7369
if (this._options.selectionType === 'cell') {
7470
this._activeSelectionIsRow = false;
@@ -94,7 +90,7 @@ export class SlickHybridSelectionModel implements SelectionModel {
9490
copyToSelectionCss: { border: '2px solid purple' } as CSSStyleDeclaration,
9591
}
9692
);
97-
this.addonOptions.cellRangeSelector = this._selector;
93+
this._options.cellRangeSelector = this._selector;
9894
}
9995

10096
if (grid.hasDataView()) {
@@ -135,6 +131,10 @@ export class SlickHybridSelectionModel implements SelectionModel {
135131
this._selector?.dispose();
136132
}
137133

134+
getOptions(): HybridSelectionModelOption {
135+
return this._options;
136+
}
137+
138138
// Region: CellSelectionModel Members
139139
// -----------------------------------------------------------------------------
140140

@@ -570,7 +570,7 @@ export class SlickHybridSelectionModel implements SelectionModel {
570570
args: { range: SlickRange; selectionMode: string; allowAutoEdit?: boolean; caller: 'onCellRangeSelecting' | 'onCellRangeSelected' }
571571
): boolean {
572572
if (this._activeSelectionIsRow) {
573-
if (!this.gridOptions.multiSelect || (!this.addonOptions?.selectActiveRow && this._options.selectionType !== 'row')) {
573+
if (!this.gridOptions.multiSelect || (!this._options?.selectActiveRow && this._options.selectionType !== 'row')) {
574574
return false;
575575
}
576576
this.setSelectedRanges(

packages/common/src/extensions/slickRowSelectionModel.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { type SelectionModel } from '../enums/index.js';
33
import { SlickCellRangeSelector } from '../extensions/slickCellRangeSelector.js';
44
import type { GridOption, OnActiveCellChangedEventArgs, RowSelectionModelOption } from '../interfaces/index.js';
55

6-
export class SlickRowSelectionModel implements SelectionModel {
6+
export class SlickRowSelectionModel implements SelectionModel<RowSelectionModelOption> {
77
pluginName: 'RowSelectionModel' = 'RowSelectionModel' as const;
88

99
/** triggered when selected ranges changes */
@@ -28,10 +28,6 @@ export class SlickRowSelectionModel implements SelectionModel {
2828
this._options = { ...this._defaults, ...options };
2929
}
3030

31-
get addonOptions(): RowSelectionModelOption {
32-
return this._options;
33-
}
34-
3531
get eventHandler(): SlickEventHandler {
3632
return this._eventHandler;
3733
}
@@ -43,7 +39,7 @@ export class SlickRowSelectionModel implements SelectionModel {
4339
init(grid: SlickGrid): void {
4440
this._grid = grid;
4541
this._options = { ...this._defaults, ...this._options };
46-
this._selector = this.addonOptions.cellRangeSelector;
42+
this._selector = this._options.cellRangeSelector;
4743

4844
// add PubSub instance to all SlickEvent
4945
const pubSub = grid.getPubSubService();
@@ -56,7 +52,7 @@ export class SlickRowSelectionModel implements SelectionModel {
5652
selectionCss: { border: 'none' } as CSSStyleDeclaration,
5753
autoScroll: this._options.autoScrollWhenDrag,
5854
});
59-
this.addonOptions.cellRangeSelector = this._selector;
55+
this._options.cellRangeSelector = this._selector;
6056
}
6157

6258
this._eventHandler
@@ -92,6 +88,10 @@ export class SlickRowSelectionModel implements SelectionModel {
9288
}
9389
}
9490

91+
getOptions(): RowSelectionModelOption {
92+
return this._options;
93+
}
94+
9595
getCellRangeSelector(): SlickCellRangeSelector | undefined {
9696
return this._selector;
9797
}
@@ -154,7 +154,7 @@ export class SlickRowSelectionModel implements SelectionModel {
154154
}
155155

156156
protected handleCellRangeSelected(_e: SlickEventData, args: { range: SlickRange; selectionMode: string }): boolean | void {
157-
if (!this.gridOptions.multiSelect || !this.addonOptions.selectActiveRow) {
157+
if (!this.gridOptions.multiSelect || !this._options.selectActiveRow) {
158158
return false;
159159
}
160160
this.setSelectedRanges(

0 commit comments

Comments
 (0)