UNPKG

@ux-aspects/ux-aspects

Version:

Open source user interface framework for building modern, responsive, mobile big data applications

103 lines 14.5 kB
import { DOWN_ARROW, LEFT_ARROW, RIGHT_ARROW, UP_ARROW } from '@angular/cdk/keycodes'; import { Injectable } from '@angular/core'; import { BehaviorSubject, Subject } from 'rxjs'; import * as i0 from "@angular/core"; export class SankeyFocusManager { constructor() { /** Store the node that can currently be tabbed to */ this.active$ = new BehaviorSubject(null); /** Emit whenever an item should receive focus */ this.focused$ = new Subject(); /** Store the nodes */ this._nodes = []; } /** Get the current active item */ get _active() { return this.active$.value; } ngOnDestroy() { this.active$.complete(); this.focused$.complete(); } /** Update the list of possible nodes */ setNodes(nodes) { this._nodes = nodes; // check if there is currently a tabbable node, if not we should make the first node tabbable if (!this.hasActiveNode()) { this.setActiveItem(this._nodes[0]); } } /** Set the current active item */ setActiveItem(node) { this.active$.next(node); } /** Handle keyboard input from nodes */ onKeydown(event) { switch (event.which) { case UP_ARROW: this.shiftFocusVertically(-1); event.preventDefault(); break; case DOWN_ARROW: this.shiftFocusVertically(1); event.preventDefault(); break; case LEFT_ARROW: this.shiftFocusHorizontally(-1); event.preventDefault(); break; case RIGHT_ARROW: this.shiftFocusHorizontally(1); event.preventDefault(); break; } } setFocusedItem(item) { this.setActiveItem(item); this.focused$.next(item); } shiftFocusVertically(delta) { const nodes = this.getNodesInColumn(this._active.column); // get the node below or above the active node const target = nodes[nodes.findIndex(node => node.node.id === this._active.node.id) + delta]; if (target) { this.setFocusedItem(target); } } /** Shift the focus to a node in a sibling column */ shiftFocusHorizontally(delta) { // get nodes in the sibling column in the desired direction const nodes = this.getNodesInColumn(this._active.column + delta); // if there are no nodes then do nothing as we cannot reduce an empty array if (nodes.length === 0) { return; } // get the node with the most similar y position const target = nodes.reduce((closest, node) => { const closestDiff = Math.max(closest.y, this._active.y) - Math.min(closest.y, this._active.y); const currentDiff = Math.max(node.y, this._active.y) - Math.min(node.y, this._active.y); return closestDiff < currentDiff ? closest : node; }); if (target) { this.setFocusedItem(target); } } /** Get a list of nodes that are in a given column */ getNodesInColumn(column) { return this.getNodesInOrder(this._nodes.filter(node => node.column === column)); } /** Sort the nodes based on the Y position */ getNodesInOrder(nodes) { return [...nodes].sort((nodeOne, nodeTwo) => nodeOne.y - nodeTwo.y); } /** Determine whether or not there is a not that is tabbable */ hasActiveNode() { return !!this.active$.value && !!this._nodes.find(node => node.node.id === this.active$.value.node.id); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.12", ngImport: i0, type: SankeyFocusManager, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); } static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.12", ngImport: i0, type: SankeyFocusManager }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.12", ngImport: i0, type: SankeyFocusManager, decorators: [{ type: Injectable }] }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2Fua2V5LWZvY3VzLW1hbmFnZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9zcmMvY29tcG9uZW50cy9zYW5rZXktY2hhcnQvc2Fua2V5LWZvY3VzLW1hbmFnZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxVQUFVLEVBQUUsV0FBVyxFQUFFLFFBQVEsRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBQ3RGLE9BQU8sRUFBRSxVQUFVLEVBQWEsTUFBTSxlQUFlLENBQUM7QUFDdEQsT0FBTyxFQUFFLGVBQWUsRUFBRSxPQUFPLEVBQUUsTUFBTSxNQUFNLENBQUM7O0FBSWhELE1BQU0sT0FBTyxrQkFBa0I7SUFEL0I7UUFHSSxxREFBcUQ7UUFDckQsWUFBTyxHQUFHLElBQUksZUFBZSxDQUFvQixJQUFJLENBQUMsQ0FBQztRQUV2RCxpREFBaUQ7UUFDakQsYUFBUSxHQUFHLElBQUksT0FBTyxFQUFxQixDQUFDO1FBRTVDLHVCQUF1QjtRQUNmLFdBQU0sR0FBcUMsRUFBRSxDQUFDO0tBMkd6RDtJQXpHRyxrQ0FBa0M7SUFDbEMsSUFBWSxPQUFPO1FBQ2YsT0FBTyxJQUFJLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQztJQUM5QixDQUFDO0lBRUQsV0FBVztRQUNQLElBQUksQ0FBQyxPQUFPLENBQUMsUUFBUSxFQUFFLENBQUM7UUFDeEIsSUFBSSxDQUFDLFFBQVEsQ0FBQyxRQUFRLEVBQUUsQ0FBQztJQUM3QixDQUFDO0lBRUQsd0NBQXdDO0lBQ3hDLFFBQVEsQ0FBQyxLQUF1QztRQUM1QyxJQUFJLENBQUMsTUFBTSxHQUFHLEtBQUssQ0FBQztRQUVwQiw2RkFBNkY7UUFDN0YsSUFBSSxDQUFDLElBQUksQ0FBQyxhQUFhLEVBQUUsRUFBRSxDQUFDO1lBQ3hCLElBQUksQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3ZDLENB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Q0FBQyxJQUFJLENBQUM7UUFDdEQsQ0FBQyxDQUFDLENBQUM7UUFFSCxJQUFJLE1BQU0sRUFBRSxDQUFDO1lBQ1QsSUFBSSxDQUFDLGNBQWMsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUNoQyxDQUFDO0lBQ0wsQ0FBQztJQUVELHFEQUFxRDtJQUM3QyxnQkFBZ0IsQ0FBQyxNQUFjO1FBQ25DLE9BQU8sSUFBSSxDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxNQUFNLEtBQUssTUFBTSxDQUFDLENBQUMsQ0FBQztJQUNwRixDQUFDO0lBRUQsNkNBQTZDO0lBQ3JDLGVBQWUsQ0FBQyxLQUF1QztRQUMzRCxPQUFPLENBQUMsR0FBRyxLQUFLLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxPQUFPLEVBQUUsT0FBTyxFQUFFLEVBQUUsQ0FBQyxPQUFPLENBQUMsQ0FBQyxHQUFHLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUN4RSxDQUFDO0lBRUQsK0RBQStEO0lBQ3ZELGFBQWE7UUFDakIsT0FBTyxDQUFDLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxLQUFLLElBQUksQ0FBQyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFLEtBQUssSUFBSSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDO0lBQzNHLENBQUM7K0dBbEhRLGtCQUFrQjttSEFBbEIsa0JBQWtCOzs0RkFBbEIsa0JBQWtCO2tCQUQ5QixVQUFVIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgRE9XTl9BUlJPVywgTEVGVF9BUlJPVywgUklHSFRfQVJST1csIFVQX0FSUk9XIH0gZnJvbSAnQGFuZ3VsYXIvY2RrL2tleWNvZGVzJztcbmltcG9ydCB7IEluamVjdGFibGUsIE9uRGVzdHJveSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQmVoYXZpb3JTdWJqZWN0LCBTdWJqZWN0IH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBTYW5rZXlOb2RlTGluayB9IGZyb20gJy4vaW50ZXJmYWNlcy9ub2RlLWxpbmsuaW50ZXJmYWNlJztcblxuQEluamVjdGFibGUoKVxuZXhwb3J0IGNsYXNzIFNhbmtleUZvY3VzTWFuYWdlcjxUPiBpbXBsZW1lbnRzIE9uRGVzdHJveSB7XG5cbiAgICAvKiogU3RvcmUgdGhlIG5vZGUgdGhhdCBjYW4gY3VycmVudGx5IGJlIHRhYmJlZCB0byAqL1xuICAgIGFjdGl2ZSQgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PFNhbmtleU5vZGVMaW5rPFQ+PihudWxsKTtcblxuICAgIC8qKiBFbWl0IHdoZW5ldmVyIGFuIGl0ZW0gc2hvdWxkIHJlY2VpdmUgZm9jdXMgKi9cbiAgICBmb2N1c2VkJCA9IG5ldyBTdWJqZWN0PFNhbmtleU5vZGVMaW5rPFQ+PigpO1xuXG4gICAgLyoqIFN0b3JlIHRoZSBub2RlcyAgKi9cbiAgICBwcml2YXRlIF9ub2RlczogUmVhZG9ubHlBcnJheTxTYW5rZXlOb2RlTGluazxUPj4gPSBbXTtcblxuICAgIC8qKiBHZXQgdGhlIGN1cnJlbnQgYWN0aXZlIGl0ZW0gKi9cbiAgICBwcml2YXRlIGdldCBfYWN0aXZlKCk6IFNhbmtleU5vZGVMaW5rPFQ+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuYWN0aXZlJC52YWx1ZTtcbiAgICB9XG5cbiAgICBuZ09uRGVzdHJveSgpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5hY3RpdmUkLmNvbXBsZXRlKCk7XG4gICAgICAgIHRoaXMuZm9jdXNlZCQuY29tcGxldGUoKTtcbiAgICB9XG5cbiAgICAvKiogVXBkYXRlIHRoZSBsaXN0IG9mIHBvc3NpYmxlIG5vZGVzICovXG4gICAgc2V0Tm9kZXMobm9kZXM6IFJlYWRvbmx5QXJyYXk8U2Fua2V5Tm9kZUxpbms8VD4+KTogdm9pZCB7XG4gICAgICAgIHRoaXMuX25vZGVzID0gbm9kZXM7XG5cbiAgICAgICAgLy8gY2hlY2sgaWYgdGhlcmUgaXMgY3VycmVudGx5IGEgdGFiYmFibGUgbm9kZSwgaWYgbm90IHdlIHNob3VsZCBtYWtlIHRoZSBmaXJzdCBub2RlIHRhYmJhYmxlXG4gICAgICAgIGlmICghdGhpcy5oYXNBY3RpdmVOb2RlKCkpIHtcbiAgICAgICAgICAgIHRoaXMuc2V0QWN0aXZlSXRlbSh0aGlzLl9ub2Rlc1swXSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKiogU2V0IHRoZSBjdXJyZW50IGFjdGl2ZSBpdGVtICovXG4gICAgc2V0QWN0aXZlSXRlbShub2RlOiBTYW5rZXlOb2RlTGluazxUPik6IHZvaWQge1xuICAgICAgICB0aGlzLmFjdGl2ZSQubmV4dChub2RlKTtcbiAgICB9XG5cbiAgICAvKiogSGFuZGxlIGtleWJvYXJkIGlucHV0IGZyb20gbm9kZXMgKi9cbiAgICBvbktleWRvd24oZXZlbnQ6IEtleWJvYXJkRXZlbnQpOiB2b2lkIHtcblxuICAgICAgICBzd2l0Y2ggKGV2ZW50LndoaWNoKSB7XG4gICAgICAgICAgICBjYXNlIFVQX0FSUk9XOlxuICAgICAgICAgICAgICAgIHRoaXMuc2hpZnRGb2N1c1ZlcnRpY2FsbHkoLTEpO1xuICAgICAgICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgICAgIGNhc2UgRE9XTl9BUlJPVzpcbiAgICAgICAgICAgICAgICB0aGlzLnNoaWZ0Rm9jdXNWZXJ0aWNhbGx5KDEpO1xuICAgICAgICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgICAgIGNhc2UgTEVGVF9BUlJPVzpcbiAgICAgICAgICAgICAgICB0aGlzLnNoaWZ0Rm9jdXNIb3Jpem9udGFsbHkoLTEpO1xuICAgICAgICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgICAgIGNhc2UgUklHSFRfQVJST1c6XG4gICAgICAgICAgICAgICAgdGhpcy5zaGlmdEZvY3VzSG9yaXpvbnRhbGx5KDEpO1xuICAgICAgICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIHNldEZvY3VzZWRJdGVtKGl0ZW06IFNhbmtleU5vZGVMaW5rPFQ+KTogdm9pZCB7XG4gICAgICAgIHRoaXMuc2V0QWN0aXZlSXRlbShpdGVtKTtcbiAgICAgICAgdGhpcy5mb2N1c2VkJC5uZXh0KGl0ZW0pO1xuICAgIH1cblxuICAgIHByaXZhdGUgc2hpZnRGb2N1c1ZlcnRpY2FsbHkoZGVsdGE6IG51bWJlcik6IHZvaWQge1xuICAgICAgICBjb25zdCBub2RlcyA9IHRoaXMuZ2V0Tm9kZXNJbkNvbHVtbih0aGlzLl9hY3RpdmUuY29sdW1uKTtcblxuICAgICAgICAvLyBnZXQgdGhlIG5vZGUgYmVsb3cgb3IgYWJvdmUgdGhlIGFjdGl2ZSBub2RlXG4gICAgICAgIGNvbnN0IHRhcmdldCA9IG5vZGVzW25vZGVzLmZpbmRJbmRleChub2RlID0+IG5vZGUubm9kZS5pZCA9PT0gdGhpcy5fYWN0aXZlLm5vZGUuaWQpICsgZGVsdGFdO1xuXG4gICAgICAgIGlmICh0YXJnZXQpIHtcbiAgICAgICAgICAgIHRoaXMuc2V0Rm9jdXNlZEl0ZW0odGFyZ2V0KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKiBTaGlmdCB0aGUgZm9jdXMgdG8gYSBub2RlIGluIGEgc2libGluZyBjb2x1bW4gKi9cbiAgICBwcml2YXRlIHNoaWZ0Rm9jdXNIb3Jpem9udGFsbHkoZGVsdGE6IG51bWJlcik6IHZvaWQge1xuXG4gICAgICAgIC8vIGdldCBub2RlcyBpbiB0aGUgc2libGluZyBjb2x1bW4gaW4gdGhlIGRlc2lyZWQgZGlyZWN0aW9uXG4gICAgICAgIGNvbnN0IG5vZGVzID0gdGhpcy5nZXROb2Rlc0luQ29sdW1uKHRoaXMuX2FjdGl2ZS5jb2x1bW4gKyBkZWx0YSk7XG5cbiAgICAgICAgLy8gaWYgdGhlcmUgYXJlIG5vIG5vZGVzIHRoZW4gZG8gbm90aGluZyBhcyB3ZSBjYW5ub3QgcmVkdWNlIGFuIGVtcHR5IGFycmF5XG4gICAgICAgIGlmIChub2Rlcy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIGdldCB0aGUgbm9kZSB3aXRoIHRoZSBtb3N0IHNpbWlsYXIgeSBwb3NpdGlvblxuICAgICAgICBjb25zdCB0YXJnZXQgPSBub2Rlcy5yZWR1Y2UoKGNsb3Nlc3QsIG5vZGUpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGNsb3Nlc3REaWZmID0gTWF0aC5tYXgoY2xvc2VzdC55LCB0aGlzLl9hY3RpdmUueSkgLSBNYXRoLm1pbihjbG9zZXN0LnksIHRoaXMuX2FjdGl2ZS55KTtcbiAgICAgICAgICAgIGNvbnN0IGN1cnJlbnREaWZmID0gTWF0aC5tYXgobm9kZS55LCB0aGlzLl9hY3RpdmUueSkgLSBNYXRoLm1pbihub2RlLnksIHRoaXMuX2FjdGl2ZS55KTtcbiAgICAgICAgICAgIHJldHVybiBjbG9zZXN0RGlmZiA8IGN1cnJlbnREaWZmID8gY2xvc2VzdCA6IG5vZGU7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGlmICh0YXJnZXQpIHtcbiAgICAgICAgICAgIHRoaXMuc2V0Rm9jdXNlZEl0ZW0odGFyZ2V0KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKiBHZXQgYSBsaXN0IG9mIG5vZGVzIHRoYXQgYXJlIGluIGEgZ2l2ZW4gY29sdW1uICovXG4gICAgcHJpdmF0ZSBnZXROb2Rlc0luQ29sdW1uKGNvbHVtbjogbnVtYmVyKTogUmVhZG9ubHlBcnJheTxTYW5rZXlOb2RlTGluazxUPj4ge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXROb2Rlc0luT3JkZXIodGhpcy5fbm9kZXMuZmlsdGVyKG5vZGUgPT4gbm9kZS5jb2x1bW4gPT09IGNvbHVtbikpO1xuICAgIH1cblxuICAgIC8qKiBTb3J0IHRoZSBub2RlcyBiYXNlZCBvbiB0aGUgWSBwb3NpdGlvbiAqL1xuICAgIHByaXZhdGUgZ2V0Tm9kZXNJbk9yZGVyKG5vZGVzOiBSZWFkb25seUFycmF5PFNhbmtleU5vZGVMaW5rPFQ+Pik6IFJlYWRvbmx5QXJyYXk8U2Fua2V5Tm9kZUxpbms8VD4+IHtcbiAgICAgICAgcmV0dXJuIFsuLi5ub2Rlc10uc29ydCgobm9kZU9uZSwgbm9kZVR3bykgPT4gbm9kZU9uZS55IC0gbm9kZVR3by55KTtcbiAgICB9XG5cbiAgICAvKiogRGV0ZXJtaW5lIHdoZXRoZXIgb3Igbm90IHRoZXJlIGlzIGEgbm90IHRoYXQgaXMgdGFiYmFibGUgKi9cbiAgICBwcml2YXRlIGhhc0FjdGl2ZU5vZGUoKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiAhIXRoaXMuYWN0aXZlJC52YWx1ZSAmJiAhIXRoaXMuX25vZGVzLmZpbmQobm9kZSA9PiBub2RlLm5vZGUuaWQgPT09IHRoaXMuYWN0aXZlJC52YWx1ZS5ub2RlLmlkKTtcbiAgICB9XG5cbn1cbiJdfQ==