Skip to content

Commit cd6e60d

Browse files
authored
Merge branch 'master' into skeleton-file-uploader
2 parents f822526 + d45f3bb commit cd6e60d

11 files changed

+170
-31
lines changed

src/accordion/accordion-item.component.ts

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,17 +21,29 @@ import {
2121
viewBox="0 0 7 12">
2222
<path fill-rule="nonzero" d="M5.569 5.994L0 .726.687 0l6.336 5.994-6.335 6.002L0 11.27z"/>
2323
</svg>
24-
<p class="bx--accordion__title">{{title}}</p>
24+
<p
25+
class="bx--accordion__title"
26+
[ngClass]="{
27+
'bx--skeleton__text': skeleton
28+
}">
29+
{{!skeleton ? title : null}}
30+
</p>
2531
</button>
2632
<div [id]="id" class="bx--accordion__content">
27-
<ng-content></ng-content>
33+
<ng-content *ngIf="!skeleton; else skeletonTemplate"></ng-content>
34+
<ng-template #skeletonTemplate>
35+
<p class="bx--skeleton__text" style="width: 90%"></p>
36+
<p class="bx--skeleton__text" style="width: 80%"></p>
37+
<p class="bx--skeleton__text" style="width: 95%"></p>
38+
</ng-template>
2839
</div>
2940
`
3041
})
3142
export class AccordionItem {
3243
static accordionItemCount = 0;
3344
@Input() title = `Title ${AccordionItem.accordionItemCount}`;
3445
@Input() id = `accordion-item-${AccordionItem.accordionItemCount}`;
46+
@Input() skeleton = false;
3547
@Output() selected = new EventEmitter();
3648

3749
@HostBinding("class.bx--accordion__item") itemClass = true;
@@ -45,7 +57,9 @@ export class AccordionItem {
4557
}
4658

4759
public toggleExpanded() {
48-
this.expanded = !this.expanded;
49-
this.selected.emit({id: this.id, expanded: this.expanded});
60+
if (!this.skeleton) {
61+
this.expanded = !this.expanded;
62+
this.selected.emit({id: this.id, expanded: this.expanded});
63+
}
5064
}
5165
}
Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,11 @@
1-
import { Component } from "@angular/core";
1+
import {
2+
Component,
3+
Input,
4+
ContentChildren,
5+
QueryList,
6+
AfterContentInit
7+
} from "@angular/core";
8+
import { AccordionItem } from "./accordion-item.component";
29

310
@Component({
411
selector: "ibm-accordion",
@@ -8,6 +15,28 @@ import { Component } from "@angular/core";
815
</ul>
916
`
1017
})
11-
export class Accordion {
18+
export class Accordion implements AfterContentInit {
19+
@ContentChildren(AccordionItem) children: QueryList<AccordionItem>;
1220

21+
protected _skeleton = false;
22+
23+
@Input()
24+
set skeleton(value: any) {
25+
this._skeleton = value;
26+
this.updateChildren();
27+
}
28+
29+
get skeleton(): any {
30+
return this._skeleton;
31+
}
32+
33+
ngAfterContentInit() {
34+
this.updateChildren();
35+
}
36+
37+
protected updateChildren() {
38+
if (this.children) {
39+
this.children.toArray().forEach(child => child.skeleton = this.skeleton);
40+
}
41+
}
1342
}

src/accordion/accordion.stories.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,4 +52,16 @@ storiesOf("Accordion", module)
5252
],
5353
selected: action("item expanded")
5454
}
55+
}))
56+
.add("Skeleton", () => ({
57+
template: `
58+
<div style="width: 500px">
59+
<ibm-accordion skeleton="true">
60+
<ibm-accordion-item expanded="true"></ibm-accordion-item>
61+
<ibm-accordion-item></ibm-accordion-item>
62+
<ibm-accordion-item></ibm-accordion-item>
63+
<ibm-accordion-item></ibm-accordion-item>
64+
</ibm-accordion>
65+
</div>
66+
`
5567
}));

src/dropdown/dropdown.component.ts

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,12 @@ import { I18n } from "./../i18n/i18n.module";
2929
selector: "ibm-dropdown",
3030
template: `
3131
<div
32-
class="bx--list-box"
33-
[ngClass]="{'bx--dropdown--light': theme === 'light'}">
32+
class="bx--list-box bx--dropdown-v2"
33+
[ngClass]="{
34+
'bx--dropdown--light': theme === 'light',
35+
'bx--list-box--inline': inline,
36+
'bx--skeleton': skeleton
37+
}">
3438
<button
3539
type="button"
3640
#dropdownButton
@@ -42,7 +46,7 @@ import { I18n } from "./../i18n/i18n.module";
4246
(blur)="onBlur()"
4347
[disabled]="disabled">
4448
<span class="bx--list-box__label">{{getDisplayValue() | async}}</span>
45-
<div class="bx--list-box__menu-icon" [ngClass]="{'bx--list-box__menu-icon--open': !menuIsClosed }">
49+
<div *ngIf="!skeleton" class="bx--list-box__menu-icon" [ngClass]="{'bx--list-box__menu-icon--open': !menuIsClosed }">
4650
<svg fill-rule="evenodd" height="5" role="img" viewBox="0 0 10 5" width="10" alt="Open menu" [attr.aria-label]="menuButtonLabel">
4751
<title>{{menuButtonLabel}}</title>
4852
<path d="M0 0l5 4.998L10 0z"></path>
@@ -93,6 +97,14 @@ export class Dropdown implements OnInit, AfterContentInit, OnDestroy {
9397
* Set to `true` to disable the dropdown.
9498
*/
9599
@Input() disabled = false;
100+
/**
101+
* Set to `true` for a loading dropdown.
102+
*/
103+
@Input() skeleton = false;
104+
/**
105+
* Set to `true` for an inline dropdown.
106+
*/
107+
@Input() inline = false;
96108
/**
97109
* Deprecated. Dropdown now defaults to appending inline
98110
* Set to `true` if the `Dropdown` is to be appended to the DOM body.
@@ -198,13 +210,18 @@ export class Dropdown implements OnInit, AfterContentInit, OnDestroy {
198210
* The `type` property specifies whether the `Dropdown` allows single selection or multi selection.
199211
*/
200212
ngOnInit() {
201-
this.view.type = this.type;
213+
if (this.view) {
214+
this.view.type = this.type;
215+
}
202216
}
203217

204218
/**
205219
* Initializes classes and subscribes to events for single or multi selection.
206220
*/
207221
ngAfterContentInit() {
222+
if (!this.view) {
223+
return;
224+
}
208225
this.view.type = this.type;
209226
this.view.size = this.size;
210227
this.view.select.subscribe(event => {
@@ -323,6 +340,9 @@ export class Dropdown implements OnInit, AfterContentInit, OnDestroy {
323340
* Returns the display value if there is no selection, otherwise the selection will be returned.
324341
*/
325342
getDisplayValue(): Observable<string> {
343+
if (!this.view) {
344+
return;
345+
}
326346
let selected = this.view.getSelected();
327347
if (selected && !this.displayValue) {
328348
if (this.type === "multi") {

src/dropdown/dropdown.stories.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,4 +87,25 @@ storiesOf("Dropdown", module)
8787
],
8888
model: null
8989
}
90+
}))
91+
.add("Skeleton", () => ({
92+
template: `
93+
<div style="width: 300px">
94+
<ibm-dropdown skeleton="true">
95+
<ibm-dropdown-list [items]="items"></ibm-dropdown-list>
96+
</ibm-dropdown>
97+
&nbsp;
98+
<ibm-dropdown skeleton="true" inline="true">
99+
<ibm-dropdown-list [items]="items"></ibm-dropdown-list>
100+
</ibm-dropdown>
101+
</div>
102+
`,
103+
props: {
104+
items: [
105+
{ content: "one" },
106+
{ content: "two" },
107+
{ content: "three" },
108+
{ content: "four" }
109+
]
110+
}
90111
}));

src/search/search.component.spec.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ describe("Search", () => {
2222

2323
beforeEach(() => {
2424
fixture = TestBed.createComponent(Search);
25+
fixture.detectChanges();
2526
component = fixture.componentInstance;
2627
inputElement = fixture.debugElement.query(By.css("input")).nativeElement;
2728
});

src/search/search.component.ts

Lines changed: 30 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -41,29 +41,35 @@ export class SearchChange {
4141
[ngClass]="{
4242
'bx--search--sm': size === 'sm',
4343
'bx--search--lg': size === 'lg',
44-
'bx--search--light': theme === 'light'
44+
'bx--search--light': theme === 'light',
45+
'bx--skeleton': skeleton
4546
}"
4647
role="search">
4748
<label class="bx--label" [for]="id">{{label}}</label>
48-
<input
49-
class="bx--search-input"
50-
type="text"
51-
role="search"
52-
[id]="id"
53-
[value]="value"
54-
[placeholder]="placeholder"
55-
[disabled]="disabled"
56-
[required]="required"
57-
(input)="onSearch($event.target.value)"/>
58-
<svg
59-
class="bx--search-magnifier"
60-
width="16"
61-
height="16"
62-
viewBox="0 0 16 16">
63-
<path
64-
d="M6.5 12a5.5 5.5 0 1 0 0-11 5.5 5.5 0 0 0 0 11zm4.936-1.27l4.563 4.557-.707.708-4.563-4.558a6.5 6.5 0 1 1 .707-.707z"
65-
fill-rule="nonzero"/>
66-
</svg>
49+
50+
<div *ngIf="skeleton; else enableInput" class="bx--search-input"></div>
51+
<ng-template #enableInput>
52+
<input
53+
class="bx--search-input"
54+
type="text"
55+
role="search"
56+
[id]="id"
57+
[value]="value"
58+
[placeholder]="placeholder"
59+
[disabled]="disabled"
60+
[required]="required"
61+
(input)="onSearch($event.target.value)"/>
62+
<svg
63+
class="bx--search-magnifier"
64+
width="16"
65+
height="16"
66+
viewBox="0 0 16 16">
67+
<path
68+
d="M6.5 12a5.5 5.5 0 1 0 0-11 5.5 5.5 0 0 0 0 11zm4.936-1.27l4.563 4.557-.707.708-4.563-4.558a6.5 6.5 0 1 1 .707-.707z"
69+
fill-rule="nonzero"/>
70+
</svg>
71+
</ng-template>
72+
6773
<button
6874
class="bx--search-close"
6975
[ngClass]="{
@@ -113,6 +119,10 @@ export class Search implements ControlValueAccessor {
113119
* Set to `true` for a disabled search input.
114120
*/
115121
@Input() disabled = false;
122+
/**
123+
* Set to `true` for a loading search component.
124+
*/
125+
@Input() skeleton = false;
116126
/**
117127
* Sets the name attribute on the `input` element.
118128
*/

src/search/search.stories.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,13 @@ storiesOf("Search", module).addDecorator(
2121
disabled: boolean("disabled", false),
2222
placeholder: text("placeholder", "Search")
2323
}
24+
}))
25+
.add("Skeleton", () => ({
26+
template: `
27+
<div style="width: 200px;">
28+
<ibm-search skeleton="true"></ibm-search>
29+
&nbsp;
30+
<ibm-search skeleton="true" size="sm"></ibm-search>
31+
</div>
32+
`
2433
}));

src/tabs/tab-headers.component.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,12 @@ import { Tab } from "./tab.component";
2525
@Component({
2626
selector: "ibm-tab-headers",
2727
template: `
28-
<nav class="bx--tabs" role="navigation">
28+
<nav
29+
class="bx--tabs"
30+
[ngClass]="{
31+
'bx--skeleton': skeleton
32+
}"
33+
role="navigation">
2934
<div class="bx--tabs-trigger" tabindex="0" (click)="showTabList()">
3035
<a href="javascript:void(0)" class="bx--tabs-trigger-text" tabindex="-1">
3136
<ng-container *ngIf="!getSelectedTab().headingIsTemplate">
@@ -102,6 +107,10 @@ export class TabHeaders implements AfterViewInit, AfterContentInit {
102107
* @memberof TabHeaders
103108
*/
104109
@Input() followFocus: boolean;
110+
/**
111+
* Set to `true` to put tabs in a loading state.
112+
*/
113+
@Input() skeleton = false;
105114

106115
/**
107116
* Gets the Unordered List element that holds the `Tab` headings from the view DOM.

src/tabs/tabs.component.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,13 +41,15 @@ import { TabHeaders } from "./tab-headers.component";
4141
template: `
4242
<ibm-tab-headers
4343
*ngIf="hasTabHeaders() && position === 'top'"
44+
[skeleton]="skeleton"
4445
[tabs]="tabs"
4546
[followFocus]="followFocus"
4647
[cacheActive]="cacheActive">
4748
</ibm-tab-headers>
4849
<ng-content></ng-content>
4950
<ibm-tab-headers
5051
*ngIf="hasTabHeaders() && position === 'bottom'"
52+
[skeleton]="skeleton"
5153
[tabs]="tabs"
5254
[cacheActive]="cacheActive">
5355
</ibm-tab-headers>
@@ -71,6 +73,10 @@ export class Tabs implements AfterContentInit {
7173
* @memberof Tabs
7274
*/
7375
@Input() followFocus = true;
76+
/**
77+
* Set to `true` to put tabs in a loading state.
78+
*/
79+
@Input() skeleton = false;
7480

7581
/**
7682
* Maintains a `QueryList` of the `Tab` elements and updates if `Tab`s are added or removed.

0 commit comments

Comments
 (0)