mirror of
https://github.com/elastic/kibana.git
synced 2025-06-28 03:01:21 -04:00
[Security Solution] Expandable flyout - add accessibility support (#166996)
## Summary This PR adds accessibility support in the new expandably flyout, namely: - Added recommended aria-label to components - Adjusted heading sizes to follow "Heading level should only increase by one" rule ### 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] 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))
This commit is contained in:
parent
14ed446c23
commit
c9a98a7846
18 changed files with 119 additions and 29 deletions
|
@ -28,11 +28,11 @@ const EnrichmentSectionHeader: React.FC<{ type?: ENRICHMENT_TYPES }> = ({ type }
|
|||
<EuiFlexGroup direction="row" gutterSize="xs" alignItems="baseline">
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiTitle size="xxxs">
|
||||
<h5>
|
||||
<h3>
|
||||
{type === ENRICHMENT_TYPES.IndicatorMatchRule
|
||||
? i18n.INDICATOR_ENRICHMENT_TITLE
|
||||
: i18n.INVESTIGATION_ENRICHMENT_TITLE}
|
||||
</h5>
|
||||
</h3>
|
||||
</EuiTitle>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem grow={false}>
|
||||
|
|
|
@ -231,12 +231,12 @@ export const HostDetails: React.FC<HostDetailsProps> = ({ hostName, timestamp, s
|
|||
return (
|
||||
<>
|
||||
<EuiTitle size="xs">
|
||||
<h4>
|
||||
<h3>
|
||||
<FormattedMessage
|
||||
id="xpack.securitySolution.flyout.left.insights.entities.hostDetailsTitle"
|
||||
defaultMessage="Host"
|
||||
/>
|
||||
</h4>
|
||||
</h3>
|
||||
</EuiTitle>
|
||||
<EuiSpacer size="s" />
|
||||
<ExpandablePanel
|
||||
|
@ -249,12 +249,12 @@ export const HostDetails: React.FC<HostDetailsProps> = ({ hostName, timestamp, s
|
|||
data-test-subj={HOST_DETAILS_TEST_ID}
|
||||
>
|
||||
<EuiTitle size="xxs">
|
||||
<h5>
|
||||
<h4>
|
||||
<FormattedMessage
|
||||
id="xpack.securitySolution.flyout.left.insights.entities.hostDetailsInfoTitle"
|
||||
defaultMessage="Host information"
|
||||
/>
|
||||
</h5>
|
||||
</h4>
|
||||
</EuiTitle>
|
||||
<EuiSpacer size="s" />
|
||||
<AnomalyTableProvider
|
||||
|
@ -289,12 +289,12 @@ export const HostDetails: React.FC<HostDetailsProps> = ({ hostName, timestamp, s
|
|||
<EuiFlexGroup direction="row" gutterSize="xs" alignItems="center">
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiTitle size="xxs">
|
||||
<h5>
|
||||
<h4>
|
||||
<FormattedMessage
|
||||
id="xpack.securitySolution.flyout.left.insights.entities.relatedUsersTitle"
|
||||
defaultMessage="Related users"
|
||||
/>
|
||||
</h5>
|
||||
</h4>
|
||||
</EuiTitle>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem grow={false}>
|
||||
|
|
|
@ -10,6 +10,7 @@ import type { EuiBasicTableColumn } from '@elastic/eui';
|
|||
import { EuiInMemoryTable, EuiSkeletonText } from '@elastic/eui';
|
||||
import type { RelatedCase } from '@kbn/cases-plugin/common';
|
||||
import { FormattedMessage } from '@kbn/i18n-react';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { CellTooltipWrapper } from '../../shared/components/cell_tooltip_wrapper';
|
||||
import { CaseDetailsLink } from '../../../common/components/links';
|
||||
import {
|
||||
|
@ -65,7 +66,19 @@ export const RelatedCases: React.VFC<RelatedCasesProps> = ({ eventId }) => {
|
|||
const { loading, error, data, dataCount } = useFetchRelatedCases({ eventId });
|
||||
|
||||
if (loading) {
|
||||
return <EuiSkeletonText lines={1} size="m" isLoading={loading} contentAriaLabel="Loading" />;
|
||||
return (
|
||||
<EuiSkeletonText
|
||||
lines={1}
|
||||
size="m"
|
||||
isLoading={loading}
|
||||
contentAriaLabel={i18n.translate(
|
||||
'xpack.securitySolution.flyout.left.insights.correlations.relatedCasesLoadingAriaLabel',
|
||||
{
|
||||
defaultMessage: 'Related cases is loading',
|
||||
}
|
||||
)}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
if (error) {
|
||||
|
|
|
@ -232,12 +232,12 @@ export const UserDetails: React.FC<UserDetailsProps> = ({ userName, timestamp, s
|
|||
return (
|
||||
<>
|
||||
<EuiTitle size="xs">
|
||||
<h4>
|
||||
<h3>
|
||||
<FormattedMessage
|
||||
id="xpack.securitySolution.flyout.left.insights.entities.userDetailsTitle"
|
||||
defaultMessage="User"
|
||||
/>
|
||||
</h4>
|
||||
</h3>
|
||||
</EuiTitle>
|
||||
<EuiSpacer size="s" />
|
||||
<ExpandablePanel
|
||||
|
@ -253,12 +253,12 @@ export const UserDetails: React.FC<UserDetailsProps> = ({ userName, timestamp, s
|
|||
data-test-subj={USER_DETAILS_TEST_ID}
|
||||
>
|
||||
<EuiTitle size="xxs">
|
||||
<h5>
|
||||
<h4>
|
||||
<FormattedMessage
|
||||
id="xpack.securitySolution.flyout.left.insights.entities.userDetailsInfoTitle"
|
||||
defaultMessage="User information"
|
||||
/>
|
||||
</h5>
|
||||
</h4>
|
||||
</EuiTitle>
|
||||
<EuiSpacer size="s" />
|
||||
<AnomalyTableProvider
|
||||
|
@ -292,12 +292,12 @@ export const UserDetails: React.FC<UserDetailsProps> = ({ userName, timestamp, s
|
|||
<EuiFlexGroup direction="row" gutterSize="xs" alignItems="center">
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiTitle size="xxs">
|
||||
<h5>
|
||||
<h4>
|
||||
<FormattedMessage
|
||||
id="xpack.securitySolution.flyout.left.insights.entities.relatedHostsTitle"
|
||||
defaultMessage="Related hosts"
|
||||
/>
|
||||
</h5>
|
||||
</h4>
|
||||
</EuiTitle>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem grow={false}>
|
||||
|
|
|
@ -113,7 +113,7 @@ export const InsightsTab: React.FC = memo(() => {
|
|||
color="primary"
|
||||
name="coarsness"
|
||||
legend={i18n.translate(
|
||||
'xpack.securitySolution.flyout.left.insights.buttonGroupButtonLabel',
|
||||
'xpack.securitySolution.flyout.left.insights.buttonGroupLegendLabel',
|
||||
{
|
||||
defaultMessage: 'Insights options',
|
||||
}
|
||||
|
|
|
@ -91,7 +91,7 @@ export const VisualizeTab: FC = memo(() => {
|
|||
color="primary"
|
||||
name="coarsness"
|
||||
legend={i18n.translate(
|
||||
'xpack.securitySolution.flyout.left.visualize.buttonGroupButtonLabel',
|
||||
'xpack.securitySolution.flyout.left.visualize.buttonGroupLegendLabel',
|
||||
{
|
||||
defaultMessage: 'Visualize options',
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@ import React, { useMemo, useCallback } from 'react';
|
|||
import { isEmpty } from 'lodash';
|
||||
import { useExpandableFlyoutContext } from '@kbn/expandable-flyout';
|
||||
import { FormattedMessage } from '@kbn/i18n-react';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { useRightPanelContext } from '../context';
|
||||
import { useBasicDataFromDetailsData } from '../../../timelines/components/side_panel/event_details/helpers';
|
||||
import {
|
||||
|
@ -65,6 +66,12 @@ export const Description: FC = () => {
|
|||
onClick={openRulePreview}
|
||||
iconSide="right"
|
||||
data-test-subj={RULE_SUMMARY_BUTTON_TEST_ID}
|
||||
aria-label={i18n.translate(
|
||||
'xpack.securitySolution.flyout.right.about.description.ruleSummaryButtonAriaLabel',
|
||||
{
|
||||
defaultMessage: 'Show rule summary',
|
||||
}
|
||||
)}
|
||||
>
|
||||
<FormattedMessage
|
||||
id="xpack.securitySolution.flyout.right.about.description.ruleSummaryButtonLabel"
|
||||
|
|
|
@ -10,6 +10,7 @@ import type { FC } from 'react';
|
|||
import React, { memo, useCallback } from 'react';
|
||||
import { useExpandableFlyoutContext } from '@kbn/expandable-flyout';
|
||||
import { FormattedMessage } from '@kbn/i18n-react';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { COLLAPSE_DETAILS_BUTTON_TEST_ID, EXPAND_DETAILS_BUTTON_TEST_ID } from './test_ids';
|
||||
import { LeftPanelKey } from '../../left';
|
||||
import { useRightPanelContext } from '../context';
|
||||
|
@ -42,6 +43,12 @@ export const ExpandDetailButton: FC = memo(() => {
|
|||
onClick={collapseDetails}
|
||||
iconType="arrowEnd"
|
||||
data-test-subj={COLLAPSE_DETAILS_BUTTON_TEST_ID}
|
||||
aria-label={i18n.translate(
|
||||
'xpack.securitySolution.flyout.right.header.collapseDetailButtonAriaLabel',
|
||||
{
|
||||
defaultMessage: 'Collapse details',
|
||||
}
|
||||
)}
|
||||
>
|
||||
<FormattedMessage
|
||||
id="xpack.securitySolution.flyout.right.header.collapseDetailButtonLabel"
|
||||
|
@ -54,6 +61,12 @@ export const ExpandDetailButton: FC = memo(() => {
|
|||
onClick={expandDetails}
|
||||
iconType="arrowStart"
|
||||
data-test-subj={EXPAND_DETAILS_BUTTON_TEST_ID}
|
||||
aria-label={i18n.translate(
|
||||
'xpack.securitySolution.flyout.right.header.expandDetailButtonAriaLabel',
|
||||
{
|
||||
defaultMessage: 'Expand details',
|
||||
}
|
||||
)}
|
||||
>
|
||||
<FormattedMessage
|
||||
id="xpack.securitySolution.flyout.right.header.expandDetailButtonLabel"
|
||||
|
|
|
@ -86,7 +86,7 @@ export const HeaderTitle: VFC<HeaderTitleProps> = memo(({ flyoutIsExpandable })
|
|||
)}
|
||||
<EuiSpacer size="s" />
|
||||
<EuiTitle size="s">
|
||||
<h4 data-test-subj={FLYOUT_HEADER_TITLE_TEST_ID}>
|
||||
<h2 data-test-subj={FLYOUT_HEADER_TITLE_TEST_ID}>
|
||||
{isAlert && !isEmpty(ruleName) ? (
|
||||
ruleName
|
||||
) : (
|
||||
|
@ -95,7 +95,7 @@ export const HeaderTitle: VFC<HeaderTitleProps> = memo(({ flyoutIsExpandable })
|
|||
defaultMessage="Event details"
|
||||
/>
|
||||
)}
|
||||
</h4>
|
||||
</h2>
|
||||
</EuiTitle>
|
||||
<EuiSpacer size="s" />
|
||||
<EuiFlexGroup direction="row" gutterSize={isAlert ? 'm' : 'none'}>
|
||||
|
|
|
@ -9,6 +9,7 @@ import type { ReactElement, VFC } from 'react';
|
|||
import React from 'react';
|
||||
import { css } from '@emotion/react';
|
||||
import { EuiButtonIcon, EuiFlexGroup, EuiFlexItem, EuiHealth, EuiSkeletonText } from '@elastic/eui';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { FormattedCount } from '../../../common/components/formatted_number';
|
||||
|
||||
export interface InsightsSummaryRowProps {
|
||||
|
@ -64,7 +65,13 @@ export const InsightsSummaryRow: VFC<InsightsSummaryRowProps> = ({
|
|||
lines={1}
|
||||
size="m"
|
||||
isLoading={loading}
|
||||
contentAriaLabel="Loading"
|
||||
contentAriaLabel={i18n.translate(
|
||||
'xpack.securitySolution.flyout.right.insights.insightSummaryLoadingAriaLabel',
|
||||
{
|
||||
defaultMessage: 'Loading insights for {value}',
|
||||
values: { value },
|
||||
}
|
||||
)}
|
||||
data-test-subj={loadingDataTestSubj}
|
||||
/>
|
||||
);
|
||||
|
@ -83,7 +90,12 @@ export const InsightsSummaryRow: VFC<InsightsSummaryRowProps> = ({
|
|||
<EuiFlexItem grow={false}>
|
||||
<EuiButtonIcon
|
||||
data-test-subj={iconDataTestSubj}
|
||||
aria-label={'entity-icon'}
|
||||
aria-label={i18n.translate(
|
||||
'xpack.securitySolution.flyout.right.insights.insightSummaryButtonIconAriaLabel',
|
||||
{
|
||||
defaultMessage: 'Insight summary row icon',
|
||||
}
|
||||
)}
|
||||
color="text"
|
||||
display="empty"
|
||||
iconType={icon}
|
||||
|
|
|
@ -8,6 +8,7 @@ import React, { useCallback } from 'react';
|
|||
import { EuiButton, EuiFlexGroup, EuiFlexItem, EuiLoadingSpinner, EuiTitle } from '@elastic/eui';
|
||||
import { useExpandableFlyoutContext } from '@kbn/expandable-flyout';
|
||||
import { FormattedMessage } from '@kbn/i18n-react';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { useInvestigationGuide } from '../../shared/hooks/use_investigation_guide';
|
||||
import { useRightPanelContext } from '../context';
|
||||
import { LeftPanelKey, LeftPanelInvestigationTab } from '../../left';
|
||||
|
@ -75,6 +76,12 @@ export const InvestigationGuide: React.FC = () => {
|
|||
onClick={goToInvestigationsTab}
|
||||
iconType="documentation"
|
||||
data-test-subj={INVESTIGATION_GUIDE_BUTTON_TEST_ID}
|
||||
aria-label={i18n.translate(
|
||||
'xpack.securitySolution.flyout.right.investigation.investigationGuide.investigationGuideButtonAriaLabel',
|
||||
{
|
||||
defaultMessage: 'Show investigation guide',
|
||||
}
|
||||
)}
|
||||
>
|
||||
<FormattedMessage
|
||||
id="xpack.securitySolution.flyout.right.investigation.investigationGuide.investigationGuideButtonLabel"
|
||||
|
|
|
@ -11,6 +11,7 @@ import { EuiButtonEmpty, EuiFlexGroup, EuiFlexItem, EuiTitle } from '@elastic/eu
|
|||
import { useExpandableFlyoutContext } from '@kbn/expandable-flyout';
|
||||
import { ALERT_REASON } from '@kbn/rule-data-utils';
|
||||
import { FormattedMessage } from '@kbn/i18n-react';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { getField } from '../../shared/utils';
|
||||
import { AlertReasonPreviewPanel, PreviewPanelKey } from '../../preview';
|
||||
import {
|
||||
|
@ -62,6 +63,12 @@ export const Reason: FC = () => {
|
|||
onClick={openRulePreview}
|
||||
iconSide="right"
|
||||
data-test-subj={REASON_DETAILS_PREVIEW_BUTTON_TEST_ID}
|
||||
aria-label={i18n.translate(
|
||||
'xpack.securitySolution.flyout.right.about.reason.alertReasonButtonAriaLabel',
|
||||
{
|
||||
defaultMessage: 'Show full reason',
|
||||
}
|
||||
)}
|
||||
>
|
||||
<FormattedMessage
|
||||
id="xpack.securitySolution.flyout.right.about.reason.alertReasonButtonLabel"
|
||||
|
|
|
@ -8,6 +8,7 @@ import React, { useCallback } from 'react';
|
|||
import { EuiButton } from '@elastic/eui';
|
||||
import { useExpandableFlyoutContext } from '@kbn/expandable-flyout';
|
||||
import { FormattedMessage } from '@kbn/i18n-react';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { expandDottedObject } from '../../../../common/utils/expand_dotted';
|
||||
import type {
|
||||
ExpandedEventFieldsObject,
|
||||
|
@ -56,6 +57,12 @@ export const ResponseButton: React.FC = () => {
|
|||
onClick={goToResponseTab}
|
||||
iconType="documentation"
|
||||
data-test-subj={RESPONSE_BUTTON_TEST_ID}
|
||||
aria-label={i18n.translate(
|
||||
'xpack.securitySolution.flyout.right.response.responseButtonAriaLabel',
|
||||
{
|
||||
defaultMessage: 'Response',
|
||||
}
|
||||
)}
|
||||
>
|
||||
<FormattedMessage
|
||||
id="xpack.securitySolution.flyout.right.response.responseButtonLabel"
|
||||
|
|
|
@ -37,12 +37,12 @@ export const RiskScore: FC = memo(() => {
|
|||
<EuiFlexGroup alignItems="center" direction="row" gutterSize="xs">
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiTitle size="xxs" data-test-subj={RISK_SCORE_TITLE_TEST_ID}>
|
||||
<h5>
|
||||
<h3>
|
||||
<FormattedMessage
|
||||
id="xpack.securitySolution.flyout.right.header.riskScoreTitle"
|
||||
defaultMessage="Risk score:"
|
||||
/>
|
||||
</h5>
|
||||
</h3>
|
||||
</EuiTitle>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem grow={false}>
|
||||
|
|
|
@ -46,12 +46,12 @@ export const DocumentSeverity: FC = memo(() => {
|
|||
<EuiFlexGroup alignItems="center" direction="row" gutterSize="xs">
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiTitle size="xxs" data-test-subj={SEVERITY_TITLE_TEST_ID}>
|
||||
<h5>
|
||||
<h3>
|
||||
<FormattedMessage
|
||||
id="xpack.securitySolution.flyout.right.header.severityTitle"
|
||||
defaultMessage="Severity:"
|
||||
/>
|
||||
</h5>
|
||||
</h3>
|
||||
</EuiTitle>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem grow={false}>
|
||||
|
|
|
@ -9,6 +9,7 @@ import { copyToClipboard, EuiButtonEmpty, EuiCopy } from '@elastic/eui';
|
|||
import type { FC } from 'react';
|
||||
import React from 'react';
|
||||
import { FormattedMessage } from '@kbn/i18n-react';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { FLYOUT_URL_PARAM } from '../../shared/hooks/url/use_sync_flyout_state_with_url';
|
||||
import { SHARE_BUTTON_TEST_ID } from './test_ids';
|
||||
|
||||
|
@ -40,6 +41,12 @@ export const ShareButton: FC<ShareButtonProps> = ({ alertUrl }) => {
|
|||
}}
|
||||
iconType="share"
|
||||
data-test-subj={SHARE_BUTTON_TEST_ID}
|
||||
aria-label={i18n.translate(
|
||||
'xpack.securitySolution.flyout.right.header.shareButtonAriaLabel',
|
||||
{
|
||||
defaultMessage: 'Share Alert',
|
||||
}
|
||||
)}
|
||||
>
|
||||
<FormattedMessage
|
||||
id="xpack.securitySolution.flyout.right.header.shareButtonLabel"
|
||||
|
|
|
@ -7,7 +7,8 @@
|
|||
|
||||
import type { FC } from 'react';
|
||||
import React, { memo } from 'react';
|
||||
import { EuiHorizontalRule } from '@elastic/eui';
|
||||
import { EuiPanel, EuiHorizontalRule } from '@elastic/eui';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { ResponseSection } from '../components/response_section';
|
||||
import { InvestigationSection } from '../components/investigation_section';
|
||||
import { AboutSection } from '../components/about_section';
|
||||
|
@ -19,7 +20,17 @@ import { VisualizationsSection } from '../components/visualizations_section';
|
|||
*/
|
||||
export const OverviewTab: FC = memo(() => {
|
||||
return (
|
||||
<>
|
||||
<EuiPanel
|
||||
hasBorder={false}
|
||||
hasShadow={false}
|
||||
paddingSize="none"
|
||||
aria-label={i18n.translate(
|
||||
'xpack.securitySolution.flyout.right.overview.overviewContentAriaLabel',
|
||||
{
|
||||
defaultMessage: 'Alert overview',
|
||||
}
|
||||
)}
|
||||
>
|
||||
<AboutSection />
|
||||
<EuiHorizontalRule margin="l" />
|
||||
<InvestigationSection />
|
||||
|
@ -29,7 +40,7 @@ export const OverviewTab: FC = memo(() => {
|
|||
<InsightsSection />
|
||||
<EuiHorizontalRule margin="l" />
|
||||
<ResponseSection />
|
||||
</>
|
||||
</EuiPanel>
|
||||
);
|
||||
});
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@ import {
|
|||
} from '@elastic/eui';
|
||||
import type { IconType } from '@elastic/eui';
|
||||
import { css } from '@emotion/react';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
|
||||
export interface ExpandablePanelPanelProps {
|
||||
header: {
|
||||
|
@ -99,7 +100,12 @@ export const ExpandablePanel: React.FC<ExpandablePanelPanelProps> = ({
|
|||
() => (
|
||||
<EuiButtonIcon
|
||||
data-test-subj={`${dataTestSubj}ToggleIcon`}
|
||||
aria-label={`entity-toggle`}
|
||||
aria-label={i18n.translate(
|
||||
'xpack.securitySolution.flyout.shared.ExpandablePanelButtonIconAriaLabel',
|
||||
{
|
||||
defaultMessage: 'Expandable panel toggle',
|
||||
}
|
||||
)}
|
||||
color="text"
|
||||
display="empty"
|
||||
iconType={toggleStatus ? 'arrowDown' : 'arrowRight'}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue