@clr/angular
Version:
Angular components for Clarity
94 lines • 13.1 kB
JavaScript
/*
* Copyright (c) 2016-2023 VMware, Inc. All Rights Reserved.
* This software is released under MIT license.
* The full license information can be found in LICENSE in the root directory of this project.
*/
import { Injectable, Optional, Renderer2, SkipSelf } from '@angular/core';
import { isObservable, of } from 'rxjs';
import { ArrowKeyDirection } from './arrow-key-direction.enum';
import * as i0 from "@angular/core";
export class FocusService {
constructor(renderer) {
this.renderer = renderer;
this._unlistenFuncs = [];
}
get current() {
return this._current;
}
reset(first) {
this._current = first;
}
listenToArrowKeys(el) {
// The following listeners return false when there was an action to take for the key pressed,
// in order to prevent the default behavior of that key.
this._unlistenFuncs.push(this.renderer.listen(el, 'keydown.arrowup', () => !this.move(ArrowKeyDirection.UP)));
this._unlistenFuncs.push(this.renderer.listen(el, 'keydown.arrowdown', () => !this.move(ArrowKeyDirection.DOWN)));
this._unlistenFuncs.push(this.renderer.listen(el, 'keydown.arrowleft', () => !this.move(ArrowKeyDirection.LEFT)));
this._unlistenFuncs.push(this.renderer.listen(el, 'keydown.arrowright', () => !this.move(ArrowKeyDirection.RIGHT)));
}
registerContainer(el, tabIndex = '0') {
this.renderer.setAttribute(el, 'tabindex', tabIndex);
this.listenToArrowKeys(el);
// The following listeners return false when there was an action to take for the key pressed,
// in order to prevent the default behavior of that key.
this._unlistenFuncs.push(this.renderer.listen(el, 'keydown.space', () => !this.activateCurrent()));
this._unlistenFuncs.push(this.renderer.listen(el, 'keydown.enter', () => !this.activateCurrent()));
}
moveTo(item) {
/**
* Make sure that item is not undefined,
* This is safety net in the case that someone sometime decide to
* call this method without having FocusableItem.
*/
if (item === undefined) {
return;
}
if (this.current) {
this.current.blur();
}
item.focus();
this._current = item;
}
move(direction) {
let moved = false;
if (this.current) {
const next = this.current[direction];
if (next) {
// Turning the value into an Observable isn't great, but it's the fastest way to avoid code duplication.
// If performance ever matters for this, we can refactor using additional private methods.
const nextObs = isObservable(next) ? next : of(next);
nextObs.subscribe(item => {
if (item) {
this.moveTo(item);
moved = true;
}
});
}
}
return moved;
}
activateCurrent() {
if (this.current && this.current.activate) {
this.current.activate();
return true;
}
return false;
}
detachListeners() {
this._unlistenFuncs.forEach(unlisten => unlisten());
}
}
FocusService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: FocusService, deps: [{ token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Injectable });
FocusService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: FocusService });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: FocusService, decorators: [{
type: Injectable
}], ctorParameters: function () { return [{ type: i0.Renderer2 }]; } });
export function clrFocusServiceFactory(existing, renderer) {
return existing || new FocusService(renderer);
}
export const FOCUS_SERVICE_PROVIDER = {
provide: FocusService,
useFactory: clrFocusServiceFactory,
deps: [[new Optional(), new SkipSelf(), FocusService], Renderer2],
};
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZm9jdXMuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2FuZ3VsYXIvc3JjL3V0aWxzL2ZvY3VzL2ZvY3VzLnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7R0FJRztBQUVILE9BQU8sRUFBRSxVQUFVLEVBQUUsUUFBUSxFQUFFLFNBQVMsRUFBRSxRQUFRLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDMUUsT0FBTyxFQUFFLFlBQVksRUFBRSxFQUFFLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFFeEMsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sNEJBQTRCLENBQUM7O0FBSS9ELE1BQU0sT0FBTyxZQUFZO0lBSXZCLFlBQW9CLFFBQW1CO1FBQW5CLGFBQVEsR0FBUixRQUFRLENBQVc7UUFGL0IsbUJBQWMsR0FBbUIsRUFBRSxDQUFDO0lBRUYsQ0FBQztJQUUzQyxJQUFJLE9BQU87UUFDVCxPQUFPLElBQUksQ0FBQyxRQUFRLENBQUM7SUFDdkIsQ0FBQztJQUVELEtBQUssQ0FBQyxLQUFvQjtRQUN4QixJQUFJLENBQUMsUUFBUSxHQUFHLEtBQUssQ0FBQztJQUN4QixDQUFDO0lBRUQsaUJBQWlCLENBQUMsRUFBZTtRQUMvQiw2RkFBNkY7UUFDN0Ysd0RBQXdEO1FBQ3hELElBQUksQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLEVBQUUsRUFBRSxpQkFBaUIsRUFBRSxHQUFHLEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsaUJBQWlCLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQzlHLElBQUksQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLEVBQUUsRUFBRSxtQkFBbUIsRUFBRSxHQUFHLEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJ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QUMsRUFBRSxDQUFDLFFBQVEsRUFBRSxDQUFDLENBQUM7SUFDdEQsQ0FBQzs7eUdBOUVVLFlBQVk7NkdBQVosWUFBWTsyRkFBWixZQUFZO2tCQUR4QixVQUFVOztBQWtGWCxNQUFNLFVBQVUsc0JBQXNCLENBQUMsUUFBc0IsRUFBRSxRQUFtQjtJQUNoRixPQUFPLFFBQVEsSUFBSSxJQUFJLFlBQVksQ0FBQyxRQUFRLENBQUMsQ0FBQztBQUNoRCxDQUFDO0FBRUQsTUFBTSxDQUFDLE1BQU0sc0JBQXNCLEdBQUc7SUFDcEMsT0FBTyxFQUFFLFlBQVk7SUFDckIsVUFBVSxFQUFFLHNCQUFzQjtJQUNsQyxJQUFJLEVBQUUsQ0FBQyxDQUFDLElBQUksUUFBUSxFQUFFLEVBQUUsSUFBSSxRQUFRLEVBQUUsRUFBRSxZQUFZLENBQUMsRUFBRSxTQUFTLENBQUM7Q0FDbEUsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qXG4gKiBDb3B5cmlnaHQgKGMpIDIwMTYtMjAyMyBWTXdhcmUsIEluYy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqIFRoaXMgc29mdHdhcmUgaXMgcmVsZWFzZWQgdW5kZXIgTUlUIGxpY2Vuc2UuXG4gKiBUaGUgZnVsbCBsaWNlbnNlIGluZm9ybWF0aW9uIGNhbiBiZSBmb3VuZCBpbiBMSUNFTlNFIGluIHRoZSByb290IGRpcmVjdG9yeSBvZiB0aGlzIHByb2plY3QuXG4gKi9cblxuaW1wb3J0IHsgSW5qZWN0YWJsZSwgT3B0aW9uYWwsIFJlbmRlcmVyMiwgU2tpcFNlbGYgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IGlzT2JzZXJ2YWJsZSwgb2YgfSBmcm9tICdyeGpzJztcblxuaW1wb3J0IHsgQXJyb3dLZXlEaXJlY3Rpb24gfSBmcm9tICcuL2Fycm93LWtleS1kaXJlY3Rpb24uZW51bSc7XG5pbXBvcnQgeyBGb2N1c2FibGVJdGVtIH0gZnJvbSAnLi9mb2N1c2FibGUtaXRlbS9mb2N1c2FibGUtaXRlbSc7XG5cbkBJbmplY3RhYmxlKClcbmV4cG9ydCBjbGFzcyBGb2N1c1NlcnZpY2Uge1xuICBwcml2YXRlIF9jdXJyZW50OiBGb2N1c2FibGVJdGVtO1xuICBwcml2YXRlIF91bmxpc3RlbkZ1bmNzOiAoKCkgPT4gdm9pZClbXSA9IFtdO1xuXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgcmVuZGVyZXI6IFJlbmRlcmVyMikge31cblxuICBnZXQgY3VycmVudCgpIHtcbiAgICByZXR1cm4gdGhpcy5fY3VycmVudDtcbiAgfVxuXG4gIHJlc2V0KGZpcnN0OiBGb2N1c2FibGVJdGVtKSB7XG4gICAgdGhpcy5fY3VycmVudCA9IGZpcnN0O1xuICB9XG5cbiAgbGlzdGVuVG9BcnJvd0tleXMoZWw6IEhUTUxFbGVtZW50KSB7XG4gICAgLy8gVGhlIGZvbGxvd2luZyBsaXN0ZW5lcnMgcmV0dXJuIGZhbHNlIHdoZW4gdGhlcmUgd2FzIGFuIGFjdGlvbiB0byB0YWtlIGZvciB0aGUga2V5IHByZXNzZWQsXG4gICAgLy8gaW4gb3JkZXIgdG8gcHJldmVudCB0aGUgZGVmYXVsdCBiZWhhdmlvciBvZiB0aGF0IGtleS5cbiAgICB0aGlzLl91bmxpc3RlbkZ1bmNzLnB1c2godGhpcy5yZW5kZXJlci5saXN0ZW4oZWwsICdrZXlkb3duLmFycm93dXAnLCAoKSA9PiAhdGhpcy5tb3ZlKEFycm93S2V5RGlyZWN0aW9uLlVQKSkpO1xuICAgIHRoaXMuX3VubGlzdGVuRnVuY3MucHVzaCh0aGlzLnJlbmRlcmVyLmxpc3RlbihlbCwgJ2tleWRvd24uYXJyb3dkb3duJywgKCkgPT4gIXRoaXMubW92ZShBcnJvd0tleURpcmVjdGlvbi5ET1dOKSkpO1xuICAgIHRoaXMuX3VubGlzdGVuRnVuY3MucHVzaCh0aGlzLnJlbmRlcmVyLmxpc3RlbihlbCwgJ2tleWRvd24uYXJyb3dsZWZ0JywgKCkgPT4gIXRoaXMubW92ZShBcnJvd0tleURpcmVjdGlvbi5MRUZUKSkpO1xuICAgIHRoaXMuX3VubGlzdGVuRnVuY3MucHVzaCh0aGlzLnJlbmRlcmVyLmxpc3RlbihlbCwgJ2tleWRvd24uYXJyb3dyaWdodCcsICgpID0+ICF0aGlzLm1vdmUoQXJyb3dLZXlEaXJlY3Rpb24uUklHSFQpKSk7XG4gIH1cblxuICByZWdpc3RlckNvbnRhaW5lcihlbDogSFRNTEVsZW1lbnQsIHRhYkluZGV4ID0gJzAnKSB7XG4gICAgdGhpcy5yZW5kZXJlci5zZXRBdHRyaWJ1dGUoZWwsICd0YWJpbmRleCcsIHRhYkluZGV4KTtcbiAgICB0aGlzLmxpc3RlblRvQXJyb3dLZXlzKGVsKTtcbiAgICAvLyBUaGUgZm9sbG93aW5nIGxpc3RlbmVycyByZXR1cm4gZmFsc2Ugd2hlbiB0aGVyZSB3YXMgYW4gYWN0aW9uIHRvIHRha2UgZm9yIHRoZSBrZXkgcHJlc3NlZCxcbiAgICAvLyBpbiBvcmRlciB0byBwcmV2ZW50IHRoZSBkZWZhdWx0IGJlaGF2aW9yIG9mIHRoYXQga2V5LlxuICAgIHRoaXMuX3VubGlzdGVuRnVuY3MucHVzaCh0aGlzLnJlbmRlcmVyLmxpc3RlbihlbCwgJ2tleWRvd24uc3BhY2UnLCAoKSA9PiAhdGhpcy5hY3RpdmF0ZUN1cnJlbnQoKSkpO1xuICAgIHRoaXMuX3VubGlzdGVuRnVuY3MucHVzaCh0aGlzLnJlbmRlcmVyLmxpc3RlbihlbCwgJ2tleWRvd24uZW50ZXInLCAoKSA9PiAhdGhpcy5hY3RpdmF0ZUN1cnJlbnQoKSkpO1xuICB9XG5cbiAgbW92ZVRvKGl0ZW06IEZvY3VzYWJsZUl0ZW0pIHtcbiAgICAvKipcbiAgICAgKiBNYWtlIHN1cmUgdGhhdCBpdGVtIGlzIG5vdCB1bmRlZmluZWQsXG4gICAgICogVGhpcyBpcyBzYWZldHkgbmV0IGluIHRoZSBjYXNlIHRoYXQgc29tZW9uZSBzb21ldGltZSBkZWNpZGUgdG9cbiAgICAgKiBjYWxsIHRoaXMgbWV0aG9kIHdpdGhvdXQgaGF2aW5nIEZvY3VzYWJsZUl0ZW0uXG4gICAgICovXG4gICAgaWYgKGl0ZW0gPT09IHVuZGVmaW5lZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmICh0aGlzLmN1cnJlbnQpIHtcbiAgICAgIHRoaXMuY3VycmVudC5ibHVyKCk7XG4gICAgfVxuICAgIGl0ZW0uZm9jdXMoKTtcbiAgICB0aGlzLl9jdXJyZW50ID0gaXRlbTtcbiAgfVxuXG4gIG1vdmUoZGlyZWN0aW9uOiBBcnJvd0tleURpcmVjdGlvbik6IGJvb2xlYW4ge1xuICAgIGxldCBtb3ZlZCA9IGZhbHNlO1xuICAgIGlmICh0aGlzLmN1cnJlbnQpIHtcbiAgICAgIGNvbnN0IG5leHQgPSB0aGlzLmN1cnJlbnRbZGlyZWN0aW9uXTtcbiAgICAgIGlmIChuZXh0KSB7XG4gICAgICAgIC8vIFR1cm5pbmcgdGhlIHZhbHVlIGludG8gYW4gT2JzZXJ2YWJsZSBpc24ndCBncmVhdCwgYnV0IGl0J3MgdGhlIGZhc3Rlc3Qgd2F5IHRvIGF2b2lkIGNvZGUgZHVwbGljYXRpb24uXG4gICAgICAgIC8vIElmIHBlcmZvcm1hbmNlIGV2ZXIgbWF0dGVycyBmb3IgdGhpcywgd2UgY2FuIHJlZmFjdG9yIHVzaW5nIGFkZGl0aW9uYWwgcHJpdmF0ZSBtZXRob2RzLlxuICAgICAgICBjb25zdCBuZXh0T2JzID0gaXNPYnNlcnZhYmxlKG5leHQpID8gbmV4dCA6IG9mKG5leHQpO1xuICAgICAgICBuZXh0T2JzLnN1YnNjcmliZShpdGVtID0+IHtcbiAgICAgICAgICBpZiAoaXRlbSkge1xuICAgICAgICAgICAgdGhpcy5tb3ZlVG8oaXRlbSk7XG4gICAgICAgICAgICBtb3ZlZCA9IHRydWU7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIG1vdmVkO1xuICB9XG5cbiAgYWN0aXZhdGVDdXJyZW50KCkge1xuICAgIGlmICh0aGlzLmN1cnJlbnQgJiYgdGhpcy5jdXJyZW50LmFjdGl2YXRlKSB7XG4gICAgICB0aGlzLmN1cnJlbnQuYWN0aXZhdGUoKTtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBkZXRhY2hMaXN0ZW5lcnMoKSB7XG4gICAgdGhpcy5fdW5saXN0ZW5GdW5jcy5mb3JFYWNoKHVubGlzdGVuID0+IHVubGlzdGVuKCkpO1xuICB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjbHJGb2N1c1NlcnZpY2VGYWN0b3J5KGV4aXN0aW5nOiBGb2N1c1NlcnZpY2UsIHJlbmRlcmVyOiBSZW5kZXJlcjIpIHtcbiAgcmV0dXJuIGV4aXN0aW5nIHx8IG5ldyBGb2N1c1NlcnZpY2UocmVuZGVyZXIpO1xufVxuXG5leHBvcnQgY29uc3QgRk9DVVNfU0VSVklDRV9QUk9WSURFUiA9IHtcbiAgcHJvdmlkZTogRm9jdXNTZXJ2aWNlLFxuICB1c2VGYWN0b3J5OiBjbHJGb2N1c1NlcnZpY2VGYWN0b3J5LFxuICBkZXBzOiBbW25ldyBPcHRpb25hbCgpLCBuZXcgU2tpcFNlbGYoKSwgRm9jdXNTZXJ2aWNlXSwgUmVuZGVyZXIyXSxcbn07XG4iXX0=