Skip to content

Commit

Permalink
Add EuiSkipLink to Kibana header (#153810)
Browse files Browse the repository at this point in the history
## Summary

This PR adds a "skip to main content" button, AKA a [skip
link](https://webaim.org/techniques/skipnav/) via
[EuiSkipLink](https://elastic.github.io/eui/#/utilities/accessibility#skip-link).

For initial behavior, this PR attempts to find a `main` tag (which will
succeed for all plugins using `KibanaPageTemplate`, followed by a
`.euiPageContent` className (which will succeed for plugins using the
old/deprecated `KibanaPageTemplate`), and as a worst case scenario for
plugins not using any EUI or Kibana page templates, targets the
`.kbnAppWrapper` app root which should be present on all pages.

At some point Kibana may want to consider adding a UI API for allowing
individual apps/plugins to set a custom `destinationId`.

## QA

- [x] Go to a plugin that uses the new KibanaPageTemplate, e.g.
Observability or Security, and confirm that the skip link correctly
targets the main content:

![1](https://user-images.githubusercontent.com/549407/228051255-0a94c95d-baf2-4ab4-8aef-e9b479de70ec.gif)

- [x] Go to a plugin that uses the old deprecated KibanaPageTemplate,
e.g. Canvas (http://localhost:5601/xyz/app/canvas), and confirm that the
skip link correctly targets the page content:

![2](https://user-images.githubusercontent.com/549407/228051148-6b0089e6-ba62-429f-90de-523f3e90e630.gif)

- [x] Go to a plugin that does not use any Kibana page template, e.g.
Maps (http://localhost:5601/xyz/app/maps) and confirm that the skip link
correctly targets the app wrapper on that plugin:

![3](https://user-images.githubusercontent.com/549407/228051161-bec401a3-e21a-41da-9911-dc95745b1d99.gif)

### Checklist

- [x] Any text added follows [EUI's writing
guidelines](https://elastic.github.io/eui/#/guidelines/writing), uses
sentence case text and includes [i18n
support](https://github.com/elastic/kibana/blob/main/packages/kbn-i18n/README.md)
- [x] [Unit or functional
tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)
were updated or added to match the most common scenarios
- [x] Any UI touched in this PR is usable by keyboard only (learn more
about [keyboard accessibility](https://webaim.org/techniques/keyboard/))
- [x] Any UI touched in this PR does not create any new axe failures
(run axe in browser:
[FF](https://addons.mozilla.org/en-US/firefox/addon/axe-devtools/),
[Chrome](https://chrome.google.com/webstore/detail/axe-web-accessibility-tes/lhdoppojpmngadmnindnejefpokejbdd?hl=en-US))
- [x] This renders correctly on smaller devices using a responsive
layout. (You can test this [in your
browser](https://www.browserstack.com/guide/responsive-testing-on-local-server))
- [x] This was checked for [cross-browser
compatibility](https://www.elastic.co/support/matrix#matrix_browsers)

---------

Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
  • Loading branch information
cee-chen and kibanamachine committed Mar 28, 2023
1 parent 3ff906d commit c2910f9
Show file tree
Hide file tree
Showing 5 changed files with 68 additions and 4 deletions.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ import { HeaderActionMenu } from './header_action_menu';
import { HeaderExtension } from './header_extension';
import { HeaderTopBanner } from './header_top_banner';
import { HeaderMenuButton } from './header_menu_button';
import { ScreenReaderRouteAnnouncements } from './screen_reader_a11y';
import { ScreenReaderRouteAnnouncements, SkipToMainContent } from './screen_reader_a11y';

export interface HeaderProps {
kibanaVersion: string;
Expand Down Expand Up @@ -114,6 +114,7 @@ export function Header({
customBranding$={customBranding$}
appId$={application.currentAppId$}
/>
<SkipToMainContent />

<HeaderTopBanner headerBanner$={observables.headerBanner$} />
<header className={className} data-test-subj="headerGlobalNav">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@
import React from 'react';
import { BehaviorSubject } from 'rxjs';
import { mountWithIntl } from '@kbn/test-jest-helpers';
import { ScreenReaderRouteAnnouncements } from './screen_reader_a11y';
import { mount } from 'enzyme';
import { ScreenReaderRouteAnnouncements, SkipToMainContent } from './screen_reader_a11y';
import { mount, render } from 'enzyme';

describe('ScreenReaderRouteAnnouncements', () => {
it('renders', () => {
Expand Down Expand Up @@ -67,3 +67,10 @@ describe('ScreenReaderRouteAnnouncements', () => {
).toBeTruthy();
});
});

describe('SkipToMainContent', () => {
it('renders', () => {
const component = render(<SkipToMainContent />);
expect(component).toMatchSnapshot();
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@

import React, { FC, useState, useEffect } from 'react';
import useObservable from 'react-use/lib/useObservable';
import { EuiScreenReaderLive } from '@elastic/eui';
import { EuiScreenReaderLive, EuiSkipLink } from '@elastic/eui';
import { i18n } from '@kbn/i18n';

import type { InternalApplicationStart } from '@kbn/core-application-browser-internal';
import type { HeaderProps } from './header';
Expand Down Expand Up @@ -56,3 +57,25 @@ export const ScreenReaderRouteAnnouncements: FC<{
</EuiScreenReaderLive>
);
};

const fallbackContentQueries = [
'main', // Ideal target for all plugins using KibanaPageTemplate
'[role="main"]', // Fallback for plugins using deprecated EuiPageContent
'.kbnAppWrapper', // Last-ditch fallback for all plugins regardless of page template
];

export const SkipToMainContent = () => {
return (
<EuiSkipLink
position="fixed"
destinationId="" // TODO: Potentially allow this to be customizable per-plugin
fallbackDestination={fallbackContentQueries}
overrideLinkBehavior
href="" // Render a button
>
{i18n.translate('core.ui.skipToMainButton', {
defaultMessage: 'Skip to main content',
})}
</EuiSkipLink>
);
};

0 comments on commit c2910f9

Please sign in to comment.