Skip to content

Commit 1bf8302

Browse files
thompsonglanishagg17
authored andcommitted
[EuiTable] Expand item action name to allow a function (elastic#3739)
* allow for item -> ReactNode in name * docs * CL
1 parent 14dda39 commit 1bf8302

9 files changed

Lines changed: 51 additions & 9 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
- Removed `src/test` and `@types/enzyme` references from `eui.d.ts` ([#3715](https://github.com/elastic/eui/pull/3715))
66
- Added `index.d.ts` file to `lib/test` and `es/test` ([#3715](https://github.com/elastic/eui/pull/3715))
77
- Added `descriptionFlexItemProps` and `fieldFlexItemProps` props to `EuiDescribedFormGroup` ([#3717](https://github.com/elastic/eui/pull/3717))
8+
- Expanded `EuiBasicTable`'s default action's name configuration to accept a function that returns a React node ([#3739](https://github.com/elastic/eui/pull/3739))
89

910
## [`27.0.0`](https://github.com/elastic/eui/tree/v27.0.0)
1011
- Added `paddingSize` prop to `EuiCard` ([#3638](https://github.com/elastic/eui/pull/3638))

src-docs/src/views/tables/actions/actions.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ export const Table = () => {
141141
'data-test-subj': 'action-clone',
142142
},
143143
{
144-
name: 'Delete',
144+
name: item => (item.id ? 'Delete' : 'Remove'),
145145
description: 'Delete this user',
146146
icon: 'trash',
147147
color: 'danger',

src-docs/src/views/tables/basic/props_info.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -395,7 +395,7 @@ export const propsInfo = {
395395
description:
396396
'The display name of the action (will be the button caption)',
397397
required: true,
398-
type: { name: 'PropTypes.node' },
398+
type: { name: 'PropTypes.node | (item) => PropTypes.node' },
399399
},
400400
description: {
401401
description: 'Describes the action (will be the button title)',

src/components/basic_table/__snapshots__/default_item_action.test.tsx.snap

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,3 +60,23 @@ exports[`DefaultItemAction render - icon 1`] = `
6060
</EuiScreenReaderOnly>
6161
</EuiToolTip>
6262
`;
63+
64+
exports[`DefaultItemAction render - name 1`] = `
65+
<EuiToolTip
66+
content="action 1"
67+
delay="long"
68+
position="top"
69+
>
70+
<EuiButtonEmpty
71+
color="primary"
72+
flush="right"
73+
isDisabled={false}
74+
onClick={[Function]}
75+
size="s"
76+
>
77+
<span>
78+
xyz
79+
</span>
80+
</EuiButtonEmpty>
81+
</EuiToolTip>
82+
`;

src/components/basic_table/action_types.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ type ButtonColor = EuiButtonIconColor | EuiButtonEmptyColor;
2828
type EuiButtonIconColorFunction<T> = (item: T) => ButtonColor;
2929

3030
interface DefaultItemActionBase<T> {
31-
name: ReactNode;
31+
name: ReactNode | ((item: T) => ReactNode);
3232
description: string;
3333
onClick?: (item: T) => void;
3434
href?: string;

src/components/basic_table/collapsed_item_actions.test.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ describe('CollapsedItemActions', () => {
2727
const props = {
2828
actions: [
2929
{
30-
name: 'default1',
30+
name: (item: { id: string }) => `default${item.id}`,
3131
description: 'default 1',
3232
onClick: () => {},
3333
},
@@ -38,7 +38,7 @@ describe('CollapsedItemActions', () => {
3838
},
3939
],
4040
itemId: 'id',
41-
item: { id: 'xyz' },
41+
item: { id: '1' },
4242
actionEnabled: (_: Action<{ id: string }>) => true,
4343
onFocus: (_: FocusEvent) => {},
4444
onBlur: () => {},

src/components/basic_table/collapsed_item_actions.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,7 @@ export class CollapsedItemActions<T> extends Component<
152152
if (buttonIcon) {
153153
icon = isString(buttonIcon) ? buttonIcon : buttonIcon(item);
154154
}
155+
const buttonContent = typeof name === 'function' ? name(item) : name;
155156

156157
controls.push(
157158
<EuiContextMenuItem
@@ -164,7 +165,7 @@ export class CollapsedItemActions<T> extends Component<
164165
onClick={() =>
165166
this.onClickItem(onClick ? () => onClick(item) : undefined)
166167
}>
167-
{name}
168+
{buttonContent}
168169
</EuiContextMenuItem>
169170
);
170171
}

src/components/basic_table/default_item_action.test.tsx

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,24 @@ describe('DefaultItemAction', () => {
7272
expect(component).toMatchSnapshot();
7373
});
7474

75+
test('render - name', () => {
76+
const action: EmptyButtonAction<Item> = {
77+
name: item => <span>{item.id}</span>,
78+
description: 'action 1',
79+
type: 'button',
80+
onClick: () => {},
81+
};
82+
const props = {
83+
action,
84+
enabled: true,
85+
item: { id: 'xyz' },
86+
};
87+
88+
const component = shallow(<DefaultItemAction {...props} />);
89+
90+
expect(component).toMatchSnapshot();
91+
});
92+
7593
test('render - icon', () => {
7694
const action: IconButtonAction<Item> = {
7795
name: <span>action1</span>,

src/components/basic_table/default_item_action.tsx

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,8 @@ export const DefaultItemAction = <T extends {}>({
6868
}
6969

7070
let button;
71+
const actionContent =
72+
typeof action.name === 'function' ? action.name(item) : action.name;
7173
if (action.type === 'icon') {
7274
if (!icon) {
7375
throw new Error(`Cannot render item action [${
@@ -89,9 +91,9 @@ export const DefaultItemAction = <T extends {}>({
8991
target={action.target}
9092
data-test-subj={action['data-test-subj']}
9193
/>
92-
{/* action.name is a ReactNode and must be rendered to an element and referenced by ID for screen readers */}
94+
{/* actionContent (action.name) is a ReactNode and must be rendered to an element and referenced by ID for screen readers */}
9395
<EuiScreenReaderOnly>
94-
<span id={ariaLabelId}>{action.name}</span>
96+
<span id={ariaLabelId}>{actionContent}</span>
9597
</EuiScreenReaderOnly>
9698
</>
9799
);
@@ -108,7 +110,7 @@ export const DefaultItemAction = <T extends {}>({
108110
target={action.target}
109111
data-test-subj={action['data-test-subj']}
110112
flush="right">
111-
{action.name}
113+
{actionContent}
112114
</EuiButtonEmpty>
113115
);
114116
}

0 commit comments

Comments
 (0)