@progress/kendo-angular-grid
Version:
Kendo UI Grid for Angular - high performance data grid with paging, filtering, virtualization, CRUD, and more.
379 lines (376 loc) • 16.1 kB
JavaScript
/**-----------------------------------------------------------------------------------------
* Copyright © 2025 Progress Software Corporation. All rights reserved.
* Licensed under commercial license. See LICENSE.md in the project root for more information
*-------------------------------------------------------------------------------------------*/
import { Component, Input, Output, EventEmitter, ContentChild, NgZone, ElementRef } from '@angular/core';
import { trigger, transition, style, animate, state } from '@angular/animations';
import { ColumnMenuItemContentTemplateDirective } from './column-menu-item-content-template.directive';
import { chevronDownIcon, chevronRightIcon, chevronUpIcon, filterIcon, sortAscSmallIcon, sortDescSmallIcon } from '@progress/kendo-svg-icons';
import { guid } from '@progress/kendo-angular-common';
import { ColumnMenuService } from './column-menu.service';
import { NgIf, NgTemplateOutlet } from '@angular/common';
import { IconWrapperComponent } from '@progress/kendo-angular-icons';
import { take } from 'rxjs/operators';
import { ContextService } from '../common/provider.service';
import { filtersByField } from '../filtering/base-filter-cell.component';
import { AdaptiveGridService } from '../common/adaptiveness.service';
import { ColumnComponent } from '../columns/column.component';
import { normalize } from '../columns/sort-settings';
import { isPresent } from '../utils';
import * as i0 from "@angular/core";
import * as i1 from "../common/provider.service";
import * as i2 from "../common/adaptiveness.service";
/**
* Represents an item that you can place inside a
* [`ColumnMenuTemplate`]({% slug api_grid_columnmenutemplatedirective %}) directive.
*
* @example
* ```html
* <kendo-grid [columnMenu]="true" ...>
* <ng-template kendoGridColumnMenuTemplate let-service="service" let-column="column">
* <kendo-grid-columnmenu-item text="Fit column"></kendo-grid-columnmenu-item>
* </ng-template>
* </kendo-grid>
* ```
* @example
* ```html
* <kendo-grid-column field="ProductName">
* <ng-template kendoGridColumnMenuTemplate let-service="service">
* kendo-grid-columnmenu-item text="Fit column"></kendo-grid-columnmenu-item>
* </ng-template>
* </kendo-grid-column>
* ```
*/
export class ColumnMenuItemComponent {
ngZone;
ctx;
adaptiveGridService;
element;
/**
* @hidden
*/
sortAscSmallIcon = sortAscSmallIcon;
/**
* @hidden
*/
sortDescSmallIcon = sortDescSmallIcon;
/**
* Fires when the item is clicked.
*/
itemClick = new EventEmitter();
/**
* Fires when the content expands.
*/
expand = new EventEmitter();
/**
* Fires when the content collapses.
*/
collapse = new EventEmitter();
/**
* Specifies the name of the font icon to render within the item.
*/
icon;
/**
* Specifies the SVG icon to render within the item.
*/
svgIcon;
/**
* @hidden
*/
indicatorIcon;
/**
* Specifies the item text.
*/
text;
/**
* Specifies if the item is selected.
*/
selected;
/**
* Specifies if the item is disabled.
*/
disabled;
/**
* Specifies if the item is expanded.
*/
expanded;
/**
* @hidden
*/
focused;
/**
* Represents the [ColumnMenuService]({% slug api_grid_columnmenuservice %}) class.
* Required to include the item in the column menu keyboard navigation sequence.
*/
service;
/**
* @hidden
*/
column;
contentTemplate;
contentState = 'collapsed';
contentId;
chevronUpIcon = chevronUpIcon;
chevronDownIcon = chevronDownIcon;
chevronRightIcon = chevronRightIcon;
filterIcon = filterIcon;
/**
* @hidden
*/
get hasFilters() {
return filtersByField(this.ctx.grid.filter, this.column.field).length > 0;
}
get expandedIcon() {
if (this.ctx.grid.isActionSheetExpanded) {
return 'arrow-chevron-right';
}
return this.expanded ? 'arrow-chevron-up' : 'arrow-chevron-down';
}
get expandedSvgIcon() {
if (this.ctx.grid.isActionSheetExpanded) {
return this.chevronRightIcon;
}
return this.expanded ? this.chevronUpIcon : this.chevronDownIcon;
}
constructor(ngZone, ctx, adaptiveGridService, element) {
this.ngZone = ngZone;
this.ctx = ctx;
this.adaptiveGridService = adaptiveGridService;
this.element = element;
}
ngAfterViewInit() {
this.ngZone.onStable.pipe(take(1)).subscribe(() => {
this.contentTemplate && (this.contentId = `k-${guid()}`);
});
}
ngOnChanges(changes) {
if (changes.expanded) {
this.updateContentState();
}
}
/**
* @hidden
*/
sortDescriptor(field) {
return this.ctx.grid.sort.find(item => item.field === field) || { field };
}
/**
* @hidden
*/
showSortNumbering(column) {
const { showIndexes } = normalize(this.ctx.grid.sortable);
return showIndexes
&& this.ctx.grid.sort
&& this.ctx.grid.sort.filter(({ dir }) => isPresent(dir)).length > 1
&& this.sortOrder(column.field) > 0;
}
/**
* @hidden
*/
sortOrder(field) {
return this.ctx.grid.sort
.filter(({ dir }) => isPresent(dir))
.findIndex(x => x.field === field)
+ 1;
}
/**
* @hidden
*/
onClick(e) {
this.itemClick.emit(e);
if (this.contentTemplate) {
if (!this.ctx.grid.isActionSheetExpanded) {
this.expanded = !this.expanded;
this.updateContentState();
}
if (this.expanded) {
this.expand.emit();
}
else {
this.collapse.emit();
}
}
}
updateContentState() {
this.contentState = this.expanded ? 'expanded' : 'collapsed';
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ColumnMenuItemComponent, deps: [{ token: i0.NgZone }, { token: i1.ContextService }, { token: i2.AdaptiveGridService }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component });
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: ColumnMenuItemComponent, isStandalone: true, selector: "kendo-grid-columnmenu-item", inputs: { icon: "icon", svgIcon: "svgIcon", indicatorIcon: "indicatorIcon", text: "text", selected: "selected", disabled: "disabled", expanded: "expanded", focused: "focused", service: "service", column: "column" }, outputs: { itemClick: "itemClick", expand: "expand", collapse: "collapse" }, queries: [{ propertyName: "contentTemplate", first: true, predicate: ColumnMenuItemContentTemplateDirective, descendants: true }], usesOnChanges: true, ngImport: i0, template: `
<div *ngIf="contentTemplate; else content" class="k-expander">
<ng-container [ngTemplateOutlet]="content"></ng-container>
</div>
<ng-template #content>
<div
class="k-columnmenu-item"
(click)="onClick($event)"
(keydown.enter)="onClick($event)"
[class.k-selected]="selected"
[class.k-disabled]="disabled"
[class.k-focus]="focused"
role="button"
[attr.aria-expanded]="expanded"
[attr.aria-controls]="expanded ? contentId : undefined">
<kendo-icon-wrapper
*ngIf="icon || svgIcon"
[name]="icon"
[svgIcon]="svgIcon"></kendo-icon-wrapper>
{{ text }}
<span *ngIf="(ctx.grid.isActionSheetExpanded && adaptiveGridService.viewType === 'sortToolbarTool' && sortDescriptor(column.field).dir)"
class="k-columnmenu-indicators">
<kendo-icon-wrapper
[name]="sortDescriptor(column.field).dir === 'asc' ? 'sort-asc-small' : 'sort-desc-small'"
[svgIcon]="sortDescriptor(column.field).dir === 'asc' ? sortAscSmallIcon : sortDescSmallIcon">
</kendo-icon-wrapper>
<span *ngIf="showSortNumbering(column)" class="k-sort-index">{{sortOrder(column.field)}}</span>
</span>
<kendo-icon-wrapper
*ngIf="(ctx.grid.isActionSheetExpanded && adaptiveGridService.viewType === 'filterToolbarTool' && hasFilters) || indicatorIcon"
class="k-columnmenu-indicators"
name="filter"
[svgIcon]="filterIcon">
</kendo-icon-wrapper>
<span *ngIf="contentTemplate && adaptiveGridService.viewType !== 'sortToolbarTool'" class="k-spacer"></span>
<span *ngIf="contentTemplate && adaptiveGridService.viewType !== 'sortToolbarTool'" class="k-expander-indicator">
<kendo-icon-wrapper
[name]="expandedIcon"
[svgIcon]="expandedSvgIcon">
</kendo-icon-wrapper>
</span>
</div>
<div *ngIf="contentTemplate" [attr.id]="contentId" []="contentState" [style.overflow]="'hidden'" class="k-columnmenu-item-content">
<ng-container [ngTemplateOutlet]="contentTemplate.templateRef">
</ng-container>
</div>
</ng-template>
`, isInline: true, dependencies: [{ kind: "component", type: IconWrapperComponent, selector: "kendo-icon-wrapper", inputs: ["name", "svgIcon", "innerCssClass", "customFontClass", "size"], exportAs: ["kendoIconWrapper"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], animations: [
trigger('state', [
state('collapsed', style({ display: 'none' })),
state('expanded', style({ display: 'block' })),
transition('collapsed => expanded', [
style({
height: '0px',
display: 'block'
}),
animate('100ms ease-in', style({
height: '*'
}))
]),
transition('expanded => collapsed', [
style({
height: '*'
}),
animate('100ms ease-in', style({
height: '0px'
}))
])
])
] });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ColumnMenuItemComponent, decorators: [{
type: Component,
args: [{
animations: [
trigger('state', [
state('collapsed', style({ display: 'none' })),
state('expanded', style({ display: 'block' })),
transition('collapsed => expanded', [
style({
height: '0px',
display: 'block'
}),
animate('100ms ease-in', style({
height: '*'
}))
]),
transition('expanded => collapsed', [
style({
height: '*'
}),
animate('100ms ease-in', style({
height: '0px'
}))
])
])
],
selector: 'kendo-grid-columnmenu-item',
template: `
<div *ngIf="contentTemplate; else content" class="k-expander">
<ng-container [ngTemplateOutlet]="content"></ng-container>
</div>
<ng-template #content>
<div
class="k-columnmenu-item"
(click)="onClick($event)"
(keydown.enter)="onClick($event)"
[class.k-selected]="selected"
[class.k-disabled]="disabled"
[class.k-focus]="focused"
role="button"
[attr.aria-expanded]="expanded"
[attr.aria-controls]="expanded ? contentId : undefined">
<kendo-icon-wrapper
*ngIf="icon || svgIcon"
[name]="icon"
[svgIcon]="svgIcon"></kendo-icon-wrapper>
{{ text }}
<span *ngIf="(ctx.grid.isActionSheetExpanded && adaptiveGridService.viewType === 'sortToolbarTool' && sortDescriptor(column.field).dir)"
class="k-columnmenu-indicators">
<kendo-icon-wrapper
[name]="sortDescriptor(column.field).dir === 'asc' ? 'sort-asc-small' : 'sort-desc-small'"
[svgIcon]="sortDescriptor(column.field).dir === 'asc' ? sortAscSmallIcon : sortDescSmallIcon">
</kendo-icon-wrapper>
<span *ngIf="showSortNumbering(column)" class="k-sort-index">{{sortOrder(column.field)}}</span>
</span>
<kendo-icon-wrapper
*ngIf="(ctx.grid.isActionSheetExpanded && adaptiveGridService.viewType === 'filterToolbarTool' && hasFilters) || indicatorIcon"
class="k-columnmenu-indicators"
name="filter"
[svgIcon]="filterIcon">
</kendo-icon-wrapper>
<span *ngIf="contentTemplate && adaptiveGridService.viewType !== 'sortToolbarTool'" class="k-spacer"></span>
<span *ngIf="contentTemplate && adaptiveGridService.viewType !== 'sortToolbarTool'" class="k-expander-indicator">
<kendo-icon-wrapper
[name]="expandedIcon"
[svgIcon]="expandedSvgIcon">
</kendo-icon-wrapper>
</span>
</div>
<div *ngIf="contentTemplate" [attr.id]="contentId" []="contentState" [style.overflow]="'hidden'" class="k-columnmenu-item-content">
<ng-container [ngTemplateOutlet]="contentTemplate.templateRef">
</ng-container>
</div>
</ng-template>
`,
standalone: true,
imports: [IconWrapperComponent, NgIf, NgTemplateOutlet]
}]
}], ctorParameters: function () { return [{ type: i0.NgZone }, { type: i1.ContextService }, { type: i2.AdaptiveGridService }, { type: i0.ElementRef }]; }, propDecorators: { itemClick: [{
type: Output
}], expand: [{
type: Output
}], collapse: [{
type: Output
}], icon: [{
type: Input
}], svgIcon: [{
type: Input
}], indicatorIcon: [{
type: Input
}], text: [{
type: Input
}], selected: [{
type: Input
}], disabled: [{
type: Input
}], expanded: [{
type: Input
}], focused: [{
type: Input
}], service: [{
type: Input
}], column: [{
type: Input
}], contentTemplate: [{
type: ContentChild,
args: [ColumnMenuItemContentTemplateDirective]
}] } });