Skip to content

Commit

Permalink
Components: Forward IconButton ref as stateless function
Browse files Browse the repository at this point in the history
  • Loading branch information
aduth committed Feb 28, 2019
1 parent d2c21db commit c050b67
Show file tree
Hide file tree
Showing 3 changed files with 106 additions and 112 deletions.
114 changes: 52 additions & 62 deletions packages/components/src/icon-button/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { isArray, isString } from 'lodash';
/**
* WordPress dependencies
*/
import { Component, forwardRef } from '@wordpress/element';
import { forwardRef } from '@wordpress/element';

/**
* Internal dependencies
Expand All @@ -16,70 +16,60 @@ import Tooltip from '../tooltip';
import Button from '../button';
import Dashicon from '../dashicon';

// This is intentionally a Component class, not a function component because it
// is common to apply a ref to the button element (only supported in class)
export class IconButton extends Component {
render() {
const {
icon,
children,
label,
className,
tooltip,
shortcut,
labelPosition,
forwardedRef,
...additionalProps
} = this.props;
const { 'aria-pressed': ariaPressed } = this.props;
const classes = classnames( 'components-icon-button', className, {
'has-text': children,
} );
const tooltipText = tooltip || label;
function IconButton( props, ref ) {
const {
icon,
children,
label,
className,
tooltip,
shortcut,
labelPosition,
'aria-pressed': ariaPressed,
...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 = (
<Button
aria-label={ label }
{ ...additionalProps }
className={ classes }
ref={ forwardedRef }
>
{ isString( icon ) ? <Dashicon icon={ icon } ariaPressed={ ariaPressed } /> : icon }
{ children }
</Button>
);
// 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
)
);

if ( showTooltip ) {
element = (
<Tooltip text={ tooltipText } shortcut={ shortcut } position={ labelPosition }>
{ element }
</Tooltip>
);
}
let element = (
<Button
aria-label={ label }
{ ...additionalProps }
className={ classes }
ref={ ref }
>
{ isString( icon ) ? <Dashicon icon={ icon } ariaPressed={ ariaPressed } /> : icon }
{ children }
</Button>
);

return element;
if ( showTooltip ) {
element = (
<Tooltip text={ tooltipText } shortcut={ shortcut } position={ labelPosition }>
{ element }
</Tooltip>
);
}
}

const forwardedIconButton = ( props, ref ) => {
return <IconButton { ...props } forwardedRef={ ref } />;
};
forwardedIconButton.displayName = 'IconButton';
return element;
}

export default forwardRef( forwardedIconButton );
export default forwardRef( IconButton );
15 changes: 14 additions & 1 deletion packages/components/src/icon-button/test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,17 @@
* 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 '../';
import IconButton from '../';

describe( 'IconButton', () => {
describe( 'basic rendering', () => {
Expand Down Expand Up @@ -72,5 +78,12 @@ describe( 'IconButton', () => {
expect( iconButton.name() ).toBe( 'Tooltip' );
expect( iconButton.prop( 'text' ) ).toBe( 'WordPress' );
} );

it( 'forwards ref', () => {
const ref = createRef();

TestUtils.renderIntoDocument( <IconButton ref={ ref } /> );
expect( ref.current.type ).toBe( 'button' );
} );
} );
} );
Original file line number Diff line number Diff line change
Expand Up @@ -19,45 +19,47 @@ exports[`MoreMenu should match snapshot 1`] = `
labelPosition="bottom"
onClick={[Function]}
>
<IconButton
aria-expanded={false}
forwardedRef={null}
icon="ellipsis"
label="Show more tools & options"
labelPosition="bottom"
onClick={[Function]}
<Tooltip
position="bottom"
text="Show more tools & options"
>
<Tooltip
position="bottom"
text="Show more tools & options"
<ForwardRef(Button)
aria-expanded={false}
aria-label="Show more tools & options"
className="components-icon-button"
onBlur={[Function]}
onClick={[Function]}
onFocus={[Function]}
onMouseEnter={[Function]}
onMouseLeave={[Function]}
>
<ForwardRef(Button)
<button
aria-expanded={false}
aria-label="Show more tools & options"
className="components-icon-button"
className="components-button components-icon-button"
onBlur={[Function]}
onClick={[Function]}
onFocus={[Function]}
onMouseEnter={[Function]}
onMouseLeave={[Function]}
type="button"
>
<button
aria-expanded={false}
aria-label="Show more tools & options"
className="components-button components-icon-button"
onBlur={[Function]}
onClick={[Function]}
onFocus={[Function]}
onMouseEnter={[Function]}
onMouseLeave={[Function]}
type="button"
<Dashicon
icon="ellipsis"
key="0,0"
>
<Dashicon
icon="ellipsis"
key="0,0"
<SVG
aria-hidden={true}
className="dashicon dashicons-ellipsis"
focusable="false"
height={20}
role="img"
viewBox="0 0 20 20"
width={20}
xmlns="http://www.w3.org/2000/svg"
>
<SVG
aria-hidden={true}
<svg
aria-hidden="true"
className="dashicon dashicons-ellipsis"
focusable="false"
height={20}
Expand All @@ -66,30 +68,19 @@ exports[`MoreMenu should match snapshot 1`] = `
width={20}
xmlns="http://www.w3.org/2000/svg"
>
<svg
aria-hidden="true"
className="dashicon dashicons-ellipsis"
focusable="false"
height={20}
role="img"
viewBox="0 0 20 20"
width={20}
xmlns="http://www.w3.org/2000/svg"
<Path
d="M5 10c0 1.1-.9 2-2 2s-2-.9-2-2 .9-2 2-2 2 .9 2 2zm12-2c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm-7 0c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2z"
>
<Path
<path
d="M5 10c0 1.1-.9 2-2 2s-2-.9-2-2 .9-2 2-2 2 .9 2 2zm12-2c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm-7 0c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2z"
>
<path
d="M5 10c0 1.1-.9 2-2 2s-2-.9-2-2 .9-2 2-2 2 .9 2 2zm12-2c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm-7 0c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2z"
/>
</Path>
</svg>
</SVG>
</Dashicon>
</button>
</ForwardRef(Button)>
</Tooltip>
</IconButton>
/>
</Path>
</svg>
</SVG>
</Dashicon>
</button>
</ForwardRef(Button)>
</Tooltip>
</ForwardRef(IconButton)>
</div>
</Dropdown>
Expand Down

0 comments on commit c050b67

Please sign in to comment.