@ux-aspects/ux-aspects
Version:
Open source user interface framework for building modern, responsive, mobile big data applications
78 lines • 10.8 kB
JavaScript
import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs';
import * as i0 from "@angular/core";
export class FloatingActionButtonsService {
constructor() {
this.open$ = new BehaviorSubject(false);
this.direction$ = new BehaviorSubject('top');
}
open() {
this.open$.next(true);
}
toggle() {
this.open$.next(!this.open$.getValue());
}
close() {
this.open$.next(false);
// make the first button tabbable again
this.setPrimaryButtonFocusable();
}
isHorizontal() {
return this.direction$.value === 'left' || this.direction$.value === 'right';
}
isVertical() {
return this.direction$.value === 'top' || this.direction$.value === 'bottom';
}
setButtons(buttons) {
this._buttons = buttons;
// make the first button tabbable (after a delay to prevent expression changed error)
requestAnimationFrame(() => this.setPrimaryButtonFocusable());
}
/** Make only the first button tabbable */
setPrimaryButtonFocusable() {
this._buttons.forEach(btn => btn.tabindex$.next(btn.primary ? 0 : -1));
}
focusPrimaryButton() {
this.focus(this._buttons.find(btn => btn.primary));
}
focus(button) {
// if the button is not defined then do nothing
if (!button) {
return;
}
// set the button tab index
this._buttons.forEach(btn => btn.tabindex$.next(button === btn ? 0 : -1));
// apply the focus
button.focus();
}
focusSibling(next) {
// if the buttons are not visible then do nothing
if (this.open$.value === false) {
return;
}
// get the current focused item
const button = this.getFocusedButton();
if (next && button === this._buttons.last) {
return this.focus(this._buttons.first);
}
else if (!next && button === this._buttons.first) {
return this.focus(this._buttons.last);
}
// find the sibling button
const sibling = this._buttons.toArray()[this.getButtonIndex(button) + (next ? 1 : -1)];
// focus the next button
this.focus(sibling);
}
getFocusedButton() {
return this._buttons.find(btn => btn.tabindex$.value === 0);
}
getButtonIndex(button) {
return this._buttons.toArray().findIndex(btn => btn === button);
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.12", ngImport: i0, type: FloatingActionButtonsService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.12", ngImport: i0, type: FloatingActionButtonsService }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.12", ngImport: i0, type: FloatingActionButtonsService, decorators: [{
type: Injectable
}] });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmxvYXRpbmctYWN0aW9uLWJ1dHRvbnMuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3NyYy9jb21wb25lbnRzL2Zsb2F0aW5nLWFjdGlvbi1idXR0b25zL2Zsb2F0aW5nLWFjdGlvbi1idXR0b25zLnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFVBQVUsRUFBYSxNQUFNLGVBQWUsQ0FBQztBQUN0RCxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sTUFBTSxDQUFDOztBQU92QyxNQUFNLE9BQU8sNEJBQTRCO0lBRHpDO1FBR0ksVUFBSyxHQUFHLElBQUksZUFBZSxDQUFVLEtBQUssQ0FBQyxDQUFDO1FBQzVDLGVBQVUsR0FBRyxJQUFJLGVBQWUsQ0FBZ0MsS0FBSyxDQUFDLENBQUM7S0F1RjFFO0lBbkZHLElBQUk7UUFDQSxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUMxQixDQUFDO0lBRUQsTUFBTTtRQUNGLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxRQUFRLEVBQUUsQ0FBQyxDQUFDO0lBQzVDLENBQUM7SUFFRCxLQUFLO1FBQ0QsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7UUFFdkIsdUNBQXVDO1FBQ3ZDLElBQUksQ0FBQyx5QkFBeUIsRUFBRSxDQUFDO0lBQ3JDLENBQUM7SUFFRCxZQUFZO1FBQ1IsT0FBTyxJQUFJLENBQUMsVUFBVSxDQUFDLEtBQUssS0FBSyxNQUFNLElBQUksSUFBSSxDQUFDLFVBQVUsQ0FBQyxLQUFLLEtBQUssT0FBTyxDQUFDO0lBQ2pGLENBQUM7SUFFRCxVQUFVO1FBQ04sT0FBTyxJQUFJLENBQUMsVUFBVSxDQUFDLEtBQUssS0FBSyxLQUFLLElBQUksSUFBSSxDQUFDLFVBQVUsQ0FBQyxLQUFLLEtBQUss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LDRCQUE0QjtrQkFEeEMsVUFBVSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEluamVjdGFibGUsIFF1ZXJ5TGlzdCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQmVoYXZpb3JTdWJqZWN0IH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBBbmNob3JQbGFjZW1lbnQgfSBmcm9tICcuLi8uLi9jb21tb24vb3ZlcmxheS9pbmRleCc7XG5pbXBvcnQgeyBGbG9hdGluZ0FjdGlvbkJ1dHRvbkNvbXBvbmVudCB9IGZyb20gJy4vZmxvYXRpbmctYWN0aW9uLWJ1dHRvbi5jb21wb25lbnQnO1xuXG5leHBvcnQgdHlwZSBGbG9hdGluZ0FjdGlvbkJ1dHRvbkRpcmVjdGlvbiA9IEFuY2hvclBsYWNlbWVudDtcblxuQEluamVjdGFibGUoKVxuZXhwb3J0IGNsYXNzIEZsb2F0aW5nQWN0aW9uQnV0dG9uc1NlcnZpY2Uge1xuXG4gICAgb3BlbiQgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PGJvb2xlYW4+KGZhbHNlKTtcbiAgICBkaXJlY3Rpb24kID0gbmV3IEJlaGF2aW9yU3ViamVjdDxGbG9hdGluZ0FjdGlvbkJ1dHRvbkRpcmVjdGlvbj4oJ3RvcCcpO1xuXG4gICAgcHJpdmF0ZSBfYnV0dG9uczogUXVlcnlMaXN0PEZsb2F0aW5nQWN0aW9uQnV0dG9uQ29tcG9uZW50PjtcblxuICAgIG9wZW4oKTogdm9pZCB7XG4gICAgICAgIHRoaXMub3BlbiQubmV4dCh0cnVlKTtcbiAgICB9XG5cbiAgICB0b2dnbGUoKTogdm9pZCB7XG4gICAgICAgIHRoaXMub3BlbiQubmV4dCghdGhpcy5vcGVuJC5nZXRWYWx1ZSgpKTtcbiAgICB9XG5cbiAgICBjbG9zZSgpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5vcGVuJC5uZXh0KGZhbHNlKTtcblxuICAgICAgICAvLyBtYWtlIHRoZSBmaXJzdCBidXR0b24gdGFiYmFibGUgYWdhaW5cbiAgICAgICAgdGhpcy5zZXRQcmltYXJ5QnV0dG9uRm9jdXNhYmxlKCk7XG4gICAgfVxuXG4gICAgaXNIb3Jpem9udGFsKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGhpcy5kaXJlY3Rpb24kLnZhbHVlID09PSAnbGVmdCcgfHwgdGhpcy5kaXJlY3Rpb24kLnZhbHVlID09PSAncmlnaHQnO1xuICAgIH1cblxuICAgIGlzVmVydGljYWwoKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiB0aGlzLmRpcmVjdGlvbiQudmFsdWUgPT09ICd0b3AnIHx8IHRoaXMuZGlyZWN0aW9uJC52YWx1ZSA9PT0gJ2JvdHRvbSc7XG4gICAgfVxuXG4gICAgc2V0QnV0dG9ucyhidXR0b25zOiBRdWVyeUxpc3Q8RmxvYXRpbmdBY3Rpb25CdXR0b25Db21wb25lbnQ+KTogdm9pZCB7XG4gICAgICAgIHRoaXMuX2J1dHRvbnMgPSBidXR0b25zO1xuXG4gICAgICAgIC8vIG1ha2UgdGhlIGZpcnN0IGJ1dHRvbiB0YWJiYWJsZSAoYWZ0ZXIgYSBkZWxheSB0byBwcmV2ZW50IGV4cHJlc3Npb24gY2hhbmdlZCBlcnJvcilcbiAgICAgICAgcmVxdWVzdEFuaW1hdGlvbkZyYW1lKCgpID0+IHRoaXMuc2V0UHJpbWFyeUJ1dHRvbkZvY3VzYWJsZSgpKTtcbiAgICB9XG5cbiAgICAvKiogTWFrZSBvbmx5IHRoZSBmaXJzdCBidXR0b24gdGFiYmFibGUgKi9cbiAgICBzZXRQcmltYXJ5QnV0dG9uRm9jdXNhYmxlKCk6IHZvaWQge1xuICAgICAgICB0aGlzLl9idXR0b25zLmZvckVhY2goYnRuID0+IGJ0bi50YWJpbmRleCQubmV4dChidG4ucHJpbWFyeSA/IDAgOiAtMSkpO1xuICAgIH1cblxuICAgIGZvY3VzUHJpbWFyeUJ1dHRvbigpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5mb2N1cyh0aGlzLl9idXR0b25zLmZpbmQoYnRuID0+IGJ0bi5wcmltYXJ5KSk7XG4gICAgfVxuXG4gICAgZm9jdXMoYnV0dG9uOiBGbG9hdGluZ0FjdGlvbkJ1dHRvbkNvbXBvbmVudCk6IHZvaWQge1xuXG4gICAgICAgIC8vIGlmIHRoZSBidXR0b24gaXMgbm90IGRlZmluZWQgdGhlbiBkbyBub3RoaW5nXG4gICAgICAgIGlmICghYnV0dG9uKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICAvLyBzZXQgdGhlIGJ1dHRvbiB0YWIgaW5kZXhcbiAgICAgICAgdGhpcy5fYnV0dG9ucy5mb3JFYWNoKGJ0biA9PiBidG4udGFiaW5kZXgkLm5leHQoYnV0dG9uID09PSBidG4gPyAwIDogLTEpKTtcblxuICAgICAgICAvLyBhcHBseSB0aGUgZm9jdXNcbiAgICAgICAgYnV0dG9uLmZvY3VzKCk7XG4gICAgfVxuXG4gICAgZm9jdXNTaWJsaW5nKG5leHQ6IGJvb2xlYW4pOiB2b2lkIHtcblxuICAgICAgICAvLyBpZiB0aGUgYnV0dG9ucyBhcmUgbm90IHZpc2libGUgdGhlbiBkbyBub3RoaW5nXG4gICAgICAgIGlmICh0aGlzLm9wZW4kLnZhbHVlID09PSBmYWxzZSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gZ2V0IHRoZSBjdXJyZW50IGZvY3VzZWQgaXRlbVxuICAgICAgICBjb25zdCBidXR0b24gPSB0aGlzLmdldEZvY3VzZWRCdXR0b24oKTtcblxuICAgICAgICBpZiAobmV4dCAmJiBidXR0b24gPT09IHRoaXMuX2J1dHRvbnMubGFzdCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuZm9jdXModGhpcy5fYnV0dG9ucy5maXJzdCk7XG4gICAgICAgIH0gZWxzZSBpZiAoIW5leHQgJiYgYnV0dG9uID09PSB0aGlzLl9idXR0b25zLmZpcnN0KSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5mb2N1cyh0aGlzLl9idXR0b25zLmxhc3QpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gZmluZCB0aGUgc2libGluZyBidXR0b25cbiAgICAgICAgY29uc3Qgc2libGluZyA9IHRoaXMuX2J1dHRvbnMudG9BcnJheSgpW3RoaXMuZ2V0QnV0dG9uSW5kZXgoYnV0dG9uKSArIChuZXh0ID8gMSA6IC0xKV07XG5cbiAgICAgICAgLy8gZm9jdXMgdGhlIG5leHQgYnV0dG9uXG4gICAgICAgIHRoaXMuZm9jdXMoc2libGluZyk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBnZXRGb2N1c2VkQnV0dG9uKCk6IEZsb2F0aW5nQWN0aW9uQnV0dG9uQ29tcG9uZW50IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2J1dHRvbnMuZmluZChidG4gPT4gYnRuLnRhYmluZGV4JC52YWx1ZSA9PT0gMCk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBnZXRCdXR0b25JbmRleChidXR0b246IEZsb2F0aW5nQWN0aW9uQnV0dG9uQ29tcG9uZW50KTogbnVtYmVyIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2J1dHRvbnMudG9BcnJheSgpLmZpbmRJbmRleChidG4gPT4gYnRuID09PSBidXR0b24pO1xuICAgIH1cbn1cbiJdfQ==