UNPKG

@swimlane/ngx-datatable

Version:

ngx-datatable is an Angular table grid component for presenting large and complex data.

863 lines 85.5 kB
import { Component, Output, EventEmitter, Input, HostBinding, ViewChild, ChangeDetectionStrategy } from '@angular/core'; import { ScrollerComponent } from './scroller.component'; import { columnsByPin, columnGroupWidths } from '../../utils/column'; import { RowHeightCache } from '../../utils/row-height-cache'; import { translateXY } from '../../utils/translate'; import * as i0 from "@angular/core"; import * as i1 from "./progress-bar.component"; import * as i2 from "./selection.component"; import * as i3 from "./scroller.component"; import * as i4 from "./summary/summary-row.component"; import * as i5 from "./body-row-wrapper.component"; import * as i6 from "./body-row.component"; import * as i7 from "@angular/common"; export class DataTableBodyComponent { /** * Creates an instance of DataTableBodyComponent. */ constructor(cd) { this.cd = cd; this.selected = []; this.scroll = new EventEmitter(); this.page = new EventEmitter(); this.activate = new EventEmitter(); this.select = new EventEmitter(); this.detailToggle = new EventEmitter(); this.rowContextmenu = new EventEmitter(false); this.treeAction = new EventEmitter(); this.rowHeightsCache = new RowHeightCache(); this.temp = []; this.offsetY = 0; this.indexes = {}; this.rowIndexes = new WeakMap(); this.rowExpansions = []; /** * Get the height of the detail row. */ this.getDetailRowHeight = (row, index) => { if (!this.rowDetail) { return 0; } const rowHeight = this.rowDetail.rowHeight; return typeof rowHeight === 'function' ? rowHeight(row, index) : rowHeight; }; // declare fn here so we can get access to the `this` property this.rowTrackingFn = (index, row) => { const idx = this.getRowIndex(row); if (this.trackByProp) { return row[this.trackByProp]; } else { return idx; } }; } set pageSize(val) { this._pageSize = val; this.recalcLayout(); } get pageSize() { return this._pageSize; } set rows(val) { this._rows = val; this.recalcLayout(); } get rows() { return this._rows; } set columns(val) { this._columns = val; const colsByPin = columnsByPin(val); this.columnGroupWidths = columnGroupWidths(colsByPin, val); } get columns() { return this._columns; } set offset(val) { this._offset = val; if (!this.scrollbarV || (this.scrollbarV && !this.virtualization)) this.recalcLayout(); } get offset() { return this._offset; } set rowCount(val) { this._rowCount = val; this.recalcLayout(); } get rowCount() { return this._rowCount; } get bodyWidth() { if (this.scrollbarH) { return this.innerWidth + 'px'; } else { return '100%'; } } set bodyHeight(val) { if (this.scrollbarV) { this._bodyHeight = val + 'px'; } else { this._bodyHeight = 'auto'; } this.recalcLayout(); } get bodyHeight() { return this._bodyHeight; } /** * Returns if selection is enabled. */ get selectEnabled() { return !!this.selectionType; } /** * Property that would calculate the height of scroll bar * based on the row heights cache for virtual scroll and virtualization. Other scenarios * calculate scroll height automatically (as height will be undefined). */ get scrollHeight() { if (this.scrollbarV && this.virtualization && this.rowCount) { return this.rowHeightsCache.query(this.rowCount - 1); } // avoid TS7030: Not all code paths return a value. return undefined; } /** * Called after the constructor, initializing input properties */ ngOnInit() { if (this.rowDetail) { this.listener = this.rowDetail.toggle.subscribe(({ type, value }) => { if (type === 'row') { this.toggleRowExpansion(value); } if (type === 'all') { this.toggleAllRows(value); } // Refresh rows after toggle // Fixes #883 this.updateIndexes(); this.updateRows(); this.cd.markForCheck(); }); } if (this.groupHeader) { this.listener = this.groupHeader.toggle.subscribe(({ type, value }) => { if (type === 'group') { this.toggleRowExpansion(value); } if (type === 'all') { this.toggleAllRows(value); } // Refresh rows after toggle // Fixes #883 this.updateIndexes(); this.updateRows(); this.cd.markForCheck(); }); } } /** * Called once, before the instance is destroyed. */ ngOnDestroy() { if (this.rowDetail || this.groupHeader) { this.listener.unsubscribe(); } } /** * Updates the Y offset given a new offset. */ updateOffsetY(offset) { // scroller is missing on empty table if (!this.scroller) { return; } if (this.scrollbarV && this.virtualization && offset) { // First get the row Index that we need to move to. const rowIndex = this.pageSize * offset; offset = this.rowHeightsCache.query(rowIndex - 1); } else if (this.scrollbarV && !this.virtualization) { offset = 0; } this.scroller.setOffset(offset || 0); } /** * Body was scrolled, this is mainly useful for * when a user is server-side pagination via virtual scroll. */ onBodyScroll(event) { const scrollYPos = event.scrollYPos; const scrollXPos = event.scrollXPos; // if scroll change, trigger update // this is mainly used for header cell positions if (this.offsetY !== scrollYPos || this.offsetX !== scrollXPos) { this.scroll.emit({ offsetY: scrollYPos, offsetX: scrollXPos }); } this.offsetY = scrollYPos; this.offsetX = scrollXPos; this.updateIndexes(); this.updatePage(event.direction); this.updateRows(); } /** * Updates the page given a direction. */ updatePage(direction) { let offset = this.indexes.first / this.pageSize; if (direction === 'up') { offset = Math.ceil(offset); } else if (direction === 'down') { offset = Math.floor(offset); } if (direction !== undefined && !isNaN(offset)) { this.page.emit({ offset }); } } /** * Updates the rows in the view port */ updateRows() { const { first, last } = this.indexes; let rowIndex = first; let idx = 0; const temp = []; // if grouprowsby has been specified treat row paging // parameters as group paging parameters ie if limit 10 has been // specified treat it as 10 groups rather than 10 rows if (this.groupedRows) { let maxRowsPerGroup = 3; // if there is only one group set the maximum number of // rows per group the same as the total number of rows if (this.groupedRows.length === 1) { maxRowsPerGroup = this.groupedRows[0].value.length; } while (rowIndex < last && rowIndex < this.groupedRows.length) { // Add the groups into this page const group = this.groupedRows[rowIndex]; this.rowIndexes.set(group, rowIndex); if (group.value) { // add indexes for each group item group.value.forEach((g, i) => { const _idx = `${rowIndex}-${i}`; this.rowIndexes.set(g, _idx); }); } temp[idx] = group; idx++; // Group index in this context rowIndex++; } } else { while (rowIndex < last && rowIndex < this.rowCount) { const row = this.rows[rowIndex]; if (row) { // add indexes for each row this.rowIndexes.set(row, rowIndex); temp[idx] = row; } idx++; rowIndex++; } } this.temp = temp; } /** * Get the row height */ getRowHeight(row) { // if its a function return it if (typeof this.rowHeight === 'function') { return this.rowHeight(row); } return this.rowHeight; } /** * @param group the group with all rows */ getGroupHeight(group) { let rowHeight = 0; if (group.value) { for (let index = 0; index < group.value.length; index++) { rowHeight += this.getRowAndDetailHeight(group.value[index]); } } return rowHeight; } /** * Calculate row height based on the expanded state of the row. */ getRowAndDetailHeight(row) { let rowHeight = this.getRowHeight(row); const expanded = this.getRowExpanded(row); // Adding detail row height if its expanded. if (expanded) { rowHeight += this.getDetailRowHeight(row); } return rowHeight; } /** * Calculates the styles for the row so that the rows can be moved in 2D space * during virtual scroll inside the DOM. In the below case the Y position is * manipulated. As an example, if the height of row 0 is 30 px and row 1 is * 100 px then following styles are generated: * * transform: translate3d(0px, 0px, 0px); -> row0 * transform: translate3d(0px, 30px, 0px); -> row1 * transform: translate3d(0px, 130px, 0px); -> row2 * * Row heights have to be calculated based on the row heights cache as we wont * be able to determine which row is of what height before hand. In the above * case the positionY of the translate3d for row2 would be the sum of all the * heights of the rows before it (i.e. row0 and row1). * * @param rows the row that needs to be placed in the 2D space. * @returns the CSS3 style to be applied * * @memberOf DataTableBodyComponent */ getRowsStyles(rows) { const styles = {}; // only add styles for the group if there is a group if (this.groupedRows) { styles.width = this.columnGroupWidths.total; } if (this.scrollbarV && this.virtualization) { let idx = 0; if (this.groupedRows) { // Get the latest row rowindex in a group const row = rows[rows.length - 1]; idx = row ? this.getRowIndex(row) : 0; } else { idx = this.getRowIndex(rows); } // const pos = idx * rowHeight; // The position of this row would be the sum of all row heights // until the previous row position. const pos = this.rowHeightsCache.query(idx - 1); translateXY(styles, 0, pos); } return styles; } /** * Calculate bottom summary row offset for scrollbar mode. * For more information about cache and offset calculation * see description for `getRowsStyles` method * * @returns the CSS3 style to be applied * * @memberOf DataTableBodyComponent */ getBottomSummaryRowStyles() { if (!this.scrollbarV || !this.rows || !this.rows.length) { return null; } const styles = { position: 'absolute' }; const pos = this.rowHeightsCache.query(this.rows.length - 1); translateXY(styles, 0, pos); return styles; } /** * Hides the loading indicator */ hideIndicator() { setTimeout(() => (this.loadingIndicator = false), 500); } /** * Updates the index of the rows in the viewport */ updateIndexes() { let first = 0; let last = 0; if (this.scrollbarV) { if (this.virtualization) { // Calculation of the first and last indexes will be based on where the // scrollY position would be at. The last index would be the one // that shows up inside the view port the last. const height = parseInt(this.bodyHeight, 0); first = this.rowHeightsCache.getRowIndex(this.offsetY); last = this.rowHeightsCache.getRowIndex(height + this.offsetY) + 1; } else { // If virtual rows are not needed // We render all in one go first = 0; last = this.rowCount; } } else { // The server is handling paging and will pass an array that begins with the // element at a specified offset. first should always be 0 with external paging. if (!this.externalPaging) { first = Math.max(this.offset * this.pageSize, 0); } last = Math.min(first + this.pageSize, this.rowCount); } this.indexes = { first, last }; } /** * Refreshes the full Row Height cache. Should be used * when the entire row array state has changed. */ refreshRowHeightCache() { if (!this.scrollbarV || (this.scrollbarV && !this.virtualization)) { return; } // clear the previous row height cache if already present. // this is useful during sorts, filters where the state of the // rows array is changed. this.rowHeightsCache.clearCache(); // Initialize the tree only if there are rows inside the tree. if (this.rows && this.rows.length) { const rowExpansions = new Set(); for (const row of this.rows) { if (this.getRowExpanded(row)) { rowExpansions.add(row); } } this.rowHeightsCache.initCache({ rows: this.rows, rowHeight: this.rowHeight, detailRowHeight: this.getDetailRowHeight, externalVirtual: this.scrollbarV && this.externalPaging, rowCount: this.rowCount, rowIndexes: this.rowIndexes, rowExpansions }); } } /** * Gets the index for the view port */ getAdjustedViewPortIndex() { // Capture the row index of the first row that is visible on the viewport. // If the scroll bar is just below the row which is highlighted then make that as the // first index. const viewPortFirstRowIndex = this.indexes.first; if (this.scrollbarV && this.virtualization) { const offsetScroll = this.rowHeightsCache.query(viewPortFirstRowIndex - 1); return offsetScroll <= this.offsetY ? viewPortFirstRowIndex - 1 : viewPortFirstRowIndex; } return viewPortFirstRowIndex; } /** * Toggle the Expansion of the row i.e. if the row is expanded then it will * collapse and vice versa. Note that the expanded status is stored as * a part of the row object itself as we have to preserve the expanded row * status in case of sorting and filtering of the row set. */ toggleRowExpansion(row) { // Capture the row index of the first row that is visible on the viewport. const viewPortFirstRowIndex = this.getAdjustedViewPortIndex(); const rowExpandedIdx = this.getRowExpandedIdx(row, this.rowExpansions); const expanded = rowExpandedIdx > -1; // If the detailRowHeight is auto --> only in case of non-virtualized scroll if (this.scrollbarV && this.virtualization) { const detailRowHeight = this.getDetailRowHeight(row) * (expanded ? -1 : 1); // const idx = this.rowIndexes.get(row) || 0; const idx = this.getRowIndex(row); this.rowHeightsCache.update(idx, detailRowHeight); } // Update the toggled row and update thive nevere heights in the cache. if (expanded) { this.rowExpansions.splice(rowExpandedIdx, 1); } else { this.rowExpansions.push(row); } this.detailToggle.emit({ rows: [row], currentIndex: viewPortFirstRowIndex }); } /** * Expand/Collapse all the rows no matter what their state is. */ toggleAllRows(expanded) { // clear prev expansions this.rowExpansions = []; // Capture the row index of the first row that is visible on the viewport. const viewPortFirstRowIndex = this.getAdjustedViewPortIndex(); if (expanded) { for (const row of this.rows) { this.rowExpansions.push(row); } } if (this.scrollbarV) { // Refresh the full row heights cache since every row was affected. this.recalcLayout(); } // Emit all rows that have been expanded. this.detailToggle.emit({ rows: this.rows, currentIndex: viewPortFirstRowIndex }); } /** * Recalculates the table */ recalcLayout() { this.refreshRowHeightCache(); this.updateIndexes(); this.updateRows(); } /** * Tracks the column */ columnTrackingFn(index, column) { return column.$$id; } /** * Gets the row pinning group styles */ stylesByGroup(group) { const widths = this.columnGroupWidths; const offsetX = this.offsetX; const styles = { width: `${widths[group]}px` }; if (group === 'left') { translateXY(styles, offsetX, 0); } else if (group === 'right') { const bodyWidth = parseInt(this.innerWidth + '', 0); const totalDiff = widths.total - bodyWidth; const offsetDiff = totalDiff - offsetX; const offset = offsetDiff * -1; translateXY(styles, offset, 0); } return styles; } /** * Returns if the row was expanded and set default row expansion when row expansion is empty */ getRowExpanded(row) { if (this.rowExpansions.length === 0 && this.groupExpansionDefault) { for (const group of this.groupedRows) { this.rowExpansions.push(group); } } return this.getRowExpandedIdx(row, this.rowExpansions) > -1; } getRowExpandedIdx(row, expanded) { if (!expanded || !expanded.length) return -1; const rowId = this.rowIdentity(row); return expanded.findIndex(r => { const id = this.rowIdentity(r); return id === rowId; }); } /** * Gets the row index given a row */ getRowIndex(row) { return this.rowIndexes.get(row) || 0; } onTreeAction(row) { this.treeAction.emit({ row }); } } DataTableBodyComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: DataTableBodyComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); DataTableBodyComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.1.1", type: DataTableBodyComponent, selector: "datatable-body", inputs: { scrollbarV: "scrollbarV", scrollbarH: "scrollbarH", loadingIndicator: "loadingIndicator", externalPaging: "externalPaging", rowHeight: "rowHeight", offsetX: "offsetX", emptyMessage: "emptyMessage", selectionType: "selectionType", selected: "selected", rowIdentity: "rowIdentity", rowDetail: "rowDetail", groupHeader: "groupHeader", selectCheck: "selectCheck", displayCheck: "displayCheck", trackByProp: "trackByProp", rowClass: "rowClass", groupedRows: "groupedRows", groupExpansionDefault: "groupExpansionDefault", innerWidth: "innerWidth", groupRowsBy: "groupRowsBy", virtualization: "virtualization", summaryRow: "summaryRow", summaryPosition: "summaryPosition", summaryHeight: "summaryHeight", pageSize: "pageSize", rows: "rows", columns: "columns", offset: "offset", rowCount: "rowCount", bodyHeight: "bodyHeight" }, outputs: { scroll: "scroll", page: "page", activate: "activate", select: "select", detailToggle: "detailToggle", rowContextmenu: "rowContextmenu", treeAction: "treeAction" }, host: { properties: { "style.width": "this.bodyWidth", "style.height": "this.bodyHeight" }, classAttribute: "datatable-body" }, viewQueries: [{ propertyName: "scroller", first: true, predicate: ScrollerComponent, descendants: true }], ngImport: i0, template: ` <datatable-progress *ngIf="loadingIndicator"> </datatable-progress> <datatable-selection #selector [selected]="selected" [rows]="rows" [selectCheck]="selectCheck" [selectEnabled]="selectEnabled" [selectionType]="selectionType" [rowIdentity]="rowIdentity" (select)="select.emit($event)" (activate)="activate.emit($event)" > <datatable-scroller *ngIf="rows?.length" [scrollbarV]="scrollbarV" [scrollbarH]="scrollbarH" [scrollHeight]="scrollHeight" [scrollWidth]="columnGroupWidths?.total" (scroll)="onBodyScroll($event)" > <datatable-summary-row *ngIf="summaryRow && summaryPosition === 'top'" [rowHeight]="summaryHeight" [offsetX]="offsetX" [innerWidth]="innerWidth" [rows]="rows" [columns]="columns" > </datatable-summary-row> <datatable-row-wrapper [groupedRows]="groupedRows" *ngFor="let group of temp; let i = index; trackBy: rowTrackingFn" [innerWidth]="innerWidth" [ngStyle]="getRowsStyles(group)" [rowDetail]="rowDetail" [groupHeader]="groupHeader" [offsetX]="offsetX" [detailRowHeight]="getDetailRowHeight(group && group[i], i)" [row]="group" [expanded]="getRowExpanded(group)" [rowIndex]="getRowIndex(group && group[i])" (rowContextmenu)="rowContextmenu.emit($event)" > <datatable-body-row role="row" *ngIf="!groupedRows; else groupedRowsTemplate" tabindex="-1" [isSelected]="selector.getRowSelected(group)" [innerWidth]="innerWidth" [offsetX]="offsetX" [columns]="columns" [rowHeight]="getRowHeight(group)" [row]="group" [rowIndex]="getRowIndex(group)" [expanded]="getRowExpanded(group)" [rowClass]="rowClass" [displayCheck]="displayCheck" [treeStatus]="group && group.treeStatus" (treeAction)="onTreeAction(group)" (activate)="selector.onActivate($event, indexes.first + i)" > </datatable-body-row> <ng-template #groupedRowsTemplate> <datatable-body-row role="row" *ngFor="let row of group.value; let i = index; trackBy: rowTrackingFn" tabindex="-1" [isSelected]="selector.getRowSelected(row)" [innerWidth]="innerWidth" [offsetX]="offsetX" [columns]="columns" [rowHeight]="getRowHeight(row)" [row]="row" [group]="group.value" [rowIndex]="getRowIndex(row)" [expanded]="getRowExpanded(row)" [rowClass]="rowClass" (activate)="selector.onActivate($event, i)" > </datatable-body-row> </ng-template> </datatable-row-wrapper> <datatable-summary-row role="row" *ngIf="summaryRow && summaryPosition === 'bottom'" [ngStyle]="getBottomSummaryRowStyles()" [rowHeight]="summaryHeight" [offsetX]="offsetX" [innerWidth]="innerWidth" [rows]="rows" [columns]="columns" > </datatable-summary-row> </datatable-scroller> <div class="empty-row" *ngIf="!rows?.length && !loadingIndicator" [innerHTML]="emptyMessage"></div> </datatable-selection> `, isInline: true, components: [{ type: i1.ProgressBarComponent, selector: "datatable-progress" }, { type: i2.DataTableSelectionComponent, selector: "datatable-selection", inputs: ["rows", "selected", "selectEnabled", "selectionType", "rowIdentity", "selectCheck"], outputs: ["activate", "select"] }, { type: i3.ScrollerComponent, selector: "datatable-scroller", inputs: ["scrollbarV", "scrollbarH", "scrollHeight", "scrollWidth"], outputs: ["scroll"] }, { type: i4.DataTableSummaryRowComponent, selector: "datatable-summary-row", inputs: ["rows", "columns", "rowHeight", "offsetX", "innerWidth"] }, { type: i5.DataTableRowWrapperComponent, selector: "datatable-row-wrapper", inputs: ["innerWidth", "rowDetail", "groupHeader", "offsetX", "detailRowHeight", "row", "groupedRows", "rowIndex", "expanded"], outputs: ["rowContextmenu"] }, { type: i6.DataTableBodyRowComponent, selector: "datatable-body-row", inputs: ["columns", "innerWidth", "expanded", "rowClass", "row", "group", "isSelected", "rowIndex", "displayCheck", "treeStatus", "offsetX", "rowHeight"], outputs: ["activate", "treeAction"] }], directives: [{ type: i7.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i7.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i7.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: DataTableBodyComponent, decorators: [{ type: Component, args: [{ selector: 'datatable-body', template: ` <datatable-progress *ngIf="loadingIndicator"> </datatable-progress> <datatable-selection #selector [selected]="selected" [rows]="rows" [selectCheck]="selectCheck" [selectEnabled]="selectEnabled" [selectionType]="selectionType" [rowIdentity]="rowIdentity" (select)="select.emit($event)" (activate)="activate.emit($event)" > <datatable-scroller *ngIf="rows?.length" [scrollbarV]="scrollbarV" [scrollbarH]="scrollbarH" [scrollHeight]="scrollHeight" [scrollWidth]="columnGroupWidths?.total" (scroll)="onBodyScroll($event)" > <datatable-summary-row *ngIf="summaryRow && summaryPosition === 'top'" [rowHeight]="summaryHeight" [offsetX]="offsetX" [innerWidth]="innerWidth" [rows]="rows" [columns]="columns" > </datatable-summary-row> <datatable-row-wrapper [groupedRows]="groupedRows" *ngFor="let group of temp; let i = index; trackBy: rowTrackingFn" [innerWidth]="innerWidth" [ngStyle]="getRowsStyles(group)" [rowDetail]="rowDetail" [groupHeader]="groupHeader" [offsetX]="offsetX" [detailRowHeight]="getDetailRowHeight(group && group[i], i)" [row]="group" [expanded]="getRowExpanded(group)" [rowIndex]="getRowIndex(group && group[i])" (rowContextmenu)="rowContextmenu.emit($event)" > <datatable-body-row role="row" *ngIf="!groupedRows; else groupedRowsTemplate" tabindex="-1" [isSelected]="selector.getRowSelected(group)" [innerWidth]="innerWidth" [offsetX]="offsetX" [columns]="columns" [rowHeight]="getRowHeight(group)" [row]="group" [rowIndex]="getRowIndex(group)" [expanded]="getRowExpanded(group)" [rowClass]="rowClass" [displayCheck]="displayCheck" [treeStatus]="group && group.treeStatus" (treeAction)="onTreeAction(group)" (activate)="selector.onActivate($event, indexes.first + i)" > </datatable-body-row> <ng-template #groupedRowsTemplate> <datatable-body-row role="row" *ngFor="let row of group.value; let i = index; trackBy: rowTrackingFn" tabindex="-1" [isSelected]="selector.getRowSelected(row)" [innerWidth]="innerWidth" [offsetX]="offsetX" [columns]="columns" [rowHeight]="getRowHeight(row)" [row]="row" [group]="group.value" [rowIndex]="getRowIndex(row)" [expanded]="getRowExpanded(row)" [rowClass]="rowClass" (activate)="selector.onActivate($event, i)" > </datatable-body-row> </ng-template> </datatable-row-wrapper> <datatable-summary-row role="row" *ngIf="summaryRow && summaryPosition === 'bottom'" [ngStyle]="getBottomSummaryRowStyles()" [rowHeight]="summaryHeight" [offsetX]="offsetX" [innerWidth]="innerWidth" [rows]="rows" [columns]="columns" > </datatable-summary-row> </datatable-scroller> <div class="empty-row" *ngIf="!rows?.length && !loadingIndicator" [innerHTML]="emptyMessage"></div> </datatable-selection> `, changeDetection: ChangeDetectionStrategy.OnPush, host: { class: 'datatable-body' } }] }], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }]; }, propDecorators: { scrollbarV: [{ type: Input }], scrollbarH: [{ type: Input }], loadingIndicator: [{ type: Input }], externalPaging: [{ type: Input }], rowHeight: [{ type: Input }], offsetX: [{ type: Input }], emptyMessage: [{ type: Input }], selectionType: [{ type: Input }], selected: [{ type: Input }], rowIdentity: [{ type: Input }], rowDetail: [{ type: Input }], groupHeader: [{ type: Input }], selectCheck: [{ type: Input }], displayCheck: [{ type: Input }], trackByProp: [{ type: Input }], rowClass: [{ type: Input }], groupedRows: [{ type: Input }], groupExpansionDefault: [{ type: Input }], innerWidth: [{ type: Input }], groupRowsBy: [{ type: Input }], virtualization: [{ type: Input }], summaryRow: [{ type: Input }], summaryPosition: [{ type: Input }], summaryHeight: [{ type: Input }], pageSize: [{ type: Input }], rows: [{ type: Input }], columns: [{ type: Input }], offset: [{ type: Input }], rowCount: [{ type: Input }], bodyWidth: [{ type: HostBinding, args: ['style.width'] }], bodyHeight: [{ type: Input }, { type: HostBinding, args: ['style.height'] }], scroll: [{ type: Output }], page: [{ type: Output }], activate: [{ type: Output }], select: [{ type: Output }], detailToggle: [{ type: Output }], rowContextmenu: [{ type: Output }], treeAction: [{ type: Output }], scroller: [{ type: ViewChild, args: [ScrollerComponent] }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYm9keS5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9zd2ltbGFuZS9uZ3gtZGF0YXRhYmxlL3NyYy9saWIvY29tcG9uZW50cy9ib2R5L2JvZHkuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFDTCxTQUFTLEVBQ1QsTUFBTSxFQUNOLFlBQVksRUFDWixLQUFLLEVBQ0wsV0FBVyxFQUVYLFNBQVMsRUFHVCx1QkFBdUIsRUFDeEIsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFFekQsT0FBTyxFQUFFLFlBQVksRUFBRSxpQkFBaUIsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBQ3JFLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSw4QkFBOEIsQ0FBQztBQUM5RCxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sdUJBQXVCLENBQUM7Ozs7Ozs7OztBQTJHcEQsTUFBTSxPQUFPLHNCQUFzQjtJQWlKakM7O09BRUc7SUFDSCxZQUFvQixFQUFxQjtRQUFyQixPQUFFLEdBQUYsRUFBRSxDQUFtQjtRQTNJaEMsYUFBUSxHQUFVLEVBQUUsQ0FBQztRQXdGcEIsV0FBTSxHQUFzQixJQUFJLFlBQVksRUFBRSxDQUFDO1FBQy9DLFNBQUksR0FBc0IsSUFBSSxZQUFZLEVBQUUsQ0FBQztRQUM3QyxhQUFRLEdBQXNCLElBQUksWUFBWSxFQUFFLENBQUM7UUFDakQsV0FBTSxHQUFzQixJQUFJLFlBQVksRUFBRSxDQUFDO1FBQy9DLGlCQUFZLEdBQXNCLElBQUksWUFBWSxFQUFFLENBQUM7UUFDckQsbUJBQWMsR0FBRyxJQUFJLFlBQVksQ0FBa0MsS0FBSyxDQUFDLENBQUM7UUFDMUUsZUFBVSxHQUFzQixJQUFJLFlBQVksRUFBRSxDQUFDO1FBd0I3RCxvQkFBZSxHQUFtQixJQUFJLGNBQWMsRUFBRSxD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