Skip to content

Commit 3f70096

Browse files
authored
Merge branch 'master' into issue#450
2 parents ef75017 + 61ac981 commit 3f70096

File tree

7 files changed

+137
-287
lines changed

7 files changed

+137
-287
lines changed

src/file-uploader/file-uploader.component.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,9 @@ export class FileUploader implements OnInit {
144144

145145
onFilesAdded() {
146146
const files = this.fileInput.nativeElement.files;
147+
if (!this.multiple) {
148+
this.files.clear();
149+
}
147150
for (let file of files) {
148151
const fileItem: FileItem = {
149152
uploaded: false,

src/file-uploader/file-uploader.stories.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ class FileUploaderStory {
3535
static notificationCount = 0;
3636

3737
@Input() notificationId = `notification-${FileUploaderStory.notificationCount}`;
38-
@Input() files: any;
38+
@Input() files = new Set();
3939
@Input() title;
4040
@Input() description;
4141
@Input() buttonText;

src/radio/radio-group.component.ts

Lines changed: 58 additions & 116 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@ import {
1111
Output,
1212
QueryList,
1313
Renderer2,
14-
HostBinding
14+
HostBinding,
15+
AfterViewInit
1516
} from "@angular/core";
1617
import { NG_VALUE_ACCESSOR, ControlValueAccessor } from "@angular/forms";
1718
import { Radio } from "./radio.component";
@@ -24,16 +25,17 @@ import { Radio } from "./radio.component";
2425
export class RadioChange {
2526
/**
2627
* Contains the `Radio` that has been changed.
27-
* @type {(Radio | null)}
28-
* @memberof RadioChange
2928
*/
3029
source: Radio | null;
3130
/**
3231
* The value of the `Radio` encompassed in the `RadioChange` class.
33-
* @type {any}
34-
* @memberof RadioChange
3532
*/
36-
value: any;
33+
value: string;
34+
35+
constructor(source: Radio, value: string) {
36+
this.source = source;
37+
this.value = value;
38+
}
3739
}
3840

3941
/**
@@ -77,15 +79,14 @@ export class RadioChange {
7779
}
7880
]
7981
})
80-
export class RadioGroup implements OnInit, AfterContentInit, ControlValueAccessor {
82+
export class RadioGroup implements AfterContentInit, AfterViewInit, ControlValueAccessor {
8183
/**
8284
* Used for creating the `RadioGroup` 'name' property dynamically.
8385
*/
8486
static radioGroupCount = 0;
8587

8688
/**
8789
* Emits event notifying other classes of a change using a `RadioChange` class.
88-
* @type {EventEmitter<RadioChange>}
8990
*/
9091
@Output() change: EventEmitter<RadioChange> = new EventEmitter<RadioChange>();
9192

@@ -95,38 +96,27 @@ export class RadioGroup implements OnInit, AfterContentInit, ControlValueAccesso
9596
// tslint:disable-next-line:no-forward-ref
9697
@ContentChildren(forwardRef(() => Radio)) radios: QueryList<Radio>;
9798

98-
/**
99-
* Determines the render size of the `Radio` inputs within the group.
100-
*/
101-
@Input() size: "sm" | "md" = "md";
102-
103-
/**
104-
* Returns the `Radio` that is selected within the `RadioGroup`.
105-
* @readonly
106-
*/
107-
@Input()
108-
get selected() {
109-
return this._selected;
110-
}
11199
/**
112100
* Sets the passed in `Radio` item as the selected input within the `RadioGroup`.
113101
*/
102+
@Input()
114103
set selected(selected: Radio | null) {
115104
this._selected = selected;
116105
this.value = selected ? selected.value : null;
117106
this.checkSelectedRadio();
118107
}
119108

120109
/**
121-
* Returns the value/state of the selected `Radio` within the `RadioGroup`.
110+
* Returns the `Radio` that is selected within the `RadioGroup`.
122111
*/
123-
@Input()
124-
get value() {
125-
return this._value;
112+
get selected() {
113+
return this._selected;
126114
}
115+
127116
/**
128117
* Sets the value/state of the selected `Radio` within the `RadioGroup` to the passed in value.
129118
*/
119+
@Input()
130120
set value(newValue: any) {
131121
if (this._value !== newValue) {
132122
this._value = newValue;
@@ -137,35 +127,31 @@ export class RadioGroup implements OnInit, AfterContentInit, ControlValueAccesso
137127
}
138128

139129
/**
140-
* Returns the associated name of the `RadioGroup`.
130+
* Returns the value/state of the selected `Radio` within the `RadioGroup`.
141131
*/
142-
@Input()
143-
get name() {
144-
return this._name;
132+
get value() {
133+
return this._value;
145134
}
135+
146136
/**
147137
* Replaces the name associated with the `RadioGroup` with the provided parameter.
148138
*/
139+
@Input()
149140
set name(name: string) {
150141
this._name = name;
151142
this.updateRadioNames();
152143
}
153-
154144
/**
155-
* Returns the disabled value in the `RadioGroup` if there is one.
145+
* Returns the associated name of the `RadioGroup`.
156146
*/
157-
@Input()
158-
get disabled() {
159-
return this._disabled;
147+
get name() {
148+
return this._name;
160149
}
150+
161151
/**
162-
* Updates the disabled value using the provided parameter and marks the radios to be checked for
163-
* changes.
152+
* Set to true to disable the whole radio group
164153
*/
165-
set disabled(value) {
166-
this._disabled = value;
167-
this.markRadiosForCheck();
168-
}
154+
@Input() disabled = false;
169155

170156
/**
171157
* Returns the skeleton value in the `RadioGroup` if there is one.
@@ -197,7 +183,7 @@ export class RadioGroup implements OnInit, AfterContentInit, ControlValueAccesso
197183
*/
198184
protected _disabled = false;
199185
/**
200-
* Reflects wheather or not the dropdown is loading.
186+
* Reflects whether or not the dropdown is loading.
201187
*/
202188
protected _skeleton = false;
203189
/**
@@ -211,21 +197,14 @@ export class RadioGroup implements OnInit, AfterContentInit, ControlValueAccesso
211197
/**
212198
* The name attribute associated with the `RadioGroup`.
213199
*/
214-
protected _name = `radio-group-${RadioGroup.radioGroupCount}`;
215-
216-
/**
217-
* Creates an instance of RadioGroup.
218-
*/
219-
constructor(protected changeDetectorRef: ChangeDetectorRef, protected elementRef: ElementRef, protected renderer: Renderer2) {
220-
RadioGroup.radioGroupCount++;
221-
}
200+
protected _name = `radio-group-${RadioGroup.radioGroupCount++}`;
222201

223202
/**
224203
* Updates the selected `Radio` to be checked (selected).
225204
*/
226205
checkSelectedRadio() {
227-
if (this._selected && !this._selected.checked) {
228-
this._selected.checked = true;
206+
if (this.selected && !this._selected.checked) {
207+
this.selected.checked = true;
229208
}
230209
}
231210

@@ -235,10 +214,9 @@ export class RadioGroup implements OnInit, AfterContentInit, ControlValueAccesso
235214
updateSelectedRadioFromValue() {
236215
let alreadySelected = this._selected != null && this._selected.value === this._value;
237216

238-
if (this.radios != null && !alreadySelected) {
217+
if (this.radios && !alreadySelected) {
239218
this._selected = null;
240219
this.radios.forEach(radio => {
241-
radio.checked = this.value === radio.value;
242220
if (radio.checked) {
243221
this._selected = radio;
244222
}
@@ -249,31 +227,20 @@ export class RadioGroup implements OnInit, AfterContentInit, ControlValueAccesso
249227
/**
250228
* Creates a class of `RadioChange` to emit the change in the `RadioGroup`.
251229
*/
252-
emitChangeEvent() {
253-
if (this.isInitialized) {
254-
let event = new RadioChange();
255-
event.source = this._selected;
256-
event.value = this._value;
257-
this.change.emit(event);
258-
}
259-
}
260-
261-
/**
262-
* Calls the `markForCheck()` function within the `changeDetectorRef` class
263-
* to trigger Angular's change detection on each radio item.
264-
*/
265-
markRadiosForCheck() {
266-
if (this.radios) {
267-
this.radios.forEach(radio => radio.markForCheck());
268-
}
230+
emitChangeEvent(event: RadioChange) {
231+
this.change.emit(event);
232+
this.propagateChange(event.value);
233+
this.onTouched();
269234
}
270235

271236
/**
272237
* Synchronizes the names of the radio items with the name of the `RadioGroup`.
273238
*/
274239
updateRadioNames() {
275240
if (this.radios) {
276-
this.radios.forEach(radio => radio.name = this.name);
241+
setTimeout(() => {
242+
this.radios.forEach(radio => radio.name = this.name);
243+
});
277244
}
278245
}
279246

@@ -282,64 +249,27 @@ export class RadioGroup implements OnInit, AfterContentInit, ControlValueAccesso
282249
*/
283250
writeValue(value: any) {
284251
this.value = value;
285-
this.changeDetectorRef.markForCheck();
286252
}
287253

288-
/**
289-
* Callback triggered when a `Radio` within the `RadioGroup` is changed.
290-
*/
291-
touch() {
292-
if (this.onTouched) {
293-
this.onTouched();
294-
}
295-
}
296-
297-
/**
298-
* Builds variant class on the radio items within the `RadioGroup`.
299-
*/
300-
ngOnInit() {
301-
// Build variant class
302-
const className = `radio${this.size !== "md" ? `--${this.size}` : ""}`;
303-
304-
// Add class to host element
305-
this.renderer.addClass(this.elementRef.nativeElement, className);
306-
}
307-
308-
/**
309-
* Marks this component as initialized to avoid the initial value getting set by `NgModel` on `RadioGroup`.
310-
* This avoids `NgModel` setting the initial value before the OnInit of the `RadioGroup`.
311-
*/
312254
ngAfterContentInit() {
313-
// Mark this component as initialized in AfterContentInit because the initial value can
314-
// possibly be set by NgModel on RadioGroup, and it is possible that the OnInit of the
315-
// NgModel occurs *after* the OnInit of the RadioGroup.
316-
this.isInitialized = true;
317-
this.updateFocusableRadio();
318-
319-
this.radios.changes.subscribe(updatedRadios => {
320-
this.radios = updatedRadios;
321-
this.updateFocusableRadio();
255+
this.radios.changes.subscribe(() => {
256+
this.updateRadioNames();
257+
this.updateRadioChangeHandler();
322258
});
323259

324260
this.updateChildren();
261+
this.updateRadioChangeHandler();
325262
}
326263

327-
updateFocusableRadio() {
328-
if (this.radios && !this.radios.some(radio => radio.checked)) {
329-
this.radios.forEach(radio => radio.needsToBeFocusable = false);
330-
this.radios.first.needsToBeFocusable = true;
331-
this.radios.forEach(radio => radio.changeDetectorRef.detectChanges());
332-
}
264+
ngAfterViewInit() {
265+
this.updateRadioNames();
333266
}
334267

335268
/**
336269
* Used to set method to propagate changes back to the form.
337270
*/
338271
public registerOnChange(fn: any) {
339-
this.propagateChange = value => {
340-
this.value = value;
341-
fn(value);
342-
};
272+
this.propagateChange = fn;
343273
}
344274

345275
/**
@@ -362,7 +292,19 @@ export class RadioGroup implements OnInit, AfterContentInit, ControlValueAccesso
362292

363293
protected updateChildren() {
364294
if (this.radios) {
365-
this.radios.toArray().forEach(child => child.skeleton = this.skeleton);
295+
this.radios.forEach(child => child.skeleton = this.skeleton);
366296
}
367297
}
298+
299+
protected updateRadioChangeHandler() {
300+
this.radios.forEach(radio => {
301+
radio.registerRadioChangeHandler((event: RadioChange) => {
302+
// update selected and value from the event
303+
this._selected = event.source;
304+
this._value = event.value;
305+
// bubble the event
306+
this.emitChangeEvent(event);
307+
});
308+
});
309+
}
368310
}

0 commit comments

Comments
 (0)