diff --git a/ui_framework/components/accessibility/__snapshots__/screen_reader.test.js.snap b/ui_framework/components/accessibility/__snapshots__/screen_reader.test.js.snap new file mode 100644 index 000000000000..b1f99be5c72b --- /dev/null +++ b/ui_framework/components/accessibility/__snapshots__/screen_reader.test.js.snap @@ -0,0 +1,17 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`KuiScreenReaderOnly adds an accessibility class to a child element and combines other classNames (foo, bar) given as props on the child 1`] = ` +

+ This paragraph is not visibile to sighted users but will be read by screenreaders. +

+`; + +exports[`KuiScreenReaderOnly adds an accessibility class to a child element when used with no props 1`] = ` +

+ This paragraph is not visibile to sighted users but will be read by screenreaders. +

+`; diff --git a/ui_framework/components/accessibility/_index.scss b/ui_framework/components/accessibility/_index.scss new file mode 100644 index 000000000000..37ec009af1e9 --- /dev/null +++ b/ui_framework/components/accessibility/_index.scss @@ -0,0 +1 @@ +@import "./_screen_reader"; diff --git a/ui_framework/components/accessibility/_screen_reader.scss b/ui_framework/components/accessibility/_screen_reader.scss new file mode 100644 index 000000000000..1d846635e21b --- /dev/null +++ b/ui_framework/components/accessibility/_screen_reader.scss @@ -0,0 +1,8 @@ +.kuiScreenReaderOnly { + position: absolute; + left: -10000px; + top: auto; + width: 1px; + height: 1px; + overflow: hidden; +} diff --git a/ui_framework/components/accessibility/index.js b/ui_framework/components/accessibility/index.js index 5b0bcc6eab80..d847a370d0d9 100644 --- a/ui_framework/components/accessibility/index.js +++ b/ui_framework/components/accessibility/index.js @@ -1 +1,2 @@ export { KuiKeyboardAccessible } from './keyboard_accessible'; +export { KuiScreenReaderOnly } from './screen_reader'; diff --git a/ui_framework/components/accessibility/screen_reader.js b/ui_framework/components/accessibility/screen_reader.js new file mode 100644 index 000000000000..53f40e28c353 --- /dev/null +++ b/ui_framework/components/accessibility/screen_reader.js @@ -0,0 +1,20 @@ +import { + cloneElement, + PropTypes, +} from 'react'; +import classNames from 'classnames'; + + +export const KuiScreenReaderOnly = ({ children }) => { + const classes = classNames('kuiScreenReaderOnly', children.props.className); + + const props = Object.assign({}, children.props, { + className: classes + }); + + return cloneElement(children, props); +}; + +KuiScreenReaderOnly.propTypes = { + children: PropTypes.node +}; diff --git a/ui_framework/components/accessibility/screen_reader.test.js b/ui_framework/components/accessibility/screen_reader.test.js new file mode 100644 index 000000000000..f22e2f4079e1 --- /dev/null +++ b/ui_framework/components/accessibility/screen_reader.test.js @@ -0,0 +1,35 @@ +import React from 'react'; +import { render } from 'enzyme'; + +import { KuiScreenReaderOnly } from './screen_reader'; + +describe('KuiScreenReaderOnly', () => { + describe('adds an accessibility class to a child element', () => { + test('when used with no props', () => { + const $paragraph = render( + +

+ This paragraph is not visibile to sighted users but will be read by + screenreaders. +

+
+ ); + + expect($paragraph) + .toMatchSnapshot(); + }); + test('and combines other classNames (foo, bar) given as props on the child', () => { + const $paragraph = render( + +

+ This paragraph is not visibile to sighted users but will be read by + screenreaders. +

+
+ ); + + expect($paragraph) + .toMatchSnapshot(); + }); + }); +}); diff --git a/ui_framework/components/index.js b/ui_framework/components/index.js index 982c193589e6..7b5b3af2f313 100644 --- a/ui_framework/components/index.js +++ b/ui_framework/components/index.js @@ -2,6 +2,7 @@ export { KuiActionItem } from './action_item'; export { KuiKeyboardAccessible, + KuiScreenReaderOnly, } from './accessibility'; export { diff --git a/ui_framework/components/index.scss b/ui_framework/components/index.scss index 63949ddd23a3..85d81497714d 100644 --- a/ui_framework/components/index.scss +++ b/ui_framework/components/index.scss @@ -19,6 +19,7 @@ @import "common_styles"; // Components +@import "accessibility/index"; @import "action_item/index"; @import "badge/index"; @import "bar/index"; diff --git a/ui_framework/dist/ui_framework.css b/ui_framework/dist/ui_framework.css index cc9213e37281..19f75b13f797 100644 --- a/ui_framework/dist/ui_framework.css +++ b/ui_framework/dist/ui_framework.css @@ -76,6 +76,14 @@ main { display: block; /* 1 */ } +.kuiScreenReaderOnly { + position: absolute; + left: -10000px; + top: auto; + width: 1px; + height: 1px; + overflow: hidden; } + .kuiActionItem { display: -webkit-box; display: -webkit-flex; diff --git a/ui_framework/doc_site/src/views/accessibility/accessibility_example.js b/ui_framework/doc_site/src/views/accessibility/accessibility_example.js index ca71a09e09c5..470127beea62 100644 --- a/ui_framework/doc_site/src/views/accessibility/accessibility_example.js +++ b/ui_framework/doc_site/src/views/accessibility/accessibility_example.js @@ -5,6 +5,7 @@ import { renderToHtml } from '../../services'; import { GuideCode, GuideDemo, + GuideLink, GuidePage, GuideSection, GuideSectionTypes, @@ -12,9 +13,14 @@ import { } from '../../components'; import KeyboardAccessible from './keyboard_accessible'; +import ScreenReaderOnly from './screen_reader'; + const keyboardAccessibleSource = require('!!raw!./keyboard_accessible'); const keyboardAccessibleHtml = renderToHtml(KeyboardAccessible); +const screenReaderOnlyHtml = renderToHtml(ScreenReaderOnly); +const screenReaderOnlySource = require('!!raw!./screen_reader'); + export default props => ( ( + + + + This class can be useful to add accessibility to older designs that are + still in use, but it shouldn't be a permanent solution. See + http://webaim.org/techniques/css/invisiblecontent/ + { + // eslint-disable-next-line react/jsx-closing-tag-location + } for more information. + + + + Use a screenreader to verify that there is a second paragraph in this example: + + + + + + ); diff --git a/ui_framework/doc_site/src/views/accessibility/screen_reader.js b/ui_framework/doc_site/src/views/accessibility/screen_reader.js new file mode 100644 index 000000000000..49ac86d04cb0 --- /dev/null +++ b/ui_framework/doc_site/src/views/accessibility/screen_reader.js @@ -0,0 +1,23 @@ +import React from 'react'; + +import { + KuiScreenReaderOnly, +} from '../../../../components'; + + +export default () => ( +
+

+ This is the first paragraph. It is visible to all. +

+ +

+ This is the second paragraph. It is hidden for sighted users but visible to screen readers. +

+
+

+ This is the third paragraph. It is visible to all. +

+
+); +