-
Notifications
You must be signed in to change notification settings - Fork 6.9k
feat(list): add list component #214
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| <div class="md-list-item"> | ||
| <ng-content select="[md-list-avatar]"></ng-content> | ||
| <div class="md-list-text"><ng-content select="[md-line]"></ng-content></div> | ||
| <ng-content></ng-content> | ||
| </div> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,138 @@ | ||
| @import "variables"; | ||
|
|
||
| $md-list-side-padding: 16px; | ||
| $md-list-avatar-size: 40px; | ||
|
|
||
| /* Normal list variables */ | ||
| $md-list-top-padding: 8px; | ||
| $md-list-font-size: 16px; | ||
| $md-list-secondary-font: 14px; | ||
| // height for single-line lists | ||
| $md-list-base-height: 48px; | ||
| // height for single-line lists with avatars | ||
| $md-list-avatar-height: 56px; | ||
| // spec requires two- and three-line lists be taller | ||
| $md-list-two-line-height: 72px; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add comments for the
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You mean something like |
||
| $md-list-three-line-height: 88px; | ||
|
|
||
| /* Dense list variables */ | ||
| $md-dense-top-padding: 4px; | ||
| $md-dense-font-size: 13px; | ||
| $md-dense-base-height: 40px; | ||
| $md-dense-avatar-height: 48px; | ||
| $md-dense-two-line-height: 60px; | ||
| $md-dense-three-line-height: 76px; | ||
|
|
||
| /* | ||
| This mixin provides all list-item styles, changing font size and height | ||
| based on whether the list is in "dense" mode. | ||
| */ | ||
| @mixin md-list-item-base($font-size, $base-height, $avatar-height, | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It might be good for these mixins to describe what's captured in the
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done |
||
| $two-line-height, $three-line-height) { | ||
|
|
||
| .md-list-item { | ||
| display: flex; | ||
| flex-direction: row; | ||
| align-items: center; | ||
| font-family: $md-font-family; | ||
| box-sizing: border-box; | ||
| font-size: $font-size; | ||
| height: $base-height; | ||
| padding: 0 $md-list-side-padding; | ||
| } | ||
|
|
||
| &.md-list-avatar .md-list-item { | ||
| height: $avatar-height; | ||
| } | ||
|
|
||
| &.md-2-line .md-list-item { | ||
| height: $two-line-height; | ||
| } | ||
|
|
||
| &.md-3-line .md-list-item { | ||
| height: $three-line-height; | ||
| } | ||
|
|
||
| .md-list-text { | ||
| display: flex; | ||
| flex-direction: column; | ||
| width: 100%; | ||
| padding: 0 $md-list-side-padding; | ||
|
|
||
| &:first-child { | ||
| padding: 0; | ||
| } | ||
|
|
||
| &:empty { | ||
| display: none; | ||
| } | ||
|
|
||
| & > * { | ||
| margin: 0; | ||
| padding: 0; | ||
| font-weight: normal; | ||
| font-size: inherit; | ||
| } | ||
| } | ||
|
|
||
| [md-list-avatar] { | ||
| width: $md-list-avatar-size; | ||
| height: $md-list-avatar-size; | ||
| } | ||
| } | ||
|
|
||
| /* | ||
| This mixin provides all md-line styles, changing secondary font size | ||
| based on whether the list is in "dense" mode. | ||
| */ | ||
| @mixin md-line-base($secondary-font-size) { | ||
|
|
||
| [md-line] { | ||
| display: block; | ||
| white-space: nowrap; | ||
| overflow-x: hidden; | ||
| text-overflow: ellipsis; | ||
| box-sizing: border-box; | ||
|
|
||
| // all lines but the top line should have smaller text | ||
| &:nth-child(n+2) { | ||
| font-size: $secondary-font-size; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add comment for this rule
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done |
||
| } | ||
| } | ||
| } | ||
|
|
||
| md-list { | ||
| padding-top: $md-list-top-padding; | ||
| display: block; | ||
|
|
||
| md-list-item { | ||
| @include md-list-item-base( | ||
| $md-list-font-size, | ||
| $md-list-base-height, | ||
| $md-list-avatar-height, | ||
| $md-list-two-line-height, | ||
| $md-list-three-line-height | ||
| ); | ||
|
|
||
| @include md-line-base($md-list-secondary-font); | ||
| } | ||
| } | ||
|
|
||
|
|
||
| md-list[dense] { | ||
| padding-top: $md-dense-top-padding; | ||
| display: block; | ||
|
|
||
|
|
||
| md-list-item { | ||
| @include md-list-item-base( | ||
| $md-dense-font-size, | ||
| $md-dense-base-height, | ||
| $md-dense-avatar-height, | ||
| $md-dense-two-line-height, | ||
| $md-dense-three-line-height | ||
| ); | ||
|
|
||
| @include md-line-base($md-dense-font-size); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,180 @@ | ||
| import { | ||
| inject, | ||
| TestComponentBuilder | ||
| } from 'angular2/testing'; | ||
| import { | ||
| it, | ||
| describe, | ||
| expect, | ||
| beforeEach, | ||
| } from '../../core/facade/testing'; | ||
| import {Component} from 'angular2/core'; | ||
| import {By} from 'angular2/platform/browser'; | ||
|
|
||
| import {MD_LIST_DIRECTIVES} from './list'; | ||
|
|
||
| export function main() { | ||
| describe('MdList', () => { | ||
| let builder: TestComponentBuilder; | ||
|
|
||
| beforeEach(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => { | ||
| builder = tcb; | ||
| })); | ||
|
|
||
| it('should not apply any class to a list without lines', (done: () => void) => { | ||
| var template = ` | ||
| <md-list> | ||
| <md-list-item> | ||
| Paprika | ||
| </md-list-item> | ||
| </md-list> | ||
| `; | ||
| return builder.overrideTemplate(TestList, template) | ||
| .createAsync(TestList).then((fixture) => { | ||
| let listItem = fixture.debugElement.query(By.css('md-list-item')); | ||
| fixture.detectChanges(); | ||
| expect(listItem.nativeElement.className).toBe(''); | ||
| done(); | ||
| }); | ||
| }); | ||
|
|
||
| it('should apply md-2-line class to lists with two lines', (done: () => void) => { | ||
| var template = ` | ||
| <md-list> | ||
| <md-list-item *ngFor="#item of items"> | ||
| <img src=""> | ||
| <h3 md-line>{{item.name}}</h3> | ||
| <p md-line>{{item.description}}</p> | ||
| </md-list-item> | ||
| </md-list> | ||
| `; | ||
| return builder.overrideTemplate(TestList, template) | ||
| .createAsync(TestList).then((fixture) => { | ||
| fixture.detectChanges(); | ||
| let listItems = fixture.debugElement.children[0].queryAll(By.css('md-list-item')); | ||
| expect(listItems[0].nativeElement.className).toBe('md-2-line'); | ||
| expect(listItems[1].nativeElement.className).toBe('md-2-line'); | ||
| done(); | ||
| }); | ||
| }); | ||
|
|
||
| it('should apply md-3-line class to lists with three lines', (done: () => void) => { | ||
| var template = ` | ||
| <md-list> | ||
| <md-list-item *ngFor="#item of items"> | ||
| <h3 md-line>{{item.name}}</h3> | ||
| <p md-line>{{item.description}}</p> | ||
| <p md-line>Some other text</p> | ||
| </md-list-item> | ||
| </md-list> | ||
| `; | ||
| return builder.overrideTemplate(TestList, template) | ||
| .createAsync(TestList).then((fixture) => { | ||
| fixture.detectChanges(); | ||
| let listItems = fixture.debugElement.children[0].queryAll(By.css('md-list-item')); | ||
| expect(listItems[0].nativeElement.className).toBe('md-3-line'); | ||
| expect(listItems[1].nativeElement.className).toBe('md-3-line'); | ||
| done(); | ||
| }); | ||
| }); | ||
|
|
||
| it('should apply md-list-avatar class to list items with avatars', (done: () => void) => { | ||
| var template = ` | ||
| <md-list> | ||
| <md-list-item> | ||
| <img src="" md-list-avatar> | ||
| Paprika | ||
| </md-list-item> | ||
| <md-list-item> | ||
| Pepper | ||
| </md-list-item> | ||
| </md-list> | ||
| `; | ||
| return builder.overrideTemplate(TestList, template) | ||
| .createAsync(TestList).then((fixture) => { | ||
| fixture.detectChanges(); | ||
| let listItems = fixture.debugElement.children[0].queryAll(By.css('md-list-item')); | ||
| expect(listItems[0].nativeElement.className).toBe('md-list-avatar'); | ||
| expect(listItems[1].nativeElement.className).toBe(''); | ||
| done(); | ||
| }); | ||
| }); | ||
|
|
||
| it('should not clear custom classes provided by user', (done: () => void) => { | ||
| var template = ` | ||
| <md-list> | ||
| <md-list-item class="test-class" *ngFor="#item of items"> | ||
| <h3 md-line>{{item.name}}</h3> | ||
| <p md-line>{{item.description}}</p> | ||
| </md-list-item> | ||
| </md-list> | ||
| `; | ||
| return builder.overrideTemplate(TestList, template) | ||
| .createAsync(TestList).then((fixture) => { | ||
| fixture.detectChanges(); | ||
| let listItems = fixture.debugElement.children[0].queryAll(By.css('md-list-item')); | ||
| expect(listItems[0].nativeElement.classList.contains('test-class')).toBe(true); | ||
| done(); | ||
| }); | ||
| }); | ||
|
|
||
| it('should update classes if number of lines change', (done: () => void) => { | ||
| var template = ` | ||
| <md-list> | ||
| <md-list-item *ngFor="#item of items"> | ||
| <h3 md-line>{{item.name}}</h3> | ||
| <p md-line>{{item.description}}</p> | ||
| <p md-line *ngIf="showThirdLine">Some other text</p> | ||
| </md-list-item> | ||
| </md-list> | ||
| `; | ||
| return builder.overrideTemplate(TestList, template) | ||
| .createAsync(TestList).then((fixture) => { | ||
| fixture.debugElement.componentInstance.showThirdLine = false; | ||
| fixture.detectChanges(); | ||
| let listItem = fixture.debugElement.children[0].query(By.css('md-list-item')); | ||
| expect(listItem.nativeElement.className).toBe('md-2-line'); | ||
|
|
||
| fixture.debugElement.componentInstance.showThirdLine = true; | ||
| fixture.detectChanges(); | ||
| setTimeout(() => { | ||
| expect(listItem.nativeElement.className).toBe('md-3-line'); | ||
| done(); | ||
| }); | ||
| }); | ||
| }); | ||
|
|
||
| it('should add aria roles properly', (done: () => void) => { | ||
| var template = ` | ||
| <md-list> | ||
| <md-list-item *ngFor="#item of items"> | ||
| {{item.name}} | ||
| </md-list-item> | ||
| </md-list> | ||
| `; | ||
| return builder.overrideTemplate(TestList, template) | ||
| .createAsync(TestList).then((fixture) => { | ||
| fixture.detectChanges(); | ||
| let list = fixture.debugElement.children[0]; | ||
| let listItem = fixture.debugElement.children[0].query(By.css('md-list-item')); | ||
| expect(list.nativeElement.getAttribute('role')).toBe('list'); | ||
| expect(listItem.nativeElement.getAttribute('role')).toBe('listitem'); | ||
| done(); | ||
| }); | ||
| }); | ||
|
|
||
| }); | ||
| } | ||
|
|
||
| @Component({ | ||
| selector: 'test-list', | ||
| template: ``, | ||
| directives: [MD_LIST_DIRECTIVES] | ||
| }) | ||
| class TestList { | ||
| items: any[] = [ | ||
| {'name': 'Paprika', 'description': 'A seasoning'}, | ||
| {'name': 'Pepper', 'description': 'Another seasoning'} | ||
| ]; | ||
| showThirdLine: boolean = false; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note: Added at Rob's request to help travis pass.