diff --git a/CHANGELOG.md b/CHANGELOG.md index d059ac22ed0..0e5a633a87a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,10 @@ - Fixed race condition in `EuiIcon` when switching from dynamically fetched components ([#3118](https://github.com/elastic/eui/pull/3118)) +**Breaking changes** + +- Removed `EuiKeyPadMenuItemButton` in favor of just `EuiKeyPadMenuItem` that can also accept an `onClick` ([#3062](https://github.com/elastic/eui/pull/3062)) + ## [`21.1.0`](https://github.com/elastic/eui/tree/v21.1.0) - Updated `EuiFilterSelect` to retain the order of its filters ([#3063](https://github.com/elastic/eui/pull/3063)) diff --git a/src-docs/src/views/key_pad_menu/key_pad_menu_example.js b/src-docs/src/views/key_pad_menu/key_pad_menu_example.js index 424fc48837f..b4fb7b98056 100644 --- a/src-docs/src/views/key_pad_menu/key_pad_menu_example.js +++ b/src-docs/src/views/key_pad_menu/key_pad_menu_example.js @@ -27,11 +27,11 @@ const keyPadMenuSnippet = ` import KeyPadMenuItemButton from './key_pad_menu_item_button'; const keyPadMenuItemButtonSource = require('!!raw-loader!./key_pad_menu_item_button'); const keyPadMenuItemButtonHtml = renderToHtml(KeyPadMenuItemButton); -const keyPadMenuItemButtonSnippet = ` - + `; import KeyPadBeta from './key_pad_beta'; @@ -85,9 +85,9 @@ export const KeyPadMenuExample = { ], text: (

- The KeyPadMenuItem component is a link by default, but you can swap it - out for a KeyPadMenuItemButton if you want onClick{' '} - behavior. + The KeyPadMenuItem component can act both as an anchor as well as a + button by specifying href or + onClick respectively.

), snippet: keyPadMenuItemButtonSnippet, diff --git a/src-docs/src/views/key_pad_menu/key_pad_menu_item_button.js b/src-docs/src/views/key_pad_menu/key_pad_menu_item_button.js index a58b7819ebe..e0011eed97d 100644 --- a/src-docs/src/views/key_pad_menu/key_pad_menu_item_button.js +++ b/src-docs/src/views/key_pad_menu/key_pad_menu_item_button.js @@ -3,21 +3,21 @@ import React from 'react'; import { EuiIcon, EuiKeyPadMenu, - EuiKeyPadMenuItemButton, + EuiKeyPadMenuItem, } from '../../../../src/components'; export default () => ( - window.alert('Clicked')}> - - + window.alert('Clicked')}> - + ); diff --git a/src/components/index.js b/src/components/index.js index 71e2cced408..91080c4ccbf 100644 --- a/src/components/index.js +++ b/src/components/index.js @@ -176,11 +176,7 @@ export { EuiLoadingSpinner, } from './loading'; -export { - EuiKeyPadMenu, - EuiKeyPadMenuItem, - EuiKeyPadMenuItemButton, -} from './key_pad_menu'; +export { EuiKeyPadMenu, EuiKeyPadMenuItem } from './key_pad_menu'; export { EuiLink } from './link'; diff --git a/src/components/key_pad_menu/__snapshots__/key_pad_menu_item.test.tsx.snap b/src/components/key_pad_menu/__snapshots__/key_pad_menu_item.test.tsx.snap index 8a6f3ec799c..2a2118c15ad 100644 --- a/src/components/key_pad_menu/__snapshots__/key_pad_menu_item.test.tsx.snap +++ b/src/components/key_pad_menu/__snapshots__/key_pad_menu_item.test.tsx.snap @@ -5,6 +5,7 @@ exports[`EuiKeyPadMenuItem is rendered 1`] = ` aria-label="aria-label" class="euiKeyPadMenuItem testClass1 testClass2" data-test-subj="test subject string" + href="#" role="menuitem" >
`; -exports[`EuiKeyPadMenuItem renders href 1`] = ` -
-
+ `; -exports[`EuiKeyPadMenuItemButton is rendered 1`] = ` - + `; diff --git a/src/components/key_pad_menu/index.ts b/src/components/key_pad_menu/index.ts index 0192d01f012..8718d918caa 100644 --- a/src/components/key_pad_menu/index.ts +++ b/src/components/key_pad_menu/index.ts @@ -1,6 +1,3 @@ export { EuiKeyPadMenu } from './key_pad_menu'; -export { - EuiKeyPadMenuItem, - EuiKeyPadMenuItemButton, -} from './key_pad_menu_item'; +export { EuiKeyPadMenuItem } from './key_pad_menu_item'; diff --git a/src/components/key_pad_menu/key_pad_menu_item.test.tsx b/src/components/key_pad_menu/key_pad_menu_item.test.tsx index e9e1dfb3eb3..5e06a15bfb5 100644 --- a/src/components/key_pad_menu/key_pad_menu_item.test.tsx +++ b/src/components/key_pad_menu/key_pad_menu_item.test.tsx @@ -2,15 +2,12 @@ import React from 'react'; import { render, shallow } from 'enzyme'; import { requiredProps } from '../../test'; -import { - EuiKeyPadMenuItem, - EuiKeyPadMenuItemButton, -} from './key_pad_menu_item'; +import { EuiKeyPadMenuItem } from './key_pad_menu_item'; describe('EuiKeyPadMenuItem', () => { test('is rendered', () => { const component = render( - + Icon ); @@ -27,44 +24,42 @@ describe('EuiKeyPadMenuItem', () => { expect(component).toMatchSnapshot(); }); -}); -describe('EuiKeyPadMenuItemButton', () => { - test('is rendered', () => { + test('renders button', () => { + const onClickHandler = jest.fn(); + const component = render( - + Icon - + ); expect(component).toMatchSnapshot(); }); - describe('onClick', () => { - test("isn't called upon instantiation", () => { - const onClickHandler = jest.fn(); + test("onClick isn't called upon instantiation", () => { + const onClickHandler = jest.fn(); - shallow( - - Icon - - ); + shallow( + + Icon + + ); - expect(onClickHandler).not.toBeCalled(); - }); + expect(onClickHandler).not.toBeCalled(); + }); - test('is called when the button is clicked', () => { - const onClickHandler = jest.fn(); + test('onClick is called when the button is clicked', () => { + const onClickHandler = jest.fn(); - const $button = shallow( - - Icon - - ); + const $button = shallow( + + Icon + + ); - $button.simulate('click'); + $button.simulate('click'); - expect(onClickHandler).toBeCalledTimes(1); - }); + expect(onClickHandler).toBeCalledTimes(1); }); }); diff --git a/src/components/key_pad_menu/key_pad_menu_item.tsx b/src/components/key_pad_menu/key_pad_menu_item.tsx index 4f6a9fb8a04..292947a121f 100644 --- a/src/components/key_pad_menu/key_pad_menu_item.tsx +++ b/src/components/key_pad_menu/key_pad_menu_item.tsx @@ -3,10 +3,11 @@ import React, { ButtonHTMLAttributes, FunctionComponent, ReactNode, + HTMLAttributes, } from 'react'; import classNames from 'classnames'; -import { CommonProps } from '../common'; +import { CommonProps, ExclusiveUnion } from '../common'; import { EuiBetaBadge } from '../badge/beta_badge'; @@ -56,14 +57,18 @@ interface EuiKeyPadMenuItemCommonProps { * Add a description to the beta badge (will appear in a tooltip) */ betaBadgeTooltipContent?: ReactNode; + onClick?: () => void; + href?: string; } export type EuiKeyPadMenuItemProps = CommonProps & - AnchorHTMLAttributes & + ExclusiveUnion< + AnchorHTMLAttributes, + ButtonHTMLAttributes + > & EuiKeyPadMenuItemCommonProps; export const EuiKeyPadMenuItem: FunctionComponent = ({ - href, isDisabled, label, children, @@ -71,6 +76,7 @@ export const EuiKeyPadMenuItem: FunctionComponent = ({ betaBadgeLabel, betaBadgeTooltipContent, betaBadgeIconType, + href, ...rest }) => { const classes = classNames( @@ -81,70 +87,27 @@ export const EuiKeyPadMenuItem: FunctionComponent = ({ className ); - if (!isDisabled) { - return ( - - {renderContent( - children, - label, - betaBadgeLabel, - betaBadgeTooltipContent, - betaBadgeIconType - )} - - ); + const Element = href && !isDisabled ? 'a' : 'button'; + const relObj: { + role?: string; + disabled?: boolean; + type?: string; + href?: string; + } = {}; + + if (href && !isDisabled) { + relObj.role = 'menuitem'; + relObj.href = href; + } else { + relObj.type = 'button'; + relObj.disabled = isDisabled; } return ( - - ); -}; - -export type EuiKeyPadMenuItemButtonProps = CommonProps & - ButtonHTMLAttributes & - EuiKeyPadMenuItemCommonProps; - -export const EuiKeyPadMenuItemButton: FunctionComponent< - EuiKeyPadMenuItemButtonProps -> = ({ - onClick, - label, - children, - className, - betaBadgeLabel, - betaBadgeTooltipContent, - betaBadgeIconType, - isDisabled, - ...rest -}) => { - const classes = classNames( - 'euiKeyPadMenuItem', - { - 'euiKeyPadMenuItem--hasBetaBadge': betaBadgeLabel, - }, - className - ); - - return ( - + ); };