UNPKG

angular-gridster2

Version:
1 lines 290 kB
{"version":3,"file":"angular-gridster2.mjs","sources":["../../../projects/angular-gridster2/src/lib/gridsterConfig.ts","../../../projects/angular-gridster2/src/lib/gridsterCompact.ts","../../../projects/angular-gridster2/src/lib/gridsterConfig.constant.ts","../../../projects/angular-gridster2/src/lib/gridsterUtils.ts","../../../projects/angular-gridster2/src/lib/gridsterEmptyCell.ts","../../../projects/angular-gridster2/src/lib/gridsterPreview.ts","../../../projects/angular-gridster2/src/lib/gridsterRenderer.ts","../../../projects/angular-gridster2/src/lib/gridster.ts","../../../projects/angular-gridster2/src/lib/gridster.html","../../../projects/angular-gridster2/src/lib/gridsterPush.ts","../../../projects/angular-gridster2/src/lib/gridsterScroll.ts","../../../projects/angular-gridster2/src/lib/gridsterSwap.ts","../../../projects/angular-gridster2/src/lib/gridsterDraggable.ts","../../../projects/angular-gridster2/src/lib/gridsterPushResize.ts","../../../projects/angular-gridster2/src/lib/gridsterResizable.ts","../../../projects/angular-gridster2/src/lib/gridsterItem.ts","../../../projects/angular-gridster2/src/lib/gridsterItem.html","../../../projects/angular-gridster2/src/public_api.ts","../../../projects/angular-gridster2/src/angular-gridster2.ts"],"sourcesContent":["import { Gridster } from './gridster';\nimport { GridsterItem } from './gridsterItem';\nimport { GridsterItemConfig, ResizableHandles } from './gridsterItemConfig';\n\nexport type gridTypes = 'fit' | 'scrollVertical' | 'scrollHorizontal' | 'fixed' | 'verticalFixed' | 'horizontalFixed';\nexport type displayGrids = 'always' | 'onDrag&Resize' | 'none';\nexport type compactTypes =\n | 'none'\n | 'compactUp'\n | 'compactLeft'\n | 'compactUp&Left'\n | 'compactLeft&Up'\n | 'compactRight'\n | 'compactUp&Right'\n | 'compactRight&Up'\n | 'compactDown'\n | 'compactDown&Left'\n | 'compactLeft&Down'\n | 'compactDown&Right'\n | 'compactRight&Down'\n | 'compactGrid';\n\nexport enum GridType {\n Fit = 'fit',\n ScrollVertical = 'scrollVertical',\n ScrollHorizontal = 'scrollHorizontal',\n Fixed = 'fixed',\n VerticalFixed = 'verticalFixed',\n HorizontalFixed = 'horizontalFixed'\n}\n\nexport enum DisplayGrid {\n Always = 'always',\n OnDragAndResize = 'onDrag&Resize',\n None = 'none'\n}\n\nexport enum CompactType {\n None = 'none',\n CompactUp = 'compactUp',\n CompactLeft = 'compactLeft',\n CompactUpAndLeft = 'compactUp&Left',\n CompactLeftAndUp = 'compactLeft&Up',\n CompactRight = 'compactRight',\n CompactUpAndRight = 'compactUp&Right',\n CompactRightAndUp = 'compactRight&Up',\n CompactDown = 'compactDown',\n CompactDownAndLeft = 'compactDown&Left',\n CompactLeftAndDown = 'compactLeft&Down',\n CompactDownAndRight = 'compactDown&Right',\n CompactRightAndDown = 'compactRight&Down',\n CompactGrid = 'compactGrid'\n}\n\nexport enum DirTypes {\n LTR = 'ltr',\n RTL = 'rtl'\n}\n\nexport type dirTypes = 'ltr' | 'rtl';\n\nexport type GridsterApi = {\n calculateLayout: () => void;\n resize: () => void;\n getNextPossiblePosition: (newItem: GridsterItemConfig, startingFrom?: { y?: number; x?: number }) => void;\n getFirstPossiblePosition: (item: GridsterItemConfig) => GridsterItemConfig;\n getLastPossiblePosition: (item: GridsterItemConfig) => GridsterItemConfig;\n getItemComponent: (item: GridsterItemConfig) => GridsterItem | undefined;\n};\n\nexport type GridsterConfig = {\n gridType?: gridTypes;\n scale?: number;\n fixedColWidth?: number;\n fixedRowHeight?: number;\n keepFixedHeightInMobile?: boolean;\n keepFixedWidthInMobile?: boolean;\n setGridSize?: boolean;\n compactType?: compactTypes;\n mobileBreakpoint?: number;\n allowMultiLayer?: boolean;\n defaultLayerIndex?: number;\n maxLayerIndex?: number;\n baseLayerIndex?: number;\n minCols?: number;\n maxCols?: number;\n minRows?: number;\n maxRows?: number;\n defaultItemCols?: number;\n defaultItemRows?: number;\n itemAspectRatio?: number | null;\n maxItemCols?: number;\n maxItemRows?: number;\n minItemCols?: number;\n minItemRows?: number;\n minItemArea?: number;\n maxItemArea?: number;\n addEmptyRowsCount?: number;\n rowHeightRatio?: number;\n margin?: number;\n outerMargin?: boolean;\n outerMarginTop?: number | null;\n outerMarginRight?: number | null;\n outerMarginBottom?: number | null;\n outerMarginLeft?: number | null;\n useTransformPositioning?: boolean;\n scrollSensitivity?: number;\n scrollSpeed?: number;\n initCallback?: (gridster: Gridster, gridsterApi: GridsterApi) => void;\n destroyCallback?: (gridster: Gridster) => void;\n gridSizeChangedCallback?: (gridster: Gridster) => void;\n itemChangeCallback?: (item: GridsterItemConfig, itemComponent: GridsterItem) => void;\n itemResizeCallback?: (item: GridsterItemConfig, itemComponent: GridsterItem) => void;\n itemInitCallback?: (item: GridsterItemConfig, itemComponent: GridsterItem) => void;\n itemRemovedCallback?: (item: GridsterItemConfig, itemComponent: GridsterItem) => void;\n itemValidateCallback?: (item: GridsterItemConfig) => boolean;\n draggable?: Draggable;\n resizable?: Resizable;\n swap?: boolean;\n swapWhileDragging?: boolean;\n pushItems?: boolean;\n disablePushOnDrag?: boolean;\n disablePushOnResize?: boolean;\n disableAutoPositionOnConflict?: boolean;\n pushDirections?: PushDirections;\n pushResizeItems?: boolean;\n displayGrid?: displayGrids;\n disableWindowResize?: boolean;\n disableWarnings?: boolean;\n scrollToNewItems?: boolean;\n disableScrollHorizontal?: boolean;\n disableScrollVertical?: boolean;\n enableBoundaryControl?: boolean;\n enableEmptyCellClick?: boolean;\n enableEmptyCellContextMenu?: boolean;\n enableEmptyCellDrop?: boolean;\n enableEmptyCellDrag?: boolean;\n enableOccupiedCellDrop?: boolean;\n emptyCellClickCallback?: (event: MouseEvent, item: GridsterItemConfig) => void;\n emptyCellContextMenuCallback?: (event: MouseEvent, item: GridsterItemConfig) => void;\n emptyCellDropCallback?: (event: DragEvent, item: GridsterItemConfig) => void;\n emptyCellDragCallback?: (event: MouseEvent, item: GridsterItemConfig) => void;\n emptyCellDragMaxCols?: number;\n emptyCellDragMaxRows?: number;\n ignoreMarginInRow?: boolean;\n dirType?: dirTypes;\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n [propName: string]: any;\n};\n\nexport type DragBase = {\n enabled?: boolean;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n stop?: (item: GridsterItemConfig, itemComponent: GridsterItem, event: MouseEvent) => Promise<any> | void;\n start?: (item: GridsterItemConfig, itemComponent: GridsterItem, event: MouseEvent) => void;\n delayStart?: number;\n};\n\nexport type Draggable = DragBase & {\n ignoreContentClass?: string;\n ignoreContent?: boolean;\n dragHandleClass?: string;\n dropOverItems?: boolean;\n dropOverItemsCallback?: (source: GridsterItemConfig, target: GridsterItemConfig, grid?: Gridster) => void;\n};\n\nexport type Resizable = DragBase & {\n handles?: ResizableHandles;\n};\n\nexport type PushDirections = {\n north: boolean;\n east: boolean;\n south: boolean;\n west: boolean;\n};\n\nexport type GridsterConfigStrict = Required<GridsterConfig> & {\n draggable: Required<Draggable>;\n resizable: Required<Resizable>;\n};\n","import { Gridster } from './gridster';\nimport { CompactType } from './gridsterConfig';\nimport { GridsterItem } from './gridsterItem';\nimport { GridsterItemConfig } from './gridsterItemConfig';\n\nexport class GridsterCompact {\n constructor(private gridster: Gridster) {}\n\n destroy(): void {\n this.gridster = null!;\n }\n\n checkCompact(): void {\n const $options = this.gridster.$options();\n if ($options.compactType !== CompactType.None) {\n if ($options.compactType === CompactType.CompactUp) {\n this.checkCompactMovement('y', -1);\n } else if ($options.compactType === CompactType.CompactLeft) {\n this.checkCompactMovement('x', -1);\n } else if ($options.compactType === CompactType.CompactUpAndLeft) {\n this.checkCompactMovement('y', -1);\n this.checkCompactMovement('x', -1);\n } else if ($options.compactType === CompactType.CompactLeftAndUp) {\n this.checkCompactMovement('x', -1);\n this.checkCompactMovement('y', -1);\n } else if ($options.compactType === CompactType.CompactRight) {\n this.checkCompactMovement('x', 1);\n } else if ($options.compactType === CompactType.CompactUpAndRight) {\n this.checkCompactMovement('y', -1);\n this.checkCompactMovement('x', 1);\n } else if ($options.compactType === CompactType.CompactRightAndUp) {\n this.checkCompactMovement('x', 1);\n this.checkCompactMovement('y', -1);\n } else if ($options.compactType === CompactType.CompactDown) {\n this.checkCompactMovement('y', 1);\n } else if ($options.compactType === CompactType.CompactDownAndLeft) {\n this.checkCompactMovement('y', 1);\n this.checkCompactMovement('x', -1);\n } else if ($options.compactType === CompactType.CompactDownAndRight) {\n this.checkCompactMovement('y', 1);\n this.checkCompactMovement('x', 1);\n } else if ($options.compactType === CompactType.CompactLeftAndDown) {\n this.checkCompactMovement('x', -1);\n this.checkCompactMovement('y', 1);\n } else if ($options.compactType === CompactType.CompactRightAndDown) {\n this.checkCompactMovement('x', 1);\n this.checkCompactMovement('y', 1);\n } else if ($options.compactType === CompactType.CompactGrid) {\n this.checkCompactGrid();\n }\n }\n }\n\n checkCompactItem(item: GridsterItemConfig): void {\n const $options = this.gridster.$options();\n if ($options.compactType !== CompactType.None) {\n if ($options.compactType === CompactType.CompactUp) {\n this.moveTillCollision(item, 'y', -1);\n } else if ($options.compactType === CompactType.CompactLeft) {\n this.moveTillCollision(item, 'x', -1);\n } else if ($options.compactType === CompactType.CompactUpAndLeft) {\n this.moveTillCollision(item, 'y', -1);\n this.moveTillCollision(item, 'x', -1);\n } else if ($options.compactType === CompactType.CompactLeftAndUp) {\n this.moveTillCollision(item, 'x', -1);\n this.moveTillCollision(item, 'y', -1);\n } else if ($options.compactType === CompactType.CompactUpAndRight) {\n this.moveTillCollision(item, 'y', -1);\n this.moveTillCollision(item, 'x', 1);\n } else if ($options.compactType === CompactType.CompactDown) {\n this.moveTillCollision(item, 'y', 1);\n } else if ($options.compactType === CompactType.CompactDownAndLeft) {\n this.moveTillCollision(item, 'y', 1);\n this.moveTillCollision(item, 'x', -1);\n } else if ($options.compactType === CompactType.CompactLeftAndDown) {\n this.moveTillCollision(item, 'x', -1);\n this.moveTillCollision(item, 'y', 1);\n } else if ($options.compactType === CompactType.CompactDownAndRight) {\n this.moveTillCollision(item, 'y', 1);\n this.moveTillCollision(item, 'x', 1);\n } else if ($options.compactType === CompactType.CompactRightAndDown) {\n this.moveTillCollision(item, 'x', 1);\n this.moveTillCollision(item, 'y', 1);\n } else if ($options.compactType === CompactType.CompactGrid) {\n this.moveToGridPosition(item);\n }\n }\n }\n\n private checkCompactMovement(direction: 'x' | 'y', delta: number): void {\n let widgetMoved = false;\n this.gridster.grid.forEach((widget: GridsterItem) => {\n if (widget.$item().compactEnabled !== false) {\n const moved = this.moveTillCollision(widget.$item(), direction, delta);\n if (moved) {\n widgetMoved = true;\n widget.item()[direction] = widget.$item()[direction];\n widget.itemChanged();\n }\n }\n });\n if (widgetMoved) {\n this.checkCompact();\n }\n }\n\n private moveTillCollision(item: GridsterItemConfig, direction: 'x' | 'y', delta: number): boolean {\n item[direction] += delta;\n if (this.gridster.checkCollision(item)) {\n item[direction] -= delta;\n return false;\n } else {\n this.moveTillCollision(item, direction, delta);\n return true;\n }\n }\n\n private checkCompactGrid(): void {\n // Sort items by their current position (top to bottom, left to right)\n const sortedItems = this.gridster.grid\n .filter((widget: GridsterItem) => widget.$item().compactEnabled !== false)\n .sort((a: GridsterItem, b: GridsterItem) => {\n if (a.$item().y !== b.$item().y) {\n return a.$item().y - b.$item().y;\n }\n return a.$item().x - b.$item().x;\n });\n\n // Reposition all items in a grid-like manner\n let currentY = 0;\n let currentX = 0;\n let maxYInRow = 0;\n\n sortedItems.forEach((widget: GridsterItem) => {\n const item = widget.$item();\n\n // Check if item fits in current row\n if (currentX + item.cols > this.gridster.columns) {\n // Move to next row\n currentY = maxYInRow;\n currentX = 0;\n maxYInRow = currentY;\n }\n\n // Position item\n const oldX = item.x;\n const oldY = item.y;\n item.x = currentX;\n item.y = currentY;\n\n // Update widget if position changed\n if (oldX !== item.x || oldY !== item.y) {\n widget.item().x = item.x;\n widget.item().y = item.y;\n widget.itemChanged();\n }\n\n // Update position for next item\n currentX += item.cols;\n maxYInRow = Math.max(maxYInRow, currentY + item.rows);\n });\n }\n\n private moveToGridPosition(item: GridsterItemConfig): void {\n // Find the next available position in grid layout\n let currentY = 0;\n let currentX = 0;\n let maxYInRow = 0;\n\n // Sort existing items to find occupied positions\n const sortedItems = this.gridster.grid\n .filter((widget: GridsterItem) => widget.$item() !== item)\n .sort((a: GridsterItem, b: GridsterItem) => {\n if (a.$item().y !== b.$item().y) {\n return a.$item().y - b.$item().y;\n }\n return a.$item().x - b.$item().x;\n });\n\n // Find the next available position\n for (const widget of sortedItems) {\n const existingItem = widget.$item();\n\n // Check if we need to move to next row\n if (currentX + existingItem.cols > this.gridster.columns) {\n currentY = maxYInRow;\n currentX = 0;\n maxYInRow = currentY;\n }\n\n // Check if current item overlaps with the position we want to place our item\n if (\n currentY < existingItem.y + existingItem.rows &&\n currentY + item.rows > existingItem.y &&\n currentX < existingItem.x + existingItem.cols &&\n currentX + item.cols > existingItem.x\n ) {\n // Move to position after this item\n currentX = existingItem.x + existingItem.cols;\n currentY = existingItem.y;\n maxYInRow = Math.max(maxYInRow, currentY + existingItem.rows);\n } else {\n // Update position for next iteration\n currentX += existingItem.cols;\n maxYInRow = Math.max(maxYInRow, currentY + existingItem.rows);\n }\n }\n\n // Check if item fits in current row\n if (currentX + item.cols > this.gridster.columns) {\n currentY = maxYInRow;\n currentX = 0;\n }\n\n // Set the position\n item.x = currentX;\n item.y = currentY;\n }\n}\n","import { CompactType, DirTypes, DisplayGrid, GridsterConfig, GridType } from './gridsterConfig';\n\nexport const GridsterConfigService: GridsterConfig = {\n gridType: GridType.Fit, // 'fit' will fit the items in the container without scroll;\n scale: 1, // scale param to zoom in/zoom out\n // 'scrollVertical' will fit on width and height of the items will be the same as the width\n // 'scrollHorizontal' will fit on height and width of the items will be the same as the height\n // 'fixed' will set the rows and columns dimensions based on fixedColWidth and fixedRowHeight options\n // 'verticalFixed' will set the rows to fixedRowHeight and columns width will fit the space available\n // 'horizontalFixed' will set the columns to fixedColWidth and rows height will fit the space available\n fixedColWidth: 250, // fixed col width for gridType: 'fixed'\n fixedRowHeight: 250, // fixed row height for gridType: 'fixed'\n keepFixedHeightInMobile: false, // keep the height from fixed gridType in mobile layout\n keepFixedWidthInMobile: false, // keep the width from fixed gridType in mobile layout\n setGridSize: false, // sets grid size depending on content\n compactType: CompactType.None, // compact items: 'none' | 'compactUp' | 'compactLeft' | 'compactUp&Left' | 'compactLeft&Up'\n mobileBreakpoint: 640, // if the screen is not wider that this, remove the grid layout and stack the items\n useBodyForBreakpoint: false, // whether to use the body width to determine the mobile breakpoint. Uses the element width when false.\n allowMultiLayer: false,\n defaultLayerIndex: 0,\n maxLayerIndex: 2,\n baseLayerIndex: 1,\n minCols: 1, // minimum amount of columns in the grid\n maxCols: 100, // maximum amount of columns in the grid\n minRows: 1, // minimum amount of rows in the grid\n maxRows: 100, // maximum amount of rows in the grid\n defaultItemCols: 1, // default width of an item in columns\n defaultItemRows: 1, // default height of an item in rows\n itemAspectRatio: null, // set a fixed aspect ratio for an item to have in cols/rows e.g. 1/1 or 4/3 or 16/9\n maxItemCols: 50, // max item number of cols\n maxItemRows: 50, // max item number of rows\n minItemCols: 1, // min item number of columns\n minItemRows: 1, // min item number of rows\n minItemArea: 1, // min item area: cols * rows\n maxItemArea: 2500, // max item area: cols * rows\n addEmptyRowsCount: 0, // add a number of extra empty rows at the end\n rowHeightRatio: 1, // row height ratio from column width\n margin: 10, // margin between grid items\n outerMargin: true, // if margins will apply to the sides of the container\n outerMarginTop: null, // override outer margin for grid\n outerMarginRight: null, // override outer margin for grid\n outerMarginBottom: null, // override outer margin for grid\n outerMarginLeft: null, // override outer margin for grid\n useTransformPositioning: true, // toggle between transform or top/left positioning of items\n scrollSensitivity: 10, // margin of the dashboard where to start scrolling\n scrollSpeed: 20, // how much to scroll each mouse move when in the scrollSensitivity zone\n initCallback: undefined, // callback to call after grid has initialized. Arguments: gridsterComponent\n destroyCallback: undefined, // callback to call after grid has destroyed. Arguments: gridsterComponent\n gridSizeChangedCallback: undefined, // callback to call after grid has changed size. Arguments: gridsterComponent\n itemChangeCallback: undefined, // callback to call for each item when is changes x, y, rows, cols.\n // Arguments: gridsterItem, gridsterItemComponent\n itemResizeCallback: undefined, // callback to call for each item when width/height changes.\n // Arguments: gridsterItem, gridsterItemComponent\n itemInitCallback: undefined, // callback to call for each item when is initialized.\n // Arguments: gridsterItem, gridsterItemComponent\n itemRemovedCallback: undefined, // callback to call for each item when is initialized.\n // Arguments: gridsterItem, gridsterItemComponent\n itemValidateCallback: undefined, // callback to call to validate item position/size. Return true if valid.\n // Arguments: gridsterItem\n enableEmptyCellClick: false, // enable empty cell click events\n enableEmptyCellContextMenu: false, // enable empty cell context menu (right click) events\n enableEmptyCellDrop: false, // enable empty cell drop events\n enableEmptyCellDrag: false, // enable empty cell drag events\n enableOccupiedCellDrop: false, // enable occupied cell drop events\n emptyCellClickCallback: undefined, // empty cell click callback\n emptyCellContextMenuCallback: undefined, // empty cell context menu (right click) callback\n emptyCellDropCallback: undefined, // empty cell drag drop callback. HTML5 Drag & Drop\n emptyCellDragCallback: undefined, // empty cell drag and create item like excel cell selection\n emptyCellDragMaxCols: 50, // limit empty cell drag max cols\n emptyCellDragMaxRows: 50, // limit empty cell drag max rows\n // Arguments: event, gridsterItem{x, y, rows: defaultItemRows, cols: defaultItemCols}\n ignoreMarginInRow: false, // ignore the gap between rows for items which span multiple rows (see #162, #224)\n draggable: {\n delayStart: 0, // milliseconds to delay the start of drag, useful for touch interaction\n enabled: false, // enable/disable draggable items\n ignoreContentClass: 'gridster-item-content', // default content class to ignore the drag event from\n ignoreContent: false, // if true drag will start only from elements from `dragHandleClass`\n dragHandleClass: 'drag-handler', // drag event only from this class. If `ignoreContent` is true.\n stop: undefined, // callback when dragging an item stops. Accepts Promise return to cancel/approve drag.\n start: undefined, // callback when dragging an item starts.\n // Arguments: item, gridsterItem, event\n dropOverItems: false, // enable drop items on top other item\n dropOverItemsCallback: undefined // callback on drop over another item\n // Arguments: source, target, gridComponent\n },\n resizable: {\n delayStart: 0, // milliseconds to delay the start of resize, useful for touch interaction\n enabled: false, // enable/disable resizable items\n handles: {\n s: true,\n e: true,\n n: true,\n w: true,\n se: true,\n ne: true,\n sw: true,\n nw: true\n }, // resizable edges of an item\n stop: undefined, // callback when resizing an item stops. Accepts Promise return to cancel/approve resize.\n start: undefined // callback when resizing an item starts.\n // Arguments: item, gridsterItem, event\n },\n swap: true, // allow items to switch position if drop on top of another\n swapWhileDragging: false, // allow items to switch position while dragging\n pushItems: false, // push items when resizing and dragging\n disablePushOnDrag: false, // disable push on drag\n disablePushOnResize: false, // disable push on resize\n pushDirections: { north: true, east: true, south: true, west: true }, // control the directions items are pushed\n pushResizeItems: false, // on resize of item will shrink adjacent items\n displayGrid: DisplayGrid.OnDragAndResize, // display background grid of rows and columns\n disableWindowResize: false, // disable the window on resize listener. This will stop grid to recalculate on window resize.\n disableWarnings: false, // disable console log warnings about misplacement of grid items\n scrollToNewItems: false, // scroll to new items placed in a scrollable view\n disableScrollHorizontal: false, // disable horizontal scrolling\n disableScrollVertical: false, // disable vertical scrolling\n enableBoundaryControl: false, // enable boundary control while dragging items\n disableAutoPositionOnConflict: false, // disable auto-position of items on conflict state,\n dirType: DirTypes.LTR // page direction, rtl=right to left ltr= left to right, if you use rtl language set dirType to rtl\n};\n","import { Gridster } from './gridster';\n\nexport class GridsterUtils {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n static merge(obj1: any, obj2: any, properties: any): any {\n for (const p in obj2) {\n if (obj2[p] !== void 0 && properties.hasOwnProperty(p)) {\n if (typeof obj2[p] === 'object') {\n // create an empty object for the property if obj1 does not already have one.\n if (!(p in obj1)) {\n obj1[p] = {};\n }\n obj1[p] = GridsterUtils.merge(obj1[p], obj2[p], properties[p]);\n } else {\n obj1[p] = obj2[p];\n }\n }\n }\n\n return obj1;\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n static checkTouchEvent(e: any): void {\n if (e.clientX === undefined && e.touches) {\n if (e.touches && e.touches.length) {\n e.clientX = e.touches[0].clientX;\n e.clientY = e.touches[0].clientY;\n } else if (e.changedTouches && e.changedTouches.length) {\n e.clientX = e.changedTouches[0].clientX;\n e.clientY = e.changedTouches[0].clientY;\n }\n }\n }\n\n static checkContentClassForEvent(gridster: Gridster, e: MouseEvent): boolean {\n const $options = gridster.$options();\n if ($options.draggable.ignoreContent) {\n if (\n !GridsterUtils.checkDragHandleClass(\n e.target as HTMLElement,\n e.currentTarget as HTMLElement,\n $options.draggable.dragHandleClass,\n $options.draggable.ignoreContentClass\n )\n ) {\n return true;\n }\n } else {\n if (GridsterUtils.checkContentClass(e.target as HTMLElement, e.currentTarget as HTMLElement, $options.draggable.ignoreContentClass)) {\n return true;\n }\n }\n return false;\n }\n\n static checkContentClassForEmptyCellClickEvent(gridster: Gridster, e: MouseEvent): boolean {\n const $options = gridster.$options();\n return (\n GridsterUtils.checkContentClass(e.target as HTMLElement, e.currentTarget as HTMLElement, $options.draggable.ignoreContentClass) ||\n GridsterUtils.checkContentClass(e.target as HTMLElement, e.currentTarget as HTMLElement, $options.draggable.dragHandleClass)\n );\n }\n\n static checkDragHandleClass(target: HTMLElement, current: HTMLElement, dragHandleClass: string, ignoreContentClass: string): boolean {\n if (!target || target === current) {\n return false;\n }\n if (target.hasAttribute('class')) {\n const classnames = target.getAttribute('class')!.split(' ');\n if (classnames.indexOf(dragHandleClass) > -1) {\n return true;\n }\n if (classnames.indexOf(ignoreContentClass) > -1) {\n return false;\n }\n }\n return GridsterUtils.checkDragHandleClass(target.parentNode as HTMLElement, current, dragHandleClass, ignoreContentClass);\n }\n\n static checkContentClass(target: HTMLElement, current: HTMLElement, contentClass: string): boolean {\n if (!target || target === current) {\n return false;\n }\n if (target.hasAttribute('class') && target.getAttribute('class')!.split(' ').indexOf(contentClass) > -1) {\n return true;\n } else {\n return GridsterUtils.checkContentClass(target.parentNode as HTMLElement, current, contentClass);\n }\n }\n\n static compareItems(a: { x: number; y: number }, b: { x: number; y: number }): number {\n if (a.y > b.y) {\n return -1;\n } else if (a.y < b.y) {\n return 1;\n } else if (a.x > b.x) {\n return -1;\n } else {\n return 1;\n }\n }\n}\n","import { Gridster } from './gridster';\nimport { GridsterItemConfig } from './gridsterItemConfig';\nimport { GridsterUtils } from './gridsterUtils';\n\nexport class GridsterEmptyCell {\n initialItem: GridsterItemConfig | null;\n removeEmptyCellClickListenerFn: (() => void) | null;\n removeEmptyCellTouchendListenerFn: (() => void) | null;\n removeEmptyCellContextMenuListenerFn: (() => void) | null;\n removeEmptyCellDropListenerFn: (() => void) | null;\n removeEmptyCellMousedownListenerFn: (() => void) | null;\n removeEmptyCellTouchstartListenerFn: (() => void) | null;\n removeWindowMousemoveListenerFn: () => void;\n removeWindowTouchmoveListenerFn: () => void;\n removeWindowMouseupListenerFn: () => void;\n removeWindowTouchendListenerFn: () => void;\n removeEmptyCellDragoverListenerFn: (() => void) | null;\n removeDocumentDragendListenerFn: (() => void) | null;\n\n constructor(private gridster: Gridster) {}\n\n destroy(): void {\n if (this.gridster.previewStyle) {\n this.gridster.previewStyle();\n }\n this.gridster.movingItem = null;\n this.initialItem = this.gridster = null!;\n if (this.removeDocumentDragendListenerFn) {\n this.removeDocumentDragendListenerFn();\n this.removeDocumentDragendListenerFn = null;\n }\n }\n\n updateOptions(): void {\n const options = this.gridster.options();\n const $options = this.gridster.$options();\n if ($options.enableEmptyCellClick && !this.removeEmptyCellClickListenerFn && options.emptyCellClickCallback) {\n this.removeEmptyCellClickListenerFn = this.gridster.renderer.listen(this.gridster.el, 'click', this.emptyCellClickCb);\n this.removeEmptyCellTouchendListenerFn = this.gridster.renderer.listen(this.gridster.el, 'touchend', this.emptyCellClickCb);\n } else if (!$options.enableEmptyCellClick && this.removeEmptyCellClickListenerFn && this.removeEmptyCellTouchendListenerFn) {\n this.removeEmptyCellClickListenerFn();\n this.removeEmptyCellTouchendListenerFn();\n this.removeEmptyCellClickListenerFn = null;\n this.removeEmptyCellTouchendListenerFn = null;\n }\n if ($options.enableEmptyCellContextMenu && !this.removeEmptyCellContextMenuListenerFn && options.emptyCellContextMenuCallback) {\n this.removeEmptyCellContextMenuListenerFn = this.gridster.renderer.listen(this.gridster.el, 'contextmenu', this.emptyCellContextMenuCb);\n } else if (!$options.enableEmptyCellContextMenu && this.removeEmptyCellContextMenuListenerFn) {\n this.removeEmptyCellContextMenuListenerFn();\n this.removeEmptyCellContextMenuListenerFn = null;\n }\n if ($options.enableEmptyCellDrop && !this.removeEmptyCellDropListenerFn && options.emptyCellDropCallback) {\n this.removeEmptyCellDropListenerFn = this.gridster.renderer.listen(this.gridster.el, 'drop', this.emptyCellDragDrop);\n this.gridster.zone.runOutsideAngular(() => {\n this.removeEmptyCellDragoverListenerFn = this.gridster.renderer.listen(this.gridster.el, 'dragover', this.emptyCellDragOver);\n });\n this.removeDocumentDragendListenerFn = this.gridster.renderer.listen('document', 'dragend', () => {\n this.gridster.movingItem = null;\n this.gridster.previewStyle();\n });\n } else if (\n !$options.enableEmptyCellDrop &&\n this.removeEmptyCellDropListenerFn &&\n this.removeEmptyCellDragoverListenerFn &&\n this.removeDocumentDragendListenerFn\n ) {\n this.removeEmptyCellDropListenerFn();\n this.removeEmptyCellDragoverListenerFn();\n this.removeDocumentDragendListenerFn();\n this.removeEmptyCellDragoverListenerFn = null;\n this.removeEmptyCellDropListenerFn = null;\n this.removeDocumentDragendListenerFn = null;\n }\n if ($options.enableEmptyCellDrag && !this.removeEmptyCellMousedownListenerFn && options.emptyCellDragCallback) {\n this.removeEmptyCellMousedownListenerFn = this.gridster.renderer.listen(this.gridster.el, 'mousedown', this.emptyCellMouseDown);\n this.removeEmptyCellTouchstartListenerFn = this.gridster.renderer.listen(this.gridster.el, 'touchstart', this.emptyCellMouseDown);\n } else if (!$options.enableEmptyCellDrag && this.removeEmptyCellMousedownListenerFn && this.removeEmptyCellTouchstartListenerFn) {\n this.removeEmptyCellMousedownListenerFn();\n this.removeEmptyCellTouchstartListenerFn();\n this.removeEmptyCellMousedownListenerFn = null;\n this.removeEmptyCellTouchstartListenerFn = null;\n }\n }\n\n emptyCellClickCb = (e: MouseEvent): void => {\n if (!this.gridster || this.gridster.movingItem || GridsterUtils.checkContentClassForEmptyCellClickEvent(this.gridster, e)) {\n return;\n }\n const item = this.getValidItemFromEvent(e);\n if (!item) {\n return;\n }\n const options = this.gridster.options();\n if (options.emptyCellClickCallback) {\n options.emptyCellClickCallback(e, item);\n }\n this.gridster.cdRef.markForCheck();\n };\n\n emptyCellContextMenuCb = (e: MouseEvent): void => {\n if (this.gridster.movingItem || GridsterUtils.checkContentClassForEmptyCellClickEvent(this.gridster, e)) {\n return;\n }\n e.preventDefault();\n e.stopPropagation();\n const item = this.getValidItemFromEvent(e);\n if (!item) {\n return;\n }\n const options = this.gridster.options();\n if (options.emptyCellContextMenuCallback) {\n options.emptyCellContextMenuCallback(e, item);\n }\n this.gridster.cdRef.markForCheck();\n };\n\n emptyCellDragDrop = (e: DragEvent): void => {\n const item = this.getValidItemFromEvent(e);\n if (!item) {\n return;\n }\n const options = this.gridster.options();\n if (options.emptyCellDropCallback) {\n options.emptyCellDropCallback(e, item);\n }\n this.gridster.cdRef.markForCheck();\n };\n\n emptyCellDragOver = (e: DragEvent): void => {\n e.preventDefault();\n e.stopPropagation();\n const item = this.getValidItemFromEvent(e);\n if (item) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = 'move';\n }\n this.gridster.movingItem = item;\n } else {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = 'none';\n }\n this.gridster.movingItem = null;\n }\n this.gridster.previewStyle();\n };\n\n emptyCellMouseDown = (e: MouseEvent): void => {\n if (GridsterUtils.checkContentClassForEmptyCellClickEvent(this.gridster, e)) {\n return;\n }\n e.preventDefault();\n e.stopPropagation();\n const item = this.getValidItemFromEvent(e);\n const leftMouseButtonCode = 1;\n if (!item || (e.buttons !== leftMouseButtonCode && !(e instanceof TouchEvent))) {\n return;\n }\n this.initialItem = item;\n this.gridster.movingItem = item;\n this.gridster.previewStyle();\n this.gridster.zone.runOutsideAngular(() => {\n this.removeWindowMousemoveListenerFn = this.gridster.renderer.listen('window', 'mousemove', this.emptyCellMouseMove);\n this.removeWindowTouchmoveListenerFn = this.gridster.renderer.listen('window', 'touchmove', this.emptyCellMouseMove);\n });\n this.removeWindowMouseupListenerFn = this.gridster.renderer.listen('window', 'mouseup', this.emptyCellMouseUp);\n this.removeWindowTouchendListenerFn = this.gridster.renderer.listen('window', 'touchend', this.emptyCellMouseUp);\n };\n\n emptyCellMouseMove = (e: MouseEvent): void => {\n e.preventDefault();\n e.stopPropagation();\n const item = this.getValidItemFromEvent(e, this.initialItem);\n if (!item) {\n return;\n }\n\n this.gridster.movingItem = item;\n this.gridster.previewStyle();\n };\n\n emptyCellMouseUp = (e: MouseEvent): void => {\n this.removeWindowMousemoveListenerFn();\n this.removeWindowTouchmoveListenerFn();\n this.removeWindowMouseupListenerFn();\n this.removeWindowTouchendListenerFn();\n const item = this.getValidItemFromEvent(e, this.initialItem);\n if (item) {\n this.gridster.movingItem = item;\n }\n const options = this.gridster.options();\n if (options.emptyCellDragCallback && this.gridster.movingItem) {\n options.emptyCellDragCallback(e, this.gridster.movingItem);\n }\n setTimeout(() => {\n this.initialItem = null;\n if (this.gridster) {\n this.gridster.movingItem = null;\n this.gridster.previewStyle();\n }\n });\n this.gridster.cdRef.markForCheck();\n };\n\n getPixelsX(e: MouseEvent, rect: ClientRect): number {\n const scale = this.gridster.options().scale;\n if (scale) {\n return (e.clientX - rect.left) / scale + this.gridster.el.scrollLeft - this.gridster.gridRenderer.getLeftMargin();\n }\n return e.clientX + this.gridster.el.scrollLeft - rect.left - this.gridster.gridRenderer.getLeftMargin();\n }\n\n getPixelsY(e: MouseEvent, rect: ClientRect): number {\n const scale = this.gridster.options().scale;\n if (scale) {\n return (e.clientY - rect.top) / scale + this.gridster.el.scrollTop - this.gridster.gridRenderer.getTopMargin();\n }\n return e.clientY + this.gridster.el.scrollTop - rect.top - this.gridster.gridRenderer.getTopMargin();\n }\n\n getValidItemFromEvent(e: MouseEvent, oldItem?: GridsterItemConfig | null): GridsterItemConfig | undefined {\n e.preventDefault();\n e.stopPropagation();\n GridsterUtils.checkTouchEvent(e);\n const rect = this.gridster.el.getBoundingClientRect();\n const x = this.getPixelsX(e, rect);\n const y = this.getPixelsY(e, rect);\n const $options = this.gridster.$options();\n const item: GridsterItemConfig = {\n x: this.gridster.pixelsToPositionX(x, Math.floor, true),\n y: this.gridster.pixelsToPositionY(y, Math.floor, true),\n cols: $options.defaultItemCols,\n rows: $options.defaultItemRows\n };\n if (oldItem) {\n item.cols = Math.min(Math.abs(oldItem.x - item.x) + 1, $options.emptyCellDragMaxCols);\n item.rows = Math.min(Math.abs(oldItem.y - item.y) + 1, $options.emptyCellDragMaxRows);\n if (oldItem.x < item.x) {\n item.x = oldItem.x;\n } else if (oldItem.x - item.x > $options.emptyCellDragMaxCols - 1) {\n item.x = this.gridster.movingItem ? this.gridster.movingItem.x : 0;\n }\n if (oldItem.y < item.y) {\n item.y = oldItem.y;\n } else if (oldItem.y - item.y > $options.emptyCellDragMaxRows - 1) {\n item.y = this.gridster.movingItem ? this.gridster.movingItem.y : 0;\n }\n }\n if (!$options.enableOccupiedCellDrop && this.gridster.checkCollision(item)) {\n return;\n }\n return item;\n }\n}\n","import { ChangeDetectionStrategy, Component, ElementRef, inject, Renderer2, ViewEncapsulation } from '@angular/core';\n\nimport { Gridster } from './gridster';\nimport { GridsterItemConfig } from './gridsterItemConfig';\n\n@Component({\n selector: 'gridster-preview',\n template: '',\n styleUrl: './gridsterPreview.css',\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None\n})\nexport class GridsterPreview {\n private readonly el = inject<ElementRef<HTMLElement>>(ElementRef).nativeElement;\n private readonly gridster = inject(Gridster);\n private readonly renderer = inject(Renderer2);\n\n previewStyle(item: GridsterItemConfig | null): void {\n if (item) {\n this.renderer.setStyle(this.el, 'display', 'block');\n this.gridster.gridRenderer.updateItem(this.el, item, this.renderer);\n } else {\n this.renderer.setStyle(this.el, 'display', '');\n }\n }\n}\n","import { Renderer2 } from '@angular/core';\n\nimport { Gridster } from './gridster';\nimport { DirTypes, GridType } from './gridsterConfig';\nimport { GridsterItemConfig } from './gridsterItemConfig';\nimport { CommonGridStyle, GridColumnCachedStyle, GridRowCachedStyle } from './gridsterRendererTypes';\n\nexport class GridsterRenderer {\n /**\n * Caches the last grid column styles.\n * This improves the grid responsiveness by caching and reusing the last style object instead of creating a new one.\n */\n private lastGridColumnStyles: Record<number, GridColumnCachedStyle> = {};\n\n /**\n * Caches the last grid column styles.\n * This improves the grid responsiveness by caching and reusing the last style object instead of creating a new one.\n */\n private lastGridRowStyles: Record<number, GridRowCachedStyle> = {};\n\n constructor(private gridster: Gridster) {}\n\n updateItem(el: Element, item: GridsterItemConfig, renderer: Renderer2): void {\n const $options = this.gridster.$options();\n if (this.gridster.mobile) {\n this.clearCellPosition(renderer, el);\n if ($options.keepFixedHeightInMobile) {\n renderer.setStyle(el, 'height', (item.rows - 1) * $options.margin + item.rows * $options.fixedRowHeight + 'px');\n } else {\n renderer.setStyle(el, 'height', (item.rows * this.gridster.curWidth) / item.cols + 'px');\n }\n if ($options.keepFixedWidthInMobile) {\n renderer.setStyle(el, 'width', $options.fixedColWidth + 'px');\n } else {\n renderer.setStyle(el, 'width', '');\n }\n\n renderer.setStyle(el, 'margin-bottom', $options.margin + 'px');\n renderer.setStyle(el, DirTypes.LTR ? 'margin-right' : 'margin-left', '');\n } else {\n const x = Math.round(this.gridster.curColWidth * item.x);\n const y = Math.round(this.gridster.curRowHeight * item.y);\n const width = this.gridster.curColWidth * item.cols - $options.margin;\n const height = this.gridster.curRowHeight * item.rows - $options.margin;\n // set the cell style\n this.setCellPosition(renderer, el, x, y);\n renderer.setStyle(el, 'width', width + 'px');\n renderer.setStyle(el, 'height', height + 'px');\n let marginBottom: string | null = null;\n let marginRight: string | null = null;\n if ($options.outerMargin) {\n if (this.gridster.rows === item.rows + item.y) {\n if ($options.outerMarginBottom !== null) {\n marginBottom = $options.outerMarginBottom + 'px';\n } else {\n marginBottom = $options.margin + 'px';\n }\n }\n if (this.gridster.columns === item.cols + item.x) {\n if ($options.outerMarginBottom !== null) {\n marginRight = $options.outerMarginRight + 'px';\n } else {\n marginRight = $options.margin + 'px';\n }\n }\n }\n\n renderer.setStyle(el, 'margin-bottom', marginBottom);\n renderer.setStyle(el, $options.dirType === DirTypes.LTR ? 'margin-right' : 'margin-left', marginRight);\n }\n }\n\n updateGridster(): void {\n const $options = this.gridster.$options();\n let addClass = '';\n let removeClass1 = '';\n let removeClass2 = '';\n let removeClass3 = '';\n if ($options.gridType === GridType.Fit) {\n addClass = GridType.Fit;\n removeClass1 = GridType.ScrollVertical;\n removeClass2 = GridType.ScrollHorizontal;\n removeClass3 = GridType.Fixed;\n } else if ($options.gridType === GridType.ScrollVertical) {\n this.gridster.curRowHeight = this.gridster.curColWidth * $options.rowHeightRatio;\n addClass = GridType.ScrollVertical;\n removeClass1 = GridType.Fit;\n removeClass2 = GridType.ScrollHorizontal;\n removeClass3 = GridType.Fixed;\n } else if ($options.gridType === GridType.ScrollHorizontal) {\n const widthRatio = $options.rowHeightRatio;\n const calWidthRatio = widthRatio >= 1 ? widthRatio : widthRatio + 1;\n this.gridster.curColWidth = this.gridster.curRowHeight * calWidthRatio;\n addClass = GridType.ScrollHorizontal;\n removeClass1 = GridType.Fit;\n removeClass2 = GridType.ScrollVertical;\n removeClass3 = GridType.Fixed;\n } else if ($options.gridType === GridType.Fixed) {\n this.gridster.curColWidth = $options.fixedColWidth + ($options.ignoreMarginInRow ? 0 : $options.margin);\n this.gridster.curRowHeight = $options.fixedRowHeight + ($options.ignoreMarginInRow ? 0 : $options.margin);\n addClass = GridType.Fixed;\n removeClass1 = GridType.Fit;\n removeClass2 = GridType.ScrollVertical;\n removeClass3 = GridType.ScrollHorizontal;\n } else if ($options.gridType === GridType.VerticalFixed) {\n this.gridster.curRowHeight = $options.fixedRowHeight + ($options.ignoreMarginInRow ? 0 : $options.margin);\n addClass = GridType.ScrollVertical;\n removeClass1 = GridType.Fit;\n removeClass2 = GridType.ScrollHorizontal;\n removeClass3 = GridType.Fixed;\n } else if ($options.gridType === GridType.HorizontalFixed) {\n this.gridster.curColWidth = $options.fixedColWidth + ($options.ignoreMarginInRow ? 0 : $options.margin);\n addClass = GridType.ScrollHorizontal;\n removeClass1 = GridType.Fit;\n removeClass2 = GridType.ScrollVertical;\n removeClass3 = GridType.Fixed;\n }\n\n if (this.gridster.mobile || ($options.setGridSize && $options.gridType !== GridType.Fit)) {\n this.gridster.renderer.removeClass(this.gridster.el, addClass);\n } else {\n this.gridster.renderer.addClass(this.gridster.el, addClass);\n }\n this.gridster.renderer.removeClass(this.gridster.el, removeClass1);\n this.gridster.renderer.removeClass(this.gridster.el, removeClass2);\n this.gridster.renderer.removeClass(this.gridster.el, removeClass3);\n }\n\n getGridColumnStyle(i: number): CommonGridStyle {\n const margin = this.gridster.$options().margin;\n // generates the new style\n const newPos: GridColumnCachedStyle = {\n left: this.gridster.curColWidth * i,\n width: this.gridster.curColWidth - margin,\n height: this.gridster.gridRows.length * this.gridster.curRowHeight - margin,\n style: {}\n };\n newPos.style = {\n ...this.getLeftPosition(newPos.left),\n width: newPos.width + 'px',\n height: newPos.height + 'px'\n };\n\n // use the last cached style if it has same values as the generated one\n const last = this.lastGridColumnStyles[i];\n if (last && last.left === newPos.left && last.width === newPos.width && last.height === newPos.height) {\n return last.style;\n }\n\n // cache and set new style\n this.lastGridColumnStyles[i] = newPos;\n return newPos.style;\n }\n\n getGridRowStyle(i: number): CommonGridStyle {\n const margin = this.gridster.$options().margin;\n // generates the new style\n const newPos: GridRowCachedStyle = {\n top: this.gridster.curRowHeight * i,\n width: this.gridster.gridColumns.length * this.gridster.curColWidth + margin,\n height: this.gridster.curRowHeight - margin,\n style: {}\n };\n newPos.style = {\n ...this.getTopPosition(newPos.top),\n width: newPos.width + 'px',\n height: newPos.height + 'px'\n };\n\n // use the last cached style if it has same values as the generated one\n const last = this.lastGridRowStyles[i];\n if (last && last.top === newPos.top && last.width === newPos.width && last.height === newPos.height) {\n return last.style;\n }\n\n // cache and set new style\n this.lastGridRowStyles[i] = newPos;\n return newPos.style;\n }\n\n getLeftPosition(d: number): { left: string } | { transform: string } {\n const $options = this.gridster.$options();\n const dPosition = $options.dirType === DirTypes.RTL ? -d : d;\n if ($options.useTransformPositioning) {\n return {\n transform: 'translateX(' + dPosition + 'px)'\n };\n } else {\n return {\n left: this.getLeftMargin() + dPosition + 'px'\n };\n }\n }\n\n getTopPosition(d: number): { top: string } | { transform: string } {\n if (this.gridster.$options().useTransformPositioning) {\n return {\n transform: 'translateY(' + d + 'px)'\n };\n } else {\n return {\n top: this.getTopMargin() + d + 'px'\n };\n }\n }\n\n clearCellPosition(renderer: Renderer2, el: Element): void {\n if (this.gridster.$options().useTransformPositioning) {\n renderer.setStyle(el, 'transform', '');\n } else {\n renderer.setStyle(el, 'top', '');\n renderer.setStyle(el, 'left', '');\n }\n }\n\n setCellPosition(renderer: Renderer2, el: Element, x: number, y: number): void {\n const $options = this.gridster.$options();\n const xPosition = this.gridster.$options().dirType === DirTypes.RTL ? -x : x;\n if (this.gridster.$options().useTransformPositioning) {\n const transform = 'translate3d(' + xPosition + 'px, ' + y + 'px, 0)';\n renderer.setStyle(el, 'transform', transform);\n } else {\n renderer.setStyle(el, 'left', this.getLeftMargin() + xPosition + 'px');\n renderer.setStyle(el, 'top', this.getTopMargin() + y + 'px');\n }\n }\n\n getLeftMargin(): number {\n const $options = this.gridster.$options();\n if ($options.outerMargin) {\n if ($options.outerMarginLeft !== null) {\n return $options.outerMarginLeft;\n } else {\n return $options.margin;\n }\n } else {\n return 0;\n }\n }\n\n getTopMargin(): number {\n const $options = this.gridster.$options();\n if ($options.outerMargin) {\n if ($options.outerMarginTop !== null) {\n return $options.outerMarginTop;\n } else {\n return $options.margin;\n }\n } else {\n return 0;\n }\n }\n}\n","import { NgStyle } from '@angular/common';\nimport {\n ChangeDetectionStrategy,\n ChangeDetectorRef,\n Component,\n computed,\n effect,\n ElementRef,\n inject,\n input,\n NgZone,\n OnDestroy,\n OnInit,\n Renderer2,\n viewChild,\n ViewEncapsulation\n} from '@angular/core';\nimport { debounceTime, Subject, switchMap, takeUntil, timer } from 'rxjs';\n\nimport { GridsterCompact } from './gridsterCompact';\nimport type { GridsterApi, GridsterConfig, GridsterConfigStrict } from './gridsterConfig';\nimport { GridType } from './gridsterConfig';\nimport { GridsterConfigService } from './gridsterConfig.constant';\nimport { GridsterEmptyCell } from './gridsterEmptyCell';\nimport { GridsterItem } from './gridsterItem';\nimport { GridsterItemConfig } from './gridsterItemConfig';\nimport { GridsterPreview } from './gridsterPreview';\nimport { GridsterRenderer } from './gridsterRenderer';\nimport { GridsterUtils } from './gridsterUtils';\n\n@Component({\n selector: 'gridster',\n templateUrl: './gridster.html',\n styleUrl: './gridster.css',\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n imports: [NgStyle, GridsterPreview]\n})\nexport class Gridster implements OnInit, OnDestroy {\n readonly