From 1c2ad223bf26e11416e8ee3df04e4cda48f614d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jon=20W=C3=A5lstedt?= Date: Thu, 5 Feb 2026 09:12:51 +0100 Subject: [PATCH] fix(kbn-elastic-assistant): fix a11y issue with missing label on flyout (#251656) ## Summary Adds missing `aria-label` property on the usage of the `EuiFlyout` component in [flyout component](https://github.com/elastic/kibana/blob/main/x-pack/platform/packages/shared/kbn-elastic-assistant/impl/assistant/common/components/assistant_settings_management/flyout/index.tsx) causing screen readers to only get the "....you are in a modal dialog..." message read. See https://eui.elastic.co/docs/components/containers/flyout/#props for `aria-label` usage in the `EuiFlyout` component. Unit tests added to ensure the `aria-label` property is passed. Verified using the VoiceOver screen reader on MacOS. Closes https://github.com/elastic/kibana/issues/231501 ### Checklist Check the PR satisfies following conditions. Reviewers should verify this PR satisfies this list as well. - [ ] 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/src/platform/packages/shared/kbn-i18n/README.md) - [ ] [Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html) was added for features that require explanation or tutorials - [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 - [ ] If a plugin configuration key changed, check if it needs to be allowlisted in the cloud and added to the [docker list](https://github.com/elastic/kibana/blob/main/src/dev/build/tasks/os_packages/docker_generator/resources/base/bin/kibana-docker) - [ ] This was checked for breaking HTTP API changes, and any breaking changes have been approved by the breaking-change committee. The `release_note:breaking` label should be applied in these situations. - [ ] [Flaky Test Runner](https://ci-stats.kibana.dev/trigger_flaky_test_runner/1) was used on any tests changed - [ ] The PR description includes the appropriate Release Notes section, and the correct `release_note:*` label is applied per the [guidelines](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process) - [ ] Review the [backport guidelines](https://docs.google.com/document/d/1VyN5k91e5OVumlc0Gb9RPa3h1ewuPE705nRtioPiTvY/edit?usp=sharing) and apply applicable `backport:*` labels. ### Identify risks Does this PR introduce any risks? For example, consider risks like hard to test bugs, performance regression, potential of data loss. No risks identified. *PR developed with Cursor CLI + GPT Codex 5.2 Hight Fast* --------- Co-authored-by: Elastic Machine (cherry picked from commit 7b08c8ce68e8ae0630a989f50242ba91501c8d16) --- .../flyout/index.test.tsx | 58 +++++++++++++++++++ .../flyout/index.tsx | 1 + 2 files changed, 59 insertions(+) create mode 100644 x-pack/platform/packages/shared/kbn-elastic-assistant/impl/assistant/common/components/assistant_settings_management/flyout/index.test.tsx diff --git a/x-pack/platform/packages/shared/kbn-elastic-assistant/impl/assistant/common/components/assistant_settings_management/flyout/index.test.tsx b/x-pack/platform/packages/shared/kbn-elastic-assistant/impl/assistant/common/components/assistant_settings_management/flyout/index.test.tsx new file mode 100644 index 0000000000000..ac3e1c23f4beb --- /dev/null +++ b/x-pack/platform/packages/shared/kbn-elastic-assistant/impl/assistant/common/components/assistant_settings_management/flyout/index.test.tsx @@ -0,0 +1,58 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { render } from '@testing-library/react'; +import { EuiFlyout } from '@elastic/eui'; +import { Flyout } from '.'; + +jest.mock('@elastic/eui', () => { + const actual = jest.requireActual('@elastic/eui'); + + return { + ...actual, + EuiFlyout: jest.fn(({ children }: { children: React.ReactNode }) =>
{children}
), + }; +}); + +describe('Assistant settings flyout', () => { + const requiredProps = { + flyoutVisible: true, + onClose: jest.fn(), + onSaveCancelled: jest.fn(), + onSaveConfirmed: jest.fn(), + }; + + beforeEach(() => { + (EuiFlyout as unknown as jest.Mock).mockClear(); + }); + + it('passes aria-label from the title to EuiFlyout', () => { + const title = 'Edit system prompt'; + const mockedEuiFlyout = EuiFlyout as unknown as jest.Mock; + render( + +
{'Body'}
+
+ ); + + const firstCallProps = mockedEuiFlyout.mock.calls[0]?.[0]; + expect(firstCallProps?.['aria-label']).toBe(title); + }); + + it('does not pass aria-label when the title is missing', () => { + const mockedEuiFlyout = EuiFlyout as unknown as jest.Mock; + render( + +
{'Body'}
+
+ ); + + const firstCallProps = mockedEuiFlyout.mock.calls[0]?.[0]; + expect(firstCallProps?.['aria-label']).toBeUndefined(); + }); +}); diff --git a/x-pack/platform/packages/shared/kbn-elastic-assistant/impl/assistant/common/components/assistant_settings_management/flyout/index.tsx b/x-pack/platform/packages/shared/kbn-elastic-assistant/impl/assistant/common/components/assistant_settings_management/flyout/index.tsx index b54f43c6a3aa4..ce498a82fcf9f 100644 --- a/x-pack/platform/packages/shared/kbn-elastic-assistant/impl/assistant/common/components/assistant_settings_management/flyout/index.tsx +++ b/x-pack/platform/packages/shared/kbn-elastic-assistant/impl/assistant/common/components/assistant_settings_management/flyout/index.tsx @@ -46,6 +46,7 @@ const FlyoutComponent: React.FC = ({ data-test-subj={'flyout'} ownFocus onClose={onClose} + aria-label={title} css={css` max-width: 656px; `}