diff --git a/CHANGELOG.md b/CHANGELOG.md index 8c9be4e6973..654377fd560 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ - Removed `src/test` and `@types/enzyme` references from `eui.d.ts` ([#3715](https://github.com/elastic/eui/pull/3715)) - Added `index.d.ts` file to `lib/test` and `es/test` ([#3715](https://github.com/elastic/eui/pull/3715)) - Added `descriptionFlexItemProps` and `fieldFlexItemProps` props to `EuiDescribedFormGroup` ([#3717](https://github.com/elastic/eui/pull/3717)) +- 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)) ## [`27.0.0`](https://github.com/elastic/eui/tree/v27.0.0) - Added `paddingSize` prop to `EuiCard` ([#3638](https://github.com/elastic/eui/pull/3638)) diff --git a/src-docs/src/views/tables/actions/actions.js b/src-docs/src/views/tables/actions/actions.js index 967b86c48a1..6545e5cc5b5 100644 --- a/src-docs/src/views/tables/actions/actions.js +++ b/src-docs/src/views/tables/actions/actions.js @@ -141,7 +141,7 @@ export const Table = () => { 'data-test-subj': 'action-clone', }, { - name: 'Delete', + name: item => (item.id ? 'Delete' : 'Remove'), description: 'Delete this user', icon: 'trash', color: 'danger', diff --git a/src-docs/src/views/tables/basic/props_info.js b/src-docs/src/views/tables/basic/props_info.js index 838ae1ab060..2533d355b70 100644 --- a/src-docs/src/views/tables/basic/props_info.js +++ b/src-docs/src/views/tables/basic/props_info.js @@ -395,7 +395,7 @@ export const propsInfo = { description: 'The display name of the action (will be the button caption)', required: true, - type: { name: 'PropTypes.node' }, + type: { name: 'PropTypes.node | (item) => PropTypes.node' }, }, description: { description: 'Describes the action (will be the button title)', diff --git a/src/components/basic_table/__snapshots__/default_item_action.test.tsx.snap b/src/components/basic_table/__snapshots__/default_item_action.test.tsx.snap index 22b39650e76..34f82252ca5 100644 --- a/src/components/basic_table/__snapshots__/default_item_action.test.tsx.snap +++ b/src/components/basic_table/__snapshots__/default_item_action.test.tsx.snap @@ -60,3 +60,23 @@ exports[`DefaultItemAction render - icon 1`] = ` `; + +exports[`DefaultItemAction render - name 1`] = ` + + + + xyz + + + +`; diff --git a/src/components/basic_table/action_types.ts b/src/components/basic_table/action_types.ts index 1f9a1d9a746..1057e7b9c9c 100644 --- a/src/components/basic_table/action_types.ts +++ b/src/components/basic_table/action_types.ts @@ -28,7 +28,7 @@ type ButtonColor = EuiButtonIconColor | EuiButtonEmptyColor; type EuiButtonIconColorFunction = (item: T) => ButtonColor; interface DefaultItemActionBase { - name: ReactNode; + name: ReactNode | ((item: T) => ReactNode); description: string; onClick?: (item: T) => void; href?: string; diff --git a/src/components/basic_table/collapsed_item_actions.test.tsx b/src/components/basic_table/collapsed_item_actions.test.tsx index 337ec34a935..1c22d421c09 100644 --- a/src/components/basic_table/collapsed_item_actions.test.tsx +++ b/src/components/basic_table/collapsed_item_actions.test.tsx @@ -27,7 +27,7 @@ describe('CollapsedItemActions', () => { const props = { actions: [ { - name: 'default1', + name: (item: { id: string }) => `default${item.id}`, description: 'default 1', onClick: () => {}, }, @@ -38,7 +38,7 @@ describe('CollapsedItemActions', () => { }, ], itemId: 'id', - item: { id: 'xyz' }, + item: { id: '1' }, actionEnabled: (_: Action<{ id: string }>) => true, onFocus: (_: FocusEvent) => {}, onBlur: () => {}, diff --git a/src/components/basic_table/collapsed_item_actions.tsx b/src/components/basic_table/collapsed_item_actions.tsx index d9a1cbcdc47..d33c9cb919f 100644 --- a/src/components/basic_table/collapsed_item_actions.tsx +++ b/src/components/basic_table/collapsed_item_actions.tsx @@ -152,6 +152,7 @@ export class CollapsedItemActions extends Component< if (buttonIcon) { icon = isString(buttonIcon) ? buttonIcon : buttonIcon(item); } + const buttonContent = typeof name === 'function' ? name(item) : name; controls.push( extends Component< onClick={() => this.onClickItem(onClick ? () => onClick(item) : undefined) }> - {name} + {buttonContent} ); } diff --git a/src/components/basic_table/default_item_action.test.tsx b/src/components/basic_table/default_item_action.test.tsx index fb9239d59e5..6cce1dae8fd 100644 --- a/src/components/basic_table/default_item_action.test.tsx +++ b/src/components/basic_table/default_item_action.test.tsx @@ -72,6 +72,24 @@ describe('DefaultItemAction', () => { expect(component).toMatchSnapshot(); }); + test('render - name', () => { + const action: EmptyButtonAction = { + name: item => {item.id}, + description: 'action 1', + type: 'button', + onClick: () => {}, + }; + const props = { + action, + enabled: true, + item: { id: 'xyz' }, + }; + + const component = shallow(); + + expect(component).toMatchSnapshot(); + }); + test('render - icon', () => { const action: IconButtonAction = { name: action1, diff --git a/src/components/basic_table/default_item_action.tsx b/src/components/basic_table/default_item_action.tsx index 6bdd646c3aa..ddf64608003 100644 --- a/src/components/basic_table/default_item_action.tsx +++ b/src/components/basic_table/default_item_action.tsx @@ -68,6 +68,8 @@ export const DefaultItemAction = ({ } let button; + const actionContent = + typeof action.name === 'function' ? action.name(item) : action.name; if (action.type === 'icon') { if (!icon) { throw new Error(`Cannot render item action [${ @@ -89,9 +91,9 @@ export const DefaultItemAction = ({ 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 */} + {/* actionContent (action.name) is a ReactNode and must be rendered to an element and referenced by ID for screen readers */} - {action.name} + {actionContent} ); @@ -108,7 +110,7 @@ export const DefaultItemAction = ({ target={action.target} data-test-subj={action['data-test-subj']} flush="right"> - {action.name} + {actionContent} ); }