Skip to content

Commit

Permalink
[EuiBasicTable] Ensure action button aria-label is unique (#7994)
Browse files Browse the repository at this point in the history
  • Loading branch information
mgadewoll committed Sep 6, 2024
1 parent ba42930 commit e36e441
Show file tree
Hide file tree
Showing 5 changed files with 53 additions and 41 deletions.
4 changes: 4 additions & 0 deletions packages/eui/changelogs/upcoming/7994.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
**Accessibility**

- Updated the `EuiBasicTable` actions button's `aria-label` by adding a reference to the current row

Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ exports[`CollapsedItemActions custom actions 1`] = `
class="euiToolTipAnchor emotion-euiToolTipAnchor-inlineBlock"
>
<button
aria-label="All actions"
aria-label="All actions, row 1"
class="euiButtonIcon emotion-euiButtonIcon-xs-empty-text"
data-test-subj="euiCollapsedItemActionsButton"
type="button"
Expand Down Expand Up @@ -123,7 +123,7 @@ exports[`CollapsedItemActions default actions 1`] = `
class="euiToolTipAnchor emotion-euiToolTipAnchor-inlineBlock"
>
<button
aria-label="All actions"
aria-label="All actions, row 1"
class="euiButtonIcon emotion-euiButtonIcon-xs-empty-text"
data-test-subj="euiCollapsedItemActionsButton"
type="button"
Expand Down Expand Up @@ -233,7 +233,7 @@ exports[`CollapsedItemActions renders 1`] = `
class="euiToolTipAnchor emotion-euiToolTipAnchor-inlineBlock"
>
<button
aria-label="All actions"
aria-label="All actions, row 1"
class="euiButtonIcon emotion-euiButtonIcon-xs-empty-text"
data-test-subj="euiCollapsedItemActionsButton"
type="button"
Expand Down
3 changes: 3 additions & 0 deletions packages/eui/src/components/basic_table/basic_table.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1004,6 +1004,7 @@ export class EuiBasicTable<T extends object = any> extends Component<
item,
column as EuiTableActionsColumnType<T>,
columnIndex,
rowIndex,
hasCustomActions
)
);
Expand Down Expand Up @@ -1142,6 +1143,7 @@ export class EuiBasicTable<T extends object = any> extends Component<
item: T,
column: EuiTableActionsColumnType<T>,
columnIndex: number,
rowIndex: number,
hasCustomActions: boolean
) {
// Disable all actions if any row(s) are selected
Expand Down Expand Up @@ -1181,6 +1183,7 @@ export class EuiBasicTable<T extends object = any> extends Component<
actionsDisabled={allDisabled}
itemId={itemId}
item={item}
displayedRowIndex={rowIndex}
/>
),
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ describe('CollapsedItemActions', () => {
itemId: 'id',
item: { id: '1' },
actionsDisabled: false,
displayedRowIndex: 0,
};

const { container } = render(<CollapsedItemActions {...props} />);
Expand Down Expand Up @@ -64,6 +65,7 @@ describe('CollapsedItemActions', () => {
itemId: 'id',
item: { id: 'xyz' },
actionsDisabled: false,
displayedRowIndex: 0,
};

const { getByTestSubject, getByText, baseElement } = render(
Expand Down Expand Up @@ -108,6 +110,7 @@ describe('CollapsedItemActions', () => {
itemId: 'id',
item: { id: 'xyz' },
actionsDisabled: false,
displayedRowIndex: 0,
};

const { getByTestSubject } = render(<CollapsedItemActions {...props} />);
Expand Down Expand Up @@ -135,6 +138,7 @@ describe('CollapsedItemActions', () => {
itemId: 'id',
item: { id: 'xyz' },
actionsDisabled: false,
displayedRowIndex: 0,
};

const { getByTestSubject, baseElement } = render(
Expand Down
77 changes: 39 additions & 38 deletions packages/eui/src/components/basic_table/collapsed_item_actions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,13 @@
* Side Public License, v 1.
*/

import React, {
useState,
useCallback,
useMemo,
ReactNode,
ReactElement,
} from 'react';
import React, { useState, useCallback, useMemo, ReactElement } from 'react';

import { EuiContextMenuItem, EuiContextMenuPanel } from '../context_menu';
import { EuiPopover } from '../popover';
import { EuiButtonIcon } from '../button';
import { EuiToolTip } from '../tool_tip';
import { EuiI18n } from '../i18n';
import { useEuiI18n } from '../i18n';

import {
Action,
Expand All @@ -33,6 +27,7 @@ export interface CollapsedItemActionsProps<T extends object> {
item: T;
itemId: ItemIdResolved;
actionsDisabled: boolean;
displayedRowIndex: number;
className?: string;
}

Expand All @@ -41,11 +36,30 @@ export const CollapsedItemActions = <T extends {}>({
itemId,
item,
actionsDisabled,
displayedRowIndex,
className,
}: CollapsedItemActionsProps<T>) => {
const [popoverOpen, setPopoverOpen] = useState(false);
const closePopover = useCallback(() => setPopoverOpen(false), []);

const allActionsTooltip = useEuiI18n(
'euiCollapsedItemActions.allActionsTooltip',
'All actions'
);

const allActionsButtonAriaLabel = useEuiI18n(
'euiCollapsedItemActions.allActions',
'All actions, row {index}',
{
index: displayedRowIndex + 1,
}
);

const allActionsButtonDisabledAriaLabel = useEuiI18n(
'euiCollapsedItemActions.allActionsDisabled',
'Individual item actions are disabled when rows are being selected.'
);

const controls = useMemo(() => {
return actions.reduce<ReactElement[]>((controls, action, index) => {
const available = action.available?.(item) ?? true;
Expand Down Expand Up @@ -107,39 +121,26 @@ export const CollapsedItemActions = <T extends {}>({
}, [actions, actionsDisabled, item, closePopover]);

const popoverButton = (
<EuiI18n
tokens={[
'euiCollapsedItemActions.allActions',
'euiCollapsedItemActions.allActionsDisabled',
]}
defaults={[
'All actions',
'Individual item actions are disabled when rows are being selected.',
]}
>
{([allActions, allActionsDisabled]: string[]) => (
<EuiButtonIcon
className={className}
aria-label={actionsDisabled ? allActionsDisabled : allActions}
title={actionsDisabled ? allActionsDisabled : undefined}
iconType="boxesHorizontal"
color="text"
isDisabled={actionsDisabled}
onClick={() => setPopoverOpen((isOpen) => !isOpen)}
data-test-subj="euiCollapsedItemActionsButton"
/>
)}
</EuiI18n>
<EuiButtonIcon
className={className}
aria-label={
actionsDisabled
? allActionsButtonDisabledAriaLabel
: allActionsButtonAriaLabel
}
title={actionsDisabled ? allActionsButtonDisabledAriaLabel : undefined}
iconType="boxesHorizontal"
color="text"
isDisabled={actionsDisabled}
onClick={() => setPopoverOpen((isOpen) => !isOpen)}
data-test-subj="euiCollapsedItemActionsButton"
/>
);

const withTooltip = !actionsDisabled && (
<EuiI18n token="euiCollapsedItemActions.allActions" default="All actions">
{(allActions: ReactNode) => (
<EuiToolTip content={allActions} delay="long">
{popoverButton}
</EuiToolTip>
)}
</EuiI18n>
<EuiToolTip content={allActionsTooltip} delay="long">
{popoverButton}
</EuiToolTip>
);

return (
Expand Down

0 comments on commit e36e441

Please sign in to comment.