Skip to content

Commit 72f36be

Browse files
authored
Merge branch 'master' into nmitich/fix-missing-dropposition-export
2 parents 66c0d70 + 20adbab commit 72f36be

File tree

3 files changed

+66
-15
lines changed

3 files changed

+66
-15
lines changed

projects/igniteui-angular/src/lib/directives/radio/radio-group.directive.spec.ts

+1-4
Original file line numberDiff line numberDiff line change
@@ -230,16 +230,14 @@ describe('IgxRadioGroupDirective', () => {
230230

231231
const domRadio = fixture.debugElement.query(By.css('igx-radio')).nativeElement;
232232
expect(domRadio.classList.contains('igx-radio--invalid')).toBe(false);
233-
expect(radioGroup.invalid).toBe(false);
234233
expect(radioGroup.selected).toBeUndefined;
235234

236235
dispatchRadioEvent('keyup', domRadio, fixture);
237236
expect(domRadio.classList.contains('igx-radio--focused')).toBe(true);
238237
dispatchRadioEvent('blur', domRadio, fixture);
239238
fixture.detectChanges();
240239
tick();
241-
242-
//expect(radioGroup.invalid).toBe(true);
240+
243241
expect(domRadio.classList.contains('igx-radio--invalid')).toBe(true);
244242

245243
dispatchRadioEvent('keyup', domRadio, fixture);
@@ -251,7 +249,6 @@ describe('IgxRadioGroupDirective', () => {
251249

252250
expect(domRadio.classList.contains('igx-radio--checked')).toBe(true);
253251
expect(radioGroup.radioButtons.first.checked).toEqual(true);
254-
expect(radioGroup.invalid).toBe(false);
255252
expect(domRadio.classList.contains('igx-radio--invalid')).toBe(false);
256253
}));
257254
});

projects/igniteui-angular/src/lib/directives/radio/radio-group.directive.ts

+55-4
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
import {
22
AfterContentInit,
33
AfterViewInit,
4-
ContentChildren, Directive, EventEmitter, HostBinding, Input, NgModule, OnDestroy, Optional, Output, QueryList, Self
4+
ContentChildren, Directive, EventEmitter, HostBinding, HostListener, Input, NgModule, OnDestroy, Optional, Output, QueryList, Self
55
} from '@angular/core';
66
import { ControlValueAccessor, NgControl, Validators } from '@angular/forms';
77
import { fromEvent, noop, Subject } from 'rxjs';
88
import { startWith, takeUntil } from 'rxjs/operators';
99
import { mkenum } from '../../core/utils';
1010
import { IChangeRadioEventArgs, IgxRadioComponent } from '../../radio/radio.component';
11+
import { IgxDirectionality } from '../../services/direction/directionality';
1112
import { IgxRippleModule } from '../ripple/ripple.directive';
1213

1314
/**
@@ -194,6 +195,51 @@ export class IgxRadioGroupDirective implements AfterContentInit, AfterViewInit,
194195
@HostBinding('class.igx-radio-group--vertical')
195196
private vertical = false;
196197

198+
@HostListener('click', ['$event'])
199+
protected handleClick(event: MouseEvent) {
200+
event.stopPropagation();
201+
this.selected.nativeElement.focus();
202+
}
203+
204+
@HostListener('keydown', ['$event'])
205+
protected handleKeyDown(event: KeyboardEvent) {
206+
const { key } = event;
207+
208+
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+
let index = checked ? buttons.indexOf(checked!) : -1;
212+
const ltr = this._directionality.value === 'ltr';
213+
214+
switch (key) {
215+
case 'ArrowUp':
216+
index += -1;
217+
break;
218+
case 'ArrowLeft':
219+
index += ltr ? -1 : 1;
220+
break;
221+
case 'ArrowRight':
222+
index += ltr ? 1 : -1;
223+
break;
224+
default:
225+
index += 1;
226+
}
227+
228+
if (index < 0) index = buttons.length - 1;
229+
if (index > buttons.length - 1) index = 0;
230+
231+
buttons.forEach((radio) => {
232+
radio.deselect();
233+
radio.nativeElement.blur();
234+
});
235+
236+
buttons[index].focused = true;
237+
buttons[index].nativeElement.focus();
238+
buttons[index].select();
239+
event.preventDefault();
240+
}
241+
}
242+
197243
/**
198244
* Returns the alignment of the `igx-radio-group`.
199245
* ```typescript
@@ -284,8 +330,8 @@ export class IgxRadioGroupDirective implements AfterContentInit, AfterViewInit,
284330
});
285331
}
286332

287-
/**
288-
* @hidden
333+
/**
334+
* @hidden
289335
* @internal
290336
*/
291337
public ngAfterViewInit() {
@@ -315,6 +361,10 @@ export class IgxRadioGroupDirective implements AfterContentInit, AfterViewInit,
315361
* @internal
316362
*/
317363
private updateValidityOnBlur() {
364+
this.radioButtons.forEach((button) => {
365+
button.focused = false;
366+
});
367+
318368
if (this.required) {
319369
const checked = this.radioButtons.find(x => x.checked);
320370
this.invalid = !checked;
@@ -372,7 +422,8 @@ export class IgxRadioGroupDirective implements AfterContentInit, AfterViewInit,
372422

373423
constructor(
374424
@Optional() @Self() public ngControl: NgControl,
375-
) {
425+
private _directionality: IgxDirectionality,
426+
) {
376427
if (this.ngControl !== null) {
377428
this.ngControl.valueAccessor = this;
378429
}

projects/igniteui-angular/src/lib/radio/radio.component.ts

+10-7
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import {
22
AfterViewInit,
3-
ChangeDetectorRef,
3+
ChangeDetectorRef,
44
Component,
55
ElementRef,
66
EventEmitter,
@@ -315,7 +315,7 @@ export class IgxRadioComponent implements AfterViewInit, ControlValueAccessor, E
315315
public set disabled(value: boolean) {
316316
this._disabled = (value as any === '') || value;
317317
}
318-
318+
319319
/**
320320
* Sets/gets whether the radio button is invalid.
321321
* Default value is `false`.
@@ -385,7 +385,7 @@ export class IgxRadioComponent implements AfterViewInit, ControlValueAccessor, E
385385
private cdr: ChangeDetectorRef,
386386
protected renderer: Renderer2,
387387
@Optional() @Self() public ngControl: NgControl,
388-
) {
388+
) {
389389
if (this.ngControl !== null) {
390390
this.ngControl.valueAccessor = this;
391391
}
@@ -400,8 +400,8 @@ export class IgxRadioComponent implements AfterViewInit, ControlValueAccessor, E
400400
this.destroy$.complete();
401401
}
402402

403-
/**
404-
* @hidden
403+
/**
404+
* @hidden
405405
* @internal
406406
*/
407407
public ngAfterViewInit() {
@@ -428,7 +428,7 @@ export class IgxRadioComponent implements AfterViewInit, ControlValueAccessor, E
428428
* @internal
429429
*/
430430
@HostListener('change', ['$event'])
431-
public _changed(){
431+
public _changed(event: Event){
432432
if(event instanceof Event){
433433
event.preventDefault();
434434
}
@@ -441,7 +441,10 @@ export class IgxRadioComponent implements AfterViewInit, ControlValueAccessor, E
441441
@HostListener('keyup', ['$event'])
442442
public onKeyUp(event: KeyboardEvent) {
443443
event.stopPropagation();
444-
this.focused = true;
444+
445+
if (!this.focused) {
446+
this.focused = true;
447+
}
445448
}
446449

447450
/**

0 commit comments

Comments
 (0)