diff --git a/packages/block-editor/src/components/link-control/test/__snapshots__/index.js.snap b/packages/block-editor/src/components/link-control/test/__snapshots__/index.js.snap index feac082de26346..cf0801f4316199 100644 --- a/packages/block-editor/src/components/link-control/test/__snapshots__/index.js.snap +++ b/packages/block-editor/src/components/link-control/test/__snapshots__/index.js.snap @@ -1,3 +1,3 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`Basic rendering should display with required props 1`] = `"
"`; +exports[`Basic rendering should display with required props 1`] = `"
"`; diff --git a/packages/components/src/button/index.js b/packages/components/src/button/index.js index 3987b0b31ac28f..77271b82ebb3b2 100644 --- a/packages/components/src/button/index.js +++ b/packages/components/src/button/index.js @@ -2,12 +2,19 @@ * External dependencies */ import classnames from 'classnames'; +import { isArray } from 'lodash'; /** * WordPress dependencies */ import deprecated from '@wordpress/deprecated'; -import { createElement, forwardRef } from '@wordpress/element'; +import { forwardRef } from '@wordpress/element'; + +/** + * Internal dependencies + */ +import Tooltip from '../tooltip'; +import Icon from '../icon'; export function Button( props, ref ) { const { @@ -25,6 +32,13 @@ export function Button( props, ref ) { isDestructive, className, disabled, + icon, + iconSize, + showTooltip, + tooltipPosition, + shortcut, + label, + children, ...additionalProps } = props; @@ -44,19 +58,54 @@ export function Button( props, ref ) { 'is-busy': isBusy, 'is-link': isLink, 'is-destructive': isDestructive, + 'has-text': !! icon && !! children, + // Ideally should be has-icon but this is named this way for BC + 'components-icon-button': !! icon, } ); - const tag = href !== undefined && ! disabled ? 'a' : 'button'; - const tagProps = tag === 'a' ? + const Tag = href !== undefined && ! disabled ? 'a' : 'button'; + const tagProps = Tag === 'a' ? { href, target } : { type: 'button', disabled, 'aria-pressed': isPressed }; - return createElement( tag, { - ...tagProps, - ...additionalProps, - className: classes, - ref, - } ); + // Should show the tooltip if... + const shouldShowTooltip = ! disabled && ( + // an explicit tooltip is passed or... + ( showTooltip && label ) || + // there's a shortcut or... + shortcut || + ( + // there's a label and... + !! label && + // the children are empty and... + ( ! children || ( isArray( children ) && ! children.length ) ) && + // the tooltip is not explicitly disabled. + false !== showTooltip + ) + ); + + const element = ( + + { icon && } + { children } + + ); + + if ( ! shouldShowTooltip ) { + return element; + } + + return ( + + { element } + + ); } export default forwardRef( Button ); diff --git a/packages/components/src/button/style.scss b/packages/components/src/button/style.scss index 154120ffd2c2b1..b33e087b450369 100644 --- a/packages/components/src/button/style.scss +++ b/packages/components/src/button/style.scss @@ -228,6 +228,23 @@ } } +.components-icon-button { + .dashicon { + display: inline-block; + flex: 0 0 auto; + } + + // Ensure that even SVG icons that don't include the .dashicon class are colored. + svg { + fill: currentColor; + outline: none; + } + + &.has-text svg { + margin-right: 8px; + } +} + @keyframes components-button__busy-animation { 0% { background-position: 200px 0; diff --git a/packages/components/src/button/test/index.js b/packages/components/src/button/test/index.js index c0b03149abd2f0..fdb194f6611c44 100644 --- a/packages/components/src/button/test/index.js +++ b/packages/components/src/button/test/index.js @@ -74,6 +74,57 @@ describe( 'Button', () => { expect( button.prop( 'WordPress' ) ).toBe( 'awesome' ); } ); + + it( 'should render an icon button', () => { + const iconButton = shallow( ); + expect( iconButton.name() ).toBe( 'button' ); + } ); + + it( 'should force showing the tooltip even if icon and children defined', () => { + const iconButton = shallow( ); + expect( iconButton.name() ).toBe( 'Tooltip' ); + } ); } ); describe( 'with href property', () => { diff --git a/packages/components/src/icon-button/index.js b/packages/components/src/icon-button/index.js index b41b3335b0c3a6..dd2b4ef36d16e7 100644 --- a/packages/components/src/icon-button/index.js +++ b/packages/components/src/icon-button/index.js @@ -1,9 +1,3 @@ -/** - * External dependencies - */ -import classnames from 'classnames'; -import { isArray } from 'lodash'; - /** * WordPress dependencies */ @@ -12,64 +6,25 @@ import { forwardRef } from '@wordpress/element'; /** * Internal dependencies */ -import Tooltip from '../tooltip'; import Button from '../button'; -import Icon from '../icon'; - -function IconButton( props, ref ) { - const { - icon, - children, - label, - className, - tooltip, - shortcut, - labelPosition, - size, - ...additionalProps - } = props; - const classes = classnames( 'components-icon-button', className, { - 'has-text': children, - } ); - const tooltipText = tooltip || label; - // Should show the tooltip if... - const showTooltip = ! additionalProps.disabled && ( - // an explicit tooltip is passed or... - tooltip || - // there's a shortcut or... - shortcut || - ( - // there's a label and... - !! label && - // the children are empty and... - ( ! children || ( isArray( children ) && ! children.length ) ) && - // the tooltip is not explicitly disabled. - false !== tooltip - ) - ); - - let element = ( +function IconButton( { + labelPosition, + size, + tooltip, + label, + ...props +}, ref ) { + return ( + tooltipPosition={ labelPosition } + iconSize={ size } + showTooltip={ tooltip !== undefined ? !! tooltip : undefined } + label={ tooltip || label } + /> ); - - if ( showTooltip ) { - element = ( - - { element } - - ); - } - - return element; } export default forwardRef( IconButton ); diff --git a/packages/components/src/icon-button/style.scss b/packages/components/src/icon-button/style.scss deleted file mode 100644 index 102a361d940885..00000000000000 --- a/packages/components/src/icon-button/style.scss +++ /dev/null @@ -1,16 +0,0 @@ -.components-icon-button { - .dashicon { - display: inline-block; - flex: 0 0 auto; - } - - // Ensure that even SVG icons that don't include the .dashicon class are colored. - svg { - fill: currentColor; - outline: none; - } - - &.has-text svg { - margin-right: 8px; - } -} diff --git a/packages/components/src/icon-button/test/index.js b/packages/components/src/icon-button/test/index.js deleted file mode 100644 index f4a8d4330d3cc2..00000000000000 --- a/packages/components/src/icon-button/test/index.js +++ /dev/null @@ -1,91 +0,0 @@ -/** - * External dependencies - */ -import { shallow } from 'enzyme'; -import TestUtils from 'react-dom/test-utils'; - -/** - * WordPress dependencies - */ -import { createRef } from '@wordpress/element'; - -/** - * Internal dependencies - */ -import IconButton from '../'; - -describe( 'IconButton', () => { - describe( 'basic rendering', () => { - it( 'should render an top level element with only a class property', () => { - const iconButton = shallow( ); - expect( iconButton.hasClass( 'components-icon-button' ) ).toBe( true ); - expect( iconButton.prop( 'aria-label' ) ).toBeUndefined(); - } ); - - it( 'should render a Dashicon component matching the wordpress icon', () => { - const iconButton = shallow( ); - expect( iconButton.find( 'Icon' ).dive().shallow().hasClass( 'dashicons-wordpress' ) ).toBe( true ); - } ); - - it( 'should render child elements when passed as children', () => { - const iconButton = shallow( Test

} /> ); - expect( iconButton.find( '.test' ).shallow().text() ).toBe( 'Test' ); - } ); - - it( 'should add an aria-label when the label property is used', () => { - const iconButton = shallow( WordPress ); - expect( iconButton.name() ).toBe( 'ForwardRef(Button)' ); - expect( iconButton.prop( 'aria-label' ) ).toBe( 'WordPress' ); - } ); - - it( 'should add an aria-label when the label property is used, with Tooltip wrapper', () => { - const iconButton = shallow( ); - expect( iconButton.name() ).toBe( 'Tooltip' ); - expect( iconButton.prop( 'text' ) ).toBe( 'WordPress' ); - expect( iconButton.find( 'ForwardRef(Button)' ).prop( 'aria-label' ) ).toBe( 'WordPress' ); - } ); - - it( 'should support explicit aria-label override', () => { - const iconButton = shallow( ); - expect( iconButton.prop( 'aria-label' ) ).toBe( 'Custom' ); - } ); - - it( 'should add an additional className', () => { - const iconButton = shallow( ); - expect( iconButton.hasClass( 'test' ) ).toBe( true ); - } ); - - it( 'should pass additional props to the underlying button', () => { - const iconButton = shallow( ); - - expect( iconButton.find( 'ForwardRef(Button)' ).prop( 'aria-pressed' ) ).toBe( 'true' ); - expect( iconButton.find( 'ForwardRef(Button)' ).prop( 'disabled' ) ).toBe( true ); - } ); - - it( 'should allow custom tooltip text', () => { - const iconButton = shallow( ); - expect( iconButton.name() ).toBe( 'Tooltip' ); - expect( iconButton.prop( 'text' ) ).toBe( 'Custom' ); - expect( iconButton.find( 'ForwardRef(Button)' ).prop( 'aria-label' ) ).toBe( 'WordPress' ); - } ); - - it( 'should allow tooltip disable', () => { - const iconButton = shallow( ); - expect( iconButton.name() ).toBe( 'ForwardRef(Button)' ); - expect( iconButton.prop( 'aria-label' ) ).toBe( 'WordPress' ); - } ); - - it( 'should show the tooltip for empty children', () => { - const iconButton = shallow( ); - expect( iconButton.name() ).toBe( 'Tooltip' ); - expect( iconButton.prop( 'text' ) ).toBe( 'WordPress' ); - } ); - - it( 'forwards ref', () => { - const ref = createRef(); - - TestUtils.renderIntoDocument( ); - expect( ref.current.type ).toBe( 'button' ); - } ); - } ); -} ); diff --git a/packages/components/src/style.scss b/packages/components/src/style.scss index b429d051bf0204..f99717ec65d84b 100644 --- a/packages/components/src/style.scss +++ b/packages/components/src/style.scss @@ -24,7 +24,6 @@ @import "./form-token-field/style.scss"; @import "./guide/style.scss"; @import "./higher-order/navigate-regions/style.scss"; -@import "./icon-button/style.scss"; @import "./menu-group/style.scss"; @import "./menu-item/style.scss"; @import "./menu-items-choice/style.scss"; diff --git a/packages/e2e-tests/specs/editor/plugins/__snapshots__/plugins-api.test.js.snap b/packages/e2e-tests/specs/editor/plugins/__snapshots__/plugins-api.test.js.snap index 86ce33a736311e..f3f0358fcd0b03 100644 --- a/packages/e2e-tests/specs/editor/plugins/__snapshots__/plugins-api.test.js.snap +++ b/packages/e2e-tests/specs/editor/plugins/__snapshots__/plugins-api.test.js.snap @@ -2,6 +2,6 @@ exports[`Using Plugins API Document Setting Custom Panel Should render a custom panel inside Document Setting sidebar 1`] = `"My Custom Panel"`; -exports[`Using Plugins API Sidebar Medium screen Should open plugins sidebar using More Menu item and render content 1`] = `"
Sidebar title plugin
"`; +exports[`Using Plugins API Sidebar Medium screen Should open plugins sidebar using More Menu item and render content 1`] = `"
Sidebar title plugin
"`; -exports[`Using Plugins API Sidebar Should open plugins sidebar using More Menu item and render content 1`] = `"
Sidebar title plugin
"`; +exports[`Using Plugins API Sidebar Should open plugins sidebar using More Menu item and render content 1`] = `"
Sidebar title plugin
"`; diff --git a/packages/edit-post/src/components/header/more-menu/test/__snapshots__/index.js.snap b/packages/edit-post/src/components/header/more-menu/test/__snapshots__/index.js.snap index e0337df629bd3a..71abd65e7b9628 100644 --- a/packages/edit-post/src/components/header/more-menu/test/__snapshots__/index.js.snap +++ b/packages/edit-post/src/components/header/more-menu/test/__snapshots__/index.js.snap @@ -43,28 +43,26 @@ exports[`MoreMenu should match snapshot 1`] = ` onKeyDown={[Function]} tooltip="More tools & options" > - - - - + + diff --git a/packages/edit-post/src/components/header/plugin-more-menu-item/test/__snapshots__/index.js.snap b/packages/edit-post/src/components/header/plugin-more-menu-item/test/__snapshots__/index.js.snap index 0a2564900eda2e..dc576582b3cc73 100644 --- a/packages/edit-post/src/components/header/plugin-more-menu-item/test/__snapshots__/index.js.snap +++ b/packages/edit-post/src/components/header/plugin-more-menu-item/test/__snapshots__/index.js.snap @@ -16,7 +16,7 @@ exports[`PluginMoreMenuItem renders menu item as button properly 1`] = ` role="group" >