[A11y] Fix header breadcrumb contrast Amsterdam (#217950)

## Summary

This PR resolves [(Accessibility) breadcrumb contrast too
low](https://github.com/elastic/kibana/issues/214597) issue.

This is a targeted fix for Amsterdam theme, since there is no plan now
to introduce HCM.

After:

<img width="1436" alt="Screenshot 2025-04-11 at 11 09 02"
src="https://github.com/user-attachments/assets/e6a1ff33-cd35-425c-bcb8-8342893b5d5d"
/>

<img width="1400" alt="Screenshot 2025-04-11 at 11 10 21"
src="https://github.com/user-attachments/assets/a6d1e31c-7197-494c-9f04-01f1716ccbb1"
/>
This commit is contained in:
Paulina Shakirova 2025-04-16 15:05:02 +02:00 committed by GitHub
parent b935520b3b
commit 6903db892c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 53 additions and 19 deletions

View file

@ -182,7 +182,7 @@ Array [
</div>
<nav
aria-label="Breadcrumbs"
class="euiBreadcrumbs euiHeaderBreadcrumbs emotion-euiHeaderBreadcrumbs"
class="euiBreadcrumbs euiHeaderBreadcrumbs emotion-euiHeaderBreadcrumbs-HeaderBreadcrumbs"
data-test-subj="breadcrumbs"
>
<ol

View file

@ -16,6 +16,7 @@ import { applicationServiceMock } from '@kbn/core-application-browser-mocks';
import { docLinksServiceMock } from '@kbn/core-doc-links-browser-mocks';
import type { ChromeBreadcrumbsAppendExtension } from '@kbn/core-chrome-browser';
import { Header } from './header';
import { EuiThemeProvider } from '@elastic/eui';
function mockProps() {
const http = httpServiceMock.createSetupContract({ basePath: '/test' });
@ -86,18 +87,20 @@ describe('Header', () => {
undefined | ChromeBreadcrumbsAppendExtension
>(undefined);
const component = mountWithIntl(
<Header
{...mockProps()}
breadcrumbs$={breadcrumbs$}
navLinks$={navLinks$}
recentlyAccessed$={recentlyAccessed$}
isLocked$={isLocked$}
customNavLink$={customNavLink$}
breadcrumbsAppendExtension$={breadcrumbsAppendExtension$}
headerBanner$={headerBanner$}
helpMenuLinks$={of([])}
isServerless={false}
/>
<EuiThemeProvider>
<Header
{...mockProps()}
breadcrumbs$={breadcrumbs$}
navLinks$={navLinks$}
recentlyAccessed$={recentlyAccessed$}
isLocked$={isLocked$}
customNavLink$={customNavLink$}
breadcrumbsAppendExtension$={breadcrumbsAppendExtension$}
headerBanner$={headerBanner$}
helpMenuLinks$={of([])}
isServerless={false}
/>
</EuiThemeProvider>
);
expect(component.find('EuiHeader').exists()).toBeTruthy();
expect(component.find('nav[aria-label="Primary"]').exists()).toBeFalsy();

View file

@ -10,6 +10,7 @@
import '@testing-library/jest-dom';
import { act, render, screen } from '@testing-library/react';
import React from 'react';
import { EuiThemeProvider } from '@elastic/eui';
import { BehaviorSubject, of } from 'rxjs';
import { HeaderBreadcrumbs } from './header_breadcrumbs';
@ -17,7 +18,11 @@ describe('HeaderBreadcrumbs', () => {
it('renders updates to the breadcrumbs$ observable', async () => {
const breadcrumbs$ = new BehaviorSubject([{ text: 'First' }]);
render(<HeaderBreadcrumbs breadcrumbs$={breadcrumbs$} />);
render(
<EuiThemeProvider>
<HeaderBreadcrumbs breadcrumbs$={breadcrumbs$} />
</EuiThemeProvider>
);
expect(await screen.findByLabelText('Breadcrumbs')).toHaveTextContent('First');
@ -36,7 +41,11 @@ describe('HeaderBreadcrumbs', () => {
{ text: 'Last', href: '/something', onClick: jest.fn() },
]);
render(<HeaderBreadcrumbs breadcrumbs$={breadcrumbs$} />);
render(
<EuiThemeProvider>
<HeaderBreadcrumbs breadcrumbs$={breadcrumbs$} />
</EuiThemeProvider>
);
const lastBreadcrumb = await screen.findByTitle('Last');

View file

@ -7,7 +7,8 @@
* License v3.0 only", or the "Server Side Public License, v 1".
*/
import { EuiHeaderBreadcrumbs } from '@elastic/eui';
import { EuiHeaderBreadcrumbs, makeHighContrastColor, shade, tint } from '@elastic/eui';
import { css } from '@emotion/react';
import classNames from 'classnames';
import React from 'react';
import useObservable from 'react-use/lib/useObservable';
@ -43,6 +44,26 @@ export function HeaderBreadcrumbs({ breadcrumbs$ }: Props) {
),
};
});
return <EuiHeaderBreadcrumbs breadcrumbs={crumbs} max={10} data-test-subj="breadcrumbs" />;
// Modify last breadcrumb's text color to comply with A11y contrast ratio (AA)
// https://github.com/elastic/kibana/issues/214597
return (
<EuiHeaderBreadcrumbs
breadcrumbs={crumbs}
max={10}
data-test-subj="breadcrumbs"
css={({ euiTheme, colorMode }) => css`
[class*='euiBreadcrumb-application'] .euiBreadcrumb__content:not(.euiLink) {
color: ${makeHighContrastColor(
colorMode === 'DARK'
? shade(euiTheme.colors.darkestShade, 0.2)
: tint(euiTheme.colors.darkestShade, 0.2)
)(
colorMode === 'DARK'
? shade(euiTheme.colors.darkestShade, 0.7)
: tint(euiTheme.colors.darkestShade, 0.85)
)};
}
`}
/>
);
}

View file

@ -8,7 +8,8 @@
"react",
"@kbn/ambient-ui-types",
"@kbn/ambient-storybook-types",
"@emotion/react/types/css-prop"
"@emotion/react/types/css-prop",
"../../../../../typings/emotion.d.ts"
]
},
"include": [