@nepwork/dashboards
Version:
Dashboards for emergencies and monitoring
437 lines • 17.5 kB
JavaScript
/**
* @license
* Copyright Akveo. All Rights Reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*/
import { __decorate, __metadata } from "tslib";
import { ChangeDetectorRef, Directive, ElementRef, forwardRef, HostBinding, HostListener, Input, } from '@angular/core';
import { NG_VALUE_ACCESSOR } from '@angular/forms';
import { NbTrigger, NbTriggerStrategyBuilderService } from '../cdk/overlay/overlay-trigger';
import { NbOverlayService } from '../cdk/overlay/overlay-service';
import { filter, startWith, switchMap, takeUntil, tap } from 'rxjs/operators';
import { merge, Subject } from 'rxjs';
import { ENTER, ESCAPE } from '../cdk/keycodes/keycodes';
import { NbAdjustment, NbPosition, NbPositionBuilderService, } from '../cdk/overlay/overlay-position';
import { NbActiveDescendantKeyManagerFactoryService, NbKeyManagerActiveItemMode, } from '../cdk/a11y/descendant-key-manager';
import { NbAutocompleteComponent } from './autocomplete.component';
import { convertToBoolProperty } from '../helpers';
/**
* The `NbAutocompleteDirective` provides a capability to expand input with
* `NbAutocompleteComponent` overlay containing options to select and fill input with.
*
* @stacked-example(Showcase, autocomplete/autocomplete-showcase.component)
*
* ### Installation
*
* Import `NbAutocompleteModule` to your feature module.
* ```ts
* @NgModule({
* imports: [
* // ...
* NbAutocompleteModule,
* ],
* })
* export class PageModule { }
* ```
* ### Usage
*
* You can bind control with form controls or ngModel.
*
* @stacked-example(Autocomplete form binding, autocomplete/autocomplete-form.component)
*
* Options in the autocomplete may be grouped using `nb-option-group` component.
*
* @stacked-example(Grouping, autocomplete/autocomplete-group.component)
*
* Autocomplete may change selected option value via provided function.
*
* @stacked-example(Custom display, autocomplete/autocomplete-custom-display.component)
*
* Also, autocomplete may make first option in option list active automatically.
*
* @stacked-example(Active first, autocomplete/autocomplete-active-first.component)
*
* */
var NbAutocompleteDirective = /** @class */ (function () {
function NbAutocompleteDirective(hostRef, overlay, cd, triggerStrategyBuilder, positionBuilder, activeDescendantKeyManagerFactory) {
this.hostRef = hostRef;
this.overlay = overlay;
this.cd = cd;
this.triggerStrategyBuilder = triggerStrategyBuilder;
this.positionBuilder = positionBuilder;
this.activeDescendantKeyManagerFactory = activeDescendantKeyManagerFactory;
this.overlayOffset = 8;
this.destroy$ = new Subject();
this._onChange = function () { };
this._onTouched = function () { };
this._focusInputOnValueChange = true;
this.role = 'combobox';
this.ariaAutocomplete = 'list';
this.hasPopup = 'true';
}
NbAutocompleteDirective_1 = NbAutocompleteDirective;
Object.defineProperty(NbAutocompleteDirective.prototype, "isOpen", {
/**
* Determines is autocomplete overlay opened.
* */
get: function () {
return this.overlayRef && this.overlayRef.hasAttached();
},
enumerable: true,
configurable: true
});
Object.defineProperty(NbAutocompleteDirective.prototype, "isClosed", {
/**
* Determines is autocomplete overlay closed.
* */
get: function () {
return !this.isOpen;
},
enumerable: true,
configurable: true
});
Object.defineProperty(NbAutocompleteDirective.prototype, "autocomplete", {
/**
* Provides autocomplete component.
* */
get: function () {
return this._autocomplete;
},
set: function (autocomplete) {
this._autocomplete = autocomplete;
},
enumerable: true,
configurable: true
});
Object.defineProperty(NbAutocompleteDirective.prototype, "focusInputOnValueChange", {
/**
* Determines if the input will be focused when the control value is changed
* */
get: function () {
return this._focusInputOnValueChange;
},
set: function (value) {
this._focusInputOnValueChange = convertToBoolProperty(value);
},
enumerable: true,
configurable: true
});
Object.defineProperty(NbAutocompleteDirective.prototype, "top", {
get: function () {
return this.isOpen && this.autocomplete.options.length && this.autocomplete.overlayPosition === NbPosition.TOP;
},
enumerable: true,
configurable: true
});
Object.defineProperty(NbAutocompleteDirective.prototype, "bottom", {
get: function () {
return this.isOpen && this.autocomplete.options.length && this.autocomplete.overlayPosition === NbPosition.BOTTOM;
},
enumerable: true,
configurable: true
});
Object.defineProperty(NbAutocompleteDirective.prototype, "ariaExpanded", {
get: function () {
return this.isOpen && this.isOpen.toString();
},
enumerable: true,
configurable: true
});
Object.defineProperty(NbAutocompleteDirective.prototype, "ariaOwns", {
get: function () {
return this.isOpen ? this.autocomplete.id : null;
},
enumerable: true,
configurable: true
});
Object.defineProperty(NbAutocompleteDirective.prototype, "ariaActiveDescendant", {
get: function () {
return (this.isOpen && this.keyManager.activeItem) ? this.keyManager.activeItem.id : null;
},
enumerable: true,
configurable: true
});
NbAutocompleteDirective.prototype.ngAfterViewInit = function () {
this.triggerStrategy = this.createTriggerStrategy();
this.subscribeOnTriggers();
};
NbAutocompleteDirective.prototype.ngOnDestroy = function () {
if (this.triggerStrategy) {
this.triggerStrategy.destroy();
}
if (this.positionStrategy) {
this.positionStrategy.dispose();
}
if (this.overlayRef) {
this.overlayRef.dispose();
}
this.destroy$.next();
this.destroy$.complete();
};
NbAutocompleteDirective.prototype.handleInput = function () {
var currentValue = this.hostRef.nativeElement.value;
this._onChange(currentValue);
this.setHostInputValue(this.getDisplayValue(currentValue));
this.show();
};
NbAutocompleteDirective.prototype.handleKeydown = function () {
this.show();
};
NbAutocompleteDirective.prototype.handleBlur = function () {
this._onTouched();
};
NbAutocompleteDirective.prototype.show = function () {
if (this.isClosed) {
this.attachToOverlay();
this.setActiveItem();
}
};
NbAutocompleteDirective.prototype.hide = function () {
if (this.isOpen) {
this.overlayRef.detach();
// Need to update class via @HostBinding
this.cd.markForCheck();
}
};
NbAutocompleteDirective.prototype.writeValue = function (value) {
this.handleInputValueUpdate(value);
};
NbAutocompleteDirective.prototype.registerOnChange = function (fn) {
this._onChange = fn;
};
NbAutocompleteDirective.prototype.registerOnTouched = function (fn) {
this._onTouched = fn;
};
NbAutocompleteDirective.prototype.subscribeOnOptionClick = function () {
var _this = this;
/**
* If the user changes provided options list in the runtime we have to handle this
* and resubscribe on options selection changes event.
* Otherwise, the user will not be able to select new options.
* */
this.autocomplete.options.changes
.pipe(tap(function () { return _this.setActiveItem(); }), startWith(this.autocomplete.options), switchMap(function (options) {
return merge.apply(void 0, options.map(function (option) { return option.click; }));
}), takeUntil(this.destroy$))
.subscribe(function (clickedOption) { return _this.handleInputValueUpdate(clickedOption.value); });
};
NbAutocompleteDirective.prototype.subscribeOnPositionChange = function () {
var _this = this;
this.positionStrategy.positionChange
.pipe(takeUntil(this.destroy$))
.subscribe(function (position) {
_this.autocomplete.overlayPosition = position;
_this.cd.detectChanges();
});
};
NbAutocompleteDirective.prototype.getActiveItem = function () {
return this.keyManager.activeItem;
};
NbAutocompleteDirective.prototype.setupAutocomplete = function () {
this.autocomplete.setHost(this.hostRef);
};
NbAutocompleteDirective.prototype.getDisplayValue = function (value) {
var displayFn = this.autocomplete.handleDisplayFn;
return displayFn ? displayFn(value) : value;
};
NbAutocompleteDirective.prototype.getContainer = function () {
return this.overlayRef && this.isOpen && {
location: {
nativeElement: this.overlayRef.overlayElement,
},
};
};
NbAutocompleteDirective.prototype.handleInputValueUpdate = function (value) {
if (value === undefined || value === null) {
return;
}
this.setHostInputValue(value);
this._onChange(value);
if (this.focusInputOnValueChange) {
this.hostRef.nativeElement.focus();
}
this.autocomplete.emitSelected(value);
this.hide();
};
NbAutocompleteDirective.prototype.subscribeOnTriggers = function () {
var _this = this;
this.triggerStrategy.show$
.pipe(filter(function () { return _this.isClosed; }))
.subscribe(function () { return _this.show(); });
this.triggerStrategy.hide$
.pipe(filter(function () { return _this.isOpen; }))
.subscribe(function () { return _this.hide(); });
};
NbAutocompleteDirective.prototype.createTriggerStrategy = function () {
var _this = this;
return this.triggerStrategyBuilder
.trigger(NbTrigger.FOCUS)
.host(this.hostRef.nativeElement)
.container(function () { return _this.getContainer(); })
.build();
};
NbAutocompleteDirective.prototype.createKeyManager = function () {
this.keyManager = this.activeDescendantKeyManagerFactory
.create(this.autocomplete.options);
};
NbAutocompleteDirective.prototype.setHostInputValue = function (value) {
this.hostRef.nativeElement.value = this.getDisplayValue(value);
};
NbAutocompleteDirective.prototype.createPositionStrategy = function () {
return this.positionBuilder
.connectedTo(this.hostRef)
.position(NbPosition.BOTTOM)
.offset(this.overlayOffset)
.adjustment(NbAdjustment.VERTICAL);
};
NbAutocompleteDirective.prototype.subscribeOnOverlayKeys = function () {
var _this = this;
this.overlayRef.keydownEvents()
.pipe(takeUntil(this.destroy$))
.subscribe(function (event) {
if (event.keyCode === ESCAPE && _this.isOpen) {
event.preventDefault();
_this.hostRef.nativeElement.focus();
_this.hide();
}
else if (event.keyCode === ENTER) {
event.preventDefault();
var activeItem = _this.getActiveItem();
if (!activeItem) {
return;
}
_this.handleInputValueUpdate(activeItem.value);
}
else {
_this.keyManager.onKeydown(event);
}
});
};
NbAutocompleteDirective.prototype.setActiveItem = function () {
// If autocomplete has activeFirst input set to true,
// keyManager set first option active, otherwise - reset active option.
var mode = this.autocomplete.activeFirst
? NbKeyManagerActiveItemMode.FIRST_ACTIVE
: NbKeyManagerActiveItemMode.RESET_ACTIVE;
this.keyManager.setActiveItem(mode);
this.cd.detectChanges();
};
NbAutocompleteDirective.prototype.attachToOverlay = function () {
if (!this.overlayRef) {
this.setupAutocomplete();
this.initOverlay();
}
this.overlayRef.attach(this.autocomplete.portal);
};
NbAutocompleteDirective.prototype.createOverlay = function () {
var scrollStrategy = this.createScrollStrategy();
this.overlayRef = this.overlay.create({ positionStrategy: this.positionStrategy, scrollStrategy: scrollStrategy });
};
NbAutocompleteDirective.prototype.initOverlay = function () {
this.positionStrategy = this.createPositionStrategy();
this.createKeyManager();
this.subscribeOnPositionChange();
this.subscribeOnOptionClick();
this.checkOverlayVisibility();
this.createOverlay();
this.subscribeOnOverlayKeys();
};
NbAutocompleteDirective.prototype.checkOverlayVisibility = function () {
var _this = this;
this.autocomplete.options.changes
.pipe(takeUntil(this.destroy$)).subscribe(function () {
if (!_this.autocomplete.options.length) {
_this.hide();
}
});
};
NbAutocompleteDirective.prototype.createScrollStrategy = function () {
return this.overlay.scrollStrategies.block();
};
var NbAutocompleteDirective_1;
__decorate([
Input('nbAutocomplete'),
__metadata("design:type", NbAutocompleteComponent),
__metadata("design:paramtypes", [NbAutocompleteComponent])
], NbAutocompleteDirective.prototype, "autocomplete", null);
__decorate([
Input(),
__metadata("design:type", Boolean),
__metadata("design:paramtypes", [Boolean])
], NbAutocompleteDirective.prototype, "focusInputOnValueChange", null);
__decorate([
HostBinding('class.nb-autocomplete-position-top'),
__metadata("design:type", Boolean),
__metadata("design:paramtypes", [])
], NbAutocompleteDirective.prototype, "top", null);
__decorate([
HostBinding('class.nb-autocomplete-position-bottom'),
__metadata("design:type", Boolean),
__metadata("design:paramtypes", [])
], NbAutocompleteDirective.prototype, "bottom", null);
__decorate([
HostBinding('attr.role'),
__metadata("design:type", String)
], NbAutocompleteDirective.prototype, "role", void 0);
__decorate([
HostBinding('attr.aria-autocomplete'),
__metadata("design:type", String)
], NbAutocompleteDirective.prototype, "ariaAutocomplete", void 0);
__decorate([
HostBinding('attr.haspopup'),
__metadata("design:type", String)
], NbAutocompleteDirective.prototype, "hasPopup", void 0);
__decorate([
HostBinding('attr.aria-expanded'),
__metadata("design:type", String),
__metadata("design:paramtypes", [])
], NbAutocompleteDirective.prototype, "ariaExpanded", null);
__decorate([
HostBinding('attr.aria-owns'),
__metadata("design:type", Object),
__metadata("design:paramtypes", [])
], NbAutocompleteDirective.prototype, "ariaOwns", null);
__decorate([
HostBinding('attr.aria-activedescendant'),
__metadata("design:type", Object),
__metadata("design:paramtypes", [])
], NbAutocompleteDirective.prototype, "ariaActiveDescendant", null);
__decorate([
HostListener('input'),
__metadata("design:type", Function),
__metadata("design:paramtypes", []),
__metadata("design:returntype", void 0)
], NbAutocompleteDirective.prototype, "handleInput", null);
__decorate([
HostListener('keydown.arrowDown'),
HostListener('keydown.arrowUp'),
__metadata("design:type", Function),
__metadata("design:paramtypes", []),
__metadata("design:returntype", void 0)
], NbAutocompleteDirective.prototype, "handleKeydown", null);
__decorate([
HostListener('blur'),
__metadata("design:type", Function),
__metadata("design:paramtypes", []),
__metadata("design:returntype", void 0)
], NbAutocompleteDirective.prototype, "handleBlur", null);
NbAutocompleteDirective = NbAutocompleteDirective_1 = __decorate([
Directive({
selector: 'input[nbAutocomplete]',
providers: [{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(function () { return NbAutocompleteDirective_1; }),
multi: true,
}],
}),
__metadata("design:paramtypes", [ElementRef,
NbOverlayService,
ChangeDetectorRef,
NbTriggerStrategyBuilderService,
NbPositionBuilderService,
NbActiveDescendantKeyManagerFactoryService])
], NbAutocompleteDirective);
return NbAutocompleteDirective;
}());
export { NbAutocompleteDirective };
//# sourceMappingURL=autocomplete.directive.js.map