diff --git a/CHANGELOG.md b/CHANGELOG.md
index 4035559c5d39..1d1320af2fd6 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,7 @@
## [`master`](https://github.com/elastic/eui/tree/master)
+- Added `showOnFocus` prop to `EuiScreenReaderOnly` to force display on keyboard focus ([#2976](https://github.com/elastic/eui/pull/2976))
+- Added `EuiSkipLink` component ([#2976](https://github.com/elastic/eui/pull/2976))
- `EuiButton` now has a single return statement ([#2954](https://github.com/elastic/eui/pull/2954))
- Added `isSortable` props to `EuiDataGridColumn` and `EuiDataGridSchemaDetector` to mark them as un-sortable ([#2952](https://github.com/elastic/eui/pull/2952))
- Converted `EuiForm` to TypeScript, added many missing `/form` Prop types ([#2896](https://github.com/elastic/eui/pull/2896))
diff --git a/src-docs/src/views/accessibility/accessibility_example.js b/src-docs/src/views/accessibility/accessibility_example.js
index 642a2c2f7391..6f71a70c1494 100644
--- a/src-docs/src/views/accessibility/accessibility_example.js
+++ b/src-docs/src/views/accessibility/accessibility_example.js
@@ -5,13 +5,16 @@ import { renderToHtml } from '../../services';
import { GuideSectionTypes } from '../../components';
import {
+ EuiCallOut,
EuiCode,
EuiLink,
EuiKeyboardAccessible,
+ EuiSkipLink,
} from '../../../../src/components';
import KeyboardAccessible from './keyboard_accessible';
import ScreenReaderOnly from './screen_reader';
+import SkipLink from './skip_link';
const keyboardAccessibleSource = require('!!raw-loader!./keyboard_accessible');
const keyboardAccessibleHtml = renderToHtml(KeyboardAccessible);
@@ -19,13 +22,16 @@ const keyboardAccessibleHtml = renderToHtml(KeyboardAccessible);
const screenReaderOnlyHtml = renderToHtml(ScreenReaderOnly);
const screenReaderOnlySource = require('!!raw-loader!./screen_reader');
+const skipLinkHtml = renderToHtml(SkipLink);
+const skipLinkSource = require('!!raw-loader!./skip_link');
+
import { ScreenReaderOnlyDocsComponent } from './props';
export const AccessibilityExample = {
title: 'Accessibility',
sections: [
{
- title: 'KeyboardAccessible',
+ title: 'Keyboard accessible',
source: [
{
type: GuideSectionTypes.JS,
@@ -38,9 +44,9 @@ export const AccessibilityExample = {
],
text: (
- You can make interactive elements keyboard-accessible with this
- component. This is necessary for non-button elements and{' '}
- a tags without
+ You can make interactive elements keyboard-accessible with the{' '}
+ EuiKeyboardAccessible component. This is necessary
+ for non-button elements and a tags without{' '}
href attributes.
),
@@ -48,7 +54,7 @@ export const AccessibilityExample = {
demo: ,
},
{
- title: 'ScreenReaderOnly',
+ title: 'Screen reader only',
source: [
{
type: GuideSectionTypes.JS,
@@ -62,20 +68,51 @@ export const AccessibilityExample = {
text: (
- 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{' '}
- {
+ Use the EuiScreenReaderOnly component to visually
+ hide elements while still allowing them to be read by screen
+ readers.
+
+
+
+ In most cases, if content (particularly content that provides
+ functionality or interactivity) is important enough to provide to
+ screen reader users, it should probably be made available to all
+ users.{' '}
- http://webaim.org/techniques/css/invisiblecontent/
+ Learn more
- }{' '}
- for more information.
-
+
+
),
- props: { EuiScreenReaderOnly: ScreenReaderOnlyDocsComponent },
+ props: {
+ EuiScreenReaderOnly: ScreenReaderOnlyDocsComponent,
+ },
demo: ,
},
+ {
+ title: 'Skip to main content',
+ source: [
+ {
+ type: GuideSectionTypes.JS,
+ code: skipLinkSource,
+ },
+ {
+ type: GuideSectionTypes.HTML,
+ code: skipLinkHtml,
+ },
+ ],
+ text: (
+
+ The EuiSkipLink component allows users to bypass
+ navigation and quickly reach the main content of the page.
+
+ ),
+ props: { EuiSkipLink },
+ demo: ,
+ },
],
};
diff --git a/src-docs/src/views/accessibility/screen_reader.tsx b/src-docs/src/views/accessibility/screen_reader.tsx
index e8ce8dc3281b..80d0023121f3 100644
--- a/src-docs/src/views/accessibility/screen_reader.tsx
+++ b/src-docs/src/views/accessibility/screen_reader.tsx
@@ -8,6 +8,9 @@ import { EuiTitle } from '../../../../src/components/title';
export default () => (
+
+ Visually hide content
+
Use a screenreader to verify that there is a second paragraph in this
@@ -27,16 +30,17 @@ export default () => (
- In certain cases, such as a Skip to content link, you
- can use the showOnFocus prop to display
- screenreader content upon focus. For example, tabbing to this section
- with your keyboard will display a link.
+ In certain cases, you may want to display screen reader-only content
+ when it is in focus. This can be accoplished by adding the{' '}
+ showOnFocus prop. For example, tabbing through this
+ section with your keyboard will display a ‘Skip to content
+ ’ link:
This link is visible to all on focus:{' '}
- Skip content
+ Skip to content
diff --git a/src-docs/src/views/accessibility/skip_link.tsx b/src-docs/src/views/accessibility/skip_link.tsx
new file mode 100644
index 000000000000..f967e9b88bf2
--- /dev/null
+++ b/src-docs/src/views/accessibility/skip_link.tsx
@@ -0,0 +1,34 @@
+import React from 'react';
+
+import { EuiSkipLink } from '../../../../src/components/accessibility/skip_link';
+import { EuiCallOut } from '../../../../src/components/call_out';
+import { EuiText } from '../../../../src/components/text';
+import { EuiPortal } from '../../../../src/components/portal';
+
+export default () => (
+
+
+
+
+ Tab out of the browser's address bar and a{' '}
+ Skip to main content link will appear on this page.
+
+
+
+
+
+
+
+
+);
diff --git a/src/components/accessibility/_index.scss b/src/components/accessibility/_index.scss
index 98294afdf558..b8b7ffe9a8f1 100644
--- a/src/components/accessibility/_index.scss
+++ b/src/components/accessibility/_index.scss
@@ -1 +1,2 @@
@import 'screen_reader';
+@import 'skip_link';
diff --git a/src/components/accessibility/_skip_link.scss b/src/components/accessibility/_skip_link.scss
new file mode 100644
index 000000000000..2dc6c46c9101
--- /dev/null
+++ b/src/components/accessibility/_skip_link.scss
@@ -0,0 +1,18 @@
+.euiSkipLink {
+ @include euiSlightShadow;
+ display: block;
+ z-index: $euiZHeader + 1;
+ background-color: $euiColorPrimary;
+ color: $euiColorGhost;
+ font-size: $euiFontSizeS;
+ padding: $euiSizeM $euiSize;
+
+ &:focus,
+ &:hover {
+ position: fixed;
+ top: 0;
+ left: $euiSizeS;
+ border-radius: 0 0 $euiBorderRadius $euiBorderRadius;
+ text-decoration: underline;
+ }
+}
diff --git a/src/components/accessibility/index.ts b/src/components/accessibility/index.ts
index d63ef5aa8008..06e7f202092d 100644
--- a/src/components/accessibility/index.ts
+++ b/src/components/accessibility/index.ts
@@ -1,2 +1,3 @@
export { EuiKeyboardAccessible } from './keyboard_accessible';
export { EuiScreenReaderOnly } from './screen_reader';
+export { EuiSkipLink } from './skip_link';
diff --git a/src/components/accessibility/skip_link.tsx b/src/components/accessibility/skip_link.tsx
new file mode 100644
index 000000000000..27ddfbd86f31
--- /dev/null
+++ b/src/components/accessibility/skip_link.tsx
@@ -0,0 +1,34 @@
+import React, { FunctionComponent } from 'react';
+import classNames from 'classnames';
+import { EuiScreenReaderOnly } from '../accessibility/screen_reader';
+
+export interface EuiSkipLinkProps {
+ /**
+ * Typically an anchor id (e.g. `#a11yMainContent`), the value provided here
+ * equates to the href for the link.
+ */
+ destination: string;
+
+ /**
+ * The text to be displayed as a link.
+ */
+ label: string;
+
+ tabIndex?: number;
+}
+
+export const EuiSkipLink: FunctionComponent
= ({
+ destination,
+ label,
+ tabIndex = 0,
+}) => {
+ const classes = classNames('euiSkipLink');
+
+ return (
+
+
+ {label}
+
+
+ );
+};
diff --git a/src/components/index.js b/src/components/index.js
index f4cb7cf66528..764036c894d5 100644
--- a/src/components/index.js
+++ b/src/components/index.js
@@ -4,7 +4,11 @@ export { EuiAspectRatio } from './aspect_ratio';
export { EuiAvatar } from './avatar';
-export { EuiKeyboardAccessible, EuiScreenReaderOnly } from './accessibility';
+export {
+ EuiKeyboardAccessible,
+ EuiScreenReaderOnly,
+ EuiSkipLink,
+} from './accessibility';
export { EuiBadge, EuiBetaBadge, EuiNotificationBadge } from './badge';