UNPKG

4.71 kBJavaScriptView Raw
1import { ChangeDetectorRef, ContentChildren, Directive, forwardRef, HostBinding, HostListener, QueryList } from '@angular/core';
2import { NG_VALUE_ACCESSOR } from '@angular/forms';
3import { ButtonRadioDirective } from './button-radio.directive';
4export const RADIO_CONTROL_VALUE_ACCESSOR = {
5 provide: NG_VALUE_ACCESSOR,
6 useExisting: forwardRef(() => ButtonRadioGroupDirective),
7 multi: true
8};
9/**
10 * A group of radio buttons.
11 * A value of a selected button is bound to a variable specified via ngModel.
12 */
13export class ButtonRadioGroupDirective {
14 constructor(cdr) {
15 this.cdr = cdr;
16 this.onChange = Function.prototype;
17 this.onTouched = Function.prototype;
18 this.role = 'radiogroup';
19 this._disabled = false;
20 }
21 get value() {
22 return this._value;
23 }
24 set value(value) {
25 this._value = value;
26 this.onChange(value);
27 }
28 get disabled() {
29 return this._disabled;
30 }
31 get tabindex() {
32 if (this._disabled) {
33 return null;
34 }
35 else {
36 return 0;
37 }
38 }
39 writeValue(value) {
40 this._value = value;
41 this.cdr.markForCheck();
42 }
43 registerOnChange(fn) {
44 this.onChange = fn;
45 }
46 registerOnTouched(fn) {
47 this.onTouched = fn;
48 }
49 setDisabledState(disabled) {
50 if (this.radioButtons) {
51 this._disabled = disabled;
52 this.radioButtons.forEach(buttons => {
53 buttons.setDisabledState(disabled);
54 });
55 this.cdr.markForCheck();
56 }
57 }
58 onFocus() {
59 if (this._disabled) {
60 return;
61 }
62 const activeRadio = this.getActiveOrFocusedRadio();
63 if (activeRadio) {
64 activeRadio.focus();
65 return;
66 }
67 if (this.radioButtons) {
68 const firstEnabled = this.radioButtons.find(r => !r.disabled);
69 if (firstEnabled) {
70 firstEnabled.focus();
71 }
72 }
73 }
74 onBlur() {
75 if (this.onTouched) {
76 this.onTouched();
77 }
78 }
79 selectNext(event) {
80 this.selectInDirection('next');
81 event.preventDefault();
82 }
83 selectPrevious(event) {
84 this.selectInDirection('previous');
85 event.preventDefault();
86 }
87 selectInDirection(direction) {
88 if (this._disabled) {
89 return;
90 }
91 function nextIndex(currentIndex, buttonRadioDirectives) {
92 const step = direction === 'next' ? 1 : -1;
93 let calcIndex = (currentIndex + step) % buttonRadioDirectives.length;
94 if (calcIndex < 0) {
95 calcIndex = buttonRadioDirectives.length - 1;
96 }
97 return calcIndex;
98 }
99 const activeRadio = this.getActiveOrFocusedRadio();
100 if (activeRadio && this.radioButtons) {
101 const buttonRadioDirectives = this.radioButtons.toArray();
102 const currentActiveIndex = buttonRadioDirectives.indexOf(activeRadio);
103 for (let i = nextIndex(currentActiveIndex, buttonRadioDirectives); i !== currentActiveIndex; i = nextIndex(i, buttonRadioDirectives)) {
104 if (buttonRadioDirectives[i].canToggle()) {
105 buttonRadioDirectives[i].toggleIfAllowed();
106 buttonRadioDirectives[i].focus();
107 break;
108 }
109 }
110 }
111 }
112 getActiveOrFocusedRadio() {
113 if (!this.radioButtons) {
114 return void 0;
115 }
116 return this.radioButtons.find(button => button.isActive)
117 || this.radioButtons.find(button => button.hasFocus);
118 }
119}
120ButtonRadioGroupDirective.decorators = [
121 { type: Directive, args: [{
122 selector: '[btnRadioGroup]',
123 providers: [RADIO_CONTROL_VALUE_ACCESSOR]
124 },] }
125];
126ButtonRadioGroupDirective.ctorParameters = () => [
127 { type: ChangeDetectorRef }
128];
129ButtonRadioGroupDirective.propDecorators = {
130 role: [{ type: HostBinding, args: ['attr.role',] }],
131 radioButtons: [{ type: ContentChildren, args: [forwardRef(() => ButtonRadioDirective),] }],
132 tabindex: [{ type: HostBinding, args: ['attr.tabindex',] }],
133 onFocus: [{ type: HostListener, args: ['focus',] }],
134 onBlur: [{ type: HostListener, args: ['blur',] }],
135 selectNext: [{ type: HostListener, args: ['keydown.ArrowRight', ['$event'],] }, { type: HostListener, args: ['keydown.ArrowDown', ['$event'],] }],
136 selectPrevious: [{ type: HostListener, args: ['keydown.ArrowLeft', ['$event'],] }, { type: HostListener, args: ['keydown.ArrowUp', ['$event'],] }]
137};
138//# sourceMappingURL=button-radio-group.directive.js.map
\No newline at end of file