From 7f9d0dd665f4d6397628e38e5b21a02111d69651 Mon Sep 17 00:00:00 2001 From: Yuan Gao Date: Tue, 8 Aug 2017 17:43:33 -0700 Subject: [PATCH 1/5] demo(list): Add accessibility demo page for list --- src/demo-app/a11y/a11y-module.ts | 2 + src/demo-app/a11y/a11y.ts | 1 + src/demo-app/a11y/list/list-a11y.html | 66 +++++++++++++++++++++++++++ src/demo-app/a11y/list/list-a11y.scss | 11 +++++ src/demo-app/a11y/list/list-a11y.ts | 55 ++++++++++++++++++++++ src/demo-app/a11y/routes.ts | 2 + src/lib/list/list.md | 9 ++++ src/lib/list/list.ts | 47 ++++++++++--------- 8 files changed, 171 insertions(+), 22 deletions(-) create mode 100644 src/demo-app/a11y/list/list-a11y.html create mode 100644 src/demo-app/a11y/list/list-a11y.scss create mode 100644 src/demo-app/a11y/list/list-a11y.ts diff --git a/src/demo-app/a11y/a11y-module.ts b/src/demo-app/a11y/a11y-module.ts index b27f2c0f89e6..9911341393ea 100644 --- a/src/demo-app/a11y/a11y-module.ts +++ b/src/demo-app/a11y/a11y-module.ts @@ -29,6 +29,7 @@ import { } from './dialog/dialog-a11y'; import {ExpansionPanelAccessibilityDemo} from './expansion/expansion-a11y'; import {GridListAccessibilityDemo} from './grid-list/grid-list-a11y'; +import {ListAccessibilityDemo} from './list/list-a11y'; import {RadioAccessibilityDemo} from './radio/radio-a11y'; import {ToolbarAccessibilityDemo} from './toolbar/toolbar-a11y'; import {DatepickerAccessibilityDemo} from './datepicker/datepicker-a11y'; @@ -93,6 +94,7 @@ export class AccessibilityRoutingModule {} GridListAccessibilityDemo, IconAccessibilityDemo, InputAccessibilityDemo, + ListAccessibilityDemo, MenuAccessibilityDemo, ProgressBarAccessibilityDemo, ProgressSpinnerAccessibilityDemo, diff --git a/src/demo-app/a11y/a11y.ts b/src/demo-app/a11y/a11y.ts index 3ac3cd80d39d..9db5dda65aa7 100644 --- a/src/demo-app/a11y/a11y.ts +++ b/src/demo-app/a11y/a11y.ts @@ -49,6 +49,7 @@ export class AccessibilityDemo implements OnDestroy { {name: 'Grid list', route: 'grid-list'}, {name: 'Icon', route: 'icon'}, {name: 'Input', route: 'input'}, + {name: 'List', route: 'list'}, {name: 'Menu', route: 'menu'}, {name: 'Progress bar', route: 'progress-bar'}, {name: 'Progress spinner', route: 'progress-spinner'}, diff --git a/src/demo-app/a11y/list/list-a11y.html b/src/demo-app/a11y/list/list-a11y.html new file mode 100644 index 000000000000..b8de2d5c405d --- /dev/null +++ b/src/demo-app/a11y/list/list-a11y.html @@ -0,0 +1,66 @@ +
+
+

Seasoning

+

Showing a non-interactive list of seasonings.

+ + {{item}} + +
+ + +
+

Mailbox navigation

+

Showing a navigation list with links to google search

+ + + {{link.name}} + + +
+ +
+

Messages

+

+ Showing a list of messages, where each message item has sender's name, sender's avatar, + message subject, and content of the message. +

+ + + +

{{message.from}}

+

{{message.subject}}

+

{{message.message}}

+
+
+ +
+ +
+

Seasoning

+

Showing a non-interactive list of seasonings with dense style.

+ + {{item}} + +
+ +
+

Folders and notes for mailbox

+

Showing a list with two sections, "folders" and "notes".

+ +

Folders

+ + folder +

{{folder.name}}

+

{{folder.updated}}

+
+ +

Notes

+ + note +

{{note.name}}

+

{{note.updated}}

+
+
+
+
diff --git a/src/demo-app/a11y/list/list-a11y.scss b/src/demo-app/a11y/list/list-a11y.scss new file mode 100644 index 000000000000..1d270debe13d --- /dev/null +++ b/src/demo-app/a11y/list/list-a11y.scss @@ -0,0 +1,11 @@ +.demo-list { + .mat-list, .mat-nav-list { + border: 1px solid rgba(0, 0, 0, 0.12); + max-width: 350px; + margin: 20px 20px 0 0; + } + + .demo-secondary-text { + color: rgba(0, 0, 0, 0.54); + } +} diff --git a/src/demo-app/a11y/list/list-a11y.ts b/src/demo-app/a11y/list/list-a11y.ts new file mode 100644 index 000000000000..0d782da7b39d --- /dev/null +++ b/src/demo-app/a11y/list/list-a11y.ts @@ -0,0 +1,55 @@ +import {Component} from '@angular/core'; + +@Component({ + moduleId: module.id, + selector: 'list-a11y', + templateUrl: 'list-a11y.html', + styleUrls: ['list-a11y.css'] +}) +export class ListAccessibilityDemo { + items: string[] = [ + 'Pepper', + 'Salt', + 'Paprika' + ]; + + messages = [ + { + from: 'Nancy', + subject: 'Brunch?', + message: 'Did you want to go on Sunday? I was thinking that might work.', + image: 'https://angular.io/generated/images/bios/julie-ralph.jpg' + }, + { + from: 'Mary', + subject: 'Summer BBQ', + message: 'Wish I could come, but I have some prior obligations.', + image: 'https://angular.io/generated/images/bios/juleskremer.jpg' + }, + { + from: 'Bobby', + subject: 'Oui oui', + message: 'Do you have Paris reservations for the 15th? I just booked!', + image: 'https://angular.io/generated/images/bios/jelbourn.jpg' + } + ]; + + links = [ + {name: 'Inbox'}, + {name: 'Outbox'}, + {name: 'Spam'}, + {name: 'Trash'} + + ]; + + folders = [ + {name: 'Imported', updated: 'Miles'}, + {name: 'Important', updated: 'Tina'}, + {name: 'Unread', updated: 'Jeremy'}, + ]; + + notes = [ + {name: 'Update screenshots', updated: 'Kara'}, + {name: 'Install new application', updated: 'Andrew'}, + ]; +} diff --git a/src/demo-app/a11y/routes.ts b/src/demo-app/a11y/routes.ts index 6d729336e2c5..8ce0372611af 100644 --- a/src/demo-app/a11y/routes.ts +++ b/src/demo-app/a11y/routes.ts @@ -22,6 +22,7 @@ import {ToolbarAccessibilityDemo} from './toolbar/toolbar-a11y'; import {DatepickerAccessibilityDemo} from './datepicker/datepicker-a11y'; import {IconAccessibilityDemo} from './icon/icon-a11y'; import {InputAccessibilityDemo} from './input/input-a11y'; +import {ListAccessibilityDemo} from './list/list-a11y'; import {MenuAccessibilityDemo} from './menu/menu-a11y'; import {ProgressBarAccessibilityDemo} from './progress-bar/progress-bar-a11y'; import {ProgressSpinnerAccessibilityDemo} from './progress-spinner/progress-spinner-a11y'; @@ -52,6 +53,7 @@ export const ACCESSIBILITY_DEMO_ROUTES: Routes = [ {path: 'grid-list', component: GridListAccessibilityDemo}, {path: 'icon', component: IconAccessibilityDemo}, {path: 'input', component: InputAccessibilityDemo}, + {path: 'list', component: ListAccessibilityDemo}, {path: 'menu', component: MenuAccessibilityDemo}, {path: 'progress-bar', component: ProgressBarAccessibilityDemo}, {path: 'progress-spinner', component: ProgressSpinnerAccessibilityDemo}, diff --git a/src/lib/list/list.md b/src/lib/list/list.md index b26595f5becf..43d5786bf6fc 100644 --- a/src/lib/list/list.md +++ b/src/lib/list/list.md @@ -150,3 +150,12 @@ To add a divider, use ``. ``` + +### Accessibility +By default, the list assumes that it will be used in a purely decorative fashion and thus sets no +roles, ARIA attributes, or keyboard shortcuts. This is equivalent to having a sequence of
+elements on the page. Any interactive content within the list should be given an appropriate +accessibility treatment based on the specific workflow of your application. + +If the list is used to present a list of non-interactive content items, then the list element should +be given `role="list"` and each list item should be given `role="listitem"`. diff --git a/src/lib/list/list.ts b/src/lib/list/list.ts index 6cd9efcd0f9a..d3a394e20007 100644 --- a/src/lib/list/list.ts +++ b/src/lib/list/list.ts @@ -44,9 +44,12 @@ export class MatListDivider {} /** A Material Design list component. */ @Component({ moduleId: module.id, - selector: 'mat-list, mat-nav-list', - exportAs: 'matList, matNavList', - host: {'role': 'list'}, + selector: 'mat-nav-list', + exportAs: 'matNavList', + host: { + 'role': 'navigation', + 'class': 'mat-nav-list' + }, template: '', styleUrls: ['list.css'], inputs: ['disableRipple'], @@ -54,27 +57,20 @@ export class MatListDivider {} preserveWhitespaces: false, changeDetection: ChangeDetectionStrategy.OnPush, }) -export class MatList extends _MatListMixinBase implements CanDisableRipple {} +export class MatNavList extends _MatListMixinBase implements CanDisableRipple {} -/** - * Directive whose purpose is to add the mat- CSS styling to this selector. - * @docs-private - */ -@Directive({ +@Component({ + moduleId: module.id, selector: 'mat-list', - host: {'class': 'mat-list'} -}) -export class MatListCssMatStyler {} - -/** - * Directive whose purpose is to add the mat- CSS styling to this selector. - * @docs-private - */ -@Directive({ - selector: 'mat-nav-list', - host: {'class': 'mat-nav-list'} + exportAs: 'matList', + template: '', + host: {'class': 'mat-list'}, + styleUrls: ['list.css'], + inputs: ['disableRipple'], + encapsulation: ViewEncapsulation.None, + changeDetection: ChangeDetectionStrategy.OnPush, }) -export class MatNavListCssMatStyler {} +export class MatList extends _MatListMixinBase implements CanDisableRipple {} /** * Directive whose purpose is to add the mat- CSS styling to this selector. @@ -149,11 +145,18 @@ export class MatListItem extends _MatListItemMixinBase implements AfterContentIn } } +<<<<<<< HEAD constructor(private _element: ElementRef, @Optional() private _list: MatList, @Optional() navList: MatNavListCssMatStyler) { +======= + constructor(private _renderer: Renderer2, + private _element: ElementRef, + @Optional() private _list: MdList, + @Optional() private _navList: MdNavList) { +>>>>>>> demo(list): Add accessibility demo page for list super(); - this._isNavList = !!navList; + this._isNavList = !!_navList; } ngAfterContentInit() { From 7eb534c49d51da7fe5adef3a0d7f5f8fa16d5716 Mon Sep 17 00:00:00 2001 From: Yuan Gao Date: Mon, 21 Aug 2017 13:56:28 -0700 Subject: [PATCH 2/5] fix test --- src/lib/list/list.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/list/list.spec.ts b/src/lib/list/list.spec.ts index f2b60c500aef..b7644f7e247c 100644 --- a/src/lib/list/list.spec.ts +++ b/src/lib/list/list.spec.ts @@ -115,7 +115,7 @@ describe('MatList', () => { let list = fixture.debugElement.children[0]; let listItem = fixture.debugElement.children[0].query(By.css('mat-list-item')); - expect(list.nativeElement.getAttribute('role')).toBe('list'); + expect(list.nativeElement.getAttribute('role')).toBeNull(); expect(listItem.nativeElement.getAttribute('role')).toBe('listitem'); }); From 7b5cdf2467f00d96c6902d71e32011d3a96ddddb Mon Sep 17 00:00:00 2001 From: Yuan Gao Date: Mon, 21 Aug 2017 17:02:04 -0700 Subject: [PATCH 3/5] set default role for md-list --- src/material-examples/list-overview/list-overview-example.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/material-examples/list-overview/list-overview-example.html b/src/material-examples/list-overview/list-overview-example.html index 4c59db7aa84e..9c416b76f0d3 100644 --- a/src/material-examples/list-overview/list-overview-example.html +++ b/src/material-examples/list-overview/list-overview-example.html @@ -1,4 +1,4 @@ - + Item 1 Item 2 Item 3 From 5131a7985dcab60b1c96c96d2317f21fb5a6e04d Mon Sep 17 00:00:00 2001 From: Yuan Gao Date: Tue, 5 Sep 2017 15:05:44 -0700 Subject: [PATCH 4/5] fix test --- src/lib/list/list.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/lib/list/list.ts b/src/lib/list/list.ts index d3a394e20007..d05799e620db 100644 --- a/src/lib/list/list.ts +++ b/src/lib/list/list.ts @@ -152,7 +152,6 @@ export class MatListItem extends _MatListItemMixinBase implements AfterContentIn ======= constructor(private _renderer: Renderer2, private _element: ElementRef, - @Optional() private _list: MdList, @Optional() private _navList: MdNavList) { >>>>>>> demo(list): Add accessibility demo page for list super(); @@ -165,7 +164,7 @@ export class MatListItem extends _MatListItemMixinBase implements AfterContentIn /** Whether this list item should show a ripple effect when clicked. */ _isRippleDisabled() { - return !this._isNavList || this.disableRipple || this._list.disableRipple; + return !this._isNavList || this.disableRipple || this._navList.disableRipple; } _handleFocus() { From 6cddd418629196ccb973dfb87782c186da996661 Mon Sep 17 00:00:00 2001 From: Yuan Gao Date: Tue, 12 Sep 2017 12:38:04 -0700 Subject: [PATCH 5/5] Add template file for list --- src/demo-app/a11y/list/list-a11y.html | 64 +++++++++++++-------------- src/demo-app/a11y/list/list-a11y.ts | 8 ++++ src/lib/list/list-module.ts | 9 ++-- src/lib/list/list.html | 2 + src/lib/list/list.ts | 14 ++---- 5 files changed, 49 insertions(+), 48 deletions(-) create mode 100644 src/lib/list/list.html diff --git a/src/demo-app/a11y/list/list-a11y.html b/src/demo-app/a11y/list/list-a11y.html index b8de2d5c405d..70eea8b8410b 100644 --- a/src/demo-app/a11y/list/list-a11y.html +++ b/src/demo-app/a11y/list/list-a11y.html @@ -2,21 +2,21 @@

Seasoning

Showing a non-interactive list of seasonings.

- - {{item}} - + + {{item}} +

Mailbox navigation

Showing a navigation list with links to google search

- - + {{link.name}} - +
@@ -25,42 +25,42 @@

Messages

Showing a list of messages, where each message item has sender's name, sender's avatar, message subject, and content of the message.

- - - -

{{message.from}}

-

{{message.subject}}

-

{{message.message}}

-
-
+ + + +

{{message.from}}

+

{{message.subject}}

+

{{message.message}}

+
+

Seasoning

Showing a non-interactive list of seasonings with dense style.

- - {{item}} - + + {{item}} +

Folders and notes for mailbox

Showing a list with two sections, "folders" and "notes".

- -

Folders

- - folder -

{{folder.name}}

-

{{folder.updated}}

-
- -

Notes

- - note -

{{note.name}}

-

{{note.updated}}

-
-
+ +

Folders

+ + folder +

{{folder.name}}

+

{{folder.updated}}

+
+ +

Notes

+ + note +

{{note.name}}

+

{{note.updated}}

+
+
diff --git a/src/demo-app/a11y/list/list-a11y.ts b/src/demo-app/a11y/list/list-a11y.ts index 0d782da7b39d..3a033d24cb58 100644 --- a/src/demo-app/a11y/list/list-a11y.ts +++ b/src/demo-app/a11y/list/list-a11y.ts @@ -1,3 +1,11 @@ +/** + * @license + * Copyright Google LLC All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.io/license + */ + import {Component} from '@angular/core'; @Component({ diff --git a/src/lib/list/list-module.ts b/src/lib/list/list-module.ts index dea04202fd89..d29e01c1b0e7 100644 --- a/src/lib/list/list-module.ts +++ b/src/lib/list/list-module.ts @@ -17,13 +17,12 @@ import { import { MatDividerCssMatStyler, MatList, + MatNavList, MatListAvatarCssMatStyler, - MatListCssMatStyler, MatListDivider, MatListIconCssMatStyler, MatListItem, MatListSubheaderCssMatStyler, - MatNavListCssMatStyler, } from './list'; import {MatListOption, MatSelectionList} from './selection-list'; @@ -32,14 +31,13 @@ import {MatListOption, MatSelectionList} from './selection-list'; imports: [MatLineModule, MatRippleModule, MatCommonModule, MatPseudoCheckboxModule, CommonModule], exports: [ MatList, + MatNavList, MatListItem, MatListDivider, MatListAvatarCssMatStyler, MatLineModule, MatCommonModule, MatListIconCssMatStyler, - MatListCssMatStyler, - MatNavListCssMatStyler, MatDividerCssMatStyler, MatListSubheaderCssMatStyler, MatPseudoCheckboxModule, @@ -48,12 +46,11 @@ import {MatListOption, MatSelectionList} from './selection-list'; ], declarations: [ MatList, + MatNavList, MatListItem, MatListDivider, MatListAvatarCssMatStyler, MatListIconCssMatStyler, - MatListCssMatStyler, - MatNavListCssMatStyler, MatDividerCssMatStyler, MatListSubheaderCssMatStyler, MatSelectionList, diff --git a/src/lib/list/list.html b/src/lib/list/list.html new file mode 100644 index 000000000000..9af43669be38 --- /dev/null +++ b/src/lib/list/list.html @@ -0,0 +1,2 @@ + + diff --git a/src/lib/list/list.ts b/src/lib/list/list.ts index d05799e620db..ab278121609d 100644 --- a/src/lib/list/list.ts +++ b/src/lib/list/list.ts @@ -50,7 +50,7 @@ export class MatListDivider {} 'role': 'navigation', 'class': 'mat-nav-list' }, - template: '', + templateUrl: 'list.html', styleUrls: ['list.css'], inputs: ['disableRipple'], encapsulation: ViewEncapsulation.None, @@ -63,11 +63,12 @@ export class MatNavList extends _MatListMixinBase implements CanDisableRipple {} moduleId: module.id, selector: 'mat-list', exportAs: 'matList', - template: '', + templateUrl: 'list.html', host: {'class': 'mat-list'}, styleUrls: ['list.css'], inputs: ['disableRipple'], encapsulation: ViewEncapsulation.None, + preserveWhitespaces: false, changeDetection: ChangeDetectionStrategy.OnPush, }) export class MatList extends _MatListMixinBase implements CanDisableRipple {} @@ -145,15 +146,8 @@ export class MatListItem extends _MatListItemMixinBase implements AfterContentIn } } -<<<<<<< HEAD constructor(private _element: ElementRef, - @Optional() private _list: MatList, - @Optional() navList: MatNavListCssMatStyler) { -======= - constructor(private _renderer: Renderer2, - private _element: ElementRef, - @Optional() private _navList: MdNavList) { ->>>>>>> demo(list): Add accessibility demo page for list + @Optional() private _navList: MatNavList) { super(); this._isNavList = !!_navList; }