From 7f7a20ccba47d6bd12ae94a27f928e01ae6bd7aa Mon Sep 17 00:00:00 2001 From: "BLACKBAUD\\Trevor.Burch" Date: Tue, 4 Sep 2018 15:02:45 -0400 Subject: [PATCH 1/3] Added a11y attributes for text expand --- .../fixtures/text-expand.component.fixture.ts | 7 +- .../text-expand/text-expand.component.html | 12 ++- .../text-expand/text-expand.component.spec.ts | 89 ++++++++++++------- .../text-expand/text-expand.component.ts | 7 ++ 4 files changed, 78 insertions(+), 37 deletions(-) diff --git a/src/modules/text-expand/fixtures/text-expand.component.fixture.ts b/src/modules/text-expand/fixtures/text-expand.component.fixture.ts index a8fc01981..14539ed17 100644 --- a/src/modules/text-expand/fixtures/text-expand.component.fixture.ts +++ b/src/modules/text-expand/fixtures/text-expand.component.fixture.ts @@ -1,11 +1,14 @@ -import { Component } from '@angular/core'; +import { Component, ViewChild } from '@angular/core'; +import { SkyTextExpandComponent } from '../text-expand.component'; @Component({ selector: 'sky-text-expand-demo', templateUrl: './text-expand.component.fixture.html' }) export class TextExpandTestComponent { - // tslint:disable-next-line + + @ViewChild(SkyTextExpandComponent) + public textExpand: SkyTextExpandComponent; public text: string; public maxLength: number; public truncateNewlines: boolean = true; diff --git a/src/modules/text-expand/text-expand.component.html b/src/modules/text-expand/text-expand.component.html index fdddbf07a..94d7a7470 100644 --- a/src/modules/text-expand/text-expand.component.html +++ b/src/modules/text-expand/text-expand.component.html @@ -2,7 +2,15 @@ class="sky-text-expand-container" (transitionend)="animationEnd()" #container> - + ... - + diff --git a/src/modules/text-expand/text-expand.component.spec.ts b/src/modules/text-expand/text-expand.component.spec.ts index 0b9c165cf..ef629bcfe 100644 --- a/src/modules/text-expand/text-expand.component.spec.ts +++ b/src/modules/text-expand/text-expand.component.spec.ts @@ -1,7 +1,8 @@ import { TestBed, inject, - async + fakeAsync, + tick } from '@angular/core/testing'; import { BrowserModule } from '@angular/platform-browser'; @@ -63,6 +64,31 @@ describe('Text expand component', () => { ); describe('basic behaviors', () => { + + it('should have necessary aria properties', fakeAsync(() => { + let fixture = TestBed.createComponent(TextExpandTestComponent); + let cmp = fixture.componentInstance as TextExpandTestComponent; + let el = fixture.nativeElement as HTMLElement; + + // tslint:disable-next-line + cmp.text = 'Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. Donec.'; + + fixture.detectChanges(); + const buttonElem = el.querySelector('.sky-text-expand-see-more'); + + expect(buttonElem.getAttribute('aria-expanded')).toBe('false'); + expect(buttonElem.getAttribute('aria-controls')).toBe(cmp.textExpand.contentSectionId); + + buttonElem.click(); + fixture.detectChanges(); + tick(20); + fixture.detectChanges(); + tick(500); + fixture.detectChanges(); + + expect(buttonElem.getAttribute('aria-expanded')).toBe('true'); + })); + it('should not have see more button or ellipsis if text is short', () => { let fixture = TestBed.createComponent(TextExpandTestComponent); let cmp = fixture.componentInstance as TextExpandTestComponent; @@ -231,7 +257,7 @@ describe('Text expand component', () => { expect(seeMoreButton.innerText.trim()).toBe(SkyResources.getString('text_expand_see_more')); }); - it('should expand on click of the see more button', async(() => { + it('should expand on click of the see more button', fakeAsync(() => { let fixture = TestBed.createComponent(TextExpandTestComponent); let cmp = fixture.componentInstance as TextExpandTestComponent; let el = fixture.nativeElement as HTMLElement; @@ -253,37 +279,34 @@ describe('Text expand component', () => { seeMoreButton.click(); fixture.detectChanges(); - fixture.whenStable().then(() => { - fixture.detectChanges(); - fixture.whenStable().then(() => { - fixture.detectChanges(); - ellipsis = el.querySelector('.sky-text-expand-ellipsis'); - textArea = el.querySelector('.sky-text-expand-text'); - - expect(container.style.maxHeight).toBe(''); - expect(seeMoreButton.innerText.trim()) - .toBe(SkyResources.getString('text_expand_see_less')); - expect(ellipsis).toBeNull(); - expect(textArea.innerText.trim()).toBe(expandedText); - seeMoreButton.click(); - fixture.detectChanges(); - fixture.whenStable().then(() => { - fixture.detectChanges(); - fixture.whenStable().then(() => { - fixture.detectChanges(); - ellipsis = el.querySelector('.sky-text-expand-ellipsis'); - textArea = el.querySelector('.sky-text-expand-text'); - - expect(container.style.maxHeight).toBe(''); - expect(seeMoreButton.innerText.trim()) - .toBe(SkyResources.getString('text_expand_see_more')); - expect(ellipsis).not.toBeNull(); - expect(textArea.innerText.trim()).toBe(collapsedText); - }); - }); - }); - }); - }), 300000); + tick(20); + fixture.detectChanges(); + tick(500); + fixture.detectChanges(); + ellipsis = el.querySelector('.sky-text-expand-ellipsis'); + textArea = el.querySelector('.sky-text-expand-text'); + + expect(container.style.maxHeight).toBe(''); + expect(seeMoreButton.innerText.trim()) + .toBe(SkyResources.getString('text_expand_see_less')); + expect(ellipsis).toBeNull(); + expect(textArea.innerText.trim()).toBe(expandedText); + seeMoreButton.click(); + fixture.detectChanges(); + tick(20); + fixture.detectChanges(); + tick(500); + fixture.detectChanges(); + ellipsis = el.querySelector('.sky-text-expand-ellipsis'); + textArea = el.querySelector('.sky-text-expand-text'); + + expect(container.style.maxHeight).toBe(''); + expect(seeMoreButton.innerText.trim()) + .toBe(SkyResources.getString('text_expand_see_more')); + expect(ellipsis).not.toBeNull(); + expect(textArea.innerText.trim()).toBe(collapsedText); + + })); it('should render newlines if requested', () => { let fixture = TestBed.createComponent(TextExpandTestComponent); diff --git a/src/modules/text-expand/text-expand.component.ts b/src/modules/text-expand/text-expand.component.ts index 1b8cb8246..fb6b2ae9f 100644 --- a/src/modules/text-expand/text-expand.component.ts +++ b/src/modules/text-expand/text-expand.component.ts @@ -22,6 +22,11 @@ import { SkyTextExpandAdapterService } from './text-expand-adapter.service'; +/** + * Auto-incrementing integer used to generate unique ids for checkbox components. + */ +let nextId = 0; + @Component({ selector: 'sky-text-expand', templateUrl: './text-expand.component.html', @@ -61,6 +66,8 @@ export class SkyTextExpandComponent implements AfterContentInit { public isExpanded: boolean = false; public expandable: boolean; public buttonText: string; + public contentSectionId: string = `sky-text-expand-content-${++nextId}`; + private seeMoreText: string = this.resources.getString('text_expand_see_more'); private seeLessText: string = this.resources.getString('text_expand_see_less'); private textToShow: string; From 4024fcfbb4b6439f09a5699fbcaaef7db2f133bf Mon Sep 17 00:00:00 2001 From: "BLACKBAUD\\Trevor.Burch" Date: Wed, 5 Sep 2018 12:22:37 -0400 Subject: [PATCH 2/3] Added modal version of a11y and added a11y for text expand repeater --- .../text-expand-repeater.component.fixture.ts | 5 +++- .../text-expand-repeater.component.html | 10 +++++-- .../text-expand-repeater.component.spec.ts | 29 ++++++++++++++++++- .../text-expand-repeater.component.ts | 7 +++++ .../text-expand/text-expand.component.html | 5 ++-- .../text-expand/text-expand.component.spec.ts | 11 +++++++ .../text-expand/text-expand.component.ts | 6 ++-- 7 files changed, 65 insertions(+), 8 deletions(-) diff --git a/src/modules/text-expand-repeater/fixtures/text-expand-repeater.component.fixture.ts b/src/modules/text-expand-repeater/fixtures/text-expand-repeater.component.fixture.ts index d8f18dd9f..05c1ec4d0 100644 --- a/src/modules/text-expand-repeater/fixtures/text-expand-repeater.component.fixture.ts +++ b/src/modules/text-expand-repeater/fixtures/text-expand-repeater.component.fixture.ts @@ -1,10 +1,13 @@ -import { Component } from '@angular/core'; +import { Component, ViewChild } from '@angular/core'; +import { SkyTextExpandRepeaterComponent } from '../text-expand-repeater.component'; @Component({ selector: 'sky-text-expand-repeater-demo', templateUrl: './text-expand-repeater.component.fixture.html' }) export class TextExpandRepeaterTestComponent { + @ViewChild(SkyTextExpandRepeaterComponent) + public textExpand: SkyTextExpandRepeaterComponent; public data: string[]; public numItems: number; } diff --git a/src/modules/text-expand-repeater/text-expand-repeater.component.html b/src/modules/text-expand-repeater/text-expand-repeater.component.html index 3a1971d1f..4059fd114 100644 --- a/src/modules/text-expand-repeater/text-expand-repeater.component.html +++ b/src/modules/text-expand-repeater/text-expand-repeater.component.html @@ -1,10 +1,16 @@
-
    +
    • {{item}}
    -
diff --git a/src/modules/text-expand-repeater/text-expand-repeater.component.spec.ts b/src/modules/text-expand-repeater/text-expand-repeater.component.spec.ts index a7bedc240..968bcd9d5 100644 --- a/src/modules/text-expand-repeater/text-expand-repeater.component.spec.ts +++ b/src/modules/text-expand-repeater/text-expand-repeater.component.spec.ts @@ -1,6 +1,8 @@ import { TestBed, - async + async, + fakeAsync, + tick } from '@angular/core/testing'; import { BrowserModule } from '@angular/platform-browser'; @@ -24,6 +26,31 @@ describe('Text expand repeater component', () => { }); describe('basic behaviors', () => { + it('should have necessary aria properties', fakeAsync(() => { + let fixture = TestBed.createComponent(TextExpandRepeaterTestComponent); + let cmp = fixture.componentInstance as TextExpandRepeaterTestComponent; + let el = fixture.nativeElement as HTMLElement; + + cmp.data = ['john', 'bob', 'hank']; + cmp.numItems = 2; + + fixture.detectChanges(); + const buttonElem = el.querySelector('.sky-text-expand-repeater-see-more'); + + expect(buttonElem.getAttribute('aria-expanded')).toBe('false'); + expect(buttonElem.getAttribute('aria-controls')).toBe(cmp.textExpand.contentSectionId); + + buttonElem.click(); + fixture.detectChanges(); + tick(20); + fixture.detectChanges(); + tick(500); + fixture.detectChanges(); + + expect(buttonElem.getAttribute('aria-expanded')).toBe('true'); + expect(buttonElem.getAttribute('aria-controls')).toBe(cmp.textExpand.contentSectionId); + })); + it('should not have see more button if data is less than or equal to max items', () => { let fixture = TestBed.createComponent(TextExpandRepeaterTestComponent); let cmp = fixture.componentInstance as TextExpandRepeaterTestComponent; diff --git a/src/modules/text-expand-repeater/text-expand-repeater.component.ts b/src/modules/text-expand-repeater/text-expand-repeater.component.ts index 43398129f..5fb2ead41 100644 --- a/src/modules/text-expand-repeater/text-expand-repeater.component.ts +++ b/src/modules/text-expand-repeater/text-expand-repeater.component.ts @@ -11,6 +11,12 @@ import { import { SkyResourcesService } from '../resources'; + +/** + * Auto-incrementing integer used to generate unique ids for checkbox components. + */ +let nextId = 0; + @Component({ selector: 'sky-text-expand-repeater', templateUrl: './text-expand-repeater.component.html', @@ -30,6 +36,7 @@ export class SkyTextExpandRepeaterComponent implements AfterViewInit { public buttonText: string; public contentItems: Array; public expandable: boolean; + public contentSectionId: string = `sky-text-expand-repeater-content-${++nextId}`; private seeMoreText: string = this.resources.getString('text_expand_see_more'); private seeLessText: string = this.resources.getString('text_expand_see_less'); diff --git a/src/modules/text-expand/text-expand.component.html b/src/modules/text-expand/text-expand.component.html index 94d7a7470..54b76bebf 100644 --- a/src/modules/text-expand/text-expand.component.html +++ b/src/modules/text-expand/text-expand.component.html @@ -7,8 +7,9 @@