Skip to content

Commit e592b0f

Browse files
committed
Merge branch 'tooltip-icon' of https://github.com/youda97/carbon-components-angular into tooltip-icon
2 parents 3ef5bf3 + 61bd5d0 commit e592b0f

16 files changed

+292
-350
lines changed

.storybook/config.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@ addDecorator(
2727
);
2828

2929
// load global styles
30-
require("!style-loader!css-loader!sass-loader!./preview.scss");
31-
require("!style-loader!css-loader!sass-loader!./preview-experimental.scss");
30+
require("!style-loader!css-loader!postcss-loader!sass-loader!./preview.scss");
31+
require("!style-loader!css-loader!postcss-loader!sass-loader!./preview-experimental.scss");
3232

3333
require("../src/index.stories");
3434
// automatically import all files ending in *.stories.ts

src/content-switcher/content-switcher-option.directive.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ import {
1111
selector: "[ibmContentOption]"
1212
})
1313
export class ContentSwitcherOption {
14+
/**
15+
* Used to activate the option. Only one option may be `active` at a time
16+
*/
1417
@Input() set active (value: boolean) {
1518
this._active = value;
1619
this.selectedClass = value;
@@ -22,8 +25,16 @@ export class ContentSwitcherOption {
2225
return this._active;
2326
}
2427

28+
/**
29+
* Internal name for the option.
30+
* Should be something that identifies the option to the application.
31+
* Accessible from the `ContentSwitcher` `selected` emitter
32+
*/
2533
@Input() name = "option";
2634

35+
/**
36+
* Emits when the option is selected.
37+
*/
2738
@Output() selected = new EventEmitter();
2839

2940
@HostBinding("class") switcherClass = "bx--content-switcher-btn";

src/content-switcher/content-switcher.component.ts

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,16 @@ import { ContentSwitcherOption } from "./content-switcher-option.directive";
1313
import { isFocusInLastItem, isFocusInFirstItem } from "./../common/tab.service";
1414

1515
/**
16+
* The content switcher can be used for toggling between distinct options.
17+
* Similar to tabs, but without an associated content panel
1618
*
17-
*
19+
* ```html
20+
* <ibm-content-switcher (selected)="selected($event)">
21+
* <button ibmContentOption>First section</button>
22+
* <button ibmContentOption>Second section</button>
23+
* <button ibmContentOption>Third section</button>
24+
* </ibm-content-switcher>
25+
* ```
1826
*/
1927
@Component({
2028
selector: "ibm-content-switcher",
@@ -28,16 +36,27 @@ import { isFocusInLastItem, isFocusInFirstItem } from "./../common/tab.service";
2836
`
2937
})
3038
export class ContentSwitcher implements AfterViewInit {
39+
/**
40+
* aria-label for the content switcher. Should be set to something descriptive
41+
*/
3142
@Input() label = "content switcher";
3243

44+
/**
45+
* Emits the activated `ContentSwitcherOption`
46+
*/
3347
@Output() selected = new EventEmitter();
3448

3549
@ContentChildren(ContentSwitcherOption) options: QueryList<ContentSwitcherOption>;
3650

3751
constructor(protected elementRef: ElementRef) {}
3852

3953
ngAfterViewInit() {
40-
this.options.first.active = true;
54+
const firstActive = this.options.find(option => option.active);
55+
// delay setting active until the DOM has settled
56+
if (!firstActive) {
57+
setTimeout(() => this.options.first.active = true);
58+
}
59+
// subscribe to each item, emit when one is selected, and reset the active states
4160
this.options.forEach(option => {
4261
option.selected.subscribe(_ => {
4362
const active = option;
@@ -53,7 +72,7 @@ export class ContentSwitcher implements AfterViewInit {
5372

5473
@HostListener("keydown", ["$event"])
5574
hostkeys(event: KeyboardEvent) {
56-
const buttonList = Array.from<any>(this.elementRef.nativeElement.querySelectorAll(".bx--content-switcher-btn"));
75+
const buttonList = Array.from<any>(this.elementRef.nativeElement.querySelectorAll("[ibmContentOption]"));
5776

5877
switch (event.key) {
5978
case "Right": // IE specific value

src/datepicker-input/datepicker-input.component.ts

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,18 @@ import { Component, Input } from "@angular/core";
55
template: `
66
<div class="bx--form-item">
77
<div class="bx--date-picker"
8-
[ngClass]= "'bx--date-picker--' + type">
8+
[ngClass]="{
9+
'bx--date-picker--single' : type === 'single',
10+
'bx--date-picker--range' : type === 'range',
11+
'bx--date-picker--light' : theme === 'light',
12+
'bx--skeleton' : skeleton
13+
}">
914
<div class="bx--date-picker-container">
1015
<label [for]="id" class="bx--label">
1116
{{label}}
1217
</label>
13-
<svg *ngIf="type == 'single'"
18+
<div *ngIf="skeleton" class="bx--date-picker__input bx--skeleton"></div>
19+
<svg *ngIf="type == 'single' && !skeleton"
1420
data-date-picker-icon
1521
class="bx--date-picker__icon"
1622
width="14" height="16"
@@ -22,17 +28,23 @@ import { Component, Input } from "@angular/core";
2228
fill-rule="nonzero"/>
2329
</svg>
2430
<input
31+
*ngIf="!skeleton"
2532
autocomplete="off"
2633
type="text"
2734
class="bx--date-picker__input"
2835
[pattern]="pattern"
2936
[placeholder]="placeholder"
3037
data-date-picker-input
3138
[attr.data-input] = "type == 'single' || type == 'range' ? '' : null"
32-
[id]= "id"/>
39+
[id]= "id"
40+
[attr.disabled]="(disabled ? '' : null)"
41+
[attr.data-invalid]="(invalid ? '' : null)"/>
42+
<div *ngIf="invalid" class="bx--form-requirement">
43+
{{invalidText}}
44+
</div>
3345
</div>
3446
35-
<svg *ngIf= "type == 'range' && hasIcon"
47+
<svg *ngIf= "type == 'range' && hasIcon && !skeleton"
3648
data-date-picker-icon
3749
class="bx--date-picker__icon"
3850
width="14" height="16"
@@ -67,4 +79,14 @@ export class DatePickerInput {
6779
@Input() placeholder = "mm/dd/yyyy";
6880

6981
@Input() pattern = "\d{1,2}/\d{1,2}/\d{4}";
82+
83+
@Input() theme: "light" | "dark" = "dark";
84+
85+
@Input() disabled = false;
86+
87+
@Input() invalid = false;
88+
89+
@Input() invalidText: string;
90+
91+
@Input() skeleton = false;
7092
}

src/datepicker-input/datepicker-input.stories.ts

Lines changed: 0 additions & 23 deletions
This file was deleted.

src/datepicker/datepicker.component.ts

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,12 @@ import rangePlugin from "flatpickr/dist/plugins/rangePlugin";
2323
data-date-picker
2424
[attr.data-date-picker-type]= "range ? 'range' : 'single'"
2525
class="bx--date-picker"
26-
[ngClass]= "range ? 'bx--date-picker--range' : 'bx--date-picker--single'">
26+
[ngClass]="{
27+
'bx--date-picker--range' : range,
28+
'bx--date-picker--single' : !range,
29+
'bx--date-picker--light' : theme === 'light',
30+
'bx--skeleton' : skeleton
31+
}">
2732
<div class="bx--date-picker-container">
2833
<ibm-date-picker-input
2934
[label]= "label"
@@ -32,6 +37,10 @@ import rangePlugin from "flatpickr/dist/plugins/rangePlugin";
3237
[id]= "id"
3338
[type]= "range ? 'range' : 'single'"
3439
[hasIcon]= "range ? false : true"
40+
[disabled]="disabled"
41+
[invalid]="invalid"
42+
[invalidText]="invalidText"
43+
[skeleton]="skeleton"
3544
(valueChange)="valueChange.emit($event)">
3645
</ibm-date-picker-input>
3746
</div>
@@ -44,6 +53,10 @@ import rangePlugin from "flatpickr/dist/plugins/rangePlugin";
4453
[id]= "id + '-rangeInput'"
4554
[type]= "range ? 'range' : 'single'"
4655
[hasIcon]= "range ? true : null"
56+
[disabled]="disabled"
57+
[invalid]="invalid"
58+
[invalidText]="invalidText"
59+
[skeleton]="skeleton"
4760
(valueChange)="valueChange.emit($event)">
4861
</ibm-date-picker-input>
4962
</div>
@@ -80,6 +93,16 @@ export class DatePicker implements OnDestroy {
8093

8194
@Input() value: Array<any>;
8295

96+
@Input() theme: "light" | "dark" = "dark";
97+
98+
@Input() disabled = false;
99+
100+
@Input() invalid = false;
101+
102+
@Input() invalidText: string;
103+
104+
@Input() skeleton = false;
105+
83106
@Output() valueChange: EventEmitter<any> = new EventEmitter();
84107

85108
flatpickrOptions: FlatpickrOptions = {
@@ -141,6 +164,9 @@ export class DatePicker implements OnDestroy {
141164
// add day classes and special case the "today" element based on `this.value`
142165
Array.from(dayContainer).forEach(element => {
143166
element.classList.add("bx--date-picker__day");
167+
if (!this.value) {
168+
return;
169+
}
144170
if (element.classList.contains("today") && this.value.length > 0) {
145171
element.classList.add("no-border");
146172
} else if (element.classList.contains("today") && this.value.length === 0) {
Lines changed: 63 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import { storiesOf, moduleMetadata } from "@storybook/angular";
22
import { action } from "@storybook/addon-actions";
3-
import { withKnobs, array } from "@storybook/addon-knobs/angular";
3+
import { withKnobs, array, select, text, boolean } from "@storybook/addon-knobs/angular";
44
import { DatePickerModule, ExperimentalModule } from "../";
5+
import { DatePickerInputModule } from "./../datepicker-input/datepicker-input.module";
56
import { ExperimentalComponenent } from "../../.storybook/experimental.component";
67

78
storiesOf("Date Picker", module)
@@ -10,41 +11,92 @@ storiesOf("Date Picker", module)
1011
declarations: [ExperimentalComponenent],
1112
imports: [
1213
DatePickerModule,
14+
DatePickerInputModule,
1315
ExperimentalModule
1416
]
1517
})
1618
)
1719
.addDecorator(withKnobs)
20+
.add("Simple", () => ({
21+
template: `
22+
<app-experimental-component></app-experimental-component>
23+
<ibm-date-picker-input
24+
[theme]="theme"
25+
[label]="label"
26+
[placeholder]="placeholder"
27+
[disabled]="disabled"
28+
[invalid]="invalid"
29+
[invalidText]="invalidText">
30+
</ibm-date-picker-input>
31+
`,
32+
props: {
33+
theme: select("Theme", ["dark", "light"], "dark"),
34+
label: text("Label text", "Date Picker Label"),
35+
placeholder: text("Placeholder text", "mm/dd/yyyy"),
36+
invalidText: text("Form validation content", "Invalid date format"),
37+
invalid: boolean("Show form validation", false),
38+
disabled: boolean("Disabled", false)
39+
}
40+
}))
1841
.add("Single", () => ({
1942
template: `
2043
<app-experimental-component></app-experimental-component>
2144
<ibm-date-picker
22-
label="Date Picker Label"
23-
[value]="value"
45+
[label]="label"
46+
[placeholder]="placeholder"
47+
[theme]="theme"
48+
[disabled]="disabled"
49+
[invalid]="invalid"
50+
[invalidText]="invalidText"
2451
(valueChange)="valueChange($event)">
2552
</ibm-date-picker>
2653
`,
2754
props: {
28-
value: array("value", ["01/01/2011"]),
29-
valueChange: action("Date change fired!")
55+
value: array("value", [(new Date().getMonth() + 1) + "/" + new Date().getDate() + "/" + new Date().getFullYear()]),
56+
valueChange: action("Date change fired!"),
57+
theme: select("Theme", ["dark", "light"], "dark"),
58+
label: text("Label text", "Date Picker Label"),
59+
placeholder: text("Placeholder text", "mm/dd/yyyy"),
60+
invalidText: text("Form validation content", "Invalid date format"),
61+
invalid: boolean("Show form validation", false),
62+
disabled: boolean("Disabled", false)
3063
}
3164
}))
3265
.add("Range", () => ({
3366
template: `
3467
<app-experimental-component></app-experimental-component>
3568
<ibm-date-picker
36-
label="Date Picker Label"
37-
rangeLabel="Date Picker Label2"
69+
[label]="label"
70+
[rangeLabel]="label"
3871
range="true"
39-
[value]="value"
72+
[placeholder]="placeholder"
73+
[theme]="theme"
74+
[disabled]="disabled"
75+
[invalid]="invalid"
76+
[invalidText]="invalidText"
4077
(valueChange)="valueChange($event)">
4178
</ibm-date-picker>
4279
`,
4380
props: {
4481
value: array("value", [
45-
"01/01/2011",
46-
"01/01/2012"
82+
(new Date().getMonth() + 1) + "/" + new Date().getDate() + "/" + new Date().getFullYear(),
83+
(new Date().getMonth() + 2) + "/" + new Date().getDate() + "/" + new Date().getFullYear()
4784
]),
48-
valueChange: action("Date change fired!")
85+
valueChange: action("Date change fired!"),
86+
theme: select("Theme", ["dark", "light"], "dark"),
87+
label: text("Label text", "Date Picker Label"),
88+
placeholder: text("Placeholder text", "mm/dd/yyyy"),
89+
invalidText: text("Form validation content", "Invalid date format"),
90+
invalid: boolean("Show form validation", false),
91+
disabled: boolean("Disabled", false)
4992
}
93+
}))
94+
.add("Skeleton", () => ({
95+
template: `
96+
<app-experimental-component></app-experimental-component>
97+
<ibm-date-picker
98+
range="true"
99+
skeleton="true">
100+
</ibm-date-picker>
101+
`
50102
}));

src/dropdown/list/dropdown-list.component.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,7 @@ export class DropdownList implements AbstractDropdownView, AfterViewInit, OnDest
212212
this.index = this._items.findIndex(item => item.selected);
213213
this.setupFocusObservable();
214214
setTimeout(() => {
215+
if (!this.getSelected()) { return; }
215216
if (this.type === "single") {
216217
this.select.emit({ item: this._items.find(item => item.selected) });
217218
} else {

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;

0 commit comments

Comments
 (0)