Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Expand table's default action type to allow reactnode names #3688

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
## [`master`](https://github.com/elastic/eui/tree/master)

No public interface changes since `26.2.0`.
- Expanded `EuiBasicTable`'s default action's name configuration to accept any React node ([#3688](https://github.com/elastic/eui/pull/3688))

## [`26.2.0`](https://github.com/elastic/eui/tree/v26.2.0)

Expand Down
2 changes: 1 addition & 1 deletion src-docs/src/views/tables/actions/actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ export const Table = () => {
]
: [
{
name: 'Clone',
name: <span>Clone</span>,
description: 'Clone this user',
icon: 'copy',
onClick: cloneUser,
Expand Down
4 changes: 2 additions & 2 deletions src-docs/src/views/tables/basic/props_info.js
Original file line number Diff line number Diff line change
Expand Up @@ -393,9 +393,9 @@ export const propsInfo = {
props: {
name: {
description:
'The display name of the action (will be the button caption',
'The display name of the action (will be the button caption)',
required: true,
type: { name: 'string' },
type: { name: 'PropTypes.node' },
},
description: {
description: 'Describes the action (will be the button title)',
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`DefaultItemAction render - default button 1`] = `
exports[`DefaultItemAction render - button 1`] = `
<EuiToolTip
content="action 1"
delay="long"
Expand All @@ -18,7 +18,7 @@ exports[`DefaultItemAction render - default button 1`] = `
</EuiToolTip>
`;

exports[`DefaultItemAction render - button 1`] = `
exports[`DefaultItemAction render - default button 1`] = `
<EuiToolTip
content="action 1"
delay="long"
Expand All @@ -43,11 +43,20 @@ exports[`DefaultItemAction render - icon 1`] = `
position="top"
>
<EuiButtonIcon
aria-label="action1"
aria-labelledby="random_id"
color="primary"
iconType="trash"
isDisabled={false}
onClick={[Function]}
/>
<EuiScreenReaderOnly>
<span
id="random_id"
>
<span>
action1
</span>
</span>
</EuiScreenReaderOnly>
</EuiToolTip>
`;
4 changes: 2 additions & 2 deletions src/components/basic_table/action_types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
* under the License.
*/

import { ReactElement } from 'react';
import { ReactElement, ReactNode } from 'react';
import { EuiIconType } from '../icon/icon';
import { EuiButtonIconColor } from '../button/button_icon/button_icon';
import { EuiButtonEmptyColor } from '../button/button_empty';
Expand All @@ -28,7 +28,7 @@ type ButtonColor = EuiButtonIconColor | EuiButtonEmptyColor;
type EuiButtonIconColorFunction<T> = (item: T) => ButtonColor;

interface DefaultItemActionBase<T> {
name: string;
name: ReactNode;
chandlerprall marked this conversation as resolved.
Show resolved Hide resolved
description: string;
onClick?: (item: T) => void;
href?: string;
Expand Down
9 changes: 8 additions & 1 deletion src/components/basic_table/default_item_action.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,13 @@ import {
DefaultItemIconButtonAction as IconButtonAction,
} from './action_types';

// Mock the htmlIdGenerator to generate predictable ids for snapshot tests
jest.mock('../../services/accessibility/html_id_generator', () => ({
htmlIdGenerator: () => {
return () => 'random_id';
},
}));

interface Item {
id: string;
}
Expand Down Expand Up @@ -67,7 +74,7 @@ describe('DefaultItemAction', () => {

test('render - icon', () => {
const action: IconButtonAction<Item> = {
name: 'action1',
name: <span>action1</span>,
description: 'action 1',
type: 'icon',
icon: 'trash',
Expand Down
31 changes: 20 additions & 11 deletions src/components/basic_table/default_item_action.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ import {
} from '../button';
import { EuiToolTip } from '../tool_tip';
import { DefaultItemAction as Action } from './action_types';
import { htmlIdGenerator } from '../../services/accessibility';
import { EuiScreenReaderOnly } from '../accessibility';

export interface DefaultItemActionProps<T> {
action: Action<T>;
Expand Down Expand Up @@ -73,18 +75,25 @@ export const DefaultItemAction = <T extends {}>({
}]. It is configured to render as an icon but no
icon is provided. Make sure to set the 'icon' property of the action`);
}
const ariaLabelId = htmlIdGenerator()();
button = (
<EuiButtonIcon
className={className}
aria-label={action.name}
isDisabled={!enabled}
color={color}
iconType={icon}
onClick={onClick}
href={action.href}
target={action.target}
data-test-subj={action['data-test-subj']}
/>
<>
<EuiButtonIcon
className={className}
aria-labelledby={ariaLabelId}
isDisabled={!enabled}
color={color}
iconType={icon}
onClick={onClick}
href={action.href}
target={action.target}
data-test-subj={action['data-test-subj']}
/>
{/* action.name is a ReactNode and must be rendered to an element and referenced by ID for screen readers */}
chandlerprall marked this conversation as resolved.
Show resolved Hide resolved
<EuiScreenReaderOnly>
<span id={ariaLabelId}>{action.name}</span>
</EuiScreenReaderOnly>
</>
);
} else {
button = (
Expand Down