Skip to content

Commit

Permalink
add accessibility description sections
Browse files Browse the repository at this point in the history
  • Loading branch information
svetoldo4444ka committed Mar 12, 2018
1 parent 70e1288 commit 1966f5a
Show file tree
Hide file tree
Showing 22 changed files with 164 additions and 61 deletions.
95 changes: 47 additions & 48 deletions cypress/integration/buttons_page_spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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');
});
});
35 changes: 27 additions & 8 deletions demo/src/app/common/getting-started/getting-started.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -130,15 +130,34 @@ <h3>Credits</h3>
</p>

<h2 id="accessibility">Accessibility</h2>
<h3>To make components accessible: </h3>

<h3>Overview and Limitations</h3>

<p>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 <a href="https://www.w3.org/TR/WCAG20/"><abbr title="Web Content Accessibility Guidelines">WCAG</abbr> 2.0</a> (A/AA/AAA),
<a href="https://www.section508.gov/">Section 508</a> and similar accessibility standards and requirements.</p>

<h3>Interactive components</h3>

<p>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 <a href="https://www.w3.org/WAI/intro/aria"><abbr title="Web Accessibility Initiative">WAI</abbr>-<abbr title="Accessible Rich Internet Applications">ARIA</abbr></a>
roles and attributes, these components should also be understandable and operable using assistive technologies (such as screen readers).</p>
<p>Authors need to include ARIA roles and attributes to more accurately convey the precise nature of their component. </p>

<h3>Color contrast</h3>

<p>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 <em>insufficient</em> color contrast (below the recommended <a href="https://www.w3.org/TR/UNDERSTANDING-WCAG20/visual-audio-contrast-contrast.html">WCAG 2.0 color contrast ratio of 4.5:1</a>) when used against a light background. Authors will need to manually modify/extend these default colors to ensure adequate color contrast ratios.</p>

<h3>Additional resources</h3>

<ul>
<li><code>alt</code> attribute was added for image to help users not miss any content.</li>
<li>semantically correct HTML was used to tell the users what type of content it’s dealing with.</li>
<li>was added good contrast and readability. For users with a low vision impairment,
high-contrast can make it much easier to navigate the content on the page. </li>
<li>add aria-attributes to provide extra information to screen readers via HTML attributes. But you should be ready
that not all of aria-attributes are supported by different screen-reader. You can see it <a href="https://www.powermapper.com/tests/screen-readers/aria/">here</a></li>
<li>was added built-in support for most standard keyboard menu interactions, e.g. you can open a datepicker pressing any key</li>
<li><a href="https://www.w3.org/TR/WCAG20/">Web Content Accessibility Guidelines (WCAG) 2.0</a></li>
<li><a href="http://a11yproject.com/">The A11Y Project</a></li>
<li><a href="https://developer.mozilla.org/en-US/docs/Web/Accessibility">MDN accessibility documentation</a></li>
<li><a href="https://tenon.io/">Tenon.io Accessibility Checker</a></li>
<li><a href="https://developer.paciellogroup.com/resources/contrastanalyser/">Colour Contrast Analyser (CCA)</a></li>
<li><a href="https://github.com/squizlabs/HTML_CodeSniffer">“HTML Codesniffer” bookmarklet for identifying accessibility issues</a></li>
</ul>
</div>
</div>
Expand Down
6 changes: 6 additions & 0 deletions demo/src/app/components/+carousel/carousel-section.list.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -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
}
]
},
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<p>The <code>alt</code> attribute is meant to help users not miss any content, so make sure your text is helpful to anyone not seeing the image. </p>
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { Component } from '@angular/core';

@Component({
selector: 'demo-accessibility',
templateUrl: './accessibility.html'
})
export class DemoAccessibilityComponent {}
4 changes: 3 additions & 1 deletion demo/src/app/components/+carousel/demos/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -20,5 +21,6 @@ export const DEMO_COMPONENTS = [
DemoCarouselIntervalComponent,
DemoCarouselDisableIndicatorComponent,
DemoCarouselDisableLoopingComponent,
DemoCarouselSlideChangedEventComponent
DemoCarouselSlideChangedEventComponent,
DemoAccessibilityComponent
];
6 changes: 6 additions & 0 deletions demo/src/app/components/+collapse/collapse-section.list.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';

Expand Down Expand Up @@ -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
}
]
},
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<p>Be sure to add <code class="highlighter-rouge">aria-expanded</code> 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 <code class="highlighter-rouge">aria-expanded="false"</code>. If you’ve set the collapsible element to be open by default using the <code class="highlighter-rouge">show</code> class, set <code class="highlighter-rouge">aria-expanded="true"</code> 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 <code class="highlighter-rouge">&lt;a&gt;</code> or <code class="highlighter-rouge">&lt;div&gt;</code>), the attribute <code class="highlighter-rouge">role="button"</code> should be added to the element.</p>
<p>If your control element is targeting a single collapsible element – i.e. the <code class="highlighter-rouge">data-target</code> attribute is pointing to an <code class="highlighter-rouge">id</code> selector – you should add the <code class="highlighter-rouge">aria-controls</code> attribute to the control element, containing the <code class="highlighter-rouge">id</code> 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.</p>

Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { Component } from '@angular/core';

@Component({
selector: 'demo-accessibility',
templateUrl: './accessibility.html'
})
export class DemoAccessibilityComponent {}
4 changes: 3 additions & 1 deletion demo/src/app/components/+collapse/demos/index.ts
Original file line number Diff line number Diff line change
@@ -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
];
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<p>The <a href="https://www.w3.org/TR/wai-aria/"><abbr title="Web Accessibility Initiative">WAI</abbr> <abbr title="Accessible Rich Internet Applications">ARIA</abbr></a> standard defines an actual <a href="https://www.w3.org/TR/wai-aria-1.1/#menu"><code class="highlighter-rouge">role="menu"</code> widget</a>, but this is specific to application-like menus which trigger actions or functions. <abbr title="Accessible Rich Internet Applications">ARIA</abbr> menus can only contain menu items, checkbox menu items, radio button menu items, radio button groups, and sub-menus.</p>
<p>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 <code class="highlighter-rouge">role</code> and <code class="highlighter-rouge">aria-</code> attributes required for true <abbr title="Accessible Rich Internet Applications">ARIA</abbr> menus. Authors will have to include these more specific attributes themselves.</p>
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { Component } from '@angular/core';

@Component({
selector: 'demo-accessibility',
templateUrl: './accessibility.html'
})
export class DemoAccessibilityComponent {}
4 changes: 3 additions & 1 deletion demo/src/app/components/+dropdown/demos/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -33,5 +34,6 @@ export const DEMO_COMPONENTS = [
DemoDropdownVisibilityEventsComponent,
DemoDropdownStateChangeEventComponent,
DemoDropdownAutoCloseComponent,
DemoDropdownCustomHtmlComponent
DemoDropdownCustomHtmlComponent,
DemoAccessibilityComponent
];
7 changes: 7 additions & 0 deletions demo/src/app/components/+dropdown/dropdown-section.list.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand All @@ -26,6 +27,7 @@ import {
NgApiDocConfigComponent
} from '../../docs/api-docs';


export const demoComponentContent: ContentSection[] = [
{
name: 'Usage',
Expand Down Expand Up @@ -186,6 +188,11 @@ export const demoComponentContent: ContentSection[] = [
html: require('!!raw-loader?lang=markup!./demos/autoclose/autoclose.html'),
description: `<p>Use <code>autoClose</code> property to change dropdown's default behavior</p>`,
outlet: DemoDropdownAutoCloseComponent
},
{
title: 'Accessibility',
anchor: 'accessibility',
outlet: DemoAccessibilityComponent
}
]
},
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<p>Be sure to add <code class="highlighter-rouge">role="dialog"</code> and <code class="highlighter-rouge">aria-labelledby="..."</code>, referencing the modal title, to <code class="highlighter-rouge">.modal</code>, and <code class="highlighter-rouge">role="document"</code> to the <code class="highlighter-rouge">.modal-dialog</code> itself. Additionally, you may give a description of your modal dialog with <code class="highlighter-rouge">aria-describedby</code> on <code class="highlighter-rouge">.modal</code>.</p>
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { Component } from '@angular/core';

@Component({
selector: 'demo-accessibility',
templateUrl: './accessibility.html'
})
export class DemoAccessibilityComponent {}
4 changes: 3 additions & 1 deletion demo/src/app/components/+modal/demos/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -32,5 +33,6 @@ export const DEMO_COMPONENTS = [
DemoModalEventsComponent,
DemoModalServiceEventsComponent,
DemoModalServiceConfirmWindowComponent,
DemoModalScrollingLongContentComponent
DemoModalScrollingLongContentComponent,
DemoAccessibilityComponent
];
Loading

0 comments on commit 1966f5a

Please sign in to comment.