UNPKG

@progress/kendo-angular-grid

Version:

Kendo UI Grid for Angular - high performance data grid with paging, filtering, virtualization, CRUD, and more.

3,828 lines 178 kB
/**-----------------------------------------------------------------------------------------
* Copyright © 2025 Progress Software Corporation. All rights reserved.
* Licensed under commercial license. See LICENSE.md in the project root for more information
*-------------------------------------------------------------------------------------------*/
import { Component, ContentChildren, ElementRef, EventEmitter, HostBinding, Input, Output, Renderer2, QueryList, ViewChild, isDevMode, NgZone, ViewChildren, ChangeDetectorRef, ViewEncapsulation } from '@angular/core';
import { ZoneAwareEventEmitter } from './common/event-emitter';
import { FormControl, FormGroup } from '@angular/forms';
import { merge } from 'rxjs';
import { map, tap, take, filter, switchMap, takeUntil } from 'rxjs/operators';
import { validatePackage } from '@progress/kendo-licensing';
import { packageMetadata } from './package-metadata';
import { ColumnComponent, isColumnComponent } from './columns/column.component';
import { isSpanColumnComponent } from './columns/span-column.component';
import { isColumnGroupComponent, ColumnGroupComponent } from './columns/column-group.component';
import { DetailTemplateDirective } from './rendering/details/detail-template.directive';
import { normalize } from './common/pager-settings';
import { isArray, anyChanged, isChanged, isPresent, isUniversal, observe, isTruthy, createPromise, hasObservers, roundDown } from './utils';
import { BrowserSupportService } from './layout/browser-support.service';
import { DataResultIterator, DataCollection } from './data/data.collection';
import { SelectionService } from './selection/selection.service';
import { Selection } from "./selection/selection-default";
import { EditService } from './editing/edit.service';
import { DetailsService } from './rendering/details/details.service';
import { GroupsService } from './grouping/groups.service';
import { ColumnsContainer } from './columns/columns-container';
import { GroupInfoService } from './grouping/group-info.service';
import { ChangeNotificationService } from './data/change-notification.service';
import { NoRecordsTemplateDirective } from './rendering/no-records-template.directive';
import { ColumnBase } from './columns/column-base';
import { syncRowsHeight } from './layout/row-sync';
import { CELL_CONTEXT, EMPTY_CELL_CONTEXT } from './rendering/common/cell-context';
import { L10N_PREFIX, LocalizationService } from '@progress/kendo-angular-l10n';
import { FilterService } from './filtering/filter.service';
import { PDFService } from './pdf/pdf.service';
import { PDFExportEvent } from './pdf/pdf-export-event';
import { SuspendService } from './scrolling/suspend.service';
import { ResponsiveService } from "./layout/responsive.service";
import { ExcelService } from './excel/excel.service';
import { ColumnList } from './columns/column-list';
import { ToolbarTemplateDirective } from "./rendering/toolbar/toolbar-template.directive";
import { expandColumns, expandColumnsWithSpan, isValidFieldName } from "./columns/column-common";
import { ScrollSyncService } from "./scrolling/scroll-sync.service";
import { ResizeService } from "./layout/resize.service";
import { closest, matchesClasses, matchesNodeName } from './rendering/common/dom-queries';
import { LocalDataChangesService } from './editing/local-data-changes.service';
import { DomEventsService } from './common/dom-events.service';
import { ColumnResizingService } from "./column-resizing/column-resizing.service";
import { hasFilterRow } from './filtering/filterable';
import { SinglePopupService } from './common/single-popup.service';
import { DragAndDropService } from './dragdrop/drag-and-drop.service';
import { DragHintService } from './dragdrop/drag-hint.service';
import { DropCueService } from './dragdrop/drop-cue.service';
import { ColumnReorderService } from './dragdrop/column-reorder.service';
import { ColumnReorderEvent } from './dragdrop/column-reorder-event';
import { FocusRoot } from './navigation/focus-root';
import { NavigationService } from './navigation/navigation.service';
import { NavigationMetadata } from './navigation/navigation-metadata';
import { IdService } from './common/id.service';
import { ColumnInfoService } from "./common/column-info.service";
import { ScrollRequestService } from './scrolling/scroll-request.service';
import { SortService } from './common/sort.service';
import { ColumnMenuTemplateDirective } from './column-menu/column-menu-template.directive';
import { ColumnVisibilityChangeEvent } from './column-menu/column-visibility-change-event';
import { ColumnLockedChangeEvent } from './column-menu/column-locked-change-event';
import { GROUP_CELL_WIDTH } from './constants';
import { sortColumns } from './columns/column-common';
import { defaultTrackBy } from './common/default-track-by';
import { CellSelectionService } from './selection/cell-selection.service';
import { ColumnStickyChangeEvent } from './column-menu/column-sticky-change-event';
import { CellLoadingTemplateDirective } from './rendering/cell-loading.template.directive';
import { ContextService } from './common/provider.service';
import { LoadingTemplateDirective } from './rendering/loading-template.directive';
import { SizingOptionsService } from './layout/sizing-options.service';
import { DraggableDirective, WatermarkOverlayComponent, guid, shouldShowValidationUI } from '@progress/kendo-angular-common';
import { DragTargetContainerDirective, DropTargetContainerDirective } from '@progress/kendo-angular-utils';
import { RowReorderService } from './row-reordering/row-reorder.service';
import { StatusBarTemplateDirective } from './aggregates/status-bar-template.directive';
import { CellSelectionAggregateService } from './aggregates/selection-aggregate.service';
import { ClipboardService } from './common/clipboard.service';
import { ColumnConfigurationErrorMessages, GridConfigurationErrorMessages } from './common/error-messages';
import { StatusBarComponent } from './aggregates/status-bar.component';
import { LoadingComponent } from './rendering/common/loading.component';
import { TableBodyComponent } from './rendering/table-body.component';
import { FooterComponent } from './rendering/footer/footer.component';
import { GridMarqueeDirective } from './selection/marquee.directive';
import { ListComponent } from './rendering/list.component';
import { ResizableContainerDirective } from './layout/resizable.directive';
import { HeaderComponent } from './rendering/header/header.component';
import { ColGroupComponent } from './rendering/common/col-group.component';
import { GridTableDirective } from './rendering/grid-table.directive';
import { TableDirective } from './column-resizing/table.directive';
import { GroupPanelComponent } from './grouping/group-panel.component';
import { NgIf, NgTemplateOutlet } from '@angular/common';
import { ToolbarComponent as GridToolbarComponent } from './rendering/toolbar/toolbar.component';
import { LocalizedMessagesDirective } from './localization/localized-messages.directive';
import { IconWrapperComponent } from '@progress/kendo-angular-icons';
import { PagerTemplateDirective, PagerContextService, PagerNavigationService, KENDO_PAGER } from '@progress/kendo-angular-pager';
import { RowspanService } from './rendering/rowspan.service';
import * as i0 from "@angular/core";
import * as i1 from "./layout/browser-support.service";
import * as i2 from "./selection/selection.service";
import * as i3 from "./selection/cell-selection.service";
import * as i4 from "./grouping/group-info.service";
import * as i5 from "./grouping/groups.service";
import * as i6 from "./data/change-notification.service";
import * as i7 from "./rendering/details/details.service";
import * as i8 from "./editing/edit.service";
import * as i9 from "./filtering/filter.service";
import * as i10 from "./pdf/pdf.service";
import * as i11 from "./layout/responsive.service";
import * as i12 from "./excel/excel.service";
import * as i13 from "./scrolling/scroll-sync.service";
import * as i14 from "./common/dom-events.service";
import * as i15 from "./column-resizing/column-resizing.service";
import * as i16 from "./dragdrop/column-reorder.service";
import * as i17 from "./common/column-info.service";
import * as i18 from "./navigation/navigation.service";
import * as i19 from "./common/sort.service";
import * as i20 from "./scrolling/scroll-request.service";
import * as i21 from "@progress/kendo-angular-l10n";
import * as i22 from "./common/provider.service";
import * as i23 from "./layout/sizing-options.service";
import * as i24 from "./row-reordering/row-reorder.service";
import * as i25 from "@progress/kendo-angular-pager";
const createControl = (source) => (acc, key) => {
    acc[key] = new FormControl(source[key]);
    return acc;
};
const validateColumnsField = (columns) => expandColumns(columns.toArray())
    .filter(isColumnComponent)
    .filter(({ field }) => !isValidFieldName(field))
    .forEach(({ field }) => console.warn(ColumnConfigurationErrorMessages.fieldName(field)));
const handleExpandCollapseGroupsService = (service, expandEmitter, collapseEmitter, map) => (service.changes.pipe(filter(({ group, emit }) => emit && isPresent(group)))
    .subscribe((x) => x.expand ? expandEmitter.emit(map(x)) : collapseEmitter.emit(map(x))));
const handleExpandCollapseDetailsService = (service, expandEmitter, collapseEmitter, map) => (service.changes.pipe(filter(({ dataItem }) => isPresent(dataItem)))
    .subscribe((x) => x.expand ? expandEmitter.emit(map(x)) : collapseEmitter.emit(map(x))));
const isInEditedCell = (element, gridElement) => closest(element, matchesClasses('k-grid-edit-cell')) &&
    closest(element, matchesNodeName('kendo-grid')) === gridElement;
const NOTIFY_DELAY = 500;
/**
 * Represents the Kendo UI for Angular Data Grid component.
 *
 * @example
 * ```html
 * <kendo-grid [data]="gridData"></kendo-grid>
 * ```
 */
export class GridComponent {
    supportService;
    selectionService;
    cellSelectionService;
    wrapper;
    groupInfoService;
    groupsService;
    changeNotification;
    detailsService;
    editService;
    filterService;
    pdfService;
    responsiveService;
    renderer;
    excelService;
    ngZone;
    scrollSyncService;
    domEvents;
    columnResizingService;
    changeDetectorRef;
    columnReorderService;
    columnInfoService;
    navigationService;
    sortService;
    scrollRequestService;
    localization;
    ctx;
    sizingService;
    rowReorderService;
    /**
     * Sets the data of the Grid. If an array is provided, the Grid automatically gets the total count
     * ([more information and example]({% slug binding_grid %})).
     */
    set data(value) {
        this._data = value;
        if (this.selectable && this.selectableSettings?.enabled && this.isVirtual) {
            this.blockArrowSelection = false;
        }
        if (this.notifyTimeout) {
            clearTimeout(this.notifyTimeout);
            this.notifyTimeout = null;
        }
        if (this.rowReorderable) {
            this.ngZone.runOutsideAngular(() => {
                this.notifyTimeout = setTimeout(() => {
                    this.notifyReorderContainers();
                }, NOTIFY_DELAY);
            });
        }
    }
    get data() {
        return this._data;
    }
    get hintText() {
        return this.rowReorderService.getDefaultHintText(this.columnList, this.flatData);
    }
    /**
     * @hidden
     */
    get customHintTemplate() {
        if (this.rowReorderable) {
            const allColumns = this.columnList.toArray();
            const rowReorderColumn = allColumns.find(column => column.isRowReorderColumn);
            return rowReorderColumn.rowDragHintTemplateRef;
        }
    }
    /**
     * @hidden
     */
    get hintContext() {
        if (this.customHintTemplate) {
            const draggedRow = this.rowReorderService?.getDraggedRow(this.flatData);
            return {
                $implicit: draggedRow?.dataItem,
                rowIndex: draggedRow?.rowIndex
            };
        }
    }
    /**
     * Defines the page size used by the Grid pager.
     * Required by the [paging]({% slug paging_grid %}) functionality.
     */
    pageSize;
    /**
     * Defines the height (in pixels) that is used when the `scrollable` option of the Grid is set.
     * To set the height of the Grid, you can also use `style.height`. The `style.height`
     * option supports units such as `px`, `%`, `em`, `rem`, and others.
     */
    height;
    /**
     * Represent the actual height of each Grid row (`tr`) element in the DOM.
     * Required by the [virtual scrolling functionality]({% slug scrollmmodes_grid %}).
     * Set the `rowHeight` option to the exact pixels as the height of the `tr` element appears in the DOM.
     */
    rowHeight;
    /**
     * Represent the actual height of each Grid detail row (`tr`) element in the DOM.
     * Required by the [virtual scrolling functionality]({% slug scrollmmodes_grid %}).
     * Set the `detailRowHeight` option to the exact pixels as the height of the detail Grid `tr` element appears in the DOM.
     */
    detailRowHeight;
    /**
     * Defines the number of records to be skipped by the pager.
     * Required by the [paging]({% slug paging_grid %}) functionality.
     */
    get skip() {
        return this._skip;
    }
    set skip(value) {
        if (typeof value === 'number' && value >= 0) {
            this._skip = this.rowReorderService.skip = value;
        }
    }
    /**
     * Defines the scroll mode used by the Grid.
     *
     * @default 'scrollable'
     */
    scrollable = 'scrollable';
    /**
     * Enables the [single-row selection](slug:grid_row_selection) of the Grid.
     *
     * @default false
     */
    selectable = false;
    /**
     * The descriptors by which the data will be sorted ([see example]({% slug sorting_grid %})).
     */
    set sort(value) {
        if (isArray(value)) {
            this._sort = value;
        }
    }
    get sort() {
        return this._sort;
    }
    /**
     * Specifies the sizing of various Grid building blocks (e.g. tables, buttons, inputs, dropdowns, etc.)
     * @default 'medium'
     */
    set size(size) {
        this._size = size;
        if (size === 'none') {
            this.wrapper.nativeElement.classList.remove('k-grid-sm', 'k-grid-md');
        }
        this.sizingService.changes.next(this.size);
    }
    get size() {
        return this._size;
    }
    /**
     * A function that defines how to track changes for the data rows.
     * By default, the Grid tracks changes by the index of the data item.
     * Edited rows are tracked by reference.
     * [See example](slug:track_changes_grid)
     */
    trackBy = defaultTrackBy;
    /**
     * The descriptor by which the data will be filtered ([see examples]({% slug filtering_grid %})).
     */
    filter;
    /**
     * The descriptors by which the data will be grouped ([see example]({% slug grouping_grid %})).
     */
    set group(value) {
        if (isArray(value)) {
            this._group = value;
        }
    }
    get group() {
        return this._group;
    }
    /**
     * If set to `true`, the grid will render only the columns in the current viewport.
     * @default false
     */
    virtualColumns = false;
    /**
     * @hidden
     */
    get showStatusBar() {
        return !!(this.selectable);
    }
    /**
     * @hidden
     */
    get showTopToolbar() {
        return this.toolbarTemplate && ['top', 'both'].indexOf(this.toolbarTemplate.position) > -1;
    }
    /**
     * @hidden
     */
    get showBottomToolbar() {
        return this.toolbarTemplate && ['bottom', 'both'].indexOf(this.toolbarTemplate.position) > -1;
    }
    /**
     * @hidden
     */
    get isLocked() {
        return this.lockedLeafColumns.length > 0;
    }
    /**
     * @hidden
     */
    get showTopPager() {
        const position = this.pageable.position;
        return !this.isVirtual && this.pageable !== false && ['top', 'both'].indexOf(position) > -1;
    }
    /**
     * @hidden
     */
    get showBottomPager() {
        const position = this.pageable.position;
        return !this.isVirtual && this.pageable !== false && position !== 'top';
    }
    /**
     * @hidden
     */
    get hasPager() {
        return this.showTopPager || this.showBottomPager;
    }
    /**
     * @hidden
     */
    get showGroupPanel() {
        return this.groupable && this.groupable.enabled !== false;
    }
    /**
     * @hidden
     */
    get groupableEmptyText() {
        return this.groupable.emptyText;
    }
    /**
     * @hidden
     */
    get marqueeSelection() {
        return this.selectionService.enableMarquee || this.cellSelectionService.enableMarquee;
    }
    /**
     * @hidden
     */
    gridData = () => { return this.flatData; };
    /**
     * Enables the [filtering]({% slug filtering_grid %}) of the Grid columns that have their `field` option set.
     * @default false
     */
    filterable = false;
    /**
     * Enables the [sorting]({% slug sorting_grid %}) of the Grid columns that have their `field` option set.
     * @default false
     */
    sortable = false;
    /**
     * Configures the pager of the Grid ([see example](slug:paging_grid_settings)).
     * @default false
     */
    pageable = false;
    get normalizedPageableSettings() {
        return normalize(this.pageable);
    }
    /**
     * If set to `true`, the user can group the Grid by dragging the column header cells ([see example]({% slug grouping_grid %})).
     * @default false
     */
    groupable = false;
    /**
     * Determines whether the Grid can be resized.
     * @default false
     */
    gridResizable = false;
    /**
     * Enables the [row reordering]({% slug reordering_rows_grid %}) of the Grid.
     * @default false
     */
    set rowReorderable(value) {
        this._rowReorderable = value;
        if (value) {
            this.rowReorderSubscription = this.rowReorderService.rowReorder.subscribe(args => {
                this.ngZone.run(() => {
                    this.rowReorder.emit(args);
                });
            });
        }
        else {
            this.rowReorderSubscription?.unsubscribe();
        }
    }
    get rowReorderable() {
        return this._rowReorderable;
    }
    /**
     * If set to `true`, the user can use dedicated shortcuts to interact with the Grid.
     * By default, navigation is disabled and the Grid content is accessible in the normal tab sequence.
     * To enable navigation through separate Grid sections only, provide a [`GridNavigableSection`]({% slug api_grid_gridnavigablesection %}) array.
     */
    set navigable(value) {
        if (typeof value === 'boolean') {
            this._navigable = value ? ['table', 'pager', 'toolbar'] : [];
            this.ctx.navigable = value;
            return;
        }
        else {
            this.ctx.navigable = value.includes('table');
        }
        this._navigable = value;
    }
    get navigable() {
        return this._navigable;
    }
    /**
     * @hidden
     *
     * An alias for `navigable` for users who migrate from Kendo UI for jQuery.
     */
    set navigatable(value) {
        this.navigable = value;
    }
    /**
     * @hidden
     */
    get navigatable() {
        return this.navigable;
    }
    /**
     * Indicates whether the Grid columns will be resized during initialization so that
     * they fit their headers and row content.
     * Columns with `autoSize` set to `false` are excluded.
     * To dynamically update the column width to match the new content,
     * refer to [this example]({% slug resizing_columns_grid %}).
     * @default false
     */
    autoSize = false;
    /**
     * Defines a function that is executed for every data row in the component
     * ([see example](slug:styling_grid_rows)).
     */
    set rowClass(fn) {
        if (isDevMode() && typeof fn !== 'function') {
            throw new Error(GridConfigurationErrorMessages.functionType('rowClass', fn));
        }
        this._rowClass = fn;
    }
    get rowClass() {
        return this._rowClass;
    }
    /**
     * Defines a function that is executed for every data row in the component,
     * and determines whether the row will be sticky, i.e. always visible after scrolling.
     */
    set rowSticky(fn) {
        if (isDevMode() && isPresent(fn) && typeof fn !== 'function') {
            throw new Error(GridConfigurationErrorMessages.functionType('rowSticky', fn));
        }
        if (isPresent(fn)) {
            this._rowSticky = fn;
        }
    }
    get rowSticky() {
        return this._rowSticky;
    }
    /**
     * Defines a Boolean function that is executed for each data row in the component
     * ([see example]({% slug grid_selection_custom %}#toc-setting-the-selected-rows)).
     * Determines whether the row will be selected.
     */
    set rowSelected(fn) {
        if (isDevMode() && typeof fn !== 'function') {
            throw new Error(GridConfigurationErrorMessages.functionType('rowSelected', fn));
        }
        this._rowSelected = fn;
    }
    get rowSelected() {
        return this._rowSelected;
    }
    /**
     * Defines a Boolean function that is executed for each data row in the component.
     * Determines whether the row will be selectable.
     */
    set isRowSelectable(fn) {
        if (isDevMode() && typeof fn !== 'function') {
            throw new Error(GridConfigurationErrorMessages.functionType('isRowSelectable', fn));
        }
        this._isRowSelectable = fn;
    }
    get isRowSelectable() {
        return this._isRowSelectable;
    }
    /**
     * Defines a function that determines the selected state of a data cell.
     * Returns an object with `selected` and `item` properties.
     * The cell is marked as selected only if the `selected` property equals `true`.
     *
     * The function is executed for each data cell and may be called more than once
     * as part of a change detection cycle. ([see example]({% slug grid_selection_custom %}#toc-setting-the-selected-cells))
     */
    set cellSelected(fn) {
        if (isDevMode() && typeof fn !== 'function') {
            throw new Error(GridConfigurationErrorMessages.functionType('cellSelected', fn));
        }
        this._cellSelected = fn;
    }
    get cellSelected() {
        return this._cellSelected;
    }
    /**
     * Returns the currently focused cell (if any).
     */
    get activeCell() {
        return this.navigationService.activeCell;
    }
    /**
     * Returns the currently focused row (if any).
     */
    get activeRow() {
        return this.navigationService.activeRow;
    }
    /**
     * Returns the current Grid selection.
     *
     * @hidden
     */
    get selection() {
        return (this.selectable || this.selectionDirective) ?
            this.defaultSelection ? this.defaultSelection.stateToArray() : this.selectionDirective.stateToArray() :
            [];
    }
    /**
     * If set to `true`, the user can resize columns by dragging the edges (resize handles) of their header cells
     * ([see example]({% slug resizing_columns_grid %})).
     *
     * @default false
     */
    resizable = false;
    /**
     * If set to `true`, the user can reorder columns by dragging their header cells
     * ([see example]({% slug reordering_columns_grid %})).
     *
     * @default false
     */
    reorderable = false;
    /**
     * Specifies if the loading indicator of the Grid will be displayed ([see example]({% slug binding_grid %})).
     *
     * @default false
     */
    set loading(value) {
        this._loading = value;
        this.rowReorderable && this.notifyReorderContainers();
    }
    get loading() {
        return this._loading;
    }
    /**
     * Specifies if the column menu of the columns will be displayed ([see example]({% slug columnmenu_grid %})).
     *
     * @default false
     */
    columnMenu = false;
    /**
     * Specifies if the header of the grid will be hidden. The header is visible by default.
     * The header includes column headers and the [filter row](slug:filter_row).
     * @default false
     */
    hideHeader = false;
    /**
     * Fires when the Grid filter is modified through the UI.
     * You have to handle the event yourself and filter the data.
     */
    filterChange = new EventEmitter();
    /**
     * Fires when the page of the Grid is changed ([see example]({% slug paging_grid %})).
     * You have to handle the event yourself and page the data.
     */
    pageChange = new EventEmitter();
    /**
     * Fires when the grouping of the Grid is changed.
     * You have to handle the event yourself and group the data ([see example]({% slug grouping_grid %})).
     */
    groupChange;
    /**
     * Fires when the sorting of the Grid is changed ([see example]({% slug sorting_grid %})).
     * You have to handle the event yourself and sort the data.
     */
    sortChange = new EventEmitter();
    /**
     * Fires when the user selects a Grid row.
     */
    selectionChange = new EventEmitter();
    /**
     * Fires when the user drops the dragged row and reordering is performed.
     */
    rowReorder = new EventEmitter();
    /**
     * Fires when the data state of the Grid is changed.
     */
    dataStateChange = new EventEmitter();
    /**
     * Fires when the user expands a group header.
     */
    groupExpand = new EventEmitter();
    /**
     * Fires when the user collapses a group header.
     */
    groupCollapse = new EventEmitter();
    /**
     * Fires when the user expands a master row.
     */
    detailExpand = new EventEmitter();
    /**
     * Fires when the user collapses a master row.
     */
    detailCollapse = new EventEmitter();
    /**
     * Fires when the user clicks the **Edit** command button to edit a row
     * ([see example](slug:inline_editing_grid#editing-records-1)).
     */
    edit = new EventEmitter();
    /**
     * Fires when the user clicks the **Cancel** command button to close a row
     * ([see example]({% slug inline_editing_grid %}#toc-canceling-editing-1)).
     */
    cancel = new EventEmitter();
    /**
     * Fires when the user clicks the **Save** command button to save changes in a row
     * ([see example]({% slug inline_editing_grid %}#toc-saving-records-1)).
     */
    save = new EventEmitter();
    /**
     * Fires when the user clicks the **Remove** command button to remove a row
     * ([see example]({% slug inline_editing_grid %}#toc-removing-records-1)).
     */
    remove = new EventEmitter();
    /**
     * Fires when the user clicks the **Add** command button to add a new row
     * ([see example]({% slug inline_editing_grid %}#toc-adding-records-1)).
     */
    add = new EventEmitter();
    /**
     * Fires when the user leaves an edited cell ([see example](slug:editing_incell_grid)).
     */
    cellClose = new EventEmitter();
    /**
     * Fires when the user clicks a cell ([see example](slug:editing_incell_grid)).
     */
    cellClick;
    /**
     * Fires when the user clicks the **Export to PDF** command button.
     */
    pdfExport = new EventEmitter();
    /**
     * Fires when the user clicks the **Export to Excel** command button.
     */
    excelExport = new EventEmitter();
    /**
     * Fires when the user completes the resizing of the column.
     */
    columnResize;
    /**
     * Fires when the user completes the reordering of the column.
     */
    columnReorder = new EventEmitter();
    /**
     * Fires when the user changes the visibility of the columns from the column menu or column chooser.
     */
    columnVisibilityChange = new EventEmitter();
    /**
     * Fires when the user changes the locked state of the columns from the column menu or by reordering the columns.
     */
    columnLockedChange = new EventEmitter();
    /**
     * Fires when the user changes the sticky state of the columns from the column menu.
     */
    columnStickyChange = new EventEmitter();
    /**
     * Fires when the user scrolls to the last record on the page and enables endless scrolling
     * ([see example]({% slug scrollmmodes_grid %}#toc-endless-scrolling)).
     * You have to handle the event yourself and page the data.
     */
    scrollBottom = new EventEmitter();
    /**
     * Fires when the grid content is scrolled.
     * For performance reasons, the event is triggered outside the Angular zone. Enter the Angular zone if you make any changes that require change detection.
     */
    contentScroll = new EventEmitter();
    /**
     * A query list of all declared columns.
     */
    columns = new QueryList();
    get dir() {
        return this.direction;
    }
    hostClass = true;
    get sizeSmallClass() {
        return this.size === 'small';
    }
    get sizeMediumClass() {
        return this.size === 'medium' || !this.size;
    }
    get lockedClasses() {
        return this.lockedLeafColumns.length > 0;
    }
    get virtualClasses() {
        return this.isVirtual;
    }
    get noScrollbarClass() {
        return this.scrollbarWidth === 0;
    }
    get isResizable() {
        return Boolean(this.gridResizable);
    }
    get minWidth() {
        return this.gridResizable.minWidth;
    }
    get maxWidth() {
        return this.gridResizable.maxWidth;
    }
    get minHeight() {
        return this.gridResizable.minHeight;
    }
    get maxHeight() {
        return this.gridResizable.maxHeight;
    }
    detailTemplateChildren;
    get detailTemplate() {
        if (this._customDetailTemplate) {
            return this._customDetailTemplate;
        }
        return this.detailTemplateChildren ? this.detailTemplateChildren.first : undefined;
    }
    set detailTemplate(detailTemplate) {
        this._customDetailTemplate = detailTemplate;
    }
    cellLoadingTemplateChildren;
    get cellLoadingTemplate() {
        if (this._cellLoadingTemplate) {
            return this._customDetailTemplate;
        }
        return this.cellLoadingTemplateChildren ? this.cellLoadingTemplateChildren.first : undefined;
    }
    set cellLoadingTemplate(cellLoadingTemplate) {
        this._cellLoadingTemplate = cellLoadingTemplate;
    }
    loadingTemplateChildren;
    get loadingTemplate() {
        if (this._loadingTemplate) {
            return this._loadingTemplate;
        }
        return this.loadingTemplateChildren ? this.loadingTemplateChildren.first : undefined;
    }
    set loadingTemplate(loadingTemplate) {
        this._loadingTemplate = loadingTemplate;
    }
    statusBarTemplateChildren;
    get statusBarTemplate() {
        if (this._statusBarTemplate) {
            return this._statusBarTemplate;
        }
        return this.statusBarTemplateChildren ? this.statusBarTemplateChildren.first : undefined;
    }
    set statusBarTemplate(statusBarTemplate) {
        this._statusBarTemplate = statusBarTemplate;
    }
    noRecordsTemplateChildren;
    get noRecordsTemplate() {
        if (this._customNoRecordsTemplate) {
            return this._customNoRecordsTemplate;
        }
        return this.noRecordsTemplateChildren ? this.noRecordsTemplateChildren.first : undefined;
    }
    set noRecordsTemplate(customNoRecordsTemplate) {
        this._customNoRecordsTemplate = customNoRecordsTemplate;
    }
    pagerTemplateChildren;
    get pagerTemplate() {
        if (this._customPagerTemplate) {
            return this._customPagerTemplate;
        }
        return this.pagerTemplateChildren ? this.pagerTemplateChildren.first : undefined;
    }
    set pagerTemplate(customPagerTemplate) {
        this._customPagerTemplate = customPagerTemplate;
    }
    toolbarTemplateChildren;
    get toolbarTemplate() {
        if (this._customToolbarTemplate) {
            return this._customToolbarTemplate;
        }
        return this.toolbarTemplateChildren ? this.toolbarTemplateChildren.first : undefined;
    }
    set toolbarTemplate(customToolbarTemplate) {
        this._customToolbarTemplate = customToolbarTemplate;
    }
    columnMenuTemplates;
    lockedHeader;
    header;
    footer = new QueryList();
    ariaRoot;
    dragTargetContainer;
    dropTargetContainer;
    get scrollbarWidth() {
        return this.supportService.scrollbarWidth;
    }
    get headerPadding() {
        if (isUniversal()) {
            return '';
        }
        const padding = Math.max(0, this.scrollbarWidth) + 'px';
        const right = this.rtl ? 0 : padding;
        const left = this.rtl ? padding : 0;
        return `0 ${right} 0 ${left}`;
    }
    columnMenuOptions;
    columnList;
    selectionDirective = false;
    ariaRootId = `k-${guid()}`;
    /**
     * @hidden
     */
    showLicenseWatermark = false;
    columnsContainer = new ColumnsContainer(() => this.columnList.filterHierarchy(column => {
        if (!isUniversal()) {
            column.matchesMedia = this.matchesMedia(column);
        }
        return column.isVisible;
    }));
    view = new DataCollection(() => new DataResultIterator(this.data, this.skip, this.hasGroupFooters));
    get hasGroupFooters() {
        return this.columnsContainer.hasGroupFooter;
    }
    get showFooter() {
        return this.columnsContainer.hasFooter;
    }
    get showGroupFooters() {
        return this.groupable && this.groupable.showFooter;
    }
    get ariaRowCount() {
        return this.totalColumnLevels + 1 + this.view.total + (hasFilterRow(this.filterable) ? 1 : 0);
    }
    get ariaColCount() {
        return this.columnsContainer.leafColumnsToRender.length;
    }
    get navigation() {
        return this.navigationService;
    }
    shouldGenerateColumns = true;
    direction;
    notifyTimeout = null;
    _sort = new Array();
    _group = new Array();
    _skip = 0;
    _data = [];
    cachedWindowWidth = 0;
    defaultSelection;
    _rowSelected = null;
    _isRowSelectable = null;
    _cellSelected = null;
    _customDetailTemplate;
    _cellLoadingTemplate;
    _loadingTemplate;
    _statusBarTemplate;
    _customNoRecordsTemplate;
    _customPagerTemplate;
    _customToolbarTemplate;
    _rowReorderable = false;
    leafViewportColumns;
    viewportColumns;
    _navigable = [];
    _size = 'medium';
    _loading = false;
    get isVirtual() {
        return this.scrollable === 'virtual';
    }
    get isScrollable() {
        return this.scrollable !== 'none';
    }
    get visibleColumns() {
        return this.columnsContainer.allColumns;
    }
    get lockedColumns() {
        return this.columnsContainer.lockedColumns;
    }
    get nonLockedColumns() {
        return this.columnsContainer.nonLockedColumns;
    }
    get lockedLeafColumns() {
        return this.columnsContainer.lockedLeafColumns;
    }
    get stickyColumns() {
        return this.columns.filter(column => column.sticky);
    }
    get nonLockedLeafColumns() {
        return this.columnsContainer.nonLockedLeafColumns;
    }
    get leafColumns() {
        return this.columnsContainer.leafColumns;
    }
    get totalColumnLevels() {
        return this.columnsContainer.totalLevels;
    }
    get headerColumns() {
        if (this.virtualColumns && !this.pdfService.exporting) {
            return this.viewportColumns;
        }
        return this.nonLockedColumns;
    }
    get headerLeafColumns() {
        if (this.virtualColumns && !this.pdfService.exporting) {
            return this.leafViewportColumns;
        }
        return this.nonLockedLeafColumns;
    }
    get lockedWidth() {
        const groupCellsWidth = this.group.length * GROUP_CELL_WIDTH;
        return expandColumns(this.lockedLeafColumns.toArray()).reduce((prev, curr) => prev + (curr.width || 0), groupCellsWidth);
    }
    get nonLockedWidth() {
        if ((!this.rtl && this.lockedLeafColumns.length) || this.virtualColumns) {
            return !this.virtualColumns ? this.columnsContainer.unlockedWidth :
                this.leafViewportColumns.reduce((acc, column) => acc + (column.width || 0), 0);
        }
        return undefined;
    }
    get selectableSettings() {
        if (this.selectionService) {
            return this.selectionService.options;
        }
        return undefined;
    }
    get columnMenuTemplate() {
        const template = this.columnMenuTemplates.first;
        return template ? template.templateRef : null;
    }
    get totalCount() {
        if (this.isVirtual || !isPresent(this.pageSize)) {
            return this.view.total;
        }
        return this.pageSize;
    }
    /**
     * @hidden
     */
    getDefaultSelectors(type) {
        return this.rowReorderService.defaultSelectors[type];
    }
    /**
     * @hidden
     */
    getHintSettings(type) {
        return this.rowReorderService[type];
    }
    /**
     * @hidden
     */
    blockArrowSelection = false;
    selectionSubscription;
    stateChangeSubscription;
    groupExpandCollapseSubscription;
    editServiceSubscription;
    detailsServiceSubscription;
    filterSubscription;
    sortSubscription;
    columnsChangeSubscription;
    pdfSubscription;
    excelSubscription;
    columnsContainerChangeSubscription;
    cellClickSubscription;
    footerChangeSubscription;
    columnResizingSubscription;
    columnReorderSubscription;
    detachElementEventHandlers;
    localizationSubscription;
    columnVisibilityChangeSubscription;
    columnLockedChangeSubscription;
    columnStickyChangeSubscription;
    focusElementSubscription;
    columnRangeChangeSubscription;
    rowReorderSubscription;
    rtl = false;
    _rowSticky;
    constructor(supportService, selectionService, cellSelectionService, wrapper, groupInfoService, groupsService, changeNotification, detailsService, editService, filterService, pdfService, responsiveService, renderer, excelService, ngZone, scrollSyncService, domEvents, columnResizingService, changeDetectorRef, columnReorderService, columnInfoService, navigationService, sortService, scrollRequestService, localization, ctx, sizingService, rowReorderService) {
        this.supportService = supportService;
        this.selectionService = selectionService;
        this.cellSelectionService = cellSelectionService;
        this.wrapper = wrapper;
        this.groupInfoService = groupInfoService;
        this.groupsService = groupsService;
        this.changeNotification = changeNotification;
        this.detailsService = detailsService;
        this.editService = editService;
        this.filterService = filterService;
        this.pdfService = pdfService;
        this.responsiveService = responsiveService;
        this.renderer = renderer;
        this.excelService = excelService;
        this.ngZone = ngZone;
        this.scrollSyncService = scrollSyncService;
        this.domEvents = domEvents;
        this.columnResizingService = columnResizingService;
        this.changeDetectorRef = changeDetectorRef;
        this.columnReorderService = columnReorderService;
        this.columnInfoService = columnInfoService;
        this.navigationService = navigationService;
        this.sortService = sortService;
        this.scrollRequestService = scrollRequestService;
        this.localization = localization;
        this.ctx = ctx;
        this.sizingService = sizingService;
        this.rowReorderService = rowReorderService;
        const isValid = validatePackage(packageMetadata);
        this.showLicenseWatermark = shouldShowValidationUI(isValid);
        this.ctx.grid = this;
        this.groupChange = new ZoneAwareEventEmitter(this.ngZone);
        this.cellClick = new ZoneAwareEventEmitter(this.ngZone);
        this.columnResize = new ZoneAwareEventEmitter(this.ngZone);
        this.localizationSubscription = this.localization.changes.subscribe(({ rtl }) => {
            this.rtl = rtl;
            this.direction = this.rtl ? 'rtl' : 'ltr';
        });
        this.groupInfoService.registerColumnsContainer(() => this.columnList);
        this.columnInfoService.init(this.columnsContainer, () => this.columnList);
        this.columnVisibilityChangeSubscription = this.columnInfoService.visibilityChange.subscribe((changed) => {
            this.columnVisibilityChange.emit(new ColumnVisibilityChangeEvent(changed));
        });
        this.columnLockedChangeSubscription = this.columnInfoService.lockedChange.subscribe((changed) => {
            this.columnLockedChange.emit(new ColumnLockedChangeEvent(changed));
        });
        this.columnStickyChangeSubscription = this.columnInfoService.stickyChange.subscribe((changed) => {
            this.columnStickyChange.emit(new ColumnStickyChangeEvent(changed));
        });
        this.groupExpandCollapseSubscription = handleExpandCollapseGroupsService(groupsService, this.groupExpand, this.groupCollapse, ({ group, groupIndex, parentGroup }) => ({ group, groupIndex, parentGroup }));
        this.detailsServiceSubscription = handleExpandCollapseDetailsService(detailsService, this.detailExpand, this.detailCollapse, args => args);
        this.filterSubscription = this.filterService.changes.subscribe(x => {
            this.filterChange.emit(x);
        });
        this.sortSubscription = this.sortService.changes.subscribe(x => {
            this.sortChange.emit(x);
        });
        this.attachStateChangesEmitter();
        this.attachEditHandlers();
        this.attachDomEventHandlers();
        this.pdfSubscription = this.pdfService.exportClick.subscribe(this.emitPDFExportEvent.bind(this));
        this.excelSubscription = this.excelService.exportClick.subscribe(this.saveAsExcel.bind(this));
        this.columnsContainerChange();
        this.handleColumnResize();
        this.columnList = new ColumnList(this.columns);
        this.columnReorderSubscription = this.columnReorderService
            .changes.subscribe(this.reorder.bind(this));
        this.columnRangeChangeSubscription = this.columnInfoService.columnRangeChange.subscribe(this.onColumnRangeChange.bind(this));
    }
    /**
     * Expands the specified master row ([see example]({% slug hierarchy_grid %})).
     *
     * This method is provided only for backwards-compatibility with legacy versions.
     * These versions tracked the expanded state internally using the data row index.
     *
     * For new development, use the [kendoGridDetailsExpandBy directive]({% slug api_grid_expanddetailsdirective %})
     * or provide an isDetailExpanded callback. See [Controlling the Expanded State]({% slug master_detail_expanded_state_grid %})
     * for examples on how to control the expanded state.
     *
     * @param index - The data row index of the master row.
     */
    expandRow(index) {
        this.toggleDetailRowLegacy(index, true);
    }
    /**
     * Collapses the specified master row ([see example]({% slug hierarchy_grid %})).
     *
     * This method is provided only for backwards-compatibility with legacy versions.
     * These versions tracked the expanded state internally using the data row index.
     *
     * For new development, use the [kendoGridDetailsExpandBy directive]({% slug api_grid_expanddetailsdirective %})
     * or provide an isDetailExpanded callback. See [Controlling the Expanded State]({% slug master_detail_expanded_state_grid %})
     * for examples on how to control the expanded state.
     *
     * @param index - The data row index of the master row.
     */
    collapseRow(index) {
        this.toggleDetailRowLegacy(index, false);
    }
    /**
     * Expands a group header item for the given index. For example,
     * `0_1` expands the second inner group of the first master group.
     *
     * This method is provided only for backwards-compatibility with legacy versions.
     * These versions tracked the expanded group state internally using the hierarchical group index.
     *
     * When a Grid is pageable, the indexes of the groups are offset by the current Grid [skip]({% slug api_grid_gridcomponent %}#toc-skip).
     *
     * @param {string} index - The underscore separated hierarchical index of the group.
     */
    expandGroup(index) {
        this.toggleGroupRowLegacy(index, true);
    }
    /**
     * Collapses a group header item for the given index. For example,
     * `0_1` collapses the second inner group of the first master group.
     *
     * This method is provided only for backwards-compatibility with legacy versions.
     * These versions tracked the expanded group state internally using the hierarchical group index.
     *
     * When a Grid is pageable, the indexes of the groups are offset by the current Grid [skip]({% slug api_grid_gridcomponent %}#toc-skip).
     *
     * @param {string} index - The underscore separated hierarchical index of the group.
     */
    collapseGroup(index) {
        this.toggleGroupRowLegacy(index, false);
    }
    /**
     * @hidden
     */
    resetGroupsState() {
        this.groupsService.reset();
    }
    /**
     * @hidden
     */
    onDataChange() {
        this.autoGenerateColumns();
        this.changeNotification.notify();
        this.pdfService.dataChanged.emit();
        if (isPresent(this.defaultSelection)) {
            this.defaultSelection.reset();
        }
        this.initSelectionService();
        this.updateNavigationMetadata();
    }
    ngOnChanges(changes) {
        if (isChanged("data", changes)) {
            this.onDataChange();
        }
        if (this.lockedLeafColumns.length && anyChanged(["pageSize", "skip", "sort", "group"], changes)) {
            this.changeNotification.notify();
        }
        if (anyChanged(["pageSize", "scrollable", 'virtualColumns'], changes)) {
            this.updateNavigationMetadata();
        }
        if (isChanged("virtualColumns", changes)) {
            this.viewportColumns = this.leafViewportColumns = null;
        }
        if (isChanged("height", changes, false)) {
            this.renderer.setStyle(this.wrapper.nativeElement, 'height', `${this.height}px`);
        }
        if (isChanged("filterable", changes) && this.lockedColumns.length) {
            this.syncHeaderHeight(this.ngZone.onStable.asObservable().pipe(take(1)));
        }
        if (anyChanged(["columnMenu", "sortable", "filterable"], changes, false)) {
            this.columnMenuOptions = this.columnMenu && Object.assign({
                filter: Boolean(this.filterable),
                sort: Boolean(this.sortable)
            }, this.columnMenu);
        }
        if (isChanged("scrollable", changes) && this.isScrollable) {
            this.ngZone.onStable.pipe(take(1)).subscribe(() => this.attachScrollSync());
        }
        if (isChanged("selectable", changes) && this.shouldResetSelection(changes['selectable'])) {
            if (this.defaultSelection) {
                this.defaultSelection.reset();
            }
            else if (this.selectionDirective) {
                this.selectionDirective.reset();
            }
        }
        if (isChanged('groupable', changes, true)) {
            this.groupable = changes['groupable'].currentValue;
        }
        if (isChanged('navigable', changes, true)) {
            if (this.navigationService.enabled) {
                this.navigationService.setActiveSections(this.navigable);
            }
            else {
                if (this.navigable.length) {
                    this.navigationService.init(this.navigationMetadata(), this.navigable);
                }
            }
        }
    }
    ngAfterContentInit() {
        this.shouldGenerateColumns = !this.columns.length;
        this.autoGenerateColumns();
        this.columnList = new ColumnList(this.columns);
        this.columnsChangeSubscription = this.columns.changes.subscribe(() => this.verifySettings());
    }
    ngAfterViewInit() {
        this.attachScrollSync();
        this.attachElementEventHandlers();
        this.updateNavigationMetadata();
        this.applyAutoSize();
        const toolbarComponentWrapper = this.wrapper?.nativeElement?.querySelector('kendo-toolbar');
        if (toolbarComponentWrapper) {
            this.renderer.addClass(toolbarComponentWrapper, 'k-grid-toolbar');
        }
    }
    ngAfterContentChecked() {
        this.columnsContainer.refresh();
        this.verifySettings();
        this.initSelectionService();
    }
    ngOnInit() {
        if (this.navigable.length) {
            this.navigationService.init(this.navigationMetadata(), this.navigable);
        }
    }
    ngOnDestroy() {
        if (this.selectionSubscription) {
            this.selectionSubscription.unsubscribe();
        }
        if (this.stateChangeSubscription) {
            this.stateChangeSubscription.unsubscribe();
        }
        if (this.groupExpandCollapseSubscription) {
            this.groupExpandCollapseSubscription.unsubscribe();
        }
        if (this.detailsServiceSubscription) {
            this.detailsServiceSubscription.unsubscribe();
        }
        if (this.editServiceSubscription) {
            this.editServiceSubscription.unsubscribe();
        }
        if (this.pdfSubscription) {
            this.pdfSubscription.unsubscribe();
        }
        if (this.filterSubscription) {
            this.filterSubscription.unsubscribe();
        }
        if (this.sortSubscription) {
            this.sortSubscription.unsubscribe();
        }
        if (this.columnsChangeSubscription) {
            this.columnsChangeSubscription.unsubscribe();
        }
        if (this.excelSubscription) {
            this.excelSubscription.unsubscribe();
        }
        if (this.columnsContainerChangeSubscription) {
            this.columnsContainerChangeSubscription.unsubscribe();
        }
        if (this.scrollSyncService) {
            this.scrollSyncService.destroy();
        }
        if (this.detachElementEventHandlers) {
            this.detachElementEventHandlers();
        }
        if (this.defaultSelection) {
            this.defaultSelection.destroy();
        }
        if (this.cellClickSubscription) {
            this.cellClickSubscription.unsubscribe();
        }
        if (this.footerChangeSubscription) {
            this.footerChangeSubscription.unsubscribe();
        }
        this.ngZone = null;
        if (this.columnResizingSubscription) {
            this.columnResizingSubscription.unsubscribe();
        }
        if (this.columnReorderSubscription) {
            this.columnReorderSubscription.unsubscribe();
        }
        if (this.localizationSubscription) {
            this.localizationSubscription.unsubscribe();
        }
        if (this.columnVisibilityChangeSubscription) {
            this.columnVisibilityChangeSubscription.unsubscribe();
        }
        if (this.columnLockedChangeSubscription) {
            this.columnLockedChangeSubscription.unsubscribe();
        }
        if (this.columnStickyChangeSubscription) {
            this.columnStickyChangeSubscription.unsubscribe();
        }
        if (this.focusElementSubscription) {
            this.focusElementSubscription.unsubscribe();
        }
        if (this.rowReorderSubscription) {
            this.rowReorderSubscription.unsubscribe();
        }
        this.columnRangeChangeSubscription.unsubscribe();
    }
    /**
     * @hidden
     */
    attachScrollSync() {
        if (isUniversal()) {
            return;
        }
        if (this.header) {
            this.scrollSyncService.registerEmitter(this.header.nativeElement, "header");
        }
        if (this.footer) {
            this.footerChangeSubscription = observe(this.footer)
                .subscribe(footers => footers
                .map(footer => footer.nativeElement)
                .filter(isPresent)
                .forEach(element => {
                this.scrollSyncService.registerEmitter(element, "footer");
                // sync footers and content scroll positions when footer visibility is changed dynamically
                element.scrollLeft = this.wrapper.nativeElement.querySelector('.k-grid-content')?.scrollLeft;
            }));
        }
    }
    /**
     * @hidden
     */
    get ariaLabel() {
        return this.localization.get('gridLabel');
    }
    /**
     * @hidden
     */
    messageFor = token => this.localization.get(token);
    /**
     * Switches the specified table row in the edit mode ([see example]({% slug inline_editing_grid %}#toc-editing-records-1)).
     *
     * @param rowIndex - The data row index that will be switched in the edit mode.
     * @param group - The [FormGroup](link:site.data.urls.angular['formgroupapi'])
     * that describes the edit form.
     * @param options - Additional options configuring the focus target once the editor opens.
     */
    editRow(rowIndex, group, options) {
        this.editService.editRow(rowIndex, group);
        if (isPresent(options) && options.skipFocus) {
            return;
        }
        const row = `tr[data-kendo-grid-item-index="${rowIndex}"]`;
        const columnIndex = options && options.columnIndex;
        const target = isNaN(columnIndex) ? row : `${row} td[data-kendo-grid-column-index="${columnIndex}"]`;
        this.focusEditElement(target);
    }
    /**
     * Closes the editor for a given row ([see example]({% slug inline_editing_grid %}#toc-canceling-editing-1)).
     *
     * @param {number} index - The row index that will be switched out of the edit mode. If no index is provided, it is assumed
     * that the new item editor will be closed.
     */
    closeRow(index) {
        this.editService.close(index);
    }
    /**
     * Creates a new row editor ([see example]({% slug inline_editing_grid %}#toc-adding-records-1)).
     *
     * @param {FormGroup} group - The [FormGroup](link:site.data.urls.angular['formgroupapi']) that describes
     * the edit form. If called with a data item, it will build the `FormGroup` from the data item fields.
     */
    addRow(group) {
        const isFormGroup = group instanceof FormGroup;
        if (!isFormGroup) {
            const fields = Object.keys(group).reduce(createControl(group), {}); // FormBuilder?
            group = new FormGroup(fields);
        }
        this.editService.addRow(group);
        this.focusEditElement('.k-grid-add-row');
    }
    /**
     * Puts the cell that is specified by the table row and column in edit mode ([see example](slug:editing_incell_grid)).
     *
     * @param {number} rowIndex - The data row index that will be switched in the edit mode.
     * @param {number|string|any} column - The leaf column index, or the field name or the column instance that should be edited.
     * @param {FormGroup} group - The [FormGroup](link:site.data.urls.angular['formgroupapi'])
     * that describes the edit form.
     */
    editCell(rowIndex, column, group) {
        const instance = this.columnInstance(column);
        this.editService.editCell(rowIndex, instance, group);
        this.focusEditElement('.k-grid-edit-cell');
    }
    /**
     * Closes the current cell in edit mode and fires
     * the [cellClose]({% slug api_grid_gridcomponent %}#toc-cellclose) event.
     *
     * @return {boolean} Indicates whether the edited cell was closed.
     * A `false` value indicates that the
     * [cellClose]({% slug api_grid_gridcomponent %}#toc-cellclose) event was prevented.
     */
    closeCell() {
        return !this.editService.closeCell();
    }
    /**
     * Closes the current cell in edit mode.
     */
    cancelCell() {
        this.editService.cancelCell();
    }
    /**
     * Returns a flag which indicates if a row or a cell is currently edited.
     *
     * @return {boolean} A flag which indicates if a row or a cell is currently edited.
     */
    isEditing() {
        return this.editService.isEditing();
    }
    /**
     * Returns a flag which indicates if a cell is currently edited.
     *
     * @return {boolean} A flag which indicates if a cell is currently being edited.
     */
    isEditingCell() {
        return this.editService.isEditingCell();
    }
    /**
     * Initiates the PDF export ([see example]({% slug pdfexport_grid %})).
     */
    saveAsPDF() {
        this.pdfService.save(this);
    }
    /**
     * Exports the Grid element to a Drawing [Group]({% slug api_kendo-drawing_group %}) by using the `kendo-grid-pdf` component options.
     * ([see example]({% slug pdfexport_grid %}#toc-exporting-multiple-grids-to-the-same-pdf)).
     *
     * @return {Promise} A promise that will be resolved with the Drawing `Group`.
     */
    drawPDF() {
        const promise = createPromise();
        this.pdfService.draw(this, promise);
        return promise;
    }
    /**
     * Initiates the Excel export ([see example]({% slug excelexport_grid %})).
     */
    saveAsExcel() {
        this.excelService.save(this);
    }
    /**
     * Applies the minimum possible width for the specified column,
     * so that the whole text fits without wrapping. This method expects the Grid
     * to be [resizable](slug:resizing_columns_grid). The method must be executed
     * after the Grid is already populated with data.
     * [See example](slug:resizing_columns_grid#toc-auto-fitting-the-content)
     */
    autoFitColumn(column) {
        this.columnResizingService.autoFit(column);
    }
    /**
     * Adjusts the width of the specified columns to fit the entire content, including headers, without wrapping.
     * If no columns are specified, `autoFitColumns` is applied to all columns.The method must be executed
     * after the Grid is already populated with data.
     * [See example](slug:resizing_columns_grid#toc-auto-fitting-the-content)
     *
     */
    autoFitColumns(columns = this.columns) {
        let cols;
        if (columns instanceof QueryList) {
            cols = columns.toArray();
        }
        else {
            cols = columns;
        }
        this.columnResizingService.autoFit(...cols);
    }
    /**
     * @hidden
     */
    notifyPageChange(source, event) {
        if (source === "list" && !this.isVirtual) {
            return;
        }
        this.pageChange.emit(event);
    }
    /**
     * @hidden
     */
    notifyScrollBottom() {
        if (this.scrollable === 'none') {
            return;
        }
        if (hasObservers(this.scrollBottom)) {
            this.ngZone.run(() => this.scrollBottom.emit({ sender: this }));
        }
    }
    /**
     * @hidden
     */
    focusEditElement(containerSelector) {
        if (this.focusElementSubscription) {
            this.focusElementSubscription.unsubscribe();
        }
        this.ngZone.runOutsideAngular(() => {
            this.focusElementSubscription = this.ngZone.onStable.asObservable().pipe(take(1)).subscribe(() => {
                const wrapper = this.wrapper.nativeElement;
                if (!this.setEditFocus(wrapper.querySelector(containerSelector)) && this.isLocked) {
                    this.setEditFocus(wrapper.querySelector(`.k-grid-content ${containerSelector}`));
                }
                this.focusElementSubscription = null;
            });
        });
    }
    /**
     * Focuses the last active or the first cell of the Grid.
     *
     * @returns {NavigationCell} The focused cell.
     */
    focus() {
        this.assertNavigable();
        return this.navigationService.focusCell();
    }
    /**
     * Focuses the cell with the specified row and column index.
     *
     * The row index is based on the logical structure of the Grid and does not correspond to the data item index.
     * Header rows are included, starting at index 0.
     * Group headers and footers are included.
     * The row indexing is absolute and does not change with paging.
     *
     * If the Grid is configured for scrolling, including virtual scrolling, the scroll position will be updated.
     * If the row is not present on the current page, the method will have no effect.
     *
     * @param rowIndex - The logical row index to focus. The top header row has an index 0.
     * @param colIndex - The column index to focus.
     * @returns {NavigationCell} The focused cell.
     *
     */
    focusCell(rowIndex, colIndex) {
        this.assertNavigable();
        return this.navigationService.focusCell(rowIndex, colIndex);
    }
    /**
     * Focuses the next cell, optionally wrapping to the next row.
     *
     * @param wrap - A Boolean value which indicates if the focus will move to the next row. Defaults to `true`.
     * @returns {NavigationCell} The focused cell. If the focus is already on the last cell, returns `null`.
     */
    focusNextCell(wrap = true) {
        this.assertNavigable();
        return this.navigationService.focusNextCell(wrap);
    }
    /**
     * Focuses the previous cell. Optionally wraps to the previous row.
     *
     * @param wrap - A Boolean value which indicates if the focus will move to the next row. Defaults to `true`.
     * @returns {NavigationCell} The focused cell. If the focus is already on the first cell, returns `null`.
     */
    focusPrevCell(wrap = true) {
        this.assertNavigable();
        return this.navigationService.focusPrevCell(wrap);
    }
    /**
     * Scrolls to the specified row and column ([see example](slug:scrollmmodes_grid#toc-scrolling-to-a-specific-row-and-column)).
     */
    scrollTo(request) {
        this.scrollRequestService.scrollTo(request, false);
    }
    /**
     * Scrolls to the specified data item and column ([see example](slug:scrollmmodes_grid#toc-scrolling-to-a-specific-item)).
     */
    scrollToItem(request) {
        this.scrollRequestService.scrollToItem(request);
    }
    /**
     * Changes the position of the specified column.
     * The reordering of columns operates only on the level
     * which is inferred by the source column.
     * For the `reorderColumn` method to work properly,
     * the `source` column has to be visible.
     *
     * @param {ColumnBase} source - The column whose position will be changed.
     * @param {number} destIndex - The new position of the column.
     * @param {ColumnReorderConfig} options - Additional options.
     *
     */
    reorderColumn(source, destIndex, options = { before: false }) {
        const columnsForLevel = sortColumns(this.allColumnsForLevel(source.level));
        let target = columnsForLevel[destIndex];
        if (!target) {
            return;
        }
        const lastNonLocked = target.isLocked &&
            !source.isLocked &&
            this.columnsContainer.nonLockedColumns.length === 1;
        if (lastNonLocked) {
            return;
        }
        if (isSpanColumnComponent(target) && !options.before) {
            target = target.childColumns.last;
        }
        this.reorder({
            before: options.before,
            source: source,
            target: target
        });
    }
    /**
     * A function which determines if a specific row is expanded.
     */
    set isDetailExpanded(callback) {
        this.detailsService.userCallback = callback;
    }
    get isDetailExpanded() {
        return this.detailsService.userCallback;
    }
    /**
     * A function which determines if a specific group row is expanded.
     */
    set isGroupExpanded(callback) {
        this.groupsService.userCallback = callback;
        this.groupable = isPresent(callback);
    }
    get isGroupExpanded() {
        return this.groupsService.userCallback;
    }
    /**
     * @hidden
     */
    handleReorderEvents(ev, evType) {
        this.rowReorderService[evType](ev);
    }
    /**
     * @hidden
     */
    get flatData() {
        return isArray(this.data) ? this.data : this.data.data;
    }
    /**
     * @hidden
     */
    updateNavigationMetadata() {
        this.navigationService.metadata = this.navigationMetadata();
    }
    /**
     * @hidden
     */
    reorder({ target, source, before, changeContainer }) {
        this.ngZone.run(() => {
            const columnsForLevel = sortColumns(this.allColumnsForLevel(source.level));
            let newIndex = columnsForLevel.indexOf(target);
            if (target.parent && target.parent.isSpanColumn) {
                newIndex = columnsForLevel.indexOf(target.parent);
                if (before) {
                    target = target.parent;
                }
            }
            const oldIndex = columnsForLevel.indexOf(source);
            if (changeContainer) {
                if (before && 0 < newIndex && oldIndex < newIndex) { // dropped before the first not locked column
                    newIndex--;
                }
                else if (!before && oldIndex > newIndex) { // dropped after the last locked column
                    newIndex++;
                }
            }
            const args = new ColumnReorderEvent({
                column: source,
                oldIndex: oldIndex,
                newIndex: newIndex
            });
            this.columnReorder.emit(args);
            if (args.isDefaultPrevented()) {
                return;
            }
            if (changeContainer) {
                this.columnLockedChange.emit(new ColumnLockedChangeEvent([source]));
            }
            this.updateColumnIndices({ columnsForLevel, source, target, before });
            if (source.locked !== target.locked) {
                source.locked = target.locked;
            }
            this.columnsContainer.refresh();
            this.changeDetectorRef.markForCheck();
        });
    }
    updateColumnIndices({ columnsForLevel, source, target, before }) {
        const expandedColumns = expandColumnsWithSpan(columnsForLevel);
        const sourceColumnIndex = expandedColumns.indexOf(source);
        let nextSourceIndex = 0;
        let nextIndex = 0;
        let toSkip = 1;
        // Possible only when called from the API.
        if (source.isSpanColumn) {
            toSkip += source.childColumns.length;
        }
        let i = 0;
        while (i < expandedColumns.length) {
            const column = expandedColumns[i];
            if (column === target) {
                nextSourceIndex = before ? nextIndex : nextIndex + 1;
                nextIndex = before ? nextIndex + toSkip : nextIndex;
                column.orderIndex = nextIndex;
                if (nextSourceIndex === nextIndex + 1) {
                    nextIndex += toSkip;
                }
            }
            else if (column === source) {
                i += toSkip;
                column.isReordered = true;
                continue;
            }
            else {
                column.orderIndex = nextIndex;
            }
            column.isReordered = true;
            nextIndex++;
            i++;
        }
        for (i = sourceColumnIndex; i < sourceColumnIndex + toSkip; i++) {
            expandedColumns[i].orderIndex = nextSourceIndex++;
            expandedColumns[i].isReordered = true;
        }
        this.updateIndicesForLevel(source.level + 1);
        this.columnResizingService.areColumnsReordered = true;
    }
    updateIndicesForLevel(level) {
        const colsForParentLevel = this.allColumnsForLevel(level - 1);
        const colsForLevel = [];
        sortColumns(colsForParentLevel).forEach((c) => {
            if (c.isColumnGroup) {
                colsForLevel.push(...c.childrenArray.sort((a, b) => a.orderIndex - b.orderIndex));
            }
        });
        expandColumnsWithSpan(colsForLevel).map((c, i) => {
            c.orderIndex = i;
            c.isReordered = true;
            return c;
        });
        if (level < this.columnList.totalColumnLevels()) {
            this.updateIndicesForLevel(level + 1);
        }
    }
    allColumnsForLevel(level) {
        return this.columnList.toArray().filter(column => column.level === level);
    }
    initSelectionService() {
        if (!this.selectable) {
            this.selectionService.ngOnDestroy();
            this.cellSelectionService.ngOnDestroy();
            return;
        }
        if (!this.selectionDirective && !isPresent(this.defaultSelection)) {
            this.defaultSelection = new Selection(this.ctx, this.changeDetectorRef);
        }
        const cellSelectionMode = this.selectable['cell'];
        const activeService = cellSelectionMode ? this.cellSelectionService : this.selectionService;
        const inactiveService = cellSelectionMode ? this.selectionService : this.cellSelectionService;
        if (inactiveService.active) {
            inactiveService.ngOnDestroy();
            activeService.addSubscriptions();
            inactiveService.active = false;
        }
        activeService.active = true;
        activeService.init({
            cellSelected: cellSelectionMode ? this.cellSelected : undefined,
            rowSelected: cellSelectionMode ? undefined : this.rowSelected,
            isRowSelectable: this.isRowSelectable,
            selectable: this.selectable,
            view: this.view,
            columns: cellSelectionMode ? this.columnList.toArray() : undefined
        });
        if (!this.selectionDirective && !this.selectableSettings.enabled) {
            this.defaultSelection.reset();
        }
        if (this.selectionSubscription) {
            this.selectionSubscription.unsubscribe();
        }
        if (cellSelectionMode) {
            this.selectionSubscription = this.cellSelectionService.changes.subscribe((event) => {
                this.ngZone.run(() => this.selectionChange.emit(event));
            });
        }
        else {
            this.selectionSubscription = this.selectionService.changes.subscribe((event) => {
                this.ngZone.run(() => this.selectionChange.emit(event));
            });
        }
    }
    setEditFocus(element) {
        if (element) {
            return this.navigationService.tryFocus(element);
        }
    }
    columnInstance(column) {
        let instance;
        if (typeof column === 'number') {
            instance = this.columnsContainer.lockedLeafColumns.toArray()
                .concat(this.columnsContainer.nonLockedLeafColumns.toArray())[column];
        }
        else if (typeof column === 'string') {
            instance = this.columnList.filter((item) => item.field === column)[0];
        }
        else {
            instance = column;
        }
        if (!instance && isDevMode()) {
            throw new Error(ColumnConfigurationErrorMessages.invalidColumn(column));
        }
        return instance;
    }
    verifySettings() {
        if (isDevMode()) {
            const locked = this.lockedLeafColumns.length || (this.columnMenu && this.columnMenu.lock);
            const stickyColumns = this.stickyColumns.length || (this.columnMenu && this.columnMenu.stick);
            if (locked && this.detailTemplate) {
                throw new Error(GridConfigurationErrorMessages.incompatibleFeatures('detail template', 'locked columns'));
            }
            if (stickyColumns && this.detailTemplate) {
                throw new Error(GridConfigurationErrorMessages.incompatibleFeatures('detail template', 'sticky columns'));
            }
            if (this.lockedLeafColumns.length && !this.nonLockedLeafColumns.length) {
                console.warn(GridConfigurationErrorMessages.nonLockedColumnPresent);
            }
            if ((locked || this.virtualColumns) && expandColumns(this.columnList.toArray()).filter(column => !column.width && !isColumnGroupComponent(column)).length) {
                console.warn(ColumnConfigurationErrorMessages.requiredWidth(locked ? 'Locked' : 'Virtual'));
            }
            if (locked && !this.isScrollable) {
                console.warn(ColumnConfigurationErrorMessages.requiredScroll('Locked'));
            }
            if (stickyColumns && !this.isScrollable) {
                console.warn(ColumnConfigurationErrorMessages.requiredScroll('Sticky'));
            }
            if (this.virtualColumns && !this.isScrollable) {
                console.warn(ColumnConfigurationErrorMessages.requiredScroll('Virtual'));
            }
            if (this.columnList.filter(isColumnGroupComponent).filter((x) => !x.hasChildren).length) {
                throw new Error(ColumnConfigurationErrorMessages.groupColumnContent);
            }
            if (this.columnList.filter(x => x.locked && x.parent && !x.parent.isLocked).length) {
                throw new Error(ColumnConfigurationErrorMessages.lockedParent);
            }
            if ((this.rowHeight || this.detailRowHeight) && !this.isVirtual) {
                console.warn(GridConfigurationErrorMessages.rowHeightVirtual);
            }
            if (!this.rowHeight && this.isVirtual) {
                console.warn(GridConfigurationErrorMessages.rowHeightVirtual);
            }
            if (!this.detailRowHeight && this.isVirtual && this.detailTemplate) {
                console.warn(GridConfigurationErrorMessages.rowHeightVirtual);
            }
            if (stickyColumns && expandColumns(this.columnList.toArray()).filter(column => !column.width && !isColumnGroupComponent(column)).length) {
                console.warn(ColumnConfigurationErrorMessages.requiredWidth('Sticky'));
            }
            if (this.rowSticky && this.scrollable === 'virtual') {
                throw new Error(GridConfigurationErrorMessages.incompatibleFeatures('sticky rows', 'row virtualization (scrollable="virtual")'));
            }
            if (this.rowSticky && this.groupable) {
                throw new Error(GridConfigurationErrorMessages.incompatibleFeatures('sticky rows', 'grouping'));
            }
            if (this.wrapper?.nativeElement?.querySelector('kendo-toolbar') && this.toolbarTemplate) {
                console.warn(GridConfigurationErrorMessages.unsupportedToolbarConfig);
            }
            validateColumnsField(this.columnList);
        }
    }
    autoGenerateColumns() {
        if (this.shouldGenerateColumns && !this.columns.length && this.view.length) {
            this.columns.reset(Object.keys(this.view.at(0)).map(field => {
                const column = new ColumnComponent();
                column.field = field;
                return column;
            }));
        }
    }
    attachStateChangesEmitter() {
        this.stateChangeSubscription =
            merge(this.pageChange.pipe(map(x => ({
                filter: this.filter, group: this.group, skip: x.skip, sort: this.sort, take: x.take
            }))), this.sortChange.pipe(map(sort => ({ filter: this.filter, group: this.group, skip: this.skip, sort: sort, take: this.pageSize }))), this.groupChange.pipe(map(group => ({
                filter: this.filter, group: group, skip: this.skip, sort: this.sort, take: this.pageSize
            }))), this.filterChange.pipe(map(filter => ({
                filter: filter, group: this.group, skip: 0, sort: this.sort, take: this.pageSize
            }))))
                .subscribe(x => {
                this.closeCell();
                this.cancelCell();
                if (this.selectable && this.selectableSettings?.enabled && this.isVirtual) {
                    this.blockArrowSelection = true;
                }
                this.dataStateChange.emit(x);
            });
    }
    attachEditHandlers() {
        if (!this.editService) {
            return;
        }
        this.editServiceSubscription = this.editService
            .changes.subscribe(this.emitCRUDEvent.bind(this));
    }
    emitCRUDEvent(args) {
        const { action, rowIndex, formGroup } = args;
        let dataItem = this.view.at(rowIndex - this.skip);
        if (action !== 'add' && !dataItem) {
            dataItem = formGroup.value;
        }
        this.closeCell();
        Object.assign(args, {
            dataItem: dataItem,
            sender: this
        });
        switch (action) {
            case 'add':
                this.add.emit(args);
                break;
            case 'cancel':
                this.cancel.emit(args);
                break;
            case 'edit':
                this.edit.emit(args);
                break;
            case 'remove':
                this.remove.emit(args);
                break;
            case 'save':
                this.save.emit(args);
                break;
            case 'cellClose':
                this.cellClose.emit(args);
                break;
            default: break;
        }
    }
    attachDomEventHandlers() {
        this.cellClickSubscription = this.domEvents.cellClick.subscribe((args) => {
            this.cellClick.emit(Object.assign({ sender: this }, args));
        });
    }
    attachElementEventHandlers() {
        if (isUniversal()) {
            return;
        }
        const wrapper = this.wrapper.nativeElement;
        const ariaRoot = this.ariaRoot.nativeElement;
        this.ngZone.runOutsideAngular(() => {
            const resizeCheck = this.resizeCheck.bind(this);
            const resizeSubscription = this.renderer.listen('window', 'resize', resizeCheck);
            const orientationSubscription = this.renderer.listen('window', 'orientationchange', resizeCheck);
            const documentClickSubscription = this.renderer.listen('document', 'click', (args) => {
                const activeElement = document.activeElement;
                if (this.editService.shouldCloseCell() &&
                    !closest(args.target, matchesClasses('k-animation-container k-grid-ignore-click')) &&
                    !(activeElement &&
                        (closest(activeElement, matchesClasses('k-animation-container')) ||
                            isInEditedCell(activeElement, this.wrapper.nativeElement)))) {
                    this.editService.closeCell(args);
                }
            });
            const windowBlurSubscription = this.renderer.listen('window', 'blur', (args) => {
                const activeElement = document.activeElement;
                if (activeElement && !(matchesNodeName('input')(activeElement) && activeElement.type === 'file' &&
                    isInEditedCell(activeElement, this.wrapper.nativeElement))) {
                    this.editService.closeCell(args);
                }
                this.domEvents.windowBlur.emit(args);
            });
            const clickSubscription = this.renderer.listen(wrapper, 'click', (args) => {
                this.domEvents.click.emit(args);
            });
            const keydownSubscription = this.renderer.listen(wrapper, 'keydown', (args) => {
                this.domEvents.keydown.emit(args);
            });
            // focusIn and focusOut are relative to the element with ARIA role "grid"
            let focused = false;
            const focusInSubscription = this.renderer.listen(ariaRoot, 'focusin', (args) => {
                this.domEvents.focus.emit(args);
                if (!focused) {
                    this.domEvents.focusIn.emit(args);
                    focused = true;
                }
            });
            const focusOutSubscription = this.renderer.listen(ariaRoot, 'focusout', (args) => {
                const next = args.relatedTarget || document.activeElement;
                const outside = !closest(next, (node) => node === ariaRoot);
                if (outside) {
                    this.domEvents.focusOut.emit(args);
                    focused = false;
                }
            });
            this.detachElementEventHandlers = () => {
                resizeSubscription();
                orientationSubscription();
                documentClickSubscription();
                windowBlurSubscription();
                clickSubscription();
                keydownSubscription();
                focusInSubscription();
                focusOutSubscription();
            };
        });
    }
    matchesMedia(c) {
        return this.responsiveService.matchesMedia(c.media);
    }
    resizeCheck() {
        if (window.innerWidth !== this.cachedWindowWidth) {
            this.cachedWindowWidth = window.innerWidth;
            let hasChanges = false;
            this.columnList.filterHierarchy(column => {
                const matchesMedia = this.matchesMedia(column);
                if (column.matchesMedia !== matchesMedia) {
                    hasChanges = true;
                    column.matchesMedia = matchesMedia;
                }
                return column.isVisible;
            });
            if (hasChanges) {
                this.ngZone.run(() => {
                    this.changeDetectorRef.markForCheck();
                });
            }
        }
    }
    emitPDFExportEvent() {
        const args = new PDFExportEvent();
        this.pdfExport.emit(args);
        if (!args.isDefaultPrevented()) {
            this.saveAsPDF();
        }
    }
    syncHeaderHeight(observable) {
        return observable
            .pipe(filter(() => isPresent(this.lockedHeader)))
            .subscribe(() => syncRowsHeight(this.lockedHeader.nativeElement.children[0], this.header.nativeElement.children[0]));
    }
    columnsContainerChange() {
        this.columnsContainerChangeSubscription =
            this.syncHeaderHeight(this.columnsContainer.changes.pipe(filter(() => this.lockedColumns.length > 0), switchMap(() => this.ngZone.onStable.asObservable().pipe(take(1)))));
    }
    handleColumnResize() {
        const resizes = this.columnResizingService.changes;
        this.columnResizingSubscription = resizes.pipe(tap(e => {
            if (e.type === 'start') {
                this.renderer.addClass(this.wrapper.nativeElement, 'k-grid-column-resizing');
            }
            else if (e.type === 'end') {
                this.renderer.removeClass(this.wrapper.nativeElement, 'k-grid-column-resizing');
            }
        }), filter(e => e.type === 'start'), switchMap(() => resizes.pipe(takeUntil(resizes.pipe(filter(e => e.type === 'triggerAutoFit'))), filter(e => e.type === 'end'))))
            .subscribe(this.notifyResize.bind(this));
    }
    notifyResize(e) {
        const args = e.resizedColumns
            .filter(item => isTruthy(item.column.resizable) && !item.column.isColumnGroup)
            .map(item => ({
            column: item.column,
            newWidth: roundDown(item.column.width),
            oldWidth: roundDown(item.oldWidth)
        }));
        this.columnResize.emit(args);
    }
    assertNavigable() {
        if (isDevMode() && !this.navigationService.enabled) {
            throw new Error(GridConfigurationErrorMessages.focusNavigable);
        }
    }
    _rowClass = () => null;
    navigationMetadata() {
        const isVirtual = this.isVirtual;
        const pageSize = this.pageSize;
        const dataRows = isVirtual ? this.view.total : pageSize;
        const addRowOffset = this.editService.hasNewItem ? 1 : 0;
        const filterRowOffset = hasFilterRow(this.filterable) ? 1 : 0;
        const headerRows = this.totalColumnLevels + 1 + filterRowOffset + addRowOffset;
        return new NavigationMetadata(dataRows, headerRows, isVirtual, this.hasPager, isPresent(this.detailTemplate), this.wrapper, this.virtualColumns, this.columnsContainer);
    }
    applyAutoSize() {
        const cols = this.columns.filter((c) => this.autoSize ? c.autoSize !== false : c.autoSize);
        if (cols.length > 0) {
            this.ngZone.onStable.pipe(take(1)).subscribe(() => this.autoFitColumns(cols));
        }
    }
    onColumnRangeChange(range) {
        const viewportColumns = this.viewportColumns = [];
        const columnsArray = this.columnsContainer.nonLockedLeafColumns.toArray();
        let leafViewportColumns = columnsArray.slice(range.start, range.end + 1);
        const stickyBeforeStart = columnsArray.slice(0, range.start).filter(c => c.sticky && !leafViewportColumns.some(col => col === c));
        const stickyAfterEnd = columnsArray.slice(range.end, columnsArray.length).filter(c => c.sticky && !leafViewportColumns.some(col => col === c));
        leafViewportColumns = [...stickyBeforeStart, ...leafViewportColumns, ...stickyAfterEnd];
        for (let idx = 0; idx < leafViewportColumns.length; idx++) {
            let column = leafViewportColumns[idx];
            while (column.parent) {
                column = column.parent;
            }
            const toAdd = [column];
            while (toAdd.length) {
                column = toAdd.shift();
                viewportColumns.push(column);
                if (column.isColumnGroup) {
                    toAdd.unshift(...column.childrenArray);
                }
            }
            const lastFromGroup = viewportColumns[viewportColumns.length - 1];
            column = leafViewportColumns[idx];
            while (column !== lastFromGroup && idx < leafViewportColumns.length) {
                idx++;
                column = leafViewportColumns[idx];
            }
        }
        if (range.start > 0) {
            const first = leafViewportColumns[0];
            let offset = range.offset;
            let current = viewportColumns[0];
            let index = 0;
            while (current !== first) {
                offset -= current.isColumnGroup ? 0 : current.width;
                index++;
                current = viewportColumns[index];
            }
            if (offset > 0) {
                const totalLevels = this.columnsContainer.totalLevels;
                let previous;
                for (let idx = 0; idx <= totalLevels; idx++) {
                    const offsetColumn = idx < totalLevels ? new ColumnGroupComponent(previous) : new ColumnBase(previous);
                    previous = offsetColumn;
                    offsetColumn.title = "\u00A0";
                    offsetColumn.width = offset;
                    viewportColumns.unshift(offsetColumn);
                }
            }
        }
        this.leafViewportColumns = viewportColumns.filter(c => !c.isColumnGroup);
    }
    toggleDetailRowLegacy(index, expand) {
        const hasCallback = typeof this.isDetailExpanded === 'function';
        if (isDevMode() && hasCallback) {
            throw new Error(GridConfigurationErrorMessages.expandCollapseMethods('expandRow', 'collapseRow', 'kendoGridDetailsExpandBy', 'isDetailExpanded'));
        }
        if (!isDevMode() && hasCallback) {
            return;
        }
        if (this.detailsService.isExpanded(index, null) !== expand) {
            this.detailsService.toggleRow(index, null);
        }
    }
    toggleGroupRowLegacy(index, expand) {
        const hasCallback = typeof this.isGroupExpanded === 'function';
        if (isDevMode() && hasCallback) {
            throw new Error(GridConfigurationErrorMessages.expandCollapseMethods('expandGroup', 'collapseGroup', 'kendoGridExpandGroupBy', 'isGroupExpanded'));
        }
        if (!isDevMode() && hasCallback) {
            return;
        }
        if (this.groupsService.isExpanded({ groupIndex: index }) !== expand) {
            this.groupsService.toggleRow({ index }, false);
            if (this.ctx.groupBindingDirective) {
                this.ctx.groupBindingDirective[`group${expand ? 'Expand' : 'Collapse'}`]({ groupIndex: index });
            }
        }
    }
    shouldResetSelection(selectableChanges) {
        const previousValue = selectableChanges.previousValue;
        if (!previousValue) {
            // Selection was disabled, no need to reset.
            return false;
        }
        const currentValue = selectableChanges.currentValue;
        if (!currentValue || currentValue.enabled === false) {
            // Selection disabled, reset.
            return true;
        }
        return previousValue.cell !== currentValue.cell;
    }
    notifyReorderContainers() {
        this.dragTargetContainer?.notify();
        this.dropTargetContainer?.notify();
    }
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: GridComponent, deps: [{ token: i1.BrowserSupportService }, { token: i2.SelectionService }, { token: i3.CellSelectionService }, { token: i0.ElementRef }, { token: i4.GroupInfoService }, { token: i5.GroupsService }, { token: i6.ChangeNotificationService }, { token: i7.DetailsService }, { token: i8.EditService }, { token: i9.FilterService }, { token: i10.PDFService }, { token: i11.ResponsiveService }, { token: i0.Renderer2 }, { token: i12.ExcelService }, { token: i0.NgZone }, { token: i13.ScrollSyncService }, { token: i14.DomEventsService }, { token: i15.ColumnResizingService }, { token: i0.ChangeDetectorRef }, { token: i16.ColumnReorderService }, { token: i17.ColumnInfoService }, { token: i18.NavigationService }, { token: i19.SortService }, { token: i20.ScrollRequestService }, { token: i21.LocalizationService }, { token: i22.ContextService }, { token: i23.SizingOptionsService }, { token: i24.RowReorderService }], target: i0.ɵɵFactoryTarget.Component });
    static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: GridComponent, isStandalone: true, selector: "kendo-grid", inputs: { data: "data", pageSize: "pageSize", height: "height", rowHeight: "rowHeight", detailRowHeight: "detailRowHeight", skip: "skip", scrollable: "scrollable", selectable: "selectable", sort: "sort", size: "size", trackBy: "trackBy", filter: "filter", group: "group", virtualColumns: "virtualColumns", filterable: "filterable", sortable: "sortable", pageable: "pageable", groupable: "groupable", gridResizable: "gridResizable", rowReorderable: "rowReorderable", navigable: "navigable", navigatable: "navigatable", autoSize: "autoSize", rowClass: "rowClass", rowSticky: "rowSticky", rowSelected: "rowSelected", isRowSelectable: "isRowSelectable", cellSelected: "cellSelected", resizable: "resizable", reorderable: "reorderable", loading: "loading", columnMenu: "columnMenu", hideHeader: "hideHeader", isDetailExpanded: "isDetailExpanded", isGroupExpanded: "isGroupExpanded" }, outputs: { filterChange: "filterChange", pageChange: "pageChange", groupChange: "groupChange", sortChange: "sortChange", selectionChange: "selectionChange", rowReorder: "rowReorder", dataStateChange: "dataStateChange", groupExpand: "groupExpand", groupCollapse: "groupCollapse", detailExpand: "detailExpand", detailCollapse: "detailCollapse", edit: "edit", cancel: "cancel", save: "save", remove: "remove", add: "add", cellClose: "cellClose", cellClick: "cellClick", pdfExport: "pdfExport", excelExport: "excelExport", columnResize: "columnResize", columnReorder: "columnReorder", columnVisibilityChange: "columnVisibilityChange", columnLockedChange: "columnLockedChange", columnStickyChange: "columnStickyChange", scrollBottom: "scrollBottom", contentScroll: "contentScroll" }, host: { properties: { "attr.dir": "this.dir", "class.k-grid": "this.hostClass", "class.k-grid-sm": "this.sizeSmallClass", "class.k-grid-md": "this.sizeMediumClass", "class.k-grid-lockedcolumns": "this.lockedClasses", "class.k-grid-virtual": "this.virtualClasses", "class.k-grid-no-scrollbar": "this.noScrollbarClass", "class.k-grid-resizable": "this.isResizable", "style.minWidth": "this.minWidth", "style.maxWidth": "this.maxWidth", "style.minHeight": "this.minHeight", "style.maxHeight": "this.maxHeight" } }, providers: [
            BrowserSupportService,
            LocalizationService,
            ColumnInfoService,
            SelectionService,
            CellSelectionService,
            DetailsService,
            GroupsService,
            GroupInfoService,
            ChangeNotificationService,
            EditService,
            PDFService,
            SuspendService,
            {
                provide: CELL_CONTEXT,
                useValue: EMPTY_CELL_CONTEXT
            },
            {
                provide: L10N_PREFIX,
                useValue: 'kendo.grid'
            },
            FilterService,
            ResponsiveService,
            PagerContextService,
            PagerNavigationService,
            ExcelService,
            ScrollSyncService,
            ResizeService,
            LocalDataChangesService,
            DomEventsService,
            ColumnResizingService,
            SinglePopupService,
            DragAndDropService,
            DragHintService,
            DropCueService,
            ColumnReorderService,
            NavigationService,
            FocusRoot,
            IdService,
            CellSelectionAggregateService,
            ScrollRequestService,
            SortService,
            ContextService,
            SizingOptionsService,
            RowReorderService,
            ClipboardService,
            RowspanService
        ], queries: [{ propertyName: "columns", predicate: ColumnBase }, { propertyName: "detailTemplateChildren", predicate: DetailTemplateDirective }, { propertyName: "cellLoadingTemplateChildren", predicate: CellLoadingTemplateDirective }, { propertyName: "loadingTemplateChildren", predicate: LoadingTemplateDirective }, { propertyName: "statusBarTemplateChildren", predicate: StatusBarTemplateDirective }, { propertyName: "noRecordsTemplateChildren", predicate: NoRecordsTemplateDirective }, { propertyName: "pagerTemplateChildren", predicate: PagerTemplateDirective }, { propertyName: "toolbarTemplateChildren", predicate: ToolbarTemplateDirective }, { propertyName: "columnMenuTemplates", predicate: ColumnMenuTemplateDirective }], viewQueries: [{ propertyName: "lockedHeader", first: true, predicate: ["lockedHeader"], descendants: true }, { propertyName: "header", first: true, predicate: ["header"], descendants: true }, { propertyName: "ariaRoot", first: true, predicate: ["ariaRoot"], descendants: true, static: true }, { propertyName: "dragTargetContainer", first: true, predicate: DragTargetContainerDirective, descendants: true }, { propertyName: "dropTargetContainer", first: true, predicate: DropTargetContainerDirective, descendants: true }, { propertyName: "footer", predicate: ["footer"], descendants: true }], exportAs: ["kendoGrid"], usesOnChanges: true, ngImport: i0, template: `
        <ng-container kendoGridLocalizedMessages
            i18n-groupPanelEmpty="kendo.grid.groupPanelEmpty|The label visible in the Grid group panel when it is empty"
            groupPanelEmpty="Drag a column header and drop it here to group by that column"

            i18n-noRecords="kendo.grid.noRecords|The label visible in the Grid when there are no records"
            noRecords="No records available."

            i18n-pagerLabel="kendo.grid.pagerLabel|The label for the Grid pager"
            pagerLabel="{{ 'Page navigation, page {currentPage} of {totalPages}' }}"

            i18n-pagerFirstPage="kendo.grid.pagerFirstPage|The label for the first page button in Grid pager"
            pagerFirstPage="Go to the first page"

            i18n-pagerPreviousPage="kendo.grid.pagerPreviousPage|The label for the previous page button in Grid pager"
            pagerPreviousPage="Go to the previous page"

            i18n-pagerNextPage="kendo.grid.pagerNextPage|The label for the next page button in Grid pager"
            pagerNextPage="Go to the next page"

            i18n-pagerLastPage="kendo.grid.pagerLastPage|The label for the last page button in Grid pager"
            pagerLastPage="Go to the last page"

            i18n-pagerPage="kendo.grid.pagerPage|The label before the current page number in the Grid pager"
            pagerPage="Page"

            i18n-pagerOf="kendo.grid.pagerOf|The label before the total pages number in the Grid pager"
            pagerOf="of"

            i18n-pagerItems="kendo.grid.pagerItems|The label after the total pages number in the Grid pager"
            pagerItems="items"

            i18n-pagerPageNumberInputTitle="kendo.grid.pagerPageNumberInputTitle|The label for the pager input in the Grid pager"
            pagerPageNumberInputTitle="Page Number"

            i18n-pagerItemsPerPage="kendo.grid.pagerItemsPerPage|The label for the page size chooser in the Grid pager"
            pagerItemsPerPage="items per page"

            i18n-pagerInputLabel="kendo.grid.pagerInputLabel|The text of the aria-label attribute applied to the input element for entering the page number"
            pagerInputLabel="Type a page number"

            i18n-filter="kendo.grid.filter|The label of the filter cell or icon"
            filter="Filter"

            i18n-filterInputLabel="kendo.grid.filterInputLabel|The label of the filter row and menu inputs"
            filterInputLabel="{{ '{columnName} Filter' }}"

            i18n-filterMenuTitle="kendo.grid.filterMenuTitle|The title of the filter menu icon"
            filterMenuTitle="{{ '{columnName} Filter Menu' }}"

            i18n-filterMenuOperatorsDropDownLabel="kendo.grid.filterMenuOperatorsDropDownLabel|The label of the filter menu operators dropdown"
            filterMenuOperatorsDropDownLabel="{{ '{columnName} Filter Operators' }}"
            
            i18n-filterCellOperatorLabel="kendo.grid.filterCellOperatorLabel|The label of the filter cell operators dropdown"
            filterCellOperatorLabel="{{ 'Filter cell operators for {columnName}' }}"

            i18n-booleanFilterCellLabel="kendo.grid.booleanFilterCellLabel|The label of the boolean filter cell dropdown"
            booleanFilterCellLabel="{{ 'Boolean filter cell for {columnName}' }}"

            i18n-filterMenuLogicDropDownLabel="kendo.grid.filterMenuLogicDropDownLabel|The label of the filter menu logic dropdown"
            filterMenuLogicDropDownLabel="{{ '{columnName} Filter Logic' }}"

            i18n-filterEqOperator="kendo.grid.filterEqOperator|The text of the equal filter operator"
            filterEqOperator="Is equal to"

            i18n-filterNotEqOperator="kendo.grid.filterNotEqOperator|The text of the not equal filter operator"
            filterNotEqOperator="Is not equal to"

            i18n-filterIsNullOperator="kendo.grid.filterIsNullOperator|The text of the is null filter operator"
            filterIsNullOperator="Is null"

            i18n-filterIsNotNullOperator="kendo.grid.filterIsNotNullOperator|The text of the is not null filter operator"
            filterIsNotNullOperator="Is not null"

            i18n-filterIsEmptyOperator="kendo.grid.filterIsEmptyOperator|The text of the is empty filter operator"
            filterIsEmptyOperator="Is empty"

            i18n-filterIsNotEmptyOperator="kendo.grid.filterIsNotEmptyOperator|The text of the is not empty filter operator"
            filterIsNotEmptyOperator="Is not empty"

            i18n-filterStartsWithOperator="kendo.grid.filterStartsWithOperator|The text of the starts with filter operator"
            filterStartsWithOperator="Starts with"

            i18n-filterContainsOperator="kendo.grid.filterContainsOperator|The text of the contains filter operator"
            filterContainsOperator="Contains"

            i18n-filterNotContainsOperator="kendo.grid.filterNotContainsOperator|The text of the does not contain filter operator"
            filterNotContainsOperator="Does not contain"

            i18n-filterEndsWithOperator="kendo.grid.filterEndsWithOperator|The text of the ends with filter operator"
            filterEndsWithOperator="Ends with"

            i18n-filterGteOperator="kendo.grid.filterGteOperator|The text of the greater than or equal filter operator"
            filterGteOperator="Is greater than or equal to"

            i18n-filterGtOperator="kendo.grid.filterGtOperator|The text of the greater than filter operator"
            filterGtOperator="Is greater than"

            i18n-filterLteOperator="kendo.grid.filterLteOperator|The text of the less than or equal filter operator"
            filterLteOperator="Is less than or equal to"

            i18n-filterLtOperator="kendo.grid.filterLtOperator|The text of the less than filter operator"
            filterLtOperator="Is less than"

            i18n-filterIsTrue="kendo.grid.filterIsTrue|The text of the IsTrue boolean filter option"
            filterIsTrue="Is True"

            i18n-filterIsFalse="kendo.grid.filterIsFalse|The text of the IsFalse boolean filter option"
            filterIsFalse="Is False"

            i18n-filterBooleanAll="kendo.grid.filterBooleanAll|The text of the (All) boolean filter option"
            filterBooleanAll="(All)"

            i18n-filterAfterOrEqualOperator="kendo.grid.filterAfterOrEqualOperator|The text of the after or equal date filter operator"
            filterAfterOrEqualOperator="Is after or equal to"

            i18n-filterAfterOperator="kendo.grid.filterAfterOperator|The text of the after date filter operator"
            filterAfterOperator="Is after"

            i18n-filterBeforeOperator="kendo.grid.filterBeforeOperator|The text of the before date filter operator"
            filterBeforeOperator="Is before"

            i18n-filterBeforeOrEqualOperator="kendo.grid.filterBeforeOrEqualOperator|The text of the before or equal date filter operator"
            filterBeforeOrEqualOperator="Is before or equal to"

            i18n-filterFilterButton="kendo.grid.filterFilterButton|The text of the filter button"
            filterFilterButton="Filter"

            i18n-filterClearButton="kendo.grid.filterClearButton|The text of the clear filter button"
            filterClearButton="Clear"

            i18n-filterAndLogic="kendo.grid.filterAndLogic|The text of the And filter logic"
            filterAndLogic="And"

            i18n-filterOrLogic="kendo.grid.filterOrLogic|The text of the Or filter logic"
            filterOrLogic="Or"

            i18n-loading="kendo.grid.loading|The loading text"
            loading="Loading"

            i18n-gridLabel="kendo.grid.gridLabel|The Grid aria-label"
            gridLabel="Data table"

            i18n-columnMenu="kendo.grid.columnMenu|The title of the column menu icon"
            columnMenu="{{ '{columnName} Column Menu' }}"

            i18n-columns="kendo.grid.columns|The text shown in the column menu for the columns item"
            columns="Columns"

            i18n-lock="kendo.grid.lock|The text shown in the column menu for the lock item"
            lock="Lock"

            i18n-unlock="kendo.grid.unlock|The text shown in the column menu for the unlock item"
            unlock="Unlock"

            i18n-setColumnPosition="kendo.grid.setColumnPosition|The text shown in the column menu for the set column position item"
            setColumnPosition="Set Column Position"

            i18n-stick="kendo.grid.stick|The text shown in the column menu for the stick item"
            stick="Stick"

            i18n-unstick="kendo.grid.unstick|The text shown in the column menu for the unstick item"
            unstick="Unstick"

            i18n-sortable="kendo.grid.sortable|The label of the sort icon"
            sortable="Sortable"

            i18n-sortAscending="kendo.grid.sortAscending|The text shown in the column menu for the sort ascending item"
            sortAscending="Sort Ascending"

            i18n-sortDescending="kendo.grid.sortDescending|The text shown in the column menu for the sort descending item"
            sortDescending="Sort Descending"

            i18n-autosizeAllColumns="kendo.grid.autosizeAllColumns|The text shown in the column menu for the autosize all columns item"
            autosizeAllColumns="Autosize All Columns"

            i18n-autosizeThisColumn="kendo.grid.autosizeThisColumn|The text shown in the column menu for the autosize this column item"
            autosizeThisColumn="Autosize This Column"

            i18n-sortedDefault="kendo.grid.sortedDefault|The status announcement when a column is no longer sorted"
            sortedDefault="Not Sorted"

            i18n-sortedAscending="kendo.grid.sortedAscending|The title of the Group Chip indicating the ascending sorting order of the groups"
            sortedAscending="Sorted Ascending"
            
            i18n-sortedDescending="kendo.grid.sortedDescending|The title of the Group Chip indicating the descending sorting order of the groups"
            sortedDescending="Sorted Descending"

            i18n-columnsApply="kendo.grid.columnsApply|The text shown in the column menu or column chooser for the columns apply button"
            columnsApply="Apply"

            i18n-columnsReset="kendo.grid.columnsReset|The text shown in the column menu or column chooser for the columns reset button"
            columnsReset="Reset"

            i18n-detailExpand="kendo.grid.detailExpand|The title of the expand icon of detail rows."
            detailExpand="Expand Details"

            i18n-detailCollapse="kendo.grid.detailCollapse|The title of the collapse icon of detail rows."
            detailCollapse="Collapse Details"

            i18n-filterDateToday="kendo.grid.filterDateToday|The text of the Today button of the Date filter."
            filterDateToday="TODAY"

            i18n-filterDateToggle="kendo.grid.filterDateToggle|The title of the Toggle button of the Date filter."
            filterDateToggle="Toggle Calendar"

            i18n-filterNumericDecrement="kendo.grid.filterNumericDecrement|The title of the Decrement button of the Numeric filter."
            filterNumericDecrement="Decrement"

            i18n-filterNumericIncrement="kendo.grid.filterNumericIncrement|The title of the Increment button of the Numeric filter."
            filterNumericIncrement="Increment"

            i18n-selectionCheckboxLabel="kendo.grid.selectionCheckboxLabel|The labels of the checkbox column checkboxes."
            selectionCheckboxLabel="Select Row"

            i18n-selectAllCheckboxLabel="kendo.grid.selectAllCheckboxLabel|The label of the checkbox column select all checkbox."
            selectAllCheckboxLabel="Select All Rows"

            i18n-groupCollapse="kendo.grid.groupCollapse|The text of the title and aria-label attributes applied to the collapse icon of group rows."
            groupCollapse="Collapse Group"

            i18n-groupExpand="kendo.grid.groupExpand|The text of the title and aria-label attributes applied to the expand icon of group rows."
            groupExpand="Expand Group"

            i18n-pagerSelectPage="kendo.grid.pagerSelectPage|The text of the title and aria-label attributes applied to the page chooser in the Grid Pager"
            pagerSelectPage="Select page"

            i18n-topToolbarLabel="kendo.grid.topToolbarLabel|The label for the Grid top toolbar"
            topToolbarLabel="Top toolbar"

            i18n-bottomToolbarLabel="kendo.grid.bottomToolbarLabel|The label for the Grid bottom toolbar"
            bottomToolbarLabel="Bottom toolbar"

            i18n-groupPanelLabel="kendo.grid.groupPanelLabel|The label for the Grid group panel toolbar"
            groupPanelLabel="Group panel"

            i18n-dragRowHandleLabel="kendo.grid.dragRowHandleLabel|The label for the Grid drag row handle"
            dragRowHandleLabel="Drag row"

            i18n-columnMenuFilterTabTitle="kendo.grid.columnMenuFilterTabTitle|The title for the column menu Filter tab"
            columnMenuFilterTabTitle="Filter"

            i18n-columnMenuGeneralTabTitle="kendo.grid.columnMenuGeneralTabTitle|The title for the column menu General tab"
            columnMenuGeneralTabTitle="General"

            i18n-columnMenuColumnsTabTitle="kendo.grid.columnMenuColumnsTabTitle|The title for the column menu Columns tab"
            columnMenuColumnsTabTitle="Columns"

            i18n-groupChipMenuPrevious="kendo.grid.groupChipMenuPrevious|The text for the Group pane Chip Menu Move as previous item"
            groupChipMenuPrevious="Move as previous"

            i18n-groupChipMenuNext="kendo.grid.groupChipMenuNext|The text for the Group pane Chip Menu Move as next item"
            groupChipMenuNext="Move as next"
        >
        </ng-container>
        <kendo-grid-toolbar
            *ngIf="showTopToolbar"
            [size]="size"
            [attr.aria-label]="messageFor('topToolbarLabel')"
            [navigable]="navigation.toolbarEnabled"
            [attr.aria-controls]="ariaRootId"
            position="top"></kendo-grid-toolbar>
        <ng-content select="kendo-toolbar"></ng-content>
        <kendo-pager
            *ngIf="showTopPager"
            #topPager
            [navigable]="navigation.pagerEnabled"
            class="k-grid-pager k-grid-pager-top"
            [pageSize]="pageSize"
            [total]="view.total"
            [skip]="skip"
            [size]="size"
            [responsive]="normalizedPageableSettings.responsive && !pagerTemplate"
            [buttonCount]="normalizedPageableSettings.buttonCount"
            [info]="normalizedPageableSettings.info"
            [pageSizeValues]="normalizedPageableSettings.pageSizes"
            [previousNext]="normalizedPageableSettings.previousNext"
            [type]="normalizedPageableSettings.type"
            (pageChange)="notifyPageChange('pager', $event)">
            <ng-template kendoPagerTemplate>
                <ng-container
                    [ngTemplateOutlet]="pagerTemplate ? pagerTemplate?.templateRef : defaultPager"
                    [ngTemplateOutletContext]="topPager.templateContext"></ng-container>
            </ng-template>
            <kendo-pager-messages
                [ariaLabel]="messageFor('pagerLabel')"
                [firstPage]="messageFor('pagerFirstPage')"
                [inputLabel]="messageFor('pagerInputLabel')"
                [previousPage]="messageFor('pagerPreviousPage')"
                [nextPage]="messageFor('pagerNextPage')"
                [lastPage]="messageFor('pagerLastPage')"
                [selectPage]="messageFor('pagerSelectPage')"
                [page]="messageFor('pagerPage')"
                [itemsPerPage]="messageFor('pagerItemsPerPage')"
                [items]="messageFor('pagerItems')"
                [of]="messageFor('pagerOf')"
                [pageNumberInputTitle]="messageFor('pagerPageNumberInputTitle')">
            </kendo-pager-messages>
        </kendo-pager>
        <kendo-grid-group-panel
            *ngIf="showGroupPanel"
            [navigable]="navigation.toolbarEnabled"
            [text]="groupableEmptyText"
            [groups]="group"
            role="toolbar"
            [attr.aria-label]="messageFor('groupPanelLabel')"
            [attr.aria-controls]="ariaRootId"
            (change)="groupChange.emit($event)">
        </kendo-grid-group-panel>
        <div #ariaRoot
            class="k-grid-aria-root"
            role="grid"
            kendoDragTargetContainer
            kendoDropTargetContainer
            mode="manual"
            [dragDisabled]="!rowReorderable"
            [dropDisabled]="!rowReorderable"
            [dragTargetFilter]="getDefaultSelectors('dragTarget')"
            [dropTargetFilter]="getDefaultSelectors('dropTarget')"
            [dragHandle]="getDefaultSelectors('handle')"
            [hint]="{hintTemplate: customHintTemplate || defaultHint}"
            [hintContext]="hintContext"
            (onPress)="handleReorderEvents($event, 'press')"
            (onDragStart)="handleReorderEvents($event, 'dragStart')"
            (onDrag)="handleReorderEvents($event, 'drag')"
            (onDragEnter)="handleReorderEvents($event, 'dragEnter')"
            (onDragLeave)="handleReorderEvents($event, 'dragLeave')"
            (onDragEnd)="handleReorderEvents($event, 'dragEnd')"
            (onDrop)="handleReorderEvents($event, 'drop')"
            [dragData]="gridData"
            [id]="ariaRootId"
            [attr.aria-label]="ariaLabel"
            [attr.aria-rowcount]="ariaRowCount"
            [attr.aria-colcount]="ariaColCount">
            <ng-container *ngIf="isScrollable">
                <div *ngIf="!hideHeader"
                    class="k-grid-header"
                    [class.k-grid-draggable-header]="groupable || reorderable"
                    role="presentation"
                    [style.padding]="headerPadding">
                    <div *ngIf="isLocked"
                        #lockedHeader
                        role="presentation"
                        class="k-grid-header-locked"
                        [style.width.px]="lockedWidth">
                        <table
                            kendoGridResizableTable
                            [locked]="true"
                            role="presentation"
                            class="k-grid-header-table"
                            [style.width.px]="lockedWidth"
                            kendoGridTable
                            [size]="size">
                            <colgroup kendoGridColGroup
                                [columns]="$any(lockedLeafColumns)"
                                [groups]="group"
                                [detailTemplate]="detailTemplate">
                            </colgroup>
                            <thead kendoGridHeader
                                role="rowgroup"
                                [resizable]="resizable"
                                [scrollable]="true"
                                [columns]="$any(lockedColumns)"
                                [totalColumnLevels]="totalColumnLevels"
                                [sort]="sort"
                                [groups]="group"
                                [filter]="filter"
                                [filterable]="filterable"
                                [groupable]="showGroupPanel"
                                [reorderable]="reorderable"
                                [sortable]="sortable"
                                [columnMenu]="columnMenuOptions"
                                [columnMenuTemplate]="columnMenuTemplate"
                                [totalColumnsCount]="leafColumns.length"
                                [totalColumns]="columnsContainer"
                                [detailTemplate]="detailTemplate"
                                [tabIndex]="navigation.tableEnabled ? '-1' : '0'">
                            </thead>
                        </table>
                    </div>
                    <div #header class="k-grid-header-wrap" role="presentation" data-scrollable
                        [kendoGridResizableContainer]="lockedLeafColumns.length > 0"
                        [lockedWidth]="lockedWidth + scrollbarWidth + 2">
                        <table
                            role="presentation"
                            class="k-grid-header-table"
                            [style.width.px]="nonLockedWidth"
                            kendoGridResizableTable
                            [virtualColumns]="virtualColumns"
                            kendoGridTable
                            [size]="size">
                            <colgroup kendoGridColGroup
                                [columns]="headerLeafColumns"
                                [groups]="isLocked ? [] : group"
                                [detailTemplate]="detailTemplate">
                            </colgroup>
                            <thead kendoGridHeader
                                [resizable]="resizable"
                                role="rowgroup"
                                [scrollable]="true"
                                [columns]="headerColumns"
                                [totalColumnLevels]="totalColumnLevels"
                                [sort]="sort"
                                [filter]="filter"
                                [filterable]="filterable"
                                [groupable]="showGroupPanel"
                                [reorderable]="reorderable"
                                [groups]="isLocked ? [] : group"
                                [sortable]="sortable"
                                [columnMenu]="columnMenuOptions"
                                [columnMenuTemplate]="columnMenuTemplate"
                                [lockedColumnsCount]="lockedLeafColumns.length"
                                [totalColumnsCount]="leafColumns.length"
                                [totalColumns]="columnsContainer"
                                [detailTemplate]="detailTemplate"
                                [tabIndex]="navigation.tableEnabled ? '-1' : '0'">
                            </thead>
                        </table>
                        <div *ngIf="virtualColumns" class="k-width-container" role="presentation">
                            <div [style.width.px]="columnsContainer.unlockedWidth"></div>
                        </div>
                    </div>
                </div>
                <kendo-grid-list
                    [data]="$any(view)"
                    [rowHeight]="rowHeight"
                    [detailRowHeight]="detailRowHeight"
                    [total]="totalCount"
                    [take]="pageSize"
                    [groups]="group"
                    [groupable]="groupable"
                    [skip]="skip"
                    [trackBy]="trackBy"
                    [columns]="columnsContainer"
                    [selectable]="selectable"
                    [filterable]="filterable"
                    [detailTemplate]="detailTemplate"
                    [noRecordsTemplate]="noRecordsTemplate"
                    [size]="size"
                    (pageChange)="notifyPageChange('list', $event)"
                    [rowClass]="rowClass"
                    [rowSticky]="rowSticky"
                    [loading]="loading"
                    [isVirtual]="isVirtual"
                    [cellLoadingTemplate]="cellLoadingTemplate?.templateRef"
                    [loadingTemplate]="loadingTemplate?.templateRef"
                    [virtualColumns]="virtualColumns"
                    (scrollBottom)="notifyScrollBottom()"
                    (contentScroll)="contentScroll.emit($event)"
                    kendoDraggable
                    kendoGridSelectionMarquee
                    [enableDrag]="marqueeSelection"
                    [sort]="sort">
                </kendo-grid-list>
                <div
                    *ngIf="showFooter"
                    class="k-grid-footer"
                    [style.padding]="headerPadding">
                    <div
                        *ngIf="lockedLeafColumns.length"
                        class="k-grid-footer-locked"
                        [style.width.px]="lockedWidth">
                        <table
                            role="presentation"
                            class="k-grid-footer-table"
                            kendoGridResizableTable
                            [locked]="true"
                            [style.width.px]="lockedWidth"
                            kendoGridTable
                            [size]="size">
                            <colgroup kendoGridColGroup
                                [columns]="$any(lockedLeafColumns)"
                                [groups]="group"
                                [detailTemplate]="detailTemplate">
                            </colgroup>
                            <tfoot kendoGridFooter
                                [scrollable]="true"
                                [groups]="group"
                                [columns]="$any(lockedLeafColumns)"
                                [detailTemplate]="detailTemplate"
                                [logicalRowIndex]="ariaRowCount"
                                [totalColumns]="columnsContainer">
                            </tfoot>
                        </table>
                    </div>
                    <div #footer
                        class="k-grid-footer-wrap" data-scrollable
                        [kendoGridResizableContainer]="lockedLeafColumns.length > 0"
                        [lockedWidth]="lockedWidth + scrollbarWidth + 3">
                        <table
                            role="presentation"
                            class="k-grid-footer-table"
                            [style.width.px]="nonLockedWidth"
                            kendoGridTable
                            kendoGridResizableTable
                            [size]="size">
                            <colgroup kendoGridColGroup
                                [columns]="$any(headerLeafColumns)"
                                [groups]="isLocked ? [] : group"
                                [detailTemplate]="detailTemplate">
                            </colgroup>
                            <tfoot kendoGridFooter
                                [logicalRowIndex]="ariaRowCount"
                                [scrollable]="true"
                                [groups]="isLocked ? [] : group"
                                [columns]="$any(headerColumns)"
                                [lockedColumnsCount]="lockedLeafColumns.length"
                                [detailTemplate]="detailTemplate"
                                [totalColumns]="columnsContainer">
                            </tfoot>
                        </table>
                    </div>
                </div>
            </ng-container>
            <ng-container *ngIf="!isScrollable">
                <table
                    [style.table-layout]="resizable ? 'fixed' : null"
                    kendoGridTable
                    kendoGridResizableTable
                    role="presentation"
                    [size]="size">
                    <colgroup kendoGridColGroup
                        [columns]="$any(leafColumns)"
                        [groups]="group"
                        [sort]="sort"
                        [detailTemplate]="detailTemplate">
                    </colgroup>
                    <thead kendoGridHeader
                        *ngIf="!hideHeader"
                        role="rowgroup"
                        [resizable]="resizable"
                        [scrollable]="false"
                        [columns]="$any(visibleColumns)"
                        [totalColumnLevels]="totalColumnLevels"
                        [totalColumns]="columnsContainer"
                        [groups]="group"
                        [groupable]="showGroupPanel"
                        [reorderable]="reorderable"
                        [sort]="sort"
                        [sortable]="sortable"
                        [filter]="filter"
                        [filterable]="filterable"
                        [columnMenu]="columnMenuOptions"
                        [columnMenuTemplate]="columnMenuTemplate"
                        [detailTemplate]="detailTemplate"
                        [tabIndex]="navigation.tableEnabled ? '-1' : '0'">
                    </thead>
                    <tbody kendoGridTableBody
                        [isLoading]="loading"
                        [groups]="group"
                        [data]="$any(view)"
                        [skip]="skip"
                        [columns]="$any(leafColumns)"
                        [selectable]="selectable"
                        [filterable]="filterable"
                        [noRecordsTemplate]="noRecordsTemplate"
                        [detailTemplate]="detailTemplate"
                        [showGroupFooters]="showGroupFooters"
                        [trackBy]="trackBy"
                        [rowClass]="rowClass"
                        kendoDraggable
                        kendoGridSelectionMarquee
                        [enableDrag]="marqueeSelection">
                    </tbody>
                    <tfoot kendoGridFooter
                        *ngIf="showFooter"
                        [scrollable]="false"
                        [logicalRowIndex]="ariaRowCount"
                        [groups]="group"
                        [columns]="$any(leafColumns)"
                        [detailTemplate]="detailTemplate"
                        [totalColumns]="columnsContainer">
                    </tfoot>
                </table>
            </ng-container>
            <div [loadingTemplate]="loadingTemplate" *ngIf="loading" kendoGridLoading></div>
        </div>
        <kendo-grid-status-bar
            *ngIf="showStatusBar"
            [statusBarTemplate]="statusBarTemplate">
        </kendo-grid-status-bar>
        <kendo-pager
            *ngIf="showBottomPager"
            #bottomPager
            class="k-grid-pager"
            [navigable]="navigation.pagerEnabled"
            [pageSize]="pageSize"
            [total]="view.total"
            [skip]="skip"
            [size]="size"
            [responsive]="normalizedPageableSettings.responsive && !pagerTemplate"
            [buttonCount]="normalizedPageableSettings.buttonCount"
            [info]="normalizedPageableSettings.info"
            [pageSizeValues]="normalizedPageableSettings.pageSizes"
            [previousNext]="normalizedPageableSettings.previousNext"
            [type]="normalizedPageableSettings.type"
            (pageChange)="notifyPageChange('pager', $event)">
            <ng-template kendoPagerTemplate>
                <ng-container 
                    [ngTemplateOutlet]="pagerTemplate ? pagerTemplate?.templateRef : defaultPager"
                    [ngTemplateOutletContext]="bottomPager.templateContext"></ng-container>
            </ng-template>
            <kendo-pager-messages
                [ariaLabel]="messageFor('pagerLabel')"
                [firstPage]="messageFor('pagerFirstPage')"
                [inputLabel]="messageFor('pagerInputLabel')"
                [previousPage]="messageFor('pagerPreviousPage')"
                [nextPage]="messageFor('pagerNextPage')"
                [lastPage]="messageFor('pagerLastPage')"
                [selectPage]="messageFor('pagerSelectPage')"
                [page]="messageFor('pagerPage')"
                [itemsPerPage]="messageFor('pagerItemsPerPage')"
                [items]="messageFor('pagerItems')"
                [of]="messageFor('pagerOf')"
                [pageNumberInputTitle]="messageFor('pagerPageNumberInputTitle')">
            </kendo-pager-messages>
        </kendo-pager>
        <kendo-grid-toolbar
            class="k-grid-toolbar-bottom"
            *ngIf="showBottomToolbar"
            [size]="size"
            [navigable]="navigation.toolbarEnabled"
            [attr.aria-label]="messageFor('bottomToolbarLabel')"
            [attr.aria-controls]="ariaRootId"
            position="bottom">
        </kendo-grid-toolbar>

        <ng-template #defaultHint>
            <kendo-icon-wrapper
                [name]="getHintSettings('hintIcon')"
                [svgIcon]="getHintSettings('hintSVGIcon')"
                innerCssClass="k-drag-status">
            </kendo-icon-wrapper>
            {{hintText}}
        </ng-template>

        <ng-template #defaultPager>
            <div class="k-pager-numbers-wrap">
                <kendo-pager-prev-buttons [size]="size" *ngIf="normalizedPageableSettings.previousNext"></kendo-pager-prev-buttons>
                <kendo-pager-numeric-buttons
                    [size]="size"
                    *ngIf="normalizedPageableSettings.type === 'numeric' && normalizedPageableSettings.buttonCount > 0"
                    [buttonCount]="normalizedPageableSettings.buttonCount">
                </kendo-pager-numeric-buttons>
                <kendo-pager-input [size]="size" *ngIf="normalizedPageableSettings.type === 'input'"></kendo-pager-input>
                <kendo-pager-next-buttons [size]="size" *ngIf="normalizedPageableSettings.previousNext"></kendo-pager-next-buttons>
            </div>
            <kendo-pager-page-sizes *ngIf="normalizedPageableSettings.pageSizes"
                [size]="size"
                [pageSizes]="normalizedPageableSettings.pageSizes">
            </kendo-pager-page-sizes>
            <kendo-pager-info *ngIf="normalizedPageableSettings.info">
            </kendo-pager-info>
        </ng-template>
        <div kendoWatermarkOverlay *ngIf="showLicenseWatermark"></div>
    `, isInline: true, dependencies: [{ kind: "directive", type: LocalizedMessagesDirective, selector: "[kendoGridLocalizedMessages]" }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: GridToolbarComponent, selector: "kendo-grid-toolbar", inputs: ["position", "size", "navigable"] }, { kind: "component", type: GroupPanelComponent, selector: "kendo-grid-group-panel", inputs: ["text", "navigable", "groups"], outputs: ["change"] }, { kind: "directive", type: TableDirective, selector: "[kendoGridResizableTable]", inputs: ["locked", "virtualColumns"] }, { kind: "directive", type: GridTableDirective, selector: "[kendoGridTable]", inputs: ["size"] }, { kind: "component", type: ColGroupComponent, selector: "[kendoGridColGroup]", inputs: ["columns", "groups", "detailTemplate", "sort"] }, { kind: "component", type: HeaderComponent, selector: "[kendoGridHeader]", inputs: ["totalColumnLevels", "columns", "groups", "detailTemplate", "scrollable", "filterable", "sort", "filter", "sortable", "groupable", "lockedColumnsCount", "resizable", "reorderable", "columnMenu", "columnMenuTemplate", "totalColumnsCount", "totalColumns", "tabIndex", "size"] }, { kind: "directive", type: ResizableContainerDirective, selector: "[kendoGridResizableContainer]", inputs: ["lockedWidth", "kendoGridResizableContainer"] }, { kind: "component", type: ListComponent, selector: "kendo-grid-list", inputs: ["data", "groups", "total", "rowHeight", "stickyRowHeight", "detailRowHeight", "take", "skip", "columns", "detailTemplate", "noRecordsTemplate", "selectable", "groupable", "filterable", "rowClass", "rowSticky", "loading", "trackBy", "virtualColumns", "isVirtual", "cellLoadingTemplate", "loadingTemplate", "sort", "size"], outputs: ["contentScroll", "pageChange", "scrollBottom"] }, { kind: "directive", type: DragTargetContainerDirective, selector: "[kendoDragTargetContainer]", inputs: ["hint", "dragTargetFilter", "dragHandle", "dragDelay", "threshold", "dragTargetId", "dragData", "dragDisabled", "mode", "cursorStyle", "hintContext"], outputs: ["onDragReady", "onPress", "onDragStart", "onDrag", "onRelease", "onDragEnd"], exportAs: ["kendoDragTargetContainer"] }, { kind: "directive", type: DropTargetContainerDirective, selector: "[kendoDropTargetContainer]", inputs: ["dropTargetFilter", "dropDisabled"], outputs: ["onDragEnter", "onDragOver", "onDragLeave", "onDrop"], exportAs: ["kendoDropTargetContainer"] }, { kind: "directive", type: DraggableDirective, selector: "[kendoDraggable]", inputs: ["enableDrag"], outputs: ["kendoPress", "kendoDrag", "kendoRelease"] }, { kind: "directive", type: GridMarqueeDirective, selector: "[kendoGridSelectionMarquee]" }, { kind: "component", type: FooterComponent, selector: "[kendoGridFooter]", inputs: ["columns", "groups", "detailTemplate", "scrollable", "lockedColumnsCount", "logicalRowIndex", "totalColumns"] }, { kind: "component", type: TableBodyComponent, selector: "[kendoGridTableBody]", inputs: ["columns", "allColumns", "groups", "detailTemplate", "noRecordsTemplate", "data", "skip", "selectable", "filterable", "noRecordsText", "isLocked", "isLoading", "isVirtual", "cellLoadingTemplate", "skipGroupDecoration", "showGroupFooters", "lockedColumnsCount", "totalColumnsCount", "virtualColumns", "trackBy", "rowSticky", "totalColumns", "rowClass"] }, { kind: "component", type: LoadingComponent, selector: "[kendoGridLoading]", inputs: ["loadingTemplate"] }, { kind: "component", type: StatusBarComponent, selector: "kendo-grid-status-bar", inputs: ["statusBarTemplate"] }, { kind: "component", type: IconWrapperComponent, selector: "kendo-icon-wrapper", inputs: ["name", "svgIcon", "innerCssClass", "customFontClass", "size"], exportAs: ["kendoIconWrapper"] }, { kind: "component", type: WatermarkOverlayComponent, selector: "div[kendoWatermarkOverlay]" }, { kind: "component", type: i25.CustomMessagesComponent, selector: "kendo-datapager-messages, kendo-pager-messages" }, { kind: "component", type: i25.PagerInfoComponent, selector: "kendo-datapager-info, kendo-pager-info" }, { kind: "component", type: i25.PagerInputComponent, selector: "kendo-datapager-input, kendo-pager-input", inputs: ["size"] }, { kind: "component", type: i25.PagerNextButtonsComponent, selector: "kendo-datapager-next-buttons, kendo-pager-next-buttons", inputs: ["size"] }, { kind: "component", type: i25.PagerNumericButtonsComponent, selector: "kendo-datapager-numeric-buttons, kendo-pager-numeric-buttons", inputs: ["buttonCount", "size"] }, { kind: "component", type: i25.PagerPageSizesComponent, selector: "kendo-datapager-page-sizes, kendo-pager-page-sizes", inputs: ["pageSizes", "size"] }, { kind: "component", type: i25.PagerPrevButtonsComponent, selector: "kendo-datapager-prev-buttons, kendo-pager-prev-buttons", inputs: ["size"] }, { kind: "directive", type: i25.PagerTemplateDirective, selector: "[kendoDataPagerTemplate], [kendoPagerTemplate]" }, { kind: "component", type: i25.PagerComponent, selector: "kendo-datapager, kendo-pager", inputs: ["externalTemplate", "total", "skip", "pageSize", "buttonCount", "info", "type", "pageSizeValues", "previousNext", "navigable", "size", "responsive"], outputs: ["pageChange", "pageSizeChange"], exportAs: ["kendoDataPager", "kendoPager"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], encapsulation: i0.ViewEncapsulation.None });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: GridComponent, decorators: [{
            type: Component,
            args: [{
                    encapsulation: ViewEncapsulation.None,
                    exportAs: 'kendoGrid',
                    providers: [
                        BrowserSupportService,
                        LocalizationService,
                        ColumnInfoService,
                        SelectionService,
                        CellSelectionService,
                        DetailsService,
                        GroupsService,
                        GroupInfoService,
                        ChangeNotificationService,
                        EditService,
                        PDFService,
                        SuspendService,
                        {
                            provide: CELL_CONTEXT,
                            useValue: EMPTY_CELL_CONTEXT
                        },
                        {
                            provide: L10N_PREFIX,
                            useValue: 'kendo.grid'
                        },
                        FilterService,
                        ResponsiveService,
                        PagerContextService,
                        PagerNavigationService,
                        ExcelService,
                        ScrollSyncService,
                        ResizeService,
                        LocalDataChangesService,
                        DomEventsService,
                        ColumnResizingService,
                        SinglePopupService,
                        DragAndDropService,
                        DragHintService,
                        DropCueService,
                        ColumnReorderService,
                        NavigationService,
                        FocusRoot,
                        IdService,
                        CellSelectionAggregateService,
                        ScrollRequestService,
                        SortService,
                        ContextService,
                        SizingOptionsService,
                        RowReorderService,
                        ClipboardService,
                        RowspanService
                    ],
                    selector: 'kendo-grid',
                    template: `
        <ng-container kendoGridLocalizedMessages
            i18n-groupPanelEmpty="kendo.grid.groupPanelEmpty|The label visible in the Grid group panel when it is empty"
            groupPanelEmpty="Drag a column header and drop it here to group by that column"

            i18n-noRecords="kendo.grid.noRecords|The label visible in the Grid when there are no records"
            noRecords="No records available."

            i18n-pagerLabel="kendo.grid.pagerLabel|The label for the Grid pager"
            pagerLabel="{{ 'Page navigation, page {currentPage} of {totalPages}' }}"

            i18n-pagerFirstPage="kendo.grid.pagerFirstPage|The label for the first page button in Grid pager"
            pagerFirstPage="Go to the first page"

            i18n-pagerPreviousPage="kendo.grid.pagerPreviousPage|The label for the previous page button in Grid pager"
            pagerPreviousPage="Go to the previous page"

            i18n-pagerNextPage="kendo.grid.pagerNextPage|The label for the next page button in Grid pager"
            pagerNextPage="Go to the next page"

            i18n-pagerLastPage="kendo.grid.pagerLastPage|The label for the last page button in Grid pager"
            pagerLastPage="Go to the last page"

            i18n-pagerPage="kendo.grid.pagerPage|The label before the current page number in the Grid pager"
            pagerPage="Page"

            i18n-pagerOf="kendo.grid.pagerOf|The label before the total pages number in the Grid pager"
            pagerOf="of"

            i18n-pagerItems="kendo.grid.pagerItems|The label after the total pages number in the Grid pager"
            pagerItems="items"

            i18n-pagerPageNumberInputTitle="kendo.grid.pagerPageNumberInputTitle|The label for the pager input in the Grid pager"
            pagerPageNumberInputTitle="Page Number"

            i18n-pagerItemsPerPage="kendo.grid.pagerItemsPerPage|The label for the page size chooser in the Grid pager"
            pagerItemsPerPage="items per page"

            i18n-pagerInputLabel="kendo.grid.pagerInputLabel|The text of the aria-label attribute applied to the input element for entering the page number"
            pagerInputLabel="Type a page number"

            i18n-filter="kendo.grid.filter|The label of the filter cell or icon"
            filter="Filter"

            i18n-filterInputLabel="kendo.grid.filterInputLabel|The label of the filter row and menu inputs"
            filterInputLabel="{{ '{columnName} Filter' }}"

            i18n-filterMenuTitle="kendo.grid.filterMenuTitle|The title of the filter menu icon"
            filterMenuTitle="{{ '{columnName} Filter Menu' }}"

            i18n-filterMenuOperatorsDropDownLabel="kendo.grid.filterMenuOperatorsDropDownLabel|The label of the filter menu operators dropdown"
            filterMenuOperatorsDropDownLabel="{{ '{columnName} Filter Operators' }}"
            
            i18n-filterCellOperatorLabel="kendo.grid.filterCellOperatorLabel|The label of the filter cell operators dropdown"
            filterCellOperatorLabel="{{ 'Filter cell operators for {columnName}' }}"

            i18n-booleanFilterCellLabel="kendo.grid.booleanFilterCellLabel|The label of the boolean filter cell dropdown"
            booleanFilterCellLabel="{{ 'Boolean filter cell for {columnName}' }}"

            i18n-filterMenuLogicDropDownLabel="kendo.grid.filterMenuLogicDropDownLabel|The label of the filter menu logic dropdown"
            filterMenuLogicDropDownLabel="{{ '{columnName} Filter Logic' }}"

            i18n-filterEqOperator="kendo.grid.filterEqOperator|The text of the equal filter operator"
            filterEqOperator="Is equal to"

            i18n-filterNotEqOperator="kendo.grid.filterNotEqOperator|The text of the not equal filter operator"
            filterNotEqOperator="Is not equal to"

            i18n-filterIsNullOperator="kendo.grid.filterIsNullOperator|The text of the is null filter operator"
            filterIsNullOperator="Is null"

            i18n-filterIsNotNullOperator="kendo.grid.filterIsNotNullOperator|The text of the is not null filter operator"
            filterIsNotNullOperator="Is not null"

            i18n-filterIsEmptyOperator="kendo.grid.filterIsEmptyOperator|The text of the is empty filter operator"
            filterIsEmptyOperator="Is empty"

            i18n-filterIsNotEmptyOperator="kendo.grid.filterIsNotEmptyOperator|The text of the is not empty filter operator"
            filterIsNotEmptyOperator="Is not empty"

            i18n-filterStartsWithOperator="kendo.grid.filterStartsWithOperator|The text of the starts with filter operator"
            filterStartsWithOperator="Starts with"

            i18n-filterContainsOperator="kendo.grid.filterContainsOperator|The text of the contains filter operator"
            filterContainsOperator="Contains"

            i18n-filterNotContainsOperator="kendo.grid.filterNotContainsOperator|The text of the does not contain filter operator"
            filterNotContainsOperator="Does not contain"

            i18n-filterEndsWithOperator="kendo.grid.filterEndsWithOperator|The text of the ends with filter operator"
            filterEndsWithOperator="Ends with"

            i18n-filterGteOperator="kendo.grid.filterGteOperator|The text of the greater than or equal filter operator"
            filterGteOperator="Is greater than or equal to"

            i18n-filterGtOperator="kendo.grid.filterGtOperator|The text of the greater than filter operator"
            filterGtOperator="Is greater than"

            i18n-filterLteOperator="kendo.grid.filterLteOperator|The text of the less than or equal filter operator"
            filterLteOperator="Is less than or equal to"

            i18n-filterLtOperator="kendo.grid.filterLtOperator|The text of the less than filter operator"
            filterLtOperator="Is less than"

            i18n-filterIsTrue="kendo.grid.filterIsTrue|The text of the IsTrue boolean filter option"
            filterIsTrue="Is True"

            i18n-filterIsFalse="kendo.grid.filterIsFalse|The text of the IsFalse boolean filter option"
            filterIsFalse="Is False"

            i18n-filterBooleanAll="kendo.grid.filterBooleanAll|The text of the (All) boolean filter option"
            filterBooleanAll="(All)"

            i18n-filterAfterOrEqualOperator="kendo.grid.filterAfterOrEqualOperator|The text of the after or equal date filter operator"
            filterAfterOrEqualOperator="Is after or equal to"

            i18n-filterAfterOperator="kendo.grid.filterAfterOperator|The text of the after date filter operator"
            filterAfterOperator="Is after"

            i18n-filterBeforeOperator="kendo.grid.filterBeforeOperator|The text of the before date filter operator"
            filterBeforeOperator="Is before"

            i18n-filterBeforeOrEqualOperator="kendo.grid.filterBeforeOrEqualOperator|The text of the before or equal date filter operator"
            filterBeforeOrEqualOperator="Is before or equal to"

            i18n-filterFilterButton="kendo.grid.filterFilterButton|The text of the filter button"
            filterFilterButton="Filter"

            i18n-filterClearButton="kendo.grid.filterClearButton|The text of the clear filter button"
            filterClearButton="Clear"

            i18n-filterAndLogic="kendo.grid.filterAndLogic|The text of the And filter logic"
            filterAndLogic="And"

            i18n-filterOrLogic="kendo.grid.filterOrLogic|The text of the Or filter logic"
            filterOrLogic="Or"

            i18n-loading="kendo.grid.loading|The loading text"
            loading="Loading"

            i18n-gridLabel="kendo.grid.gridLabel|The Grid aria-label"
            gridLabel="Data table"

            i18n-columnMenu="kendo.grid.columnMenu|The title of the column menu icon"
            columnMenu="{{ '{columnName} Column Menu' }}"

            i18n-columns="kendo.grid.columns|The text shown in the column menu for the columns item"
            columns="Columns"

            i18n-lock="kendo.grid.lock|The text shown in the column menu for the lock item"
            lock="Lock"

            i18n-unlock="kendo.grid.unlock|The text shown in the column menu for the unlock item"
            unlock="Unlock"

            i18n-setColumnPosition="kendo.grid.setColumnPosition|The text shown in the column menu for the set column position item"
            setColumnPosition="Set Column Position"

            i18n-stick="kendo.grid.stick|The text shown in the column menu for the stick item"
            stick="Stick"

            i18n-unstick="kendo.grid.unstick|The text shown in the column menu for the unstick item"
            unstick="Unstick"

            i18n-sortable="kendo.grid.sortable|The label of the sort icon"
            sortable="Sortable"

            i18n-sortAscending="kendo.grid.sortAscending|The text shown in the column menu for the sort ascending item"
            sortAscending="Sort Ascending"

            i18n-sortDescending="kendo.grid.sortDescending|The text shown in the column menu for the sort descending item"
            sortDescending="Sort Descending"

            i18n-autosizeAllColumns="kendo.grid.autosizeAllColumns|The text shown in the column menu for the autosize all columns item"
            autosizeAllColumns="Autosize All Columns"

            i18n-autosizeThisColumn="kendo.grid.autosizeThisColumn|The text shown in the column menu for the autosize this column item"
            autosizeThisColumn="Autosize This Column"

            i18n-sortedDefault="kendo.grid.sortedDefault|The status announcement when a column is no longer sorted"
            sortedDefault="Not Sorted"

            i18n-sortedAscending="kendo.grid.sortedAscending|The title of the Group Chip indicating the ascending sorting order of the groups"
            sortedAscending="Sorted Ascending"
            
            i18n-sortedDescending="kendo.grid.sortedDescending|The title of the Group Chip indicating the descending sorting order of the groups"
            sortedDescending="Sorted Descending"

            i18n-columnsApply="kendo.grid.columnsApply|The text shown in the column menu or column chooser for the columns apply button"
            columnsApply="Apply"

            i18n-columnsReset="kendo.grid.columnsReset|The text shown in the column menu or column chooser for the columns reset button"
            columnsReset="Reset"

            i18n-detailExpand="kendo.grid.detailExpand|The title of the expand icon of detail rows."
            detailExpand="Expand Details"

            i18n-detailCollapse="kendo.grid.detailCollapse|The title of the collapse icon of detail rows."
            detailCollapse="Collapse Details"

            i18n-filterDateToday="kendo.grid.filterDateToday|The text of the Today button of the Date filter."
            filterDateToday="TODAY"

            i18n-filterDateToggle="kendo.grid.filterDateToggle|The title of the Toggle button of the Date filter."
            filterDateToggle="Toggle Calendar"

            i18n-filterNumericDecrement="kendo.grid.filterNumericDecrement|The title of the Decrement button of the Numeric filter."
            filterNumericDecrement="Decrement"

            i18n-filterNumericIncrement="kendo.grid.filterNumericIncrement|The title of the Increment button of the Numeric filter."
            filterNumericIncrement="Increment"

            i18n-selectionCheckboxLabel="kendo.grid.selectionCheckboxLabel|The labels of the checkbox column checkboxes."
            selectionCheckboxLabel="Select Row"

            i18n-selectAllCheckboxLabel="kendo.grid.selectAllCheckboxLabel|The label of the checkbox column select all checkbox."
            selectAllCheckboxLabel="Select All Rows"

            i18n-groupCollapse="kendo.grid.groupCollapse|The text of the title and aria-label attributes applied to the collapse icon of group rows."
            groupCollapse="Collapse Group"

            i18n-groupExpand="kendo.grid.groupExpand|The text of the title and aria-label attributes applied to the expand icon of group rows."
            groupExpand="Expand Group"

            i18n-pagerSelectPage="kendo.grid.pagerSelectPage|The text of the title and aria-label attributes applied to the page chooser in the Grid Pager"
            pagerSelectPage="Select page"

            i18n-topToolbarLabel="kendo.grid.topToolbarLabel|The label for the Grid top toolbar"
            topToolbarLabel="Top toolbar"

            i18n-bottomToolbarLabel="kendo.grid.bottomToolbarLabel|The label for the Grid bottom toolbar"
            bottomToolbarLabel="Bottom toolbar"

            i18n-groupPanelLabel="kendo.grid.groupPanelLabel|The label for the Grid group panel toolbar"
            groupPanelLabel="Group panel"

            i18n-dragRowHandleLabel="kendo.grid.dragRowHandleLabel|The label for the Grid drag row handle"
            dragRowHandleLabel="Drag row"

            i18n-columnMenuFilterTabTitle="kendo.grid.columnMenuFilterTabTitle|The title for the column menu Filter tab"
            columnMenuFilterTabTitle="Filter"

            i18n-columnMenuGeneralTabTitle="kendo.grid.columnMenuGeneralTabTitle|The title for the column menu General tab"
            columnMenuGeneralTabTitle="General"

            i18n-columnMenuColumnsTabTitle="kendo.grid.columnMenuColumnsTabTitle|The title for the column menu Columns tab"
            columnMenuColumnsTabTitle="Columns"

            i18n-groupChipMenuPrevious="kendo.grid.groupChipMenuPrevious|The text for the Group pane Chip Menu Move as previous item"
            groupChipMenuPrevious="Move as previous"

            i18n-groupChipMenuNext="kendo.grid.groupChipMenuNext|The text for the Group pane Chip Menu Move as next item"
            groupChipMenuNext="Move as next"
        >
        </ng-container>
        <kendo-grid-toolbar
            *ngIf="showTopToolbar"
            [size]="size"
            [attr.aria-label]="messageFor('topToolbarLabel')"
            [navigable]="navigation.toolbarEnabled"
            [attr.aria-controls]="ariaRootId"
            position="top"></kendo-grid-toolbar>
        <ng-content select="kendo-toolbar"></ng-content>
        <kendo-pager
            *ngIf="showTopPager"
            #topPager
            [navigable]="navigation.pagerEnabled"
            class="k-grid-pager k-grid-pager-top"
            [pageSize]="pageSize"
            [total]="view.total"
            [skip]="skip"
            [size]="size"
            [responsive]="normalizedPageableSettings.responsive && !pagerTemplate"
            [buttonCount]="normalizedPageableSettings.buttonCount"
            [info]="normalizedPageableSettings.info"
            [pageSizeValues]="normalizedPageableSettings.pageSizes"
            [previousNext]="normalizedPageableSettings.previousNext"
            [type]="normalizedPageableSettings.type"
            (pageChange)="notifyPageChange('pager', $event)">
            <ng-template kendoPagerTemplate>
                <ng-container
                    [ngTemplateOutlet]="pagerTemplate ? pagerTemplate?.templateRef : defaultPager"
                    [ngTemplateOutletContext]="topPager.templateContext"></ng-container>
            </ng-template>
            <kendo-pager-messages
                [ariaLabel]="messageFor('pagerLabel')"
                [firstPage]="messageFor('pagerFirstPage')"
                [inputLabel]="messageFor('pagerInputLabel')"
                [previousPage]="messageFor('pagerPreviousPage')"
                [nextPage]="messageFor('pagerNextPage')"
                [lastPage]="messageFor('pagerLastPage')"
                [selectPage]="messageFor('pagerSelectPage')"
                [page]="messageFor('pagerPage')"
                [itemsPerPage]="messageFor('pagerItemsPerPage')"
                [items]="messageFor('pagerItems')"
                [of]="messageFor('pagerOf')"
                [pageNumberInputTitle]="messageFor('pagerPageNumberInputTitle')">
            </kendo-pager-messages>
        </kendo-pager>
        <kendo-grid-group-panel
            *ngIf="showGroupPanel"
            [navigable]="navigation.toolbarEnabled"
            [text]="groupableEmptyText"
            [groups]="group"
            role="toolbar"
            [attr.aria-label]="messageFor('groupPanelLabel')"
            [attr.aria-controls]="ariaRootId"
            (change)="groupChange.emit($event)">
        </kendo-grid-group-panel>
        <div #ariaRoot
            class="k-grid-aria-root"
            role="grid"
            kendoDragTargetContainer
            kendoDropTargetContainer
            mode="manual"
            [dragDisabled]="!rowReorderable"
            [dropDisabled]="!rowReorderable"
            [dragTargetFilter]="getDefaultSelectors('dragTarget')"
            [dropTargetFilter]="getDefaultSelectors('dropTarget')"
            [dragHandle]="getDefaultSelectors('handle')"
            [hint]="{hintTemplate: customHintTemplate || defaultHint}"
            [hintContext]="hintContext"
            (onPress)="handleReorderEvents($event, 'press')"
            (onDragStart)="handleReorderEvents($event, 'dragStart')"
            (onDrag)="handleReorderEvents($event, 'drag')"
            (onDragEnter)="handleReorderEvents($event, 'dragEnter')"
            (onDragLeave)="handleReorderEvents($event, 'dragLeave')"
            (onDragEnd)="handleReorderEvents($event, 'dragEnd')"
            (onDrop)="handleReorderEvents($event, 'drop')"
            [dragData]="gridData"
            [id]="ariaRootId"
            [attr.aria-label]="ariaLabel"
            [attr.aria-rowcount]="ariaRowCount"
            [attr.aria-colcount]="ariaColCount">
            <ng-container *ngIf="isScrollable">
                <div *ngIf="!hideHeader"
                    class="k-grid-header"
                    [class.k-grid-draggable-header]="groupable || reorderable"
                    role="presentation"
                    [style.padding]="headerPadding">
                    <div *ngIf="isLocked"
                        #lockedHeader
                        role="presentation"
                        class="k-grid-header-locked"
                        [style.width.px]="lockedWidth">
                        <table
                            kendoGridResizableTable
                            [locked]="true"
                            role="presentation"
                            class="k-grid-header-table"
                            [style.width.px]="lockedWidth"
                            kendoGridTable
                            [size]="size">
                            <colgroup kendoGridColGroup
                                [columns]="$any(lockedLeafColumns)"
                                [groups]="group"
                                [detailTemplate]="detailTemplate">
                            </colgroup>
                            <thead kendoGridHeader
                                role="rowgroup"
                                [resizable]="resizable"
                                [scrollable]="true"
                                [columns]="$any(lockedColumns)"
                                [totalColumnLevels]="totalColumnLevels"
                                [sort]="sort"
                                [groups]="group"
                                [filter]="filter"
                                [filterable]="filterable"
                                [groupable]="showGroupPanel"
                                [reorderable]="reorderable"
                                [sortable]="sortable"
                                [columnMenu]="columnMenuOptions"
                                [columnMenuTemplate]="columnMenuTemplate"
                                [totalColumnsCount]="leafColumns.length"
                                [totalColumns]="columnsContainer"
                                [detailTemplate]="detailTemplate"
                                [tabIndex]="navigation.tableEnabled ? '-1' : '0'">
                            </thead>
                        </table>
                    </div>
                    <div #header class="k-grid-header-wrap" role="presentation" data-scrollable
                        [kendoGridResizableContainer]="lockedLeafColumns.length > 0"
                        [lockedWidth]="lockedWidth + scrollbarWidth + 2">
                        <table
                            role="presentation"
                            class="k-grid-header-table"
                            [style.width.px]="nonLockedWidth"
                            kendoGridResizableTable
                            [virtualColumns]="virtualColumns"
                            kendoGridTable
                            [size]="size">
                            <colgroup kendoGridColGroup
                                [columns]="headerLeafColumns"
                                [groups]="isLocked ? [] : group"
                                [detailTemplate]="detailTemplate">
                            </colgroup>
                            <thead kendoGridHeader
                                [resizable]="resizable"
                                role="rowgroup"
                                [scrollable]="true"
                                [columns]="headerColumns"
                                [totalColumnLevels]="totalColumnLevels"
                                [sort]="sort"
                                [filter]="filter"
                                [filterable]="filterable"
                                [groupable]="showGroupPanel"
                                [reorderable]="reorderable"
                                [groups]="isLocked ? [] : group"
                                [sortable]="sortable"
                                [columnMenu]="columnMenuOptions"
                                [columnMenuTemplate]="columnMenuTemplate"
                                [lockedColumnsCount]="lockedLeafColumns.length"
                                [totalColumnsCount]="leafColumns.length"
                                [totalColumns]="columnsContainer"
                                [detailTemplate]="detailTemplate"
                                [tabIndex]="navigation.tableEnabled ? '-1' : '0'">
                            </thead>
                        </table>
                        <div *ngIf="virtualColumns" class="k-width-container" role="presentation">
                            <div [style.width.px]="columnsContainer.unlockedWidth"></div>
                        </div>
                    </div>
                </div>
                <kendo-grid-list
                    [data]="$any(view)"
                    [rowHeight]="rowHeight"
                    [detailRowHeight]="detailRowHeight"
                    [total]="totalCount"
                    [take]="pageSize"
                    [groups]="group"
                    [groupable]="groupable"
                    [skip]="skip"
                    [trackBy]="trackBy"
                    [columns]="columnsContainer"
                    [selectable]="selectable"
                    [filterable]="filterable"
                    [detailTemplate]="detailTemplate"
                    [noRecordsTemplate]="noRecordsTemplate"
                    [size]="size"
                    (pageChange)="notifyPageChange('list', $event)"
                    [rowClass]="rowClass"
                    [rowSticky]="rowSticky"
                    [loading]="loading"
                    [isVirtual]="isVirtual"
                    [cellLoadingTemplate]="cellLoadingTemplate?.templateRef"
                    [loadingTemplate]="loadingTemplate?.templateRef"
                    [virtualColumns]="virtualColumns"
                    (scrollBottom)="notifyScrollBottom()"
                    (contentScroll)="contentScroll.emit($event)"
                    kendoDraggable
                    kendoGridSelectionMarquee
                    [enableDrag]="marqueeSelection"
                    [sort]="sort">
                </kendo-grid-list>
                <div
                    *ngIf="showFooter"
                    class="k-grid-footer"
                    [style.padding]="headerPadding">
                    <div
                        *ngIf="lockedLeafColumns.length"
                        class="k-grid-footer-locked"
                        [style.width.px]="lockedWidth">
                        <table
                            role="presentation"
                            class="k-grid-footer-table"
                            kendoGridResizableTable
                            [locked]="true"
                            [style.width.px]="lockedWidth"
                            kendoGridTable
                            [size]="size">
                            <colgroup kendoGridColGroup
                                [columns]="$any(lockedLeafColumns)"
                                [groups]="group"
                                [detailTemplate]="detailTemplate">
                            </colgroup>
                            <tfoot kendoGridFooter
                                [scrollable]="true"
                                [groups]="group"
                                [columns]="$any(lockedLeafColumns)"
                                [detailTemplate]="detailTemplate"
                                [logicalRowIndex]="ariaRowCount"
                                [totalColumns]="columnsContainer">
                            </tfoot>
                        </table>
                    </div>
                    <div #footer
                        class="k-grid-footer-wrap" data-scrollable
                        [kendoGridResizableContainer]="lockedLeafColumns.length > 0"
                        [lockedWidth]="lockedWidth + scrollbarWidth + 3">
                        <table
                            role="presentation"
                            class="k-grid-footer-table"
                            [style.width.px]="nonLockedWidth"
                            kendoGridTable
                            kendoGridResizableTable
                            [size]="size">
                            <colgroup kendoGridColGroup
                                [columns]="$any(headerLeafColumns)"
                                [groups]="isLocked ? [] : group"
                                [detailTemplate]="detailTemplate">
                            </colgroup>
                            <tfoot kendoGridFooter
                                [logicalRowIndex]="ariaRowCount"
                                [scrollable]="true"
                                [groups]="isLocked ? [] : group"
                                [columns]="$any(headerColumns)"
                                [lockedColumnsCount]="lockedLeafColumns.length"
                                [detailTemplate]="detailTemplate"
                                [totalColumns]="columnsContainer">
                            </tfoot>
                        </table>
                    </div>
                </div>
            </ng-container>
            <ng-container *ngIf="!isScrollable">
                <table
                    [style.table-layout]="resizable ? 'fixed' : null"
                    kendoGridTable
                    kendoGridResizableTable
                    role="presentation"
                    [size]="size">
                    <colgroup kendoGridColGroup
                        [columns]="$any(leafColumns)"
                        [groups]="group"
                        [sort]="sort"
                        [detailTemplate]="detailTemplate">
                    </colgroup>
                    <thead kendoGridHeader
                        *ngIf="!hideHeader"
                        role="rowgroup"
                        [resizable]="resizable"
                        [scrollable]="false"
                        [columns]="$any(visibleColumns)"
                        [totalColumnLevels]="totalColumnLevels"
                        [totalColumns]="columnsContainer"
                        [groups]="group"
                        [groupable]="showGroupPanel"
                        [reorderable]="reorderable"
                        [sort]="sort"
                        [sortable]="sortable"
                        [filter]="filter"
                        [filterable]="filterable"
                        [columnMenu]="columnMenuOptions"
                        [columnMenuTemplate]="columnMenuTemplate"
                        [detailTemplate]="detailTemplate"
                        [tabIndex]="navigation.tableEnabled ? '-1' : '0'">
                    </thead>
                    <tbody kendoGridTableBody
                        [isLoading]="loading"
                        [groups]="group"
                        [data]="$any(view)"
                        [skip]="skip"
                        [columns]="$any(leafColumns)"
                        [selectable]="selectable"
                        [filterable]="filterable"
                        [noRecordsTemplate]="noRecordsTemplate"
                        [detailTemplate]="detailTemplate"
                        [showGroupFooters]="showGroupFooters"
                        [trackBy]="trackBy"
                        [rowClass]="rowClass"
                        kendoDraggable
                        kendoGridSelectionMarquee
                        [enableDrag]="marqueeSelection">
                    </tbody>
                    <tfoot kendoGridFooter
                        *ngIf="showFooter"
                        [scrollable]="false"
                        [logicalRowIndex]="ariaRowCount"
                        [groups]="group"
                        [columns]="$any(leafColumns)"
                        [detailTemplate]="detailTemplate"
                        [totalColumns]="columnsContainer">
                    </tfoot>
                </table>
            </ng-container>
            <div [loadingTemplate]="loadingTemplate" *ngIf="loading" kendoGridLoading></div>
        </div>
        <kendo-grid-status-bar
            *ngIf="showStatusBar"
            [statusBarTemplate]="statusBarTemplate">
        </kendo-grid-status-bar>
        <kendo-pager
            *ngIf="showBottomPager"
            #bottomPager
            class="k-grid-pager"
            [navigable]="navigation.pagerEnabled"
            [pageSize]="pageSize"
            [total]="view.total"
            [skip]="skip"
            [size]="size"
            [responsive]="normalizedPageableSettings.responsive && !pagerTemplate"
            [buttonCount]="normalizedPageableSettings.buttonCount"
            [info]="normalizedPageableSettings.info"
            [pageSizeValues]="normalizedPageableSettings.pageSizes"
            [previousNext]="normalizedPageableSettings.previousNext"
            [type]="normalizedPageableSettings.type"
            (pageChange)="notifyPageChange('pager', $event)">
            <ng-template kendoPagerTemplate>
                <ng-container 
                    [ngTemplateOutlet]="pagerTemplate ? pagerTemplate?.templateRef : defaultPager"
                    [ngTemplateOutletContext]="bottomPager.templateContext"></ng-container>
            </ng-template>
            <kendo-pager-messages
                [ariaLabel]="messageFor('pagerLabel')"
                [firstPage]="messageFor('pagerFirstPage')"
                [inputLabel]="messageFor('pagerInputLabel')"
                [previousPage]="messageFor('pagerPreviousPage')"
                [nextPage]="messageFor('pagerNextPage')"
                [lastPage]="messageFor('pagerLastPage')"
                [selectPage]="messageFor('pagerSelectPage')"
                [page]="messageFor('pagerPage')"
                [itemsPerPage]="messageFor('pagerItemsPerPage')"
                [items]="messageFor('pagerItems')"
                [of]="messageFor('pagerOf')"
                [pageNumberInputTitle]="messageFor('pagerPageNumberInputTitle')">
            </kendo-pager-messages>
        </kendo-pager>
        <kendo-grid-toolbar
            class="k-grid-toolbar-bottom"
            *ngIf="showBottomToolbar"
            [size]="size"
            [navigable]="navigation.toolbarEnabled"
            [attr.aria-label]="messageFor('bottomToolbarLabel')"
            [attr.aria-controls]="ariaRootId"
            position="bottom">
        </kendo-grid-toolbar>

        <ng-template #defaultHint>
            <kendo-icon-wrapper
                [name]="getHintSettings('hintIcon')"
                [svgIcon]="getHintSettings('hintSVGIcon')"
                innerCssClass="k-drag-status">
            </kendo-icon-wrapper>
            {{hintText}}
        </ng-template>

        <ng-template #defaultPager>
            <div class="k-pager-numbers-wrap">
                <kendo-pager-prev-buttons [size]="size" *ngIf="normalizedPageableSettings.previousNext"></kendo-pager-prev-buttons>
                <kendo-pager-numeric-buttons
                    [size]="size"
                    *ngIf="normalizedPageableSettings.type === 'numeric' && normalizedPageableSettings.buttonCount > 0"
                    [buttonCount]="normalizedPageableSettings.buttonCount">
                </kendo-pager-numeric-buttons>
                <kendo-pager-input [size]="size" *ngIf="normalizedPageableSettings.type === 'input'"></kendo-pager-input>
                <kendo-pager-next-buttons [size]="size" *ngIf="normalizedPageableSettings.previousNext"></kendo-pager-next-buttons>
            </div>
            <kendo-pager-page-sizes *ngIf="normalizedPageableSettings.pageSizes"
                [size]="size"
                [pageSizes]="normalizedPageableSettings.pageSizes">
            </kendo-pager-page-sizes>
            <kendo-pager-info *ngIf="normalizedPageableSettings.info">
            </kendo-pager-info>
        </ng-template>
        <div kendoWatermarkOverlay *ngIf="showLicenseWatermark"></div>
    `,
                    standalone: true,
                    imports: [
                        LocalizedMessagesDirective, NgIf, GridToolbarComponent, GroupPanelComponent,
                        TableDirective, GridTableDirective, ColGroupComponent, HeaderComponent, ResizableContainerDirective,
                        ListComponent, DragTargetContainerDirective, DropTargetContainerDirective, DraggableDirective,
                        GridMarqueeDirective, FooterComponent, TableBodyComponent, LoadingComponent, StatusBarComponent,
                        IconWrapperComponent, WatermarkOverlayComponent, ...KENDO_PAGER, NgTemplateOutlet
                    ]
                }]
        }], ctorParameters: function () { return [{ type: i1.BrowserSupportService }, { type: i2.SelectionService }, { type: i3.CellSelectionService }, { type: i0.ElementRef }, { type: i4.GroupInfoService }, { type: i5.GroupsService }, { type: i6.ChangeNotificationService }, { type: i7.DetailsService }, { type: i8.EditService }, { type: i9.FilterService }, { type: i10.PDFService }, { type: i11.ResponsiveService }, { type: i0.Renderer2 }, { type: i12.ExcelService }, { type: i0.NgZone }, { type: i13.ScrollSyncService }, { type: i14.DomEventsService }, { type: i15.ColumnResizingService }, { type: i0.ChangeDetectorRef }, { type: i16.ColumnReorderService }, { type: i17.ColumnInfoService }, { type: i18.NavigationService }, { type: i19.SortService }, { type: i20.ScrollRequestService }, { type: i21.LocalizationService }, { type: i22.ContextService }, { type: i23.SizingOptionsService }, { type: i24.RowReorderService }]; }, propDecorators: { data: [{
                type: Input
            }], pageSize: [{
                type: Input
            }], height: [{
                type: Input
            }], rowHeight: [{
                type: Input
            }], detailRowHeight: [{
                type: Input
            }], skip: [{
                type: Input
            }], scrollable: [{
                type: Input
            }], selectable: [{
                type: Input
            }], sort: [{
                type: Input
            }], size: [{
                type: Input
            }], trackBy: [{
                type: Input
            }], filter: [{
                type: Input
            }], group: [{
                type: Input
            }], virtualColumns: [{
                type: Input
            }], filterable: [{
                type: Input
            }], sortable: [{
                type: Input
            }], pageable: [{
                type: Input
            }], groupable: [{
                type: Input
            }], gridResizable: [{
                type: Input
            }], rowReorderable: [{
                type: Input
            }], navigable: [{
                type: Input
            }], navigatable: [{
                type: Input
            }], autoSize: [{
                type: Input
            }], rowClass: [{
                type: Input
            }], rowSticky: [{
                type: Input
            }], rowSelected: [{
                type: Input
            }], isRowSelectable: [{
                type: Input
            }], cellSelected: [{
                type: Input
            }], resizable: [{
                type: Input
            }], reorderable: [{
                type: Input
            }], loading: [{
                type: Input
            }], columnMenu: [{
                type: Input
            }], hideHeader: [{
                type: Input
            }], filterChange: [{
                type: Output
            }], pageChange: [{
                type: Output
            }], groupChange: [{
                type: Output
            }], sortChange: [{
                type: Output
            }], selectionChange: [{
                type: Output
            }], rowReorder: [{
                type: Output
            }], dataStateChange: [{
                type: Output
            }], groupExpand: [{
                type: Output
            }], groupCollapse: [{
                type: Output
            }], detailExpand: [{
                type: Output
            }], detailCollapse: [{
                type: Output
            }], edit: [{
                type: Output
            }], cancel: [{
                type: Output
            }], save: [{
                type: Output
            }], remove: [{
                type: Output
            }], add: [{
                type: Output
            }], cellClose: [{
                type: Output
            }], cellClick: [{
                type: Output
            }], pdfExport: [{
                type: Output
            }], excelExport: [{
                type: Output
            }], columnResize: [{
                type: Output
            }], columnReorder: [{
                type: Output
            }], columnVisibilityChange: [{
                type: Output
            }], columnLockedChange: [{
                type: Output
            }], columnStickyChange: [{
                type: Output
            }], scrollBottom: [{
                type: Output
            }], contentScroll: [{
                type: Output
            }], columns: [{
                type: ContentChildren,
                args: [ColumnBase]
            }], dir: [{
                type: HostBinding,
                args: ['attr.dir']
            }], hostClass: [{
                type: HostBinding,
                args: ['class.k-grid']
            }], sizeSmallClass: [{
                type: HostBinding,
                args: ['class.k-grid-sm']
            }], sizeMediumClass: [{
                type: HostBinding,
                args: ['class.k-grid-md']
            }], lockedClasses: [{
                type: HostBinding,
                args: ['class.k-grid-lockedcolumns']
            }], virtualClasses: [{
                type: HostBinding,
                args: ['class.k-grid-virtual']
            }], noScrollbarClass: [{
                type: HostBinding,
                args: ['class.k-grid-no-scrollbar']
            }], isResizable: [{
                type: HostBinding,
                args: ['class.k-grid-resizable']
            }], minWidth: [{
                type: HostBinding,
                args: ['style.minWidth']
            }], maxWidth: [{
                type: HostBinding,
                args: ['style.maxWidth']
            }], minHeight: [{
                type: HostBinding,
                args: ['style.minHeight']
            }], maxHeight: [{
                type: HostBinding,
                args: ['style.maxHeight']
            }], detailTemplateChildren: [{
                type: ContentChildren,
                args: [DetailTemplateDirective]
            }], cellLoadingTemplateChildren: [{
                type: ContentChildren,
                args: [CellLoadingTemplateDirective]
            }], loadingTemplateChildren: [{
                type: ContentChildren,
                args: [LoadingTemplateDirective]
            }], statusBarTemplateChildren: [{
                type: ContentChildren,
                args: [StatusBarTemplateDirective]
            }], noRecordsTemplateChildren: [{
                type: ContentChildren,
                args: [NoRecordsTemplateDirective]
            }], pagerTemplateChildren: [{
                type: ContentChildren,
                args: [PagerTemplateDirective]
            }], toolbarTemplateChildren: [{
                type: ContentChildren,
                args: [ToolbarTemplateDirective]
            }], columnMenuTemplates: [{
                type: ContentChildren,
                args: [ColumnMenuTemplateDirective]
            }], lockedHeader: [{
                type: ViewChild,
                args: ['lockedHeader', { static: false }]
            }], header: [{
                type: ViewChild,
                args: ['header', { static: false }]
            }], footer: [{
                type: ViewChildren,
                args: ['footer']
            }], ariaRoot: [{
                type: ViewChild,
                args: ['ariaRoot', { static: true }]
            }], dragTargetContainer: [{
                type: ViewChild,
                args: [DragTargetContainerDirective]
            }], dropTargetContainer: [{
                type: ViewChild,
                args: [DropTargetContainerDirective]
            }], isDetailExpanded: [{
                type: Input
            }], isGroupExpanded: [{
                type: Input
            }] } });