UNPKG

@progress/kendo-angular-toolbar

Version:

Kendo UI Angular Toolbar component - a single UI element that organizes buttons and other navigation elements

425 lines (424 loc) 20.1 kB
/**----------------------------------------------------------------------------------------- * Copyright © 2025 Progress Software Corporation. All rights reserved. * Licensed under commercial license. See LICENSE.md in the project root for more information *-------------------------------------------------------------------------------------------*/ import { Component, forwardRef, ViewChild, ContentChildren, QueryList, Input, ViewChildren } from '@angular/core'; import { LocalizationService } from '@progress/kendo-angular-l10n'; import { ToolBarToolComponent } from './toolbar-tool.component'; import { ToolBarButtonComponent } from './toolbar-button.component'; import { makePeeker, getIndexOfFocused, seekFocusedIndex, getNextKey, getPrevKey, areEqual } from '../util'; import { ButtonGroupComponent, ButtonComponent } from '@progress/kendo-angular-buttons'; import { IconWrapperComponent } from '@progress/kendo-angular-icons'; import { NgFor, NgStyle, NgClass, NgIf } from '@angular/common'; import { ToolBarComponent } from '../toolbar.component'; import * as i0 from "@angular/core"; import * as i1 from "@progress/kendo-angular-l10n"; import * as i2 from "../toolbar.component"; /** * Represents the Kendo UI Toolbar ButtonGroup for Angular. */ export class ToolBarButtonGroupComponent extends ToolBarToolComponent { localization; host; /** * By default, the ButtonGroup is enabled. To disable the whole group of buttons, set its `disabled` * attribute to `true`. To disable a specific button, set the `disabled` attribute of the button to * `true` and leave the `disabled` attribute of the ButtonGroup undefined. If you define the `disabled` * attribute of the ButtonGroup, it will take precedence over the `disabled` attributes of the underlying * buttons and they will be ignored. */ disabled; /** * @hidden * * Used to set different fillmode in Spreadsheet and Toolbar to comply with referent rendering. */ fillMode = 'solid'; /** * By default, the selection mode of the ButtonGroup is set to `multiple`. */ selection = 'multiple'; /** * Sets the width of the ButtonGroup. * * If the width of the ButtonGroup is set: * - The buttons resize automatically to fill the full width of the group wrapper. * - The buttons acquire the same width. */ width; /** * @hidden */ set look(look) { if (look) { this.buttonComponents.forEach(b => b.fillMode = look === 'default' ? 'solid' : look); } } toolbarButtonGroup; sectionButtonGroup; overflowListItems; buttonComponents; get buttonElements() { if (this.overflows && this.location === 'overflow') { return [...this.overflowListItems.toArray().filter(el => !el.nativeElement.classList.contains('k-disabled'))].map(el => el.nativeElement); } else if (this.overflows && this.location === 'section') { return this.sectionButtonGroup .buttons.filter(b => !b.isDisabled) .map(b => b.element); } else { return this.toolbarButtonGroup .buttons.filter(b => !b.isDisabled) .map(b => b.element); } } focusedIndex = -1; getNextKey; getPrevKey; constructor(localization, host) { super(); this.localization = localization; this.host = host; this.getNextKey = getNextKey(this.localization.rtl); this.getPrevKey = getPrevKey(this.localization.rtl); this.isBuiltInTool = true; } /** * @hidden */ onFocus() { // triggered on tabin this.focusedIndex = 0; } /** * @hidden */ onNavigate(ev) { ev.preventDefault(); } /** * @hidden */ selectedChangeHandler(state, button) { button.selected = state; button.selectedChange.emit(state); } /** * @hidden */ overflowSelectedChangeHandler(button) { if (this.selection === 'multiple') { button.selected = !button.selected; } else { const filteredButtons = this.buttonComponents.filter(b => b !== button); filteredButtons.forEach(b => b.selected = false); button.selected = !button.selected; } button.selectedChange.emit(button.selected); } /** * @hidden */ onButtonClick(ev) { this.focusedIndex = this.buttonElements.findIndex(be => be === ev.target || be.contains(ev.target)); this.focusButton(this.focusedIndex, ev); } /** * @hidden */ canFocus() { return !(this.disabled || this.buttonElements.length === 0); } /** * @hidden */ focus(ev = {}) { const nextKey = this.getNextKey((this.overflows && this.location === 'overflow')); const prevKey = this.getPrevKey((this.overflows && this.location === 'overflow')); this.focusedIndex = getIndexOfFocused(prevKey, nextKey, this.buttonElements)(ev); this.focusButton(this.focusedIndex, ev); } /** * @hidden */ handleKey(ev) { const nextKey = this.getNextKey((this.overflows && this.location === 'overflow')); const prevKey = this.getPrevKey((this.overflows && this.location === 'overflow')); const peekAtIndex = makePeeker(this.buttonElements); const isUnmodified = areEqual(this.focusedIndex); this.focusedIndex = seekFocusedIndex(prevKey, nextKey, peekAtIndex)(this.focusedIndex, ev); this.focusButton(this.focusedIndex, ev); return !isUnmodified(this.focusedIndex); } /** * @hidden */ handleClick(ev, button) { button.click.emit(ev); this.onButtonClick(ev); this.overflowSelectedChangeHandler(button); } /** * @hidden */ getIconClasses(button) { if (button.overflowOptions.icon) { return `${button.overflowOptions.icon}`; } if (button.overflowOptions.iconClass) { return button.overflowOptions.iconClass; } if (button.overflowOptions.svgIcon) { return button.overflowOptions.svgIcon; } } /** * @hidden */ get size() { return this.host.size; } focusButton(index, ev) { // Guard against focusing twice on mousedown. if (!ev.type || ev.type === 'focus' || ev.type === 'keydown') { this.buttonElements[index]?.focus(); } } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ToolBarButtonGroupComponent, deps: [{ token: i1.LocalizationService }, { token: i2.ToolBarComponent }], target: i0.ɵɵFactoryTarget.Component }); static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: ToolBarButtonGroupComponent, isStandalone: true, selector: "kendo-toolbar-buttongroup", inputs: { disabled: "disabled", fillMode: "fillMode", selection: "selection", width: "width", look: "look" }, providers: [LocalizationService, { provide: ToolBarToolComponent, useExisting: forwardRef(() => ToolBarButtonGroupComponent) }], queries: [{ propertyName: "buttonComponents", predicate: i0.forwardRef(function () { return ToolBarButtonComponent; }) }], viewQueries: [{ propertyName: "toolbarButtonGroup", first: true, predicate: ["toolbarButtonGroup"], descendants: true }, { propertyName: "sectionButtonGroup", first: true, predicate: ["sectionButtonGroup"], descendants: true }, { propertyName: "overflowListItems", predicate: ["listItem"], descendants: true }], exportAs: ["kendoToolBarButtonGroup"], usesInheritance: true, ngImport: i0, template: ` <ng-template #toolbarTemplate> <kendo-buttongroup class="k-toolbar-button-group k-button-group-{{fillMode}}" #toolbarButtonGroup [tabIndex]="-1" [selection]="selection" [disabled]="disabled" [width]="width" (navigate)="onNavigate($event)" (focus)="onFocus()" > <button kendoButton type="button" *ngFor="let button of buttonComponents" [ngStyle]="button.style" [ngClass]="button.className" [attr.title]="button.title" [disabled]="button.disabled" [size]="size" [togglable]="button.togglable" [selected]="button.selected" [attr.aria-pressed]="button.selected ? true : false" [fillMode]="button.fillMode" [themeColor]="button.fillMode ? button.themeColor : null" [icon]="button.toolbarOptions.icon" [iconClass]="button.toolbarOptions.iconClass" [svgIcon]="button.toolbarOptions.svgIcon" [imageUrl]="button.toolbarOptions.imageUrl" (click)="button.click.emit($event); onButtonClick($event)" (pointerdown)="button.pointerdown.emit($event)" (selectedChange)="selectedChangeHandler($event, button)" > {{ button.toolbarOptions.text }} </button> </kendo-buttongroup> </ng-template> <ng-template #popupTemplate> <div *ngFor="let button of buttonComponents" #listItem tabindex="-1" role="menuitem" class="k-item k-menu-item" [class.k-disabled]="disabled || button.disabled" [ngStyle]="button.style" [ngClass]="button.className" (click)="handleClick($event, button)"> <span class="k-link k-menu-link" [class.k-selected]="button.selected" > <kendo-icon-wrapper *ngIf="button.overflowOptions.icon || button.overflowOptions.iconClass || button.overflowOptions.svgIcon" [name]="button.overflowOptions.icon" [customFontClass]="button.overflowOptions.iconClass" [svgIcon]="button.overflowOptions.svgIcon" ></kendo-icon-wrapper> <span *ngIf="button.overflowOptions.text" class="k-menu-link-text">{{button.overflowOptions.text}}</span> </span> </div> </ng-template> <ng-template #sectionTemplate> <kendo-buttongroup class="k-toolbar-button-group k-button-group-{{fillMode}}" #sectionButtonGroup [tabIndex]="-1" [selection]="selection" [disabled]="disabled" [width]="width" (navigate)="onNavigate($event)" (focus)="onFocus()" > <button kendoButton type="button" *ngFor="let button of buttonComponents" [ngStyle]="button.style" [ngClass]="button.className" [attr.title]="button.title" [disabled]="button.disabled" [size]="size" [togglable]="button.togglable" [selected]="button.selected" [attr.aria-pressed]="button.selected ? true : false" [fillMode]="button.fillMode" [themeColor]="button.fillMode ? button.themeColor : null" [icon]="button.toolbarOptions.icon" [iconClass]="button.toolbarOptions.iconClass" [svgIcon]="button.toolbarOptions.svgIcon" [imageUrl]="button.toolbarOptions.imageUrl" (click)="button.click.emit($event); onButtonClick($event)" (pointerdown)="button.pointerdown.emit($event)" (selectedChange)="selectedChangeHandler($event, button)" > {{ button.toolbarOptions.text }} </button> </kendo-buttongroup> </ng-template> `, isInline: true, dependencies: [{ kind: "component", type: ButtonGroupComponent, selector: "kendo-buttongroup", inputs: ["disabled", "selection", "width", "tabIndex", "navigable"], outputs: ["navigate"], exportAs: ["kendoButtonGroup"] }, { kind: "directive", type: NgFor, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "component", type: ButtonComponent, selector: "button[kendoButton]", inputs: ["arrowIcon", "toggleable", "togglable", "selected", "tabIndex", "imageUrl", "iconClass", "icon", "disabled", "size", "rounded", "fillMode", "themeColor", "svgIcon", "primary", "look"], outputs: ["selectedChange", "click"], exportAs: ["kendoButton"] }, { kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: IconWrapperComponent, selector: "kendo-icon-wrapper", inputs: ["name", "svgIcon", "innerCssClass", "customFontClass", "size"], exportAs: ["kendoIconWrapper"] }] }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ToolBarButtonGroupComponent, decorators: [{ type: Component, args: [{ exportAs: 'kendoToolBarButtonGroup', providers: [LocalizationService, { provide: ToolBarToolComponent, useExisting: forwardRef(() => ToolBarButtonGroupComponent) }], selector: 'kendo-toolbar-buttongroup', template: ` <ng-template #toolbarTemplate> <kendo-buttongroup class="k-toolbar-button-group k-button-group-{{fillMode}}" #toolbarButtonGroup [tabIndex]="-1" [selection]="selection" [disabled]="disabled" [width]="width" (navigate)="onNavigate($event)" (focus)="onFocus()" > <button kendoButton type="button" *ngFor="let button of buttonComponents" [ngStyle]="button.style" [ngClass]="button.className" [attr.title]="button.title" [disabled]="button.disabled" [size]="size" [togglable]="button.togglable" [selected]="button.selected" [attr.aria-pressed]="button.selected ? true : false" [fillMode]="button.fillMode" [themeColor]="button.fillMode ? button.themeColor : null" [icon]="button.toolbarOptions.icon" [iconClass]="button.toolbarOptions.iconClass" [svgIcon]="button.toolbarOptions.svgIcon" [imageUrl]="button.toolbarOptions.imageUrl" (click)="button.click.emit($event); onButtonClick($event)" (pointerdown)="button.pointerdown.emit($event)" (selectedChange)="selectedChangeHandler($event, button)" > {{ button.toolbarOptions.text }} </button> </kendo-buttongroup> </ng-template> <ng-template #popupTemplate> <div *ngFor="let button of buttonComponents" #listItem tabindex="-1" role="menuitem" class="k-item k-menu-item" [class.k-disabled]="disabled || button.disabled" [ngStyle]="button.style" [ngClass]="button.className" (click)="handleClick($event, button)"> <span class="k-link k-menu-link" [class.k-selected]="button.selected" > <kendo-icon-wrapper *ngIf="button.overflowOptions.icon || button.overflowOptions.iconClass || button.overflowOptions.svgIcon" [name]="button.overflowOptions.icon" [customFontClass]="button.overflowOptions.iconClass" [svgIcon]="button.overflowOptions.svgIcon" ></kendo-icon-wrapper> <span *ngIf="button.overflowOptions.text" class="k-menu-link-text">{{button.overflowOptions.text}}</span> </span> </div> </ng-template> <ng-template #sectionTemplate> <kendo-buttongroup class="k-toolbar-button-group k-button-group-{{fillMode}}" #sectionButtonGroup [tabIndex]="-1" [selection]="selection" [disabled]="disabled" [width]="width" (navigate)="onNavigate($event)" (focus)="onFocus()" > <button kendoButton type="button" *ngFor="let button of buttonComponents" [ngStyle]="button.style" [ngClass]="button.className" [attr.title]="button.title" [disabled]="button.disabled" [size]="size" [togglable]="button.togglable" [selected]="button.selected" [attr.aria-pressed]="button.selected ? true : false" [fillMode]="button.fillMode" [themeColor]="button.fillMode ? button.themeColor : null" [icon]="button.toolbarOptions.icon" [iconClass]="button.toolbarOptions.iconClass" [svgIcon]="button.toolbarOptions.svgIcon" [imageUrl]="button.toolbarOptions.imageUrl" (click)="button.click.emit($event); onButtonClick($event)" (pointerdown)="button.pointerdown.emit($event)" (selectedChange)="selectedChangeHandler($event, button)" > {{ button.toolbarOptions.text }} </button> </kendo-buttongroup> </ng-template> `, standalone: true, imports: [ButtonGroupComponent, NgFor, ButtonComponent, NgStyle, NgClass, NgIf, IconWrapperComponent] }] }], ctorParameters: function () { return [{ type: i1.LocalizationService }, { type: i2.ToolBarComponent }]; }, propDecorators: { disabled: [{ type: Input }], fillMode: [{ type: Input }], selection: [{ type: Input }], width: [{ type: Input }], look: [{ type: Input }], toolbarButtonGroup: [{ type: ViewChild, args: ['toolbarButtonGroup', { static: false }] }], sectionButtonGroup: [{ type: ViewChild, args: ['sectionButtonGroup', { static: false }] }], overflowListItems: [{ type: ViewChildren, args: ['listItem'] }], buttonComponents: [{ type: ContentChildren, args: [forwardRef(() => ToolBarButtonComponent)] }] } });