Angular Grid Layout
![PRs](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square)
Angular Grid Layout is a grid layout system with draggable and resizable items for Angular Applications. It is mainly designed to create highly customizable dashboards.
Its core functionalities are based in the well known React-Grid-Layout library. It can be considered a 'port' (with some changes) to the Angular ecosystem.
Both cover the same necessities.
![demo example](https://github.com/katoid/angular-grid-layout/raw/HEAD/./assets/demo.gif)
Features
- No dependencies
- Draggable items
- Resizable items
- REDUX friendly (akita, ngrx, ngxs...)
- Customizable Drag & Resize handles.
- 3 modes of grid compaction: vertical, horizontal and free (exact same algorithm as React-Grid-Layout)
- Add/Remove items
- High performance
- Supports touch devices
- Auto-scrolling while dragging
Compatibility
Version | Compatibility |
---|
>= 3.0.0 | Angular 16, 17 & 18 |
>= 2.0.0 | Angular 14, 15 |
>= 1.1.0 && < 2.0.0 | Angular 12, 13 & 14 |
>= 0.1.1 && < 1.1.0 | Angular 9, 10 & 11 |
Demos
Playground - Stackblitz
Custom handles
Real life example
Installation
To use @katoid/angular-grid-layout in your project install it via npm:
npm install @katoid/angular-grid-layout --save
Usage
Import KtdGridModule to the module where you want to use the grid:
import { KtdGridModule } from '@katoid/angular-grid-layout';
@NgModule({
imports: [KtdGridModule]
})
Use it in your template:
<ktd-grid [cols]="cols"
[rowHeight]="rowHeight"
[layout]="layout"
(layoutUpdated)="onLayoutUpdated($event)">
<ktd-grid-item *ngFor="let item of layout; trackBy:trackById" [id]="item.id">
<ng-template ktdGridItemPlaceholder>
</ng-template>
</ktd-grid-item>
</ktd-grid>
Where template variables could be:
import { ktdTrackById } from '@katoid/angular-grid-layout';
cols: number = 6;
rowHeight: number = 100;
layout: KtdGridLayout = [
{id: '0', x: 0, y: 0, w: 3, h: 3},
{id: '1', x: 3, y: 0, w: 3, h: 3},
{id: '2', x: 0, y: 3, w: 3, h: 3, minW: 2, minH: 3},
{id: '3', x: 3, y: 3, w: 3, h: 3, minW: 2, maxW: 3, minH: 2, maxH: 5},
];
trackById = ktdTrackById
API
Here is listed the basic API of both KtdGridComponent and KtdGridItemComponent. See source code for full knowledge of the API.
KtdGridComponent
@Input() compactType: KtdGridCompactType = 'vertical';
@Input() rowHeight: number | 'fit' = 100;
@Input() cols: number = 6;
@Input() layout: KtdGridLayout;
@Input() gap: number = 0;
@Input() height: number | null = null;
@Input() scrollableParent: HTMLElement | Document | string | null = null;
@Input() scrollSpeed: number = 2;
@Input() compactOnPropsChange = true;
@Input() preventCollision = false;
@Output() layoutUpdated: EventEmitter<KtdGridLayout> = new EventEmitter<KtdGridLayout>();
@Output() dragStarted: EventEmitter<KtdDragStart> = new EventEmitter<KtdDragStart>();
@Output() resizeStarted: EventEmitter<KtdResizeStart> = new EventEmitter<KtdResizeStart>();
@Output() dragEnded: EventEmitter<KtdDragEnd> = new EventEmitter<KtdDragEnd>();
@Output() resizeEnded: EventEmitter<KtdResizeEnd> = new EventEmitter<KtdResizeEnd>();
@Output() gridItemResize: EventEmitter<KtdGridItemResizeEvent> = new EventEmitter<KtdGridItemResizeEvent>();
KtdGridItem
@Input() id: string;
@Input() minW?: number;
@Input() minH?: number;
@Input() maxW?: number;
@Input() maxH?: number;
@Input() draggable: boolean = true;
@Input() resizable: boolean = true;
@Input() transition: string = 'transform 500ms ease, width 500ms ease, height 500ms ease';
@Input() dragStartThreshold: number = 0;
startDragManually(startEvent: MouseEvent | TouchEvent);
TODO features
IMPORTANT: These features would be done in the near future. If any lib user needs them earlier, we encourage you to contribute to this project and speed up the process! To do so, please:
- Open an issue mentioning one of these features.
- Explain your thoughts on how to implement it & we will discuss the possible solutions.
- Do a Merge Request when the feature is done and tested.
Troubleshooting
- Mutating the layout would cause an error like: 'ERROR TypeError: Cannot read property 'id' of undefined'. Never mutate the layout, always return a new instance when modifying it.
- Always use trackBy for the ngFor that renders the ktd-grid-items. If not, Angular would always re-render all items when layout changes.
- My Grid Item 'content' doesn't resize well when size changes. This may be caused for 'transform' property in ktd-grid-item, try to remove transform animations on 'width' and 'height' properties. You can also watch the real-life-example which uses other technique valid also.