From 1966f5afff9b8c59936e3b9f0044c420db73e06d Mon Sep 17 00:00:00 2001 From: svetoldo4444ka Date: Mon, 12 Mar 2018 15:30:39 +0200 Subject: [PATCH] add accessibility description sections --- cypress/integration/buttons_page_spec.ts | 95 +++++++++---------- .../getting-started.component.html | 35 +++++-- .../+carousel/carousel-section.list.ts | 6 ++ .../demos/accessibility/accessibility.html | 1 + .../demos/accessibility/accessibility.ts | 7 ++ .../app/components/+carousel/demos/index.ts | 4 +- .../+collapse/collapse-section.list.ts | 6 ++ .../demos/accessibility/accessibility.html | 3 + .../demos/accessibility/accessibility.ts | 7 ++ .../app/components/+collapse/demos/index.ts | 4 +- .../demos/accessibility/accessibility.html | 2 + .../demos/accessibility/accessibility.ts | 7 ++ .../app/components/+dropdown/demos/index.ts | 4 +- .../+dropdown/dropdown-section.list.ts | 7 ++ .../demos/accessibility/accessibility.html | 1 + .../demos/accessibility/accessibility.ts | 7 ++ demo/src/app/components/+modal/demos/index.ts | 4 +- .../components/+modal/modal-section.list.ts | 6 ++ .../demos/accessibility/accessibility.html | 1 + .../demos/accessibility/accessibility.ts | 7 ++ demo/src/app/components/+tabs/demos/index.ts | 5 +- .../app/components/+tabs/tabs-section.list.ts | 6 ++ 22 files changed, 164 insertions(+), 61 deletions(-) create mode 100644 demo/src/app/components/+carousel/demos/accessibility/accessibility.html create mode 100644 demo/src/app/components/+carousel/demos/accessibility/accessibility.ts create mode 100644 demo/src/app/components/+collapse/demos/accessibility/accessibility.html create mode 100644 demo/src/app/components/+collapse/demos/accessibility/accessibility.ts create mode 100644 demo/src/app/components/+dropdown/demos/accessibility/accessibility.html create mode 100644 demo/src/app/components/+dropdown/demos/accessibility/accessibility.ts create mode 100644 demo/src/app/components/+modal/demos/accessibility/accessibility.html create mode 100644 demo/src/app/components/+modal/demos/accessibility/accessibility.ts create mode 100644 demo/src/app/components/+tabs/demos/accessibility/accessibility.html create mode 100644 demo/src/app/components/+tabs/demos/accessibility/accessibility.ts diff --git a/cypress/integration/buttons_page_spec.ts b/cypress/integration/buttons_page_spec.ts index 3e029bae87..17f9415d29 100644 --- a/cypress/integration/buttons_page_spec.ts +++ b/cypress/integration/buttons_page_spec.ts @@ -66,68 +66,67 @@ describe('Buttons page test suite', () => { buttons.clickByText(buttonDemos[2], buttonNames[1]); buttons.clickByText(buttonDemos[2], buttonNames[2]); - it('checkbox example contains checkboxes, that can be checked or unchecked', () => { - buttons.clickByText(buttonDemos[1], buttonNames[0]); - buttons.clickByText(buttonDemos[1], buttonNames[1]); - - cy.get(buttonDemos[1]).children('.card-header').as('output') - .should('to.contain', `"${buttonOutput[0]}": true`); - cy.get('@output') - .should('to.contain', `"${buttonOutput[1]}": false`); - }); + it('checkbox example contains checkboxes, that can be checked or unchecked', () => { + buttons.clickByText(buttonDemos[1], buttonNames[0]); + buttons.clickByText(buttonDemos[1], buttonNames[1]); - it('checkbox example contains checkboxes, that can be checked or unchecked and reactive form', () => { - buttons.clickByText(buttonDemos[2], buttonNames[1]); - buttons.clickByText(buttonDemos[2], buttonNames[2]); + cy.get(buttonDemos[1]).children('.card-header').as('output') + .should('to.contain', `"${buttonOutput[0]}": true`); + cy.get('@output') + .should('to.contain', `"${buttonOutput[1]}": false`); + }); - cy.get(buttonDemos[2]).children('.card-header').as('output') - .should('to.contain', `"${buttonOutput[1]}": false`); - cy.get('@output') - .should('to.contain', `"${buttonOutput[2]}": true`); + it('checkbox example contains checkboxes, that can be checked or unchecked and reactive form', () => { + buttons.clickByText(buttonDemos[2], buttonNames[1]); + buttons.clickByText(buttonDemos[2], buttonNames[2]); - buttons.clickByText(buttonDemos[2], buttonNames[1]); - cy.get('@output') - .should('to.contain', `"${buttonOutput[1]}": true`); - }); + cy.get(buttonDemos[2]).children('.card-header').as('output') + .should('to.contain', `"${buttonOutput[1]}": false`); + cy.get('@output') + .should('to.contain', `"${buttonOutput[2]}": true`); - it('Radio and Uncheckable Radio example contains checkboxes and radioButtons', () => { - cy.get(buttonDemos[3]).as('radioUncheckRadio').find('.btn-group').as('allRadios').eq(0).as('radioBtnNgModel'); - cy.get('@allRadios').eq(1).as('radioBtn'); - cy.get('@allRadios').eq(2).as('uncheckableRadio'); + buttons.clickByText(buttonDemos[2], buttonNames[1]); + cy.get('@output') + .should('to.contain', `"${buttonOutput[1]}": true`); + }); - cy.get('@radioBtnNgModel').find('.btn').eq(0).click(); - cy.get('@radioUncheckRadio').children('.card-header').as('formOutput').should('to.contain', 'Left'); + it('Radio and Uncheckable Radio example contains checkboxes and radioButtons', () => { + cy.get(buttonDemos[3]).as('radioUncheckRadio').find('.btn-group').as('allRadios').eq(0).as('radioBtnNgModel'); + cy.get('@allRadios').eq(1).as('radioBtn'); + cy.get('@allRadios').eq(2).as('uncheckableRadio'); - cy.get('@radioBtn').find('.btn').eq(1).click(); - cy.get('@formOutput').should('to.contain', 'Middle'); + cy.get('@radioBtnNgModel').find('.btn').eq(0).click(); + cy.get('@radioUncheckRadio').children('.card-header').as('formOutput').should('to.contain', 'Left'); - cy.get('@uncheckableRadio').find('.btn').eq(2).click(); - cy.get('@formOutput').should('to.contain', 'Right'); + cy.get('@radioBtn').find('.btn').eq(1).click(); + cy.get('@formOutput').should('to.contain', 'Middle'); - cy.get('@uncheckableRadio').find('.btn').eq(2).click(); - cy.get('@formOutput').should('to.contain', 'null'); - }); + cy.get('@uncheckableRadio').find('.btn').eq(2).click(); + cy.get('@formOutput').should('to.contain', 'Right'); + + cy.get('@uncheckableRadio').find('.btn').eq(2).click(); + cy.get('@formOutput').should('to.contain', 'null'); + }); - it('radio example should dynamicly update reactive form', () => { - const val = ['A', 'B', 'C']; + it('radio example should dynamicly update reactive form', () => { + const val = ['A', 'B', 'C']; - cy.get(buttonDemos[4]).as('radioReactiveForms').find('label').as('radioBtn').each(($radioBtn, i) => { - cy.get('@radioBtn').eq(i).click(); + cy.get(buttonDemos[4]).as('radioReactiveForms').find('label').as('radioBtn').each(($radioBtn, i) => { + cy.get('@radioBtn').eq(i).click(); - cy.get('@radioReactiveForms').children('.card-header') - .should('to.contain', `"radio": "${val[i]}"`); - }); + cy.get('@radioReactiveForms').children('.card-header') + .should('to.contain', `"radio": "${val[i]}"`); }); + }); - it('disabled buttons examples contains button, that can be disabled', () => { - cy.get(buttonDemos[5]).as('disabledButton') - .should('to.have.descendants', '.btn-primary') - .and('to.have.descendants', '.btn-warning'); + it('disabled buttons examples contains button, that can be disabled', () => { + cy.get(buttonDemos[5]).as('disabledButton') + .should('to.have.descendants', '.btn-primary') + .and('to.have.descendants', '.btn-warning'); - buttons.clickByText(buttonDemos[5], 'Enable/Disable'); + buttons.clickByText(buttonDemos[5], 'Enable/Disable'); - cy.get('@disabledButton').contains('Button') - .should('not.to.be.enabled'); - }); + cy.get('@disabledButton').contains('Button') + .should('not.to.be.enabled'); }); }); diff --git a/demo/src/app/common/getting-started/getting-started.component.html b/demo/src/app/common/getting-started/getting-started.component.html index 39ebd97af5..ee174bc295 100644 --- a/demo/src/app/common/getting-started/getting-started.component.html +++ b/demo/src/app/common/getting-started/getting-started.component.html @@ -130,15 +130,34 @@

Credits

Accessibility

-

To make components accessible:

+ +

Overview and Limitations

+ +

The overall accessibility of any project built with ngx-bootstrap depends in large part on the author’s markup, additional styling, and scripting they’ve included. + However, provided that these have been implemented correctly, it should be perfectly possible to create websites and applications + that fulfill WCAG 2.0 (A/AA/AAA), + Section 508 and similar accessibility standards and requirements.

+ +

Interactive components

+ +

Interactive components—such as modal dialogs, dropdown menus and custom tooltips—are designed to work for touch, mouse and keyboard users. + Through the use of relevant WAI-ARIA + roles and attributes, these components should also be understandable and operable using assistive technologies (such as screen readers).

+

Authors need to include ARIA roles and attributes to more accurately convey the precise nature of their component.

+ +

Color contrast

+ +

Most colors that currently make up Bootstrap’s default palette—used throughout the framework for things such as button variations, alert variations, form validation indicators—lead to insufficient color contrast (below the recommended WCAG 2.0 color contrast ratio of 4.5:1) when used against a light background. Authors will need to manually modify/extend these default colors to ensure adequate color contrast ratios.

+ +

Additional resources

+ diff --git a/demo/src/app/components/+carousel/carousel-section.list.ts b/demo/src/app/components/+carousel/carousel-section.list.ts index 1adb504a68..460e191188 100644 --- a/demo/src/app/components/+carousel/carousel-section.list.ts +++ b/demo/src/app/components/+carousel/carousel-section.list.ts @@ -8,6 +8,7 @@ import { DemoCarouselIntervalComponent } from './demos/interval/interval'; import { DemoCarouselDisableIndicatorComponent } from './demos/disable-indicator/disable-indicator'; import { DemoCarouselDisableLoopingComponent } from './demos/disable-looping/disable-looping'; import { DemoCarouselSlideChangedEventComponent } from './demos/slide-changed-event/slide-changed-event'; +import { DemoAccessibilityComponent } from './demos/accessibility/accessibility'; import { ContentSection } from '../../docs/models/content-section.model'; import { DemoTopSectionComponent } from '../../docs/demo-section-components/demo-top-section/index'; @@ -103,6 +104,11 @@ export const demoComponentContent: ContentSection[] = [ component: require('!!raw-loader?lang=typescript!./demos/slide-changed-event/slide-changed-event.ts'), html: require('!!raw-loader?lang=markup!./demos/slide-changed-event/slide-changed-event.html'), outlet: DemoCarouselSlideChangedEventComponent + }, + { + title: 'Accessibility', + anchor: 'accessibility', + outlet: DemoAccessibilityComponent } ] }, diff --git a/demo/src/app/components/+carousel/demos/accessibility/accessibility.html b/demo/src/app/components/+carousel/demos/accessibility/accessibility.html new file mode 100644 index 0000000000..8e02305ca3 --- /dev/null +++ b/demo/src/app/components/+carousel/demos/accessibility/accessibility.html @@ -0,0 +1 @@ +

The alt attribute is meant to help users not miss any content, so make sure your text is helpful to anyone not seeing the image.

diff --git a/demo/src/app/components/+carousel/demos/accessibility/accessibility.ts b/demo/src/app/components/+carousel/demos/accessibility/accessibility.ts new file mode 100644 index 0000000000..8cc0725c7c --- /dev/null +++ b/demo/src/app/components/+carousel/demos/accessibility/accessibility.ts @@ -0,0 +1,7 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'demo-accessibility', + templateUrl: './accessibility.html' +}) +export class DemoAccessibilityComponent {} diff --git a/demo/src/app/components/+carousel/demos/index.ts b/demo/src/app/components/+carousel/demos/index.ts index 45b24c50b9..96d54e2a4a 100644 --- a/demo/src/app/components/+carousel/demos/index.ts +++ b/demo/src/app/components/+carousel/demos/index.ts @@ -8,6 +8,7 @@ import { DemoCarouselIntervalComponent } from './interval/interval'; import { DemoCarouselDisableIndicatorComponent } from './disable-indicator/disable-indicator'; import { DemoCarouselDisableLoopingComponent } from './disable-looping/disable-looping'; import { DemoCarouselSlideChangedEventComponent } from './slide-changed-event/slide-changed-event'; +import { DemoAccessibilityComponent } from './accessibility/accessibility'; export const DEMO_COMPONENTS = [ DemoCarouselDynamicComponent, @@ -20,5 +21,6 @@ export const DEMO_COMPONENTS = [ DemoCarouselIntervalComponent, DemoCarouselDisableIndicatorComponent, DemoCarouselDisableLoopingComponent, - DemoCarouselSlideChangedEventComponent + DemoCarouselSlideChangedEventComponent, + DemoAccessibilityComponent ]; diff --git a/demo/src/app/components/+collapse/collapse-section.list.ts b/demo/src/app/components/+collapse/collapse-section.list.ts index 96ecc71f1f..87d73a3ccf 100644 --- a/demo/src/app/components/+collapse/collapse-section.list.ts +++ b/demo/src/app/components/+collapse/collapse-section.list.ts @@ -5,6 +5,7 @@ import { ContentSection } from '../../docs/models/content-section.model'; import { DemoTopSectionComponent } from '../../docs/demo-section-components/demo-top-section/index'; import { ExamplesComponent } from '../../docs/demo-section-components/demo-examples-section/index'; import { ApiSectionsComponent } from '../../docs/demo-section-components/demo-api-section/index'; +import { DemoAccessibilityComponent } from './demos/accessibility/accessibility'; import { NgApiDocComponent } from '../../docs/api-docs'; @@ -35,6 +36,11 @@ export const demoComponentContent: ContentSection[] = [ component: require('!!raw-loader?lang=typescript!./demos/toggle-manual/toggle-manual'), html: require('!!raw-loader?lang=markup!./demos/toggle-manual/toggle-manual.html'), outlet: ToggleManualDemoComponent + }, + { + title: 'Accessibility', + anchor: 'accessibility', + outlet: DemoAccessibilityComponent } ] }, diff --git a/demo/src/app/components/+collapse/demos/accessibility/accessibility.html b/demo/src/app/components/+collapse/demos/accessibility/accessibility.html new file mode 100644 index 0000000000..ecda634d3e --- /dev/null +++ b/demo/src/app/components/+collapse/demos/accessibility/accessibility.html @@ -0,0 +1,3 @@ +

Be sure to add aria-expanded to the control element. This attribute explicitly conveys the current state of the collapsible element tied to the control to screen readers and similar assistive technologies. If the collapsible element is closed by default, the attribute on the control element should have a value of aria-expanded="false". If you’ve set the collapsible element to be open by default using the show class, set aria-expanded="true" on the control instead. The plugin will automatically toggle this attribute on the control based on whether or not the collapsible element has been opened or closed. If the control element’s HTML element is not a button (e.g., an <a> or <div>), the attribute role="button" should be added to the element.

+

If your control element is targeting a single collapsible element – i.e. the data-target attribute is pointing to an id selector – you should add the aria-controls attribute to the control element, containing the id of the collapsible element. Modern screen readers and similar assistive technologies make use of this attribute to provide users with additional shortcuts to navigate directly to the collapsible element itself.

+ diff --git a/demo/src/app/components/+collapse/demos/accessibility/accessibility.ts b/demo/src/app/components/+collapse/demos/accessibility/accessibility.ts new file mode 100644 index 0000000000..8cc0725c7c --- /dev/null +++ b/demo/src/app/components/+collapse/demos/accessibility/accessibility.ts @@ -0,0 +1,7 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'demo-accessibility', + templateUrl: './accessibility.html' +}) +export class DemoAccessibilityComponent {} diff --git a/demo/src/app/components/+collapse/demos/index.ts b/demo/src/app/components/+collapse/demos/index.ts index bfd2b29ddf..537e939678 100644 --- a/demo/src/app/components/+collapse/demos/index.ts +++ b/demo/src/app/components/+collapse/demos/index.ts @@ -1,7 +1,9 @@ import { CollapseDemoComponent } from './basic/basic'; import { ToggleManualDemoComponent } from './toggle-manual/toggle-manual'; +import { DemoAccessibilityComponent } from './accessibility/accessibility'; export const DEMO_COMPONENTS = [ CollapseDemoComponent, - ToggleManualDemoComponent + ToggleManualDemoComponent, + DemoAccessibilityComponent ]; diff --git a/demo/src/app/components/+dropdown/demos/accessibility/accessibility.html b/demo/src/app/components/+dropdown/demos/accessibility/accessibility.html new file mode 100644 index 0000000000..6d6c65e003 --- /dev/null +++ b/demo/src/app/components/+dropdown/demos/accessibility/accessibility.html @@ -0,0 +1,2 @@ +

The WAI ARIA standard defines an actual role="menu" widget, but this is specific to application-like menus which trigger actions or functions. ARIA menus can only contain menu items, checkbox menu items, radio button menu items, radio button groups, and sub-menus.

+

Dropdowns, on the other hand, are designed to be generic and applicable to a variety of situations and markup structures. For instance, it is possible to create dropdowns that contain additional inputs and form controls, such as search fields or login forms. For this reason, ngx-bootstrap does not expect (nor automatically add) any of the role and aria- attributes required for true ARIA menus. Authors will have to include these more specific attributes themselves.

diff --git a/demo/src/app/components/+dropdown/demos/accessibility/accessibility.ts b/demo/src/app/components/+dropdown/demos/accessibility/accessibility.ts new file mode 100644 index 0000000000..8cc0725c7c --- /dev/null +++ b/demo/src/app/components/+dropdown/demos/accessibility/accessibility.ts @@ -0,0 +1,7 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'demo-accessibility', + templateUrl: './accessibility.html' +}) +export class DemoAccessibilityComponent {} diff --git a/demo/src/app/components/+dropdown/demos/index.ts b/demo/src/app/components/+dropdown/demos/index.ts index edd868fb7b..ecc147c298 100644 --- a/demo/src/app/components/+dropdown/demos/index.ts +++ b/demo/src/app/components/+dropdown/demos/index.ts @@ -15,6 +15,7 @@ import { DemoDropdownDisabledItemComponent } from './disabled-item/disabled-item import { DemoDropdownStateChangeEventComponent } from './state-change-event/state-change-event'; import { DemoDropdownAutoCloseComponent } from './autoclose/autoclose'; import { DemoDropdownCustomHtmlComponent } from './custom-html/custom-html'; +import { DemoAccessibilityComponent } from './accessibility/accessibility'; export const DEMO_COMPONENTS = [ DemoDropdownBasicComponent, @@ -33,5 +34,6 @@ export const DEMO_COMPONENTS = [ DemoDropdownVisibilityEventsComponent, DemoDropdownStateChangeEventComponent, DemoDropdownAutoCloseComponent, - DemoDropdownCustomHtmlComponent + DemoDropdownCustomHtmlComponent, + DemoAccessibilityComponent ]; diff --git a/demo/src/app/components/+dropdown/dropdown-section.list.ts b/demo/src/app/components/+dropdown/dropdown-section.list.ts index 25c93a0ffb..5d8556decc 100644 --- a/demo/src/app/components/+dropdown/dropdown-section.list.ts +++ b/demo/src/app/components/+dropdown/dropdown-section.list.ts @@ -15,6 +15,7 @@ import { DemoDropdownVisibilityEventsComponent } from './demos/visibility-events import { DemoDropdownStateChangeEventComponent } from './demos/state-change-event/state-change-event'; import { DemoDropdownAutoCloseComponent } from './demos/autoclose/autoclose'; import { DemoDropdownCustomHtmlComponent } from './demos/custom-html/custom-html'; +import { DemoAccessibilityComponent } from './demos/accessibility/accessibility'; import { ContentSection } from '../../docs/models/content-section.model'; import { DemoTopSectionComponent } from '../../docs/demo-section-components/demo-top-section/index'; @@ -26,6 +27,7 @@ import { NgApiDocConfigComponent } from '../../docs/api-docs'; + export const demoComponentContent: ContentSection[] = [ { name: 'Usage', @@ -186,6 +188,11 @@ export const demoComponentContent: ContentSection[] = [ html: require('!!raw-loader?lang=markup!./demos/autoclose/autoclose.html'), description: `

Use autoClose property to change dropdown's default behavior

`, outlet: DemoDropdownAutoCloseComponent + }, + { + title: 'Accessibility', + anchor: 'accessibility', + outlet: DemoAccessibilityComponent } ] }, diff --git a/demo/src/app/components/+modal/demos/accessibility/accessibility.html b/demo/src/app/components/+modal/demos/accessibility/accessibility.html new file mode 100644 index 0000000000..a5c9d4631e --- /dev/null +++ b/demo/src/app/components/+modal/demos/accessibility/accessibility.html @@ -0,0 +1 @@ +

Be sure to add role="dialog" and aria-labelledby="...", referencing the modal title, to .modal, and role="document" to the .modal-dialog itself. Additionally, you may give a description of your modal dialog with aria-describedby on .modal.

diff --git a/demo/src/app/components/+modal/demos/accessibility/accessibility.ts b/demo/src/app/components/+modal/demos/accessibility/accessibility.ts new file mode 100644 index 0000000000..8cc0725c7c --- /dev/null +++ b/demo/src/app/components/+modal/demos/accessibility/accessibility.ts @@ -0,0 +1,7 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'demo-accessibility', + templateUrl: './accessibility.html' +}) +export class DemoAccessibilityComponent {} diff --git a/demo/src/app/components/+modal/demos/index.ts b/demo/src/app/components/+modal/demos/index.ts index bd0a4a2e27..583937973b 100644 --- a/demo/src/app/components/+modal/demos/index.ts +++ b/demo/src/app/components/+modal/demos/index.ts @@ -15,6 +15,7 @@ import { DemoModalServiceDisableBackdropComponent } from './service-options/disa import { DemoModalServiceEventsComponent } from './service-events/service-events'; import { DemoModalServiceConfirmWindowComponent } from './service-confirm-window/service-confirm-window'; import { DemoModalScrollingLongContentComponent } from './scrolling-long-content/scrolling-long-content'; +import { DemoAccessibilityComponent } from './accessibility/accessibility'; export const DEMO_COMPONENTS = [ DemoModalSizesComponent, @@ -32,5 +33,6 @@ export const DEMO_COMPONENTS = [ DemoModalEventsComponent, DemoModalServiceEventsComponent, DemoModalServiceConfirmWindowComponent, - DemoModalScrollingLongContentComponent + DemoModalScrollingLongContentComponent, + DemoAccessibilityComponent ]; diff --git a/demo/src/app/components/+modal/modal-section.list.ts b/demo/src/app/components/+modal/modal-section.list.ts index 063ca1cecb..34af073cc3 100644 --- a/demo/src/app/components/+modal/modal-section.list.ts +++ b/demo/src/app/components/+modal/modal-section.list.ts @@ -14,6 +14,7 @@ import { DemoModalChildComponent } from './demos/child/child'; import { DemoModalNestedComponent } from './demos/nested/nested'; import { DemoModalEventsComponent } from './demos/events/events'; import { DemoAutoShownModalComponent } from './demos/auto-shown/auto-shown'; +import { DemoAccessibilityComponent } from './demos/accessibility/accessibility'; import { ContentSection } from '../../docs/models/content-section.model'; import { DemoTopSectionComponent } from '../../docs/demo-section-components/demo-top-section/index'; @@ -198,6 +199,11 @@ export const demoComponentContent: ContentSection[] = [ want to defer that until user actually sees modal content. I.e. for a "Select e-mail recipient" modal you might want to defer recipient list loading until the modal is shown.

`, outlet: DemoAutoShownModalComponent + }, + { + title: 'Accessibility', + anchor: 'accessibility', + outlet: DemoAccessibilityComponent } ] }, diff --git a/demo/src/app/components/+tabs/demos/accessibility/accessibility.html b/demo/src/app/components/+tabs/demos/accessibility/accessibility.html new file mode 100644 index 0000000000..3af7c23773 --- /dev/null +++ b/demo/src/app/components/+tabs/demos/accessibility/accessibility.html @@ -0,0 +1 @@ +

Note that tabs can be given role="tablist", role="tab" and role="tabpanel" attributes. These are appropriate for tabbed interfaces, as described in the WAI ARIA Authoring Practices.

diff --git a/demo/src/app/components/+tabs/demos/accessibility/accessibility.ts b/demo/src/app/components/+tabs/demos/accessibility/accessibility.ts new file mode 100644 index 0000000000..8cc0725c7c --- /dev/null +++ b/demo/src/app/components/+tabs/demos/accessibility/accessibility.ts @@ -0,0 +1,7 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'demo-accessibility', + templateUrl: './accessibility.html' +}) +export class DemoAccessibilityComponent {} diff --git a/demo/src/app/components/+tabs/demos/index.ts b/demo/src/app/components/+tabs/demos/index.ts index aef0b70a88..9a8849c7e1 100644 --- a/demo/src/app/components/+tabs/demos/index.ts +++ b/demo/src/app/components/+tabs/demos/index.ts @@ -9,11 +9,13 @@ import { DemoTabsManualComponent } from './manual/manual'; import { DemoTabsDisableComponent } from './disable/disable'; import { DemoTabsCustomComponent } from './custom-template/custom-template'; import { DemoTabsSelectEventComponent } from './select-event/select-event'; +import { DemoAccessibilityComponent } from './accessibility/accessibility'; export const DEMO_COMPONENTS = [ DemoTabsBasicComponent, DemoTabsManualComponent, DemoTabsDisableComponent, + DemoTabsDisableComponent, DemoTabsDynamicComponent, DemoTabsStylingComponent, DemoTabsPillsComponent, @@ -21,5 +23,6 @@ export const DEMO_COMPONENTS = [ DemoTabsJustifiedComponent, DemoTabsConfigComponent, DemoTabsCustomComponent, - DemoTabsSelectEventComponent + DemoTabsSelectEventComponent, + DemoAccessibilityComponent ]; diff --git a/demo/src/app/components/+tabs/tabs-section.list.ts b/demo/src/app/components/+tabs/tabs-section.list.ts index 21f93cc2cb..e46db8c0d0 100644 --- a/demo/src/app/components/+tabs/tabs-section.list.ts +++ b/demo/src/app/components/+tabs/tabs-section.list.ts @@ -9,6 +9,7 @@ import { DemoTabsConfigComponent } from './demos/config/config'; import { DemoTabsDisableComponent } from './demos/disable/disable'; import { DemoTabsCustomComponent } from './demos/custom-template/custom-template'; import { DemoTabsSelectEventComponent } from './demos/select-event/select-event'; +import { DemoAccessibilityComponent } from './demos/accessibility/accessibility'; import { ContentSection } from '../../docs/models/content-section.model'; import { DemoTopSectionComponent } from '../../docs/demo-section-components/demo-top-section/index'; @@ -112,6 +113,11 @@ export const demoComponentContent: ContentSection[] = [ component: require('!!raw-loader?lang=typescript!./demos/custom-template/custom-template'), html: require('!!raw-loader?lang=markup!./demos/custom-template/custom-template.html'), outlet: DemoTabsCustomComponent + }, + { + title: 'Accessibility', + anchor: 'accessibility', + outlet: DemoAccessibilityComponent } ] },