Skip to content

Commit ef75017

Browse files
authored
Merge branch 'master' into issue#450
2 parents b58aa74 + bf3d8dd commit ef75017

11 files changed

+449
-42
lines changed

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/i18n/en.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,11 @@
131131
"BUTTON_ARIA_LEFT": "Go to the previous tab",
132132
"BUTTON_ARIA_RIGHT": "Go to the next tab"
133133
},
134+
"TILES": {
135+
"TILE": "tile",
136+
"EXPAND": "Expand",
137+
"COLLAPSE": "Collapse"
138+
},
134139
"TOGGLE": {
135140
"OFF": "Off",
136141
"ON": "On"
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
import {
2+
Component,
3+
HostBinding,
4+
Input,
5+
ViewChild,
6+
ElementRef,
7+
AfterContentInit
8+
} from "@angular/core";
9+
import { I18n } from "./../i18n/i18n.module";
10+
11+
@Component({
12+
selector: "ibm-expandable-tile",
13+
template: `
14+
<div
15+
class="bx--tile bx--tile--expandable"
16+
[ngClass]="{'bx--tile--is-expanded' : expanded}"
17+
[ngStyle]="{'max-height': expandedHeight + 'px'}"
18+
role="button"
19+
tabindex="0"
20+
(click)="onClick()">
21+
<button [attr.aria-label]="(expanded ? collapse : expand) | async" class="bx--tile__chevron">
22+
<svg *ngIf="!expanded" width="12" height="7" viewBox="0 0 12 7" role="img">
23+
<title>{{expand | async}}</title>
24+
<path fill-rule="nonzero" d="M6.002 5.55L11.27 0l.726.685L6.003 7 0 .685.726 0z"/>
25+
</svg>
26+
<svg *ngIf="expanded" width="12" height="7" viewBox="0 0 12 7" role="img">
27+
<title>{{collapse | async}}</title>
28+
<path fill-rule="nonzero" d="M6.002 5.55L11.27 0l.726.685L6.003 7 0 .685.726 0z"/>
29+
</svg>
30+
</button>
31+
<div class="bx--tile-content">
32+
<ng-content select=".bx--tile-content__above-the-fold"></ng-content>
33+
<ng-content select=".bx--tile-content__below-the-fold"></ng-content>
34+
</div>
35+
</div>
36+
`
37+
})
38+
export class ExpandableTile implements AfterContentInit {
39+
@Input() expanded = false;
40+
/**
41+
* Expects an object that contains some or all of:
42+
* ```
43+
* {
44+
* "EXPAND": "Expand",
45+
* "COLLAPSE": "Collapse",
46+
* }
47+
* ```
48+
*/
49+
@Input()
50+
set translations (value) {
51+
if (value.EXPAND) {
52+
this.expand.next(value.EXPAND);
53+
}
54+
if (value.COLLAPSE) {
55+
this.collapse.next(value.COLLAPSE);
56+
}
57+
}
58+
59+
tileMaxHeight = 0;
60+
element = this.elementRef.nativeElement;
61+
62+
expand = this.i18n.get("TILES.EXPAND");
63+
collapse = this.i18n.get("TILES.COLLAPSE");
64+
65+
constructor(protected i18n: I18n, protected elementRef: ElementRef) {}
66+
67+
ngAfterContentInit() {
68+
this.updateMaxHeight();
69+
}
70+
71+
get expandedHeight() {
72+
return this.tileMaxHeight + parseInt(getComputedStyle(this.element.querySelector(".bx--tile")).paddingBottom, 10);
73+
}
74+
75+
updateMaxHeight() {
76+
if (this.expanded) {
77+
this.tileMaxHeight = this.element.querySelector(".bx--tile-content").getBoundingClientRect().height;
78+
} else {
79+
this.tileMaxHeight = this.element.querySelector(".bx--tile-content__above-the-fold").getBoundingClientRect().height;
80+
}
81+
}
82+
83+
onClick() {
84+
this.expanded = !this.expanded;
85+
this.updateMaxHeight();
86+
}
87+
}

0 commit comments

Comments
 (0)