Skip to content

Commit 210291b

Browse files
committed
Merge branch 'master' of https://github.com/carbon-design-system/carbon-components-angular into master-to-next
2 parents 8e2889f + 8641edb commit 210291b

File tree

7 files changed

+85
-9
lines changed

7 files changed

+85
-9
lines changed

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

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,5 +120,26 @@ describe("FileUploader", () => {
120120

121121
expect(element.nativeElement.querySelector(".cds--file__state-container .cds--file--invalid")).toBeTruthy();
122122
});
123+
124+
it("should correctly update this.files when onFilesAdded is called", () => {
125+
fixture = TestBed.createComponent(FileUploader);
126+
wrapper = fixture.componentInstance;
127+
fixture.detectChanges();
128+
129+
const fileAlreadyAdded = new File([""], "test-filename-added", {type: "text/html"});
130+
const currentFiles = new Set().add(wrapper.createFileItem(fileAlreadyAdded));
131+
wrapper.files = currentFiles;
132+
fixture.detectChanges();
133+
expect(wrapper.value).toBe(currentFiles);
134+
135+
const dataTransfer = new DataTransfer();
136+
const fileToAdd = new File(["test file"], "test-filename", {type: "text/html"});
137+
dataTransfer.items.add(fileToAdd);
138+
wrapper.fileInput.nativeElement.files = dataTransfer.files;
139+
fixture.detectChanges();
140+
wrapper.onFilesAdded();
141+
const filesArray: FileItem[] = Array.from(wrapper.files);
142+
expect(!!filesArray.find((fileItem: FileItem) => fileItem.file.name === fileToAdd.name)).toBe(true);
143+
});
123144
});
124145

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

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import {
66
EventEmitter,
77
TemplateRef
88
} from "@angular/core";
9-
import { NG_VALUE_ACCESSOR } from "@angular/forms";
9+
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from "@angular/forms";
1010

1111
import { I18n } from "carbon-components-angular/i18n";
1212
import { FileItem } from "./file-item.interface";
@@ -89,7 +89,7 @@ const noop = () => { };
8989
}
9090
]
9191
})
92-
export class FileUploader {
92+
export class FileUploader implements ControlValueAccessor {
9393
/**
9494
* Counter used to create unique ids for file-uploader components
9595
*/
@@ -214,16 +214,17 @@ export class FileUploader {
214214
}
215215

216216
onFilesAdded() {
217+
const newFiles = new Set<FileItem>(this.files);
217218
if (!this.multiple) {
218-
this.files.clear();
219+
newFiles.clear();
219220
}
220221
for (let file of this.fileList) {
221222
const fileItem = this.createFileItem(file);
222-
this.files.add(fileItem);
223+
newFiles.add(fileItem);
223224
}
224225

225-
this.filesChange.emit(this.files);
226-
this.value = this.files;
226+
this.value = newFiles;
227+
this.filesChange.emit(newFiles);
227228
}
228229

229230
onDragOver(event) {
@@ -289,4 +290,15 @@ export class FileUploader {
289290
registerOnChange(fn: any) {
290291
this.onChangeCallback = fn;
291292
}
293+
294+
/**
295+
* `ControlValueAccessor` method to programmatically disable the checkbox.
296+
*
297+
* ex: `this.formGroup.get("myFileUploader").disable();`
298+
*
299+
* @param isDisabled `true` to disable the file uploader
300+
*/
301+
setDisabledState(isDisabled: boolean) {
302+
this.disabled = isDisabled;
303+
}
292304
}

src/file-uploader/stories/uploader-reactive-form.component.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,28 @@ import {
3737
Upload
3838
</button>
3939
</form>
40+
<form [formGroup]="disabledFormGroup" (ngSubmit)="onUpload()">
41+
<ibm-file-uploader
42+
[title]="title"
43+
[description]="description"
44+
[buttonText]="buttonText"
45+
[buttonType]="buttonType"
46+
[accept]="accept"
47+
[multiple]="multiple"
48+
[skeleton]="skeleton"
49+
[size]="size"
50+
formControlName="files">
51+
</ibm-file-uploader>
52+
<div [id]="notificationId" style="width: 300px; margin-top: 20px"></div>
53+
<button ibmButton *ngIf="disabledFormGroup.get('files').value && disabledFormGroup.get('files').value.size > 0" type="submit">
54+
Upload
55+
</button>
56+
</form>
4057
`
4158
})
4259
export class ReactiveFormsStory implements OnInit {
4360
public formGroup: FormGroup;
61+
public disabledFormGroup: FormGroup;
4462

4563
@Input() title;
4664
@Input() description;
@@ -61,6 +79,10 @@ export class ReactiveFormsStory implements OnInit {
6179
this.formGroup = this.formBuilder.group({
6280
files: new FormControl(new Set<any>(), [Validators.required])
6381
});
82+
this.disabledFormGroup = this.formBuilder.group({
83+
files: new FormControl(new Set<any>(), [Validators.required])
84+
});
85+
this.disabledFormGroup.disable();
6486
}
6587

6688
onUpload() {

src/input/label.component.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,12 +162,19 @@ export class Label implements AfterContentInit, AfterViewInit {
162162
// Prioritize setting id to `input` & `textarea` over div
163163
const inputElement = this.wrapper.nativeElement.querySelector("input,textarea");
164164
if (inputElement) {
165+
// avoid overriding ids already set by the user reuse it instead
166+
if (inputElement.id) {
167+
this.labelInputID = inputElement.id;
168+
}
165169
inputElement.setAttribute("id", this.labelInputID);
166170
return;
167171
}
168172

169173
const divElement = this.wrapper.nativeElement.querySelector("div");
170174
if (divElement) {
175+
if (divElement.id) {
176+
this.labelInputID = divElement.id;
177+
}
171178
divElement.setAttribute("id", this.labelInputID);
172179
}
173180
}

src/tiles/clickable-tile.component.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import { Router } from "@angular/router";
2424
<a
2525
ibmLink
2626
class="cds--tile cds--tile--clickable"
27+
[ngClass]="{'cds--tile--light': theme === 'light'}"
2728
tabindex="0"
2829
(click)="navigate($event)"
2930
[href]="href"
@@ -33,6 +34,8 @@ import { Router } from "@angular/router";
3334
</a>`
3435
})
3536
export class ClickableTile {
37+
@Input() theme: "light" | "dark" = "dark";
38+
3639
/**
3740
* Sets the `href` attribute on the `ibm-clickable-tile` element.
3841
*/

src/tiles/expandable-tile.component.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,10 @@ export interface ExpandableTileTranslations {
1717
template: `
1818
<button
1919
class="cds--tile cds--tile--expandable"
20-
[ngClass]="{'cds--tile--is-expanded' : expanded}"
20+
[ngClass]="{
21+
'cds--tile--is-expanded' : expanded,
22+
'cds--tile--light': theme === 'light'
23+
}"
2124
[ngStyle]="{'max-height': expandedHeight + 'px'}"
2225
type="button"
2326
(click)="onClick()">
@@ -39,6 +42,8 @@ export interface ExpandableTileTranslations {
3942
`
4043
})
4144
export class ExpandableTile implements AfterContentInit {
45+
@Input() theme: "light" | "dark" = "dark";
46+
4247
@Input() expanded = false;
4348
/**
4449
* Expects an object that contains some or all of:

src/tiles/selection-tile.component.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import {
77
HostListener,
88
AfterViewInit
99
} from "@angular/core";
10-
import { NG_VALUE_ACCESSOR } from "@angular/forms";
1110
import { I18n } from "carbon-components-angular/i18n";
1211

1312
@Component({
@@ -17,7 +16,10 @@ import { I18n } from "carbon-components-angular/i18n";
1716
class="cds--tile cds--tile--selectable"
1817
tabindex="0"
1918
[for]="id"
20-
[ngClass]="{'cds--tile--is-selected' : selected}"
19+
[ngClass]="{
20+
'cds--tile--is-selected' : selected,
21+
'cds--tile--light': theme === 'light'
22+
}"
2123
[attr.aria-label]="i18n.get('TILES.TILE') | async">
2224
<input
2325
#input
@@ -42,10 +44,14 @@ import { I18n } from "carbon-components-angular/i18n";
4244
})
4345
export class SelectionTile implements AfterViewInit {
4446
static tileCount = 0;
47+
48+
@Input() theme: "light" | "dark" = "dark";
49+
4550
/**
4651
* The unique id for the input.
4752
*/
4853
@Input() id = `tile-${SelectionTile.tileCount}`;
54+
4955
/**
5056
* Updating the state of the input to match the state of the parameter passed in.
5157
* Set to `true` if this tile should be selected.

0 commit comments

Comments
 (0)