[Chrome Project Header] Fix side nav collapsed state toggle (#159850)

## Summary

Closes https://github.com/elastic/kibana/issues/159846

This PR restores this specific code to how it was previous to
09577fa0af

### Checklist

Delete any items that are not applicable to this PR.

- [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)
This commit is contained in:
Tim Sullivan 2023-06-19 07:47:14 -07:00 committed by GitHub
parent f4d71c2a5e
commit acda8cf8b9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 79 additions and 15 deletions

View file

@ -0,0 +1,71 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
import { EuiHeader } from '@elastic/eui';
import { applicationServiceMock } from '@kbn/core-application-browser-mocks';
import { fireEvent, render, screen } from '@testing-library/react';
import React from 'react';
import * as Rx from 'rxjs';
import { ProjectHeader, Props as ProjectHeaderProps } from './header';
const mockApplication = applicationServiceMock.createInternalStartContract();
describe('Header', () => {
const mockProps: Omit<ProjectHeaderProps, 'children'> = {
application: mockApplication,
breadcrumbs$: Rx.of([]),
actionMenu$: Rx.of(undefined),
kibanaDocLink: 'app/help/doclinks',
globalHelpExtensionMenuLinks$: Rx.of([]),
helpExtension$: Rx.of(undefined),
helpSupportUrl$: Rx.of('app/help'),
homeHref$: Rx.of('app/home'),
kibanaVersion: '8.9',
loadingCount$: Rx.of(0),
navControlsLeft$: Rx.of([]),
navControlsCenter$: Rx.of([]),
navControlsRight$: Rx.of([]),
prependBasePath: (str) => `hello/world/${str}`,
};
it('renders', async () => {
render(
<ProjectHeader {...mockProps}>
<EuiHeader>Hello, world!</EuiHeader>
</ProjectHeader>
);
expect(await screen.findByTestId('toggleNavButton')).toBeVisible();
expect(await screen.findByText('Hello, world!')).toBeVisible();
});
it('can collapse and uncollapse', async () => {
render(
<ProjectHeader {...mockProps}>
<EuiHeader>Hello, goodbye!</EuiHeader>
</ProjectHeader>
);
expect(await screen.findByTestId('toggleNavButton')).toBeVisible();
expect(await screen.findByText('Hello, goodbye!')).toBeVisible(); // title is shown
const toggleNav = async () => {
fireEvent.click(await screen.findByTestId('toggleNavButton')); // click
expect(screen.queryAllByText('Hello, goodbye!')).toHaveLength(0); // title is not shown
fireEvent.click(await screen.findByTestId('toggleNavButton')); // click again
expect(await screen.findByText('Hello, goodbye!')).toBeVisible(); // title is shown
};
await toggleNav();
await toggleNav();
await toggleNav();
});
});

View file

@ -84,7 +84,7 @@ const headerStrings = {
},
};
interface Props {
export interface Props {
breadcrumbs$: Observable<ChromeBreadcrumb[]>;
actionMenu$: Observable<MountPoint | undefined>;
kibanaDocLink: string;
@ -169,18 +169,6 @@ export const ProjectHeader = ({
const toggleCollapsibleNavRef = createRef<HTMLButtonElement & { euiAnimate: () => void }>();
const headerActionMenuMounter = useHeaderActionMenuMounter(observables.actionMenu$);
const handleCloseNav = useCallback(() => {
setIsOpen(false);
if (toggleCollapsibleNavRef.current) {
toggleCollapsibleNavRef.current.focus();
}
}, [setIsOpen, toggleCollapsibleNavRef]);
const handleToggleNavButtonClick = useCallback(
() => setIsOpen((prevIsOpen) => !prevIsOpen),
[setIsOpen]
);
return (
<>
<EuiHeader position="fixed" data-test-subj="kibanaProjectHeader">
@ -190,12 +178,17 @@ export const ProjectHeader = ({
<CompatRouter>
<ProjectNavigation
isOpen={isOpen!}
closeNav={handleCloseNav}
closeNav={() => {
setIsOpen(false);
if (toggleCollapsibleNavRef.current) {
toggleCollapsibleNavRef.current.focus();
}
}}
button={
<EuiHeaderSectionItemButton
data-test-subj="toggleNavButton"
aria-label={headerStrings.nav.closeNavAriaLabel}
onClick={handleToggleNavButtonClick}
onClick={() => setIsOpen(!isOpen)}
aria-expanded={isOpen!}
aria-pressed={isOpen!}
aria-controls={navId}