@progress/kendo-angular-grid 18.0.0-develop.4 → 18.0.0-develop.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -3,8 +3,8 @@
3
3
  * Licensed under commercial license. See LICENSE.md in the project root for more information
4
4
  *-------------------------------------------------------------------------------------------*/
5
5
  import * as i0 from '@angular/core';
6
- import { EventEmitter, Injectable, SecurityContext, InjectionToken, Optional, Inject, Directive, SkipSelf, Input, Host, Output, isDevMode, QueryList, Component, ContentChildren, ContentChild, forwardRef, HostBinding, Pipe, TemplateRef, ChangeDetectionStrategy, ViewChildren, ViewChild, Self, NgZone, HostListener, ViewEncapsulation, NgModule } from '@angular/core';
7
- import { merge, of, Subject, from, Subscription, interval, fromEvent, Observable, zip as zip$1, BehaviorSubject } from 'rxjs';
6
+ import { EventEmitter, Injectable, SecurityContext, InjectionToken, Optional, Inject, Directive, SkipSelf, Input, isDevMode, QueryList, Component, ContentChildren, ContentChild, forwardRef, Host, Output, HostBinding, Pipe, TemplateRef, ChangeDetectionStrategy, ViewChildren, ViewChild, Self, NgZone, HostListener, ViewEncapsulation, NgModule } from '@angular/core';
7
+ import { merge, of, Subject, zip as zip$1, from, Subscription, interval, fromEvent, Observable, BehaviorSubject } from 'rxjs';
8
8
  import * as i1$3 from '@progress/kendo-angular-common';
9
9
  import { isDocumentAvailable, Keys, isPresent as isPresent$1, anyChanged, TemplateContextDirective, DraggableDirective, EventsOutsideAngularDirective, isChanged as isChanged$1, KendoInput, guid, hasObservers, ResizeSensorComponent, closest as closest$1, isFocusable as isFocusable$1, shouldShowValidationUI, WatermarkOverlayComponent, ResizeBatchService } from '@progress/kendo-angular-common';
10
10
  import * as i1 from '@angular/platform-browser';
@@ -1780,2156 +1780,2316 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
1780
1780
  type: Injectable
1781
1781
  }] });
1782
1782
 
1783
- const isInSameGrid = (element, gridElement) => closest(element, matchesNodeName('kendo-grid')) === gridElement;
1784
- const matchHeaderCell = matchesNodeName('th');
1785
- const matchDataCell = matchesNodeName('td');
1786
- const matchFooterCell = matchesNodeName('.k-grid-footer td');
1787
- const matchCell = (element) => matchDataCell(element) || matchHeaderCell(element) || matchFooterCell(element);
1788
- const gridCell = (element, gridElement) => {
1789
- let target = closest(element, matchCell);
1790
- while (target && !isInSameGrid(target, gridElement)) {
1791
- target = closest(target.parentElement, matchCell);
1783
+ /**
1784
+ * Represents the column cell template of the Grid.
1785
+ * Helps to customize the content of the cells. To define the cell template, nest an `<ng-template>` tag with the
1786
+ * `kendoGridCellTemplate` directive inside a `<kendo-grid-column>` tag [see example](slug:templates_columns_grid#toc-cell-template).
1787
+ *
1788
+ * The template context is set to the current data item and the following additional fields are passed:
1789
+ * - `columnIndex`&mdash;The current column index. Use it as an alias for a template variable by utilizing the `let-columnIndex="columnIndex"` syntax.
1790
+ * - `rowIndex`&mdash;The current data row index. Use it as an alias for a template variable by utilizing the `let-rowIndex="rowIndex"` syntax.
1791
+ * - `dataItem`&mdash;The current data item. Represents the default context that will be assigned to any template variable which utilizes the `let-x` syntax&mdash;for example, `let-dataItem`.
1792
+ * - `column`&mdash;The current column instance. Use it as an alias for a template variable by utilizing the `let-column="column"` syntax.
1793
+ *
1794
+ * @example
1795
+ * ```html
1796
+ * <kendo-grid [data]="gridData" ...>
1797
+ * <kendo-grid-column field="ProductName">
1798
+ * <ng-template kendoGridCellTemplate let-dataItem let-rowIndex="rowIndex" let-column="column">
1799
+ * Data Row: {{rowIndex}}
1800
+ * </ng-template>
1801
+ * </kendo-grid-column>
1802
+ * </kendo-grid>
1803
+ * ```
1804
+ */
1805
+ class CellTemplateDirective {
1806
+ templateRef;
1807
+ constructor(templateRef) {
1808
+ this.templateRef = templateRef;
1792
1809
  }
1793
- return target;
1794
- };
1795
- const targetCell = (target, gridElement) => {
1796
- const cell = gridCell(target, gridElement);
1797
- const row = closest(cell, matchesNodeName('tr'));
1798
- if (cell && row) {
1799
- let rowIndex = row.getAttribute('aria-rowindex') || row.getAttribute('data-kendo-grid-row-index');
1800
- rowIndex = rowIndex ? parseInt(rowIndex, 10) - 1 : null;
1801
- let colIndex = cell.getAttribute('aria-colindex');
1802
- colIndex = colIndex ? parseInt(colIndex, 10) - 1 : null;
1803
- if (rowIndex !== null && colIndex !== null) {
1804
- return { colIndex, rowIndex, element: cell };
1805
- }
1810
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: CellTemplateDirective, deps: [{ token: i0.TemplateRef, optional: true }], target: i0.ɵɵFactoryTarget.Directive });
1811
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: CellTemplateDirective, isStandalone: true, selector: "[kendoGridCellTemplate]", ngImport: i0 });
1812
+ }
1813
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: CellTemplateDirective, decorators: [{
1814
+ type: Directive,
1815
+ args: [{
1816
+ selector: '[kendoGridCellTemplate]',
1817
+ standalone: true
1818
+ }]
1819
+ }], ctorParameters: function () { return [{ type: i0.TemplateRef, decorators: [{
1820
+ type: Optional
1821
+ }] }]; } });
1822
+
1823
+ /**
1824
+ * Represents the column edit-cell template of the Grid ([see example](slug:custom_reactive_editing_grid#toc-setting-up-custom-inputs)).
1825
+ * Helps to customize the content of the edited cells. To define the cell template, nest an `<ng-template>`
1826
+ * tag with the `kendoGridEditTemplate` directive inside a `<kendo-grid-column>` tag.
1827
+ *
1828
+ * The template context is set to the current form group and the following additional fields are passed:
1829
+ * - `formGroup`&mdash;The current [FormGroup](link:site.data.urls.angular['formgroupapi']). Represents the default context that will be assigned to any template variable which utilizes the `let-x` syntax, for example, `let-formGroup`. If you use the Grid inside [Template-Driven Forms](link:site.data.urls.angular['forms']), it will be `undefined`.
1830
+ * - `rowIndex`&mdash;The current data row index. If inside a new item row, `rowIndex` is `-1`. Use it as an alias for a template variable by utilizing the `let-rowIndex="rowIndex"` syntax.
1831
+ * - `dataItem`&mdash;The current data item. Use it as an alias for a template variable by utilizing the `let-dataItem="dataItem"` syntax.
1832
+ * - `column`&mdash;The current column instance. Use it as an alias for a template variable by utilizing the `let-column="column"` syntax.
1833
+ * - `isNew`&mdash;The state of the current item. Use it as an alias for a template variable by utilizing the `let-isNew="isNew"` syntax.
1834
+ */
1835
+ class EditTemplateDirective {
1836
+ templateRef;
1837
+ constructor(templateRef) {
1838
+ this.templateRef = templateRef;
1806
1839
  }
1807
- };
1808
- const isArrowKey = keyCode => keyCode === Keys.ArrowLeft || keyCode === Keys.ArrowRight ||
1809
- keyCode === Keys.ArrowUp || keyCode === Keys.ArrowDown;
1810
- const isNavigationKey = keyCode => isArrowKey(keyCode) ||
1811
- keyCode === Keys.PageUp || keyCode === Keys.PageDown ||
1812
- keyCode === Keys.Home || keyCode === Keys.End;
1813
- const isInput = matchesNodeName('input');
1814
- const isTextInput = element => element && isInput(element) && element.type.toLowerCase() === 'text';
1815
- const isPrintableCharacter = (str) => str.length === 1 && str.match(/\S/);
1840
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: EditTemplateDirective, deps: [{ token: i0.TemplateRef, optional: true }], target: i0.ɵɵFactoryTarget.Directive });
1841
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: EditTemplateDirective, isStandalone: true, selector: "[kendoGridEditTemplate]", ngImport: i0 });
1842
+ }
1843
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: EditTemplateDirective, decorators: [{
1844
+ type: Directive,
1845
+ args: [{
1846
+ selector: '[kendoGridEditTemplate]',
1847
+ standalone: true
1848
+ }]
1849
+ }], ctorParameters: function () { return [{ type: i0.TemplateRef, decorators: [{
1850
+ type: Optional
1851
+ }] }]; } });
1852
+
1816
1853
  /**
1817
- * @hidden
1854
+ * Represents the column header cell template of the Grid
1855
+ * ([more information and example]({% slug templates_columns_grid %}#toc-header-template)).
1856
+ * Helps to customize the table header cell for the column.
1857
+ * To define a header template, nest an `<ng-template>` tag with the
1858
+ * `kendoGridHeaderTemplate` directive inside the `<kendo-grid-column>` tag.
1859
+ *
1860
+ * The template context is set to the current column and then the following additional fields are passed:
1861
+ * * `column`&mdash;Defines an instance of the [ColumnComponent]({% slug api_grid_columncomponent %}) option.
1862
+ * * `columnIndex`&mdash;Defines the current column index.
1863
+ *
1864
+ * @example
1865
+ * ```html
1866
+ * <kendo-grid [data]="gridData">
1867
+ * <kendo-grid-column field="ProductName">
1868
+ * <ng-template kendoGridHeaderTemplate let-column let-columnIndex="columnIndex">
1869
+ * {{column.field}}({{columnIndex}})
1870
+ * </ng-template>
1871
+ * </kendo-grid-column>
1872
+ * </kendo-grid>
1873
+ * ```
1818
1874
  */
1819
- class NavigationViewport {
1820
- firstItemIndex;
1821
- lastItemIndex;
1822
- constructor(firstItemIndex, lastItemIndex) {
1823
- this.firstItemIndex = firstItemIndex;
1824
- this.lastItemIndex = lastItemIndex;
1875
+ class HeaderTemplateDirective {
1876
+ templateRef;
1877
+ constructor(templateRef) {
1878
+ this.templateRef = templateRef;
1825
1879
  }
1826
- containsRow(dataRowIndex) {
1827
- const headerRow = dataRowIndex < 0;
1828
- return headerRow || (dataRowIndex >= this.firstItemIndex && dataRowIndex <= this.lastItemIndex);
1880
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: HeaderTemplateDirective, deps: [{ token: i0.TemplateRef, optional: true }], target: i0.ɵɵFactoryTarget.Directive });
1881
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: HeaderTemplateDirective, isStandalone: true, selector: "[kendoGridHeaderTemplate]", ngImport: i0 });
1882
+ }
1883
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: HeaderTemplateDirective, decorators: [{
1884
+ type: Directive,
1885
+ args: [{
1886
+ selector: '[kendoGridHeaderTemplate]',
1887
+ standalone: true
1888
+ }]
1889
+ }], ctorParameters: function () { return [{ type: i0.TemplateRef, decorators: [{
1890
+ type: Optional
1891
+ }] }]; } });
1892
+
1893
+ /**
1894
+ * Represents the column footer cell template of the Grid
1895
+ * ([more information and example]({% slug templates_columns_grid %}#toc-footer-template)).
1896
+ * Helps to customize the table footer cell for the column.
1897
+ * To define a footer template, nest an `<ng-template>` tag with the
1898
+ * [kendoGridFooterTemplate]({% slug api_grid_footertemplatedirective %}) directive inside the `<kendo-grid-column>` tag.
1899
+ *
1900
+ * The template context is set to the current column and the following additional fields are passed:
1901
+ * * `column`&mdash;Defines an instance of the [ColumnComponent]({% slug api_grid_columncomponent %}) option.
1902
+ * * `columnIndex`&mdash;Defines the current column index.
1903
+ *
1904
+ * For more information on how to display aggregates in the footer of the Grid,
1905
+ * refer to the article on [aggregates]({% slug groupable_grid_with_aggregates %}).
1906
+ *
1907
+ * @example
1908
+ * ```html
1909
+ * <kendo-grid [data]="gridData" scrollable="none">
1910
+ * <kendo-grid-column field="ProductName">
1911
+ * <ng-template kendoGridFooterTemplate let-column let-columnIndex="columnIndex">
1912
+ * {{column.field}}({{columnIndex}})
1913
+ * </ng-template>
1914
+ * </kendo-grid-column>
1915
+ * </kendo-grid>
1916
+ * ```
1917
+ */
1918
+ class FooterTemplateDirective {
1919
+ templateRef;
1920
+ constructor(templateRef) {
1921
+ this.templateRef = templateRef;
1829
1922
  }
1830
- intersects(start, end) {
1831
- return (start <= this.firstItemIndex && this.lastItemIndex <= end) ||
1832
- (this.firstItemIndex <= start && start <= this.lastItemIndex) ||
1833
- (this.firstItemIndex <= end && end <= this.lastItemIndex);
1923
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: FooterTemplateDirective, deps: [{ token: i0.TemplateRef, optional: true }], target: i0.ɵɵFactoryTarget.Directive });
1924
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: FooterTemplateDirective, isStandalone: true, selector: "[kendoGridFooterTemplate]", ngImport: i0 });
1925
+ }
1926
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: FooterTemplateDirective, decorators: [{
1927
+ type: Directive,
1928
+ args: [{
1929
+ selector: '[kendoGridFooterTemplate]',
1930
+ standalone: true
1931
+ }]
1932
+ }], ctorParameters: function () { return [{ type: i0.TemplateRef, decorators: [{
1933
+ type: Optional
1934
+ }] }]; } });
1935
+
1936
+ /**
1937
+ * Represents the template for the column menu in the Grid. Provides an option for
1938
+ * customizing the content of the column menu for all or for specific columns.
1939
+ * To define the content template, nest an `<ng-template>` tag with the
1940
+ * `kendoGridColumnMenuTemplate` directive inside the `<kendo-grid>` or the `<kendo-grid-column>` component.
1941
+ *
1942
+ * The template context is passes through the following fields:
1943
+ * - `service`&mdash;Represents the [ColumnMenuService]({% slug api_grid_columnmenuservice %}).
1944
+ * - `column`&mdash;Represents the Grid column.
1945
+ *
1946
+ * @example
1947
+ * ```html
1948
+ * <kendo-grid [kendoGridBinding]="data" [sortable]="true" [columnMenu]="true">
1949
+ * <ng-template kendoGridColumnMenuTemplate let-service="service">
1950
+ * <kendo-grid-columnmenu-sort [service]="service"></kendo-grid-columnmenu-sort>
1951
+ * </ng-template>
1952
+ * <kendo-grid-column field="Field1">
1953
+ * <ng-template kendoGridColumnMenuTemplate let-service="service">
1954
+ * <kendo-grid-columnmenu-lock [service]="service"></kendo-grid-columnmenu-lock>
1955
+ * <kendo-grid-columnmenu-sort [service]="service"></kendo-grid-columnmenu-sort>
1956
+ * </ng-template>
1957
+ * </kendo-grid-column>
1958
+ * <kendo-grid-column field="Field2"></kendo-grid-column>
1959
+ * </kendo-grid>
1960
+ * ```
1961
+ */
1962
+ class ColumnMenuTemplateDirective {
1963
+ templateRef;
1964
+ constructor(templateRef) {
1965
+ this.templateRef = templateRef;
1834
1966
  }
1967
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ColumnMenuTemplateDirective, deps: [{ token: i0.TemplateRef, optional: true }], target: i0.ɵɵFactoryTarget.Directive });
1968
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: ColumnMenuTemplateDirective, isStandalone: true, selector: "[kendoGridColumnMenuTemplate]", ngImport: i0 });
1835
1969
  }
1970
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ColumnMenuTemplateDirective, decorators: [{
1971
+ type: Directive,
1972
+ args: [{
1973
+ selector: '[kendoGridColumnMenuTemplate]',
1974
+ standalone: true
1975
+ }]
1976
+ }], ctorParameters: function () { return [{ type: i0.TemplateRef, decorators: [{
1977
+ type: Optional
1978
+ }] }]; } });
1979
+
1980
+ // Incremented each time the service is instantiated.
1981
+ let sequence = 0;
1836
1982
  /**
1837
1983
  * @hidden
1838
1984
  */
1839
- class NavigationService {
1840
- zone;
1841
- domEvents;
1842
- pagerContextService;
1843
- scrollRequestService;
1844
- groupsService;
1845
- detailsService;
1846
- focusRoot;
1847
- editService;
1848
- cd;
1849
- ctx;
1850
- focusableParent;
1851
- changes;
1852
- cellKeydown = new EventEmitter();
1853
- set metadata(value) {
1854
- this.meta = value;
1855
- this.cursor.metadata = value;
1856
- }
1857
- get metadata() {
1858
- return this.meta;
1859
- }
1860
- get enabled() {
1861
- return this.alive;
1862
- }
1863
- get pagerEnabled() {
1864
- return this.alive && this.pagerIsNavigable;
1985
+ class IdService {
1986
+ prefix;
1987
+ constructor() {
1988
+ this.prefix = `k-grid${sequence++}`;
1865
1989
  }
1866
- get tableEnabled() {
1867
- return this.alive && this.tableIsNavigable;
1990
+ gridId() {
1991
+ return this.prefix;
1868
1992
  }
1869
- get toolbarEnabled() {
1870
- return this.alive && this.toolbarIsNavigable;
1993
+ cellId(rowIndex, colIndex) {
1994
+ return `${this.prefix}-r${rowIndex}c${colIndex}`;
1871
1995
  }
1872
- get activeCell() {
1873
- if (this.mode !== 0 /* NavigationMode.Standby */) {
1874
- return this.cursor.cell;
1875
- }
1996
+ selectionCheckboxId(itemIndex) {
1997
+ return `${this.prefix}-checkbox${itemIndex}`;
1876
1998
  }
1877
- get activeRow() {
1878
- if (this.mode !== 0 /* NavigationMode.Standby */) {
1879
- return Object.assign({}, this.cursor.row, {
1880
- cells: this.cursor.row?.cells.toArray()
1881
- });
1882
- }
1999
+ selectAllCheckboxId() {
2000
+ return `${this.prefix}-select-all`;
1883
2001
  }
1884
- viewport;
1885
- columnViewport;
1886
- activeRowIndex = 0;
1887
- alive = false;
1888
- active = true;
1889
- mode = 0 /* NavigationMode.Standby */;
1890
- model = new NavigationModel();
1891
- cursor = new NavigationCursor(this.model);
1892
- meta;
1893
- subs;
1894
- pendingRowIndex;
1895
- virtualCell;
1896
- pagerIsNavigable = false;
1897
- tableIsNavigable = false;
1898
- toolbarIsNavigable = false;
1899
- get activeDataRow() {
1900
- return Math.max(0, this.activeRowIndex - this.meta.headerRows);
2002
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: IdService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
2003
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: IdService });
2004
+ }
2005
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: IdService, decorators: [{
2006
+ type: Injectable
2007
+ }], ctorParameters: function () { return []; } });
2008
+
2009
+ /**
2010
+ * @hidden
2011
+ */
2012
+ const ColumnMenuErrorMessages = {
2013
+ autoSizeColumn: `The auto size column does not work with enabled virtual columns.
2014
+ See https://www.telerik.com/kendo-angular-ui/components/grid/accessories/column-menu/#toc-autosize-column-item.`,
2015
+ autoSizeAllColumns: `The auto size all columns does not work with enabled virtual columns.
2016
+ See https://www.telerik.com/kendo-angular-ui/components/grid/accessories/column-menu/#toc-autosize-all-columns-item.`,
2017
+ serviceInput: `The service input of the predefined column menu components is mandatory.
2018
+ See https://www.telerik.com/kendo-angular-ui/components/grid/accessories/column-menu/#toc-customizing-the-content.`
2019
+ };
2020
+ /**
2021
+ * @hidden
2022
+ */
2023
+ const ClipboardErrorMessages = {
2024
+ activeCellNavigable: `Grid must be navigable to use "activeCell" as clipboard target type.
2025
+ See https://www.telerik.com/kendo-angular-ui/components/grid/accessories/clipboard/#toc-active-cell.`,
2026
+ selectionSelectable: `Grid must be selectable to use "selection" as clipboard target type.
2027
+ See https://www.telerik.com/kendo-angular-ui/components/grid/accessories/clipboard/#toc-current-selection.`
2028
+ };
2029
+ /**
2030
+ * @hidden
2031
+ */
2032
+ const ColumnConfigurationErrorMessages = {
2033
+ fieldName: (field) => `Grid column field name '${field}' does not look like a valid JavaScript identifier.
2034
+ Identifiers can contain only alphanumeric characters (including "$" or "_"), and may not start with a digit.
2035
+ Please use only valid identifier names to ensure error-free operation.`,
2036
+ width: (value, parsedValue) => `Expected numeric value for column width, but got a string "${value}". Treating as ${parsedValue}px.`,
2037
+ invalidColumn: (column) => `Invalid column ${column}.`,
2038
+ requiredWidth: (columnType) => `${columnType} columns feature requires all columns to have set width.
2039
+ See https://www.telerik.com/kendo-angular-ui/components/grid/columns/${columnType.toLowerCase()}.`,
2040
+ requiredScroll: (columnType) => `${columnType} columns are only supported when scrolling is enabled.
2041
+ See https://www.telerik.com/kendo-angular-ui/components/grid/columns/${columnType.toLowerCase()}/`,
2042
+ groupColumnContent: 'ColumnGroupComponent should contain ColumnComponent or CommandColumnComponent.',
2043
+ lockedParent: 'Locked child columns require their parent columns to be locked.',
2044
+ columnNested: 'Columns can be nested only inside ColumnGroupComponent',
2045
+ nestedInside: (nestedColumnNameType, parentColumnType) => `${nestedColumnNameType} cannot be nested inside ${parentColumnType}.`
2046
+ };
2047
+ /**
2048
+ * @hidden
2049
+ */
2050
+ const GridConfigurationErrorMessages = {
2051
+ functionType: (propName, fn) => `${propName} must be a function, but received ${JSON.stringify(fn)}.`,
2052
+ incompatibleFeatures: (feat1Name, feat2Name) => `'Having both ${feat1Name} and ${feat2Name} is not supported.'`,
2053
+ nonLockedColumnPresent: 'There should be at least one non-locked column. See https://www.telerik.com/kendo-angular-ui/components/grid/columns/locked/#toc-known-limitations',
2054
+ rowHeightVirtual: `The virtual scrolling functionality requires setting the rowHeight (and detailRowHeight when there are detail rows).
2055
+ Row height and detail row height settings should be set only when virtual scrolling mode is enabled.
2056
+ See https://www.telerik.com/kendo-angular-ui/components/grid/scroll-modes/virtual/#toc-getting-started.`,
2057
+ focusNavigable: 'The Grid should be configured as navigable to control focus. See https://www.telerik.com/kendo-angular-ui/components/grid/keyboard-navigation/.',
2058
+ expandCollapseMethods: (expandMethodName, collapseMethodName, directiveName, callbackName) => `The ${expandMethodName} and ${collapseMethodName} methods should not be called
2059
+ when using the ${directiveName} directive or the ${callbackName} callback.
2060
+ These methods are provided only for backwards compatibility with legacy versions.`,
2061
+ requiredEditService: `The default edit service of the editing directives works only when binding to plain array.
2062
+ Please provide an editService. See https://www.telerik.com/kendo-angular-ui/components/grid/editing/editing-directives/#toc-custom-editing-service.`,
2063
+ requiredModule: (exportedType, moduleName, componentSelector) => `Creating ${exportedType} requires including the ${moduleName} and adding the ${componentSelector} component.`,
2064
+ groupBindingDirectives: `Using the "kendoGridGroupBinding" directive in combination with the "kendoGridExpandGroupBy" directive
2065
+ or the "isGroupExpanded" callback is not supported. To use grouping with the "kendoGridGroupBinding" directive,
2066
+ set the Grid "groupable" property to "true".`,
2067
+ unsupportedMethod: (methodName, suggestedMethodName) => `Using ${methodName} in this context is not supported. Use ${suggestedMethodName} instead.`,
2068
+ unsupportedToolbarConfig: `
2069
+ Defining both a toolbar template and a ToolBarComponent within the Grid is not supported.
2070
+ Please use either the ToolBarComponent or a custom template.`
2071
+ };
2072
+
2073
+ /**
2074
+ * @hidden
2075
+ */
2076
+ const isSpanColumn = column => column.isSpanColumn;
2077
+ /**
2078
+ * @hidden
2079
+ */
2080
+ const isCheckboxColumn = column => column.isCheckboxColumn;
2081
+ /**
2082
+ * @hidden
2083
+ */
2084
+ const isRowReorderColumn = column => column.isRowReorderColumn;
2085
+ const isColumnContainer = column => column.isColumnGroup || isSpanColumn(column);
2086
+ /**
2087
+ * The base class for the column components of the Grid.
2088
+ */
2089
+ class ColumnBase {
2090
+ parent;
2091
+ /**
2092
+ * @hidden
2093
+ */
2094
+ matchesMedia = true;
2095
+ /**
2096
+ * The column index after reordering. The `orderIndex` is a read-only property. Setting this field does not affect column order.
2097
+ *
2098
+ * @default 0
2099
+ */
2100
+ orderIndex = 0;
2101
+ /**
2102
+ * @hidden
2103
+ */
2104
+ set leafIndex(value) {
2105
+ this._leafIndex = value;
1901
2106
  }
1902
- constructor(zone, domEvents, pagerContextService, scrollRequestService, groupsService, detailsService, focusRoot, editService, cd, ctx, focusableParent) {
1903
- this.zone = zone;
1904
- this.domEvents = domEvents;
1905
- this.pagerContextService = pagerContextService;
1906
- this.scrollRequestService = scrollRequestService;
1907
- this.groupsService = groupsService;
1908
- this.detailsService = detailsService;
1909
- this.focusRoot = focusRoot;
1910
- this.editService = editService;
1911
- this.cd = cd;
1912
- this.ctx = ctx;
1913
- this.focusableParent = focusableParent;
1914
- this.changes = this.cursor.changes;
2107
+ /**
2108
+ * @hidden
2109
+ */
2110
+ get leafIndex() {
2111
+ return this._leafIndex;
1915
2112
  }
1916
- init(meta, navigableOptions) {
1917
- this.setActiveSections(navigableOptions);
1918
- this.alive = true;
1919
- this.focusRoot.active = true;
1920
- this.metadata = meta;
1921
- const onStableSubscriber = (...operators) => (args) => this.zone.isStable ?
1922
- from([true]).pipe(map(() => args)) :
1923
- this.zone.onStable.pipe(take(1), map(() => args), ...operators);
1924
- const onStable = onStableSubscriber();
1925
- this.subs = new Subscription();
1926
- this.subs.add(this.cursor.changes.subscribe(args => this.onCursorChanges(args)));
1927
- this.subs.add(this.domEvents.focus.pipe(switchMap(onStable))
1928
- .subscribe((args) => this.navigateTo(args.target)));
1929
- this.subs.add(this.domEvents.focusOut.pipe(filter(() => this.mode !== 0 /* NavigationMode.Standby */), switchMap(onStableSubscriber(takeUntil(this.domEvents.focus))))
1930
- .subscribe(args => this.onFocusOut(args)));
1931
- this.subs.add(this.domEvents.windowBlur.pipe(filter(() => this.mode !== 0 /* NavigationMode.Standby */))
1932
- .subscribe(() => this.onWindowBlur()));
1933
- this.subs.add(
1934
- // Closing the editor will not always trigger focusout in Firefox.
1935
- // To get around this, we ensure that the cell is closed after editing.
1936
- this.editService.changes.pipe(filter(e => e.action !== 'edit' && this.mode === 2 /* NavigationMode.Content */), filter((e) => e.action === 'cellClose' && !e.prevented), switchMap(onStable))
1937
- .subscribe(() => this.leaveCell()));
1938
- this.subs.add(this.pagerContextService.pageChange
1939
- .subscribe(() => this.cursor.reset(0, 0)));
1940
- this.subs.add(this.domEvents.keydown
1941
- .subscribe(args => this.onKeydown(args)));
1942
- this.subs.add(this.domEvents.keydown.pipe(filter(args => args.keyCode === Keys.Tab && this.mode === 2 /* NavigationMode.Content */), switchMapTo(this.domEvents.focusOut.pipe(takeUntil(
1943
- // Timeout if focusOut doesn't fire very soon
1944
- interval(0).pipe(take(1))))))
1945
- .subscribe(() => this.onTabout()));
1946
- if (this.focusableParent) {
1947
- const element = new GridFocusableElement(this);
1948
- this.focusableParent.registerElement(element);
2113
+ _leafIndex;
2114
+ /**
2115
+ * @hidden
2116
+ */
2117
+ isColumnGroup = false;
2118
+ /**
2119
+ * @hidden
2120
+ */
2121
+ isSpanColumn = false;
2122
+ /**
2123
+ * Indicates whether the column is resizable.
2124
+ * @default true
2125
+ */
2126
+ resizable = true;
2127
+ /**
2128
+ * Indicates whether the column is reorderable.
2129
+ * @default true
2130
+ */
2131
+ reorderable = true;
2132
+ /**
2133
+ * The width (in pixels) below which the user is not able to resize the column by using the UI ([see example]({% slug resizing_columns_grid %}#toc-limiting-the-resizing)).
2134
+ * The `autoFitColumn` and `autoFitColumns` methods have higher priority.
2135
+ * @default 10
2136
+ */
2137
+ minResizableWidth = 10;
2138
+ /**
2139
+ * The width (in pixels) above which the user is not able to resize the column by using the UI ([see example]({% slug resizing_columns_grid %}#toc-limiting-the-resizing)).
2140
+ * By default, the maximum width is not restricted.
2141
+ * The `autoFitColumn` and `autoFitColumns` methods have higher priority.
2142
+ */
2143
+ maxResizableWidth;
2144
+ /**
2145
+ * The title of the column.
2146
+ */
2147
+ title;
2148
+ /**
2149
+ * The width of the column (in pixels).
2150
+ */
2151
+ set width(value) {
2152
+ if (typeof value === 'string') {
2153
+ const parsedValue = this._width = parseInt(value, 10);
2154
+ if (isDevMode()) {
2155
+ console.warn(ColumnConfigurationErrorMessages.width(value, parsedValue));
2156
+ }
1949
2157
  }
1950
- this.deactivateElements();
1951
- }
1952
- ngOnDestroy() {
1953
- if (this.subs) {
1954
- this.subs.unsubscribe();
2158
+ else {
2159
+ this._width = value;
1955
2160
  }
1956
- this.alive = false;
1957
2161
  }
1958
- registerCell(cell) {
1959
- if (cell.logicalRowIndex !== this.pendingRowIndex) {
1960
- const modelCell = this.model.registerCell(cell);
1961
- if (this.virtualCell && this.cursor.activateVirtualCell(modelCell)) {
1962
- this.virtualCell = false;
1963
- }
1964
- }
2162
+ get width() { return this._width; }
2163
+ /**
2164
+ * Indicates whether the column will be resized during initialization so that it fits its header and row content.
2165
+ */
2166
+ autoSize;
2167
+ /**
2168
+ * Toggles the locked (frozen) state of the columns ([more information and example]({% slug locked_columns_grid %})).
2169
+ *
2170
+ * @default false
2171
+ *
2172
+ */
2173
+ set locked(value) {
2174
+ this._locked = value;
1965
2175
  }
1966
- registerCellOnCurrentRow(cell) {
1967
- if (cell.logicalRowIndex === this.pendingRowIndex) {
1968
- this.model.registerCell(cell);
2176
+ get locked() {
2177
+ return this._locked;
2178
+ }
2179
+ _locked = false;
2180
+ /**
2181
+ * Determines whether the column will be always visible when scrolling the Grid horizontally.
2182
+ *
2183
+ * @default false
2184
+ */
2185
+ sticky = false;
2186
+ /**
2187
+ * Sets the visibility of the column ([see example](slug:hidden_columns_grid#toc-using-the-built-in-options)).
2188
+ *
2189
+ * @default false
2190
+ */
2191
+ hidden;
2192
+ /**
2193
+ * Sets the condition that needs to be satisfied for a column to remain visible ([see example]({% slug styling_responsive_grid %}#toc-columns)).
2194
+ * If you set the `hidden` property, the behavior of `media` is overridden.
2195
+ *
2196
+ * Accepts the device identifiers that are [available in Bootstrap 4](https://v4-alpha.getbootstrap.com/layout/grid/#grid-options)
2197
+ * ([see example](slug:styling_responsive_grid)):
2198
+ */
2199
+ media;
2200
+ /**
2201
+ * Specifies if the column can be locked or unlocked from the column menu or by reordering the columns.
2202
+ * @default true
2203
+ */
2204
+ lockable = true;
2205
+ /**
2206
+ * Specifies if the column can be stuck or unstuck from the column menu.
2207
+ * @default true
2208
+ */
2209
+ stickable = true;
2210
+ /**
2211
+ * Specifies if the column menu will be shown for the column.
2212
+ * @default true
2213
+ */
2214
+ columnMenu = true;
2215
+ /**
2216
+ * Specifies if the column will be included in the column-chooser list.
2217
+ * @default true
2218
+ */
2219
+ includeInChooser = true;
2220
+ /**
2221
+ * Allows setting the `role` attribute for the table cells (excluding the footer and header ones) of the column.
2222
+ * @default "gridcell"
2223
+ */
2224
+ tableCellsRole = 'gridcell';
2225
+ /**
2226
+ * Sets the custom styles for the table cells (excluding the footer and header ones) of the column. Under the hood,
2227
+ * to apply the property, the `style` option uses the
2228
+ * [NgStyle](link:site.data.urls.angular['ngstyleapi']) directive. [See example](slug:styling_grid_columns#toc-customizing-column-cells).
2229
+ *
2230
+ */
2231
+ style;
2232
+ /**
2233
+ * Sets the custom styles for the header cell of the column. Under the hood, to apply the property,
2234
+ * the `headerStyle` option uses the
2235
+ * [NgStyle](link:site.data.urls.angular['ngstyleapi']) directive. [See example](slug:styling_grid_columns#toc-customizing-column-header).
2236
+ *
2237
+ */
2238
+ headerStyle;
2239
+ /**
2240
+ * Sets the custom styles for the filter row cell. Under the hood, to apply the property,
2241
+ * the `filterStyle` option uses the
2242
+ * [NgStyle](link:site.data.urls.angular['ngstyleapi']) directive. [See example](slug:styling_grid_columns#toc-customizing-filter-row-cells).
2243
+ *
2244
+ */
2245
+ filterStyle;
2246
+ /**
2247
+ * Sets the custom styles for the footer cell of the column. Under the hood, to apply the property,
2248
+ * the `footerStyle` option uses the
2249
+ * [NgStyle](link:site.data.urls.angular['ngstyleapi']) directive. [See example](slug:styling_grid_columns#toc-customizing-column-footer).
2250
+ *
2251
+ */
2252
+ footerStyle;
2253
+ /**
2254
+ * Sets the custom CSS classes to the column cells. Under the hood, to apply the property, the `class` option uses the
2255
+ * [NgClass](link:site.data.urls.angular['ngclassapi']) directive. [See example](slug:styling_grid_columns#toc-customizing-column-cells).
2256
+ * To customize header and footer column cells, use the [headerClass]({% slug api_grid_columncomponent %}#toc-headerclass)
2257
+ * and [footerClass]({% slug api_grid_columncomponent %}#toc-footerclass) inputs.
2258
+ *
2259
+ */
2260
+ cssClass;
2261
+ /**
2262
+ * Sets the custom CSS classes to the column header cell. Under the hood, to apply the property,
2263
+ * the `headerClass` option uses the
2264
+ * [NgClass](link:site.data.urls.angular['ngclassapi']) directive. [See example](slug:styling_grid_columns#toc-customizing-column-header).
2265
+ *
2266
+ */
2267
+ headerClass;
2268
+ /**
2269
+ * Sets the custom CSS classes to the filter row cell. Under the hood, to apply the property,
2270
+ * the `filterClass` option uses the
2271
+ * [NgClass](link:site.data.urls.angular['ngclassapi']) directive. [See example](slug:styling_grid_columns#toc-customizing-filter-row-cells).
2272
+ *
2273
+ */
2274
+ filterClass;
2275
+ /**
2276
+ * Sets the custom CSS classes to the column footer cell. Under the hood, to apply the property,
2277
+ * the `footerClass` option uses the
2278
+ * [NgClass](link:site.data.urls.angular['ngclassapi']) directive. [See example](slug:styling_grid_columns#toc-customizing-column-footer).
2279
+ *
2280
+ */
2281
+ footerClass;
2282
+ /**
2283
+ * @hidden
2284
+ */
2285
+ headerTemplates = new QueryList();
2286
+ /**
2287
+ * @hidden
2288
+ */
2289
+ footerTemplate;
2290
+ /**
2291
+ * @hidden
2292
+ */
2293
+ columnMenuTemplates = new QueryList();
2294
+ /**
2295
+ * @hidden
2296
+ */
2297
+ resizeStartWidth;
2298
+ /**
2299
+ * @hidden
2300
+ */
2301
+ idService;
2302
+ /**
2303
+ * @hidden
2304
+ */
2305
+ implicitWidth;
2306
+ /**
2307
+ * @hidden
2308
+ */
2309
+ get level() {
2310
+ if (this.parent && isSpanColumn(this.parent)) {
2311
+ return this.parent.level;
1969
2312
  }
2313
+ return this.parent ? this.parent.level + 1 : 0;
1970
2314
  }
1971
- unregisterCell(index, rowIndex, cell) {
1972
- this.model.unregisterCell(index, rowIndex, cell);
2315
+ /**
2316
+ * @hidden
2317
+ */
2318
+ get isLocked() {
2319
+ return this.parent ? this.parent.isLocked : this.locked;
1973
2320
  }
1974
- registerRow(row) {
1975
- this.model.registerRow(row);
1976
- this.pendingRowIndex = row.logicalRowIndex;
2321
+ _width;
2322
+ /**
2323
+ * @hidden
2324
+ */
2325
+ get colspan() {
2326
+ return 1;
1977
2327
  }
1978
- updateRow(row) {
1979
- this.model.updateRow(row);
2328
+ /**
2329
+ * @hidden
2330
+ */
2331
+ rowspan(totalColumnLevels) {
2332
+ return this.level < totalColumnLevels ? (totalColumnLevels - this.level) + 1 : 1;
1980
2333
  }
1981
- unregisterRow(index, row) {
1982
- this.model.unregisterRow(index, row);
1983
- const lastRow = this.model.lastRow;
1984
- if (lastRow && this.mode === 0 /* NavigationMode.Standby */) {
1985
- const maxIndex = (this.needsViewport() && this.viewport) ? this.viewport.lastItemIndex : lastRow.index;
1986
- if (this.activeRowIndex > maxIndex) {
1987
- this.cursor.reset(0, 0);
1988
- }
1989
- }
2334
+ /**
2335
+ * @hidden
2336
+ */
2337
+ get headerTemplateRef() {
2338
+ const template = this.headerTemplates.first;
2339
+ return template ? template.templateRef : undefined;
1990
2340
  }
1991
- isCellFocusable(cell) {
1992
- return this.alive &&
1993
- this.active &&
1994
- this.mode !== 2 /* NavigationMode.Content */ &&
1995
- this.cursor.isActive(cell.logicalRowIndex, cell.logicalColIndex);
2341
+ /**
2342
+ * @hidden
2343
+ */
2344
+ get footerTemplateRef() {
2345
+ return this.footerTemplate ? this.footerTemplate.templateRef : undefined;
1996
2346
  }
1997
- isCellFocused(cell) {
1998
- return this.mode === 1 /* NavigationMode.Cursor */ && this.isCellFocusable(cell);
2347
+ /**
2348
+ * @hidden
2349
+ */
2350
+ get columnMenuTemplateRef() {
2351
+ const template = this.columnMenuTemplates.first;
2352
+ return template ? template.templateRef : null;
1999
2353
  }
2000
- navigateTo(el) {
2001
- if (!this.alive || !isDocumentAvailable()) {
2002
- return;
2003
- }
2004
- const cell = targetCell(el, this.meta.gridElement.nativeElement);
2005
- if (!cell) {
2006
- return;
2007
- }
2008
- const oldMode = this.mode;
2009
- const focusInCell = contains$1(cell.element, document.activeElement);
2010
- const focusInActiveRowContent = this.mode === 2 /* NavigationMode.Content */ &&
2011
- this.activeRowIndex === cell.rowIndex &&
2012
- el !== cell.element;
2013
- if (focusInCell) {
2014
- this.mode = 2 /* NavigationMode.Content */;
2015
- this.cursor.reset(cell.rowIndex, cell.colIndex);
2016
- this.activateRow();
2017
- }
2018
- else if (!focusInActiveRowContent) {
2019
- this.mode = 1 /* NavigationMode.Cursor */;
2020
- this.deactivateElements();
2021
- const alreadyActive = this.cursor.isActive(cell.rowIndex, cell.colIndex);
2022
- const isCursor = oldMode === 1 /* NavigationMode.Cursor */ && alreadyActive;
2023
- if (!isCursor) {
2024
- this.cursor.reset(cell.rowIndex, cell.colIndex);
2025
- }
2026
- }
2354
+ /**
2355
+ * @hidden
2356
+ */
2357
+ get displayTitle() {
2358
+ return this.title;
2027
2359
  }
2028
- tryFocus(el) {
2029
- this.activateElements();
2030
- const focusable = findFocusableChild(el);
2031
- if (focusable) {
2032
- const cell = targetCell(focusable, this.meta.gridElement.nativeElement);
2033
- if (cell) {
2034
- this.cursor.reset(cell.rowIndex, cell.colIndex);
2035
- this.deactivateElements();
2036
- this.enterCell();
2037
- }
2038
- focusable.focus();
2039
- }
2040
- else {
2041
- this.deactivateElements();
2042
- }
2043
- return !!focusable;
2044
- }
2045
- needsViewport() {
2046
- return this.meta && this.meta.isVirtual;
2047
- }
2048
- setViewport(firstItemIndex, lastItemIndex) {
2049
- this.viewport = new NavigationViewport(firstItemIndex, lastItemIndex);
2050
- if (this.meta && this.meta.isVirtual && this.activeDataRow > -1) {
2051
- const dataRowIndex = this.activeDataRow;
2052
- const ahead = firstItemIndex - dataRowIndex;
2053
- const behind = dataRowIndex - lastItemIndex;
2054
- if (ahead > 0) {
2055
- this.cursor.reset(firstItemIndex + this.meta.headerRows);
2056
- }
2057
- else if (behind > 0) {
2058
- this.cursor.reset(lastItemIndex - this.meta.headerRows);
2059
- }
2060
- }
2061
- }
2062
- setColumnViewport(firstItemIndex, lastItemIndex) {
2063
- this.columnViewport = new NavigationViewport(firstItemIndex, lastItemIndex);
2064
- if (this.meta && this.meta.isVirtual && this.activeDataRow > -1) {
2065
- const activeColumnIndex = this.cursor.cell ? this.cursor.cell.colIndex : 0;
2066
- const ahead = firstItemIndex - activeColumnIndex;
2067
- const behind = activeColumnIndex - lastItemIndex;
2068
- if (ahead > 0) {
2069
- this.cursor.reset(undefined, firstItemIndex, false);
2070
- }
2071
- else if (behind > 0) {
2072
- this.cursor.reset(undefined, lastItemIndex, false);
2073
- }
2074
- }
2075
- }
2076
- focusCell(rowIndex = undefined, colIndex = undefined) {
2077
- this.mode = 1 /* NavigationMode.Cursor */;
2078
- this.cursor.reset(rowIndex, colIndex);
2079
- return this.activeCell;
2360
+ /**
2361
+ * @hidden
2362
+ */
2363
+ get isVisible() {
2364
+ return !this.hidden && this.matchesMedia;
2080
2365
  }
2081
- focusCellByElement(el) {
2082
- const cell = targetCell(el, this.meta.gridElement.nativeElement);
2083
- if (cell) {
2084
- return this.focusCell(cell.rowIndex, cell.colIndex);
2366
+ /**
2367
+ * @hidden
2368
+ */
2369
+ constructor(parent, idService) {
2370
+ this.parent = parent;
2371
+ this.idService = idService;
2372
+ if (parent && idService && parent.idService.gridId() === idService.gridId() && !isColumnContainer(parent)) {
2373
+ throw new Error(ColumnConfigurationErrorMessages.columnNested);
2085
2374
  }
2086
2375
  }
2087
- focusNextCell(wrap = true) {
2088
- return this.focusAdjacentCell(true, wrap);
2089
- }
2090
- focusPrevCell(wrap = true) {
2091
- return this.focusAdjacentCell(false, wrap);
2092
- }
2093
- toggle(active) {
2094
- this.active = active;
2095
- this.cursor.announce();
2096
- }
2097
- hasFocus() {
2098
- return this.mode === 1 /* NavigationMode.Cursor */ || this.mode === 2 /* NavigationMode.Content */;
2376
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ColumnBase, deps: [{ token: ColumnBase }, { token: IdService }], target: i0.ɵɵFactoryTarget.Component });
2377
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: ColumnBase, selector: "kendo-grid-column-base", inputs: { resizable: "resizable", reorderable: "reorderable", minResizableWidth: "minResizableWidth", maxResizableWidth: "maxResizableWidth", title: "title", width: "width", autoSize: "autoSize", locked: "locked", sticky: "sticky", hidden: "hidden", media: "media", lockable: "lockable", stickable: "stickable", columnMenu: "columnMenu", includeInChooser: "includeInChooser", tableCellsRole: "tableCellsRole", style: "style", headerStyle: "headerStyle", filterStyle: "filterStyle", footerStyle: "footerStyle", cssClass: ["class", "cssClass"], headerClass: "headerClass", filterClass: "filterClass", footerClass: "footerClass" }, queries: [{ propertyName: "footerTemplate", first: true, predicate: FooterTemplateDirective, descendants: true }, { propertyName: "headerTemplates", predicate: HeaderTemplateDirective }, { propertyName: "columnMenuTemplates", predicate: ColumnMenuTemplateDirective }], ngImport: i0, template: ``, isInline: true });
2378
+ }
2379
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ColumnBase, decorators: [{
2380
+ type: Component,
2381
+ args: [{
2382
+ selector: 'kendo-grid-column-base',
2383
+ template: ``
2384
+ }]
2385
+ }], ctorParameters: function () { return [{ type: ColumnBase }, { type: IdService }]; }, propDecorators: { resizable: [{
2386
+ type: Input
2387
+ }], reorderable: [{
2388
+ type: Input
2389
+ }], minResizableWidth: [{
2390
+ type: Input
2391
+ }], maxResizableWidth: [{
2392
+ type: Input
2393
+ }], title: [{
2394
+ type: Input
2395
+ }], width: [{
2396
+ type: Input
2397
+ }], autoSize: [{
2398
+ type: Input
2399
+ }], locked: [{
2400
+ type: Input
2401
+ }], sticky: [{
2402
+ type: Input
2403
+ }], hidden: [{
2404
+ type: Input
2405
+ }], media: [{
2406
+ type: Input
2407
+ }], lockable: [{
2408
+ type: Input
2409
+ }], stickable: [{
2410
+ type: Input
2411
+ }], columnMenu: [{
2412
+ type: Input
2413
+ }], includeInChooser: [{
2414
+ type: Input
2415
+ }], tableCellsRole: [{
2416
+ type: Input
2417
+ }], style: [{
2418
+ type: Input
2419
+ }], headerStyle: [{
2420
+ type: Input
2421
+ }], filterStyle: [{
2422
+ type: Input
2423
+ }], footerStyle: [{
2424
+ type: Input
2425
+ }], cssClass: [{
2426
+ type: Input,
2427
+ args: ['class']
2428
+ }], headerClass: [{
2429
+ type: Input
2430
+ }], filterClass: [{
2431
+ type: Input
2432
+ }], footerClass: [{
2433
+ type: Input
2434
+ }], headerTemplates: [{
2435
+ type: ContentChildren,
2436
+ args: [HeaderTemplateDirective, { descendants: false }]
2437
+ }], footerTemplate: [{
2438
+ type: ContentChild,
2439
+ args: [FooterTemplateDirective, { static: false }]
2440
+ }], columnMenuTemplates: [{
2441
+ type: ContentChildren,
2442
+ args: [ColumnMenuTemplateDirective]
2443
+ }] } });
2444
+
2445
+ /**
2446
+ * Represents the group-header cell template of the Grid which helps to customize the content of the group header item.
2447
+ * To define the group header template, nest an `<ng-template>` tag with the `kendoGridGroupHeaderTemplate`
2448
+ * directive inside `<kendo-grid-column>`. ([See example](slug:grouping_grid_templates#toc-header-template)).
2449
+ *
2450
+ * The template context is set to the current data item and the following additional fields are passed:
2451
+ * - `group`&mdash;The current group item.
2452
+ * - `field`&mdash;The name of the field by which data is grouped.
2453
+ * - `value`&mdash;The current group value.
2454
+ * - `aggregates`&mdash;All aggregate values for the current group.
2455
+ * - `index`&mdash;The index of the current group.
2456
+ * - `expanded`&mdash;A boolean value indicating if the group is currently expanded.
2457
+ *
2458
+ * @example
2459
+ * ```html
2460
+ * <kendo-grid [data]="gridData" [group]="groups">
2461
+ * <kendo-grid-column field="ProductName">
2462
+ * <ng-template kendoGridGroupHeaderTemplate let-group let-field="field" let-value="value">
2463
+ * <strong>{{field}}</strong>: {{value}}
2464
+ * </ng-template>
2465
+ * </kendo-grid-column>
2466
+ * </kendo-grid>
2467
+ * ```
2468
+ */
2469
+ class GroupHeaderTemplateDirective {
2470
+ templateRef;
2471
+ constructor(templateRef) {
2472
+ this.templateRef = templateRef;
2099
2473
  }
2100
- autoFocusCell(start, end) {
2101
- return !this.meta.virtualColumns || end < this.meta.columns.lockedLeafColumns.length || this.columnViewport.intersects(start, end);
2474
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: GroupHeaderTemplateDirective, deps: [{ token: i0.TemplateRef, optional: true }], target: i0.ɵɵFactoryTarget.Directive });
2475
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: GroupHeaderTemplateDirective, isStandalone: true, selector: "[kendoGridGroupHeaderTemplate]", ngImport: i0 });
2476
+ }
2477
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: GroupHeaderTemplateDirective, decorators: [{
2478
+ type: Directive,
2479
+ args: [{
2480
+ selector: '[kendoGridGroupHeaderTemplate]',
2481
+ standalone: true
2482
+ }]
2483
+ }], ctorParameters: function () { return [{ type: i0.TemplateRef, decorators: [{
2484
+ type: Optional
2485
+ }] }]; } });
2486
+
2487
+ /**
2488
+ * Represents the group-header column template of the Grid which helps to customize the content of the group headers.
2489
+ * To define the group header template, nest an `<ng-template>` tag with the `kendoGridGroupHeaderColumnTemplate`
2490
+ * directive inside `<kendo-grid-column>`. ([See example](slug:grouping_grid_templates#toc-header-column-template)).
2491
+ *
2492
+ * The template context is set to the current data item and the following additional fields are passed:
2493
+ * - `group`&mdash;The current group item.
2494
+ * - `field`&mdash;The name of the field by which data is grouped.
2495
+ * - `value`&mdash;The current group value.
2496
+ * - `aggregates`&mdash;All aggregate values for the current group.
2497
+ *
2498
+ * @example
2499
+ * ```html
2500
+ * <kendo-grid-column field="ProductName" title="Product Name">
2501
+ * <ng-template kendoGridGroupHeaderColumnTemplate let-group="group" let-aggregates="aggregates">
2502
+ * <span title="Group Header Column Template for ProductName">
2503
+ * Count: {{ aggregates.Discontinued.count }}
2504
+ * </span>
2505
+ * </ng-template>
2506
+ * </kendo-grid-column>
2507
+ * ```
2508
+ */
2509
+ class GroupHeaderColumnTemplateDirective {
2510
+ templateRef;
2511
+ constructor(templateRef) {
2512
+ this.templateRef = templateRef;
2102
2513
  }
2103
- setActiveSections(navigableOptions) {
2104
- this.pagerIsNavigable = navigableOptions.includes('pager');
2105
- this.tableIsNavigable = navigableOptions.includes('table');
2106
- this.toolbarIsNavigable = navigableOptions.includes('toolbar');
2514
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: GroupHeaderColumnTemplateDirective, deps: [{ token: i0.TemplateRef, optional: true }], target: i0.ɵɵFactoryTarget.Directive });
2515
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: GroupHeaderColumnTemplateDirective, isStandalone: true, selector: "[kendoGridGroupHeaderColumnTemplate]", ngImport: i0 });
2516
+ }
2517
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: GroupHeaderColumnTemplateDirective, decorators: [{
2518
+ type: Directive,
2519
+ args: [{
2520
+ selector: '[kendoGridGroupHeaderColumnTemplate]',
2521
+ standalone: true
2522
+ }]
2523
+ }], ctorParameters: function () { return [{ type: i0.TemplateRef, decorators: [{
2524
+ type: Optional
2525
+ }] }]; } });
2526
+
2527
+ /**
2528
+ * Represents the column group footer cell template of the Grid which helps to customize the group footer cell for the column.
2529
+ * To define the group footer template, nest an `<ng-template>` tag with the `kendoGridGroupFooterTemplate` directive
2530
+ * inside `<kendo-grid-column>`.
2531
+ *
2532
+ * The template context is set to the current data item and the following additional fields are passed:
2533
+ * - `column`&mdash;Defines an instance of the `ColumnComponent` option.
2534
+ * - `field`&mdash;The current column field name.
2535
+ * - `group`&mdash;The current group data item.
2536
+ * - `aggregates`&mdash;All aggregate values for the current group.
2537
+ *
2538
+ * @example
2539
+ * ```html
2540
+ * <kendo-grid [data]="gridData" [group]="groups">
2541
+ * <kendo-grid-column field="ProductName">
2542
+ * <ng-template kendoGridGroupFooterTemplate let-aggregates let-field="field">
2543
+ * Count: {{aggregates[field].count}}
2544
+ * </ng-template>
2545
+ * </kendo-grid-column>
2546
+ * </kendo-grid>
2547
+ * ```
2548
+ */
2549
+ class GroupFooterTemplateDirective {
2550
+ templateRef;
2551
+ constructor(templateRef) {
2552
+ this.templateRef = templateRef;
2107
2553
  }
2108
- focusAdjacentCell(fwd, wrap) {
2109
- this.focusCell();
2110
- let success = fwd ? this.moveCursorFwd() : this.moveCursorBwd();
2111
- if (wrap && !success) {
2112
- success = fwd ? this.cursor.moveDown(1) : this.cursor.moveUp(1);
2113
- if (success) {
2114
- const row = this.cursor.row;
2115
- const colIdx = fwd ? 0 : this.cursor.lastCellIndex(row);
2116
- this.cursor.reset(row.index, colIdx);
2117
- }
2118
- }
2119
- if (success) {
2120
- return this.activeCell;
2121
- }
2122
- else {
2123
- this.mode = 0 /* NavigationMode.Standby */;
2124
- this.cursor.announce();
2125
- }
2126
- return null;
2554
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: GroupFooterTemplateDirective, deps: [{ token: i0.TemplateRef, optional: true }], target: i0.ɵɵFactoryTarget.Directive });
2555
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: GroupFooterTemplateDirective, isStandalone: true, selector: "[kendoGridGroupFooterTemplate]", ngImport: i0 });
2556
+ }
2557
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: GroupFooterTemplateDirective, decorators: [{
2558
+ type: Directive,
2559
+ args: [{
2560
+ selector: '[kendoGridGroupFooterTemplate]',
2561
+ standalone: true
2562
+ }]
2563
+ }], ctorParameters: function () { return [{ type: i0.TemplateRef, decorators: [{
2564
+ type: Optional
2565
+ }] }]; } });
2566
+
2567
+ /**
2568
+ * Represents the filter-cell template.
2569
+ * Helps to customize the content of the filter cell. To define the filter cell template, nest an `<ng-template>` tag with the
2570
+ * `kendoGridFilterCellTemplate` directive inside a `<kendo-grid-column>` tag ([see example]({% slug filter_row %}#toc-custom-filters)).
2571
+ *
2572
+ * The template context is set to the current data item and the following additional fields are passed:
2573
+ * - `column`&mdash;Defines an instance of the [`ColumnComponent`]({% slug api_grid_columncomponent %}) option. Use it as an alias for a template variable by utilizing the `let-column="column"` syntax.
2574
+ * - `filter`&mdash;The provided filter descriptors. Use it as an alias for a template variable by utilizing the `let-filter="filter"` syntax.
2575
+ *
2576
+ * ```html
2577
+ * <kendo-grid-column field="CategoryID" title="Category">
2578
+ * <ng-template kendoGridFilterCellTemplate
2579
+ * let-column="column"
2580
+ * let-filter="filter"
2581
+ * >
2582
+ * ...
2583
+ * </ng-template>
2584
+ * ...
2585
+ * </kendo-grid-column>
2586
+ * ```
2587
+ */
2588
+ class FilterCellTemplateDirective {
2589
+ templateRef;
2590
+ constructor(templateRef) {
2591
+ this.templateRef = templateRef;
2127
2592
  }
2128
- enterCell() {
2129
- const cell = this.cursor.cell;
2130
- if (!cell) {
2131
- return;
2132
- }
2133
- const group = cell.focusGroup;
2134
- const focusable = group && group.canFocus();
2135
- this.mode = focusable ? 2 /* NavigationMode.Content */ : 1 /* NavigationMode.Cursor */;
2136
- this.cursor.announce();
2137
- if (focusable) {
2138
- this.activateRow();
2139
- group.focus();
2140
- }
2593
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: FilterCellTemplateDirective, deps: [{ token: i0.TemplateRef, optional: true }], target: i0.ɵɵFactoryTarget.Directive });
2594
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: FilterCellTemplateDirective, isStandalone: true, selector: "[kendoGridFilterCellTemplate]", ngImport: i0 });
2595
+ }
2596
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: FilterCellTemplateDirective, decorators: [{
2597
+ type: Directive,
2598
+ args: [{
2599
+ selector: '[kendoGridFilterCellTemplate]',
2600
+ standalone: true
2601
+ }]
2602
+ }], ctorParameters: function () { return [{ type: i0.TemplateRef, decorators: [{
2603
+ type: Optional
2604
+ }] }]; } });
2605
+
2606
+ /**
2607
+ * Represents the filter-menu template.
2608
+ * Helps to customize the content of the filter menu. To define the filter menu template, nest an `<ng-template>` tag with the
2609
+ * `kendoGridFilterMenuTemplate` directive inside a `<kendo-grid-column>` tag
2610
+ * ([see example]({% slug filter_menu %}#toc-custom-filters)).
2611
+ *
2612
+ * The template context is set to the current data item and the following additional fields are passed:
2613
+ * - `column`&mdash;Defines an instance of the [`ColumnComponent`]({% slug api_grid_columncomponent %}) option. Use it as an alias for a template variable by utilizing the `let-column="column"` syntax.
2614
+ * - `filter`&mdash;The provided filter descriptors. Use it as an alias for a template variable by utilizing the `let-filter="filter"` syntax.
2615
+ * - `filterService`&mdash;Represents the [`FilterService`]({% slug api_grid_filterservice %}). Use it as an alias for a template variable by utilizing the `let-filterService="filterService"` syntax.
2616
+ *
2617
+ * ```html
2618
+ * <kendo-grid-column field="CategoryID" title="Category">
2619
+ * <ng-template kendoGridFilterMenuTemplate
2620
+ * let-column="column"
2621
+ * let-filter="filter"
2622
+ * let-filterService="filterService"
2623
+ * >
2624
+ * ...
2625
+ * </ng-template>
2626
+ * </kendo-grid-column>
2627
+ * ```
2628
+ */
2629
+ class FilterMenuTemplateDirective {
2630
+ templateRef;
2631
+ constructor(templateRef) {
2632
+ this.templateRef = templateRef;
2141
2633
  }
2142
- leaveCell() {
2143
- const cell = this.cursor.cell;
2144
- if (!cell) {
2145
- return;
2146
- }
2147
- const group = cell.focusGroup;
2148
- const focusable = group && group.canFocus();
2149
- if (!focusable) {
2150
- this.deactivateElements();
2151
- }
2152
- this.mode = 1 /* NavigationMode.Cursor */;
2153
- this.cursor.announce();
2634
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: FilterMenuTemplateDirective, deps: [{ token: i0.TemplateRef, optional: true }], target: i0.ɵɵFactoryTarget.Directive });
2635
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: FilterMenuTemplateDirective, isStandalone: true, selector: "[kendoGridFilterMenuTemplate]", ngImport: i0 });
2636
+ }
2637
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: FilterMenuTemplateDirective, decorators: [{
2638
+ type: Directive,
2639
+ args: [{
2640
+ selector: '[kendoGridFilterMenuTemplate]',
2641
+ standalone: true
2642
+ }]
2643
+ }], ctorParameters: function () { return [{ type: i0.TemplateRef, decorators: [{
2644
+ type: Optional
2645
+ }] }]; } });
2646
+
2647
+ /**
2648
+ * @hidden
2649
+ */
2650
+ function isColumnComponent(column) {
2651
+ return isPresent(column.field);
2652
+ }
2653
+ /**
2654
+ * Represents the column of the Grid. [See example](slug:columns_config#toc-using-the-column-component)
2655
+ *
2656
+ * @example
2657
+ * ```html
2658
+ * <kendo-grid [data]="gridData">
2659
+ * <kendo-grid-column field="ProductID" title="Product ID"></kendo-grid-column>
2660
+ * <kendo-grid-column field="ProductName" title="Product Name"></kendo-grid-column>
2661
+ * <kendo-grid-column field="UnitPrice" title="Unit Price"></kendo-grid-column>
2662
+ * </kendo-grid>
2663
+ * ```
2664
+ */
2665
+ class ColumnComponent extends ColumnBase {
2666
+ /**
2667
+ * The field to which the column is bound.
2668
+ */
2669
+ field;
2670
+ /**
2671
+ * The format that is applied to the value before it is displayed. For more information on the supported date and number formats,
2672
+ * refer to the [Column Formats](slug:formats_columns_grid) documentation article.
2673
+ */
2674
+ format;
2675
+ /**
2676
+ * Allows the user to click the column headers and emits the `sortChange` event. [See example](slug:sorting_grid).
2677
+ *
2678
+ * @default true
2679
+ */
2680
+ sortable = true;
2681
+ /**
2682
+ * Determines if the column can be dragged to the group panel.
2683
+ * If set to `false`, you can group the columns by the column field by using the API of the Grid.
2684
+ *
2685
+ * @default true
2686
+ */
2687
+ groupable = true;
2688
+ /**
2689
+ * Defines the editor type. [See example](slug:inline_editing_grid#toc-using-reactive-forms).
2690
+ * Used when the column enters the edit mode.
2691
+ *
2692
+ * @default 'text'
2693
+ */
2694
+ editor = 'text';
2695
+ /**
2696
+ * Defines the filter type that is displayed inside the filter row. [See example](slug:filtering_grid#toc-filter-data-types).
2697
+ *
2698
+ * @default 'text'
2699
+ */
2700
+ filter = 'text';
2701
+ /**
2702
+ * Defines if a filter UI will be displayed for this column. [See example](slug:filtering_grid).
2703
+ *
2704
+ * @default true
2705
+ */
2706
+ filterable = true;
2707
+ /**
2708
+ * Defines whether the column is editable. [See example](slug:make_fields_uneditable_grid).
2709
+ *
2710
+ * @default true
2711
+ */
2712
+ editable = true;
2713
+ template;
2714
+ groupHeaderTemplate;
2715
+ groupHeaderColumnTemplate;
2716
+ groupFooterTemplate;
2717
+ editTemplate;
2718
+ filterCellTemplate;
2719
+ filterMenuTemplate;
2720
+ constructor(parent, idService) {
2721
+ super(parent, idService);
2154
2722
  }
2155
- activateElements() {
2156
- this.focusRoot.activate();
2723
+ get templateRef() {
2724
+ return this.template ? this.template.templateRef : undefined;
2157
2725
  }
2158
- deactivateElements() {
2159
- this.focusRoot.deactivate();
2726
+ get groupHeaderTemplateRef() {
2727
+ return this.groupHeaderTemplate ? this.groupHeaderTemplate.templateRef : undefined;
2160
2728
  }
2161
- activateRow() {
2162
- this.cursor.row.cells
2163
- .forEach(cell => cell.focusGroup && cell.focusGroup.activate());
2729
+ get groupHeaderColumnTemplateRef() {
2730
+ return this.groupHeaderColumnTemplate ? this.groupHeaderColumnTemplate.templateRef : undefined;
2164
2731
  }
2165
- moveCursorFwd() {
2166
- return this.ctx.localization.rtl ? this.cursor.moveLeft() : this.cursor.moveRight();
2732
+ get groupFooterTemplateRef() {
2733
+ return this.groupFooterTemplate ? this.groupFooterTemplate.templateRef : undefined;
2167
2734
  }
2168
- moveCursorBwd() {
2169
- return this.ctx.localization.rtl ? this.cursor.moveRight() : this.cursor.moveLeft();
2735
+ get editTemplateRef() {
2736
+ return this.editTemplate ? this.editTemplate.templateRef : undefined;
2170
2737
  }
2171
- onCursorKeydown(args) {
2172
- let preventDefault = false;
2173
- const modifier = args.ctrlKey || args.metaKey;
2174
- const step = modifier ? 5 : 1;
2175
- if (!this.onCellKeydown(args)) {
2176
- return;
2177
- }
2178
- const row = this.cursor.row;
2179
- switch (args.keyCode) {
2180
- case Keys.ArrowDown:
2181
- if (args.shiftKey) {
2182
- if (this.ctx.grid.blockArrowSelection) {
2183
- return;
2184
- }
2185
- preventDefault = this.cursor.moveDown(step);
2186
- if (this.activeRow?.dataItem) {
2187
- this.handleVerticalArrowSelection(step);
2188
- }
2189
- }
2190
- else {
2191
- preventDefault = this.cursor.moveDown(step);
2192
- }
2193
- break;
2194
- case Keys.ArrowUp:
2195
- if (args.shiftKey) {
2196
- if (this.ctx.grid.blockArrowSelection) {
2197
- return;
2198
- }
2199
- preventDefault = this.cursor.moveUp(step);
2200
- if (this.activeRow?.dataItem) {
2201
- this.handleVerticalArrowSelection(-step);
2202
- }
2203
- }
2204
- else {
2205
- preventDefault = this.cursor.moveUp(step);
2206
- }
2207
- break;
2208
- case Keys.ArrowRight:
2209
- if (args.shiftKey) {
2210
- if (this.ctx.grid.blockArrowSelection) {
2211
- return;
2212
- }
2213
- preventDefault = this.moveCursorFwd();
2214
- this.handleHorizontalArrowSelection(args);
2215
- }
2216
- else {
2217
- preventDefault = this.moveCursorFwd();
2218
- }
2219
- break;
2220
- case Keys.ArrowLeft:
2221
- if (args.shiftKey) {
2222
- if (this.ctx.grid.blockArrowSelection) {
2223
- return;
2224
- }
2225
- preventDefault = this.moveCursorBwd();
2226
- this.handleHorizontalArrowSelection(args);
2227
- }
2228
- else {
2229
- preventDefault = this.moveCursorBwd();
2230
- }
2231
- break;
2232
- case Keys.PageDown:
2233
- if (this.metadata.isVirtual && this.viewport) {
2234
- let nextItemIndex = this.meta.headerRows + this.viewport.lastItemIndex + 1;
2235
- if (this.metadata.hasDetailTemplate) {
2236
- nextItemIndex++;
2237
- }
2238
- nextItemIndex = Math.min(this.meta.maxLogicalRowIndex, nextItemIndex);
2239
- this.cursor.reset(nextItemIndex);
2240
- preventDefault = true;
2241
- }
2242
- else if (this.metadata.hasPager) {
2243
- this.zone.run(() => this.pagerContextService.nextPage());
2244
- preventDefault = true;
2245
- }
2246
- break;
2247
- case Keys.PageUp:
2248
- if (this.metadata.isVirtual && this.viewport) {
2249
- const viewportSize = this.viewport.lastItemIndex - this.viewport.firstItemIndex;
2250
- const firstItemIndex = this.viewport.firstItemIndex;
2251
- const nextItemIndex = Math.max(this.meta.headerRows, firstItemIndex - viewportSize - 1);
2252
- this.cursor.reset(nextItemIndex);
2253
- preventDefault = true;
2254
- }
2255
- else if (this.metadata.hasPager) {
2256
- this.zone.run(() => this.pagerContextService.prevPage());
2257
- preventDefault = true;
2258
- }
2259
- break;
2260
- case Keys.Home:
2261
- if (modifier) {
2262
- if (this.meta.isVirtual) {
2263
- this.cursor.reset(this.meta.headerRows, 0, false);
2264
- }
2265
- else {
2266
- this.cursor.reset(this.model.firstRow.index, 0, false);
2267
- }
2268
- }
2269
- else {
2270
- let firstColumnIndex = 0;
2271
- if (this.meta.hasDetailTemplate && row.index < this.meta.headerRows) {
2272
- firstColumnIndex = 1;
2273
- }
2274
- this.cursor.reset(row.index, firstColumnIndex, false);
2275
- }
2276
- preventDefault = true;
2277
- break;
2278
- case Keys.End:
2279
- if (modifier) {
2280
- if (this.meta.isVirtual) {
2281
- let lastRowIndex = this.meta.maxLogicalRowIndex;
2282
- if (this.meta.hasDetailTemplate) {
2283
- lastRowIndex--;
2284
- }
2285
- this.cursor.reset(lastRowIndex, this.cursor.lastCellIndex(), false);
2286
- }
2287
- else {
2288
- this.cursor.reset(this.model.lastRow.index, this.cursor.lastCellIndex(this.model.lastRow), false);
2289
- }
2290
- }
2291
- else {
2292
- const lastIndex = this.cursor.lastCellIndex(row);
2293
- const cell = this.model.findCell(lastIndex, row);
2294
- if (cell) {
2295
- this.cursor.reset(cell.rowIndex, cell.colIndex);
2296
- }
2297
- else {
2298
- this.cursor.reset(row.index, lastIndex);
2299
- }
2300
- }
2301
- preventDefault = true;
2302
- break;
2303
- case Keys.Enter:
2304
- case Keys.F2: {
2305
- const groupItem = row.groupItem;
2306
- if (groupItem) {
2307
- this.zone.run(() => this.groupsService.toggleRow(groupItem));
2308
- }
2309
- else if (this.cursor.cell.detailExpandCell) {
2310
- this.zone.run(() => this.detailsService.toggleRow(row.dataRowIndex, row.dataItem));
2311
- }
2312
- else {
2313
- this.enterCell();
2314
- if (!this.cursor.cell.focusGroup.isNavigable()) {
2315
- preventDefault = true;
2316
- }
2317
- }
2318
- break;
2319
- }
2320
- default:
2321
- if (!args.ctrlKey && !args.altKey && isPrintableCharacter(args.key)) {
2322
- this.enterCell();
2323
- }
2324
- }
2325
- if (preventDefault) {
2326
- args.preventDefault();
2327
- }
2328
- }
2329
- onContentKeydown(args) {
2330
- if (!this.onCellKeydown(args)) {
2331
- return;
2332
- }
2333
- const confirm = !args.defaultPrevented && args.keyCode === Keys.Enter && isTextInput(args.srcElement);
2334
- if (args.keyCode === Keys.Escape || args.keyCode === Keys.F2 || confirm) {
2335
- this.leaveCell();
2336
- this.cursor.reset();
2337
- args.stopPropagation();
2338
- }
2339
- else if (isNavigationKey(args.keyCode) && this.cursor.cell.focusGroup.isNavigable()) {
2340
- this.onCursorKeydown(args);
2341
- if (args.defaultPrevented) {
2342
- this.leaveCell();
2343
- }
2344
- }
2345
- }
2346
- onCellKeydown(args) {
2347
- if (this.editService.isEditingCell()) {
2348
- const confirm = args.keyCode === Keys.Enter;
2349
- const cancel = args.keyCode === Keys.Escape;
2350
- const navigate = isNavigationKey(args.keyCode);
2351
- if (confirm) {
2352
- this.editService.closeCell(args);
2353
- }
2354
- else if (cancel) {
2355
- this.editService.closeCell(args);
2356
- this.cd.detectChanges();
2357
- }
2358
- else if (navigate) {
2359
- return false;
2360
- }
2361
- }
2362
- this.cellKeydown.emit(args);
2363
- return true;
2364
- }
2365
- onCursorChanges(args) {
2366
- this.activeRowIndex = args.rowIndex;
2367
- const dataRowIndex = this.activeDataRow;
2368
- if (this.meta && (this.meta.isVirtual &&
2369
- args.rowIndex >= this.meta.headerRows &&
2370
- this.viewport &&
2371
- !this.viewport.containsRow(dataRowIndex) && dataRowIndex > -1)) {
2372
- this.scrollRequestService.scrollTo({ row: dataRowIndex });
2373
- }
2374
- if (this.meta.virtualColumns && args.colIndex >= this.meta.columns.lockedLeafColumns.length) {
2375
- const cell = this.activeCell;
2376
- const { start, end } = this.model.cellRange(cell);
2377
- if (!cell) {
2378
- this.virtualCell = true;
2379
- }
2380
- if ((!cell && this.mode !== 0 /* NavigationMode.Standby */) || (cell && !this.columnViewport.intersects(start, end))) {
2381
- this.scrollRequestService.scrollTo({ column: args.colIndex - (this.metadata.hasDetailTemplate ? 1 : 0) });
2382
- }
2383
- }
2384
- }
2385
- onFocusOut(args) {
2386
- if (isVisible(args.target)) {
2387
- this.mode = 0 /* NavigationMode.Standby */;
2388
- }
2389
- else {
2390
- // Focused target is no longer visible,
2391
- // reset to cursor mode and recapture focus.
2392
- this.mode = 1 /* NavigationMode.Cursor */;
2393
- }
2394
- this.deactivateElements();
2395
- this.cursor.announce();
2396
- }
2397
- onWindowBlur() {
2398
- this.mode = 0 /* NavigationMode.Standby */;
2399
- this.deactivateElements();
2400
- this.cursor.announce();
2738
+ get filterCellTemplateRef() {
2739
+ return this.filterCellTemplate ? this.filterCellTemplate.templateRef : undefined;
2401
2740
  }
2402
- onKeydown(args) {
2403
- if (this.mode === 1 /* NavigationMode.Cursor */) {
2404
- this.onCursorKeydown(args);
2405
- }
2406
- else if (this.mode === 2 /* NavigationMode.Content */) {
2407
- this.onContentKeydown(args);
2408
- }
2741
+ get filterMenuTemplateRef() {
2742
+ return this.filterMenuTemplate ? this.filterMenuTemplate.templateRef : undefined;
2409
2743
  }
2410
- onTabout() {
2411
- // Tabbed out of the last focusable content element
2412
- // reset to cursor mode and recapture focus.
2413
- if (this.cursor.cell.focusGroup.isNavigable()) {
2414
- // Unless the cell has a single focusable element,
2415
- // otherwise we'd return to Content mode and enter an endless loop
2416
- return;
2417
- }
2418
- this.leaveCell();
2419
- this.cursor.reset();
2744
+ get displayTitle() {
2745
+ return this.title === undefined ? this.field : this.title;
2420
2746
  }
2421
- handleVerticalArrowSelection(args) {
2422
- const cellSelectionEnabled = this.ctx.grid.cellSelectionService.active;
2423
- const rowSelectionEnabled = this.ctx.grid.selectionService.active && !this.ctx.grid.selectableSettings.checkboxOnly;
2424
- if (cellSelectionEnabled || rowSelectionEnabled) {
2425
- const selectionService = this.ctx.grid[cellSelectionEnabled ? 'cellSelectionService' : 'selectionService'];
2426
- const colIdx = this.cursor.cell ? this.cursor.cell.colIndex : 0;
2427
- const rowIdx = this.activeRow.dataRowIndex - this.ctx.grid.skip;
2428
- const dataItem = selectionService.settings.view.at(rowIdx);
2429
- const item = { index: this.activeRow.dataRowIndex, data: dataItem, column: this.ctx.grid.columnsContainer.leafColumnsToRender[colIdx] };
2430
- if (selectionService.options.mode === 'multiple') {
2431
- cellSelectionEnabled ? this.handleMultipleArrowCellSelection(item) : this.handleMultipleArrowRowSelection(item);
2432
- }
2433
- else {
2434
- selectionService.handleClick(item, args);
2747
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ColumnComponent, deps: [{ token: ColumnBase, host: true, optional: true, skipSelf: true }, { token: IdService, optional: true }], target: i0.ɵɵFactoryTarget.Component });
2748
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: ColumnComponent, isStandalone: true, selector: "kendo-grid-column", inputs: { field: "field", format: "format", sortable: "sortable", groupable: "groupable", editor: "editor", filter: "filter", filterable: "filterable", editable: "editable" }, providers: [
2749
+ {
2750
+ provide: ColumnBase,
2751
+ useExisting: forwardRef(() => ColumnComponent)
2435
2752
  }
2436
- }
2437
- }
2438
- handleHorizontalArrowSelection(args) {
2439
- const cellSelectionEnabled = this.ctx.grid.cellSelectionService.active;
2440
- if (cellSelectionEnabled) {
2441
- const selectionService = this.ctx.grid[cellSelectionEnabled ? 'cellSelectionService' : 'selectionService'];
2442
- const row = this.activeRow;
2443
- const colIdx = this.cursor.cell ? this.cursor.cell.colIndex : 0;
2444
- const dataItem = selectionService.settings.view.at(row.dataRowIndex - this.ctx.grid.skip);
2445
- const item = { index: row.dataRowIndex, data: dataItem, column: this.ctx.grid.columnsContainer.leafColumnsToRender[colIdx] };
2446
- if (!isPresent$1(dataItem) || !isPresent$1(item.column)) {
2447
- return;
2448
- }
2449
- if (selectionService.options.mode === 'multiple') {
2450
- this.handleMultipleArrowCellSelection(item);
2451
- }
2452
- else {
2453
- selectionService.handleClick(item, args);
2454
- }
2455
- }
2456
- }
2457
- handleMultipleArrowCellSelection(item) {
2458
- const cellSelectionService = this.ctx.grid.cellSelectionService;
2459
- const startRowIndex = Math.min(cellSelectionService.lastSelectionItemRowIndex, item.index);
2460
- const startColIndex = Math.min(cellSelectionService.lastSelectionItemColIndex, item.column.leafIndex);
2461
- const endRowIndex = Math.max(cellSelectionService.lastSelectionItemRowIndex, item.index);
2462
- const endColIndex = Math.max(cellSelectionService.lastSelectionItemColIndex, item.column.leafIndex);
2463
- const ev = cellSelectionService.selectRange(startRowIndex, startColIndex, endRowIndex, endColIndex);
2464
- cellSelectionService.changes.emit(ev);
2465
- }
2466
- handleMultipleArrowRowSelection(item) {
2467
- const rowSelectionService = this.ctx.grid.selectionService;
2468
- const startRowIndex = Math.min(rowSelectionService.lastSelectionStartIndex, item.index);
2469
- const endRowIndex = Math.max(rowSelectionService.lastSelectionStartIndex, item.index);
2470
- const ev = rowSelectionService.selectRange(startRowIndex, endRowIndex);
2471
- rowSelectionService.changes.emit(ev);
2472
- }
2473
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: NavigationService, deps: [{ token: i0.NgZone }, { token: DomEventsService }, { token: i44.PagerContextService }, { token: ScrollRequestService }, { token: GroupsService }, { token: DetailsService }, { token: FocusRoot }, { token: EditService }, { token: i0.ChangeDetectorRef }, { token: ContextService }, { token: FocusableDirective, optional: true }], target: i0.ɵɵFactoryTarget.Injectable });
2474
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: NavigationService });
2753
+ ], queries: [{ propertyName: "template", first: true, predicate: CellTemplateDirective, descendants: true }, { propertyName: "groupHeaderTemplate", first: true, predicate: GroupHeaderTemplateDirective, descendants: true }, { propertyName: "groupHeaderColumnTemplate", first: true, predicate: GroupHeaderColumnTemplateDirective, descendants: true }, { propertyName: "groupFooterTemplate", first: true, predicate: GroupFooterTemplateDirective, descendants: true }, { propertyName: "editTemplate", first: true, predicate: EditTemplateDirective, descendants: true }, { propertyName: "filterCellTemplate", first: true, predicate: FilterCellTemplateDirective, descendants: true }, { propertyName: "filterMenuTemplate", first: true, predicate: FilterMenuTemplateDirective, descendants: true }], usesInheritance: true, ngImport: i0, template: ``, isInline: true });
2475
2754
  }
2476
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: NavigationService, decorators: [{
2477
- type: Injectable
2478
- }], ctorParameters: function () { return [{ type: i0.NgZone }, { type: DomEventsService }, { type: i44.PagerContextService }, { type: ScrollRequestService }, { type: GroupsService }, { type: DetailsService }, { type: FocusRoot }, { type: EditService }, { type: i0.ChangeDetectorRef }, { type: ContextService }, { type: FocusableDirective, decorators: [{
2755
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ColumnComponent, decorators: [{
2756
+ type: Component,
2757
+ args: [{
2758
+ providers: [
2759
+ {
2760
+ provide: ColumnBase,
2761
+ useExisting: forwardRef(() => ColumnComponent)
2762
+ }
2763
+ ],
2764
+ selector: 'kendo-grid-column',
2765
+ template: ``,
2766
+ standalone: true
2767
+ }]
2768
+ }], ctorParameters: function () { return [{ type: ColumnBase, decorators: [{
2769
+ type: SkipSelf
2770
+ }, {
2771
+ type: Host
2772
+ }, {
2479
2773
  type: Optional
2480
- }] }]; } });
2774
+ }] }, { type: IdService, decorators: [{
2775
+ type: Optional
2776
+ }] }]; }, propDecorators: { field: [{
2777
+ type: Input
2778
+ }], format: [{
2779
+ type: Input
2780
+ }], sortable: [{
2781
+ type: Input
2782
+ }], groupable: [{
2783
+ type: Input
2784
+ }], editor: [{
2785
+ type: Input
2786
+ }], filter: [{
2787
+ type: Input
2788
+ }], filterable: [{
2789
+ type: Input
2790
+ }], editable: [{
2791
+ type: Input
2792
+ }], template: [{
2793
+ type: ContentChild,
2794
+ args: [CellTemplateDirective, { static: false }]
2795
+ }], groupHeaderTemplate: [{
2796
+ type: ContentChild,
2797
+ args: [GroupHeaderTemplateDirective, { static: false }]
2798
+ }], groupHeaderColumnTemplate: [{
2799
+ type: ContentChild,
2800
+ args: [GroupHeaderColumnTemplateDirective, { static: false }]
2801
+ }], groupFooterTemplate: [{
2802
+ type: ContentChild,
2803
+ args: [GroupFooterTemplateDirective, { static: false }]
2804
+ }], editTemplate: [{
2805
+ type: ContentChild,
2806
+ args: [EditTemplateDirective, { static: false }]
2807
+ }], filterCellTemplate: [{
2808
+ type: ContentChild,
2809
+ args: [FilterCellTemplateDirective, { static: false }]
2810
+ }], filterMenuTemplate: [{
2811
+ type: ContentChild,
2812
+ args: [FilterMenuTemplateDirective, { static: false }]
2813
+ }] } });
2481
2814
 
2482
2815
  /**
2483
2816
  * @hidden
2484
2817
  */
2485
- const preventOnDblClick$1 = release => mouseDown => of(mouseDown).pipe(delay(150), takeUntil(release));
2486
- const hasClass = className => el => new RegExp(`(^| )${className}( |$)`).test(el.className);
2487
- const isDeleteButton = or(hasClass('k-i-x'), hasClass('k-svg-i-x'), hasClass('k-icon-button'));
2488
- const isSortIcon = or(hasClass('k-i-sort-asc-small'), hasClass('k-i-sort-desc-small'), hasClass('k-svg-i-sort-asc-small'), hasClass('k-svg-i-sort-desc-small'));
2489
- const skipButtons = and(not(isDeleteButton), not(isSortIcon), not(isFocusableWithTabKey), not(matchesNodeName('label')));
2490
- const elementUnderCursor = ({ clientX, clientY }) => isDocumentAvailable() && document.elementFromPoint(clientX, clientY);
2491
- const hideThenShow = (element, cont) => {
2492
- element.style.display = 'none';
2493
- const result = cont();
2494
- element.style.display = 'block';
2495
- return result;
2496
- };
2818
+ function isSpanColumnComponent(column) {
2819
+ return column.isSpanColumn;
2820
+ }
2497
2821
  /**
2498
- * @hidden
2822
+ * Represents a column which can be spanned over multiple data cells while the individual
2823
+ * header and footer cells are retained ([see example]({% slug spanned_columns_grid %})).
2824
+ * Enables you to achieve more flexible layout while keeping the built-in UI element for
2825
+ * [sorting]({% slug sorting_grid %}), [filtering]({% slug filtering_grid %}), and
2826
+ * [grouping]({% slug grouping_grid %}). Wrap the columns that will be
2827
+ * merged inside the `<kendo-grid-span-column>` tag.
2828
+ *
2829
+ * ```html
2830
+ * <kendo-grid-span-column>
2831
+ * <kendo-grid-column field="field1"></kendo-grid-column>
2832
+ * <kendo-grid-column field="field2"></kendo-grid-column>
2833
+ * <ng-template kendoGridCellTemplate let-dataItem>
2834
+ * <h5>{{ dataItem.field1 }}</h5>
2835
+ * <p>{{ dataItem.field2 }}</p>
2836
+ * </ng-template>
2837
+ * </kendo-grid-span-column>
2838
+ * ```
2499
2839
  */
2500
- class DraggableColumnDirective {
2501
- draggable;
2502
- element;
2503
- zone;
2504
- service;
2505
- hint;
2506
- cue;
2507
- nav;
2508
- renderer;
2509
- context = {};
2510
- set enableDrag(enabled) {
2511
- this.enabled = enabled;
2512
- this.updateTouchAction();
2840
+ class SpanColumnComponent extends ColumnBase {
2841
+ /*
2842
+ * @hidden
2843
+ */
2844
+ isSpanColumn = true;
2845
+ template = new QueryList();
2846
+ editTemplate = new QueryList();
2847
+ /**
2848
+ * @hidden
2849
+ */
2850
+ childColumns = new QueryList();
2851
+ /**
2852
+ * @hidden
2853
+ */
2854
+ title;
2855
+ /**
2856
+ * @hidden
2857
+ */
2858
+ headerStyle;
2859
+ /**
2860
+ * @hidden
2861
+ */
2862
+ footerStyle;
2863
+ /**
2864
+ * @hidden
2865
+ */
2866
+ headerClass;
2867
+ /**
2868
+ * @hidden
2869
+ */
2870
+ footerClass;
2871
+ /**
2872
+ * @hidden
2873
+ */
2874
+ includeInChooser = false;
2875
+ /**
2876
+ * Defines whether the edit template of the column will be rendered.
2877
+ * To enable the editing functionality for a spanned column, set an edit template for it ([see example](slug:custom_reactive_editing_grid)).
2878
+ * @default false
2879
+ */
2880
+ set editable(value) {
2881
+ this._editable = value;
2513
2882
  }
2514
- drag = new EventEmitter();
2515
- subscriptions = new Subscription();
2516
- enabled;
2517
- constructor(draggable, element, zone, service, hint, cue, nav, renderer) {
2518
- this.draggable = draggable;
2519
- this.element = element;
2520
- this.zone = zone;
2521
- this.service = service;
2522
- this.hint = hint;
2523
- this.cue = cue;
2524
- this.nav = nav;
2525
- this.renderer = renderer;
2883
+ get editable() {
2884
+ return isPresent(this.editTemplateRef) && this._editable;
2526
2885
  }
2527
- ngOnInit() {
2528
- this.subscriptions.add(this.zone.runOutsideAngular(() => this.draggable.kendoPress.pipe(filter(_ => this.enabled), filter(({ originalEvent: { target } }) => target === this.element.nativeElement || skipButtons(target)), tap((e) => {
2529
- const originalEvent = e.originalEvent;
2530
- if (!e.isTouch) {
2531
- originalEvent.preventDefault();
2532
- }
2533
- this.nav.navigateTo(originalEvent.target);
2534
- }), switchMap(preventOnDblClick$1(this.draggable.kendoRelease)), tap((_) => {
2535
- this.hint.create(this.context.hint);
2536
- this.cue.create();
2537
- }), switchMap(down => this.draggable.kendoDrag.pipe(tap((e) => {
2538
- if (e.isTouch) {
2539
- e.originalEvent.preventDefault();
2540
- }
2541
- }), tap(this.hint.attach()), tap(this.cue.attach()), takeUntil(this.draggable.kendoRelease), map(move => ({ move, down })))), tap(this.performDrag.bind(this)), switchMapTo(this.draggable.kendoRelease)).subscribe(this.drop.bind(this))));
2886
+ /**
2887
+ * @hidden
2888
+ * added for backwards compitability
2889
+ */
2890
+ set width(_value) {
2542
2891
  }
2543
- ngOnDestroy() {
2544
- if (this.subscriptions) {
2545
- this.subscriptions.unsubscribe();
2546
- }
2892
+ get width() {
2893
+ return this.childColumns.reduce((total, column) => total + column.width, 0);
2547
2894
  }
2548
- drop(upEvent) {
2549
- this.hint.remove();
2550
- this.cue.remove();
2551
- this.service.notifyDrop(this, upEvent);
2895
+ /**
2896
+ * @hidden
2897
+ */
2898
+ get leafIndex() {
2899
+ return this.childColumns.first.leafIndex;
2552
2900
  }
2553
- performDrag({ move }) {
2554
- this.hint.move(move);
2555
- const cursorElement = this.elementUnderCursor(move);
2556
- if (cursorElement) {
2557
- this.service.notifyDrag(this, cursorElement, move);
2901
+ _editable = true;
2902
+ constructor(parent, idService) {
2903
+ super(parent, idService);
2904
+ if (parent && parent.isSpanColumn) {
2905
+ throw new Error(ColumnConfigurationErrorMessages.nestedInside('SpanColumnComponent', 'SpanColumnComponent'));
2558
2906
  }
2559
- this.drag.emit({
2560
- draggable: this,
2561
- mouseEvent: move
2562
- });
2563
2907
  }
2564
- elementUnderCursor(mouseEvent) {
2565
- this.hint.hide();
2566
- let target = elementUnderCursor(mouseEvent);
2567
- if (target && /k-grouping-dropclue/.test(target.className)) {
2568
- target = hideThenShow(target, elementUnderCursor.bind(this, mouseEvent));
2569
- }
2570
- this.hint.show();
2571
- return target;
2908
+ /**
2909
+ * @hidden
2910
+ */
2911
+ get templateRef() {
2912
+ const template = this.template.first;
2913
+ return template ? template.templateRef : undefined;
2572
2914
  }
2573
- updateTouchAction() {
2574
- if (!this.element) {
2575
- return;
2576
- }
2577
- // eslint-disable-next-line no-unused-expressions
2578
- this.enabled ? this.renderer.addClass(this.element.nativeElement, 'k-touch-action-none') :
2579
- this.renderer.removeClass(this.element.nativeElement, 'k-touch-action-none');
2915
+ /**
2916
+ * @hidden
2917
+ */
2918
+ get editTemplateRef() {
2919
+ const editTemplate = this.editTemplate.first;
2920
+ return editTemplate ? editTemplate.templateRef : undefined;
2580
2921
  }
2581
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DraggableColumnDirective, deps: [{ token: i1$3.DraggableDirective, host: true }, { token: i0.ElementRef }, { token: i0.NgZone }, { token: DragAndDropService }, { token: DragHintService }, { token: DropCueService }, { token: NavigationService }, { token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Directive });
2582
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: DraggableColumnDirective, isStandalone: true, selector: "[kendoDraggableColumn]", inputs: { context: "context", enableDrag: "enableDrag" }, outputs: { drag: "drag" }, ngImport: i0 });
2922
+ /**
2923
+ * @hidden
2924
+ */
2925
+ get colspan() {
2926
+ return this.childColumns.filter(c => c.isVisible).length;
2927
+ }
2928
+ /**
2929
+ * Toggles the locked (frozen) state of the columns ([see example](slug:locked_columns_grid)).
2930
+ * @default false
2931
+ */
2932
+ set locked(value) {
2933
+ this._locked = value;
2934
+ }
2935
+ get locked() {
2936
+ return this._locked || this.childColumns.some(c => c.locked);
2937
+ }
2938
+ get childrenArray() {
2939
+ return this.childColumns.toArray();
2940
+ }
2941
+ get hasChildren() {
2942
+ return this.childColumns.length > 0;
2943
+ }
2944
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: SpanColumnComponent, deps: [{ token: ColumnBase, host: true, optional: true, skipSelf: true }, { token: IdService, optional: true }], target: i0.ɵɵFactoryTarget.Component });
2945
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: SpanColumnComponent, isStandalone: true, selector: "kendo-grid-span-column", inputs: { editable: "editable", locked: "locked" }, providers: [
2946
+ {
2947
+ provide: ColumnBase,
2948
+ useExisting: forwardRef(() => SpanColumnComponent)
2949
+ }
2950
+ ], queries: [{ propertyName: "template", predicate: CellTemplateDirective }, { propertyName: "editTemplate", predicate: EditTemplateDirective }, { propertyName: "childColumns", predicate: ColumnComponent }], usesInheritance: true, ngImport: i0, template: ``, isInline: true });
2583
2951
  }
2584
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DraggableColumnDirective, decorators: [{
2585
- type: Directive,
2952
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: SpanColumnComponent, decorators: [{
2953
+ type: Component,
2586
2954
  args: [{
2587
- selector: '[kendoDraggableColumn]',
2955
+ providers: [
2956
+ {
2957
+ provide: ColumnBase,
2958
+ useExisting: forwardRef(() => SpanColumnComponent)
2959
+ }
2960
+ ],
2961
+ selector: 'kendo-grid-span-column',
2962
+ template: ``,
2588
2963
  standalone: true
2589
2964
  }]
2590
- }], ctorParameters: function () { return [{ type: i1$3.DraggableDirective, decorators: [{
2965
+ }], ctorParameters: function () { return [{ type: ColumnBase, decorators: [{
2966
+ type: SkipSelf
2967
+ }, {
2591
2968
  type: Host
2592
- }] }, { type: i0.ElementRef }, { type: i0.NgZone }, { type: DragAndDropService }, { type: DragHintService }, { type: DropCueService }, { type: NavigationService }, { type: i0.Renderer2 }]; }, propDecorators: { context: [{
2969
+ }, {
2970
+ type: Optional
2971
+ }] }, { type: IdService, decorators: [{
2972
+ type: Optional
2973
+ }] }]; }, propDecorators: { template: [{
2974
+ type: ContentChildren,
2975
+ args: [CellTemplateDirective, { descendants: false }]
2976
+ }], editTemplate: [{
2977
+ type: ContentChildren,
2978
+ args: [EditTemplateDirective, { descendants: false }]
2979
+ }], childColumns: [{
2980
+ type: ContentChildren,
2981
+ args: [ColumnComponent]
2982
+ }], editable: [{
2593
2983
  type: Input
2594
- }], enableDrag: [{
2984
+ }], locked: [{
2595
2985
  type: Input
2596
- }], drag: [{
2597
- type: Output
2598
2986
  }] } });
2599
2987
 
2600
2988
  /**
2601
2989
  * @hidden
2602
2990
  */
2603
- class DropTargetDirective {
2604
- element;
2605
- service;
2606
- context = {};
2607
- enter = new EventEmitter();
2608
- leave = new EventEmitter();
2609
- drop = new EventEmitter();
2610
- subscriptions = new Subscription();
2611
- constructor(element, service) {
2612
- this.element = element;
2613
- this.service = service;
2614
- }
2615
- ngOnInit() {
2616
- this.service.add(this);
2617
- const changes = this.service.changes.pipe(filter(({ target }) => target === this));
2618
- this.subscriptions.add(changes.pipe(filter(({ type }) => type === 'leave'))
2619
- .subscribe(e => {
2620
- this.leave.next(this.eventArgs(e));
2621
- }));
2622
- this.subscriptions.add(changes.pipe(filter(({ type }) => type === 'enter'))
2623
- .subscribe(e => {
2624
- this.enter.next(this.eventArgs(e));
2625
- }));
2626
- this.subscriptions.add(changes.pipe(filter(({ type }) => type === 'drop'))
2627
- .subscribe(e => {
2628
- this.drop.next(this.eventArgs(e));
2629
- }));
2630
- }
2631
- ngOnDestroy() {
2632
- if (this.subscriptions) {
2633
- this.subscriptions.unsubscribe();
2634
- }
2635
- }
2636
- eventArgs(e) {
2637
- return {
2638
- target: this,
2639
- mouseEvent: e.mouseEvent,
2640
- draggable: e.draggable
2641
- };
2642
- }
2643
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DropTargetDirective, deps: [{ token: i0.ElementRef }, { token: DragAndDropService }], target: i0.ɵɵFactoryTarget.Directive });
2644
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: DropTargetDirective, isStandalone: true, selector: "[kendoDropTarget]", inputs: { context: "context" }, outputs: { enter: "enter", leave: "leave", drop: "drop" }, ngImport: i0 });
2645
- }
2646
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DropTargetDirective, decorators: [{
2647
- type: Directive,
2648
- args: [{
2649
- selector: '[kendoDropTarget]',
2650
- standalone: true
2651
- }]
2652
- }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: DragAndDropService }]; }, propDecorators: { context: [{
2653
- type: Input
2654
- }], enter: [{
2655
- type: Output
2656
- }], leave: [{
2657
- type: Output
2658
- }], drop: [{
2659
- type: Output
2660
- }] } });
2661
-
2991
+ const expandColumns = (columns) => (columns.reduce((acc, column) => acc.concat(isSpanColumnComponent(column) ? column.childrenArray : [column]), []));
2662
2992
  /**
2663
- * Represents the column cell template of the Grid.
2664
- * Helps to customize the content of the cells. To define the cell template, nest an `<ng-template>` tag with the
2665
- * `kendoGridCellTemplate` directive inside a `<kendo-grid-column>` tag [see example](slug:templates_columns_grid#toc-cell-template).
2666
- *
2667
- * The template context is set to the current data item and the following additional fields are passed:
2668
- * - `columnIndex`&mdash;The current column index. Use it as an alias for a template variable by utilizing the `let-columnIndex="columnIndex"` syntax.
2669
- * - `rowIndex`&mdash;The current data row index. Use it as an alias for a template variable by utilizing the `let-rowIndex="rowIndex"` syntax.
2670
- * - `dataItem`&mdash;The current data item. Represents the default context that will be assigned to any template variable which utilizes the `let-x` syntax&mdash;for example, `let-dataItem`.
2671
- * - `column`&mdash;The current column instance. Use it as an alias for a template variable by utilizing the `let-column="column"` syntax.
2672
- *
2673
- * @example
2674
- * ```html
2675
- * <kendo-grid [data]="gridData" ...>
2676
- * <kendo-grid-column field="ProductName">
2677
- * <ng-template kendoGridCellTemplate let-dataItem let-rowIndex="rowIndex" let-column="column">
2678
- * Data Row: {{rowIndex}}
2679
- * </ng-template>
2680
- * </kendo-grid-column>
2681
- * </kendo-grid>
2682
- * ```
2993
+ * @hidden
2683
2994
  */
2684
- class CellTemplateDirective {
2685
- templateRef;
2686
- constructor(templateRef) {
2687
- this.templateRef = templateRef;
2688
- }
2689
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: CellTemplateDirective, deps: [{ token: i0.TemplateRef, optional: true }], target: i0.ɵɵFactoryTarget.Directive });
2690
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: CellTemplateDirective, isStandalone: true, selector: "[kendoGridCellTemplate]", ngImport: i0 });
2691
- }
2692
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: CellTemplateDirective, decorators: [{
2693
- type: Directive,
2694
- args: [{
2695
- selector: '[kendoGridCellTemplate]',
2696
- standalone: true
2697
- }]
2698
- }], ctorParameters: function () { return [{ type: i0.TemplateRef, decorators: [{
2699
- type: Optional
2700
- }] }]; } });
2701
-
2995
+ const expandColumnsWithSpan = (columns) => (columns.reduce((acc, column) => acc.concat(isSpanColumnComponent(column) ?
2996
+ [column].concat(column.childrenArray) :
2997
+ [column]), []));
2702
2998
  /**
2703
- * Represents the group-header cell template of the Grid which helps to customize the content of the group header item.
2704
- * To define the group header template, nest an `<ng-template>` tag with the `kendoGridGroupHeaderTemplate`
2705
- * directive inside `<kendo-grid-column>`. ([See example](slug:grouping_grid_templates#toc-header-template)).
2706
- *
2707
- * The template context is set to the current data item and the following additional fields are passed:
2708
- * - `group`&mdash;The current group item.
2709
- * - `field`&mdash;The name of the field by which data is grouped.
2710
- * - `value`&mdash;The current group value.
2711
- * - `aggregates`&mdash;All aggregate values for the current group.
2712
- * - `index`&mdash;The index of the current group.
2713
- * - `expanded`&mdash;A boolean value indicating if the group is currently expanded.
2714
- *
2715
- * @example
2716
- * ```html
2717
- * <kendo-grid [data]="gridData" [group]="groups">
2718
- * <kendo-grid-column field="ProductName">
2719
- * <ng-template kendoGridGroupHeaderTemplate let-group let-field="field" let-value="value">
2720
- * <strong>{{field}}</strong>: {{value}}
2721
- * </ng-template>
2722
- * </kendo-grid-column>
2723
- * </kendo-grid>
2724
- * ```
2999
+ * @hidden
2725
3000
  */
2726
- class GroupHeaderTemplateDirective {
2727
- templateRef;
2728
- constructor(templateRef) {
2729
- this.templateRef = templateRef;
2730
- }
2731
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: GroupHeaderTemplateDirective, deps: [{ token: i0.TemplateRef, optional: true }], target: i0.ɵɵFactoryTarget.Directive });
2732
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: GroupHeaderTemplateDirective, isStandalone: true, selector: "[kendoGridGroupHeaderTemplate]", ngImport: i0 });
2733
- }
2734
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: GroupHeaderTemplateDirective, decorators: [{
2735
- type: Directive,
2736
- args: [{
2737
- selector: '[kendoGridGroupHeaderTemplate]',
2738
- standalone: true
2739
- }]
2740
- }], ctorParameters: function () { return [{ type: i0.TemplateRef, decorators: [{
2741
- type: Optional
2742
- }] }]; } });
2743
-
3001
+ const columnsToRender = (columns) => (expandColumns(columns).filter(x => x.isVisible));
3002
+ const sumProp = (prop) => (array) => (array || []).reduce((prev, curr) => prev + (curr[prop] || 0), 0);
2744
3003
  /**
2745
- * Represents the group-header column template of the Grid which helps to customize the content of the group headers.
2746
- * To define the group header template, nest an `<ng-template>` tag with the `kendoGridGroupHeaderColumnTemplate`
2747
- * directive inside `<kendo-grid-column>`. ([See example](slug:grouping_grid_templates#toc-header-column-template)).
2748
- *
2749
- * The template context is set to the current data item and the following additional fields are passed:
2750
- * - `group`&mdash;The current group item.
2751
- * - `field`&mdash;The name of the field by which data is grouped.
2752
- * - `value`&mdash;The current group value.
2753
- * - `aggregates`&mdash;All aggregate values for the current group.
2754
- *
2755
- * @example
2756
- * ```html
2757
- * <kendo-grid-column field="ProductName" title="Product Name">
2758
- * <ng-template kendoGridGroupHeaderColumnTemplate let-group="group" let-aggregates="aggregates">
2759
- * <span title="Group Header Column Template for ProductName">
2760
- * Count: {{ aggregates.Discontinued.count }}
2761
- * </span>
2762
- * </ng-template>
2763
- * </kendo-grid-column>
2764
- * ```
3004
+ * @hidden
2765
3005
  */
2766
- class GroupHeaderColumnTemplateDirective {
2767
- templateRef;
2768
- constructor(templateRef) {
2769
- this.templateRef = templateRef;
2770
- }
2771
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: GroupHeaderColumnTemplateDirective, deps: [{ token: i0.TemplateRef, optional: true }], target: i0.ɵɵFactoryTarget.Directive });
2772
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: GroupHeaderColumnTemplateDirective, isStandalone: true, selector: "[kendoGridGroupHeaderColumnTemplate]", ngImport: i0 });
2773
- }
2774
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: GroupHeaderColumnTemplateDirective, decorators: [{
2775
- type: Directive,
2776
- args: [{
2777
- selector: '[kendoGridGroupHeaderColumnTemplate]',
2778
- standalone: true
2779
- }]
2780
- }], ctorParameters: function () { return [{ type: i0.TemplateRef, decorators: [{
2781
- type: Optional
2782
- }] }]; } });
2783
-
3006
+ const sumColumnWidths = sumProp('width');
2784
3007
  /**
2785
- * Represents the column edit-cell template of the Grid ([see example](slug:custom_reactive_editing_grid#toc-setting-up-custom-inputs)).
2786
- * Helps to customize the content of the edited cells. To define the cell template, nest an `<ng-template>`
2787
- * tag with the `kendoGridEditTemplate` directive inside a `<kendo-grid-column>` tag.
2788
- *
2789
- * The template context is set to the current form group and the following additional fields are passed:
2790
- * - `formGroup`&mdash;The current [FormGroup](link:site.data.urls.angular['formgroupapi']). Represents the default context that will be assigned to any template variable which utilizes the `let-x` syntax, for example, `let-formGroup`. If you use the Grid inside [Template-Driven Forms](link:site.data.urls.angular['forms']), it will be `undefined`.
2791
- * - `rowIndex`&mdash;The current data row index. If inside a new item row, `rowIndex` is `-1`. Use it as an alias for a template variable by utilizing the `let-rowIndex="rowIndex"` syntax.
2792
- * - `dataItem`&mdash;The current data item. Use it as an alias for a template variable by utilizing the `let-dataItem="dataItem"` syntax.
2793
- * - `column`&mdash;The current column instance. Use it as an alias for a template variable by utilizing the `let-column="column"` syntax.
2794
- * - `isNew`&mdash;The state of the current item. Use it as an alias for a template variable by utilizing the `let-isNew="isNew"` syntax.
3008
+ * @hidden
2795
3009
  */
2796
- class EditTemplateDirective {
2797
- templateRef;
2798
- constructor(templateRef) {
2799
- this.templateRef = templateRef;
2800
- }
2801
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: EditTemplateDirective, deps: [{ token: i0.TemplateRef, optional: true }], target: i0.ɵɵFactoryTarget.Directive });
2802
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: EditTemplateDirective, isStandalone: true, selector: "[kendoGridEditTemplate]", ngImport: i0 });
2803
- }
2804
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: EditTemplateDirective, decorators: [{
2805
- type: Directive,
2806
- args: [{
2807
- selector: '[kendoGridEditTemplate]',
2808
- standalone: true
2809
- }]
2810
- }], ctorParameters: function () { return [{ type: i0.TemplateRef, decorators: [{
2811
- type: Optional
2812
- }] }]; } });
2813
-
3010
+ const columnsSpan = sumProp('colspan');
3011
+ const validField = new RegExp(`^[$A-Z\_a-z][$A-Z\_a-z0-9\\.]*$`);
2814
3012
  /**
2815
- * Represents the column group footer cell template of the Grid which helps to customize the group footer cell for the column.
2816
- * To define the group footer template, nest an `<ng-template>` tag with the `kendoGridGroupFooterTemplate` directive
2817
- * inside `<kendo-grid-column>`.
2818
- *
2819
- * The template context is set to the current data item and the following additional fields are passed:
2820
- * - `column`&mdash;Defines an instance of the `ColumnComponent` option.
2821
- * - `field`&mdash;The current column field name.
2822
- * - `group`&mdash;The current group data item.
2823
- * - `aggregates`&mdash;All aggregate values for the current group.
2824
- *
2825
- * @example
2826
- * ```html
2827
- * <kendo-grid [data]="gridData" [group]="groups">
2828
- * <kendo-grid-column field="ProductName">
2829
- * <ng-template kendoGridGroupFooterTemplate let-aggregates let-field="field">
2830
- * Count: {{aggregates[field].count}}
2831
- * </ng-template>
2832
- * </kendo-grid-column>
2833
- * </kendo-grid>
2834
- * ```
3013
+ * @hidden
2835
3014
  */
2836
- class GroupFooterTemplateDirective {
2837
- templateRef;
2838
- constructor(templateRef) {
2839
- this.templateRef = templateRef;
2840
- }
2841
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: GroupFooterTemplateDirective, deps: [{ token: i0.TemplateRef, optional: true }], target: i0.ɵɵFactoryTarget.Directive });
2842
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: GroupFooterTemplateDirective, isStandalone: true, selector: "[kendoGridGroupFooterTemplate]", ngImport: i0 });
2843
- }
2844
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: GroupFooterTemplateDirective, decorators: [{
2845
- type: Directive,
2846
- args: [{
2847
- selector: '[kendoGridGroupFooterTemplate]',
2848
- standalone: true
2849
- }]
2850
- }], ctorParameters: function () { return [{ type: i0.TemplateRef, decorators: [{
2851
- type: Optional
2852
- }] }]; } });
2853
-
3015
+ const isValidFieldName = (fieldName) => !isNullOrEmptyString(fieldName) && validField.test(fieldName) &&
3016
+ fieldName[0] !== "." && fieldName[fieldName.length - 1] !== ".";
2854
3017
  /**
2855
- * Represents the column header cell template of the Grid
2856
- * ([more information and example]({% slug templates_columns_grid %}#toc-header-template)).
2857
- * Helps to customize the table header cell for the column.
2858
- * To define a header template, nest an `<ng-template>` tag with the
2859
- * `kendoGridHeaderTemplate` directive inside the `<kendo-grid-column>` tag.
2860
- *
2861
- * The template context is set to the current column and then the following additional fields are passed:
2862
- * * `column`&mdash;Defines an instance of the [ColumnComponent]({% slug api_grid_columncomponent %}) option.
2863
- * * `columnIndex`&mdash;Defines the current column index.
2864
- *
2865
- * @example
2866
- * ```html
2867
- * <kendo-grid [data]="gridData">
2868
- * <kendo-grid-column field="ProductName">
2869
- * <ng-template kendoGridHeaderTemplate let-column let-columnIndex="columnIndex">
2870
- * {{column.field}}({{columnIndex}})
2871
- * </ng-template>
2872
- * </kendo-grid-column>
2873
- * </kendo-grid>
2874
- * ```
3018
+ * @hidden
2875
3019
  */
2876
- class HeaderTemplateDirective {
2877
- templateRef;
2878
- constructor(templateRef) {
2879
- this.templateRef = templateRef;
2880
- }
2881
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: HeaderTemplateDirective, deps: [{ token: i0.TemplateRef, optional: true }], target: i0.ɵɵFactoryTarget.Directive });
2882
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: HeaderTemplateDirective, isStandalone: true, selector: "[kendoGridHeaderTemplate]", ngImport: i0 });
2883
- }
2884
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: HeaderTemplateDirective, decorators: [{
2885
- type: Directive,
2886
- args: [{
2887
- selector: '[kendoGridHeaderTemplate]',
2888
- standalone: true
2889
- }]
2890
- }], ctorParameters: function () { return [{ type: i0.TemplateRef, decorators: [{
2891
- type: Optional
2892
- }] }]; } });
2893
-
3020
+ const children = column => column.children.filter(child => child !== column);
2894
3021
  /**
2895
- * Represents the column footer cell template of the Grid
2896
- * ([more information and example]({% slug templates_columns_grid %}#toc-footer-template)).
2897
- * Helps to customize the table footer cell for the column.
2898
- * To define a footer template, nest an `<ng-template>` tag with the
2899
- * [kendoGridFooterTemplate]({% slug api_grid_footertemplatedirective %}) directive inside the `<kendo-grid-column>` tag.
2900
- *
2901
- * The template context is set to the current column and the following additional fields are passed:
2902
- * * `column`&mdash;Defines an instance of the [ColumnComponent]({% slug api_grid_columncomponent %}) option.
2903
- * * `columnIndex`&mdash;Defines the current column index.
2904
- *
2905
- * For more information on how to display aggregates in the footer of the Grid,
2906
- * refer to the article on [aggregates]({% slug groupable_grid_with_aggregates %}).
2907
- *
2908
- * @example
2909
- * ```html
2910
- * <kendo-grid [data]="gridData" scrollable="none">
2911
- * <kendo-grid-column field="ProductName">
2912
- * <ng-template kendoGridFooterTemplate let-column let-columnIndex="columnIndex">
2913
- * {{column.field}}({{columnIndex}})
2914
- * </ng-template>
2915
- * </kendo-grid-column>
2916
- * </kendo-grid>
2917
- * ```
3022
+ * @hidden
2918
3023
  */
2919
- class FooterTemplateDirective {
2920
- templateRef;
2921
- constructor(templateRef) {
2922
- this.templateRef = templateRef;
2923
- }
2924
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: FooterTemplateDirective, deps: [{ token: i0.TemplateRef, optional: true }], target: i0.ɵɵFactoryTarget.Directive });
2925
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: FooterTemplateDirective, isStandalone: true, selector: "[kendoGridFooterTemplate]", ngImport: i0 });
2926
- }
2927
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: FooterTemplateDirective, decorators: [{
2928
- type: Directive,
2929
- args: [{
2930
- selector: '[kendoGridFooterTemplate]',
2931
- standalone: true
2932
- }]
2933
- }], ctorParameters: function () { return [{ type: i0.TemplateRef, decorators: [{
2934
- type: Optional
2935
- }] }]; } });
2936
-
3024
+ const leafColumns = columns => {
3025
+ return columns.reduce((acc, column) => {
3026
+ if (column.isColumnGroup) {
3027
+ acc = acc.concat(leafColumns(children(column)));
3028
+ }
3029
+ else if (column.isSpanColumn) {
3030
+ acc = acc.concat(column.childrenArray);
3031
+ }
3032
+ else {
3033
+ acc.push(column);
3034
+ }
3035
+ return acc;
3036
+ }, []).filter(x => x.isVisible);
3037
+ };
2937
3038
  /**
2938
- * Represents the template for the column menu in the Grid. Provides an option for
2939
- * customizing the content of the column menu for all or for specific columns.
2940
- * To define the content template, nest an `<ng-template>` tag with the
2941
- * `kendoGridColumnMenuTemplate` directive inside the `<kendo-grid>` or the `<kendo-grid-column>` component.
2942
- *
2943
- * The template context is passes through the following fields:
2944
- * - `service`&mdash;Represents the [ColumnMenuService]({% slug api_grid_columnmenuservice %}).
2945
- * - `column`&mdash;Represents the Grid column.
2946
- *
2947
- * @example
2948
- * ```html
2949
- * <kendo-grid [kendoGridBinding]="data" [sortable]="true" [columnMenu]="true">
2950
- * <ng-template kendoGridColumnMenuTemplate let-service="service">
2951
- * <kendo-grid-columnmenu-sort [service]="service"></kendo-grid-columnmenu-sort>
2952
- * </ng-template>
2953
- * <kendo-grid-column field="Field1">
2954
- * <ng-template kendoGridColumnMenuTemplate let-service="service">
2955
- * <kendo-grid-columnmenu-lock [service]="service"></kendo-grid-columnmenu-lock>
2956
- * <kendo-grid-columnmenu-sort [service]="service"></kendo-grid-columnmenu-sort>
2957
- * </ng-template>
2958
- * </kendo-grid-column>
2959
- * <kendo-grid-column field="Field2"></kendo-grid-column>
2960
- * </kendo-grid>
2961
- * ```
3039
+ * @hidden
2962
3040
  */
2963
- class ColumnMenuTemplateDirective {
2964
- templateRef;
2965
- constructor(templateRef) {
2966
- this.templateRef = templateRef;
2967
- }
2968
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ColumnMenuTemplateDirective, deps: [{ token: i0.TemplateRef, optional: true }], target: i0.ɵɵFactoryTarget.Directive });
2969
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: ColumnMenuTemplateDirective, isStandalone: true, selector: "[kendoGridColumnMenuTemplate]", ngImport: i0 });
2970
- }
2971
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ColumnMenuTemplateDirective, decorators: [{
2972
- type: Directive,
2973
- args: [{
2974
- selector: '[kendoGridColumnMenuTemplate]',
2975
- standalone: true
2976
- }]
2977
- }], ctorParameters: function () { return [{ type: i0.TemplateRef, decorators: [{
2978
- type: Optional
2979
- }] }]; } });
2980
-
2981
- // Incremented each time the service is instantiated.
2982
- let sequence = 0;
3041
+ const someLeafColumn = (callback, ...columns) => leafColumns(columns).some(callback);
2983
3042
  /**
2984
3043
  * @hidden
2985
3044
  */
2986
- class IdService {
2987
- prefix;
2988
- constructor() {
2989
- this.prefix = `k-grid${sequence++}`;
2990
- }
2991
- gridId() {
2992
- return this.prefix;
2993
- }
2994
- cellId(rowIndex, colIndex) {
2995
- return `${this.prefix}-r${rowIndex}c${colIndex}`;
2996
- }
2997
- selectionCheckboxId(itemIndex) {
2998
- return `${this.prefix}-checkbox${itemIndex}`;
2999
- }
3000
- selectAllCheckboxId() {
3001
- return `${this.prefix}-select-all`;
3002
- }
3003
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: IdService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
3004
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: IdService });
3005
- }
3006
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: IdService, decorators: [{
3007
- type: Injectable
3008
- }], ctorParameters: function () { return []; } });
3009
-
3045
+ const resizableColumns = columns => columns.filter(column => isTruthy(column.resizable) && column.isVisible);
3010
3046
  /**
3011
3047
  * @hidden
3012
3048
  */
3013
- const ColumnMenuErrorMessages = {
3014
- autoSizeColumn: `The auto size column does not work with enabled virtual columns.
3015
- See https://www.telerik.com/kendo-angular-ui/components/grid/accessories/column-menu/#toc-autosize-column-item.`,
3016
- autoSizeAllColumns: `The auto size all columns does not work with enabled virtual columns.
3017
- See https://www.telerik.com/kendo-angular-ui/components/grid/accessories/column-menu/#toc-autosize-all-columns-item.`,
3018
- serviceInput: `The service input of the predefined column menu components is mandatory.
3019
- See https://www.telerik.com/kendo-angular-ui/components/grid/accessories/column-menu/#toc-customizing-the-content.`
3020
- };
3049
+ const sortColumns = (columns) => orderBy(columns, [{ field: 'orderIndex', dir: 'asc' }]);
3021
3050
  /**
3022
3051
  * @hidden
3023
3052
  */
3024
- const ClipboardErrorMessages = {
3025
- activeCellNavigable: `Grid must be navigable to use "activeCell" as clipboard target type.
3026
- See https://www.telerik.com/kendo-angular-ui/components/grid/accessories/clipboard/#toc-active-cell.`,
3027
- selectionSelectable: `Grid must be selectable to use "selection" as clipboard target type.
3028
- See https://www.telerik.com/kendo-angular-ui/components/grid/accessories/clipboard/#toc-current-selection.`
3029
- };
3030
- /**
3031
- * @hidden
3032
- */
3033
- const ColumnConfigurationErrorMessages = {
3034
- fieldName: (field) => `Grid column field name '${field}' does not look like a valid JavaScript identifier.
3035
- Identifiers can contain only alphanumeric characters (including "$" or "_"), and may not start with a digit.
3036
- Please use only valid identifier names to ensure error-free operation.`,
3037
- width: (value, parsedValue) => `Expected numeric value for column width, but got a string "${value}". Treating as ${parsedValue}px.`,
3038
- invalidColumn: (column) => `Invalid column ${column}.`,
3039
- requiredWidth: (columnType) => `${columnType} columns feature requires all columns to have set width.
3040
- See https://www.telerik.com/kendo-angular-ui/components/grid/columns/${columnType.toLowerCase()}.`,
3041
- requiredScroll: (columnType) => `${columnType} columns are only supported when scrolling is enabled.
3042
- See https://www.telerik.com/kendo-angular-ui/components/grid/columns/${columnType.toLowerCase()}/`,
3043
- groupColumnContent: 'ColumnGroupComponent should contain ColumnComponent or CommandColumnComponent.',
3044
- lockedParent: 'Locked child columns require their parent columns to be locked.',
3045
- columnNested: 'Columns can be nested only inside ColumnGroupComponent',
3046
- nestedInside: (nestedColumnNameType, parentColumnType) => `${nestedColumnNameType} cannot be nested inside ${parentColumnType}.`
3047
- };
3048
- /**
3049
- * @hidden
3050
- */
3051
- const GridConfigurationErrorMessages = {
3052
- functionType: (propName, fn) => `${propName} must be a function, but received ${JSON.stringify(fn)}.`,
3053
- incompatibleFeatures: (feat1Name, feat2Name) => `'Having both ${feat1Name} and ${feat2Name} is not supported.'`,
3054
- nonLockedColumnPresent: 'There should be at least one non-locked column. See https://www.telerik.com/kendo-angular-ui/components/grid/columns/locked/#toc-known-limitations',
3055
- rowHeightVirtual: `The virtual scrolling functionality requires setting the rowHeight (and detailRowHeight when there are detail rows).
3056
- Row height and detail row height settings should be set only when virtual scrolling mode is enabled.
3057
- See https://www.telerik.com/kendo-angular-ui/components/grid/scroll-modes/virtual/#toc-getting-started.`,
3058
- focusNavigable: 'The Grid should be configured as navigable to control focus. See https://www.telerik.com/kendo-angular-ui/components/grid/keyboard-navigation/.',
3059
- expandCollapseMethods: (expandMethodName, collapseMethodName, directiveName, callbackName) => `The ${expandMethodName} and ${collapseMethodName} methods should not be called
3060
- when using the ${directiveName} directive or the ${callbackName} callback.
3061
- These methods are provided only for backwards compatibility with legacy versions.`,
3062
- requiredEditService: `The default edit service of the editing directives works only when binding to plain array.
3063
- Please provide an editService. See https://www.telerik.com/kendo-angular-ui/components/grid/editing/editing-directives/#toc-custom-editing-service.`,
3064
- requiredModule: (exportedType, moduleName, componentSelector) => `Creating ${exportedType} requires including the ${moduleName} and adding the ${componentSelector} component.`,
3065
- groupBindingDirectives: `Using the "kendoGridGroupBinding" directive in combination with the "kendoGridExpandGroupBy" directive
3066
- or the "isGroupExpanded" callback is not supported. To use grouping with the "kendoGridGroupBinding" directive,
3067
- set the Grid "groupable" property to "true".`,
3068
- unsupportedMethod: (methodName, suggestedMethodName) => `Using ${methodName} in this context is not supported. Use ${suggestedMethodName} instead.`,
3069
- unsupportedToolbarConfig: `
3070
- Defining both a toolbar template and a ToolBarComponent within the Grid is not supported.
3071
- Please use either the ToolBarComponent or a custom template.`
3072
- };
3053
+ const isInSpanColumn$1 = (column) => isTruthy(column.parent) && isSpanColumnComponent(column.parent);
3073
3054
 
3074
3055
  /**
3075
3056
  * @hidden
3076
3057
  */
3077
- const isSpanColumn = column => column.isSpanColumn;
3058
+ const isLocked = column => column.parent ? isLocked(column.parent) : !!column.locked;
3078
3059
  /**
3079
3060
  * @hidden
3080
3061
  */
3081
- const isCheckboxColumn = column => column.isCheckboxColumn;
3062
+ const resizeArgs = (column, extra) => Object.assign({
3063
+ columns: leafColumns([column]),
3064
+ locked: isLocked(column)
3065
+ }, extra);
3082
3066
  /**
3083
3067
  * @hidden
3084
3068
  */
3085
- const isRowReorderColumn = column => column.isRowReorderColumn;
3086
- const isColumnContainer = column => column.isColumnGroup || isSpanColumn(column);
3087
- /**
3088
- * The base class for the column components of the Grid.
3089
- */
3090
- class ColumnBase {
3091
- parent;
3092
- /**
3093
- * @hidden
3094
- */
3095
- matchesMedia = true;
3096
- /**
3097
- * The column index after reordering. The `orderIndex` is a read-only property. Setting this field does not affect column order.
3098
- *
3099
- * @default 0
3100
- */
3101
- orderIndex = 0;
3102
- /**
3103
- * @hidden
3104
- */
3105
- set leafIndex(value) {
3106
- this._leafIndex = value;
3069
+ class ColumnResizingService {
3070
+ changes = new EventEmitter();
3071
+ adjacentColumn;
3072
+ areColumnsReordered = false;
3073
+ isShiftPressed = false;
3074
+ originalWidth;
3075
+ column;
3076
+ resizedColumns;
3077
+ tables = [];
3078
+ batch = null;
3079
+ start(column) {
3080
+ this.trackColumns(column);
3081
+ const columns = (this.column.isColumnGroup ? [column] : [])
3082
+ .concat(leafColumns([column]));
3083
+ this.changes.emit({
3084
+ columns: columns,
3085
+ locked: isLocked(this.column),
3086
+ type: 'start'
3087
+ });
3107
3088
  }
3108
- /**
3109
- * @hidden
3110
- */
3111
- get leafIndex() {
3112
- return this._leafIndex;
3089
+ resizeColumns(deltaPercent) {
3090
+ const action = resizeArgs(this.column, {
3091
+ deltaPercent,
3092
+ type: 'resizeColumn'
3093
+ });
3094
+ this.changes.emit(action);
3113
3095
  }
3114
- _leafIndex;
3115
- /**
3116
- * @hidden
3117
- */
3118
- isColumnGroup = false;
3119
- /**
3120
- * @hidden
3121
- */
3122
- isSpanColumn = false;
3123
- /**
3124
- * Indicates whether the column is resizable.
3125
- * @default true
3126
- */
3127
- resizable = true;
3128
- /**
3129
- * Indicates whether the column is reorderable.
3130
- * @default true
3131
- */
3132
- reorderable = true;
3133
- /**
3134
- * The width (in pixels) below which the user is not able to resize the column by using the UI ([see example]({% slug resizing_columns_grid %}#toc-limiting-the-resizing)).
3135
- * The `autoFitColumn` and `autoFitColumns` methods have higher priority.
3136
- * @default 10
3137
- */
3138
- minResizableWidth = 10;
3139
- /**
3140
- * The width (in pixels) above which the user is not able to resize the column by using the UI ([see example]({% slug resizing_columns_grid %}#toc-limiting-the-resizing)).
3141
- * By default, the maximum width is not restricted.
3142
- * The `autoFitColumn` and `autoFitColumns` methods have higher priority.
3143
- */
3144
- maxResizableWidth;
3145
- /**
3146
- * The title of the column.
3147
- */
3148
- title;
3149
- /**
3150
- * The width of the column (in pixels).
3151
- */
3152
- set width(value) {
3153
- if (typeof value === 'string') {
3154
- const parsedValue = this._width = parseInt(value, 10);
3155
- if (isDevMode()) {
3156
- console.warn(ColumnConfigurationErrorMessages.width(value, parsedValue));
3157
- }
3096
+ resizeTable(column, delta) {
3097
+ const action = resizeArgs(column, {
3098
+ delta,
3099
+ type: 'resizeTable'
3100
+ });
3101
+ this.changes.emit(action);
3102
+ }
3103
+ resizedColumn(state) {
3104
+ this.resizedColumns.push(state);
3105
+ }
3106
+ end() {
3107
+ this.changes.emit({
3108
+ columns: [],
3109
+ resizedColumns: this.resizedColumns,
3110
+ type: 'end'
3111
+ });
3112
+ this.adjacentColumn = null;
3113
+ }
3114
+ registerTable(tableMetadata) {
3115
+ this.tables.push(tableMetadata);
3116
+ const unregisterTable = () => {
3117
+ this.tables.splice(this.tables.indexOf(tableMetadata), 1);
3118
+ };
3119
+ return unregisterTable;
3120
+ }
3121
+ measureColumns(info) {
3122
+ if (this.batch !== null) {
3123
+ this.batch.push(...info);
3158
3124
  }
3159
3125
  else {
3160
- this._width = value;
3126
+ this.autoFitBatch(info, () => this.end());
3161
3127
  }
3162
3128
  }
3163
- get width() { return this._width; }
3164
- /**
3165
- * Indicates whether the column will be resized during initialization so that it fits its header and row content.
3166
- */
3167
- autoSize;
3168
- /**
3169
- * Toggles the locked (frozen) state of the columns ([more information and example]({% slug locked_columns_grid %})).
3170
- *
3171
- * @default false
3172
- *
3173
- */
3174
- set locked(value) {
3175
- this._locked = value;
3129
+ autoFit(...columns) {
3130
+ const nonLockedColumns = columns.filter(column => !column.isLocked);
3131
+ this.autoFitStart(nonLockedColumns);
3132
+ this.autoFitBatch(this.batch, () => {
3133
+ if (nonLockedColumns.length < columns.length) {
3134
+ const lockedColumns = columns.filter(column => column.isLocked);
3135
+ this.autoFitStart(lockedColumns);
3136
+ this.autoFitBatch(this.batch, () => this.end());
3137
+ }
3138
+ else {
3139
+ this.end();
3140
+ }
3141
+ });
3176
3142
  }
3177
- get locked() {
3178
- return this._locked;
3143
+ trackColumns(column) {
3144
+ this.resizedColumns = [];
3145
+ this.column = column;
3179
3146
  }
3180
- _locked = false;
3181
- /**
3182
- * Determines whether the column will be always visible when scrolling the Grid horizontally.
3183
- *
3184
- * @default false
3185
- */
3186
- sticky = false;
3187
- /**
3188
- * Sets the visibility of the column ([see example](slug:hidden_columns_grid#toc-using-the-built-in-options)).
3189
- *
3190
- * @default false
3191
- */
3192
- hidden;
3193
- /**
3194
- * Sets the condition that needs to be satisfied for a column to remain visible ([see example]({% slug styling_responsive_grid %}#toc-columns)).
3195
- * If you set the `hidden` property, the behavior of `media` is overridden.
3196
- *
3197
- * Accepts the device identifiers that are [available in Bootstrap 4](https://v4-alpha.getbootstrap.com/layout/grid/#grid-options)
3198
- * ([see example](slug:styling_responsive_grid)):
3199
- */
3200
- media;
3201
- /**
3202
- * Specifies if the column can be locked or unlocked from the column menu or by reordering the columns.
3203
- * @default true
3204
- */
3205
- lockable = true;
3206
- /**
3207
- * Specifies if the column can be stuck or unstuck from the column menu.
3208
- * @default true
3209
- */
3210
- stickable = true;
3211
- /**
3212
- * Specifies if the column menu will be shown for the column.
3213
- * @default true
3214
- */
3215
- columnMenu = true;
3216
- /**
3217
- * Specifies if the column will be included in the column-chooser list.
3218
- * @default true
3219
- */
3220
- includeInChooser = true;
3221
- /**
3222
- * Allows setting the `role` attribute for the table cells (excluding the footer and header ones) of the column.
3223
- * @default "gridcell"
3224
- */
3225
- tableCellsRole = 'gridcell';
3226
- /**
3227
- * Sets the custom styles for the table cells (excluding the footer and header ones) of the column. Under the hood,
3228
- * to apply the property, the `style` option uses the
3229
- * [NgStyle](link:site.data.urls.angular['ngstyleapi']) directive. [See example](slug:styling_grid_columns#toc-customizing-column-cells).
3230
- *
3231
- */
3232
- style;
3233
- /**
3234
- * Sets the custom styles for the header cell of the column. Under the hood, to apply the property,
3235
- * the `headerStyle` option uses the
3236
- * [NgStyle](link:site.data.urls.angular['ngstyleapi']) directive. [See example](slug:styling_grid_columns#toc-customizing-column-header).
3237
- *
3238
- */
3239
- headerStyle;
3240
- /**
3241
- * Sets the custom styles for the filter row cell. Under the hood, to apply the property,
3242
- * the `filterStyle` option uses the
3243
- * [NgStyle](link:site.data.urls.angular['ngstyleapi']) directive. [See example](slug:styling_grid_columns#toc-customizing-filter-row-cells).
3244
- *
3245
- */
3246
- filterStyle;
3247
- /**
3248
- * Sets the custom styles for the footer cell of the column. Under the hood, to apply the property,
3249
- * the `footerStyle` option uses the
3250
- * [NgStyle](link:site.data.urls.angular['ngstyleapi']) directive. [See example](slug:styling_grid_columns#toc-customizing-column-footer).
3251
- *
3252
- */
3253
- footerStyle;
3254
- /**
3255
- * Sets the custom CSS classes to the column cells. Under the hood, to apply the property, the `class` option uses the
3256
- * [NgClass](link:site.data.urls.angular['ngclassapi']) directive. [See example](slug:styling_grid_columns#toc-customizing-column-cells).
3257
- * To customize header and footer column cells, use the [headerClass]({% slug api_grid_columncomponent %}#toc-headerclass)
3258
- * and [footerClass]({% slug api_grid_columncomponent %}#toc-footerclass) inputs.
3259
- *
3260
- */
3261
- cssClass;
3262
- /**
3263
- * Sets the custom CSS classes to the column header cell. Under the hood, to apply the property,
3264
- * the `headerClass` option uses the
3265
- * [NgClass](link:site.data.urls.angular['ngclassapi']) directive. [See example](slug:styling_grid_columns#toc-customizing-column-header).
3266
- *
3267
- */
3268
- headerClass;
3269
- /**
3270
- * Sets the custom CSS classes to the filter row cell. Under the hood, to apply the property,
3271
- * the `filterClass` option uses the
3272
- * [NgClass](link:site.data.urls.angular['ngclassapi']) directive. [See example](slug:styling_grid_columns#toc-customizing-filter-row-cells).
3273
- *
3274
- */
3275
- filterClass;
3276
- /**
3277
- * Sets the custom CSS classes to the column footer cell. Under the hood, to apply the property,
3278
- * the `footerClass` option uses the
3279
- * [NgClass](link:site.data.urls.angular['ngclassapi']) directive. [See example](slug:styling_grid_columns#toc-customizing-column-footer).
3280
- *
3281
- */
3282
- footerClass;
3283
- /**
3284
- * @hidden
3285
- */
3286
- headerTemplates = new QueryList();
3287
- /**
3288
- * @hidden
3289
- */
3290
- footerTemplate;
3291
- /**
3292
- * @hidden
3293
- */
3294
- columnMenuTemplates = new QueryList();
3295
- /**
3296
- * @hidden
3297
- */
3298
- resizeStartWidth;
3299
- /**
3300
- * @hidden
3301
- */
3302
- idService;
3303
- /**
3304
- * @hidden
3305
- */
3306
- implicitWidth;
3307
- /**
3308
- * @hidden
3309
- */
3310
- get level() {
3311
- if (this.parent && isSpanColumn(this.parent)) {
3312
- return this.parent.level;
3147
+ autoFitStart(columns) {
3148
+ this.batch = [];
3149
+ this.resizedColumns = [];
3150
+ if (columns.length === 0) {
3151
+ return;
3313
3152
  }
3314
- return this.parent ? this.parent.level + 1 : 0;
3153
+ const locked = columns[0].isLocked;
3154
+ this.changes.emit({
3155
+ type: 'start',
3156
+ columns,
3157
+ locked
3158
+ });
3159
+ this.changes.emit({
3160
+ type: 'triggerAutoFit',
3161
+ columns,
3162
+ locked
3163
+ });
3315
3164
  }
3316
- /**
3317
- * @hidden
3318
- */
3319
- get isLocked() {
3320
- return this.parent ? this.parent.isLocked : this.locked;
3165
+ autoFitBatch(info, onComplete) {
3166
+ const locked = info.length > 0 ? info[0].column.isLocked : false;
3167
+ const observables = this.tables
3168
+ .filter(table => table.locked === locked)
3169
+ .map(table => table.autoFit(info));
3170
+ zip$1(...observables)
3171
+ .pipe(take(1))
3172
+ .subscribe(widths => {
3173
+ this.changes.emit({
3174
+ columns: info.map(i => i.column),
3175
+ type: 'autoFitComplete',
3176
+ widths,
3177
+ locked
3178
+ });
3179
+ if (onComplete) {
3180
+ onComplete();
3181
+ }
3182
+ });
3183
+ this.batch = null;
3321
3184
  }
3322
- _width;
3323
- /**
3324
- * @hidden
3325
- */
3326
- get colspan() {
3327
- return 1;
3185
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ColumnResizingService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
3186
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ColumnResizingService });
3187
+ }
3188
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ColumnResizingService, decorators: [{
3189
+ type: Injectable
3190
+ }] });
3191
+
3192
+ const isInSameGrid = (element, gridElement) => closest(element, matchesNodeName('kendo-grid')) === gridElement;
3193
+ const matchHeaderCell = matchesNodeName('th');
3194
+ const matchDataCell = matchesNodeName('td');
3195
+ const matchFooterCell = matchesNodeName('.k-grid-footer td');
3196
+ const matchCell = (element) => matchDataCell(element) || matchHeaderCell(element) || matchFooterCell(element);
3197
+ const gridCell = (element, gridElement) => {
3198
+ let target = closest(element, matchCell);
3199
+ while (target && !isInSameGrid(target, gridElement)) {
3200
+ target = closest(target.parentElement, matchCell);
3328
3201
  }
3329
- /**
3330
- * @hidden
3331
- */
3332
- rowspan(totalColumnLevels) {
3333
- return this.level < totalColumnLevels ? (totalColumnLevels - this.level) + 1 : 1;
3202
+ return target;
3203
+ };
3204
+ const targetCell = (target, gridElement) => {
3205
+ const cell = gridCell(target, gridElement);
3206
+ const row = closest(cell, matchesNodeName('tr'));
3207
+ if (cell && row) {
3208
+ let rowIndex = row.getAttribute('aria-rowindex') || row.getAttribute('data-kendo-grid-row-index');
3209
+ rowIndex = rowIndex ? parseInt(rowIndex, 10) - 1 : null;
3210
+ let colIndex = cell.getAttribute('aria-colindex');
3211
+ colIndex = colIndex ? parseInt(colIndex, 10) - 1 : null;
3212
+ if (rowIndex !== null && colIndex !== null) {
3213
+ return { colIndex, rowIndex, element: cell };
3214
+ }
3334
3215
  }
3335
- /**
3336
- * @hidden
3337
- */
3338
- get headerTemplateRef() {
3339
- const template = this.headerTemplates.first;
3340
- return template ? template.templateRef : undefined;
3216
+ };
3217
+ const isArrowKey = keyCode => keyCode === Keys.ArrowLeft || keyCode === Keys.ArrowRight ||
3218
+ keyCode === Keys.ArrowUp || keyCode === Keys.ArrowDown;
3219
+ const isNavigationKey = keyCode => isArrowKey(keyCode) ||
3220
+ keyCode === Keys.PageUp || keyCode === Keys.PageDown ||
3221
+ keyCode === Keys.Home || keyCode === Keys.End;
3222
+ const isInput = matchesNodeName('input');
3223
+ const isTextInput = element => element && isInput(element) && element.type.toLowerCase() === 'text';
3224
+ const isPrintableCharacter = (str) => str.length === 1 && str.match(/\S/);
3225
+ const resizeStep = 10;
3226
+ /**
3227
+ * @hidden
3228
+ */
3229
+ class NavigationViewport {
3230
+ firstItemIndex;
3231
+ lastItemIndex;
3232
+ constructor(firstItemIndex, lastItemIndex) {
3233
+ this.firstItemIndex = firstItemIndex;
3234
+ this.lastItemIndex = lastItemIndex;
3341
3235
  }
3342
- /**
3343
- * @hidden
3344
- */
3345
- get footerTemplateRef() {
3346
- return this.footerTemplate ? this.footerTemplate.templateRef : undefined;
3236
+ containsRow(dataRowIndex) {
3237
+ const headerRow = dataRowIndex < 0;
3238
+ return headerRow || (dataRowIndex >= this.firstItemIndex && dataRowIndex <= this.lastItemIndex);
3347
3239
  }
3348
- /**
3349
- * @hidden
3350
- */
3351
- get columnMenuTemplateRef() {
3352
- const template = this.columnMenuTemplates.first;
3353
- return template ? template.templateRef : null;
3240
+ intersects(start, end) {
3241
+ return (start <= this.firstItemIndex && this.lastItemIndex <= end) ||
3242
+ (this.firstItemIndex <= start && start <= this.lastItemIndex) ||
3243
+ (this.firstItemIndex <= end && end <= this.lastItemIndex);
3354
3244
  }
3355
- /**
3356
- * @hidden
3357
- */
3358
- get displayTitle() {
3359
- return this.title;
3245
+ }
3246
+ /**
3247
+ * @hidden
3248
+ */
3249
+ class NavigationService {
3250
+ zone;
3251
+ domEvents;
3252
+ pagerContextService;
3253
+ scrollRequestService;
3254
+ groupsService;
3255
+ detailsService;
3256
+ focusRoot;
3257
+ editService;
3258
+ cd;
3259
+ ctx;
3260
+ resizeService;
3261
+ focusableParent;
3262
+ changes;
3263
+ cellKeydown = new EventEmitter();
3264
+ set metadata(value) {
3265
+ this.meta = value;
3266
+ this.cursor.metadata = value;
3360
3267
  }
3361
- /**
3362
- * @hidden
3363
- */
3364
- get isVisible() {
3365
- return !this.hidden && this.matchesMedia;
3268
+ get metadata() {
3269
+ return this.meta;
3366
3270
  }
3367
- /**
3368
- * @hidden
3369
- */
3370
- constructor(parent, idService) {
3371
- this.parent = parent;
3372
- this.idService = idService;
3373
- if (parent && idService && parent.idService.gridId() === idService.gridId() && !isColumnContainer(parent)) {
3374
- throw new Error(ColumnConfigurationErrorMessages.columnNested);
3375
- }
3271
+ get enabled() {
3272
+ return this.alive;
3376
3273
  }
3377
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ColumnBase, deps: [{ token: ColumnBase }, { token: IdService }], target: i0.ɵɵFactoryTarget.Component });
3378
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: ColumnBase, selector: "kendo-grid-column-base", inputs: { resizable: "resizable", reorderable: "reorderable", minResizableWidth: "minResizableWidth", maxResizableWidth: "maxResizableWidth", title: "title", width: "width", autoSize: "autoSize", locked: "locked", sticky: "sticky", hidden: "hidden", media: "media", lockable: "lockable", stickable: "stickable", columnMenu: "columnMenu", includeInChooser: "includeInChooser", tableCellsRole: "tableCellsRole", style: "style", headerStyle: "headerStyle", filterStyle: "filterStyle", footerStyle: "footerStyle", cssClass: ["class", "cssClass"], headerClass: "headerClass", filterClass: "filterClass", footerClass: "footerClass" }, queries: [{ propertyName: "footerTemplate", first: true, predicate: FooterTemplateDirective, descendants: true }, { propertyName: "headerTemplates", predicate: HeaderTemplateDirective }, { propertyName: "columnMenuTemplates", predicate: ColumnMenuTemplateDirective }], ngImport: i0, template: ``, isInline: true });
3379
- }
3380
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ColumnBase, decorators: [{
3381
- type: Component,
3382
- args: [{
3383
- selector: 'kendo-grid-column-base',
3384
- template: ``
3385
- }]
3386
- }], ctorParameters: function () { return [{ type: ColumnBase }, { type: IdService }]; }, propDecorators: { resizable: [{
3387
- type: Input
3388
- }], reorderable: [{
3389
- type: Input
3390
- }], minResizableWidth: [{
3391
- type: Input
3392
- }], maxResizableWidth: [{
3393
- type: Input
3394
- }], title: [{
3395
- type: Input
3396
- }], width: [{
3397
- type: Input
3398
- }], autoSize: [{
3399
- type: Input
3400
- }], locked: [{
3401
- type: Input
3402
- }], sticky: [{
3403
- type: Input
3404
- }], hidden: [{
3405
- type: Input
3406
- }], media: [{
3407
- type: Input
3408
- }], lockable: [{
3409
- type: Input
3410
- }], stickable: [{
3411
- type: Input
3412
- }], columnMenu: [{
3413
- type: Input
3414
- }], includeInChooser: [{
3415
- type: Input
3416
- }], tableCellsRole: [{
3417
- type: Input
3418
- }], style: [{
3419
- type: Input
3420
- }], headerStyle: [{
3421
- type: Input
3422
- }], filterStyle: [{
3423
- type: Input
3424
- }], footerStyle: [{
3425
- type: Input
3426
- }], cssClass: [{
3427
- type: Input,
3428
- args: ['class']
3429
- }], headerClass: [{
3430
- type: Input
3431
- }], filterClass: [{
3432
- type: Input
3433
- }], footerClass: [{
3434
- type: Input
3435
- }], headerTemplates: [{
3436
- type: ContentChildren,
3437
- args: [HeaderTemplateDirective, { descendants: false }]
3438
- }], footerTemplate: [{
3439
- type: ContentChild,
3440
- args: [FooterTemplateDirective, { static: false }]
3441
- }], columnMenuTemplates: [{
3442
- type: ContentChildren,
3443
- args: [ColumnMenuTemplateDirective]
3444
- }] } });
3445
-
3446
- /**
3447
- * Represents the filter-cell template.
3448
- * Helps to customize the content of the filter cell. To define the filter cell template, nest an `<ng-template>` tag with the
3449
- * `kendoGridFilterCellTemplate` directive inside a `<kendo-grid-column>` tag ([see example]({% slug filter_row %}#toc-custom-filters)).
3450
- *
3451
- * The template context is set to the current data item and the following additional fields are passed:
3452
- * - `column`&mdash;Defines an instance of the [`ColumnComponent`]({% slug api_grid_columncomponent %}) option. Use it as an alias for a template variable by utilizing the `let-column="column"` syntax.
3453
- * - `filter`&mdash;The provided filter descriptors. Use it as an alias for a template variable by utilizing the `let-filter="filter"` syntax.
3454
- *
3455
- * ```html
3456
- * <kendo-grid-column field="CategoryID" title="Category">
3457
- * <ng-template kendoGridFilterCellTemplate
3458
- * let-column="column"
3459
- * let-filter="filter"
3460
- * >
3461
- * ...
3462
- * </ng-template>
3463
- * ...
3464
- * </kendo-grid-column>
3465
- * ```
3466
- */
3467
- class FilterCellTemplateDirective {
3468
- templateRef;
3469
- constructor(templateRef) {
3470
- this.templateRef = templateRef;
3274
+ get pagerEnabled() {
3275
+ return this.alive && this.pagerIsNavigable;
3471
3276
  }
3472
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: FilterCellTemplateDirective, deps: [{ token: i0.TemplateRef, optional: true }], target: i0.ɵɵFactoryTarget.Directive });
3473
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: FilterCellTemplateDirective, isStandalone: true, selector: "[kendoGridFilterCellTemplate]", ngImport: i0 });
3474
- }
3475
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: FilterCellTemplateDirective, decorators: [{
3476
- type: Directive,
3477
- args: [{
3478
- selector: '[kendoGridFilterCellTemplate]',
3479
- standalone: true
3480
- }]
3481
- }], ctorParameters: function () { return [{ type: i0.TemplateRef, decorators: [{
3482
- type: Optional
3483
- }] }]; } });
3484
-
3485
- /**
3486
- * Represents the filter-menu template.
3487
- * Helps to customize the content of the filter menu. To define the filter menu template, nest an `<ng-template>` tag with the
3488
- * `kendoGridFilterMenuTemplate` directive inside a `<kendo-grid-column>` tag
3489
- * ([see example]({% slug filter_menu %}#toc-custom-filters)).
3490
- *
3491
- * The template context is set to the current data item and the following additional fields are passed:
3492
- * - `column`&mdash;Defines an instance of the [`ColumnComponent`]({% slug api_grid_columncomponent %}) option. Use it as an alias for a template variable by utilizing the `let-column="column"` syntax.
3493
- * - `filter`&mdash;The provided filter descriptors. Use it as an alias for a template variable by utilizing the `let-filter="filter"` syntax.
3494
- * - `filterService`&mdash;Represents the [`FilterService`]({% slug api_grid_filterservice %}). Use it as an alias for a template variable by utilizing the `let-filterService="filterService"` syntax.
3495
- *
3496
- * ```html
3497
- * <kendo-grid-column field="CategoryID" title="Category">
3498
- * <ng-template kendoGridFilterMenuTemplate
3499
- * let-column="column"
3500
- * let-filter="filter"
3501
- * let-filterService="filterService"
3502
- * >
3503
- * ...
3504
- * </ng-template>
3505
- * </kendo-grid-column>
3506
- * ```
3507
- */
3508
- class FilterMenuTemplateDirective {
3509
- templateRef;
3510
- constructor(templateRef) {
3511
- this.templateRef = templateRef;
3277
+ get tableEnabled() {
3278
+ return this.alive && this.tableIsNavigable;
3512
3279
  }
3513
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: FilterMenuTemplateDirective, deps: [{ token: i0.TemplateRef, optional: true }], target: i0.ɵɵFactoryTarget.Directive });
3514
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: FilterMenuTemplateDirective, isStandalone: true, selector: "[kendoGridFilterMenuTemplate]", ngImport: i0 });
3515
- }
3516
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: FilterMenuTemplateDirective, decorators: [{
3517
- type: Directive,
3518
- args: [{
3519
- selector: '[kendoGridFilterMenuTemplate]',
3520
- standalone: true
3521
- }]
3522
- }], ctorParameters: function () { return [{ type: i0.TemplateRef, decorators: [{
3523
- type: Optional
3524
- }] }]; } });
3525
-
3526
- /**
3527
- * @hidden
3528
- */
3529
- function isColumnComponent(column) {
3530
- return isPresent(column.field);
3531
- }
3532
- /**
3533
- * Represents the column of the Grid. [See example](slug:columns_config#toc-using-the-column-component)
3534
- *
3535
- * @example
3536
- * ```html
3537
- * <kendo-grid [data]="gridData">
3538
- * <kendo-grid-column field="ProductID" title="Product ID"></kendo-grid-column>
3539
- * <kendo-grid-column field="ProductName" title="Product Name"></kendo-grid-column>
3540
- * <kendo-grid-column field="UnitPrice" title="Unit Price"></kendo-grid-column>
3541
- * </kendo-grid>
3542
- * ```
3543
- */
3544
- class ColumnComponent extends ColumnBase {
3545
- /**
3546
- * The field to which the column is bound.
3547
- */
3548
- field;
3549
- /**
3550
- * The format that is applied to the value before it is displayed. For more information on the supported date and number formats,
3551
- * refer to the [Column Formats](slug:formats_columns_grid) documentation article.
3552
- */
3553
- format;
3554
- /**
3555
- * Allows the user to click the column headers and emits the `sortChange` event. [See example](slug:sorting_grid).
3556
- *
3557
- * @default true
3558
- */
3559
- sortable = true;
3560
- /**
3561
- * Determines if the column can be dragged to the group panel.
3562
- * If set to `false`, you can group the columns by the column field by using the API of the Grid.
3563
- *
3564
- * @default true
3565
- */
3566
- groupable = true;
3567
- /**
3568
- * Defines the editor type. [See example](slug:inline_editing_grid#toc-using-reactive-forms).
3569
- * Used when the column enters the edit mode.
3570
- *
3571
- * @default 'text'
3572
- */
3573
- editor = 'text';
3574
- /**
3575
- * Defines the filter type that is displayed inside the filter row. [See example](slug:filtering_grid#toc-filter-data-types).
3576
- *
3577
- * @default 'text'
3578
- */
3579
- filter = 'text';
3580
- /**
3581
- * Defines if a filter UI will be displayed for this column. [See example](slug:filtering_grid).
3582
- *
3583
- * @default true
3584
- */
3585
- filterable = true;
3586
- /**
3587
- * Defines whether the column is editable. [See example](slug:make_fields_uneditable_grid).
3588
- *
3589
- * @default true
3590
- */
3591
- editable = true;
3592
- template;
3593
- groupHeaderTemplate;
3594
- groupHeaderColumnTemplate;
3595
- groupFooterTemplate;
3596
- editTemplate;
3597
- filterCellTemplate;
3598
- filterMenuTemplate;
3599
- constructor(parent, idService) {
3600
- super(parent, idService);
3280
+ get toolbarEnabled() {
3281
+ return this.alive && this.toolbarIsNavigable;
3282
+ }
3283
+ get activeCell() {
3284
+ if (this.mode !== 0 /* NavigationMode.Standby */) {
3285
+ return this.cursor.cell;
3286
+ }
3287
+ }
3288
+ get activeRow() {
3289
+ if (this.mode !== 0 /* NavigationMode.Standby */) {
3290
+ return Object.assign({}, this.cursor.row, {
3291
+ cells: this.cursor.row?.cells.toArray()
3292
+ });
3293
+ }
3294
+ }
3295
+ get isColumnResizable() {
3296
+ return this.activeCell.colIndex !== this.ctx.grid.columnsContainer.leafColumnsToRender.length - 1;
3297
+ }
3298
+ viewport;
3299
+ columnViewport;
3300
+ activeRowIndex = 0;
3301
+ alive = false;
3302
+ active = true;
3303
+ mode = 0 /* NavigationMode.Standby */;
3304
+ model = new NavigationModel();
3305
+ cursor = new NavigationCursor(this.model);
3306
+ meta;
3307
+ subs;
3308
+ pendingRowIndex;
3309
+ virtualCell;
3310
+ pagerIsNavigable = false;
3311
+ tableIsNavigable = false;
3312
+ toolbarIsNavigable = false;
3313
+ get activeDataRow() {
3314
+ return Math.max(0, this.activeRowIndex - this.meta.headerRows);
3315
+ }
3316
+ constructor(zone, domEvents, pagerContextService, scrollRequestService, groupsService, detailsService, focusRoot, editService, cd, ctx, resizeService, focusableParent) {
3317
+ this.zone = zone;
3318
+ this.domEvents = domEvents;
3319
+ this.pagerContextService = pagerContextService;
3320
+ this.scrollRequestService = scrollRequestService;
3321
+ this.groupsService = groupsService;
3322
+ this.detailsService = detailsService;
3323
+ this.focusRoot = focusRoot;
3324
+ this.editService = editService;
3325
+ this.cd = cd;
3326
+ this.ctx = ctx;
3327
+ this.resizeService = resizeService;
3328
+ this.focusableParent = focusableParent;
3329
+ this.changes = this.cursor.changes;
3330
+ }
3331
+ init(meta, navigableOptions) {
3332
+ this.setActiveSections(navigableOptions);
3333
+ this.alive = true;
3334
+ this.focusRoot.active = true;
3335
+ this.metadata = meta;
3336
+ const onStableSubscriber = (...operators) => (args) => this.zone.isStable ?
3337
+ from([true]).pipe(map(() => args)) :
3338
+ this.zone.onStable.pipe(take(1), map(() => args), ...operators);
3339
+ const onStable = onStableSubscriber();
3340
+ this.subs = new Subscription();
3341
+ this.subs.add(this.cursor.changes.subscribe(args => this.onCursorChanges(args)));
3342
+ this.subs.add(this.domEvents.focus.pipe(switchMap(onStable))
3343
+ .subscribe((args) => this.navigateTo(args.target)));
3344
+ this.subs.add(this.domEvents.focusOut.pipe(filter(() => this.mode !== 0 /* NavigationMode.Standby */), switchMap(onStableSubscriber(takeUntil(this.domEvents.focus))))
3345
+ .subscribe(args => this.onFocusOut(args)));
3346
+ this.subs.add(this.domEvents.windowBlur.pipe(filter(() => this.mode !== 0 /* NavigationMode.Standby */))
3347
+ .subscribe(() => this.onWindowBlur()));
3348
+ this.subs.add(
3349
+ // Closing the editor will not always trigger focusout in Firefox.
3350
+ // To get around this, we ensure that the cell is closed after editing.
3351
+ this.editService.changes.pipe(filter(e => e.action !== 'edit' && this.mode === 2 /* NavigationMode.Content */), filter((e) => e.action === 'cellClose' && !e.prevented), switchMap(onStable))
3352
+ .subscribe(() => this.leaveCell()));
3353
+ this.subs.add(this.pagerContextService.pageChange
3354
+ .subscribe(() => this.cursor.reset(0, 0)));
3355
+ this.subs.add(this.domEvents.keydown
3356
+ .subscribe(args => this.onKeydown(args)));
3357
+ this.subs.add(this.domEvents.keydown.pipe(filter(args => args.keyCode === Keys.Tab && this.mode === 2 /* NavigationMode.Content */), switchMapTo(this.domEvents.focusOut.pipe(takeUntil(
3358
+ // Timeout if focusOut doesn't fire very soon
3359
+ interval(0).pipe(take(1))))))
3360
+ .subscribe(() => this.onTabout()));
3361
+ if (this.focusableParent) {
3362
+ const element = new GridFocusableElement(this);
3363
+ this.focusableParent.registerElement(element);
3364
+ }
3365
+ this.deactivateElements();
3366
+ }
3367
+ ngOnDestroy() {
3368
+ if (this.subs) {
3369
+ this.subs.unsubscribe();
3370
+ }
3371
+ this.alive = false;
3372
+ }
3373
+ registerCell(cell) {
3374
+ if (cell.logicalRowIndex !== this.pendingRowIndex) {
3375
+ const modelCell = this.model.registerCell(cell);
3376
+ if (this.virtualCell && this.cursor.activateVirtualCell(modelCell)) {
3377
+ this.virtualCell = false;
3378
+ }
3379
+ }
3380
+ }
3381
+ registerCellOnCurrentRow(cell) {
3382
+ if (cell.logicalRowIndex === this.pendingRowIndex) {
3383
+ this.model.registerCell(cell);
3384
+ }
3385
+ }
3386
+ unregisterCell(index, rowIndex, cell) {
3387
+ this.model.unregisterCell(index, rowIndex, cell);
3388
+ }
3389
+ registerRow(row) {
3390
+ this.model.registerRow(row);
3391
+ this.pendingRowIndex = row.logicalRowIndex;
3392
+ }
3393
+ updateRow(row) {
3394
+ this.model.updateRow(row);
3395
+ }
3396
+ unregisterRow(index, row) {
3397
+ this.model.unregisterRow(index, row);
3398
+ const lastRow = this.model.lastRow;
3399
+ if (lastRow && this.mode === 0 /* NavigationMode.Standby */) {
3400
+ const maxIndex = (this.needsViewport() && this.viewport) ? this.viewport.lastItemIndex : lastRow.index;
3401
+ if (this.activeRowIndex > maxIndex) {
3402
+ this.cursor.reset(0, 0);
3403
+ }
3404
+ }
3405
+ }
3406
+ isCellFocusable(cell) {
3407
+ return this.alive &&
3408
+ this.active &&
3409
+ this.mode !== 2 /* NavigationMode.Content */ &&
3410
+ this.cursor.isActive(cell.logicalRowIndex, cell.logicalColIndex);
3411
+ }
3412
+ isCellFocused(cell) {
3413
+ return this.mode === 1 /* NavigationMode.Cursor */ && this.isCellFocusable(cell);
3414
+ }
3415
+ navigateTo(el) {
3416
+ if (!this.alive || !isDocumentAvailable()) {
3417
+ return;
3418
+ }
3419
+ const cell = targetCell(el, this.meta.gridElement.nativeElement);
3420
+ if (!cell) {
3421
+ return;
3422
+ }
3423
+ const oldMode = this.mode;
3424
+ const focusInCell = contains$1(cell.element, document.activeElement);
3425
+ const focusInActiveRowContent = this.mode === 2 /* NavigationMode.Content */ &&
3426
+ this.activeRowIndex === cell.rowIndex &&
3427
+ el !== cell.element;
3428
+ if (focusInCell) {
3429
+ this.mode = 2 /* NavigationMode.Content */;
3430
+ this.cursor.reset(cell.rowIndex, cell.colIndex);
3431
+ this.activateRow();
3432
+ }
3433
+ else if (!focusInActiveRowContent) {
3434
+ this.mode = 1 /* NavigationMode.Cursor */;
3435
+ this.deactivateElements();
3436
+ const alreadyActive = this.cursor.isActive(cell.rowIndex, cell.colIndex);
3437
+ const isCursor = oldMode === 1 /* NavigationMode.Cursor */ && alreadyActive;
3438
+ if (!isCursor) {
3439
+ this.cursor.reset(cell.rowIndex, cell.colIndex);
3440
+ }
3441
+ }
3442
+ }
3443
+ tryFocus(el) {
3444
+ this.activateElements();
3445
+ const focusable = findFocusableChild(el);
3446
+ if (focusable) {
3447
+ const cell = targetCell(focusable, this.meta.gridElement.nativeElement);
3448
+ if (cell) {
3449
+ this.cursor.reset(cell.rowIndex, cell.colIndex);
3450
+ this.deactivateElements();
3451
+ this.enterCell();
3452
+ }
3453
+ focusable.focus();
3454
+ }
3455
+ else {
3456
+ this.deactivateElements();
3457
+ }
3458
+ return !!focusable;
3459
+ }
3460
+ needsViewport() {
3461
+ return this.meta && this.meta.isVirtual;
3462
+ }
3463
+ setViewport(firstItemIndex, lastItemIndex) {
3464
+ this.viewport = new NavigationViewport(firstItemIndex, lastItemIndex);
3465
+ if (this.meta && this.meta.isVirtual && this.activeDataRow > -1) {
3466
+ const dataRowIndex = this.activeDataRow;
3467
+ const ahead = firstItemIndex - dataRowIndex;
3468
+ const behind = dataRowIndex - lastItemIndex;
3469
+ if (ahead > 0) {
3470
+ this.cursor.reset(firstItemIndex + this.meta.headerRows);
3471
+ }
3472
+ else if (behind > 0) {
3473
+ this.cursor.reset(lastItemIndex - this.meta.headerRows);
3474
+ }
3475
+ }
3476
+ }
3477
+ setColumnViewport(firstItemIndex, lastItemIndex) {
3478
+ this.columnViewport = new NavigationViewport(firstItemIndex, lastItemIndex);
3479
+ if (this.meta && this.meta.isVirtual && this.activeDataRow > -1) {
3480
+ const activeColumnIndex = this.cursor.cell ? this.cursor.cell.colIndex : 0;
3481
+ const ahead = firstItemIndex - activeColumnIndex;
3482
+ const behind = activeColumnIndex - lastItemIndex;
3483
+ if (ahead > 0) {
3484
+ this.cursor.reset(undefined, firstItemIndex, false);
3485
+ }
3486
+ else if (behind > 0) {
3487
+ this.cursor.reset(undefined, lastItemIndex, false);
3488
+ }
3489
+ }
3490
+ }
3491
+ focusCell(rowIndex = undefined, colIndex = undefined) {
3492
+ this.mode = 1 /* NavigationMode.Cursor */;
3493
+ this.cursor.reset(rowIndex, colIndex);
3494
+ return this.activeCell;
3495
+ }
3496
+ focusCellByElement(el) {
3497
+ const cell = targetCell(el, this.meta.gridElement.nativeElement);
3498
+ if (cell) {
3499
+ return this.focusCell(cell.rowIndex, cell.colIndex);
3500
+ }
3501
+ }
3502
+ focusNextCell(wrap = true) {
3503
+ return this.focusAdjacentCell(true, wrap);
3504
+ }
3505
+ focusPrevCell(wrap = true) {
3506
+ return this.focusAdjacentCell(false, wrap);
3507
+ }
3508
+ toggle(active) {
3509
+ this.active = active;
3510
+ this.cursor.announce();
3511
+ }
3512
+ hasFocus() {
3513
+ return this.mode === 1 /* NavigationMode.Cursor */ || this.mode === 2 /* NavigationMode.Content */;
3514
+ }
3515
+ autoFocusCell(start, end) {
3516
+ return !this.meta.virtualColumns || end < this.meta.columns.lockedLeafColumns.length || this.columnViewport.intersects(start, end);
3517
+ }
3518
+ setActiveSections(navigableOptions) {
3519
+ this.pagerIsNavigable = navigableOptions.includes('pager');
3520
+ this.tableIsNavigable = navigableOptions.includes('table');
3521
+ this.toolbarIsNavigable = navigableOptions.includes('toolbar');
3522
+ }
3523
+ focusAdjacentCell(fwd, wrap) {
3524
+ this.focusCell();
3525
+ let success = fwd ? this.moveCursorFwd() : this.moveCursorBwd();
3526
+ if (wrap && !success) {
3527
+ success = fwd ? this.cursor.moveDown(1) : this.cursor.moveUp(1);
3528
+ if (success) {
3529
+ const row = this.cursor.row;
3530
+ const colIdx = fwd ? 0 : this.cursor.lastCellIndex(row);
3531
+ this.cursor.reset(row.index, colIdx);
3532
+ }
3533
+ }
3534
+ if (success) {
3535
+ return this.activeCell;
3536
+ }
3537
+ else {
3538
+ this.mode = 0 /* NavigationMode.Standby */;
3539
+ this.cursor.announce();
3540
+ }
3541
+ return null;
3542
+ }
3543
+ enterCell() {
3544
+ const cell = this.cursor.cell;
3545
+ if (!cell) {
3546
+ return;
3547
+ }
3548
+ const group = cell.focusGroup;
3549
+ const focusable = group && group.canFocus();
3550
+ this.mode = focusable ? 2 /* NavigationMode.Content */ : 1 /* NavigationMode.Cursor */;
3551
+ this.cursor.announce();
3552
+ if (focusable) {
3553
+ this.activateRow();
3554
+ group.focus();
3555
+ }
3556
+ }
3557
+ leaveCell() {
3558
+ const cell = this.cursor.cell;
3559
+ if (!cell) {
3560
+ return;
3561
+ }
3562
+ const group = cell.focusGroup;
3563
+ const focusable = group && group.canFocus();
3564
+ if (!focusable) {
3565
+ this.deactivateElements();
3566
+ }
3567
+ this.mode = 1 /* NavigationMode.Cursor */;
3568
+ this.cursor.announce();
3569
+ }
3570
+ activateElements() {
3571
+ this.focusRoot.activate();
3572
+ }
3573
+ deactivateElements() {
3574
+ this.focusRoot.deactivate();
3575
+ }
3576
+ activateRow() {
3577
+ this.cursor.row.cells
3578
+ .forEach(cell => cell.focusGroup && cell.focusGroup.activate());
3579
+ }
3580
+ moveCursorFwd() {
3581
+ return this.ctx.localization.rtl ? this.cursor.moveLeft() : this.cursor.moveRight();
3582
+ }
3583
+ moveCursorBwd() {
3584
+ return this.ctx.localization.rtl ? this.cursor.moveRight() : this.cursor.moveLeft();
3585
+ }
3586
+ onCursorKeydown(args) {
3587
+ let preventDefault = false;
3588
+ const modifier = args.ctrlKey || args.metaKey;
3589
+ const step = modifier ? 5 : 1;
3590
+ if (!this.onCellKeydown(args)) {
3591
+ return;
3592
+ }
3593
+ const row = this.cursor.row;
3594
+ switch (args.keyCode) {
3595
+ case Keys.ArrowDown:
3596
+ if (args.shiftKey) {
3597
+ if (this.ctx.grid.blockArrowSelection) {
3598
+ return;
3599
+ }
3600
+ preventDefault = this.cursor.moveDown(step);
3601
+ if (this.activeRow?.dataItem) {
3602
+ this.handleVerticalArrowSelection(step);
3603
+ }
3604
+ }
3605
+ else {
3606
+ preventDefault = this.cursor.moveDown(step);
3607
+ }
3608
+ break;
3609
+ case Keys.ArrowUp:
3610
+ if (args.shiftKey) {
3611
+ if (this.ctx.grid.blockArrowSelection) {
3612
+ return;
3613
+ }
3614
+ preventDefault = this.cursor.moveUp(step);
3615
+ if (this.activeRow?.dataItem) {
3616
+ this.handleVerticalArrowSelection(-step);
3617
+ }
3618
+ }
3619
+ else {
3620
+ preventDefault = this.cursor.moveUp(step);
3621
+ }
3622
+ break;
3623
+ case Keys.ArrowRight:
3624
+ if (args.altKey && this.ctx.grid.resizable && this.isColumnResizable) {
3625
+ this.columnResize(true);
3626
+ break;
3627
+ }
3628
+ if (args.shiftKey) {
3629
+ if (this.ctx.grid.blockArrowSelection) {
3630
+ return;
3631
+ }
3632
+ preventDefault = this.moveCursorFwd();
3633
+ this.handleHorizontalArrowSelection(args);
3634
+ }
3635
+ else {
3636
+ preventDefault = this.moveCursorFwd();
3637
+ }
3638
+ break;
3639
+ case Keys.ArrowLeft:
3640
+ if (args.altKey && this.ctx.grid.resizable && this.isColumnResizable) {
3641
+ this.columnResize(false);
3642
+ break;
3643
+ }
3644
+ if (args.shiftKey) {
3645
+ if (this.ctx.grid.blockArrowSelection) {
3646
+ return;
3647
+ }
3648
+ preventDefault = this.moveCursorBwd();
3649
+ this.handleHorizontalArrowSelection(args);
3650
+ }
3651
+ else {
3652
+ preventDefault = this.moveCursorBwd();
3653
+ }
3654
+ break;
3655
+ case Keys.PageDown:
3656
+ if (this.metadata.isVirtual && this.viewport) {
3657
+ let nextItemIndex = this.meta.headerRows + this.viewport.lastItemIndex + 1;
3658
+ if (this.metadata.hasDetailTemplate) {
3659
+ nextItemIndex++;
3660
+ }
3661
+ nextItemIndex = Math.min(this.meta.maxLogicalRowIndex, nextItemIndex);
3662
+ this.cursor.reset(nextItemIndex);
3663
+ preventDefault = true;
3664
+ }
3665
+ else if (this.metadata.hasPager) {
3666
+ this.zone.run(() => this.pagerContextService.nextPage());
3667
+ preventDefault = true;
3668
+ }
3669
+ break;
3670
+ case Keys.PageUp:
3671
+ if (this.metadata.isVirtual && this.viewport) {
3672
+ const viewportSize = this.viewport.lastItemIndex - this.viewport.firstItemIndex;
3673
+ const firstItemIndex = this.viewport.firstItemIndex;
3674
+ const nextItemIndex = Math.max(this.meta.headerRows, firstItemIndex - viewportSize - 1);
3675
+ this.cursor.reset(nextItemIndex);
3676
+ preventDefault = true;
3677
+ }
3678
+ else if (this.metadata.hasPager) {
3679
+ this.zone.run(() => this.pagerContextService.prevPage());
3680
+ preventDefault = true;
3681
+ }
3682
+ break;
3683
+ case Keys.Home:
3684
+ if (modifier) {
3685
+ if (this.meta.isVirtual) {
3686
+ this.cursor.reset(this.meta.headerRows, 0, false);
3687
+ }
3688
+ else {
3689
+ this.cursor.reset(this.model.firstRow.index, 0, false);
3690
+ }
3691
+ }
3692
+ else {
3693
+ let firstColumnIndex = 0;
3694
+ if (this.meta.hasDetailTemplate && row.index < this.meta.headerRows) {
3695
+ firstColumnIndex = 1;
3696
+ }
3697
+ this.cursor.reset(row.index, firstColumnIndex, false);
3698
+ }
3699
+ preventDefault = true;
3700
+ break;
3701
+ case Keys.End:
3702
+ if (modifier) {
3703
+ if (this.meta.isVirtual) {
3704
+ let lastRowIndex = this.meta.maxLogicalRowIndex;
3705
+ if (this.meta.hasDetailTemplate) {
3706
+ lastRowIndex--;
3707
+ }
3708
+ this.cursor.reset(lastRowIndex, this.cursor.lastCellIndex(), false);
3709
+ }
3710
+ else {
3711
+ this.cursor.reset(this.model.lastRow.index, this.cursor.lastCellIndex(this.model.lastRow), false);
3712
+ }
3713
+ }
3714
+ else {
3715
+ const lastIndex = this.cursor.lastCellIndex(row);
3716
+ const cell = this.model.findCell(lastIndex, row);
3717
+ if (cell) {
3718
+ this.cursor.reset(cell.rowIndex, cell.colIndex);
3719
+ }
3720
+ else {
3721
+ this.cursor.reset(row.index, lastIndex);
3722
+ }
3723
+ }
3724
+ preventDefault = true;
3725
+ break;
3726
+ case Keys.Enter:
3727
+ case Keys.F2: {
3728
+ const groupItem = row.groupItem;
3729
+ if (groupItem) {
3730
+ this.zone.run(() => this.groupsService.toggleRow(groupItem));
3731
+ }
3732
+ else if (this.cursor.cell.detailExpandCell) {
3733
+ this.zone.run(() => this.detailsService.toggleRow(row.dataRowIndex, row.dataItem));
3734
+ }
3735
+ else {
3736
+ this.enterCell();
3737
+ if (!this.cursor.cell.focusGroup.isNavigable()) {
3738
+ preventDefault = true;
3739
+ }
3740
+ }
3741
+ break;
3742
+ }
3743
+ default:
3744
+ if (!args.ctrlKey && !args.altKey && isPrintableCharacter(args.key)) {
3745
+ this.enterCell();
3746
+ }
3747
+ }
3748
+ if (preventDefault) {
3749
+ args.preventDefault();
3750
+ }
3601
3751
  }
3602
- get templateRef() {
3603
- return this.template ? this.template.templateRef : undefined;
3752
+ columnResize(onRightArrow) {
3753
+ const column = this.ctx.grid.columnsContainer.leafColumnsToRender[this.activeCell.colIndex];
3754
+ column.resizeStartWidth = Array.from(this.ctx.grid.wrapper.nativeElement.querySelectorAll('.k-grid-header th.k-header'))[this.activeCell.colIndex]['offsetWidth'];
3755
+ this.resizeService.start(column);
3756
+ this.resizeService.resizeColumns(onRightArrow ? resizeStep : -1 * resizeStep);
3757
+ if (this.resizeService.resizeColumns.length > 0) {
3758
+ this.resizeService.end();
3759
+ }
3604
3760
  }
3605
- get groupHeaderTemplateRef() {
3606
- return this.groupHeaderTemplate ? this.groupHeaderTemplate.templateRef : undefined;
3761
+ onContentKeydown(args) {
3762
+ if (!this.onCellKeydown(args)) {
3763
+ return;
3764
+ }
3765
+ const confirm = !args.defaultPrevented && args.keyCode === Keys.Enter && isTextInput(args.srcElement);
3766
+ if (args.keyCode === Keys.Escape || args.keyCode === Keys.F2 || confirm) {
3767
+ this.leaveCell();
3768
+ this.cursor.reset();
3769
+ args.stopPropagation();
3770
+ }
3771
+ else if (isNavigationKey(args.keyCode) && this.cursor.cell.focusGroup.isNavigable()) {
3772
+ this.onCursorKeydown(args);
3773
+ if (args.defaultPrevented) {
3774
+ this.leaveCell();
3775
+ }
3776
+ }
3607
3777
  }
3608
- get groupHeaderColumnTemplateRef() {
3609
- return this.groupHeaderColumnTemplate ? this.groupHeaderColumnTemplate.templateRef : undefined;
3778
+ onCellKeydown(args) {
3779
+ if (this.editService.isEditingCell()) {
3780
+ const confirm = args.keyCode === Keys.Enter;
3781
+ const cancel = args.keyCode === Keys.Escape;
3782
+ const navigate = isNavigationKey(args.keyCode);
3783
+ if (confirm) {
3784
+ this.editService.closeCell(args);
3785
+ }
3786
+ else if (cancel) {
3787
+ this.editService.closeCell(args);
3788
+ this.cd.detectChanges();
3789
+ }
3790
+ else if (navigate) {
3791
+ return false;
3792
+ }
3793
+ }
3794
+ this.cellKeydown.emit(args);
3795
+ return true;
3610
3796
  }
3611
- get groupFooterTemplateRef() {
3612
- return this.groupFooterTemplate ? this.groupFooterTemplate.templateRef : undefined;
3797
+ onCursorChanges(args) {
3798
+ this.activeRowIndex = args.rowIndex;
3799
+ const dataRowIndex = this.activeDataRow;
3800
+ if (this.meta && (this.meta.isVirtual &&
3801
+ args.rowIndex >= this.meta.headerRows &&
3802
+ this.viewport &&
3803
+ !this.viewport.containsRow(dataRowIndex) && dataRowIndex > -1)) {
3804
+ this.scrollRequestService.scrollTo({ row: dataRowIndex });
3805
+ }
3806
+ if (this.meta.virtualColumns && args.colIndex >= this.meta.columns.lockedLeafColumns.length) {
3807
+ const cell = this.activeCell;
3808
+ const { start, end } = this.model.cellRange(cell);
3809
+ if (!cell) {
3810
+ this.virtualCell = true;
3811
+ }
3812
+ if ((!cell && this.mode !== 0 /* NavigationMode.Standby */) || (cell && !this.columnViewport.intersects(start, end))) {
3813
+ this.scrollRequestService.scrollTo({ column: args.colIndex - (this.metadata.hasDetailTemplate ? 1 : 0) });
3814
+ }
3815
+ }
3613
3816
  }
3614
- get editTemplateRef() {
3615
- return this.editTemplate ? this.editTemplate.templateRef : undefined;
3817
+ onFocusOut(args) {
3818
+ if (isVisible(args.target)) {
3819
+ this.mode = 0 /* NavigationMode.Standby */;
3820
+ }
3821
+ else {
3822
+ // Focused target is no longer visible,
3823
+ // reset to cursor mode and recapture focus.
3824
+ this.mode = 1 /* NavigationMode.Cursor */;
3825
+ }
3826
+ this.deactivateElements();
3827
+ this.cursor.announce();
3616
3828
  }
3617
- get filterCellTemplateRef() {
3618
- return this.filterCellTemplate ? this.filterCellTemplate.templateRef : undefined;
3829
+ onWindowBlur() {
3830
+ this.mode = 0 /* NavigationMode.Standby */;
3831
+ this.deactivateElements();
3832
+ this.cursor.announce();
3619
3833
  }
3620
- get filterMenuTemplateRef() {
3621
- return this.filterMenuTemplate ? this.filterMenuTemplate.templateRef : undefined;
3834
+ onKeydown(args) {
3835
+ if (this.mode === 1 /* NavigationMode.Cursor */) {
3836
+ this.onCursorKeydown(args);
3837
+ }
3838
+ else if (this.mode === 2 /* NavigationMode.Content */) {
3839
+ this.onContentKeydown(args);
3840
+ }
3622
3841
  }
3623
- get displayTitle() {
3624
- return this.title === undefined ? this.field : this.title;
3842
+ onTabout() {
3843
+ // Tabbed out of the last focusable content element
3844
+ // reset to cursor mode and recapture focus.
3845
+ if (this.cursor.cell.focusGroup.isNavigable()) {
3846
+ // Unless the cell has a single focusable element,
3847
+ // otherwise we'd return to Content mode and enter an endless loop
3848
+ return;
3849
+ }
3850
+ this.leaveCell();
3851
+ this.cursor.reset();
3625
3852
  }
3626
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ColumnComponent, deps: [{ token: ColumnBase, host: true, optional: true, skipSelf: true }, { token: IdService, optional: true }], target: i0.ɵɵFactoryTarget.Component });
3627
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: ColumnComponent, isStandalone: true, selector: "kendo-grid-column", inputs: { field: "field", format: "format", sortable: "sortable", groupable: "groupable", editor: "editor", filter: "filter", filterable: "filterable", editable: "editable" }, providers: [
3628
- {
3629
- provide: ColumnBase,
3630
- useExisting: forwardRef(() => ColumnComponent)
3853
+ handleVerticalArrowSelection(args) {
3854
+ const cellSelectionEnabled = this.ctx.grid.cellSelectionService.active;
3855
+ const rowSelectionEnabled = this.ctx.grid.selectionService.active && !this.ctx.grid.selectableSettings.checkboxOnly;
3856
+ if (cellSelectionEnabled || rowSelectionEnabled) {
3857
+ const selectionService = this.ctx.grid[cellSelectionEnabled ? 'cellSelectionService' : 'selectionService'];
3858
+ const colIdx = this.cursor.cell ? this.cursor.cell.colIndex : 0;
3859
+ const rowIdx = this.activeRow.dataRowIndex - this.ctx.grid.skip;
3860
+ const dataItem = selectionService.settings.view.at(rowIdx);
3861
+ const item = { index: this.activeRow.dataRowIndex, data: dataItem, column: this.ctx.grid.columnsContainer.leafColumnsToRender[colIdx] };
3862
+ if (selectionService.options.mode === 'multiple') {
3863
+ cellSelectionEnabled ? this.handleMultipleArrowCellSelection(item) : this.handleMultipleArrowRowSelection(item);
3631
3864
  }
3632
- ], queries: [{ propertyName: "template", first: true, predicate: CellTemplateDirective, descendants: true }, { propertyName: "groupHeaderTemplate", first: true, predicate: GroupHeaderTemplateDirective, descendants: true }, { propertyName: "groupHeaderColumnTemplate", first: true, predicate: GroupHeaderColumnTemplateDirective, descendants: true }, { propertyName: "groupFooterTemplate", first: true, predicate: GroupFooterTemplateDirective, descendants: true }, { propertyName: "editTemplate", first: true, predicate: EditTemplateDirective, descendants: true }, { propertyName: "filterCellTemplate", first: true, predicate: FilterCellTemplateDirective, descendants: true }, { propertyName: "filterMenuTemplate", first: true, predicate: FilterMenuTemplateDirective, descendants: true }], usesInheritance: true, ngImport: i0, template: ``, isInline: true });
3633
- }
3634
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ColumnComponent, decorators: [{
3635
- type: Component,
3636
- args: [{
3637
- providers: [
3638
- {
3639
- provide: ColumnBase,
3640
- useExisting: forwardRef(() => ColumnComponent)
3641
- }
3642
- ],
3643
- selector: 'kendo-grid-column',
3644
- template: ``,
3645
- standalone: true
3646
- }]
3647
- }], ctorParameters: function () { return [{ type: ColumnBase, decorators: [{
3648
- type: SkipSelf
3649
- }, {
3650
- type: Host
3651
- }, {
3652
- type: Optional
3653
- }] }, { type: IdService, decorators: [{
3654
- type: Optional
3655
- }] }]; }, propDecorators: { field: [{
3656
- type: Input
3657
- }], format: [{
3658
- type: Input
3659
- }], sortable: [{
3660
- type: Input
3661
- }], groupable: [{
3662
- type: Input
3663
- }], editor: [{
3664
- type: Input
3665
- }], filter: [{
3666
- type: Input
3667
- }], filterable: [{
3668
- type: Input
3669
- }], editable: [{
3670
- type: Input
3671
- }], template: [{
3672
- type: ContentChild,
3673
- args: [CellTemplateDirective, { static: false }]
3674
- }], groupHeaderTemplate: [{
3675
- type: ContentChild,
3676
- args: [GroupHeaderTemplateDirective, { static: false }]
3677
- }], groupHeaderColumnTemplate: [{
3678
- type: ContentChild,
3679
- args: [GroupHeaderColumnTemplateDirective, { static: false }]
3680
- }], groupFooterTemplate: [{
3681
- type: ContentChild,
3682
- args: [GroupFooterTemplateDirective, { static: false }]
3683
- }], editTemplate: [{
3684
- type: ContentChild,
3685
- args: [EditTemplateDirective, { static: false }]
3686
- }], filterCellTemplate: [{
3687
- type: ContentChild,
3688
- args: [FilterCellTemplateDirective, { static: false }]
3689
- }], filterMenuTemplate: [{
3690
- type: ContentChild,
3691
- args: [FilterMenuTemplateDirective, { static: false }]
3692
- }] } });
3693
-
3694
- /**
3695
- * @hidden
3696
- */
3697
- function isSpanColumnComponent(column) {
3698
- return column.isSpanColumn;
3699
- }
3700
- /**
3701
- * Represents a column which can be spanned over multiple data cells while the individual
3702
- * header and footer cells are retained ([see example]({% slug spanned_columns_grid %})).
3703
- * Enables you to achieve more flexible layout while keeping the built-in UI element for
3704
- * [sorting]({% slug sorting_grid %}), [filtering]({% slug filtering_grid %}), and
3705
- * [grouping]({% slug grouping_grid %}). Wrap the columns that will be
3706
- * merged inside the `<kendo-grid-span-column>` tag.
3707
- *
3708
- * ```html
3709
- * <kendo-grid-span-column>
3710
- * <kendo-grid-column field="field1"></kendo-grid-column>
3711
- * <kendo-grid-column field="field2"></kendo-grid-column>
3712
- * <ng-template kendoGridCellTemplate let-dataItem>
3713
- * <h5>{{ dataItem.field1 }}</h5>
3714
- * <p>{{ dataItem.field2 }}</p>
3715
- * </ng-template>
3716
- * </kendo-grid-span-column>
3717
- * ```
3718
- */
3719
- class SpanColumnComponent extends ColumnBase {
3720
- /*
3721
- * @hidden
3722
- */
3723
- isSpanColumn = true;
3724
- template = new QueryList();
3725
- editTemplate = new QueryList();
3726
- /**
3727
- * @hidden
3728
- */
3729
- childColumns = new QueryList();
3730
- /**
3731
- * @hidden
3732
- */
3733
- title;
3734
- /**
3735
- * @hidden
3736
- */
3737
- headerStyle;
3738
- /**
3739
- * @hidden
3740
- */
3741
- footerStyle;
3742
- /**
3743
- * @hidden
3744
- */
3745
- headerClass;
3746
- /**
3747
- * @hidden
3748
- */
3749
- footerClass;
3750
- /**
3751
- * @hidden
3752
- */
3753
- includeInChooser = false;
3754
- /**
3755
- * Defines whether the edit template of the column will be rendered.
3756
- * To enable the editing functionality for a spanned column, set an edit template for it ([see example](slug:custom_reactive_editing_grid)).
3757
- * @default false
3758
- */
3759
- set editable(value) {
3760
- this._editable = value;
3761
- }
3762
- get editable() {
3763
- return isPresent(this.editTemplateRef) && this._editable;
3865
+ else {
3866
+ selectionService.handleClick(item, args);
3867
+ }
3868
+ }
3764
3869
  }
3765
- /**
3766
- * @hidden
3767
- * added for backwards compitability
3768
- */
3769
- set width(_value) {
3870
+ handleHorizontalArrowSelection(args) {
3871
+ const cellSelectionEnabled = this.ctx.grid.cellSelectionService.active;
3872
+ if (cellSelectionEnabled) {
3873
+ const selectionService = this.ctx.grid[cellSelectionEnabled ? 'cellSelectionService' : 'selectionService'];
3874
+ const row = this.activeRow;
3875
+ const colIdx = this.cursor.cell ? this.cursor.cell.colIndex : 0;
3876
+ const dataItem = selectionService.settings.view.at(row.dataRowIndex - this.ctx.grid.skip);
3877
+ const item = { index: row.dataRowIndex, data: dataItem, column: this.ctx.grid.columnsContainer.leafColumnsToRender[colIdx] };
3878
+ if (!isPresent$1(dataItem) || !isPresent$1(item.column)) {
3879
+ return;
3880
+ }
3881
+ if (selectionService.options.mode === 'multiple') {
3882
+ this.handleMultipleArrowCellSelection(item);
3883
+ }
3884
+ else {
3885
+ selectionService.handleClick(item, args);
3886
+ }
3887
+ }
3770
3888
  }
3771
- get width() {
3772
- return this.childColumns.reduce((total, column) => total + column.width, 0);
3889
+ handleMultipleArrowCellSelection(item) {
3890
+ const cellSelectionService = this.ctx.grid.cellSelectionService;
3891
+ const startRowIndex = Math.min(cellSelectionService.lastSelectionItemRowIndex, item.index);
3892
+ const startColIndex = Math.min(cellSelectionService.lastSelectionItemColIndex, item.column.leafIndex);
3893
+ const endRowIndex = Math.max(cellSelectionService.lastSelectionItemRowIndex, item.index);
3894
+ const endColIndex = Math.max(cellSelectionService.lastSelectionItemColIndex, item.column.leafIndex);
3895
+ const ev = cellSelectionService.selectRange(startRowIndex, startColIndex, endRowIndex, endColIndex);
3896
+ cellSelectionService.changes.emit(ev);
3773
3897
  }
3774
- /**
3775
- * @hidden
3776
- */
3777
- get leafIndex() {
3778
- return this.childColumns.first.leafIndex;
3898
+ handleMultipleArrowRowSelection(item) {
3899
+ const rowSelectionService = this.ctx.grid.selectionService;
3900
+ const startRowIndex = Math.min(rowSelectionService.lastSelectionStartIndex, item.index);
3901
+ const endRowIndex = Math.max(rowSelectionService.lastSelectionStartIndex, item.index);
3902
+ const ev = rowSelectionService.selectRange(startRowIndex, endRowIndex);
3903
+ rowSelectionService.changes.emit(ev);
3779
3904
  }
3780
- _editable = true;
3781
- constructor(parent, idService) {
3782
- super(parent, idService);
3783
- if (parent && parent.isSpanColumn) {
3784
- throw new Error(ColumnConfigurationErrorMessages.nestedInside('SpanColumnComponent', 'SpanColumnComponent'));
3785
- }
3905
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: NavigationService, deps: [{ token: i0.NgZone }, { token: DomEventsService }, { token: i44.PagerContextService }, { token: ScrollRequestService }, { token: GroupsService }, { token: DetailsService }, { token: FocusRoot }, { token: EditService }, { token: i0.ChangeDetectorRef }, { token: ContextService }, { token: ColumnResizingService }, { token: FocusableDirective, optional: true }], target: i0.ɵɵFactoryTarget.Injectable });
3906
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: NavigationService });
3907
+ }
3908
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: NavigationService, decorators: [{
3909
+ type: Injectable
3910
+ }], ctorParameters: function () { return [{ type: i0.NgZone }, { type: DomEventsService }, { type: i44.PagerContextService }, { type: ScrollRequestService }, { type: GroupsService }, { type: DetailsService }, { type: FocusRoot }, { type: EditService }, { type: i0.ChangeDetectorRef }, { type: ContextService }, { type: ColumnResizingService }, { type: FocusableDirective, decorators: [{
3911
+ type: Optional
3912
+ }] }]; } });
3913
+
3914
+ /**
3915
+ * @hidden
3916
+ */
3917
+ const preventOnDblClick$1 = release => mouseDown => of(mouseDown).pipe(delay(150), takeUntil(release));
3918
+ const hasClass = className => el => new RegExp(`(^| )${className}( |$)`).test(el.className);
3919
+ const isDeleteButton = or(hasClass('k-i-x'), hasClass('k-svg-i-x'), hasClass('k-icon-button'));
3920
+ const isSortIcon = or(hasClass('k-i-sort-asc-small'), hasClass('k-i-sort-desc-small'), hasClass('k-svg-i-sort-asc-small'), hasClass('k-svg-i-sort-desc-small'));
3921
+ const skipButtons = and(not(isDeleteButton), not(isSortIcon), not(isFocusableWithTabKey), not(matchesNodeName('label')));
3922
+ const elementUnderCursor = ({ clientX, clientY }) => isDocumentAvailable() && document.elementFromPoint(clientX, clientY);
3923
+ const hideThenShow = (element, cont) => {
3924
+ element.style.display = 'none';
3925
+ const result = cont();
3926
+ element.style.display = 'block';
3927
+ return result;
3928
+ };
3929
+ /**
3930
+ * @hidden
3931
+ */
3932
+ class DraggableColumnDirective {
3933
+ draggable;
3934
+ element;
3935
+ zone;
3936
+ service;
3937
+ hint;
3938
+ cue;
3939
+ nav;
3940
+ renderer;
3941
+ context = {};
3942
+ set enableDrag(enabled) {
3943
+ this.enabled = enabled;
3944
+ this.updateTouchAction();
3786
3945
  }
3787
- /**
3788
- * @hidden
3789
- */
3790
- get templateRef() {
3791
- const template = this.template.first;
3792
- return template ? template.templateRef : undefined;
3946
+ drag = new EventEmitter();
3947
+ subscriptions = new Subscription();
3948
+ enabled;
3949
+ constructor(draggable, element, zone, service, hint, cue, nav, renderer) {
3950
+ this.draggable = draggable;
3951
+ this.element = element;
3952
+ this.zone = zone;
3953
+ this.service = service;
3954
+ this.hint = hint;
3955
+ this.cue = cue;
3956
+ this.nav = nav;
3957
+ this.renderer = renderer;
3793
3958
  }
3794
- /**
3795
- * @hidden
3796
- */
3797
- get editTemplateRef() {
3798
- const editTemplate = this.editTemplate.first;
3799
- return editTemplate ? editTemplate.templateRef : undefined;
3959
+ ngOnInit() {
3960
+ this.subscriptions.add(this.zone.runOutsideAngular(() => this.draggable.kendoPress.pipe(filter(_ => this.enabled), filter(({ originalEvent: { target } }) => target === this.element.nativeElement || skipButtons(target)), tap((e) => {
3961
+ const originalEvent = e.originalEvent;
3962
+ if (!e.isTouch) {
3963
+ originalEvent.preventDefault();
3964
+ }
3965
+ this.nav.navigateTo(originalEvent.target);
3966
+ }), switchMap(preventOnDblClick$1(this.draggable.kendoRelease)), tap((_) => {
3967
+ this.hint.create(this.context.hint);
3968
+ this.cue.create();
3969
+ }), switchMap(down => this.draggable.kendoDrag.pipe(tap((e) => {
3970
+ if (e.isTouch) {
3971
+ e.originalEvent.preventDefault();
3972
+ }
3973
+ }), tap(this.hint.attach()), tap(this.cue.attach()), takeUntil(this.draggable.kendoRelease), map(move => ({ move, down })))), tap(this.performDrag.bind(this)), switchMapTo(this.draggable.kendoRelease)).subscribe(this.drop.bind(this))));
3800
3974
  }
3801
- /**
3802
- * @hidden
3803
- */
3804
- get colspan() {
3805
- return this.childColumns.filter(c => c.isVisible).length;
3975
+ ngOnDestroy() {
3976
+ if (this.subscriptions) {
3977
+ this.subscriptions.unsubscribe();
3978
+ }
3806
3979
  }
3807
- /**
3808
- * Toggles the locked (frozen) state of the columns ([see example](slug:locked_columns_grid)).
3809
- * @default false
3810
- */
3811
- set locked(value) {
3812
- this._locked = value;
3980
+ drop(upEvent) {
3981
+ this.hint.remove();
3982
+ this.cue.remove();
3983
+ this.service.notifyDrop(this, upEvent);
3813
3984
  }
3814
- get locked() {
3815
- return this._locked || this.childColumns.some(c => c.locked);
3985
+ performDrag({ move }) {
3986
+ this.hint.move(move);
3987
+ const cursorElement = this.elementUnderCursor(move);
3988
+ if (cursorElement) {
3989
+ this.service.notifyDrag(this, cursorElement, move);
3990
+ }
3991
+ this.drag.emit({
3992
+ draggable: this,
3993
+ mouseEvent: move
3994
+ });
3816
3995
  }
3817
- get childrenArray() {
3818
- return this.childColumns.toArray();
3996
+ elementUnderCursor(mouseEvent) {
3997
+ this.hint.hide();
3998
+ let target = elementUnderCursor(mouseEvent);
3999
+ if (target && /k-grouping-dropclue/.test(target.className)) {
4000
+ target = hideThenShow(target, elementUnderCursor.bind(this, mouseEvent));
4001
+ }
4002
+ this.hint.show();
4003
+ return target;
3819
4004
  }
3820
- get hasChildren() {
3821
- return this.childColumns.length > 0;
4005
+ updateTouchAction() {
4006
+ if (!this.element) {
4007
+ return;
4008
+ }
4009
+ // eslint-disable-next-line no-unused-expressions
4010
+ this.enabled ? this.renderer.addClass(this.element.nativeElement, 'k-touch-action-none') :
4011
+ this.renderer.removeClass(this.element.nativeElement, 'k-touch-action-none');
3822
4012
  }
3823
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: SpanColumnComponent, deps: [{ token: ColumnBase, host: true, optional: true, skipSelf: true }, { token: IdService, optional: true }], target: i0.ɵɵFactoryTarget.Component });
3824
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: SpanColumnComponent, isStandalone: true, selector: "kendo-grid-span-column", inputs: { editable: "editable", locked: "locked" }, providers: [
3825
- {
3826
- provide: ColumnBase,
3827
- useExisting: forwardRef(() => SpanColumnComponent)
3828
- }
3829
- ], queries: [{ propertyName: "template", predicate: CellTemplateDirective }, { propertyName: "editTemplate", predicate: EditTemplateDirective }, { propertyName: "childColumns", predicate: ColumnComponent }], usesInheritance: true, ngImport: i0, template: ``, isInline: true });
4013
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DraggableColumnDirective, deps: [{ token: i1$3.DraggableDirective, host: true }, { token: i0.ElementRef }, { token: i0.NgZone }, { token: DragAndDropService }, { token: DragHintService }, { token: DropCueService }, { token: NavigationService }, { token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Directive });
4014
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: DraggableColumnDirective, isStandalone: true, selector: "[kendoDraggableColumn]", inputs: { context: "context", enableDrag: "enableDrag" }, outputs: { drag: "drag" }, ngImport: i0 });
3830
4015
  }
3831
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: SpanColumnComponent, decorators: [{
3832
- type: Component,
4016
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DraggableColumnDirective, decorators: [{
4017
+ type: Directive,
3833
4018
  args: [{
3834
- providers: [
3835
- {
3836
- provide: ColumnBase,
3837
- useExisting: forwardRef(() => SpanColumnComponent)
3838
- }
3839
- ],
3840
- selector: 'kendo-grid-span-column',
3841
- template: ``,
4019
+ selector: '[kendoDraggableColumn]',
3842
4020
  standalone: true
3843
4021
  }]
3844
- }], ctorParameters: function () { return [{ type: ColumnBase, decorators: [{
3845
- type: SkipSelf
3846
- }, {
3847
- type: Host
3848
- }, {
3849
- type: Optional
3850
- }] }, { type: IdService, decorators: [{
3851
- type: Optional
3852
- }] }]; }, propDecorators: { template: [{
3853
- type: ContentChildren,
3854
- args: [CellTemplateDirective, { descendants: false }]
3855
- }], editTemplate: [{
3856
- type: ContentChildren,
3857
- args: [EditTemplateDirective, { descendants: false }]
3858
- }], childColumns: [{
3859
- type: ContentChildren,
3860
- args: [ColumnComponent]
3861
- }], editable: [{
3862
- type: Input
3863
- }], locked: [{
3864
- type: Input
3865
- }] } });
3866
-
3867
- /**
3868
- * @hidden
3869
- */
3870
- const expandColumns = (columns) => (columns.reduce((acc, column) => acc.concat(isSpanColumnComponent(column) ? column.childrenArray : [column]), []));
3871
- /**
3872
- * @hidden
3873
- */
3874
- const expandColumnsWithSpan = (columns) => (columns.reduce((acc, column) => acc.concat(isSpanColumnComponent(column) ?
3875
- [column].concat(column.childrenArray) :
3876
- [column]), []));
3877
- /**
3878
- * @hidden
3879
- */
3880
- const columnsToRender = (columns) => (expandColumns(columns).filter(x => x.isVisible));
3881
- const sumProp = (prop) => (array) => (array || []).reduce((prev, curr) => prev + (curr[prop] || 0), 0);
3882
- /**
3883
- * @hidden
3884
- */
3885
- const sumColumnWidths = sumProp('width');
3886
- /**
3887
- * @hidden
3888
- */
3889
- const columnsSpan = sumProp('colspan');
3890
- const validField = new RegExp(`^[$A-Z\_a-z][$A-Z\_a-z0-9\\.]*$`);
3891
- /**
3892
- * @hidden
3893
- */
3894
- const isValidFieldName = (fieldName) => !isNullOrEmptyString(fieldName) && validField.test(fieldName) &&
3895
- fieldName[0] !== "." && fieldName[fieldName.length - 1] !== ".";
3896
- /**
3897
- * @hidden
3898
- */
3899
- const children = column => column.children.filter(child => child !== column);
4022
+ }], ctorParameters: function () { return [{ type: i1$3.DraggableDirective, decorators: [{
4023
+ type: Host
4024
+ }] }, { type: i0.ElementRef }, { type: i0.NgZone }, { type: DragAndDropService }, { type: DragHintService }, { type: DropCueService }, { type: NavigationService }, { type: i0.Renderer2 }]; }, propDecorators: { context: [{
4025
+ type: Input
4026
+ }], enableDrag: [{
4027
+ type: Input
4028
+ }], drag: [{
4029
+ type: Output
4030
+ }] } });
4031
+
3900
4032
  /**
3901
4033
  * @hidden
3902
4034
  */
3903
- const leafColumns = columns => {
3904
- return columns.reduce((acc, column) => {
3905
- if (column.isColumnGroup) {
3906
- acc = acc.concat(leafColumns(children(column)));
3907
- }
3908
- else if (column.isSpanColumn) {
3909
- acc = acc.concat(column.childrenArray);
3910
- }
3911
- else {
3912
- acc.push(column);
4035
+ class DropTargetDirective {
4036
+ element;
4037
+ service;
4038
+ context = {};
4039
+ enter = new EventEmitter();
4040
+ leave = new EventEmitter();
4041
+ drop = new EventEmitter();
4042
+ subscriptions = new Subscription();
4043
+ constructor(element, service) {
4044
+ this.element = element;
4045
+ this.service = service;
4046
+ }
4047
+ ngOnInit() {
4048
+ this.service.add(this);
4049
+ const changes = this.service.changes.pipe(filter(({ target }) => target === this));
4050
+ this.subscriptions.add(changes.pipe(filter(({ type }) => type === 'leave'))
4051
+ .subscribe(e => {
4052
+ this.leave.next(this.eventArgs(e));
4053
+ }));
4054
+ this.subscriptions.add(changes.pipe(filter(({ type }) => type === 'enter'))
4055
+ .subscribe(e => {
4056
+ this.enter.next(this.eventArgs(e));
4057
+ }));
4058
+ this.subscriptions.add(changes.pipe(filter(({ type }) => type === 'drop'))
4059
+ .subscribe(e => {
4060
+ this.drop.next(this.eventArgs(e));
4061
+ }));
4062
+ }
4063
+ ngOnDestroy() {
4064
+ if (this.subscriptions) {
4065
+ this.subscriptions.unsubscribe();
3913
4066
  }
3914
- return acc;
3915
- }, []).filter(x => x.isVisible);
3916
- };
3917
- /**
3918
- * @hidden
3919
- */
3920
- const someLeafColumn = (callback, ...columns) => leafColumns(columns).some(callback);
3921
- /**
3922
- * @hidden
3923
- */
3924
- const resizableColumns = columns => columns.filter(column => isTruthy(column.resizable) && column.isVisible);
3925
- /**
3926
- * @hidden
3927
- */
3928
- const sortColumns = (columns) => orderBy(columns, [{ field: 'orderIndex', dir: 'asc' }]);
3929
- /**
3930
- * @hidden
3931
- */
3932
- const isInSpanColumn$1 = (column) => isTruthy(column.parent) && isSpanColumnComponent(column.parent);
4067
+ }
4068
+ eventArgs(e) {
4069
+ return {
4070
+ target: this,
4071
+ mouseEvent: e.mouseEvent,
4072
+ draggable: e.draggable
4073
+ };
4074
+ }
4075
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DropTargetDirective, deps: [{ token: i0.ElementRef }, { token: DragAndDropService }], target: i0.ɵɵFactoryTarget.Directive });
4076
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: DropTargetDirective, isStandalone: true, selector: "[kendoDropTarget]", inputs: { context: "context" }, outputs: { enter: "enter", leave: "leave", drop: "drop" }, ngImport: i0 });
4077
+ }
4078
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DropTargetDirective, decorators: [{
4079
+ type: Directive,
4080
+ args: [{
4081
+ selector: '[kendoDropTarget]',
4082
+ standalone: true
4083
+ }]
4084
+ }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: DragAndDropService }]; }, propDecorators: { context: [{
4085
+ type: Input
4086
+ }], enter: [{
4087
+ type: Output
4088
+ }], leave: [{
4089
+ type: Output
4090
+ }], drop: [{
4091
+ type: Output
4092
+ }] } });
3933
4093
 
3934
4094
  /**
3935
4095
  * @hidden
@@ -14423,138 +14583,6 @@ class ColumnReorderEvent extends PreventableEvent {
14423
14583
  }
14424
14584
  }
14425
14585
 
14426
- /**
14427
- * @hidden
14428
- */
14429
- const isLocked = column => column.parent ? isLocked(column.parent) : !!column.locked;
14430
- /**
14431
- * @hidden
14432
- */
14433
- const resizeArgs = (column, extra) => Object.assign({
14434
- columns: leafColumns([column]),
14435
- locked: isLocked(column)
14436
- }, extra);
14437
- /**
14438
- * @hidden
14439
- */
14440
- class ColumnResizingService {
14441
- changes = new EventEmitter();
14442
- column;
14443
- resizedColumns;
14444
- tables = [];
14445
- batch = null;
14446
- start(column) {
14447
- this.trackColumns(column);
14448
- const columns = (this.column.isColumnGroup ? [column] : [])
14449
- .concat(leafColumns([column]));
14450
- this.changes.emit({
14451
- columns: columns,
14452
- locked: isLocked(this.column),
14453
- type: 'start'
14454
- });
14455
- }
14456
- resizeColumns(deltaPercent) {
14457
- const action = resizeArgs(this.column, {
14458
- deltaPercent,
14459
- type: 'resizeColumn'
14460
- });
14461
- this.changes.emit(action);
14462
- }
14463
- resizeTable(column, delta) {
14464
- const action = resizeArgs(column, {
14465
- delta,
14466
- type: 'resizeTable'
14467
- });
14468
- this.changes.emit(action);
14469
- }
14470
- resizedColumn(state) {
14471
- this.resizedColumns.push(state);
14472
- }
14473
- end() {
14474
- this.changes.emit({
14475
- columns: [],
14476
- resizedColumns: this.resizedColumns,
14477
- type: 'end'
14478
- });
14479
- }
14480
- registerTable(tableMetadata) {
14481
- this.tables.push(tableMetadata);
14482
- const unregisterTable = () => {
14483
- this.tables.splice(this.tables.indexOf(tableMetadata), 1);
14484
- };
14485
- return unregisterTable;
14486
- }
14487
- measureColumns(info) {
14488
- if (this.batch !== null) {
14489
- this.batch.push(...info);
14490
- }
14491
- else {
14492
- this.autoFitBatch(info, () => this.end());
14493
- }
14494
- }
14495
- autoFit(...columns) {
14496
- const nonLockedColumns = columns.filter(column => !column.isLocked);
14497
- this.autoFitStart(nonLockedColumns);
14498
- this.autoFitBatch(this.batch, () => {
14499
- if (nonLockedColumns.length < columns.length) {
14500
- const lockedColumns = columns.filter(column => column.isLocked);
14501
- this.autoFitStart(lockedColumns);
14502
- this.autoFitBatch(this.batch, () => this.end());
14503
- }
14504
- else {
14505
- this.end();
14506
- }
14507
- });
14508
- }
14509
- trackColumns(column) {
14510
- this.resizedColumns = [];
14511
- this.column = column;
14512
- }
14513
- autoFitStart(columns) {
14514
- this.batch = [];
14515
- this.resizedColumns = [];
14516
- if (columns.length === 0) {
14517
- return;
14518
- }
14519
- const locked = columns[0].isLocked;
14520
- this.changes.emit({
14521
- type: 'start',
14522
- columns,
14523
- locked
14524
- });
14525
- this.changes.emit({
14526
- type: 'triggerAutoFit',
14527
- columns,
14528
- locked
14529
- });
14530
- }
14531
- autoFitBatch(info, onComplete) {
14532
- const locked = info.length > 0 ? info[0].column.isLocked : false;
14533
- const observables = this.tables
14534
- .filter(table => table.locked === locked)
14535
- .map(table => table.autoFit(info));
14536
- zip$1(...observables)
14537
- .pipe(take(1))
14538
- .subscribe(widths => {
14539
- this.changes.emit({
14540
- columns: info.map(i => i.column),
14541
- type: 'autoFitComplete',
14542
- widths,
14543
- locked
14544
- });
14545
- if (onComplete) {
14546
- onComplete();
14547
- }
14548
- });
14549
- this.batch = null;
14550
- }
14551
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ColumnResizingService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
14552
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ColumnResizingService });
14553
- }
14554
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ColumnResizingService, decorators: [{
14555
- type: Injectable
14556
- }] });
14557
-
14558
14586
  /**
14559
14587
  * @hidden
14560
14588
  */
@@ -14573,15 +14601,12 @@ const headerWidth = (handle) => handle.nativeElement.parentElement.offsetWidth;
14573
14601
  /**
14574
14602
  * @hidden
14575
14603
  */
14576
- const allLeafColumns = columns => expandColumns(columns)
14577
- .filter(c => !c.isColumnGroup);
14604
+ const adjacentColumnWidth = (handle) => handle.nativeElement.parentElement.nextElementSibling?.offsetWidth;
14578
14605
  /**
14579
14606
  * @hidden
14580
14607
  */
14581
- const stopPropagation = ({ originalEvent: event }) => {
14582
- event.stopPropagation();
14583
- event.preventDefault();
14584
- };
14608
+ const allLeafColumns = columns => expandColumns(columns)
14609
+ .filter(c => !c.isColumnGroup);
14585
14610
  /**
14586
14611
  * @hidden
14587
14612
  */
@@ -14632,9 +14657,13 @@ class ColumnHandleDirective {
14632
14657
  cdr;
14633
14658
  ctx;
14634
14659
  columnInfoService;
14660
+ isLast;
14635
14661
  columns = [];
14636
14662
  column;
14637
14663
  get visible() {
14664
+ if (this.isConstrainedMode && this.isLast) {
14665
+ return 'none';
14666
+ }
14638
14667
  return this.column.resizable ? 'block' : 'none';
14639
14668
  }
14640
14669
  get leftStyle() {
@@ -14643,6 +14672,13 @@ class ColumnHandleDirective {
14643
14672
  get rightStyle() {
14644
14673
  return isTruthy(this.rtl) ? null : 0;
14645
14674
  }
14675
+ get isConstrainedMode() {
14676
+ const isConstrainedMode = this.ctx.grid?.resizable === 'constrained';
14677
+ const isUnconstrainedMode = this.ctx.grid?.resizable === true || this.ctx.grid?.resizable === 'unconstrained';
14678
+ const constrainedNoShift = isConstrainedMode && !this.service.isShiftPressed;
14679
+ const unconstrainedWithShift = isUnconstrainedMode && this.service.isShiftPressed;
14680
+ return constrainedNoShift || unconstrainedWithShift;
14681
+ }
14646
14682
  subscriptions = new Subscription();
14647
14683
  rtl = false;
14648
14684
  autoFit() {
@@ -14684,7 +14720,7 @@ class ColumnHandleDirective {
14684
14720
  .subscribe(this.resize.bind(this)));
14685
14721
  this.subscriptions.add(this.service.changes.pipe(filter(e => e.type === 'start'), filter(this.shouldUpdate.bind(this)), take(1) //on first resize only
14686
14722
  ).subscribe(this.initColumnWidth.bind(this)));
14687
- this.subscriptions.add(this.zone.runOutsideAngular(() => this.draggable.kendoPress.pipe(tap(stopPropagation), tap(() => this.service.start(this.column)), switchMap(preventOnDblClick(this.draggable.kendoRelease)), switchMap(createMoveStream(this.service, this.draggable)))
14723
+ this.subscriptions.add(this.zone.runOutsideAngular(() => this.draggable.kendoPress.pipe(tap(this.stopPropagation), tap(() => this.service.start(this.column)), switchMap(preventOnDblClick(this.draggable.kendoRelease)), switchMap(createMoveStream(this.service, this.draggable)))
14688
14724
  .subscribe(({ pageX, originalX }) => {
14689
14725
  const delta = pageX - originalX;
14690
14726
  const percent = toPercentage(delta, this.column.resizeStartWidth || this.column.width);
@@ -14711,6 +14747,28 @@ class ColumnHandleDirective {
14711
14747
  }
14712
14748
  initState() {
14713
14749
  this.column.resizeStartWidth = headerWidth(this.element);
14750
+ let columns = [];
14751
+ if (this.ctx.grid?.columns) {
14752
+ columns = Array.from(this.ctx.grid?.columns) || [];
14753
+ }
14754
+ if (this.isConstrainedMode) {
14755
+ if (this.service.areColumnsReordered) {
14756
+ this.service.adjacentColumn = columns.find(c => c.orderIndex === this.column.orderIndex + 1);
14757
+ this.service.adjacentColumn.resizeStartWidth = adjacentColumnWidth(this.element);
14758
+ this.service.resizedColumn({
14759
+ column: this.service.adjacentColumn,
14760
+ oldWidth: this.service.adjacentColumn.resizeStartWidth
14761
+ });
14762
+ }
14763
+ else {
14764
+ this.service.adjacentColumn = columns[this.column.leafIndex + 1];
14765
+ this.service.adjacentColumn.resizeStartWidth = adjacentColumnWidth(this.element);
14766
+ this.service.resizedColumn({
14767
+ column: this.service.adjacentColumn,
14768
+ oldWidth: this.service.adjacentColumn.resizeStartWidth
14769
+ });
14770
+ }
14771
+ }
14714
14772
  this.service.resizedColumn({
14715
14773
  column: this.column,
14716
14774
  oldWidth: this.column.resizeStartWidth
@@ -14725,6 +14783,14 @@ class ColumnHandleDirective {
14725
14783
  if (isPresent(this.column.maxResizableWidth)) {
14726
14784
  newWidth = Math.min(newWidth, this.column.maxResizableWidth);
14727
14785
  }
14786
+ if (this.isConstrainedMode) {
14787
+ const maxAllowedResizableWidth = this.column.resizeStartWidth + this.service.adjacentColumn.resizeStartWidth - this.service.adjacentColumn.minResizableWidth;
14788
+ newWidth = Math.min(newWidth, maxAllowedResizableWidth);
14789
+ }
14790
+ if (this.isConstrainedMode && isPresent(this.service.adjacentColumn.maxResizableWidth)) {
14791
+ const maxAllowedResizableWidth = this.column.resizeStartWidth + this.service.adjacentColumn.resizeStartWidth - this.service.adjacentColumn.maxResizableWidth;
14792
+ newWidth = Math.max(newWidth, maxAllowedResizableWidth);
14793
+ }
14728
14794
  const tableDelta = this.getTableDelta(newWidth, delta);
14729
14795
  this.updateWidth(this.column, newWidth);
14730
14796
  this.service.resizeTable(this.column, tableDelta);
@@ -14737,6 +14803,12 @@ class ColumnHandleDirective {
14737
14803
  this.service.resizeTable(this.column, tableDelta);
14738
14804
  }
14739
14805
  updateWidth(column, width) {
14806
+ if (this.isConstrainedMode && this.service.adjacentColumn) {
14807
+ const adjacentColumnNewWidth = column.resizeStartWidth + this.service.adjacentColumn.resizeStartWidth - width;
14808
+ if (adjacentColumnNewWidth < (column.resizeStartWidth + this.service.adjacentColumn.resizeStartWidth)) {
14809
+ this.service.adjacentColumn.width = adjacentColumnNewWidth;
14810
+ }
14811
+ }
14740
14812
  column.width = width;
14741
14813
  this.columnInfoService.hiddenColumns.forEach((col) => {
14742
14814
  if (isBlank(col.width) && isPresent(col.implicitWidth)) {
@@ -14769,8 +14841,13 @@ class ColumnHandleDirective {
14769
14841
  return startWidth - maxWidth;
14770
14842
  }
14771
14843
  }
14844
+ stopPropagation = ({ originalEvent: event }) => {
14845
+ this.service.isShiftPressed = event.shiftKey;
14846
+ event.stopPropagation();
14847
+ event.preventDefault();
14848
+ };
14772
14849
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ColumnHandleDirective, deps: [{ token: i1$3.DraggableDirective, host: true }, { token: i0.ElementRef }, { token: ColumnResizingService }, { token: i0.NgZone }, { token: i0.ChangeDetectorRef }, { token: ContextService }, { token: ColumnInfoService }], target: i0.ɵɵFactoryTarget.Directive });
14773
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: ColumnHandleDirective, isStandalone: true, selector: "[kendoGridColumnHandle]", inputs: { columns: "columns", column: "column" }, host: { listeners: { "dblclick": "autoFit()" }, properties: { "style.display": "this.visible", "style.left": "this.leftStyle", "style.right": "this.rightStyle" } }, ngImport: i0 });
14850
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: ColumnHandleDirective, isStandalone: true, selector: "[kendoGridColumnHandle]", inputs: { isLast: "isLast", columns: "columns", column: "column" }, host: { listeners: { "dblclick": "autoFit()" }, properties: { "style.display": "this.visible", "style.left": "this.leftStyle", "style.right": "this.rightStyle" } }, ngImport: i0 });
14774
14851
  }
14775
14852
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ColumnHandleDirective, decorators: [{
14776
14853
  type: Directive,
@@ -14780,7 +14857,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
14780
14857
  }]
14781
14858
  }], ctorParameters: function () { return [{ type: i1$3.DraggableDirective, decorators: [{
14782
14859
  type: Host
14783
- }] }, { type: i0.ElementRef }, { type: ColumnResizingService }, { type: i0.NgZone }, { type: i0.ChangeDetectorRef }, { type: ContextService }, { type: ColumnInfoService }]; }, propDecorators: { columns: [{
14860
+ }] }, { type: i0.ElementRef }, { type: ColumnResizingService }, { type: i0.NgZone }, { type: i0.ChangeDetectorRef }, { type: ContextService }, { type: ColumnInfoService }]; }, propDecorators: { isLast: [{
14861
+ type: Input
14862
+ }], columns: [{
14784
14863
  type: Input
14785
14864
  }], column: [{
14786
14865
  type: Input
@@ -16453,6 +16532,7 @@ class HeaderComponent {
16453
16532
  kendoDraggable
16454
16533
  class="k-column-resizer"
16455
16534
  *ngIf="resizable"
16535
+ [isLast]="last"
16456
16536
  [column]="column"
16457
16537
  [columns]="columns">
16458
16538
  </span>
@@ -16507,6 +16587,7 @@ class HeaderComponent {
16507
16587
  kendoDraggable
16508
16588
  class="k-column-resizer"
16509
16589
  *ngIf="resizable"
16590
+ [isLast]="last"
16510
16591
  [column]="column"
16511
16592
  [columns]="columns">
16512
16593
  </span>
@@ -16528,7 +16609,7 @@ class HeaderComponent {
16528
16609
  [totalColumns]="totalColumns"
16529
16610
  ></tr>
16530
16611
  </ng-container>
16531
- `, isInline: true, dependencies: [{ kind: "directive", type: NgFor, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: LogicalRowDirective, selector: "[kendoGridLogicalRow]", inputs: ["logicalRowIndex", "logicalSlaveRow", "logicalCellsCount", "logicalSlaveCellsCount", "dataRowIndex", "dataItem", "totalColumns"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: LogicalCellDirective, selector: "[kendoGridLogicalCell]", inputs: ["logicalColIndex", "logicalRowIndex", "logicalSlaveCell", "colIndex", "colSpan", "rowSpan", "groupItem", "dataRowIndex", "dataItem", "detailExpandCell", "headerLabelText"] }, { kind: "directive", type: DropTargetDirective, selector: "[kendoDropTarget]", inputs: ["context"], outputs: ["enter", "leave", "drop"] }, { kind: "directive", type: DraggableDirective, selector: "[kendoDraggable]", inputs: ["enableDrag"], outputs: ["kendoPress", "kendoDrag", "kendoRelease"] }, { kind: "directive", type: DraggableColumnDirective, selector: "[kendoDraggableColumn]", inputs: ["context", "enableDrag"], outputs: ["drag"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: TemplateContextDirective, selector: "[templateContext]", inputs: ["templateContext"] }, { kind: "component", type: FilterMenuComponent, selector: "kendo-grid-filter-menu", inputs: ["column", "filter", "tabIndex"] }, { kind: "component", type: ColumnMenuComponent, selector: "kendo-grid-column-menu", inputs: ["standalone", "column", "settings", "sort", "filter", "sortable", "columnMenuTemplate", "tabIndex"] }, { kind: "component", type: IconWrapperComponent, selector: "kendo-icon-wrapper", inputs: ["name", "svgIcon", "innerCssClass", "customFontClass", "size"], exportAs: ["kendoIconWrapper"] }, { kind: "directive", type: SelectAllCheckboxDirective, selector: "[kendoGridSelectAllCheckbox]", inputs: ["state"], outputs: ["selectAllChange"] }, { kind: "directive", type: FocusableDirective, selector: "[kendoGridFocusable],\n [kendoGridEditCommand],\n [kendoGridRemoveCommand],\n [kendoGridSaveCommand],\n [kendoGridCancelCommand],\n [kendoGridSelectionCheckbox]\n ", inputs: ["kendoGridFocusable"] }, { kind: "directive", type: ColumnHandleDirective, selector: "[kendoGridColumnHandle]", inputs: ["columns", "column"] }, { kind: "component", type: FilterRowComponent, selector: "[kendoGridFilterRow]", inputs: ["columns", "filter", "groups", "detailTemplate", "logicalRowIndex", "lockedColumnsCount"] }, { kind: "component", type: CheckBoxComponent, selector: "kendo-checkbox", inputs: ["checkedState", "rounded"], outputs: ["checkedStateChange"], exportAs: ["kendoCheckBox"] }] });
16612
+ `, isInline: true, dependencies: [{ kind: "directive", type: NgFor, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: LogicalRowDirective, selector: "[kendoGridLogicalRow]", inputs: ["logicalRowIndex", "logicalSlaveRow", "logicalCellsCount", "logicalSlaveCellsCount", "dataRowIndex", "dataItem", "totalColumns"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: LogicalCellDirective, selector: "[kendoGridLogicalCell]", inputs: ["logicalColIndex", "logicalRowIndex", "logicalSlaveCell", "colIndex", "colSpan", "rowSpan", "groupItem", "dataRowIndex", "dataItem", "detailExpandCell", "headerLabelText"] }, { kind: "directive", type: DropTargetDirective, selector: "[kendoDropTarget]", inputs: ["context"], outputs: ["enter", "leave", "drop"] }, { kind: "directive", type: DraggableDirective, selector: "[kendoDraggable]", inputs: ["enableDrag"], outputs: ["kendoPress", "kendoDrag", "kendoRelease"] }, { kind: "directive", type: DraggableColumnDirective, selector: "[kendoDraggableColumn]", inputs: ["context", "enableDrag"], outputs: ["drag"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: TemplateContextDirective, selector: "[templateContext]", inputs: ["templateContext"] }, { kind: "component", type: FilterMenuComponent, selector: "kendo-grid-filter-menu", inputs: ["column", "filter", "tabIndex"] }, { kind: "component", type: ColumnMenuComponent, selector: "kendo-grid-column-menu", inputs: ["standalone", "column", "settings", "sort", "filter", "sortable", "columnMenuTemplate", "tabIndex"] }, { kind: "component", type: IconWrapperComponent, selector: "kendo-icon-wrapper", inputs: ["name", "svgIcon", "innerCssClass", "customFontClass", "size"], exportAs: ["kendoIconWrapper"] }, { kind: "directive", type: SelectAllCheckboxDirective, selector: "[kendoGridSelectAllCheckbox]", inputs: ["state"], outputs: ["selectAllChange"] }, { kind: "directive", type: FocusableDirective, selector: "[kendoGridFocusable],\n [kendoGridEditCommand],\n [kendoGridRemoveCommand],\n [kendoGridSaveCommand],\n [kendoGridCancelCommand],\n [kendoGridSelectionCheckbox]\n ", inputs: ["kendoGridFocusable"] }, { kind: "directive", type: ColumnHandleDirective, selector: "[kendoGridColumnHandle]", inputs: ["isLast", "columns", "column"] }, { kind: "component", type: FilterRowComponent, selector: "[kendoGridFilterRow]", inputs: ["columns", "filter", "groups", "detailTemplate", "logicalRowIndex", "lockedColumnsCount"] }, { kind: "component", type: CheckBoxComponent, selector: "kendo-checkbox", inputs: ["checkedState", "rounded"], outputs: ["checkedStateChange"], exportAs: ["kendoCheckBox"] }] });
16532
16613
  }
16533
16614
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: HeaderComponent, decorators: [{
16534
16615
  type: Component,
@@ -16678,6 +16759,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
16678
16759
  kendoDraggable
16679
16760
  class="k-column-resizer"
16680
16761
  *ngIf="resizable"
16762
+ [isLast]="last"
16681
16763
  [column]="column"
16682
16764
  [columns]="columns">
16683
16765
  </span>
@@ -16732,6 +16814,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
16732
16814
  kendoDraggable
16733
16815
  class="k-column-resizer"
16734
16816
  *ngIf="resizable"
16817
+ [isLast]="last"
16735
16818
  [column]="column"
16736
16819
  [columns]="columns">
16737
16820
  </span>
@@ -19326,8 +19409,8 @@ const packageMetadata = {
19326
19409
  name: '@progress/kendo-angular-grid',
19327
19410
  productName: 'Kendo UI for Angular',
19328
19411
  productCodes: ['KENDOUIANGULAR', 'KENDOUICOMPLETE'],
19329
- publishDate: 1736354347,
19330
- version: '18.0.0-develop.4',
19412
+ publishDate: 1736439823,
19413
+ version: '18.0.0-develop.6',
19331
19414
  licensingDocsUrl: 'https://www.telerik.com/kendo-angular-ui/my-license/'
19332
19415
  };
19333
19416
 
@@ -21210,7 +21293,7 @@ class ScrollerService {
21210
21293
  /**
21211
21294
  * @hidden
21212
21295
  */
21213
- const columnsToResize = ({ columns }) => Math.max(1, resizableColumns(columns).length);
21296
+ const columnsToResize = ({ columns }) => Math.max(1, resizableColumns(columns).filter(c => !c.isColumnGroup).length);
21214
21297
  /**
21215
21298
  * @hidden
21216
21299
  */
@@ -21240,21 +21323,22 @@ class TableDirective {
21240
21323
  service;
21241
21324
  zone;
21242
21325
  cdr;
21326
+ ctx;
21243
21327
  locked = false;
21244
21328
  virtualColumns;
21245
21329
  get minWidth() {
21246
21330
  return this.firstResize ? 0 : null;
21247
21331
  }
21248
- originalWidth;
21249
21332
  firstResize = false;
21250
21333
  subscription;
21251
21334
  autoFitSubscription;
21252
- constructor(element, renderer, service, zone, cdr) {
21335
+ constructor(element, renderer, service, zone, cdr, ctx) {
21253
21336
  this.element = element;
21254
21337
  this.renderer = renderer;
21255
21338
  this.service = service;
21256
21339
  this.zone = zone;
21257
21340
  this.cdr = cdr;
21341
+ this.ctx = ctx;
21258
21342
  }
21259
21343
  ngOnInit() {
21260
21344
  const obs = this.service
@@ -21277,15 +21361,24 @@ class TableDirective {
21277
21361
  }
21278
21362
  initState() {
21279
21363
  this.firstResize = true;
21280
- if (!this.virtualColumns || this.locked) {
21281
- this.originalWidth = offsetWidth(this.element.nativeElement);
21364
+ const constrainedWithVirtualColumns = this.ctx.grid?.resizable === 'constrained' && this.virtualColumns;
21365
+ if ((!this.virtualColumns || this.locked) || constrainedWithVirtualColumns) {
21366
+ this.service.originalWidth = offsetWidth(this.element.nativeElement);
21282
21367
  }
21283
21368
  }
21284
21369
  resize(deltas) {
21285
- if (!this.virtualColumns || this.locked) {
21286
- const delta = deltas.reduce((sum, item) => sum + item, 0);
21287
- const width = this.originalWidth + delta;
21288
- this.renderer.setStyle(this.element.nativeElement, 'width', width + 'px');
21370
+ const constrainedModeNoShift = this.ctx.grid?.resizable === 'constrained' && !this.service.isShiftPressed;
21371
+ const unconstrainedModeShift = (this.ctx.grid?.resizable === true || this.ctx.grid?.resizable === 'unconstrained') && this.service.isShiftPressed;
21372
+ const isConstrainedMode = constrainedModeNoShift || unconstrainedModeShift;
21373
+ if (isConstrainedMode) {
21374
+ this.renderer.setStyle(this.element.nativeElement, 'width', this.service.originalWidth + 'px');
21375
+ }
21376
+ else {
21377
+ if (!this.virtualColumns || this.locked) {
21378
+ const delta = deltas.reduce((sum, item) => sum + item, 0);
21379
+ const width = this.service.originalWidth + delta;
21380
+ this.renderer.setStyle(this.element.nativeElement, 'width', width + 'px');
21381
+ }
21289
21382
  }
21290
21383
  this.cdr.detectChanges();
21291
21384
  }
@@ -21310,7 +21403,7 @@ class TableDirective {
21310
21403
  const footer = pipe(row('tfoot>tr'), cell(info.index), offsetWidth)(dom);
21311
21404
  return Math.max(header, data, footer);
21312
21405
  }
21313
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: TableDirective, deps: [{ token: i0.ElementRef }, { token: i0.Renderer2 }, { token: ColumnResizingService }, { token: i0.NgZone }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Directive });
21406
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: TableDirective, deps: [{ token: i0.ElementRef }, { token: i0.Renderer2 }, { token: ColumnResizingService }, { token: i0.NgZone }, { token: i0.ChangeDetectorRef }, { token: ContextService }], target: i0.ɵɵFactoryTarget.Directive });
21314
21407
  static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: TableDirective, isStandalone: true, selector: "[kendoGridResizableTable]", inputs: { locked: "locked", virtualColumns: "virtualColumns" }, host: { properties: { "style.min-width": "this.minWidth" } }, ngImport: i0 });
21315
21408
  }
21316
21409
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: TableDirective, decorators: [{
@@ -21319,7 +21412,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
21319
21412
  selector: '[kendoGridResizableTable]',
21320
21413
  standalone: true
21321
21414
  }]
21322
- }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.Renderer2 }, { type: ColumnResizingService }, { type: i0.NgZone }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { locked: [{
21415
+ }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.Renderer2 }, { type: ColumnResizingService }, { type: i0.NgZone }, { type: i0.ChangeDetectorRef }, { type: ContextService }]; }, propDecorators: { locked: [{
21323
21416
  type: Input
21324
21417
  }], virtualColumns: [{
21325
21418
  type: Input
@@ -24607,6 +24700,7 @@ class GridComponent {
24607
24700
  expandedColumns[i].orderIndex = nextSourceIndex++;
24608
24701
  }
24609
24702
  this.updateIndicesForLevel(source.level + 1);
24703
+ this.columnResizingService.areColumnsReordered = true;
24610
24704
  }
24611
24705
  updateIndicesForLevel(level) {
24612
24706
  const colsForParentLevel = this.allColumnsForLevel(level - 1);