@@ -8,10 +8,10 @@ import {
8
8
dispatchEvent ,
9
9
} from '../../testing/private' ;
10
10
import { DOCUMENT } from '@angular/common' ;
11
- import { Component , NgZone } from '@angular/core' ;
11
+ import { Component , NgZone , ViewChild } from '@angular/core' ;
12
12
import { ComponentFixture , fakeAsync , flush , inject , TestBed , tick } from '@angular/core/testing' ;
13
13
import { By } from '@angular/platform-browser' ;
14
- import { A11yModule } from '../index' ;
14
+ import { A11yModule , CdkMonitorFocus } from '../index' ;
15
15
import { TOUCH_BUFFER_MS } from '../input-modality/input-modality-detector' ;
16
16
import {
17
17
FocusMonitor ,
@@ -515,6 +515,7 @@ describe('cdkMonitorFocus', () => {
515
515
ComplexComponentWithMonitorSubtreeFocus ,
516
516
ComplexComponentWithMonitorSubtreeFocusAndMonitorElementFocus ,
517
517
FocusMonitorOnCommentNode ,
518
+ ExportedFocusMonitor ,
518
519
] ,
519
520
} ) . compileComponents ( ) ;
520
521
} ) ;
@@ -737,6 +738,77 @@ describe('cdkMonitorFocus', () => {
737
738
} ) ) ;
738
739
} ) ;
739
740
741
+ describe ( 'button with exported cdkMonitorElementFocus' , ( ) => {
742
+ let fixture : ComponentFixture < ExportedFocusMonitor > ;
743
+ let buttonElement : HTMLElement ;
744
+
745
+ beforeEach ( ( ) => {
746
+ fixture = TestBed . createComponent ( ExportedFocusMonitor ) ;
747
+ fixture . detectChanges ( ) ;
748
+
749
+ buttonElement = fixture . debugElement . query ( By . css ( 'button' ) ) ! . nativeElement ;
750
+ patchElementFocus ( buttonElement ) ;
751
+ } ) ;
752
+
753
+ it ( 'should initially not be focused' , ( ) => {
754
+ expect ( fixture . componentInstance . exportedDirRef . focusOrigin )
755
+ . withContext ( 'initial focus origin should be null' )
756
+ . toBeNull ( ) ;
757
+ } ) ;
758
+
759
+ it ( 'should detect focus via keyboard' , fakeAsync ( ( ) => {
760
+ // Simulate focus via keyboard.
761
+ dispatchKeyboardEvent ( document , 'keydown' , TAB ) ;
762
+ buttonElement . focus ( ) ;
763
+ fixture . detectChanges ( ) ;
764
+ flush ( ) ;
765
+
766
+ expect ( fixture . componentInstance . exportedDirRef . focusOrigin ) . toEqual ( 'keyboard' ) ;
767
+ } ) ) ;
768
+
769
+ it ( 'should detect focus via mouse' , fakeAsync ( ( ) => {
770
+ // Simulate focus via mouse.
771
+ dispatchMouseEvent ( buttonElement , 'mousedown' ) ;
772
+ buttonElement . focus ( ) ;
773
+ fixture . detectChanges ( ) ;
774
+ flush ( ) ;
775
+
776
+ expect ( fixture . componentInstance . exportedDirRef . focusOrigin ) . toEqual ( 'mouse' ) ;
777
+ } ) ) ;
778
+
779
+ it ( 'should detect focus via touch' , fakeAsync ( ( ) => {
780
+ // Simulate focus via touch.
781
+ dispatchFakeEvent ( buttonElement , 'touchstart' ) ;
782
+ buttonElement . focus ( ) ;
783
+ fixture . detectChanges ( ) ;
784
+ tick ( TOUCH_BUFFER_MS ) ;
785
+
786
+ expect ( fixture . componentInstance . exportedDirRef . focusOrigin ) . toEqual ( 'touch' ) ;
787
+ } ) ) ;
788
+
789
+ it ( 'should detect programmatic focus' , fakeAsync ( ( ) => {
790
+ // Programmatically focus.
791
+ buttonElement . focus ( ) ;
792
+ fixture . detectChanges ( ) ;
793
+ tick ( ) ;
794
+
795
+ expect ( fixture . componentInstance . exportedDirRef . focusOrigin ) . toEqual ( 'program' ) ;
796
+ } ) ) ;
797
+
798
+ it ( 'should remove focus classes on blur' , fakeAsync ( ( ) => {
799
+ buttonElement . focus ( ) ;
800
+ fixture . detectChanges ( ) ;
801
+ tick ( ) ;
802
+
803
+ expect ( fixture . componentInstance . exportedDirRef . focusOrigin ) . toEqual ( 'program' ) ;
804
+
805
+ buttonElement . blur ( ) ;
806
+ fixture . detectChanges ( ) ;
807
+
808
+ expect ( fixture . componentInstance . exportedDirRef . focusOrigin ) . toEqual ( null ) ;
809
+ } ) ) ;
810
+ } ) ;
811
+
740
812
it ( 'should not throw when trying to monitor focus on a non-element node' , ( ) => {
741
813
expect ( ( ) => {
742
814
const fixture = TestBed . createComponent ( FocusMonitorOnCommentNode ) ;
@@ -862,3 +934,10 @@ class FocusMonitorOnCommentNode {}
862
934
` ,
863
935
} )
864
936
class CheckboxWithLabel { }
937
+
938
+ @Component ( {
939
+ template : `<button cdkMonitorElementFocus #exportedDir="cdkMonitorFocus"></button>` ,
940
+ } )
941
+ class ExportedFocusMonitor {
942
+ @ViewChild ( 'exportedDir' ) exportedDirRef : CdkMonitorFocus ;
943
+ }
0 commit comments