import { Injectable , QueryList } from '@angular/core' ; import { BehaviorSubject } from 'rxjs' ; import { AnchorPlacement } from '../../common/overlay/index' ; import { FloatingActionButtonComponent } from './floating-action-button.component' ; export type FloatingActionButtonDirection = AnchorPlacement ; @ Injectable ( ) export class FloatingActionButtonsService { open$ = new BehaviorSubject < boolean > ( false ) ; direction$ = new BehaviorSubject < FloatingActionButtonDirection > ( 'top' ) ; private _buttons : QueryList < FloatingActionButtonComponent > ; open ( ) { this . open$ . next ( true ) ; } toggle ( ) { this . open$ . next ( ! this . open$ . getValue ( ) ) ; } close ( ) { this . open$ . next ( false ) ; 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 ; 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 ( ! button ) { return ; } this . _buttons . forEach ( btn => btn . tabindex$ . next ( button === btn ? 0 : - 1 ) ) ; button . focus ( ) ; } focusSibling ( next ) { if ( this . open$ . value === false ) { return ; } 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 ) ; } const sibling = this . _buttons . toArray ( ) [ this . getButtonIndex ( button ) + ( next ? 1 : - 1 ) ] ; this . focus ( sibling ) ; } private getFocusedButton ( ) { return this . _buttons . find ( btn => btn . tabindex$ . value === 0 ) ; } private getButtonIndex ( button ) { return this . _buttons . toArray ( ) . findIndex ( btn => btn === button ) ; } }