@progress/kendo-angular-spreadsheet
Version:
A Spreadsheet Component for Angular
184 lines (183 loc) • 8.16 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 { Directive, ElementRef, HostBinding, Input } from '@angular/core';
import { FormulaListComponent } from './list.component';
import { PopupService } from '@progress/kendo-angular-popup';
import { SpreadsheetService } from '../common/spreadsheet.service';
import { SpreadsheetLocalizationService } from '../localization/spreadsheet-localization.service';
import * as i0 from "@angular/core";
import * as i1 from "@progress/kendo-angular-popup";
import * as i2 from "../common/spreadsheet.service";
import * as i3 from "../localization/spreadsheet-localization.service";
/**
* @hidden
*/
export class FormulaInputDirective {
element;
popupService;
spreadsheetService;
localization;
hostClasses = true;
get title() {
return this.localization.get('formulaInput');
}
role = 'combobox';
ariaHasPopup = 'menu';
ariaExpanded = 'false';
get ariaControls() {
return this.ariaExpanded === 'true' ? this.spreadsheetService.formulaListId : null;
}
formulaListMaxHeight;
list;
data;
constructor(element, popupService, spreadsheetService, localization) {
this.element = element;
this.popupService = popupService;
this.spreadsheetService = spreadsheetService;
this.localization = localization;
}
popupRef;
handler;
get listElement() {
return this.list?.element.nativeElement.firstElementChild;
}
get current() {
return {
element: this.element.nativeElement,
list: {
element: this.list?.element.nativeElement,
data: (d) => {
if (d) {
this.data = d;
this.list && (this.list.data = d);
}
else {
return this.data;
}
},
itemClick: (handler) => {
this.handler = handler;
},
value: () => { return {}; },
focus: () => {
const items = Array.from(this.listElement?.children || []);
return items.indexOf(this.focusedItem());
},
focusNext: () => this.focusNext(1),
focusPrev: () => this.focusNext(-1),
focusFirst: () => {
const list = this.listElement;
if (list && list.children.item(0)) {
this.unfocus();
list.children.item(0).classList.add('k-focus');
}
},
focusLast: () => {
const list = this.listElement;
if (list && list.children.length) {
this.unfocus();
list.children.item(list.children.length - 1).classList.add('k-focus');
}
},
},
popup: {
open: () => {
this.popupRef?.close();
this.popupRef = null;
this.popupRef = this.popupService.open({
anchor: this.element,
content: FormulaListComponent,
animate: { direction: 'down', duration: 100 }
});
const list = this.popupRef.content.instance;
this.list = list;
list.data = this.data;
list.itemClick = this.handler;
list.maxHeight = this.formulaListMaxHeight;
this.ariaExpanded = 'true';
},
close: () => {
this.popupRef?.close();
this.popupRef = null;
this.ariaExpanded = 'false';
},
position: () => { },
visible: () => {
return this.popupRef;
}
}
};
}
focusedItem = () => this.list?.element.nativeElement.querySelector('.k-focus');
unfocus = () => {
const focused = this.focusedItem();
if (focused) {
focused.classList.remove('k-focus');
}
};
focusNext = (dir) => {
const element = this.list?.element.nativeElement.firstElementChild;
const items = Array.from((element && element.children) || []);
const focused = this.focusedItem();
let next;
if (focused) {
const index = items.indexOf(focused);
focused.classList.remove('k-focus');
next = items[index + dir] ? items[index + dir] : (dir === 1 ? items[0] : items[items.length - 1]);
}
else {
next = (dir === 1 ? items[0] : items[items.length - 1]);
}
if (next) {
next.classList.add('k-focus');
const { offsetTop, offsetHeight, parentElement } = next;
if (dir > 0) {
if (offsetTop + offsetHeight >= parentElement.offsetHeight + parentElement.scrollTop) {
parentElement.scrollTop = Math.min(parentElement.scrollTop + offsetHeight, parentElement.scrollHeight - parentElement.offsetHeight);
}
if (next === items[0]) {
next.scrollIntoView();
}
}
else {
if (offsetTop <= parentElement.scrollTop) {
parentElement.scrollTop = Math.max(parentElement.scrollTop - offsetHeight, 0);
}
if (next === items[items.length - 1]) {
next.scrollIntoView();
}
}
}
};
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: FormulaInputDirective, deps: [{ token: i0.ElementRef }, { token: i1.PopupService }, { token: i2.SpreadsheetService }, { token: i3.SpreadsheetLocalizationService }], target: i0.ɵɵFactoryTarget.Directive });
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: FormulaInputDirective, isStandalone: true, selector: "[kendoSpreadsheetFormulaInput]", inputs: { formulaListMaxHeight: "formulaListMaxHeight" }, host: { properties: { "class.k-spreadsheet-formula-input": "this.hostClasses", "attr.title": "this.title", "attr.role": "this.role", "attr.aria-haspopup": "this.ariaHasPopup", "attr.aria-expanded": "this.ariaExpanded", "attr.aria-controls": "this.ariaControls" } }, ngImport: i0 });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: FormulaInputDirective, decorators: [{
type: Directive,
args: [{
selector: '[kendoSpreadsheetFormulaInput]',
standalone: true
}]
}], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i1.PopupService }, { type: i2.SpreadsheetService }, { type: i3.SpreadsheetLocalizationService }]; }, propDecorators: { hostClasses: [{
type: HostBinding,
args: ['class.k-spreadsheet-formula-input']
}], title: [{
type: HostBinding,
args: ['attr.title']
}], role: [{
type: HostBinding,
args: ['attr.role']
}], ariaHasPopup: [{
type: HostBinding,
args: ['attr.aria-haspopup']
}], ariaExpanded: [{
type: HostBinding,
args: ['attr.aria-expanded']
}], ariaControls: [{
type: HostBinding,
args: ['attr.aria-controls']
}], formulaListMaxHeight: [{
type: Input
}] } });