diff --git a/projects/angular-gridster2/src/lib/gridsterEmptyCell.ts b/projects/angular-gridster2/src/lib/gridsterEmptyCell.ts index 6018287c..51879723 100644 --- a/projects/angular-gridster2/src/lib/gridsterEmptyCell.ts +++ b/projects/angular-gridster2/src/lib/gridsterEmptyCell.ts @@ -245,6 +245,8 @@ export class GridsterEmptyCell { item.y = this.gridster.movingItem ? this.gridster.movingItem.y : 0; } } + item.x = Math.min(item.x, Math.max($options.maxCols - item.cols, 0)); + item.y = Math.min(item.y, Math.max($options.maxRows - item.rows, 0)); if (!$options.enableOccupiedCellDrop && this.gridster.checkCollision(item)) { return; } diff --git a/projects/angular-gridster2/src/lib/tests/gridsterEmptyCell.spec.ts b/projects/angular-gridster2/src/lib/tests/gridsterEmptyCell.spec.ts new file mode 100644 index 00000000..fda296f7 --- /dev/null +++ b/projects/angular-gridster2/src/lib/tests/gridsterEmptyCell.spec.ts @@ -0,0 +1,48 @@ +import { signal } from '@angular/core'; + +import { GridsterEmptyCell } from '../gridsterEmptyCell'; + +describe('gridsterEmptyCell service', () => { + it('keeps default-sized drop items inside max grid bounds', () => { + const gridster: any = { + options: signal({ scale: 1 }), + $options: signal({ + defaultItemCols: 6, + defaultItemRows: 3, + emptyCellDragMaxCols: 50, + emptyCellDragMaxRows: 50, + enableOccupiedCellDrop: false, + maxCols: 12, + maxRows: 25 + }), + el: { + scrollLeft: 0, + scrollTop: 0, + getBoundingClientRect: () => + ({ + left: 0, + top: 0 + }) as ClientRect + }, + gridRenderer: { + getLeftMargin: () => 0, + getTopMargin: () => 0 + }, + pixelsToPositionX: (x: number, roundingMethod: (x: number) => number) => roundingMethod(x / 100), + pixelsToPositionY: (y: number, roundingMethod: (y: number) => number) => roundingMethod(y / 100), + checkCollision: vi.fn(() => false) + }; + const emptyCell = new GridsterEmptyCell(gridster); + const event = { + clientX: 700, + clientY: 100, + preventDefault: vi.fn(), + stopPropagation: vi.fn() + } as unknown as MouseEvent; + + const item = emptyCell.getValidItemFromEvent(event); + + expect(item).toMatchObject({ x: 6, y: 1, cols: 6, rows: 3 }); + expect(gridster.checkCollision).toHaveBeenCalledWith(item); + }); +});