From 026ff94f19e93bc2755558a57ecc2c38ff15d2b0 Mon Sep 17 00:00:00 2001 From: AlmeroSteyn Date: Wed, 30 Mar 2016 19:43:22 +0200 Subject: [PATCH 1/6] docs(cb-a11y): add accessibility (a11y) cookbook --- public/docs/_examples/.gitignore | 2 +- public/docs/_examples/cb-a11y/e2e-spec.ts | 543 +++ public/docs/_examples/cb-a11y/ts/.gitignore | 11 + public/docs/_examples/cb-a11y/ts/a11y.css | 91 + public/docs/_examples/cb-a11y/ts/a2docs.css | 3609 +++++++++++++++++ .../cb-a11y/ts/app/a11y-index.component.html | 20 + .../cb-a11y/ts/app/a11y-index.component.ts | 10 + .../cb-a11y/ts/app/app.component.html | 8 + .../_examples/cb-a11y/ts/app/app.component.ts | 16 + .../_examples/cb-a11y/ts/app/app.routes.ts | 27 + .../a11y-component-roles.component.html | 56 + .../a11y-component-roles.component.ts | 28 + .../a11y-dev-tools-index.component.html | 14 + .../a11y-dev-tools-index.component.ts | 10 + .../dev-tools/a11y-dev-tools.component.html | 1 + .../app/dev-tools/a11y-dev-tools.component.ts | 10 + .../a11y-fails/a11y-fails.component.html | 53 + .../a11y-fails/a11y-fails.component.ts | 28 + .../a11y-pass/a11y-pass.component.html | 56 + .../a11y-pass/a11y-pass.component.ts | 20 + .../a11y-form-controls.component.html | 193 + .../a11y-form-controls.component.ts | 65 + .../a11y-input-wrapper.component.css | 25 + .../a11y-input-wrapper.component.html | 19 + .../a11y-input-wrapper.component.ts | 17 + public/docs/_examples/cb-a11y/ts/app/main.ts | 11 + .../a11y-error-demo.component.html | 18 + .../a11y-error-demo.component.ts | 19 + .../a11y-managing-focus.component.html | 110 + .../a11y-managing-focus.component.ts | 38 + .../ts/app/services/a11y-helper.service.ts | 97 + .../shared/a11y-custom-button.component.html | 3 + .../shared/a11y-custom-button.component.ts | 25 + .../shared/a11y-custom-control.component.css | 7 + .../shared/a11y-custom-control.component.html | 18 + .../shared/a11y-custom-control.component.ts | 67 + .../shared/a11y-value-helper.component.html | 5 + .../app/shared/a11y-value-helper.component.ts | 17 + .../_examples/cb-a11y/ts/example-config.json | 1 + public/docs/_examples/cb-a11y/ts/index.html | 29 + public/docs/_examples/cb-a11y/ts/plnkr.json | 8 + public/docs/dart/latest/cookbook/_data.json | 6 + public/docs/dart/latest/cookbook/a11y.jade | 2 + public/docs/js/latest/cookbook/_data.json | 6 + public/docs/js/latest/cookbook/a11y.jade | 1 + public/docs/ts/latest/cookbook/_data.json | 6 + public/docs/ts/latest/cookbook/a11y.jade | 1091 +++++ .../cookbooks/a11y/AXE-Details-Fails.png | Bin 0 -> 53525 bytes .../cookbooks/a11y/AXE-Overall-Analyze.png | Bin 0 -> 29208 bytes .../cookbooks/a11y/AXE-Overall-Fails.png | Bin 0 -> 12530 bytes .../cookbooks/a11y/AXE-Overall-Pass.png | Bin 0 -> 18351 bytes ...rome-experimental-a11y-inspector-label.png | Bin 0 -> 81601 bytes ...imental-a11y-inspector-unlabeled-input.png | Bin 0 -> 79180 bytes .../Chrome-experimental-a11y-inspector.png | Bin 0 -> 5418 bytes .../a11y/Safari-a11y-inspector-label.png | Bin 0 -> 605993 bytes .../Safari-a11y-inspector-unlabeled input.png | Bin 0 -> 604708 bytes .../cookbooks/a11y/WAVE-Contrast-Fails.png | Bin 0 -> 69072 bytes .../cookbooks/a11y/WAVE-Details-Fails.png | Bin 0 -> 102415 bytes .../cookbooks/a11y/WAVE-Overall-Fails.png | Bin 0 -> 67251 bytes .../cookbooks/a11y/WAVE-Overall-Pass.png | Bin 0 -> 73925 bytes .../cookbooks/a11y/custom-focus-outline.png | Bin 0 -> 3494 bytes .../images/cookbooks/a11y/focus-flow-bad.png | Bin 0 -> 22133 bytes .../cookbooks/a11y/focus-flow-clean.png | Bin 0 -> 15031 bytes .../images/cookbooks/a11y/focus-flow-good.png | Bin 0 -> 30208 bytes .../a11y/invisible-label-input-labeled.png | Bin 0 -> 24670 bytes .../invisible-label-input-not-labeled.png | Bin 0 -> 20888 bytes .../images/cookbooks/a11y/skiplinks.png | Bin 0 -> 5467 bytes .../cookbooks/a11y/standard-focus-outline.png | Bin 0 -> 2288 bytes 68 files changed, 6516 insertions(+), 1 deletion(-) create mode 100644 public/docs/_examples/cb-a11y/e2e-spec.ts create mode 100644 public/docs/_examples/cb-a11y/ts/.gitignore create mode 100644 public/docs/_examples/cb-a11y/ts/a11y.css create mode 100644 public/docs/_examples/cb-a11y/ts/a2docs.css create mode 100644 public/docs/_examples/cb-a11y/ts/app/a11y-index.component.html create mode 100644 public/docs/_examples/cb-a11y/ts/app/a11y-index.component.ts create mode 100644 public/docs/_examples/cb-a11y/ts/app/app.component.html create mode 100644 public/docs/_examples/cb-a11y/ts/app/app.component.ts create mode 100644 public/docs/_examples/cb-a11y/ts/app/app.routes.ts create mode 100644 public/docs/_examples/cb-a11y/ts/app/component-roles/a11y-component-roles.component.html create mode 100644 public/docs/_examples/cb-a11y/ts/app/component-roles/a11y-component-roles.component.ts create mode 100644 public/docs/_examples/cb-a11y/ts/app/dev-tools/a11y-dev-tools-index.component.html create mode 100644 public/docs/_examples/cb-a11y/ts/app/dev-tools/a11y-dev-tools-index.component.ts create mode 100644 public/docs/_examples/cb-a11y/ts/app/dev-tools/a11y-dev-tools.component.html create mode 100644 public/docs/_examples/cb-a11y/ts/app/dev-tools/a11y-dev-tools.component.ts create mode 100644 public/docs/_examples/cb-a11y/ts/app/dev-tools/a11y-fails/a11y-fails.component.html create mode 100644 public/docs/_examples/cb-a11y/ts/app/dev-tools/a11y-fails/a11y-fails.component.ts create mode 100644 public/docs/_examples/cb-a11y/ts/app/dev-tools/a11y-pass/a11y-pass.component.html create mode 100644 public/docs/_examples/cb-a11y/ts/app/dev-tools/a11y-pass/a11y-pass.component.ts create mode 100644 public/docs/_examples/cb-a11y/ts/app/form-controls/a11y-form-controls.component.html create mode 100644 public/docs/_examples/cb-a11y/ts/app/form-controls/a11y-form-controls.component.ts create mode 100644 public/docs/_examples/cb-a11y/ts/app/form-controls/a11y-input-wrapper.component.css create mode 100644 public/docs/_examples/cb-a11y/ts/app/form-controls/a11y-input-wrapper.component.html create mode 100644 public/docs/_examples/cb-a11y/ts/app/form-controls/a11y-input-wrapper.component.ts create mode 100644 public/docs/_examples/cb-a11y/ts/app/main.ts create mode 100644 public/docs/_examples/cb-a11y/ts/app/managing-focus/a11y-error-demo.component.html create mode 100644 public/docs/_examples/cb-a11y/ts/app/managing-focus/a11y-error-demo.component.ts create mode 100644 public/docs/_examples/cb-a11y/ts/app/managing-focus/a11y-managing-focus.component.html create mode 100644 public/docs/_examples/cb-a11y/ts/app/managing-focus/a11y-managing-focus.component.ts create mode 100644 public/docs/_examples/cb-a11y/ts/app/services/a11y-helper.service.ts create mode 100644 public/docs/_examples/cb-a11y/ts/app/shared/a11y-custom-button.component.html create mode 100644 public/docs/_examples/cb-a11y/ts/app/shared/a11y-custom-button.component.ts create mode 100644 public/docs/_examples/cb-a11y/ts/app/shared/a11y-custom-control.component.css create mode 100644 public/docs/_examples/cb-a11y/ts/app/shared/a11y-custom-control.component.html create mode 100644 public/docs/_examples/cb-a11y/ts/app/shared/a11y-custom-control.component.ts create mode 100644 public/docs/_examples/cb-a11y/ts/app/shared/a11y-value-helper.component.html create mode 100644 public/docs/_examples/cb-a11y/ts/app/shared/a11y-value-helper.component.ts create mode 100644 public/docs/_examples/cb-a11y/ts/example-config.json create mode 100644 public/docs/_examples/cb-a11y/ts/index.html create mode 100644 public/docs/_examples/cb-a11y/ts/plnkr.json create mode 100644 public/docs/dart/latest/cookbook/a11y.jade create mode 100644 public/docs/js/latest/cookbook/a11y.jade create mode 100644 public/docs/ts/latest/cookbook/a11y.jade create mode 100644 public/resources/images/cookbooks/a11y/AXE-Details-Fails.png create mode 100644 public/resources/images/cookbooks/a11y/AXE-Overall-Analyze.png create mode 100644 public/resources/images/cookbooks/a11y/AXE-Overall-Fails.png create mode 100644 public/resources/images/cookbooks/a11y/AXE-Overall-Pass.png create mode 100644 public/resources/images/cookbooks/a11y/Chrome-experimental-a11y-inspector-label.png create mode 100644 public/resources/images/cookbooks/a11y/Chrome-experimental-a11y-inspector-unlabeled-input.png create mode 100644 public/resources/images/cookbooks/a11y/Chrome-experimental-a11y-inspector.png create mode 100644 public/resources/images/cookbooks/a11y/Safari-a11y-inspector-label.png create mode 100644 public/resources/images/cookbooks/a11y/Safari-a11y-inspector-unlabeled input.png create mode 100644 public/resources/images/cookbooks/a11y/WAVE-Contrast-Fails.png create mode 100644 public/resources/images/cookbooks/a11y/WAVE-Details-Fails.png create mode 100644 public/resources/images/cookbooks/a11y/WAVE-Overall-Fails.png create mode 100644 public/resources/images/cookbooks/a11y/WAVE-Overall-Pass.png create mode 100644 public/resources/images/cookbooks/a11y/custom-focus-outline.png create mode 100644 public/resources/images/cookbooks/a11y/focus-flow-bad.png create mode 100644 public/resources/images/cookbooks/a11y/focus-flow-clean.png create mode 100644 public/resources/images/cookbooks/a11y/focus-flow-good.png create mode 100644 public/resources/images/cookbooks/a11y/invisible-label-input-labeled.png create mode 100644 public/resources/images/cookbooks/a11y/invisible-label-input-not-labeled.png create mode 100644 public/resources/images/cookbooks/a11y/skiplinks.png create mode 100644 public/resources/images/cookbooks/a11y/standard-focus-outline.png diff --git a/public/docs/_examples/.gitignore b/public/docs/_examples/.gitignore index b6733dc6ea..83f3135c58 100644 --- a/public/docs/_examples/.gitignore +++ b/public/docs/_examples/.gitignore @@ -14,7 +14,7 @@ _test-output **/ts-snippets/**/*.js *.d.ts -!**/*e2e-spec.js +!**/*e2e-spec.ts !systemjs.config.1.js !_boilerplate/* _boilerplate/a2docs.css diff --git a/public/docs/_examples/cb-a11y/e2e-spec.ts b/public/docs/_examples/cb-a11y/e2e-spec.ts new file mode 100644 index 0000000000..c56223c928 --- /dev/null +++ b/public/docs/_examples/cb-a11y/e2e-spec.ts @@ -0,0 +1,543 @@ +/// +'use strict'; +declare module jasmine { + + interface Matchers { + toHaveTextByCss(expected: any): boolean; + toHaveText(expected: any): boolean; + toBeDisplayed(expectationFailOutput?: any): boolean; + toBePresent(expectationFailOutput?: any): boolean; + toHaveValue(expected: any): boolean; + toContainText(expected: any): boolean; + toBeSelected(expectationFailOutput?: any): boolean; + } + + interface ProtractorCustomMatcherResult { + pass: webdriver.promise.Promise; + message?: string; + } + +} + +let matchers: any = { + toHaveTextByCss: toHaveTextByCss, + toHaveText: toHaveText, + toContainText: toContainText, + toHaveValue: toHaveValue, + toBeSelected: toBeSelected, + toBePresent: toBePresent, + toBeDisplayed: toBeDisplayed, + toHaveClass: toHaveClass +}; + +function toHaveTextByCss() { + return { + compare: function (cssSelector: string, expectedText: string): any { + let ret: jasmine.ProtractorCustomMatcherResult = { + pass: element.all(by.css(cssSelector)).first().getText().then(function (elementText) { + if (elementText !== expectedText) { + ret.message = 'Element by CSS "' + cssSelector + '" expected to have text: ' + expectedText; + } + return elementText === expectedText; + }) + }; + return ret; + } + }; +} + +function toHaveText() { + return { + compare: function (element: any, expectedText: string): any { + let ret: jasmine.ProtractorCustomMatcherResult = { + pass: element.getText().then(function (elementText: string) { + if (elementText !== expectedText) { + ret.message = 'Element expected to have text: ' + expectedText; + } + return elementText === expectedText; + }) + }; + return ret; + } + }; +} + +function toContainText() { + return { + compare: function (element: any, expectedText: string): any { + let ret: jasmine.ProtractorCustomMatcherResult = { + pass: element.getText().then(function (elementText: string) { + if (elementText.indexOf(expectedText) === -1) { + ret.message = 'Element expected to contain text: ' + expectedText; + } + return elementText.indexOf(expectedText) !== -1; + }) + }; + return ret; + } + }; +} + +function toHaveValue() { + return { + compare: function (element: any, expectedValue: any): any { + let ret: jasmine.ProtractorCustomMatcherResult = { + pass: element.getAttribute('value').then(function (elementValue: any) { + if (elementValue !== expectedValue) { + ret.message = 'Element expected to have value: ' + expectedValue; + } + return elementValue === expectedValue; + }) + }; + return ret; + } + }; +} + +function toBeSelected() { + return { + compare: function (element: any): any { + let ret: jasmine.ProtractorCustomMatcherResult = { + pass: element.isSelected().then(function (isSelected: boolean) { + if (!isSelected) { + ret.message = 'Element expected to be selected'; + } + return isSelected === true; + }) + }; + return ret; + }, + negativeCompare: function (element: any) { + let ret: jasmine.ProtractorCustomMatcherResult = { + pass: element.isSelected().then(function (isSelected: boolean) { + + if (isSelected) { + ret.message = 'Element expected not to be selected'; + } + return isSelected === false; + + }) + }; + return ret; + } + }; +} + +function toBePresent() { + return { + compare: function (element: any) { + let ret: jasmine.ProtractorCustomMatcherResult = { + pass: element.isPresent().then(function (isPresent: boolean) { + if (!isPresent) { + ret.message = 'Element expected to be present'; + } + return isPresent === true; + }) + }; + return ret; + }, + negativeCompare: function (element: any) { + let ret: jasmine.ProtractorCustomMatcherResult = { + pass: element.isPresent().then(function (isPresent: boolean) { + + if (isPresent) { + ret.message = 'Element expected not to be present'; + } + return isPresent === false; + + }) + }; + return ret; + } + }; +} + +function toBeDisplayed() { + return { + compare: function (element: any) { + let ret: jasmine.ProtractorCustomMatcherResult = { + pass: element.isDisplayed().then(function (isDisplayed: boolean) { + if (!isDisplayed) { + ret.message = 'Element expected to be displayed'; + } + return isDisplayed === true; + }) + }; + return ret; + }, + negativeCompare: function (element: any) { + let ret: jasmine.ProtractorCustomMatcherResult = { + pass: element.isDisplayed().then(function (isDisplayed: boolean) { + + if (isDisplayed) { + ret.message = 'Element expected not to be displayed'; + } + return isDisplayed === false; + + }) + }; + return ret; + } + }; +} + +function toHaveClass() { + return { + + compare: function (element: any, expectedClass: string) { + let ret: jasmine.ProtractorCustomMatcherResult = { + pass: element.getAttribute('class').then(function (actualClasses: string) { + + let index = actualClasses.indexOf(expectedClass); + + if (index === -1) { + ret.message = 'Expected to have class ' + expectedClass; + } + + return index !== -1; + + }) + }; + return ret; + }, + + negativeCompare: function (element: any, forbiddenClass: string) { + let ret: jasmine.ProtractorCustomMatcherResult = { + pass: element.getAttribute('class').then(function (actualClasses: string) { + + let index = actualClasses.indexOf(forbiddenClass); + + if (index !== -1) { + ret.message = 'Expected not to have class ' + forbiddenClass; + } + + return index === -1; + + }) + }; + return ret; + } + + }; + +} + +describe('A11y Cookbook', () => { + + describe('A11y Cookbook main index', () => { + + beforeAll(() => { + jasmine.addMatchers(matchers); + browser.get(''); + }); + + it('should display the main heading and links', () => { + expect('h1').toHaveTextByCss('Angular 2 a11y cookbook'); + expect(element.all(by.tagName('a')).get(0)).toHaveText('Accessible form control labels'); + expect(element.all(by.tagName('a')).get(1)).toHaveText('Managing focus'); + expect(element.all(by.tagName('a')).get(2)).toHaveText('Roles for custom component widgets'); + expect(element.all(by.tagName('a')).get(3)).toHaveText('Developer tools'); + }); + + it('should display the dev tool deeplinks', () => { + element.all(by.tagName('a')).get(3).click(); + expect(element.all(by.tagName('a')).get(0)).toHaveText('Demo with a11y errors'); + expect(element.all(by.tagName('a')).get(1)).toHaveText('Demo with full a11y features'); + }); + + }); + + describe('A11y Cookbook control labels', () => { + + beforeAll(() => { + jasmine.addMatchers(matchers); + browser.get(''); + element.all(by.tagName('a')).get(0).click(); + }); + + it('should have the correct page heading', () => { + expect('h2').toHaveTextByCss('Accessible form control labels'); + }); + + it('should have the correct sections', () => { + let headings = element.all(by.tagName('h3')); + expect(headings.get(0)).toHaveText('Implicit labeling'); + expect(headings.get(1)).toHaveText('Explicit labeling'); + expect(headings.get(2)).toHaveText('Hiding labels'); + expect(headings.get(3)).toHaveText('Labeling custom controls'); + }); + + it('should have a working implicitly labelled input', () => { + let testVal = 'Some text'; + expect(element.all(by.tagName('label')).get(0)).toHaveText('Type something:'); + let input = element.all(by.css('label > input')).first(); + expect(input).toHaveValue(''); + sendKeys(input, testVal); + expect(input).toHaveValue(testVal); + testValueDecorator(0, testVal); + }); + + it('should have a working implicitly labelled textarea', () => { + let testVal = 'Some text'; + expect(element.all(by.tagName('label')).get(1)).toHaveText('Type some text:'); + let textarea = element.all(by.css('label > textarea')).first(); + expect(textarea).toHaveValue(''); + sendKeys(textarea, testVal); + expect(textarea).toHaveValue(testVal); + testValueDecorator(1, testVal); + }); + + it('should have working implicitly labelled checkboxes', () => { + expect('fieldset legend').toHaveTextByCss('What do you like most about Angular 2?'); + let fieldSet = element.all(by.css('fieldset')).first(); + expect(fieldSet.all(by.css('label')).get(0)).toHaveText('Template syntax'); + expect(fieldSet.all(by.css('label')).get(1)).toHaveText('Observables'); + expect(fieldSet.all(by.css('label')).get(2)).toHaveText('Components'); + expect(fieldSet.all(by.css('label')).get(3)).toHaveText('Forms'); + expect(fieldSet.all(by.css('input')).get(0)).not.toBeSelected(); + expect(fieldSet.all(by.css('input')).get(1)).toBeSelected(); + expect(fieldSet.all(by.css('input')).get(2)).toBeSelected(); + expect(fieldSet.all(by.css('input')).get(3)).not.toBeSelected(); + testValueDecorator(2, '[ "Observables", "Components" ]'); + fieldSet.all(by.css('input')).get(1).click(); + testValueDecorator(2, '[ "Components" ]'); + fieldSet.all(by.css('input')).get(0).click(); + testValueDecorator(2, '[ "Components", "Template syntax" ]'); + }); + + it('should have working implicitly labelled radiobuttons', () => { + expect(element.all(by.css('fieldset legend')).get(1)).toHaveText('Choose your favourite Angular 2 language:'); + let fieldSet = element.all(by.css('fieldset')).get(1); + expect(fieldSet.all(by.css('label')).get(0)).toHaveText('TypeScript'); + expect(fieldSet.all(by.css('label')).get(1)).toHaveText('JavaScript'); + expect(fieldSet.all(by.css('label')).get(2)).toHaveText('ES6'); + expect(fieldSet.all(by.css('label')).get(3)).toHaveText('Dart'); + expect(fieldSet.all(by.css('input')).get(0)).toBeSelected(); + expect(fieldSet.all(by.css('input')).get(1)).not.toBeSelected(); + expect(fieldSet.all(by.css('input')).get(2)).not.toBeSelected(); + expect(fieldSet.all(by.css('input')).get(3)).not.toBeSelected(); + testValueDecorator(3, 'TypeScript'); + fieldSet.all(by.css('label')).get(1).click(); + testValueDecorator(3, 'JavaScript'); + }); + + it('should have a working implicitly labelled select', () => { + expect(element.all(by.tagName('label')).get(10)).toContainText('Why are you interested in a11y?'); + expect(element.all(by.tagName('select')).get(0)).toHaveValue('Curiosity'); + testValueDecorator(4, 'Curiosity'); + }); + + it('should have a working explicitly labelled input', () => { + let testVal = 'Some text'; + expect(element.all(by.tagName('label[for="inputexplicit"]')).first()).toHaveText('Label for input:'); + let input = element.all(by.css('#inputexplicit')).get(0); + expect(input).toHaveValue(''); + sendKeys(input, testVal); + expect(input).toHaveValue(testVal); + testValueDecorator(5, testVal); + }); + + it('should have a working input with hidden label', () => { + let testVal = 'Some text'; + expect(element.all(by.tagName('label.visually-hidden')).first()).toHaveText('Search:'); + let input = element.all(by.css('#inputsearch')).first(); + expect(input).toHaveValue(''); + sendKeys(input, testVal); + expect(input).toHaveValue(testVal); + testValueDecorator(6, testVal); + }); + + it('should have a working input with aria-label', () => { + let testVal = 'Some text'; + let input = element.all(by.css('input[aria-label="Filter:"')).first(); + expect(input).toHaveValue(''); + sendKeys(input, testVal); + expect(input).toHaveValue(testVal); + testValueDecorator(7, testVal); + }); + + it('should have a working editable div with label', () => { + let testVal = 'Value'; + expect(element.all(by.tagName('div.col-xs-6 label')).first()).toHaveText('Write in this labeled div:'); + let input = element.all(by.css('div.col-xs-6 div.edit-box')).first(); + expect(input).toHaveText(''); + sendKeys(input, testVal); + expect(input).toHaveText(testVal); + }); + + it('should have a working wrapped input', () => { + let testVal = 'Test'; + expect(element.all(by.tagName('div.col-xs-6 label span')).first()).toHaveText('Write in this wrapped input:'); + let input = element.all(by.css('div.input-group input')).first(); + expect(input).toHaveValue(''); + sendKeys(input, testVal); + expect(input).toHaveValue(testVal); + }); + + }); + + describe('A11y Cookbook managing focus', () => { + + beforeAll(() => { + jasmine.addMatchers(matchers); + browser.get(''); + element.all(by.tagName('a')).get(1).click(); + }); + + it('should have the correct page heading', () => { + expect('h2').toHaveTextByCss('Managing focus'); + }); + + it('should have the correct sections', () => { + let headings = element.all(by.tagName('h3')); + expect(headings.get(0)).toHaveText('The focus outline'); + expect(headings.get(1)).toHaveText('Focus flow'); + expect(headings.get(2)).toHaveText('Focusing custom controls'); + expect(headings.get(3)).toHaveText('Internal focus in a component'); + }); + + it('should have the focus outline elements', () => { + expect(element.all(by.cssContainingText('label', 'Focus me for the standard browser outline:')).first()).toBePresent(); + expect(element.all(by.cssContainingText('label', 'Focus me for a new and unusual outline:')).first()).toBePresent(); + }); + + it('should have the focus flow elements', () => { + expect(element.all(by.cssContainingText('label', 'Which city of The USA did you work in:')).first()).toBePresent(); + expect(element.all(by.cssContainingText('label', 'How many months did you work in The USA:')).first()).toBePresent(); + expect(element.all(by.cssContainingText('label', 'Which city of The Netherlands did you work in:')).first()).toBePresent(); + expect(element.all(by.cssContainingText('label', 'How many months did you work in The Netherlands:')).first()).toBePresent(); + expect(element.all(by.cssContainingText('label', 'Which city of South Africa did you work in:')).first()).toBePresent(); + expect(element.all(by.cssContainingText('label', 'How many months did you work in South Africa:')).first()).toBePresent(); + expect(element.all(by.cssContainingText('label', 'Which city of Germany did you work in:')).first()).toBePresent(); + expect(element.all(by.cssContainingText('label', 'How many months did you work in Germany:')).first()).toBePresent(); + expect(element.all(by.cssContainingText('label', 'Which city of The UK did you work in:')).first()).toBePresent(); + expect(element.all(by.cssContainingText('label', 'How many months did you work in The UK:')).first()).toBePresent(); + }); + + it('should have a clickable custom button component', () => { + element.all(by.tagName('a11y-custom-button')).get(0).click(); + testValueDecorator(0, 'Button has been clicked 1 times'); + }); + + it('should have an error toggling component', () => { + let showErrorButton = element(by.css('a11y-error-demo button.btn.btn-primary')); + expect(showErrorButton).toHaveText('Show error'); + let errorBanner = element(by.css('a11y-error-demo div.alert')); + expect(errorBanner).not.toBeDisplayed(); + showErrorButton.click(); + expect(errorBanner).toBeDisplayed(); + element(by.css('a11y-error-demo button.close')).click(); + expect(errorBanner).not.toBeDisplayed(); + }); + + }); + + describe('A11y Cookbook roles for custom components', () => { + + beforeAll(() => { + jasmine.addMatchers(matchers); + browser.get(''); + element.all(by.tagName('a')).get(2).click(); + }); + + it('should have the correct page heading', () => { + expect('h2').toHaveTextByCss('Roles for custom component widgets'); + }); + + it('should have the correct sections', () => { + let headings = element.all(by.tagName('h3')); + expect(headings.get(0)).toHaveText('Roles in the template'); + expect(headings.get(1)).toHaveText('Roles of the host element'); + }); + + it('should have a working editable div with label and internal role', () => { + let testVal = 'Test'; + expect(element.all(by.tagName('div.col-xs-6 label')).first()).toHaveText('I set the role in my template:'); + let input = element.all(by.css('div[role="textbox"]')).get(0); + expect(input).toHaveText(''); + sendKeys(input, testVal); + expect(input).toHaveText(testVal); + }); + + it('should have a clickable custom button component with role', () => { + element.all(by.css('a11y-custom-button[role="button"]')).get(0).click(); + testValueDecorator(1, 'Button has been clicked 1 times'); + }); + + }); + + describe('A11y Cookbook a11y errors page', () => { + + beforeAll(() => { + jasmine.addMatchers(matchers); + browser.get(''); + element.all(by.tagName('a')).get(3).click(); + element.all(by.tagName('a')).first().click(); + }); + + it('should have the correct page heading', () => { + expect('h3').toHaveTextByCss('Demo with a11y errors'); + }); + + it('should have the required form elements', () => { + testDemoPageLabels(); + }); + + it('should have basic form functionality', () => { + testDemoPageFunction(); + }); + + }); + + describe('A11y Cookbook a11y features page', () => { + + beforeAll(() => { + jasmine.addMatchers(matchers); + browser.get(''); + element.all(by.tagName('a')).get(3).click(); + element.all(by.tagName('a')).get(1).click(); + }); + + it('should have the correct page heading', () => { + expect('h2').toHaveTextByCss('Demo with full a11y features'); + }); + + it('should have the required form elements', () => { + testDemoPageLabels(); + }); + + it('should have basic form functionality', () => { + testDemoPageFunction(); + }); + + }); + + function testDemoPageLabels() { + expect(element.all(by.cssContainingText('label', 'Your name:')).first()).toBePresent(); + expect(element.all(by.cssContainingText('label', 'Your surname:')).first()).toBePresent(); + expect(element.all(by.cssContainingText('label', 'Tell us why you love Angular:')).first()).toBePresent(); + expect(element.all(by.cssContainingText('button', 'Submit')).first()).toBePresent(); + } + + function testDemoPageFunction() { + let statusBanner = element(by.css('div.alert.alert-success')); + let submitButton = element(by.css('button.btn.btn-primary')); + expect(statusBanner).not.toBeDisplayed(); + let nameInput = element.all(by.css('input')).get(0); + sendKeys(nameInput, 'John'); + let surnameInput = element.all(by.css('input')).get(1); + sendKeys(surnameInput, 'Smith'); + let reasonInput = element.all(by.css('input')).get(2); + sendKeys(reasonInput, 'It is awesome!!'); + submitButton.click(); + expect(statusBanner).toBeDisplayed(); + expect(element.all(by.cssContainingText('div.alert.alert-success', + 'Hi John Smith! Your reason for liking Angular 2 is: It is awesome!!.')).first()).toBePresent(); + } + + function testValueDecorator(index: number, contentText: string) { + let decorator = element.all(by.css('a11y-value-helper span')).get(index); + expect(decorator).toHaveText('Current value: ' + contentText); + } + +}); diff --git a/public/docs/_examples/cb-a11y/ts/.gitignore b/public/docs/_examples/cb-a11y/ts/.gitignore new file mode 100644 index 0000000000..0390f46835 --- /dev/null +++ b/public/docs/_examples/cb-a11y/ts/.gitignore @@ -0,0 +1,11 @@ +styles.css +typings +typings.json +*.js.map +package.json +karma.conf.js +karma-test-shim.js +tsconfig.json +npm-debug*. +**/protractor.config.js + diff --git a/public/docs/_examples/cb-a11y/ts/a11y.css b/public/docs/_examples/cb-a11y/ts/a11y.css new file mode 100644 index 0000000000..34e6887830 --- /dev/null +++ b/public/docs/_examples/cb-a11y/ts/a11y.css @@ -0,0 +1,91 @@ +label { + width: 100%; +} + +hr { + border-top: 3px double; +} + +h3 { + outline: 0; +} + +.hide-element { + display: none !important; +} + +.btn { + margin-bottom: 15px; +} + +.skiplink { + min-height: 20px; +} + +/* #docregion cb-a11y-managing-focus-skiplinks-style */ +.skiplink a { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0, 0, 0, 0); + border: 0; + color: darkblue; +} + +.skiplink a:active, +.skiplink a:focus { + position: static; + width: auto; + height: auto; + margin: 0; + overflow: visible; + clip: auto; +} + +/* #enddocregion */ + +/* #docregion cb-a11y-managing-focus-custom-outline */ +.custom-outline:focus { + border-color: #7F0037; + outline: 0; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 8px rgba(127, 0, 55, .6); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 8px rgba(127, 0, 55, .6); +} + +/* #enddocregion */ + +/* #docregion cb-a11y-form-controls-visually-hidden-style*/ +.visually-hidden { + border: 0; + clip: rect(0 0 0 0); + height: 1px; + margin: -1px; + overflow: hidden; + padding: 0; + position: absolute; + width: 1px; +} + +/* #enddocregion */ + +.like-bootstrap { + display: block; + width: 100%; + height: 34px; + padding: 6px 12px; + font-size: 14px; + line-height: 1.42857143; + color: #000000; + background-color: #fff; + background-image: none; + border: 1px solid #ccc; + border-radius: 4px; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); + -webkit-transition: border-color ease-in-out .15s, -webkit-box-shadow ease-in-out .15s; + -o-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s; + transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s; +} diff --git a/public/docs/_examples/cb-a11y/ts/a2docs.css b/public/docs/_examples/cb-a11y/ts/a2docs.css new file mode 100644 index 0000000000..f58ad962ca --- /dev/null +++ b/public/docs/_examples/cb-a11y/ts/a2docs.css @@ -0,0 +1,3609 @@ +* { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +*:before, +*:after { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +html { + font-size: 10px; + -webkit-tap-highlight-color: rgba(0, 0, 0, 0); +} +body { + font-family: "Roboto", Helvetica, Sans-Serif; + font-size: 14px; + line-height: 1.42857143; + color: #000000; + background-color: #fff; +} +input, +button, +select, +textarea { + font-family: inherit; + font-size: inherit; + line-height: inherit; +} +a { + color: #337ab7; + text-decoration: none; +} +a:hover, +a:focus { + color: #23527c; + text-decoration: underline; +} +a:focus { + outline: thin dotted; + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; +} +figure { + margin: 0; +} +img { + vertical-align: middle; +} +.img-responsive { + display: block; + max-width: 100%; + height: auto; +} +.img-rounded { + border-radius: 6px; +} +.img-thumbnail { + padding: 4px; + line-height: 1.42857143; + background-color: #fff; + border: 1px solid #ddd; + border-radius: 4px; + -webkit-transition: all 0.2s ease-in-out; + -o-transition: all 0.2s ease-in-out; + transition: all 0.2s ease-in-out; + display: inline-block; + max-width: 100%; + height: auto; +} +.img-circle { + border-radius: 50%; +} +hr { + margin-top: 20px; + margin-bottom: 20px; + border: 0; + border-top: 1px solid #EEEEEE; +} +.sr-only { + position: absolute; + width: 1px; + height: 1px; + margin: -1px; + padding: 0; + overflow: hidden; + clip: rect(0, 0, 0, 0); + border: 0; +} +.sr-only-focusable:active, +.sr-only-focusable:focus { + position: static; + width: auto; + height: auto; + margin: 0; + overflow: visible; + clip: auto; +} +[role="button"] { + cursor: pointer; +} +.container { + margin-right: auto; + margin-left: auto; + padding-left: 15px; + padding-right: 15px; +} +@media (min-width: 768px) { + .container { + width: 750px; + } +} +@media (min-width: 992px) { + .container { + width: 970px; + } +} +@media (min-width: 1200px) { + .container { + width: 1170px; + } +} +.container-fluid { + margin-right: auto; + margin-left: auto; + padding-left: 15px; + padding-right: 15px; +} +.row { + margin-left: -15px; + margin-right: -15px; +} +.col-xs-1, .col-sm-1, .col-md-1, .col-lg-1, .col-xs-2, .col-sm-2, .col-md-2, .col-lg-2, .col-xs-3, .col-sm-3, .col-md-3, .col-lg-3, .col-xs-4, .col-sm-4, .col-md-4, .col-lg-4, .col-xs-5, .col-sm-5, .col-md-5, .col-lg-5, .col-xs-6, .col-sm-6, .col-md-6, .col-lg-6, .col-xs-7, .col-sm-7, .col-md-7, .col-lg-7, .col-xs-8, .col-sm-8, .col-md-8, .col-lg-8, .col-xs-9, .col-sm-9, .col-md-9, .col-lg-9, .col-xs-10, .col-sm-10, .col-md-10, .col-lg-10, .col-xs-11, .col-sm-11, .col-md-11, .col-lg-11, .col-xs-12, .col-sm-12, .col-md-12, .col-lg-12 { + position: relative; + min-height: 1px; + padding-left: 15px; + padding-right: 15px; +} +.col-xs-1, .col-xs-2, .col-xs-3, .col-xs-4, .col-xs-5, .col-xs-6, .col-xs-7, .col-xs-8, .col-xs-9, .col-xs-10, .col-xs-11, .col-xs-12 { + float: left; +} +.col-xs-12 { + width: 100%; +} +.col-xs-11 { + width: 91.66666667%; +} +.col-xs-10 { + width: 83.33333333%; +} +.col-xs-9 { + width: 75%; +} +.col-xs-8 { + width: 66.66666667%; +} +.col-xs-7 { + width: 58.33333333%; +} +.col-xs-6 { + width: 50%; +} +.col-xs-5 { + width: 41.66666667%; +} +.col-xs-4 { + width: 33.33333333%; +} +.col-xs-3 { + width: 25%; +} +.col-xs-2 { + width: 16.66666667%; +} +.col-xs-1 { + width: 8.33333333%; +} +.col-xs-pull-12 { + right: 100%; +} +.col-xs-pull-11 { + right: 91.66666667%; +} +.col-xs-pull-10 { + right: 83.33333333%; +} +.col-xs-pull-9 { + right: 75%; +} +.col-xs-pull-8 { + right: 66.66666667%; +} +.col-xs-pull-7 { + right: 58.33333333%; +} +.col-xs-pull-6 { + right: 50%; +} +.col-xs-pull-5 { + right: 41.66666667%; +} +.col-xs-pull-4 { + right: 33.33333333%; +} +.col-xs-pull-3 { + right: 25%; +} +.col-xs-pull-2 { + right: 16.66666667%; +} +.col-xs-pull-1 { + right: 8.33333333%; +} +.col-xs-pull-0 { + right: auto; +} +.col-xs-push-12 { + left: 100%; +} +.col-xs-push-11 { + left: 91.66666667%; +} +.col-xs-push-10 { + left: 83.33333333%; +} +.col-xs-push-9 { + left: 75%; +} +.col-xs-push-8 { + left: 66.66666667%; +} +.col-xs-push-7 { + left: 58.33333333%; +} +.col-xs-push-6 { + left: 50%; +} +.col-xs-push-5 { + left: 41.66666667%; +} +.col-xs-push-4 { + left: 33.33333333%; +} +.col-xs-push-3 { + left: 25%; +} +.col-xs-push-2 { + left: 16.66666667%; +} +.col-xs-push-1 { + left: 8.33333333%; +} +.col-xs-push-0 { + left: auto; +} +.col-xs-offset-12 { + margin-left: 100%; +} +.col-xs-offset-11 { + margin-left: 91.66666667%; +} +.col-xs-offset-10 { + margin-left: 83.33333333%; +} +.col-xs-offset-9 { + margin-left: 75%; +} +.col-xs-offset-8 { + margin-left: 66.66666667%; +} +.col-xs-offset-7 { + margin-left: 58.33333333%; +} +.col-xs-offset-6 { + margin-left: 50%; +} +.col-xs-offset-5 { + margin-left: 41.66666667%; +} +.col-xs-offset-4 { + margin-left: 33.33333333%; +} +.col-xs-offset-3 { + margin-left: 25%; +} +.col-xs-offset-2 { + margin-left: 16.66666667%; +} +.col-xs-offset-1 { + margin-left: 8.33333333%; +} +.col-xs-offset-0 { + margin-left: 0%; +} +@media (min-width: 768px) { + .col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12 { + float: left; + } + .col-sm-12 { + width: 100%; + } + .col-sm-11 { + width: 91.66666667%; + } + .col-sm-10 { + width: 83.33333333%; + } + .col-sm-9 { + width: 75%; + } + .col-sm-8 { + width: 66.66666667%; + } + .col-sm-7 { + width: 58.33333333%; + } + .col-sm-6 { + width: 50%; + } + .col-sm-5 { + width: 41.66666667%; + } + .col-sm-4 { + width: 33.33333333%; + } + .col-sm-3 { + width: 25%; + } + .col-sm-2 { + width: 16.66666667%; + } + .col-sm-1 { + width: 8.33333333%; + } + .col-sm-pull-12 { + right: 100%; + } + .col-sm-pull-11 { + right: 91.66666667%; + } + .col-sm-pull-10 { + right: 83.33333333%; + } + .col-sm-pull-9 { + right: 75%; + } + .col-sm-pull-8 { + right: 66.66666667%; + } + .col-sm-pull-7 { + right: 58.33333333%; + } + .col-sm-pull-6 { + right: 50%; + } + .col-sm-pull-5 { + right: 41.66666667%; + } + .col-sm-pull-4 { + right: 33.33333333%; + } + .col-sm-pull-3 { + right: 25%; + } + .col-sm-pull-2 { + right: 16.66666667%; + } + .col-sm-pull-1 { + right: 8.33333333%; + } + .col-sm-pull-0 { + right: auto; + } + .col-sm-push-12 { + left: 100%; + } + .col-sm-push-11 { + left: 91.66666667%; + } + .col-sm-push-10 { + left: 83.33333333%; + } + .col-sm-push-9 { + left: 75%; + } + .col-sm-push-8 { + left: 66.66666667%; + } + .col-sm-push-7 { + left: 58.33333333%; + } + .col-sm-push-6 { + left: 50%; + } + .col-sm-push-5 { + left: 41.66666667%; + } + .col-sm-push-4 { + left: 33.33333333%; + } + .col-sm-push-3 { + left: 25%; + } + .col-sm-push-2 { + left: 16.66666667%; + } + .col-sm-push-1 { + left: 8.33333333%; + } + .col-sm-push-0 { + left: auto; + } + .col-sm-offset-12 { + margin-left: 100%; + } + .col-sm-offset-11 { + margin-left: 91.66666667%; + } + .col-sm-offset-10 { + margin-left: 83.33333333%; + } + .col-sm-offset-9 { + margin-left: 75%; + } + .col-sm-offset-8 { + margin-left: 66.66666667%; + } + .col-sm-offset-7 { + margin-left: 58.33333333%; + } + .col-sm-offset-6 { + margin-left: 50%; + } + .col-sm-offset-5 { + margin-left: 41.66666667%; + } + .col-sm-offset-4 { + margin-left: 33.33333333%; + } + .col-sm-offset-3 { + margin-left: 25%; + } + .col-sm-offset-2 { + margin-left: 16.66666667%; + } + .col-sm-offset-1 { + margin-left: 8.33333333%; + } + .col-sm-offset-0 { + margin-left: 0%; + } +} +@media (min-width: 992px) { + .col-md-1, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-10, .col-md-11, .col-md-12 { + float: left; + } + .col-md-12 { + width: 100%; + } + .col-md-11 { + width: 91.66666667%; + } + .col-md-10 { + width: 83.33333333%; + } + .col-md-9 { + width: 75%; + } + .col-md-8 { + width: 66.66666667%; + } + .col-md-7 { + width: 58.33333333%; + } + .col-md-6 { + width: 50%; + } + .col-md-5 { + width: 41.66666667%; + } + .col-md-4 { + width: 33.33333333%; + } + .col-md-3 { + width: 25%; + } + .col-md-2 { + width: 16.66666667%; + } + .col-md-1 { + width: 8.33333333%; + } + .col-md-pull-12 { + right: 100%; + } + .col-md-pull-11 { + right: 91.66666667%; + } + .col-md-pull-10 { + right: 83.33333333%; + } + .col-md-pull-9 { + right: 75%; + } + .col-md-pull-8 { + right: 66.66666667%; + } + .col-md-pull-7 { + right: 58.33333333%; + } + .col-md-pull-6 { + right: 50%; + } + .col-md-pull-5 { + right: 41.66666667%; + } + .col-md-pull-4 { + right: 33.33333333%; + } + .col-md-pull-3 { + right: 25%; + } + .col-md-pull-2 { + right: 16.66666667%; + } + .col-md-pull-1 { + right: 8.33333333%; + } + .col-md-pull-0 { + right: auto; + } + .col-md-push-12 { + left: 100%; + } + .col-md-push-11 { + left: 91.66666667%; + } + .col-md-push-10 { + left: 83.33333333%; + } + .col-md-push-9 { + left: 75%; + } + .col-md-push-8 { + left: 66.66666667%; + } + .col-md-push-7 { + left: 58.33333333%; + } + .col-md-push-6 { + left: 50%; + } + .col-md-push-5 { + left: 41.66666667%; + } + .col-md-push-4 { + left: 33.33333333%; + } + .col-md-push-3 { + left: 25%; + } + .col-md-push-2 { + left: 16.66666667%; + } + .col-md-push-1 { + left: 8.33333333%; + } + .col-md-push-0 { + left: auto; + } + .col-md-offset-12 { + margin-left: 100%; + } + .col-md-offset-11 { + margin-left: 91.66666667%; + } + .col-md-offset-10 { + margin-left: 83.33333333%; + } + .col-md-offset-9 { + margin-left: 75%; + } + .col-md-offset-8 { + margin-left: 66.66666667%; + } + .col-md-offset-7 { + margin-left: 58.33333333%; + } + .col-md-offset-6 { + margin-left: 50%; + } + .col-md-offset-5 { + margin-left: 41.66666667%; + } + .col-md-offset-4 { + margin-left: 33.33333333%; + } + .col-md-offset-3 { + margin-left: 25%; + } + .col-md-offset-2 { + margin-left: 16.66666667%; + } + .col-md-offset-1 { + margin-left: 8.33333333%; + } + .col-md-offset-0 { + margin-left: 0%; + } +} +@media (min-width: 1200px) { + .col-lg-1, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-10, .col-lg-11, .col-lg-12 { + float: left; + } + .col-lg-12 { + width: 100%; + } + .col-lg-11 { + width: 91.66666667%; + } + .col-lg-10 { + width: 83.33333333%; + } + .col-lg-9 { + width: 75%; + } + .col-lg-8 { + width: 66.66666667%; + } + .col-lg-7 { + width: 58.33333333%; + } + .col-lg-6 { + width: 50%; + } + .col-lg-5 { + width: 41.66666667%; + } + .col-lg-4 { + width: 33.33333333%; + } + .col-lg-3 { + width: 25%; + } + .col-lg-2 { + width: 16.66666667%; + } + .col-lg-1 { + width: 8.33333333%; + } + .col-lg-pull-12 { + right: 100%; + } + .col-lg-pull-11 { + right: 91.66666667%; + } + .col-lg-pull-10 { + right: 83.33333333%; + } + .col-lg-pull-9 { + right: 75%; + } + .col-lg-pull-8 { + right: 66.66666667%; + } + .col-lg-pull-7 { + right: 58.33333333%; + } + .col-lg-pull-6 { + right: 50%; + } + .col-lg-pull-5 { + right: 41.66666667%; + } + .col-lg-pull-4 { + right: 33.33333333%; + } + .col-lg-pull-3 { + right: 25%; + } + .col-lg-pull-2 { + right: 16.66666667%; + } + .col-lg-pull-1 { + right: 8.33333333%; + } + .col-lg-pull-0 { + right: auto; + } + .col-lg-push-12 { + left: 100%; + } + .col-lg-push-11 { + left: 91.66666667%; + } + .col-lg-push-10 { + left: 83.33333333%; + } + .col-lg-push-9 { + left: 75%; + } + .col-lg-push-8 { + left: 66.66666667%; + } + .col-lg-push-7 { + left: 58.33333333%; + } + .col-lg-push-6 { + left: 50%; + } + .col-lg-push-5 { + left: 41.66666667%; + } + .col-lg-push-4 { + left: 33.33333333%; + } + .col-lg-push-3 { + left: 25%; + } + .col-lg-push-2 { + left: 16.66666667%; + } + .col-lg-push-1 { + left: 8.33333333%; + } + .col-lg-push-0 { + left: auto; + } + .col-lg-offset-12 { + margin-left: 100%; + } + .col-lg-offset-11 { + margin-left: 91.66666667%; + } + .col-lg-offset-10 { + margin-left: 83.33333333%; + } + .col-lg-offset-9 { + margin-left: 75%; + } + .col-lg-offset-8 { + margin-left: 66.66666667%; + } + .col-lg-offset-7 { + margin-left: 58.33333333%; + } + .col-lg-offset-6 { + margin-left: 50%; + } + .col-lg-offset-5 { + margin-left: 41.66666667%; + } + .col-lg-offset-4 { + margin-left: 33.33333333%; + } + .col-lg-offset-3 { + margin-left: 25%; + } + .col-lg-offset-2 { + margin-left: 16.66666667%; + } + .col-lg-offset-1 { + margin-left: 8.33333333%; + } + .col-lg-offset-0 { + margin-left: 0%; + } +} +.clearfix:before, +.clearfix:after, +.container:before, +.container:after, +.container-fluid:before, +.container-fluid:after, +.row:before, +.row:after, +.form-horizontal .form-group:before, +.form-horizontal .form-group:after, +.btn-toolbar:before, +.btn-toolbar:after, +.btn-group-vertical > .btn-group:before, +.btn-group-vertical > .btn-group:after { + content: " "; + display: table; +} +.clearfix:after, +.container:after, +.container-fluid:after, +.row:after, +.form-horizontal .form-group:after, +.btn-toolbar:after, +.btn-group-vertical > .btn-group:after { + clear: both; +} +.center-block { + display: block; + margin-left: auto; + margin-right: auto; +} +.pull-right { + float: right !important; +} +.pull-left { + float: left !important; +} +.hide { + display: none !important; +} +.show { + display: block !important; +} +.invisible { + visibility: hidden; +} +.text-hide { + font: 0/0 a; + color: transparent; + text-shadow: none; + background-color: transparent; + border: 0; +} +.hidden { + display: none !important; +} +.affix { + position: fixed; +} +@-ms-viewport { + width: device-width; +} +.visible-xs, +.visible-sm, +.visible-md, +.visible-lg { + display: none !important; +} +.visible-xs-block, +.visible-xs-inline, +.visible-xs-inline-block, +.visible-sm-block, +.visible-sm-inline, +.visible-sm-inline-block, +.visible-md-block, +.visible-md-inline, +.visible-md-inline-block, +.visible-lg-block, +.visible-lg-inline, +.visible-lg-inline-block { + display: none !important; +} +@media (max-width: 767px) { + .visible-xs { + display: block !important; + } + table.visible-xs { + display: table !important; + } + tr.visible-xs { + display: table-row !important; + } + th.visible-xs, + td.visible-xs { + display: table-cell !important; + } +} +@media (max-width: 767px) { + .visible-xs-block { + display: block !important; + } +} +@media (max-width: 767px) { + .visible-xs-inline { + display: inline !important; + } +} +@media (max-width: 767px) { + .visible-xs-inline-block { + display: inline-block !important; + } +} +@media (min-width: 768px) and (max-width: 991px) { + .visible-sm { + display: block !important; + } + table.visible-sm { + display: table !important; + } + tr.visible-sm { + display: table-row !important; + } + th.visible-sm, + td.visible-sm { + display: table-cell !important; + } +} +@media (min-width: 768px) and (max-width: 991px) { + .visible-sm-block { + display: block !important; + } +} +@media (min-width: 768px) and (max-width: 991px) { + .visible-sm-inline { + display: inline !important; + } +} +@media (min-width: 768px) and (max-width: 991px) { + .visible-sm-inline-block { + display: inline-block !important; + } +} +@media (min-width: 992px) and (max-width: 1199px) { + .visible-md { + display: block !important; + } + table.visible-md { + display: table !important; + } + tr.visible-md { + display: table-row !important; + } + th.visible-md, + td.visible-md { + display: table-cell !important; + } +} +@media (min-width: 992px) and (max-width: 1199px) { + .visible-md-block { + display: block !important; + } +} +@media (min-width: 992px) and (max-width: 1199px) { + .visible-md-inline { + display: inline !important; + } +} +@media (min-width: 992px) and (max-width: 1199px) { + .visible-md-inline-block { + display: inline-block !important; + } +} +@media (min-width: 1200px) { + .visible-lg { + display: block !important; + } + table.visible-lg { + display: table !important; + } + tr.visible-lg { + display: table-row !important; + } + th.visible-lg, + td.visible-lg { + display: table-cell !important; + } +} +@media (min-width: 1200px) { + .visible-lg-block { + display: block !important; + } +} +@media (min-width: 1200px) { + .visible-lg-inline { + display: inline !important; + } +} +@media (min-width: 1200px) { + .visible-lg-inline-block { + display: inline-block !important; + } +} +@media (max-width: 767px) { + .hidden-xs { + display: none !important; + } +} +@media (min-width: 768px) and (max-width: 991px) { + .hidden-sm { + display: none !important; + } +} +@media (min-width: 992px) and (max-width: 1199px) { + .hidden-md { + display: none !important; + } +} +@media (min-width: 1200px) { + .hidden-lg { + display: none !important; + } +} +.visible-print { + display: none !important; +} +@media print { + .visible-print { + display: block !important; + } + table.visible-print { + display: table !important; + } + tr.visible-print { + display: table-row !important; + } + th.visible-print, + td.visible-print { + display: table-cell !important; + } +} +.visible-print-block { + display: none !important; +} +@media print { + .visible-print-block { + display: block !important; + } +} +.visible-print-inline { + display: none !important; +} +@media print { + .visible-print-inline { + display: inline !important; + } +} +.visible-print-inline-block { + display: none !important; +} +@media print { + .visible-print-inline-block { + display: inline-block !important; + } +} +@media print { + .hidden-print { + display: none !important; + } +} +fieldset { + padding: 0; + margin: 0; + border: 0; + min-width: 0; +} +legend { + display: block; + width: 100%; + padding: 0; + margin-bottom: 20px; + font-size: 21px; + line-height: inherit; + color: #212121; + border: 0; + border-bottom: 1px solid #e5e5e5; +} +label { + display: inline-block; + max-width: 100%; + margin-bottom: 5px; + font-weight: bold; +} +input[type="search"] { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +input[type="radio"], +input[type="checkbox"] { + margin: 4px 0 0; + margin-top: 1px \9; + line-height: normal; +} +input[type="file"] { + display: block; +} +input[type="range"] { + display: block; + width: 100%; +} +select[multiple], +select[size] { + height: auto; +} +input[type="file"]:focus, +input[type="radio"]:focus, +input[type="checkbox"]:focus { + outline: thin dotted; + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; +} +output { + display: block; + padding-top: 7px; + font-size: 14px; + line-height: 1.42857143; + color: #000000; +} +.form-control { + display: block; + width: 100%; + height: 34px; + padding: 6px 12px; + font-size: 14px; + line-height: 1.42857143; + color: #000000; + background-color: #fff; + background-image: none; + border: 1px solid #ccc; + border-radius: 4px; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + -webkit-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s; + -o-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s; + transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s; +} +.form-control:focus { + border-color: #66afe9; + outline: 0; + -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6); + box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6); +} +.form-control::-moz-placeholder { + color: #999; + opacity: 1; +} +.form-control:-ms-input-placeholder { + color: #999; +} +.form-control::-webkit-input-placeholder { + color: #999; +} +.form-control::-ms-expand { + border: 0; + background-color: transparent; +} +.form-control[disabled], +.form-control[readonly], +fieldset[disabled] .form-control { + background-color: #EEEEEE; + opacity: 1; +} +.form-control[disabled], +fieldset[disabled] .form-control { + cursor: not-allowed; +} +textarea.form-control { + height: auto; +} +input[type="search"] { + -webkit-appearance: none; +} +@media screen and (-webkit-min-device-pixel-ratio: 0) { + input[type="date"].form-control, + input[type="time"].form-control, + input[type="datetime-local"].form-control, + input[type="month"].form-control { + line-height: 34px; + } + input[type="date"].input-sm, + input[type="time"].input-sm, + input[type="datetime-local"].input-sm, + input[type="month"].input-sm, + .input-group-sm input[type="date"], + .input-group-sm input[type="time"], + .input-group-sm input[type="datetime-local"], + .input-group-sm input[type="month"] { + line-height: 30px; + } + input[type="date"].input-lg, + input[type="time"].input-lg, + input[type="datetime-local"].input-lg, + input[type="month"].input-lg, + .input-group-lg input[type="date"], + .input-group-lg input[type="time"], + .input-group-lg input[type="datetime-local"], + .input-group-lg input[type="month"] { + line-height: 46px; + } +} +.form-group { + margin-bottom: 15px; +} +.radio, +.checkbox { + position: relative; + display: block; + margin-top: 10px; + margin-bottom: 10px; +} +.radio label, +.checkbox label { + min-height: 20px; + padding-left: 20px; + margin-bottom: 0; + font-weight: normal; + cursor: pointer; +} +.radio input[type="radio"], +.radio-inline input[type="radio"], +.checkbox input[type="checkbox"], +.checkbox-inline input[type="checkbox"] { + position: absolute; + margin-left: -20px; + margin-top: 4px \9; +} +.radio + .radio, +.checkbox + .checkbox { + margin-top: -5px; +} +.radio-inline, +.checkbox-inline { + position: relative; + display: inline-block; + padding-left: 20px; + margin-bottom: 0; + vertical-align: middle; + font-weight: normal; + cursor: pointer; +} +.radio-inline + .radio-inline, +.checkbox-inline + .checkbox-inline { + margin-top: 0; + margin-left: 10px; +} +input[type="radio"][disabled], +input[type="checkbox"][disabled], +input[type="radio"].disabled, +input[type="checkbox"].disabled, +fieldset[disabled] input[type="radio"], +fieldset[disabled] input[type="checkbox"] { + cursor: not-allowed; +} +.radio-inline.disabled, +.checkbox-inline.disabled, +fieldset[disabled] .radio-inline, +fieldset[disabled] .checkbox-inline { + cursor: not-allowed; +} +.radio.disabled label, +.checkbox.disabled label, +fieldset[disabled] .radio label, +fieldset[disabled] .checkbox label { + cursor: not-allowed; +} +.form-control-static { + padding-top: 7px; + padding-bottom: 7px; + margin-bottom: 0; + min-height: 34px; +} +.form-control-static.input-lg, +.form-control-static.input-sm { + padding-left: 0; + padding-right: 0; +} +.input-sm { + height: 30px; + padding: 5px 10px; + font-size: 12px; + line-height: 1.5; + border-radius: 3px; +} +select.input-sm { + height: 30px; + line-height: 30px; +} +textarea.input-sm, +select[multiple].input-sm { + height: auto; +} +.form-group-sm .form-control { + height: 30px; + padding: 5px 10px; + font-size: 12px; + line-height: 1.5; + border-radius: 3px; +} +.form-group-sm select.form-control { + height: 30px; + line-height: 30px; +} +.form-group-sm textarea.form-control, +.form-group-sm select[multiple].form-control { + height: auto; +} +.form-group-sm .form-control-static { + height: 30px; + min-height: 32px; + padding: 6px 10px; + font-size: 12px; + line-height: 1.5; +} +.input-lg { + height: 46px; + padding: 10px 16px; + font-size: 18px; + line-height: 1.3333333; + border-radius: 6px; +} +select.input-lg { + height: 46px; + line-height: 46px; +} +textarea.input-lg, +select[multiple].input-lg { + height: auto; +} +.form-group-lg .form-control { + height: 46px; + padding: 10px 16px; + font-size: 18px; + line-height: 1.3333333; + border-radius: 6px; +} +.form-group-lg select.form-control { + height: 46px; + line-height: 46px; +} +.form-group-lg textarea.form-control, +.form-group-lg select[multiple].form-control { + height: auto; +} +.form-group-lg .form-control-static { + height: 46px; + min-height: 38px; + padding: 11px 16px; + font-size: 18px; + line-height: 1.3333333; +} +.has-feedback { + position: relative; +} +.has-feedback .form-control { + padding-right: 42.5px; +} +.form-control-feedback { + position: absolute; + top: 0; + right: 0; + z-index: 2; + display: block; + width: 34px; + height: 34px; + line-height: 34px; + text-align: center; + pointer-events: none; +} +.input-lg + .form-control-feedback, +.input-group-lg + .form-control-feedback, +.form-group-lg .form-control + .form-control-feedback { + width: 46px; + height: 46px; + line-height: 46px; +} +.input-sm + .form-control-feedback, +.input-group-sm + .form-control-feedback, +.form-group-sm .form-control + .form-control-feedback { + width: 30px; + height: 30px; + line-height: 30px; +} +.has-success .help-block, +.has-success .control-label, +.has-success .radio, +.has-success .checkbox, +.has-success .radio-inline, +.has-success .checkbox-inline, +.has-success.radio label, +.has-success.checkbox label, +.has-success.radio-inline label, +.has-success.checkbox-inline label { + color: #3c763d; +} +.has-success .form-control { + border-color: #3c763d; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); +} +.has-success .form-control:focus { + border-color: #2b542c; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #67b168; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #67b168; +} +.has-success .input-group-addon { + color: #3c763d; + border-color: #3c763d; + background-color: #dff0d8; +} +.has-success .form-control-feedback { + color: #3c763d; +} +.has-warning .help-block, +.has-warning .control-label, +.has-warning .radio, +.has-warning .checkbox, +.has-warning .radio-inline, +.has-warning .checkbox-inline, +.has-warning.radio label, +.has-warning.checkbox label, +.has-warning.radio-inline label, +.has-warning.checkbox-inline label { + color: #8a6d3b; +} +.has-warning .form-control { + border-color: #8a6d3b; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); +} +.has-warning .form-control:focus { + border-color: #66512c; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #c0a16b; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #c0a16b; +} +.has-warning .input-group-addon { + color: #8a6d3b; + border-color: #8a6d3b; + background-color: #fcf8e3; +} +.has-warning .form-control-feedback { + color: #8a6d3b; +} +.has-error .help-block, +.has-error .control-label, +.has-error .radio, +.has-error .checkbox, +.has-error .radio-inline, +.has-error .checkbox-inline, +.has-error.radio label, +.has-error.checkbox label, +.has-error.radio-inline label, +.has-error.checkbox-inline label { + color: #632827; +} +.has-error .form-control { + border-color: #632827; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); +} +.has-error .form-control:focus { + border-color: #3e1919; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ac4644; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ac4644; +} +.has-error .input-group-addon { + color: #632827; + border-color: #632827; + background-color: #f2dede; +} +.has-error .form-control-feedback { + color: #632827; +} +.has-feedback label ~ .form-control-feedback { + top: 25px; +} +.has-feedback label.sr-only ~ .form-control-feedback { + top: 0; +} +.help-block { + display: block; + margin-top: 5px; + margin-bottom: 10px; + color: #404040; +} +@media (min-width: 768px) { + .form-inline .form-group { + display: inline-block; + margin-bottom: 0; + vertical-align: middle; + } + .form-inline .form-control { + display: inline-block; + width: auto; + vertical-align: middle; + } + .form-inline .form-control-static { + display: inline-block; + } + .form-inline .input-group { + display: inline-table; + vertical-align: middle; + } + .form-inline .input-group .input-group-addon, + .form-inline .input-group .input-group-btn, + .form-inline .input-group .form-control { + width: auto; + } + .form-inline .input-group > .form-control { + width: 100%; + } + .form-inline .control-label { + margin-bottom: 0; + vertical-align: middle; + } + .form-inline .radio, + .form-inline .checkbox { + display: inline-block; + margin-top: 0; + margin-bottom: 0; + vertical-align: middle; + } + .form-inline .radio label, + .form-inline .checkbox label { + padding-left: 0; + } + .form-inline .radio input[type="radio"], + .form-inline .checkbox input[type="checkbox"] { + position: relative; + margin-left: 0; + } + .form-inline .has-feedback .form-control-feedback { + top: 0; + } +} +.form-horizontal .radio, +.form-horizontal .checkbox, +.form-horizontal .radio-inline, +.form-horizontal .checkbox-inline { + margin-top: 0; + margin-bottom: 0; + padding-top: 7px; +} +.form-horizontal .radio, +.form-horizontal .checkbox { + min-height: 27px; +} +.form-horizontal .form-group { + margin-left: -15px; + margin-right: -15px; +} +@media (min-width: 768px) { + .form-horizontal .control-label { + text-align: right; + margin-bottom: 0; + padding-top: 7px; + } +} +.form-horizontal .has-feedback .form-control-feedback { + right: 15px; +} +@media (min-width: 768px) { + .form-horizontal .form-group-lg .control-label { + padding-top: 11px; + font-size: 18px; + } +} +@media (min-width: 768px) { + .form-horizontal .form-group-sm .control-label { + padding-top: 6px; + font-size: 12px; + } +} +.btn { + display: inline-block; + margin-bottom: 0; + font-weight: normal; + text-align: center; + vertical-align: middle; + touch-action: manipulation; + cursor: pointer; + background-image: none; + border: 1px solid transparent; + white-space: nowrap; + padding: 6px 12px; + font-size: 14px; + line-height: 1.42857143; + border-radius: 4px; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} +.btn:focus, +.btn:active:focus, +.btn.active:focus, +.btn.focus, +.btn:active.focus, +.btn.active.focus { + outline: thin dotted; + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; +} +.btn:hover, +.btn:focus, +.btn.focus { + color: #FFFFFF; + text-decoration: none; +} +.btn:active, +.btn.active { + outline: 0; + background-image: none; + -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); + box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); +} +.btn.disabled, +.btn[disabled], +fieldset[disabled] .btn { + cursor: not-allowed; + opacity: 0.65; + filter: alpha(opacity=65); + -webkit-box-shadow: none; + box-shadow: none; +} +a.btn.disabled, +fieldset[disabled] a.btn { + pointer-events: none; +} +.btn-default { + color: #FFFFFF; + background-color: #37474F; + border-color: #ccc; +} +.btn-default:focus, +.btn-default.focus { + color: #FFFFFF; + background-color: #222c31; + border-color: #8c8c8c; +} +.btn-default:hover { + color: #FFFFFF; + background-color: #222c31; + border-color: #adadad; +} +.btn-default:active, +.btn-default.active, +.open > .dropdown-toggle.btn-default { + color: #FFFFFF; + background-color: #222c31; + border-color: #adadad; +} +.btn-default:active:hover, +.btn-default.active:hover, +.open > .dropdown-toggle.btn-default:hover, +.btn-default:active:focus, +.btn-default.active:focus, +.open > .dropdown-toggle.btn-default:focus, +.btn-default:active.focus, +.btn-default.active.focus, +.open > .dropdown-toggle.btn-default.focus { + color: #FFFFFF; + background-color: #13191c; + border-color: #8c8c8c; +} +.btn-default:active, +.btn-default.active, +.open > .dropdown-toggle.btn-default { + background-image: none; +} +.btn-default.disabled:hover, +.btn-default[disabled]:hover, +fieldset[disabled] .btn-default:hover, +.btn-default.disabled:focus, +.btn-default[disabled]:focus, +fieldset[disabled] .btn-default:focus, +.btn-default.disabled.focus, +.btn-default[disabled].focus, +fieldset[disabled] .btn-default.focus { + background-color: #37474F; + border-color: #ccc; +} +.btn-default .badge { + color: #37474F; + background-color: #FFFFFF; +} +.btn-primary { + color: #EEEEEE; + background-color: #263238; + border-color: #1c2429; +} +.btn-primary:focus, +.btn-primary.focus { + color: #EEEEEE; + background-color: #11171a; + border-color: #000000; +} +.btn-primary:hover { + color: #EEEEEE; + background-color: #11171a; + border-color: #030404; +} +.btn-primary:active, +.btn-primary.active, +.open > .dropdown-toggle.btn-primary { + color: #EEEEEE; + background-color: #11171a; + border-color: #030404; +} +.btn-primary:active:hover, +.btn-primary.active:hover, +.open > .dropdown-toggle.btn-primary:hover, +.btn-primary:active:focus, +.btn-primary.active:focus, +.open > .dropdown-toggle.btn-primary:focus, +.btn-primary:active.focus, +.btn-primary.active.focus, +.open > .dropdown-toggle.btn-primary.focus { + color: #EEEEEE; + background-color: #030404; + border-color: #000000; +} +.btn-primary:active, +.btn-primary.active, +.open > .dropdown-toggle.btn-primary { + background-image: none; +} +.btn-primary.disabled:hover, +.btn-primary[disabled]:hover, +fieldset[disabled] .btn-primary:hover, +.btn-primary.disabled:focus, +.btn-primary[disabled]:focus, +fieldset[disabled] .btn-primary:focus, +.btn-primary.disabled.focus, +.btn-primary[disabled].focus, +fieldset[disabled] .btn-primary.focus { + background-color: #263238; + border-color: #1c2429; +} +.btn-primary .badge { + color: #263238; + background-color: #EEEEEE; +} +.btn-success { + color: #fff; + background-color: #5cb85c; + border-color: #4cae4c; +} +.btn-success:focus, +.btn-success.focus { + color: #fff; + background-color: #449d44; + border-color: #255625; +} +.btn-success:hover { + color: #fff; + background-color: #449d44; + border-color: #398439; +} +.btn-success:active, +.btn-success.active, +.open > .dropdown-toggle.btn-success { + color: #fff; + background-color: #449d44; + border-color: #398439; +} +.btn-success:active:hover, +.btn-success.active:hover, +.open > .dropdown-toggle.btn-success:hover, +.btn-success:active:focus, +.btn-success.active:focus, +.open > .dropdown-toggle.btn-success:focus, +.btn-success:active.focus, +.btn-success.active.focus, +.open > .dropdown-toggle.btn-success.focus { + color: #fff; + background-color: #398439; + border-color: #255625; +} +.btn-success:active, +.btn-success.active, +.open > .dropdown-toggle.btn-success { + background-image: none; +} +.btn-success.disabled:hover, +.btn-success[disabled]:hover, +fieldset[disabled] .btn-success:hover, +.btn-success.disabled:focus, +.btn-success[disabled]:focus, +fieldset[disabled] .btn-success:focus, +.btn-success.disabled.focus, +.btn-success[disabled].focus, +fieldset[disabled] .btn-success.focus { + background-color: #5cb85c; + border-color: #4cae4c; +} +.btn-success .badge { + color: #5cb85c; + background-color: #fff; +} +.btn-info { + color: #fff; + background-color: #5bc0de; + border-color: #46b8da; +} +.btn-info:focus, +.btn-info.focus { + color: #fff; + background-color: #31b0d5; + border-color: #1b6d85; +} +.btn-info:hover { + color: #fff; + background-color: #31b0d5; + border-color: #269abc; +} +.btn-info:active, +.btn-info.active, +.open > .dropdown-toggle.btn-info { + color: #fff; + background-color: #31b0d5; + border-color: #269abc; +} +.btn-info:active:hover, +.btn-info.active:hover, +.open > .dropdown-toggle.btn-info:hover, +.btn-info:active:focus, +.btn-info.active:focus, +.open > .dropdown-toggle.btn-info:focus, +.btn-info:active.focus, +.btn-info.active.focus, +.open > .dropdown-toggle.btn-info.focus { + color: #fff; + background-color: #269abc; + border-color: #1b6d85; +} +.btn-info:active, +.btn-info.active, +.open > .dropdown-toggle.btn-info { + background-image: none; +} +.btn-info.disabled:hover, +.btn-info[disabled]:hover, +fieldset[disabled] .btn-info:hover, +.btn-info.disabled:focus, +.btn-info[disabled]:focus, +fieldset[disabled] .btn-info:focus, +.btn-info.disabled.focus, +.btn-info[disabled].focus, +fieldset[disabled] .btn-info.focus { + background-color: #5bc0de; + border-color: #46b8da; +} +.btn-info .badge { + color: #5bc0de; + background-color: #fff; +} +.btn-warning { + color: #fff; + background-color: #f0ad4e; + border-color: #eea236; +} +.btn-warning:focus, +.btn-warning.focus { + color: #fff; + background-color: #ec971f; + border-color: #985f0d; +} +.btn-warning:hover { + color: #fff; + background-color: #ec971f; + border-color: #d58512; +} +.btn-warning:active, +.btn-warning.active, +.open > .dropdown-toggle.btn-warning { + color: #fff; + background-color: #ec971f; + border-color: #d58512; +} +.btn-warning:active:hover, +.btn-warning.active:hover, +.open > .dropdown-toggle.btn-warning:hover, +.btn-warning:active:focus, +.btn-warning.active:focus, +.open > .dropdown-toggle.btn-warning:focus, +.btn-warning:active.focus, +.btn-warning.active.focus, +.open > .dropdown-toggle.btn-warning.focus { + color: #fff; + background-color: #d58512; + border-color: #985f0d; +} +.btn-warning:active, +.btn-warning.active, +.open > .dropdown-toggle.btn-warning { + background-image: none; +} +.btn-warning.disabled:hover, +.btn-warning[disabled]:hover, +fieldset[disabled] .btn-warning:hover, +.btn-warning.disabled:focus, +.btn-warning[disabled]:focus, +fieldset[disabled] .btn-warning:focus, +.btn-warning.disabled.focus, +.btn-warning[disabled].focus, +fieldset[disabled] .btn-warning.focus { + background-color: #f0ad4e; + border-color: #eea236; +} +.btn-warning .badge { + color: #f0ad4e; + background-color: #fff; +} +.btn-danger { + color: #fff; + background-color: #d9534f; + border-color: #d43f3a; +} +.btn-danger:focus, +.btn-danger.focus { + color: #fff; + background-color: #c9302c; + border-color: #761c19; +} +.btn-danger:hover { + color: #fff; + background-color: #c9302c; + border-color: #ac2925; +} +.btn-danger:active, +.btn-danger.active, +.open > .dropdown-toggle.btn-danger { + color: #fff; + background-color: #c9302c; + border-color: #ac2925; +} +.btn-danger:active:hover, +.btn-danger.active:hover, +.open > .dropdown-toggle.btn-danger:hover, +.btn-danger:active:focus, +.btn-danger.active:focus, +.open > .dropdown-toggle.btn-danger:focus, +.btn-danger:active.focus, +.btn-danger.active.focus, +.open > .dropdown-toggle.btn-danger.focus { + color: #fff; + background-color: #ac2925; + border-color: #761c19; +} +.btn-danger:active, +.btn-danger.active, +.open > .dropdown-toggle.btn-danger { + background-image: none; +} +.btn-danger.disabled:hover, +.btn-danger[disabled]:hover, +fieldset[disabled] .btn-danger:hover, +.btn-danger.disabled:focus, +.btn-danger[disabled]:focus, +fieldset[disabled] .btn-danger:focus, +.btn-danger.disabled.focus, +.btn-danger[disabled].focus, +fieldset[disabled] .btn-danger.focus { + background-color: #d9534f; + border-color: #d43f3a; +} +.btn-danger .badge { + color: #d9534f; + background-color: #fff; +} +.btn-link { + color: #337ab7; + font-weight: normal; + border-radius: 0; +} +.btn-link, +.btn-link:active, +.btn-link.active, +.btn-link[disabled], +fieldset[disabled] .btn-link { + background-color: transparent; + -webkit-box-shadow: none; + box-shadow: none; +} +.btn-link, +.btn-link:hover, +.btn-link:focus, +.btn-link:active { + border-color: transparent; +} +.btn-link:hover, +.btn-link:focus { + color: #23527c; + text-decoration: underline; + background-color: transparent; +} +.btn-link[disabled]:hover, +fieldset[disabled] .btn-link:hover, +.btn-link[disabled]:focus, +fieldset[disabled] .btn-link:focus { + color: #616161; + text-decoration: none; +} +.btn-lg, +.btn-group-lg > .btn { + padding: 10px 16px; + font-size: 18px; + line-height: 1.3333333; + border-radius: 6px; +} +.btn-sm, +.btn-group-sm > .btn { + padding: 5px 10px; + font-size: 12px; + line-height: 1.5; + border-radius: 3px; +} +.btn-xs, +.btn-group-xs > .btn { + padding: 1px 5px; + font-size: 12px; + line-height: 1.5; + border-radius: 3px; +} +.btn-block { + display: block; + width: 100%; +} +.btn-block + .btn-block { + margin-top: 5px; +} +input[type="submit"].btn-block, +input[type="reset"].btn-block, +input[type="button"].btn-block { + width: 100%; +} +.btn-group, +.btn-group-vertical { + position: relative; + display: inline-block; + vertical-align: middle; +} +.btn-group > .btn, +.btn-group-vertical > .btn { + position: relative; + float: left; +} +.btn-group > .btn:hover, +.btn-group-vertical > .btn:hover, +.btn-group > .btn:focus, +.btn-group-vertical > .btn:focus, +.btn-group > .btn:active, +.btn-group-vertical > .btn:active, +.btn-group > .btn.active, +.btn-group-vertical > .btn.active { + z-index: 2; +} +.btn-group .btn + .btn, +.btn-group .btn + .btn-group, +.btn-group .btn-group + .btn, +.btn-group .btn-group + .btn-group { + margin-left: -1px; +} +.btn-toolbar { + margin-left: -5px; +} +.btn-toolbar .btn, +.btn-toolbar .btn-group, +.btn-toolbar .input-group { + float: left; +} +.btn-toolbar > .btn, +.btn-toolbar > .btn-group, +.btn-toolbar > .input-group { + margin-left: 5px; +} +.btn-group > .btn:not(:first-child):not(:last-child):not(.dropdown-toggle) { + border-radius: 0; +} +.btn-group > .btn:first-child { + margin-left: 0; +} +.btn-group > .btn:first-child:not(:last-child):not(.dropdown-toggle) { + border-bottom-right-radius: 0; + border-top-right-radius: 0; +} +.btn-group > .btn:last-child:not(:first-child), +.btn-group > .dropdown-toggle:not(:first-child) { + border-bottom-left-radius: 0; + border-top-left-radius: 0; +} +.btn-group > .btn-group { + float: left; +} +.btn-group > .btn-group:not(:first-child):not(:last-child) > .btn { + border-radius: 0; +} +.btn-group > .btn-group:first-child:not(:last-child) > .btn:last-child, +.btn-group > .btn-group:first-child:not(:last-child) > .dropdown-toggle { + border-bottom-right-radius: 0; + border-top-right-radius: 0; +} +.btn-group > .btn-group:last-child:not(:first-child) > .btn:first-child { + border-bottom-left-radius: 0; + border-top-left-radius: 0; +} +.btn-group .dropdown-toggle:active, +.btn-group.open .dropdown-toggle { + outline: 0; +} +.btn-group > .btn + .dropdown-toggle { + padding-left: 8px; + padding-right: 8px; +} +.btn-group > .btn-lg + .dropdown-toggle { + padding-left: 12px; + padding-right: 12px; +} +.btn-group.open .dropdown-toggle { + -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); + box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); +} +.btn-group.open .dropdown-toggle.btn-link { + -webkit-box-shadow: none; + box-shadow: none; +} +.btn .caret { + margin-left: 0; +} +.btn-lg .caret { + border-width: 5px 5px 0; + border-bottom-width: 0; +} +.dropup .btn-lg .caret { + border-width: 0 5px 5px; +} +.btn-group-vertical > .btn, +.btn-group-vertical > .btn-group, +.btn-group-vertical > .btn-group > .btn { + display: block; + float: none; + width: 100%; + max-width: 100%; +} +.btn-group-vertical > .btn-group > .btn { + float: none; +} +.btn-group-vertical > .btn + .btn, +.btn-group-vertical > .btn + .btn-group, +.btn-group-vertical > .btn-group + .btn, +.btn-group-vertical > .btn-group + .btn-group { + margin-top: -1px; + margin-left: 0; +} +.btn-group-vertical > .btn:not(:first-child):not(:last-child) { + border-radius: 0; +} +.btn-group-vertical > .btn:first-child:not(:last-child) { + border-top-right-radius: 4px; + border-top-left-radius: 4px; + border-bottom-right-radius: 0; + border-bottom-left-radius: 0; +} +.btn-group-vertical > .btn:last-child:not(:first-child) { + border-top-right-radius: 0; + border-top-left-radius: 0; + border-bottom-right-radius: 4px; + border-bottom-left-radius: 4px; +} +.btn-group-vertical > .btn-group:not(:first-child):not(:last-child) > .btn { + border-radius: 0; +} +.btn-group-vertical > .btn-group:first-child:not(:last-child) > .btn:last-child, +.btn-group-vertical > .btn-group:first-child:not(:last-child) > .dropdown-toggle { + border-bottom-right-radius: 0; + border-bottom-left-radius: 0; +} +.btn-group-vertical > .btn-group:last-child:not(:first-child) > .btn:first-child { + border-top-right-radius: 0; + border-top-left-radius: 0; +} +.btn-group-justified { + display: table; + width: 100%; + table-layout: fixed; + border-collapse: separate; +} +.btn-group-justified > .btn, +.btn-group-justified > .btn-group { + float: none; + display: table-cell; + width: 1%; +} +.btn-group-justified > .btn-group .btn { + width: 100%; +} +.btn-group-justified > .btn-group .dropdown-menu { + left: auto; +} +[data-toggle="buttons"] > .btn input[type="radio"], +[data-toggle="buttons"] > .btn-group > .btn input[type="radio"], +[data-toggle="buttons"] > .btn input[type="checkbox"], +[data-toggle="buttons"] > .btn-group > .btn input[type="checkbox"] { + position: absolute; + clip: rect(0, 0, 0, 0); + pointer-events: none; +} +.input-group { + position: relative; + display: table; + border-collapse: separate; +} +.input-group[class*="col-"] { + float: none; + padding-left: 0; + padding-right: 0; +} +.input-group .form-control { + position: relative; + z-index: 2; + float: left; + width: 100%; + margin-bottom: 0; +} +.input-group .form-control:focus { + z-index: 3; +} +.input-group-lg > .form-control, +.input-group-lg > .input-group-addon, +.input-group-lg > .input-group-btn > .btn { + height: 46px; + padding: 10px 16px; + font-size: 18px; + line-height: 1.3333333; + border-radius: 6px; +} +select.input-group-lg > .form-control, +select.input-group-lg > .input-group-addon, +select.input-group-lg > .input-group-btn > .btn { + height: 46px; + line-height: 46px; +} +textarea.input-group-lg > .form-control, +textarea.input-group-lg > .input-group-addon, +textarea.input-group-lg > .input-group-btn > .btn, +select[multiple].input-group-lg > .form-control, +select[multiple].input-group-lg > .input-group-addon, +select[multiple].input-group-lg > .input-group-btn > .btn { + height: auto; +} +.input-group-sm > .form-control, +.input-group-sm > .input-group-addon, +.input-group-sm > .input-group-btn > .btn { + height: 30px; + padding: 5px 10px; + font-size: 12px; + line-height: 1.5; + border-radius: 3px; +} +select.input-group-sm > .form-control, +select.input-group-sm > .input-group-addon, +select.input-group-sm > .input-group-btn > .btn { + height: 30px; + line-height: 30px; +} +textarea.input-group-sm > .form-control, +textarea.input-group-sm > .input-group-addon, +textarea.input-group-sm > .input-group-btn > .btn, +select[multiple].input-group-sm > .form-control, +select[multiple].input-group-sm > .input-group-addon, +select[multiple].input-group-sm > .input-group-btn > .btn { + height: auto; +} +.input-group-addon, +.input-group-btn, +.input-group .form-control { + display: table-cell; +} +.input-group-addon:not(:first-child):not(:last-child), +.input-group-btn:not(:first-child):not(:last-child), +.input-group .form-control:not(:first-child):not(:last-child) { + border-radius: 0; +} +.input-group-addon, +.input-group-btn { + width: 1%; + white-space: nowrap; + vertical-align: middle; +} +.input-group-addon { + padding: 6px 12px; + font-size: 14px; + font-weight: normal; + line-height: 1; + color: #000000; + text-align: center; + background-color: #EEEEEE; + border: 1px solid #ccc; + border-radius: 4px; +} +.input-group-addon.input-sm { + padding: 5px 10px; + font-size: 12px; + border-radius: 3px; +} +.input-group-addon.input-lg { + padding: 10px 16px; + font-size: 18px; + border-radius: 6px; +} +.input-group-addon input[type="radio"], +.input-group-addon input[type="checkbox"] { + margin-top: 0; +} +.input-group .form-control:first-child, +.input-group-addon:first-child, +.input-group-btn:first-child > .btn, +.input-group-btn:first-child > .btn-group > .btn, +.input-group-btn:first-child > .dropdown-toggle, +.input-group-btn:last-child > .btn:not(:last-child):not(.dropdown-toggle), +.input-group-btn:last-child > .btn-group:not(:last-child) > .btn { + border-bottom-right-radius: 0; + border-top-right-radius: 0; +} +.input-group-addon:first-child { + border-right: 0; +} +.input-group .form-control:last-child, +.input-group-addon:last-child, +.input-group-btn:last-child > .btn, +.input-group-btn:last-child > .btn-group > .btn, +.input-group-btn:last-child > .dropdown-toggle, +.input-group-btn:first-child > .btn:not(:first-child), +.input-group-btn:first-child > .btn-group:not(:first-child) > .btn { + border-bottom-left-radius: 0; + border-top-left-radius: 0; +} +.input-group-addon:last-child { + border-left: 0; +} +.input-group-btn { + position: relative; + font-size: 0; + white-space: nowrap; +} +.input-group-btn > .btn { + position: relative; +} +.input-group-btn > .btn + .btn { + margin-left: -1px; +} +.input-group-btn > .btn:hover, +.input-group-btn > .btn:focus, +.input-group-btn > .btn:active { + z-index: 2; +} +.input-group-btn:first-child > .btn, +.input-group-btn:first-child > .btn-group { + margin-right: -1px; +} +.input-group-btn:last-child > .btn, +.input-group-btn:last-child > .btn-group { + z-index: 2; + margin-left: -1px; +} +table { + background-color: transparent; +} +caption { + padding-top: 8px; + padding-bottom: 8px; + color: #616161; + text-align: left; +} +th { + text-align: left; +} +.table { + width: 100%; + max-width: 100%; + margin-bottom: 20px; +} +.table > thead > tr > th, +.table > tbody > tr > th, +.table > tfoot > tr > th, +.table > thead > tr > td, +.table > tbody > tr > td, +.table > tfoot > tr > td { + padding: 8px; + line-height: 1.42857143; + vertical-align: top; + border-top: 1px solid #ddd; +} +.table > thead > tr > th { + vertical-align: bottom; + border-bottom: 2px solid #ddd; +} +.table > caption + thead > tr:first-child > th, +.table > colgroup + thead > tr:first-child > th, +.table > thead:first-child > tr:first-child > th, +.table > caption + thead > tr:first-child > td, +.table > colgroup + thead > tr:first-child > td, +.table > thead:first-child > tr:first-child > td { + border-top: 0; +} +.table > tbody + tbody { + border-top: 2px solid #ddd; +} +.table .table { + background-color: #fff; +} +.table-condensed > thead > tr > th, +.table-condensed > tbody > tr > th, +.table-condensed > tfoot > tr > th, +.table-condensed > thead > tr > td, +.table-condensed > tbody > tr > td, +.table-condensed > tfoot > tr > td { + padding: 5px; +} +.table-bordered { + border: 1px solid #ddd; +} +.table-bordered > thead > tr > th, +.table-bordered > tbody > tr > th, +.table-bordered > tfoot > tr > th, +.table-bordered > thead > tr > td, +.table-bordered > tbody > tr > td, +.table-bordered > tfoot > tr > td { + border: 1px solid #ddd; +} +.table-bordered > thead > tr > th, +.table-bordered > thead > tr > td { + border-bottom-width: 2px; +} +.table-striped > tbody > tr:nth-of-type(odd) { + background-color: #f9f9f9; +} +.table-hover > tbody > tr:hover { + background-color: #f5f5f5; +} +table col[class*="col-"] { + position: static; + float: none; + display: table-column; +} +table td[class*="col-"], +table th[class*="col-"] { + position: static; + float: none; + display: table-cell; +} +.table > thead > tr > td.active, +.table > tbody > tr > td.active, +.table > tfoot > tr > td.active, +.table > thead > tr > th.active, +.table > tbody > tr > th.active, +.table > tfoot > tr > th.active, +.table > thead > tr.active > td, +.table > tbody > tr.active > td, +.table > tfoot > tr.active > td, +.table > thead > tr.active > th, +.table > tbody > tr.active > th, +.table > tfoot > tr.active > th { + background-color: #f5f5f5; +} +.table-hover > tbody > tr > td.active:hover, +.table-hover > tbody > tr > th.active:hover, +.table-hover > tbody > tr.active:hover > td, +.table-hover > tbody > tr:hover > .active, +.table-hover > tbody > tr.active:hover > th { + background-color: #e8e8e8; +} +.table > thead > tr > td.success, +.table > tbody > tr > td.success, +.table > tfoot > tr > td.success, +.table > thead > tr > th.success, +.table > tbody > tr > th.success, +.table > tfoot > tr > th.success, +.table > thead > tr.success > td, +.table > tbody > tr.success > td, +.table > tfoot > tr.success > td, +.table > thead > tr.success > th, +.table > tbody > tr.success > th, +.table > tfoot > tr.success > th { + background-color: #dff0d8; +} +.table-hover > tbody > tr > td.success:hover, +.table-hover > tbody > tr > th.success:hover, +.table-hover > tbody > tr.success:hover > td, +.table-hover > tbody > tr:hover > .success, +.table-hover > tbody > tr.success:hover > th { + background-color: #d0e9c6; +} +.table > thead > tr > td.info, +.table > tbody > tr > td.info, +.table > tfoot > tr > td.info, +.table > thead > tr > th.info, +.table > tbody > tr > th.info, +.table > tfoot > tr > th.info, +.table > thead > tr.info > td, +.table > tbody > tr.info > td, +.table > tfoot > tr.info > td, +.table > thead > tr.info > th, +.table > tbody > tr.info > th, +.table > tfoot > tr.info > th { + background-color: #d9edf7; +} +.table-hover > tbody > tr > td.info:hover, +.table-hover > tbody > tr > th.info:hover, +.table-hover > tbody > tr.info:hover > td, +.table-hover > tbody > tr:hover > .info, +.table-hover > tbody > tr.info:hover > th { + background-color: #c4e3f3; +} +.table > thead > tr > td.warning, +.table > tbody > tr > td.warning, +.table > tfoot > tr > td.warning, +.table > thead > tr > th.warning, +.table > tbody > tr > th.warning, +.table > tfoot > tr > th.warning, +.table > thead > tr.warning > td, +.table > tbody > tr.warning > td, +.table > tfoot > tr.warning > td, +.table > thead > tr.warning > th, +.table > tbody > tr.warning > th, +.table > tfoot > tr.warning > th { + background-color: #fcf8e3; +} +.table-hover > tbody > tr > td.warning:hover, +.table-hover > tbody > tr > th.warning:hover, +.table-hover > tbody > tr.warning:hover > td, +.table-hover > tbody > tr:hover > .warning, +.table-hover > tbody > tr.warning:hover > th { + background-color: #faf2cc; +} +.table > thead > tr > td.danger, +.table > tbody > tr > td.danger, +.table > tfoot > tr > td.danger, +.table > thead > tr > th.danger, +.table > tbody > tr > th.danger, +.table > tfoot > tr > th.danger, +.table > thead > tr.danger > td, +.table > tbody > tr.danger > td, +.table > tfoot > tr.danger > td, +.table > thead > tr.danger > th, +.table > tbody > tr.danger > th, +.table > tfoot > tr.danger > th { + background-color: #f2dede; +} +.table-hover > tbody > tr > td.danger:hover, +.table-hover > tbody > tr > th.danger:hover, +.table-hover > tbody > tr.danger:hover > td, +.table-hover > tbody > tr:hover > .danger, +.table-hover > tbody > tr.danger:hover > th { + background-color: #ebcccc; +} +.table-responsive { + overflow-x: auto; + min-height: 0.01%; +} +@media screen and (max-width: 767px) { + .table-responsive { + width: 100%; + margin-bottom: 15px; + overflow-y: hidden; + -ms-overflow-style: -ms-autohiding-scrollbar; + border: 1px solid #ddd; + } + .table-responsive > .table { + margin-bottom: 0; + } + .table-responsive > .table > thead > tr > th, + .table-responsive > .table > tbody > tr > th, + .table-responsive > .table > tfoot > tr > th, + .table-responsive > .table > thead > tr > td, + .table-responsive > .table > tbody > tr > td, + .table-responsive > .table > tfoot > tr > td { + white-space: nowrap; + } + .table-responsive > .table-bordered { + border: 0; + } + .table-responsive > .table-bordered > thead > tr > th:first-child, + .table-responsive > .table-bordered > tbody > tr > th:first-child, + .table-responsive > .table-bordered > tfoot > tr > th:first-child, + .table-responsive > .table-bordered > thead > tr > td:first-child, + .table-responsive > .table-bordered > tbody > tr > td:first-child, + .table-responsive > .table-bordered > tfoot > tr > td:first-child { + border-left: 0; + } + .table-responsive > .table-bordered > thead > tr > th:last-child, + .table-responsive > .table-bordered > tbody > tr > th:last-child, + .table-responsive > .table-bordered > tfoot > tr > th:last-child, + .table-responsive > .table-bordered > thead > tr > td:last-child, + .table-responsive > .table-bordered > tbody > tr > td:last-child, + .table-responsive > .table-bordered > tfoot > tr > td:last-child { + border-right: 0; + } + .table-responsive > .table-bordered > tbody > tr:last-child > th, + .table-responsive > .table-bordered > tfoot > tr:last-child > th, + .table-responsive > .table-bordered > tbody > tr:last-child > td, + .table-responsive > .table-bordered > tfoot > tr:last-child > td { + border-bottom: 0; + } +} +@font-face { + font-family: 'Glyphicons Halflings'; + src: url('node_modules/bootstrap/fonts/glyphicons-halflings-regular.eot'); + src: url('node_modules/bootstrap/fonts/glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'), url('node_modules/bootstrap/fonts/glyphicons-halflings-regular.woff2') format('woff2'), url('node_modules/bootstrap/fonts/glyphicons-halflings-regular.woff') format('woff'), url('node_modules/bootstrap/fonts/glyphicons-halflings-regular.ttf') format('truetype'), url('node_modules/bootstrap/fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular') format('svg'); +} +.glyphicon { + position: relative; + top: 1px; + display: inline-block; + font-family: 'Glyphicons Halflings'; + font-style: normal; + font-weight: normal; + line-height: 1; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} +.glyphicon-asterisk:before { + content: "\002a"; +} +.glyphicon-plus:before { + content: "\002b"; +} +.glyphicon-euro:before, +.glyphicon-eur:before { + content: "\20ac"; +} +.glyphicon-minus:before { + content: "\2212"; +} +.glyphicon-cloud:before { + content: "\2601"; +} +.glyphicon-envelope:before { + content: "\2709"; +} +.glyphicon-pencil:before { + content: "\270f"; +} +.glyphicon-glass:before { + content: "\e001"; +} +.glyphicon-music:before { + content: "\e002"; +} +.glyphicon-search:before { + content: "\e003"; +} +.glyphicon-heart:before { + content: "\e005"; +} +.glyphicon-star:before { + content: "\e006"; +} +.glyphicon-star-empty:before { + content: "\e007"; +} +.glyphicon-user:before { + content: "\e008"; +} +.glyphicon-film:before { + content: "\e009"; +} +.glyphicon-th-large:before { + content: "\e010"; +} +.glyphicon-th:before { + content: "\e011"; +} +.glyphicon-th-list:before { + content: "\e012"; +} +.glyphicon-ok:before { + content: "\e013"; +} +.glyphicon-remove:before { + content: "\e014"; +} +.glyphicon-zoom-in:before { + content: "\e015"; +} +.glyphicon-zoom-out:before { + content: "\e016"; +} +.glyphicon-off:before { + content: "\e017"; +} +.glyphicon-signal:before { + content: "\e018"; +} +.glyphicon-cog:before { + content: "\e019"; +} +.glyphicon-trash:before { + content: "\e020"; +} +.glyphicon-home:before { + content: "\e021"; +} +.glyphicon-file:before { + content: "\e022"; +} +.glyphicon-time:before { + content: "\e023"; +} +.glyphicon-road:before { + content: "\e024"; +} +.glyphicon-download-alt:before { + content: "\e025"; +} +.glyphicon-download:before { + content: "\e026"; +} +.glyphicon-upload:before { + content: "\e027"; +} +.glyphicon-inbox:before { + content: "\e028"; +} +.glyphicon-play-circle:before { + content: "\e029"; +} +.glyphicon-repeat:before { + content: "\e030"; +} +.glyphicon-refresh:before { + content: "\e031"; +} +.glyphicon-list-alt:before { + content: "\e032"; +} +.glyphicon-lock:before { + content: "\e033"; +} +.glyphicon-flag:before { + content: "\e034"; +} +.glyphicon-headphones:before { + content: "\e035"; +} +.glyphicon-volume-off:before { + content: "\e036"; +} +.glyphicon-volume-down:before { + content: "\e037"; +} +.glyphicon-volume-up:before { + content: "\e038"; +} +.glyphicon-qrcode:before { + content: "\e039"; +} +.glyphicon-barcode:before { + content: "\e040"; +} +.glyphicon-tag:before { + content: "\e041"; +} +.glyphicon-tags:before { + content: "\e042"; +} +.glyphicon-book:before { + content: "\e043"; +} +.glyphicon-bookmark:before { + content: "\e044"; +} +.glyphicon-print:before { + content: "\e045"; +} +.glyphicon-camera:before { + content: "\e046"; +} +.glyphicon-font:before { + content: "\e047"; +} +.glyphicon-bold:before { + content: "\e048"; +} +.glyphicon-italic:before { + content: "\e049"; +} +.glyphicon-text-height:before { + content: "\e050"; +} +.glyphicon-text-width:before { + content: "\e051"; +} +.glyphicon-align-left:before { + content: "\e052"; +} +.glyphicon-align-center:before { + content: "\e053"; +} +.glyphicon-align-right:before { + content: "\e054"; +} +.glyphicon-align-justify:before { + content: "\e055"; +} +.glyphicon-list:before { + content: "\e056"; +} +.glyphicon-indent-left:before { + content: "\e057"; +} +.glyphicon-indent-right:before { + content: "\e058"; +} +.glyphicon-facetime-video:before { + content: "\e059"; +} +.glyphicon-picture:before { + content: "\e060"; +} +.glyphicon-map-marker:before { + content: "\e062"; +} +.glyphicon-adjust:before { + content: "\e063"; +} +.glyphicon-tint:before { + content: "\e064"; +} +.glyphicon-edit:before { + content: "\e065"; +} +.glyphicon-share:before { + content: "\e066"; +} +.glyphicon-check:before { + content: "\e067"; +} +.glyphicon-move:before { + content: "\e068"; +} +.glyphicon-step-backward:before { + content: "\e069"; +} +.glyphicon-fast-backward:before { + content: "\e070"; +} +.glyphicon-backward:before { + content: "\e071"; +} +.glyphicon-play:before { + content: "\e072"; +} +.glyphicon-pause:before { + content: "\e073"; +} +.glyphicon-stop:before { + content: "\e074"; +} +.glyphicon-forward:before { + content: "\e075"; +} +.glyphicon-fast-forward:before { + content: "\e076"; +} +.glyphicon-step-forward:before { + content: "\e077"; +} +.glyphicon-eject:before { + content: "\e078"; +} +.glyphicon-chevron-left:before { + content: "\e079"; +} +.glyphicon-chevron-right:before { + content: "\e080"; +} +.glyphicon-plus-sign:before { + content: "\e081"; +} +.glyphicon-minus-sign:before { + content: "\e082"; +} +.glyphicon-remove-sign:before { + content: "\e083"; +} +.glyphicon-ok-sign:before { + content: "\e084"; +} +.glyphicon-question-sign:before { + content: "\e085"; +} +.glyphicon-info-sign:before { + content: "\e086"; +} +.glyphicon-screenshot:before { + content: "\e087"; +} +.glyphicon-remove-circle:before { + content: "\e088"; +} +.glyphicon-ok-circle:before { + content: "\e089"; +} +.glyphicon-ban-circle:before { + content: "\e090"; +} +.glyphicon-arrow-left:before { + content: "\e091"; +} +.glyphicon-arrow-right:before { + content: "\e092"; +} +.glyphicon-arrow-up:before { + content: "\e093"; +} +.glyphicon-arrow-down:before { + content: "\e094"; +} +.glyphicon-share-alt:before { + content: "\e095"; +} +.glyphicon-resize-full:before { + content: "\e096"; +} +.glyphicon-resize-small:before { + content: "\e097"; +} +.glyphicon-exclamation-sign:before { + content: "\e101"; +} +.glyphicon-gift:before { + content: "\e102"; +} +.glyphicon-leaf:before { + content: "\e103"; +} +.glyphicon-fire:before { + content: "\e104"; +} +.glyphicon-eye-open:before { + content: "\e105"; +} +.glyphicon-eye-close:before { + content: "\e106"; +} +.glyphicon-warning-sign:before { + content: "\e107"; +} +.glyphicon-plane:before { + content: "\e108"; +} +.glyphicon-calendar:before { + content: "\e109"; +} +.glyphicon-random:before { + content: "\e110"; +} +.glyphicon-comment:before { + content: "\e111"; +} +.glyphicon-magnet:before { + content: "\e112"; +} +.glyphicon-chevron-up:before { + content: "\e113"; +} +.glyphicon-chevron-down:before { + content: "\e114"; +} +.glyphicon-retweet:before { + content: "\e115"; +} +.glyphicon-shopping-cart:before { + content: "\e116"; +} +.glyphicon-folder-close:before { + content: "\e117"; +} +.glyphicon-folder-open:before { + content: "\e118"; +} +.glyphicon-resize-vertical:before { + content: "\e119"; +} +.glyphicon-resize-horizontal:before { + content: "\e120"; +} +.glyphicon-hdd:before { + content: "\e121"; +} +.glyphicon-bullhorn:before { + content: "\e122"; +} +.glyphicon-bell:before { + content: "\e123"; +} +.glyphicon-certificate:before { + content: "\e124"; +} +.glyphicon-thumbs-up:before { + content: "\e125"; +} +.glyphicon-thumbs-down:before { + content: "\e126"; +} +.glyphicon-hand-right:before { + content: "\e127"; +} +.glyphicon-hand-left:before { + content: "\e128"; +} +.glyphicon-hand-up:before { + content: "\e129"; +} +.glyphicon-hand-down:before { + content: "\e130"; +} +.glyphicon-circle-arrow-right:before { + content: "\e131"; +} +.glyphicon-circle-arrow-left:before { + content: "\e132"; +} +.glyphicon-circle-arrow-up:before { + content: "\e133"; +} +.glyphicon-circle-arrow-down:before { + content: "\e134"; +} +.glyphicon-globe:before { + content: "\e135"; +} +.glyphicon-wrench:before { + content: "\e136"; +} +.glyphicon-tasks:before { + content: "\e137"; +} +.glyphicon-filter:before { + content: "\e138"; +} +.glyphicon-briefcase:before { + content: "\e139"; +} +.glyphicon-fullscreen:before { + content: "\e140"; +} +.glyphicon-dashboard:before { + content: "\e141"; +} +.glyphicon-paperclip:before { + content: "\e142"; +} +.glyphicon-heart-empty:before { + content: "\e143"; +} +.glyphicon-link:before { + content: "\e144"; +} +.glyphicon-phone:before { + content: "\e145"; +} +.glyphicon-pushpin:before { + content: "\e146"; +} +.glyphicon-usd:before { + content: "\e148"; +} +.glyphicon-gbp:before { + content: "\e149"; +} +.glyphicon-sort:before { + content: "\e150"; +} +.glyphicon-sort-by-alphabet:before { + content: "\e151"; +} +.glyphicon-sort-by-alphabet-alt:before { + content: "\e152"; +} +.glyphicon-sort-by-order:before { + content: "\e153"; +} +.glyphicon-sort-by-order-alt:before { + content: "\e154"; +} +.glyphicon-sort-by-attributes:before { + content: "\e155"; +} +.glyphicon-sort-by-attributes-alt:before { + content: "\e156"; +} +.glyphicon-unchecked:before { + content: "\e157"; +} +.glyphicon-expand:before { + content: "\e158"; +} +.glyphicon-collapse-down:before { + content: "\e159"; +} +.glyphicon-collapse-up:before { + content: "\e160"; +} +.glyphicon-log-in:before { + content: "\e161"; +} +.glyphicon-flash:before { + content: "\e162"; +} +.glyphicon-log-out:before { + content: "\e163"; +} +.glyphicon-new-window:before { + content: "\e164"; +} +.glyphicon-record:before { + content: "\e165"; +} +.glyphicon-save:before { + content: "\e166"; +} +.glyphicon-open:before { + content: "\e167"; +} +.glyphicon-saved:before { + content: "\e168"; +} +.glyphicon-import:before { + content: "\e169"; +} +.glyphicon-export:before { + content: "\e170"; +} +.glyphicon-send:before { + content: "\e171"; +} +.glyphicon-floppy-disk:before { + content: "\e172"; +} +.glyphicon-floppy-saved:before { + content: "\e173"; +} +.glyphicon-floppy-remove:before { + content: "\e174"; +} +.glyphicon-floppy-save:before { + content: "\e175"; +} +.glyphicon-floppy-open:before { + content: "\e176"; +} +.glyphicon-credit-card:before { + content: "\e177"; +} +.glyphicon-transfer:before { + content: "\e178"; +} +.glyphicon-cutlery:before { + content: "\e179"; +} +.glyphicon-header:before { + content: "\e180"; +} +.glyphicon-compressed:before { + content: "\e181"; +} +.glyphicon-earphone:before { + content: "\e182"; +} +.glyphicon-phone-alt:before { + content: "\e183"; +} +.glyphicon-tower:before { + content: "\e184"; +} +.glyphicon-stats:before { + content: "\e185"; +} +.glyphicon-sd-video:before { + content: "\e186"; +} +.glyphicon-hd-video:before { + content: "\e187"; +} +.glyphicon-subtitles:before { + content: "\e188"; +} +.glyphicon-sound-stereo:before { + content: "\e189"; +} +.glyphicon-sound-dolby:before { + content: "\e190"; +} +.glyphicon-sound-5-1:before { + content: "\e191"; +} +.glyphicon-sound-6-1:before { + content: "\e192"; +} +.glyphicon-sound-7-1:before { + content: "\e193"; +} +.glyphicon-copyright-mark:before { + content: "\e194"; +} +.glyphicon-registration-mark:before { + content: "\e195"; +} +.glyphicon-cloud-download:before { + content: "\e197"; +} +.glyphicon-cloud-upload:before { + content: "\e198"; +} +.glyphicon-tree-conifer:before { + content: "\e199"; +} +.glyphicon-tree-deciduous:before { + content: "\e200"; +} +.glyphicon-cd:before { + content: "\e201"; +} +.glyphicon-save-file:before { + content: "\e202"; +} +.glyphicon-open-file:before { + content: "\e203"; +} +.glyphicon-level-up:before { + content: "\e204"; +} +.glyphicon-copy:before { + content: "\e205"; +} +.glyphicon-paste:before { + content: "\e206"; +} +.glyphicon-alert:before { + content: "\e209"; +} +.glyphicon-equalizer:before { + content: "\e210"; +} +.glyphicon-king:before { + content: "\e211"; +} +.glyphicon-queen:before { + content: "\e212"; +} +.glyphicon-pawn:before { + content: "\e213"; +} +.glyphicon-bishop:before { + content: "\e214"; +} +.glyphicon-knight:before { + content: "\e215"; +} +.glyphicon-baby-formula:before { + content: "\e216"; +} +.glyphicon-tent:before { + content: "\26fa"; +} +.glyphicon-blackboard:before { + content: "\e218"; +} +.glyphicon-bed:before { + content: "\e219"; +} +.glyphicon-apple:before { + content: "\f8ff"; +} +.glyphicon-erase:before { + content: "\e221"; +} +.glyphicon-hourglass:before { + content: "\231b"; +} +.glyphicon-lamp:before { + content: "\e223"; +} +.glyphicon-duplicate:before { + content: "\e224"; +} +.glyphicon-piggy-bank:before { + content: "\e225"; +} +.glyphicon-scissors:before { + content: "\e226"; +} +.glyphicon-bitcoin:before { + content: "\e227"; +} +.glyphicon-btc:before { + content: "\e227"; +} +.glyphicon-xbt:before { + content: "\e227"; +} +.glyphicon-yen:before { + content: "\00a5"; +} +.glyphicon-jpy:before { + content: "\00a5"; +} +.glyphicon-ruble:before { + content: "\20bd"; +} +.glyphicon-rub:before { + content: "\20bd"; +} +.glyphicon-scale:before { + content: "\e230"; +} +.glyphicon-ice-lolly:before { + content: "\e231"; +} +.glyphicon-ice-lolly-tasted:before { + content: "\e232"; +} +.glyphicon-education:before { + content: "\e233"; +} +.glyphicon-option-horizontal:before { + content: "\e234"; +} +.glyphicon-option-vertical:before { + content: "\e235"; +} +.glyphicon-menu-hamburger:before { + content: "\e236"; +} +.glyphicon-modal-window:before { + content: "\e237"; +} +.glyphicon-oil:before { + content: "\e238"; +} +.glyphicon-grain:before { + content: "\e239"; +} +.glyphicon-sunglasses:before { + content: "\e240"; +} +.glyphicon-text-size:before { + content: "\e241"; +} +.glyphicon-text-color:before { + content: "\e242"; +} +.glyphicon-text-background:before { + content: "\e243"; +} +.glyphicon-object-align-top:before { + content: "\e244"; +} +.glyphicon-object-align-bottom:before { + content: "\e245"; +} +.glyphicon-object-align-horizontal:before { + content: "\e246"; +} +.glyphicon-object-align-left:before { + content: "\e247"; +} +.glyphicon-object-align-vertical:before { + content: "\e248"; +} +.glyphicon-object-align-right:before { + content: "\e249"; +} +.glyphicon-triangle-right:before { + content: "\e250"; +} +.glyphicon-triangle-left:before { + content: "\e251"; +} +.glyphicon-triangle-bottom:before { + content: "\e252"; +} +.glyphicon-triangle-top:before { + content: "\e253"; +} +.glyphicon-console:before { + content: "\e254"; +} +.glyphicon-superscript:before { + content: "\e255"; +} +.glyphicon-subscript:before { + content: "\e256"; +} +.glyphicon-menu-left:before { + content: "\e257"; +} +.glyphicon-menu-right:before { + content: "\e258"; +} +.glyphicon-menu-down:before { + content: "\e259"; +} +.glyphicon-menu-up:before { + content: "\e260"; +} +.alert { + padding: 15px; + margin-bottom: 20px; + border: 1px solid transparent; + border-radius: 4px; +} +.alert h4 { + margin-top: 0; + color: inherit; +} +.alert .alert-link { + font-weight: bold; +} +.alert > p, +.alert > ul { + margin-bottom: 0; +} +.alert > p + p { + margin-top: 5px; +} +.alert-dismissable, +.alert-dismissible { + padding-right: 35px; +} +.alert-dismissable .close, +.alert-dismissible .close { + position: relative; + top: -2px; + right: -21px; + color: inherit; +} +.alert-success { + background-color: #dff0d8; + border-color: #d6e9c6; + color: #3c763d; +} +.alert-success hr { + border-top-color: #c9e2b3; +} +.alert-success .alert-link { + color: #2b542c; +} +.alert-info { + background-color: #d9edf7; + border-color: #bce8f1; + color: #31708f; +} +.alert-info hr { + border-top-color: #a6e1ec; +} +.alert-info .alert-link { + color: #245269; +} +.alert-warning { + background-color: #fcf8e3; + border-color: #faebcc; + color: #8a6d3b; +} +.alert-warning hr { + border-top-color: #f7e1b5; +} +.alert-warning .alert-link { + color: #66512c; +} +.alert-danger { + background-color: #f2dede; + border-color: #ebccd1; + color: #632827; +} +.alert-danger hr { + border-top-color: #e4b9c0; +} +.alert-danger .alert-link { + color: #3e1919; +} +.close { + float: right; + font-size: 21px; + font-weight: bold; + line-height: 1; + color: #000; + text-shadow: 0 1px 0 #fff; + opacity: 0.2; + filter: alpha(opacity=20); +} +.close:hover, +.close:focus { + color: #000; + text-decoration: none; + cursor: pointer; + opacity: 0.5; + filter: alpha(opacity=50); +} +button.close { + padding: 0; + cursor: pointer; + background: transparent; + border: 0; + -webkit-appearance: none; +} +h1, +h2, +h3, +h4, +h5, +h6, +.h1, +.h2, +.h3, +.h4, +.h5, +.h6 { + opacity: 0.87; +} +label { + opacity: 0.87; +} +.label-default { + opacity: 0.87; +} +legend { + opacity: 0.87; +} +button { + opacity: 0.87; +} +h1 { + color: #455A64; + font-size: 50px; + font-weight: bold; +} +h2 { + color: #455A64; + font-size: 30px; + font-weight: bold; +} +h3, +legend { + font-size: 20px; + font-weight: 400; + line-height: 40px; +} +label, +.label-default { + font-size: 16px; + font-weight: 400; + line-height: 28px; +} +input, +textarea, +select { + font-size: 16px; + font-weight: 400; + line-height: 28px; + margin-top: 15px; +} +span, +p { + font-size: 16px; + font-weight: 400; + line-height: 28px; +} +button.btn { + font-size: 16px; + font-weight: bold; + line-height: 28px; +} +.input-group-btn { + padding-top: 15px; +} +.input-group-btn button.btn { + padding-top: 2px; + padding-bottom: 3px; +} +.shadow-1 { + box-shadow: 0 1px 4px 0 rgba(0, 0, 0, 0.37); +} +.showcase { + margin-bottom: 20px; +} +.showcase .showcase-header { + background: #E0E0E0; + padding: 32px; +} +.showcase .showcase-content { + padding: 32px; +} +.main-header { + margin-bottom: 40px; +} +a * { + color: inherit; +} +a *:hover { + color: inherit; +} +input::-webkit-input-placeholder { + color: #616161 !important; +} +input::-moz-placeholder { + color: #616161 !important; +} +label input, +label textarea, +label select { + font-weight: normal; +} +.btn.btn-primary:hover, +.btn.btn-primary:focus { + color: #263238; + background-color: #EEEEEE; +} +.btn.btn-default:hover, +.btn.btn-default:focus { + color: #37474F; + background-color: #EEEEEE; +} +.close, +.close:hover, +.close:focus { + opacity: 1; +} diff --git a/public/docs/_examples/cb-a11y/ts/app/a11y-index.component.html b/public/docs/_examples/cb-a11y/ts/app/a11y-index.component.html new file mode 100644 index 0000000000..7802428ada --- /dev/null +++ b/public/docs/_examples/cb-a11y/ts/app/a11y-index.component.html @@ -0,0 +1,20 @@ + diff --git a/public/docs/_examples/cb-a11y/ts/app/a11y-index.component.ts b/public/docs/_examples/cb-a11y/ts/app/a11y-index.component.ts new file mode 100644 index 0000000000..9b22929469 --- /dev/null +++ b/public/docs/_examples/cb-a11y/ts/app/a11y-index.component.ts @@ -0,0 +1,10 @@ +import { Component } from '@angular/core'; +import { ROUTER_DIRECTIVES } from '@angular/router'; + +@Component({ + selector: 'a11y-index', + templateUrl: './app/a11y-index.component.html', + directives: [ROUTER_DIRECTIVES] +}) +export class A11yIndexComponent { +} diff --git a/public/docs/_examples/cb-a11y/ts/app/app.component.html b/public/docs/_examples/cb-a11y/ts/app/app.component.html new file mode 100644 index 0000000000..a244c1424c --- /dev/null +++ b/public/docs/_examples/cb-a11y/ts/app/app.component.html @@ -0,0 +1,8 @@ + +
+ +
diff --git a/public/docs/_examples/cb-a11y/ts/app/app.component.ts b/public/docs/_examples/cb-a11y/ts/app/app.component.ts new file mode 100644 index 0000000000..f7deadfbae --- /dev/null +++ b/public/docs/_examples/cb-a11y/ts/app/app.component.ts @@ -0,0 +1,16 @@ +import { Component } from '@angular/core'; +import { ROUTER_DIRECTIVES } from '@angular/router'; +import { A11yHelperService } from './services/a11y-helper.service'; + +@Component({ + selector: 'a11y-app', + templateUrl: 'app/app.component.html', + directives: [ + ROUTER_DIRECTIVES + ], + providers: [ + A11yHelperService + ] +}) +export class AppComponent { +} diff --git a/public/docs/_examples/cb-a11y/ts/app/app.routes.ts b/public/docs/_examples/cb-a11y/ts/app/app.routes.ts new file mode 100644 index 0000000000..b063c40416 --- /dev/null +++ b/public/docs/_examples/cb-a11y/ts/app/app.routes.ts @@ -0,0 +1,27 @@ +import { provideRouter, RouterConfig } from '@angular/router'; +import { A11yIndexComponent } from './a11y-index.component'; +import { A11yFormControlsComponent } from './form-controls/a11y-form-controls.component'; +import { A11yDevToolsComponent } from './dev-tools/a11y-dev-tools.component'; +import { A11yManagingFocusComponent } from './managing-focus/a11y-managing-focus.component'; +import { A11yComponentRolesComponent } from './component-roles/a11y-component-roles.component'; +import { A11yDevToolsIndexComponent } from './dev-tools/a11y-dev-tools-index.component'; +import { A11yPassComponent } from './dev-tools/a11y-pass/a11y-pass.component'; +import { A11yFailsComponent } from './dev-tools/a11y-fails/a11y-fails.component'; + +export const routes: RouterConfig = [ + {path: '', component: A11yIndexComponent}, + {path: 'form-controls', component: A11yFormControlsComponent}, + {path: 'managing-focus', component: A11yManagingFocusComponent}, + {path: 'component-roles', component: A11yComponentRolesComponent}, + { + path: 'dev-tools', component: A11yDevToolsComponent, children: [ + {path: '', component: A11yDevToolsIndexComponent}, + {path: 'fail-demo', component: A11yFailsComponent}, + {path: 'pass-demo', component: A11yPassComponent} + ] + } +]; + +export const APP_ROUTER_PROVIDERS = [ + provideRouter(routes) +]; diff --git a/public/docs/_examples/cb-a11y/ts/app/component-roles/a11y-component-roles.component.html b/public/docs/_examples/cb-a11y/ts/app/component-roles/a11y-component-roles.component.html new file mode 100644 index 0000000000..8916ba3200 --- /dev/null +++ b/public/docs/_examples/cb-a11y/ts/app/component-roles/a11y-component-roles.component.html @@ -0,0 +1,56 @@ + + +
+ +
+

Roles for custom component widgets

+
+ +
+ +
+

Roles in the template

+
+ +
+ + + I set the role in my template: + + + + +
+ +
+ +
+ +
+

Roles of the host element

+
+ +
+ +
+
+ + Do something... + +
+
+ +
+
+ +
+
+ +
+ +
+ +
diff --git a/public/docs/_examples/cb-a11y/ts/app/component-roles/a11y-component-roles.component.ts b/public/docs/_examples/cb-a11y/ts/app/component-roles/a11y-component-roles.component.ts new file mode 100644 index 0000000000..59dac19ab4 --- /dev/null +++ b/public/docs/_examples/cb-a11y/ts/app/component-roles/a11y-component-roles.component.ts @@ -0,0 +1,28 @@ +import { Component } from '@angular/core'; +import { A11yCustomControlComponent } from '../shared/a11y-custom-control.component'; +import { A11yValueHelperComponent } from '../shared/a11y-value-helper.component'; +import { A11yCustomButtonComponent } from '../shared/a11y-custom-button.component'; + +@Component({ + selector: 'a11y-component-roles', + templateUrl: './app/component-roles/a11y-component-roles.component.html', + directives: [ + A11yCustomControlComponent, + A11yValueHelperComponent, + A11yCustomButtonComponent + ] +}) +export class A11yComponentRolesComponent { + + inputDivModel: string = ''; + buttonClicks: number = 0; + + onClick(): void { + this.buttonClicks++; + } + + generateButtonString(): string { + return `Button has been clicked ${this.buttonClicks} times`; + } + +} diff --git a/public/docs/_examples/cb-a11y/ts/app/dev-tools/a11y-dev-tools-index.component.html b/public/docs/_examples/cb-a11y/ts/app/dev-tools/a11y-dev-tools-index.component.html new file mode 100644 index 0000000000..b56e08eeb4 --- /dev/null +++ b/public/docs/_examples/cb-a11y/ts/app/dev-tools/a11y-dev-tools-index.component.html @@ -0,0 +1,14 @@ + diff --git a/public/docs/_examples/cb-a11y/ts/app/dev-tools/a11y-dev-tools-index.component.ts b/public/docs/_examples/cb-a11y/ts/app/dev-tools/a11y-dev-tools-index.component.ts new file mode 100644 index 0000000000..afc4932e4c --- /dev/null +++ b/public/docs/_examples/cb-a11y/ts/app/dev-tools/a11y-dev-tools-index.component.ts @@ -0,0 +1,10 @@ +import { Component } from '@angular/core'; +import { ROUTER_DIRECTIVES } from '@angular/router'; + +@Component({ + selector: 'a11y-dev-tools-index', + templateUrl: './app/dev-tools/a11y-dev-tools-index.component.html', + directives: [ROUTER_DIRECTIVES] +}) +export class A11yDevToolsIndexComponent { +} diff --git a/public/docs/_examples/cb-a11y/ts/app/dev-tools/a11y-dev-tools.component.html b/public/docs/_examples/cb-a11y/ts/app/dev-tools/a11y-dev-tools.component.html new file mode 100644 index 0000000000..0680b43f9c --- /dev/null +++ b/public/docs/_examples/cb-a11y/ts/app/dev-tools/a11y-dev-tools.component.html @@ -0,0 +1 @@ + diff --git a/public/docs/_examples/cb-a11y/ts/app/dev-tools/a11y-dev-tools.component.ts b/public/docs/_examples/cb-a11y/ts/app/dev-tools/a11y-dev-tools.component.ts new file mode 100644 index 0000000000..359b7a0219 --- /dev/null +++ b/public/docs/_examples/cb-a11y/ts/app/dev-tools/a11y-dev-tools.component.ts @@ -0,0 +1,10 @@ +import { Component } from '@angular/core'; +import { ROUTER_DIRECTIVES } from '@angular/router'; + +@Component({ + selector: 'a11y-dev-tools', + templateUrl: './app/dev-tools/a11y-dev-tools.component.html', + directives: [ROUTER_DIRECTIVES] +}) +export class A11yDevToolsComponent { +} diff --git a/public/docs/_examples/cb-a11y/ts/app/dev-tools/a11y-fails/a11y-fails.component.html b/public/docs/_examples/cb-a11y/ts/app/dev-tools/a11y-fails/a11y-fails.component.html new file mode 100644 index 0000000000..8a91dbdd82 --- /dev/null +++ b/public/docs/_examples/cb-a11y/ts/app/dev-tools/a11y-fails/a11y-fails.component.html @@ -0,0 +1,53 @@ +
+
+

Demo with a11y errors

+
+ +
+ +
+ + + + + + +
+ +
+ Hi {{demoForm.value.name}} {{demoForm.value.surname}}! Your reason for liking Angular 2 is: {{demoForm.value.reason}}. + +
+ + + +
+ + + +
+ +
+ +
diff --git a/public/docs/_examples/cb-a11y/ts/app/dev-tools/a11y-fails/a11y-fails.component.ts b/public/docs/_examples/cb-a11y/ts/app/dev-tools/a11y-fails/a11y-fails.component.ts new file mode 100644 index 0000000000..e0740d4389 --- /dev/null +++ b/public/docs/_examples/cb-a11y/ts/app/dev-tools/a11y-fails/a11y-fails.component.ts @@ -0,0 +1,28 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'a11y-fails', + templateUrl: './app/dev-tools/a11y-fails/a11y-fails.component.html', + styles: [ + ` + input { + font-weight: bold; + } + + label { + color: #808080; + } + ` + ] +}) +export class A11yFailsComponent { + + model: any = {}; + + hideSuccessConfirmation: boolean = true; + + submit(): void { + this.hideSuccessConfirmation = false; + } + +} diff --git a/public/docs/_examples/cb-a11y/ts/app/dev-tools/a11y-pass/a11y-pass.component.html b/public/docs/_examples/cb-a11y/ts/app/dev-tools/a11y-pass/a11y-pass.component.html new file mode 100644 index 0000000000..c957b18b43 --- /dev/null +++ b/public/docs/_examples/cb-a11y/ts/app/dev-tools/a11y-pass/a11y-pass.component.html @@ -0,0 +1,56 @@ +
+
+

Demo with full a11y features

+
+ +
+ +
+ + + + + +
+ + + + + +
+ + + +
+ +
+ +
diff --git a/public/docs/_examples/cb-a11y/ts/app/dev-tools/a11y-pass/a11y-pass.component.ts b/public/docs/_examples/cb-a11y/ts/app/dev-tools/a11y-pass/a11y-pass.component.ts new file mode 100644 index 0000000000..94de2bd436 --- /dev/null +++ b/public/docs/_examples/cb-a11y/ts/app/dev-tools/a11y-pass/a11y-pass.component.ts @@ -0,0 +1,20 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'a11y-fails', + templateUrl: './app/dev-tools/a11y-pass/a11y-pass.component.html' +}) +export class A11yPassComponent { + + model: any = {}; + + hideSuccessConfirmation: boolean = true; + + submit(messageElement: any): void { + this.hideSuccessConfirmation = false; + setTimeout(() => { + messageElement.focus(); + }, 200); + } + +} diff --git a/public/docs/_examples/cb-a11y/ts/app/form-controls/a11y-form-controls.component.html b/public/docs/_examples/cb-a11y/ts/app/form-controls/a11y-form-controls.component.html new file mode 100644 index 0000000000..f50199db18 --- /dev/null +++ b/public/docs/_examples/cb-a11y/ts/app/form-controls/a11y-form-controls.component.html @@ -0,0 +1,193 @@ + + +
+
+

Accessible form control labels

+
+ +
+ +
+

Implicit labeling

+
+ +
+ + +
+ +
+ + + + + +
+ +
+ + + + + +
+ + What do you like most about Angular 2? + +
+ +
+
+ + + + + +
+ + Choose your favourite Angular 2 language: + +
+ +
+
+ + + + + +
+ +
+ + +
+
+ +
+ +
+

Explicit labeling

+
+ +
+ + +
+ + +
+ + + + +
+ +
+ +
+ +
+

Hiding labels

+
+ +
+ + +
+ + +
+ + + + + +
+ +
+ + + + +
+ +
+ +
+ +
+

Labeling custom controls

+
+ +
+ + + + Write in this labeled div: + + + + + + + + Write in this wrapped input: + + + + + + +
+ +
+ +
+ + diff --git a/public/docs/_examples/cb-a11y/ts/app/form-controls/a11y-form-controls.component.ts b/public/docs/_examples/cb-a11y/ts/app/form-controls/a11y-form-controls.component.ts new file mode 100644 index 0000000000..5e4e710d4a --- /dev/null +++ b/public/docs/_examples/cb-a11y/ts/app/form-controls/a11y-form-controls.component.ts @@ -0,0 +1,65 @@ +import { Component, OnInit } from '@angular/core'; +import { CORE_DIRECTIVES } from '@angular/common'; +import { FORM_DIRECTIVES } from '@angular/forms'; +import { A11yHelperService } from '../services/a11y-helper.service'; +import { A11yInputWrapperComponent } from './a11y-input-wrapper.component'; +import { A11yValueHelperComponent } from '../shared/a11y-value-helper.component'; +import { A11yCustomControlComponent } from '../shared/a11y-custom-control.component'; + +@Component({ + selector: 'a11y-form-controls', + templateUrl: './app/form-controls/a11y-form-controls.component.html', + directives: [ + CORE_DIRECTIVES, + FORM_DIRECTIVES, + A11yCustomControlComponent, + A11yInputWrapperComponent, + A11yValueHelperComponent + ] +}) +export class A11yFormControlsComponent implements OnInit { + + checkBoxes: any; + radioButtons: any; + selectOptions: any; + + inputModel: string; + inputExplicitModel: string; + inputWrappedModel: string; + inputWrappedSaveModel: string = ''; + inputDivModel: string = ''; + textModel: string; + selectModel: string = 'Curiosity'; + searchModel: string; + filterModel: string; + + radioModel: string = 'TypeScript'; + checkboxModel: Array = ['Observables', 'Components']; + + + constructor(private _a11yHelper: A11yHelperService) { + } + + isChecked(item: string): boolean { + return this._a11yHelper.isStringInArray(this.checkboxModel, item); + } + + toggleCheckbox(item: string): void { + this._a11yHelper.toggleItemInArray(this.checkboxModel, item); + } + + onSave() { + this.inputWrappedSaveModel = this.inputWrappedModel; + } + + ngOnInit() { + this.checkBoxes = this._a11yHelper.getCheckboxModel(); + this.radioButtons = this._a11yHelper.getRadiobuttonsModel(); + this.selectOptions = this._a11yHelper.getSelectOptions(); + } + + updateSelect(value: string): void { + this.selectModel = value; + } + +} diff --git a/public/docs/_examples/cb-a11y/ts/app/form-controls/a11y-input-wrapper.component.css b/public/docs/_examples/cb-a11y/ts/app/form-controls/a11y-input-wrapper.component.css new file mode 100644 index 0000000000..57e41b1abe --- /dev/null +++ b/public/docs/_examples/cb-a11y/ts/app/form-controls/a11y-input-wrapper.component.css @@ -0,0 +1,25 @@ +/* #docregion */ +:host input { + display: block; + width: 100%; + height: 34px; + padding: 6px 12px; + font-size: 14px; + line-height: 1.42857143; + background-image: none; + border: 1px solid #ccc; + border-radius: 4px; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); + -webkit-transition: border-color ease-in-out .15s, -webkit-box-shadow ease-in-out .15s; + -o-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s; + transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s; +} + +:host input:focus { + border-color: #66afe9; + outline: 0; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 8px rgba(102, 175, 233, .6); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 8px rgba(102, 175, 233, .6); +} +/* #enddocregion */ diff --git a/public/docs/_examples/cb-a11y/ts/app/form-controls/a11y-input-wrapper.component.html b/public/docs/_examples/cb-a11y/ts/app/form-controls/a11y-input-wrapper.component.html new file mode 100644 index 0000000000..544ea235fc --- /dev/null +++ b/public/docs/_examples/cb-a11y/ts/app/form-controls/a11y-input-wrapper.component.html @@ -0,0 +1,19 @@ + +
+
+ +
+
+ diff --git a/public/docs/_examples/cb-a11y/ts/app/form-controls/a11y-input-wrapper.component.ts b/public/docs/_examples/cb-a11y/ts/app/form-controls/a11y-input-wrapper.component.ts new file mode 100644 index 0000000000..5e87242433 --- /dev/null +++ b/public/docs/_examples/cb-a11y/ts/app/form-controls/a11y-input-wrapper.component.ts @@ -0,0 +1,17 @@ +import { Component, Output, EventEmitter } from '@angular/core'; + +// #docregion +@Component({ + selector: 'a11y-input-wrapper', + templateUrl: './app/form-controls/a11y-input-wrapper.component.html', + styleUrls: ['./app/form-controls/a11y-input-wrapper.component.css'] +}) +export class A11yInputWrapperComponent { + + @Output() onSave: EventEmitter = new EventEmitter(); + + save() { + this.onSave.emit(null); + } +} +// #enddocregion diff --git a/public/docs/_examples/cb-a11y/ts/app/main.ts b/public/docs/_examples/cb-a11y/ts/app/main.ts new file mode 100644 index 0000000000..01d3440aa4 --- /dev/null +++ b/public/docs/_examples/cb-a11y/ts/app/main.ts @@ -0,0 +1,11 @@ +import { bootstrap } from '@angular/platform-browser-dynamic'; +import { AppComponent } from './app.component'; +import { APP_ROUTER_PROVIDERS } from './app.routes'; +import { disableDeprecatedForms, provideForms } from '@angular/forms'; + +bootstrap(AppComponent, [ + APP_ROUTER_PROVIDERS, + disableDeprecatedForms(), + provideForms() +]) + .catch(err => console.error(err)); diff --git a/public/docs/_examples/cb-a11y/ts/app/managing-focus/a11y-error-demo.component.html b/public/docs/_examples/cb-a11y/ts/app/managing-focus/a11y-error-demo.component.html new file mode 100644 index 0000000000..52a6e22017 --- /dev/null +++ b/public/docs/_examples/cb-a11y/ts/app/managing-focus/a11y-error-demo.component.html @@ -0,0 +1,18 @@ + + + + diff --git a/public/docs/_examples/cb-a11y/ts/app/managing-focus/a11y-error-demo.component.ts b/public/docs/_examples/cb-a11y/ts/app/managing-focus/a11y-error-demo.component.ts new file mode 100644 index 0000000000..de0e68b2b4 --- /dev/null +++ b/public/docs/_examples/cb-a11y/ts/app/managing-focus/a11y-error-demo.component.ts @@ -0,0 +1,19 @@ +import { Component } from '@angular/core'; + +// #docregion +@Component({ + selector: 'a11y-error-demo', + templateUrl: './app/managing-focus/a11y-error-demo.component.html' +}) +export class A11yErrorDemoComponent { + + hideErrorConfirmation: boolean = true; + + setFocusOn(element: any) { + this.hideErrorConfirmation = false; + setTimeout(() => { + element.focus(); + }, 200); + } +} +// #enddocregion diff --git a/public/docs/_examples/cb-a11y/ts/app/managing-focus/a11y-managing-focus.component.html b/public/docs/_examples/cb-a11y/ts/app/managing-focus/a11y-managing-focus.component.html new file mode 100644 index 0000000000..611810237c --- /dev/null +++ b/public/docs/_examples/cb-a11y/ts/app/managing-focus/a11y-managing-focus.component.html @@ -0,0 +1,110 @@ + + + + +
+ +
+

Managing focus

+
+ +
+ +
+

The focus outline

+
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +

Focus flow

+ +
+ +
+ + +
+
+ +
+
+ +
+
+ + +
+ +
+ +
+ +
+

Focusing custom controls

+
+ +
+ +
+
+ + Do something... + +
+
+ +
+
+ +
+
+ +
+ +
+ +
+ +
+

Internal focus in a component

+
+ +
+ + + +
+ +
+ +
+ diff --git a/public/docs/_examples/cb-a11y/ts/app/managing-focus/a11y-managing-focus.component.ts b/public/docs/_examples/cb-a11y/ts/app/managing-focus/a11y-managing-focus.component.ts new file mode 100644 index 0000000000..2802299391 --- /dev/null +++ b/public/docs/_examples/cb-a11y/ts/app/managing-focus/a11y-managing-focus.component.ts @@ -0,0 +1,38 @@ +import { Component, OnInit } from '@angular/core'; +import { A11yHelperService } from '../services/a11y-helper.service'; +import { CORE_DIRECTIVES } from '@angular/common'; +import { A11yErrorDemoComponent } from './a11y-error-demo.component'; +import { A11yCustomButtonComponent } from '../shared/a11y-custom-button.component'; +import { A11yValueHelperComponent } from '../shared/a11y-value-helper.component'; + +@Component({ + selector: 'a11y-managing-focus', + templateUrl: './app/managing-focus/a11y-managing-focus.component.html', + directives: [ + CORE_DIRECTIVES, + A11yCustomButtonComponent, + A11yValueHelperComponent, + A11yErrorDemoComponent + ] +}) +export class A11yManagingFocusComponent implements OnInit { + + countriesWorkedIn: Array; + buttonClicks: number = 0; + + constructor(private _a11yHelper: A11yHelperService) { + } + + onClick(): void { + this.buttonClicks++; + } + + generateButtonString(): string { + return `Button has been clicked ${this.buttonClicks} times`; + } + + ngOnInit(): void { + this.countriesWorkedIn = this._a11yHelper.getCountriesWorkedIn(); + } + +} diff --git a/public/docs/_examples/cb-a11y/ts/app/services/a11y-helper.service.ts b/public/docs/_examples/cb-a11y/ts/app/services/a11y-helper.service.ts new file mode 100644 index 0000000000..185dc42fcb --- /dev/null +++ b/public/docs/_examples/cb-a11y/ts/app/services/a11y-helper.service.ts @@ -0,0 +1,97 @@ +import { Injectable } from '@angular/core'; + +@Injectable() +export class A11yHelperService { + + generateUniqueIdString(): string { + return this.guidPartial() + this.guidPartial(true) + this.guidPartial(true) + this.guidPartial(); + } + + getCheckboxModel(): any { + return [ + { + name: 'Template syntax', + value: 'Template syntax' + }, + { + name: 'Observables', + value: 'Observables' + }, + { + name: 'Components', + value: 'Components' + }, + { + name: 'Forms', + value: 'Forms' + } + ]; + } + + getRadiobuttonsModel(): any { + return [ + { + name: 'TypeScript', + value: 'TypeScript' + }, + { + name: 'JavaScript', + value: 'JavaScript' + }, + { + name: 'ES6', + value: 'ES6' + }, + { + name: 'Dart', + value: 'Dart' + } + ]; + } + + getSelectOptions(): any { + return [ + { + name: 'Curiosity', + value: 'Curiosity' + }, + { + name: 'Increased userbase', + value: 'Increased userbase' + }, + { + name: 'Legal reasons', + value: 'Legal reasons' + } + ]; + } + + getCountriesWorkedIn(): Array { + return ['The USA', 'The Netherlands', 'South Africa', 'Germany', 'The UK']; + } + + toggleItemInArray(stringArray: Array, item: string): void { + let entryIndex = stringArray.indexOf(item); + if (entryIndex !== -1) { + stringArray.splice(entryIndex, 1); + } else { + stringArray.push(item); + } + } + + isStringInArray(stringArray: Array, item: string): boolean { + return stringArray.indexOf(item.toString()) !== -1; + } + + removeHtmlStringBreaks(inputValue: string): string { + return inputValue.replace(new RegExp('
', 'g'), '') + .replace(new RegExp('
', 'g'), '\n') + .replace(new RegExp('
', 'g'), ''); + } + + guidPartial(s?: boolean) { + let p = (Math.random().toString(16) + '000000000').substr(2, 8); + return s ? '-' + p.substr(0, 4) + '-' + p.substr(4, 4) : p; + } + +} diff --git a/public/docs/_examples/cb-a11y/ts/app/shared/a11y-custom-button.component.html b/public/docs/_examples/cb-a11y/ts/app/shared/a11y-custom-button.component.html new file mode 100644 index 0000000000..ceb79a69d3 --- /dev/null +++ b/public/docs/_examples/cb-a11y/ts/app/shared/a11y-custom-button.component.html @@ -0,0 +1,3 @@ + + + diff --git a/public/docs/_examples/cb-a11y/ts/app/shared/a11y-custom-button.component.ts b/public/docs/_examples/cb-a11y/ts/app/shared/a11y-custom-button.component.ts new file mode 100644 index 0000000000..05973f18a9 --- /dev/null +++ b/public/docs/_examples/cb-a11y/ts/app/shared/a11y-custom-button.component.ts @@ -0,0 +1,25 @@ +import { Component, EventEmitter, Output, HostBinding, HostListener } from '@angular/core'; + +// #docregion +@Component({ + selector: 'a11y-custom-button', + templateUrl: './app/shared/a11y-custom-button.component.html' +}) +export class A11yCustomButtonComponent { + + @HostBinding('attr.role') role = 'button'; + + @HostBinding('attr.class') classes = 'btn btn-primary'; + + @HostBinding('attr.tabindex') tabIndex = '0'; + + @Output() click: EventEmitter = new EventEmitter(); + + @HostListener('keydown.space') + @HostListener('keydown.enter') + onKeyDown() { + this.click.emit(null); + } + +} +// #enddocregion diff --git a/public/docs/_examples/cb-a11y/ts/app/shared/a11y-custom-control.component.css b/public/docs/_examples/cb-a11y/ts/app/shared/a11y-custom-control.component.css new file mode 100644 index 0000000000..d837c8ed0b --- /dev/null +++ b/public/docs/_examples/cb-a11y/ts/app/shared/a11y-custom-control.component.css @@ -0,0 +1,7 @@ +/* #docregion */ +div.edit-box { + height: auto; + min-height: 50px; + margin-top: 15px; +} +/* #enddocregion */ diff --git a/public/docs/_examples/cb-a11y/ts/app/shared/a11y-custom-control.component.html b/public/docs/_examples/cb-a11y/ts/app/shared/a11y-custom-control.component.html new file mode 100644 index 0000000000..21fdf24fbe --- /dev/null +++ b/public/docs/_examples/cb-a11y/ts/app/shared/a11y-custom-control.component.html @@ -0,0 +1,18 @@ + +
+
+ +
+
+
+ diff --git a/public/docs/_examples/cb-a11y/ts/app/shared/a11y-custom-control.component.ts b/public/docs/_examples/cb-a11y/ts/app/shared/a11y-custom-control.component.ts new file mode 100644 index 0000000000..e6e97f342e --- /dev/null +++ b/public/docs/_examples/cb-a11y/ts/app/shared/a11y-custom-control.component.ts @@ -0,0 +1,67 @@ +import { Component, OnInit, Provider, forwardRef } from '@angular/core'; +import { A11yHelperService } from '../services/a11y-helper.service'; +import { NG_VALUE_ACCESSOR, ControlValueAccessor } from '@angular/forms'; + +// #docregion +const noop = () => { +}; + +const A11Y_CUSTOM_CONTROL_VALUE_ACCESSOR = new Provider( + NG_VALUE_ACCESSOR, { + useExisting: forwardRef(() => A11yCustomControlComponent), + multi: true + }); + +@Component({ + selector: 'a11y-custom-control', + templateUrl: './app/shared/a11y-custom-control.component.html', + styleUrls: ['./app/shared/a11y-custom-control.component.css'], + providers: [A11Y_CUSTOM_CONTROL_VALUE_ACCESSOR] +}) +export class A11yCustomControlComponent implements OnInit, ControlValueAccessor { + + uniqueId: string; + + private innerValue: any = ''; + outerValue: string = ''; + + private onTouchedCallback: () => void = noop; + private onChangeCallback: (_: any) => void = noop; + + constructor(private _a11yHelper: A11yHelperService) { + } + + onChange(event: any, value: string) { + if (event.keyCode === 13) { + event.preventDefault(); + } else { + this.innerValue = this._a11yHelper.removeHtmlStringBreaks(value); + this.onChangeCallback(this.innerValue); + } + } + + onBlur() { + this.onTouchedCallback(); + } + + writeValue(value: any) { + if (value !== this.innerValue) { + this.innerValue = value; + this.outerValue = value; + } + } + + registerOnChange(fn: any) { + this.onChangeCallback = fn; + } + + registerOnTouched(fn: any) { + this.onTouchedCallback = fn; + } + + ngOnInit(): void { + this.uniqueId = this._a11yHelper.generateUniqueIdString(); + } + +} +// #enddocregion diff --git a/public/docs/_examples/cb-a11y/ts/app/shared/a11y-value-helper.component.html b/public/docs/_examples/cb-a11y/ts/app/shared/a11y-value-helper.component.html new file mode 100644 index 0000000000..2ef242ba25 --- /dev/null +++ b/public/docs/_examples/cb-a11y/ts/app/shared/a11y-value-helper.component.html @@ -0,0 +1,5 @@ + + Current value: {{displayValue}} + diff --git a/public/docs/_examples/cb-a11y/ts/app/shared/a11y-value-helper.component.ts b/public/docs/_examples/cb-a11y/ts/app/shared/a11y-value-helper.component.ts new file mode 100644 index 0000000000..238c1bec8f --- /dev/null +++ b/public/docs/_examples/cb-a11y/ts/app/shared/a11y-value-helper.component.ts @@ -0,0 +1,17 @@ +import { Component, Input } from '@angular/core'; + +@Component({ + selector: 'a11y-value-helper', + templateUrl: './app/shared/a11y-value-helper.component.html', + styles: [` + .value-label { + position:relative; + top: -15px; + } +`] +}) +export class A11yValueHelperComponent { + + @Input() displayValue: any; + +} diff --git a/public/docs/_examples/cb-a11y/ts/example-config.json b/public/docs/_examples/cb-a11y/ts/example-config.json new file mode 100644 index 0000000000..8b13789179 --- /dev/null +++ b/public/docs/_examples/cb-a11y/ts/example-config.json @@ -0,0 +1 @@ + diff --git a/public/docs/_examples/cb-a11y/ts/index.html b/public/docs/_examples/cb-a11y/ts/index.html new file mode 100644 index 0000000000..2a79a9631d --- /dev/null +++ b/public/docs/_examples/cb-a11y/ts/index.html @@ -0,0 +1,29 @@ + + + + + Angular 2 a11y cookbook + + + + + + + + + + + + + + + + +loading... + + + diff --git a/public/docs/_examples/cb-a11y/ts/plnkr.json b/public/docs/_examples/cb-a11y/ts/plnkr.json new file mode 100644 index 0000000000..8e4e448188 --- /dev/null +++ b/public/docs/_examples/cb-a11y/ts/plnkr.json @@ -0,0 +1,8 @@ +{ + "description": "A11y Cookbook samples", + "files":[ + "!**/*.d.ts", + "!**/*.js" + ], + "tags":["cookbook", "a11y"] +} \ No newline at end of file diff --git a/public/docs/dart/latest/cookbook/_data.json b/public/docs/dart/latest/cookbook/_data.json index a747acd83f..bf2575a30d 100644 --- a/public/docs/dart/latest/cookbook/_data.json +++ b/public/docs/dart/latest/cookbook/_data.json @@ -18,6 +18,12 @@ "hide": true }, + "a11y": { + "title": "ARIA / Accessibility (a11y) reference", + "navTitle": "ARIA / Accessibility (a11y)", + "intro": "Learn how to make your Angular 2 sites accessible for everyone" + }, + "component-communication": { "title": "Component Interaction", "intro": "Share information between different directives and components" diff --git a/public/docs/dart/latest/cookbook/a11y.jade b/public/docs/dart/latest/cookbook/a11y.jade new file mode 100644 index 0000000000..e44128c6a2 --- /dev/null +++ b/public/docs/dart/latest/cookbook/a11y.jade @@ -0,0 +1,2 @@ +!= partial("../../../_includes/_ts-temp") + diff --git a/public/docs/js/latest/cookbook/_data.json b/public/docs/js/latest/cookbook/_data.json index 3f319736d6..115ea100b8 100644 --- a/public/docs/js/latest/cookbook/_data.json +++ b/public/docs/js/latest/cookbook/_data.json @@ -17,6 +17,12 @@ "hide": true }, + "a11y": { + "title": "ARIA / Accessibility (a11y) reference", + "navTitle": "ARIA / Accessibility (a11y)", + "intro": "Learn how to make your Angular 2 sites accessible for everyone" + }, + "component-communication": { "title": "Component Interaction", "intro": "Share information between different directives and components" diff --git a/public/docs/js/latest/cookbook/a11y.jade b/public/docs/js/latest/cookbook/a11y.jade new file mode 100644 index 0000000000..6778b6af28 --- /dev/null +++ b/public/docs/js/latest/cookbook/a11y.jade @@ -0,0 +1 @@ +!= partial("../../../_includes/_ts-temp") diff --git a/public/docs/ts/latest/cookbook/_data.json b/public/docs/ts/latest/cookbook/_data.json index 7a45a91e77..e67cda277e 100644 --- a/public/docs/ts/latest/cookbook/_data.json +++ b/public/docs/ts/latest/cookbook/_data.json @@ -21,6 +21,12 @@ "intro": "Answers to frequently asked questions about @NgModule" }, + "a11y": { + "title": "ARIA / Accessibility (a11y) reference", + "navTitle": "ARIA / Accessibility (a11y)", + "intro": "Learn how to make your Angular 2 sites accessible for everyone" + }, + "component-communication": { "title": "Component Interaction", "intro": "Share information between different directives and components" diff --git a/public/docs/ts/latest/cookbook/a11y.jade b/public/docs/ts/latest/cookbook/a11y.jade new file mode 100644 index 0000000000..1a6dbbcab1 --- /dev/null +++ b/public/docs/ts/latest/cookbook/a11y.jade @@ -0,0 +1,1091 @@ +include ../_util-fns + +:marked + Many people rely on assistive technologies to interact with the web, accessing visual + content via screen readers or braille displays. Some rely exclusively on the keyboard for + input, others adapt to motor impairment via pointing devices other than a mouse. + + This guide will show you how to design Angular components and applications that work well + for all users. + +:marked + **Follow along in this [live example](/resources/live-examples/cb-a11y/ts/plnkr.html)**. + + +.l-main-section + +:marked + ## Table of contents + + [Accessible form control labels](#form-control-labels) + + [Managing focus](#managing-focus) + + [Roles for custom component widgets](#component-roles) + + [Tools to help you build accessible web pages](#developer-tools) + + +.l-main-section + +:marked + ## Accessible form control labels + + Native HTML elements already have accessibility support via the browser. Because Angular extends + HTML and allows you to create your own elements, it's important to ensure that anything you add + also works in an accessible way. + +.l-sub-section + :marked + If there is already an HTML element that provides the function that you need, use that element + instead of writing your own. You'll get all the built-in browser support for focus management, + tabindex, etc. and have more time to think about your code. If you want to accept user text + input, use the `input` element instead of constructing something new. + +:marked + Because assistive technologies can't rely on the visual appearance of a form component, + any form component, or `form control` must be explicitly labeled to ensure that it's clear what + its purpose is. + + We will discuss some ways to do this. + + ### Implicit labeling + + The most direct way to assign an accessible label to a form control is by `implicit + labeling` with a `