1
1
import {
2
2
AfterContentInit ,
3
3
AfterViewInit ,
4
- ContentChildren , Directive , EventEmitter , HostBinding , HostListener , Input , NgModule , OnDestroy , Optional , Output , QueryList , Self
4
+ ContentChildren , Directive , DoCheck , EventEmitter , HostBinding , HostListener , Input , NgModule , OnDestroy , Optional , Output , QueryList , Self
5
5
} from '@angular/core' ;
6
6
import { ControlValueAccessor , NgControl , Validators } from '@angular/forms' ;
7
7
import { fromEvent , noop , Subject } from 'rxjs' ;
@@ -49,7 +49,7 @@ let nextId = 0;
49
49
exportAs : 'igxRadioGroup' ,
50
50
selector : 'igx-radio-group, [igxRadioGroup]'
51
51
} )
52
- export class IgxRadioGroupDirective implements AfterContentInit , AfterViewInit , ControlValueAccessor , OnDestroy {
52
+ export class IgxRadioGroupDirective implements AfterContentInit , AfterViewInit , ControlValueAccessor , OnDestroy , DoCheck {
53
53
private static ngAcceptInputType_required : boolean | '' ;
54
54
private static ngAcceptInputType_invalid : boolean | '' ;
55
55
/**
@@ -204,10 +204,10 @@ export class IgxRadioGroupDirective implements AfterContentInit, AfterViewInit,
204
204
@HostListener ( 'keydown' , [ '$event' ] )
205
205
protected handleKeyDown ( event : KeyboardEvent ) {
206
206
const { key } = event ;
207
+ const buttons = this . radioButtons . filter ( radio => ! radio . disabled ) ;
208
+ const checked = buttons . find ( ( radio ) => radio . checked ) ;
207
209
208
210
if ( [ 'ArrowUp' , 'ArrowDown' , 'ArrowLeft' , 'ArrowRight' ] . includes ( key ) ) {
209
- const buttons = this . radioButtons . filter ( radio => ! radio . disabled ) ;
210
- const checked = buttons . find ( ( radio ) => radio . checked ) ;
211
211
let index = checked ? buttons . indexOf ( checked ! ) : - 1 ;
212
212
const ltr = this . _directionality . value === 'ltr' ;
213
213
@@ -238,6 +238,14 @@ export class IgxRadioGroupDirective implements AfterContentInit, AfterViewInit,
238
238
buttons [ index ] . select ( ) ;
239
239
event . preventDefault ( ) ;
240
240
}
241
+
242
+ if ( event . key === "Tab" ) {
243
+ buttons . forEach ( ( radio ) => {
244
+ if ( radio !== checked ) {
245
+ event . stopPropagation ( ) ;
246
+ }
247
+ } ) ;
248
+ }
241
249
}
242
250
243
251
/**
@@ -352,6 +360,12 @@ export class IgxRadioGroupDirective implements AfterContentInit, AfterViewInit,
352
360
. subscribe ( ( ) => {
353
361
this . updateValidityOnBlur ( )
354
362
} ) ;
363
+
364
+ fromEvent ( button . nativeElement , 'keyup' )
365
+ . pipe ( takeUntil ( this . destroy$ ) )
366
+ . subscribe ( ( event : KeyboardEvent ) => {
367
+ this . updateOnKeyUp ( event )
368
+ } ) ;
355
369
} ) ;
356
370
}
357
371
}
@@ -371,6 +385,45 @@ export class IgxRadioGroupDirective implements AfterContentInit, AfterViewInit,
371
385
}
372
386
}
373
387
388
+ /**
389
+ * @hidden
390
+ * @internal
391
+ */
392
+ private updateOnKeyUp ( event : KeyboardEvent ) {
393
+ const checked = this . radioButtons . find ( x => x . checked ) ;
394
+
395
+ if ( event . key === "Tab" ) {
396
+ this . radioButtons . forEach ( ( radio ) => {
397
+ if ( radio === checked ) {
398
+ checked . focused = true ;
399
+ }
400
+ } ) ;
401
+ }
402
+ }
403
+
404
+ public ngDoCheck ( ) : void {
405
+ this . _updateTabIndex ( ) ;
406
+ }
407
+
408
+ private _updateTabIndex ( ) {
409
+ // Needed so that the keyboard navigation of a radio group
410
+ // placed inside a dialog works properly
411
+ if ( this . radioButtons ) {
412
+ const checked = this . radioButtons . find ( x => x . checked ) ;
413
+
414
+ if ( checked ) {
415
+ this . radioButtons . forEach ( ( button ) => {
416
+ checked . nativeElement . tabIndex = 0 ;
417
+
418
+ if ( button !== checked ) {
419
+ button . nativeElement . tabIndex = - 1 ;
420
+ button . focused = false ;
421
+ }
422
+ } ) ;
423
+ }
424
+ }
425
+ }
426
+
374
427
/**
375
428
* Sets the "checked" property value on the radio input element.
376
429
*
0 commit comments