Skip to content

Commit 22aeb11

Browse files
committed
feat(core): onExpanded
onExpanded event is triggered when the list status changes Closes closes #7
1 parent 749d4fc commit 22aeb11

File tree

7 files changed

+173
-100
lines changed

7 files changed

+173
-100
lines changed

README.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,32 @@ export class AppComponent {
263263
| disabled | boolean | When applied to the `expandable-list-item`, disabled the
264264
| is-expanded | boolean | Reflect the expandable state of the item list element
265265

266+
## Events
267+
268+
| Name | Type | Description |
269+
| --- | --- | --- |
270+
| onExpanded | boolean | Triggered when the list expansion status changes
271+
272+
Example:
273+
274+
```ts
275+
@Component({
276+
selector: 'app',
277+
template: `
278+
<expandable-list class="expandable-list">
279+
<expandable-list-item [isExpanded]="listExpanded"
280+
(onExpanded)="listExpanded = $event">
281+
<span title>My list</span>
282+
<a item href="http://www.goo.gl">Google</a>
283+
</expandable-list-item>
284+
</expandable-list>
285+
`
286+
})
287+
export class AppComponent {
288+
listExpanded = true;
289+
}
290+
```
291+
266292
## Angular 4
267293

268294
This module will work with Angular 4 projects but requires `@angular/animations`

demo/app.component.css

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
:host {
2+
background: rgb(184, 218, 215);
3+
display: block;
4+
height: 100%;
5+
padding-top: 50px;
6+
box-sizing: border-box;
7+
}
8+
9+
.content-wrapper {
10+
max-width: 600px;
11+
margin: 0 auto;
12+
}
13+
14+
.button {
15+
margin: 10px 0;
16+
border: 1px solid #333;
17+
background: #eee;
18+
color: #000;
19+
font-size: 14px;
20+
border-radius: 4px;
21+
padding: 5px 15px;
22+
}

demo/app.component.html

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
<div class="content-wrapper">
2+
<button class="button"
3+
(click)="toggleMe()"> Toggle List</button>
4+
<p>List status: {{ listAExpanded ? 'Expanded' : 'Collapsed' }}</p>
5+
6+
<expandable-list class="expandable-list">
7+
<expandable-list-item *ngFor="let item of items"
8+
[isExpanded]="listAExpanded"
9+
(onExpanded)="updateStatus($event)">
10+
<span title>{{ item.title }}</span>
11+
<a item *ngFor="let i of item.items"
12+
[href]="i.link">
13+
{{ i.title }}
14+
</a>
15+
</expandable-list-item>
16+
17+
<expandable-list-item disabled>
18+
<span title>Manual</span>
19+
<span secondary>disabled</span>
20+
</expandable-list-item>
21+
22+
<expandable-list-item [isExpanded]="listCExpanded">
23+
<span title>Manual</span>
24+
<span secondary>first</span>
25+
26+
<a href="http://www.goo.gl">THIS WON'T BE RENDERED!</a>
27+
28+
<a item href="http://www.goo.gl">Google</a>
29+
<a item href="http://www.goo.gl">Google</a>
30+
<a item href="http://www.goo.gl">Google</a>
31+
32+
<expandable-list-divider></expandable-list-divider>
33+
34+
<a item href="http://www.goo.gl">Google after</a>
35+
</expandable-list-item>
36+
37+
<expandable-list-item [isExpanded]="listBExpanded" disabled>
38+
<span title>Manual</span>
39+
<span secondary>second</span>
40+
<a href="http://www.goo.gl">Something else</a>
41+
<a item href="http://www.goo.gl">Google</a>
42+
<a item href="http://www.goo.gl">Google</a>
43+
<a item href="http://www.goo.gl">Google</a>
44+
45+
<expandable-list-divider></expandable-list-divider>
46+
47+
<a item href="http://www.goo.gl">Google</a>
48+
</expandable-list-item>
49+
</expandable-list>
50+
</div>

demo/app.component.ts

Lines changed: 45 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -1,107 +1,56 @@
1-
import { Component } from '@angular/core';
1+
import { Component, OnInit } from '@angular/core';
22

33
@Component({
44
selector: 'app',
5-
styles: [`
6-
:host {
7-
background: rgb(184, 218, 215);
8-
display: block;
9-
height: 100%;
10-
padding-top: 50px;
11-
box-sizing: border-box;
12-
}
13-
.expandable-list {
14-
max-width: 600px;
15-
margin: 0 auto;
16-
}
17-
`],
18-
template: `
19-
<expandable-list class="expandable-list">
20-
<expandable-list-item *ngFor="let item of items" [isExpanded]="listAExpanded">
21-
<span title>{{ item.title }}</span>
22-
<a item *ngFor="let i of item.items"
23-
[href]="i.link">
24-
{{ i.title }}
25-
</a>
26-
</expandable-list-item>
27-
28-
<expandable-list-item disabled>
29-
<span title>Manual</span>
30-
<span secondary>disabled</span>
31-
</expandable-list-item>
32-
33-
<expandable-list-item [isExpanded]="listCExpanded">
34-
<span title>Manual</span>
35-
<span secondary>first</span>
36-
37-
<a href="http://www.goo.gl">THIS WON'T BE RENDERED!</a>
38-
39-
<a item href="http://www.goo.gl">Google</a>
40-
<a item href="http://www.goo.gl">Google</a>
41-
<a item href="http://www.goo.gl">Google</a>
42-
43-
<expandable-list-divider></expandable-list-divider>
44-
45-
<a item href="http://www.goo.gl">Google after</a>
46-
</expandable-list-item>
47-
48-
<expandable-list-item [isExpanded]="listBExpanded" disabled>
49-
<span title>Manual</span>
50-
<span secondary>second</span>
51-
<a href="http://www.goo.gl">Something else</a>
52-
<a item href="http://www.goo.gl">Google</a>
53-
<a item href="http://www.goo.gl">Google</a>
54-
<a item href="http://www.goo.gl">Google</a>
55-
56-
<expandable-list-divider></expandable-list-divider>
57-
58-
<a item href="http://www.goo.gl">Google</a>
59-
</expandable-list-item>
60-
</expandable-list>
61-
`
5+
styleUrls: ['./app.component.css'],
6+
templateUrl: './app.component.html',
627
})
63-
export class AppComponent {
8+
export class AppComponent implements OnInit {
649
items: any;
6510
listAExpanded = false;
6611
listBExpanded = true;
6712
listCExpanded = false;
6813

69-
constructor() {
70-
this.items = [
71-
{
72-
title: 'Spices',
73-
items: [
74-
{
75-
title: 'salt',
76-
link: 'https://en.wikipedia.org/wiki/Salt'
77-
},
78-
{
79-
title: 'Black pepper',
80-
link: 'https://en.wikipedia.org/wiki/Black_pepper'
81-
},
82-
]
83-
},
84-
{
85-
title: 'Cats',
86-
items: [
87-
{
88-
title: 'Siberian',
89-
link: 'https://en.wikipedia.org/wiki/Siberian_cat'
90-
},
91-
{
92-
title: 'Maine Coon',
93-
link: 'https://en.wikipedia.org/wiki/Maine_Coon'
94-
},
95-
{
96-
title: 'American Bobtail',
97-
link: 'https://en.wikipedia.org/wiki/American_Bobtail'
98-
},
99-
{
100-
title: 'British Longhair',
101-
link: 'https://en.wikipedia.org/wiki/British_Longhair'
102-
},
103-
]
104-
},
105-
];
14+
constructor() { }
15+
16+
ngOnInit(): void {
17+
this.items = [{
18+
title: 'Spices',
19+
items: [
20+
{
21+
title: 'salt',
22+
link: 'https://en.wikipedia.org/wiki/Salt'
23+
}, {
24+
title: 'Black pepper',
25+
link: 'https://en.wikipedia.org/wiki/Black_pepper'
26+
}
27+
]
28+
}, {
29+
title: 'Cats',
30+
items: [
31+
{
32+
title: 'Siberian',
33+
link: 'https://en.wikipedia.org/wiki/Siberian_cat'
34+
}, {
35+
title: 'Maine Coon',
36+
link: 'https://en.wikipedia.org/wiki/Maine_Coon'
37+
}, {
38+
title: 'American Bobtail',
39+
link: 'https://en.wikipedia.org/wiki/American_Bobtail'
40+
}, {
41+
title: 'British Longhair',
42+
link: 'https://en.wikipedia.org/wiki/British_Longhair'
43+
}
44+
]
45+
}];
46+
}
47+
48+
toggleMe(): void {
49+
this.listAExpanded = !this.listAExpanded;
50+
}
51+
52+
updateStatus(event: boolean) {
53+
console.log(event);
54+
this.listAExpanded = event;
10655
}
10756
}

demo/main.map

Lines changed: 0 additions & 1 deletion
This file was deleted.

src/expandable-list.component.spec.ts

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ describe('ExpandableListModule', () => {
5959
expect(itemContent).toBeTruthy();
6060
});
6161

62-
it('The title should contatin a label and a drop-down button', () => {
62+
it('the title should contatin a label and a drop-down button', () => {
6363
fixture.detectChanges();
6464
let itemTitle = listItemDe.query(By.css('.expandable-list-item-title .expandable-list-item--title'));
6565
let titleLabel = itemTitle.query(By.css('span'));
@@ -101,7 +101,7 @@ describe('ExpandableListModule', () => {
101101
});
102102

103103
it('user interaction', () => {
104-
let testComponent = fixture.debugElement.componentInstance;
104+
let testComponent: TestApp = fixture.debugElement.componentInstance;
105105

106106
fixture.detectChanges();
107107
let itemTitle = listItemDe.query(By.css('.expandable-list-item-title'));
@@ -124,6 +124,20 @@ describe('ExpandableListModule', () => {
124124
.toBe('false', 'list item element collapsed');
125125
});
126126

127+
it('should trigger an event when the status change', () => {
128+
let testComponent: TestApp = fixture.debugElement.componentInstance;
129+
let itemTitle = listItemDe.query(By.css('.expandable-list-item-title'));
130+
131+
fixture.detectChanges();
132+
133+
expect(testComponent.listExpanded).toBe(false);
134+
135+
itemTitle.nativeElement.click();
136+
fixture.detectChanges();
137+
138+
expect(testComponent.listExpanded).toBe(true);
139+
});
140+
127141
it('user interaction on a disabled list', () => {
128142
let fixture2 = TestBed.createComponent(TestApp2);
129143
let listItem2De = fixture2.debugElement.query(By.css('expandable-list-item'));
@@ -148,7 +162,9 @@ describe('ExpandableListModule', () => {
148162
selector: 'test-app',
149163
template: `
150164
<expandable-list class="expandable-list">
151-
<expandable-list-item [isExpanded]="listExpanded" [disabled]="listDisabled">
165+
<expandable-list-item [isExpanded]="listExpanded"
166+
[disabled]="listDisabled"
167+
(onExpanded)="listExpanded = $event">
152168
<span title>Title</span>
153169
<span secondary>secondary</span>
154170
<a href="http://www.goo.gl">Something else</a>

src/expandable-list.component.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,13 @@ import {
1212
ViewEncapsulation,
1313
HostBinding,
1414
Input,
15+
Output,
1516
AfterViewInit,
1617
OnChanges,
1718
SimpleChanges,
1819
ElementRef,
1920
ViewChild,
21+
EventEmitter,
2022
} from '@angular/core';
2123

2224
@Component({
@@ -69,6 +71,9 @@ export class ExpandableListItemComponent implements AfterViewInit, OnChanges {
6971
this.isDisabled = (value !== null && `${value}` !== 'false') ? true : null;
7072
}
7173

74+
@Output()
75+
public onExpanded: EventEmitter<boolean>;
76+
7277
private elHeight: number;
7378

7479
@ViewChild('contentEl')
@@ -84,6 +89,10 @@ export class ExpandableListItemComponent implements AfterViewInit, OnChanges {
8489
this.elHeight = this.elementView.nativeElement.offsetHeight;
8590
}
8691

92+
constructor() {
93+
this.onExpanded = new EventEmitter<boolean>();
94+
}
95+
8796
public ngOnChanges(changes: SimpleChanges) {
8897
if ('isExpanded' in changes) {
8998
this.updateMarginTop();
@@ -106,5 +115,7 @@ export class ExpandableListItemComponent implements AfterViewInit, OnChanges {
106115
} else {
107116
this.marginTop = '0';
108117
}
118+
119+
this.onExpanded.emit(this.isExpanded);
109120
}
110121
}

0 commit comments

Comments
 (0)