Skip to content

Commit

Permalink
Add show on hover to info popover (#48990)
Browse files Browse the repository at this point in the history
* Add show on hover cap. to info popover

* Bump CI

* Bump CI #2

* Change popover timeout to 250ms

* Bump CI #3

* Bump CI #4

* Bump CI #5
  • Loading branch information
becdetat committed Jan 20, 2021
1 parent 93cb8c8 commit 7ecca39
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 5 deletions.
8 changes: 8 additions & 0 deletions client/components/info-popover/docs/example.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,14 @@ class InfoPopoverExample extends React.PureComponent {
<InfoPopover id="popover__info-popover-example" position={ this.state.popoverPosition }>
Some informational text.
</InfoPopover>

<InfoPopover
id="popover__info-popover-example"
position={ this.state.popoverPosition }
showOnHover={ true }
>
Shows on hover.
</InfoPopover>
</div>
);
}
Expand Down
55 changes: 52 additions & 3 deletions client/components/info-popover/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,31 +42,40 @@ export default class InfoPopover extends Component {
'left',
'top left',
] ),
showOnHover: PropTypes.bool,
};

static defaultProps = {
autoRtl: true,
icon: 'info-outline',
iconSize: 18,
position: 'bottom',
showOnHover: false,
};

iconRef = React.createRef();

state = { showPopover: false };

handleClick = ( e ) => {
const { onOpen, showOnHover } = this.props;
const { showPopover } = this.state;

e.preventDefault();
e.stopPropagation();

if ( showOnHover ) {
return;
}

// There's no "handleOpen" method for us to hook into,
// so we check here to see if the intent is to open the popover
// and fire onOpen accordingly
if ( ! this.state.showPopover ) {
this.props.onOpen?.();
if ( ! showPopover ) {
onOpen?.();
}

this.setState( { showPopover: ! this.state.showPopover }, this.recordStats );
this.setState( { showPopover: ! showPopover }, this.recordStats );
};

handleClose = () => {
Expand All @@ -83,6 +92,42 @@ export default class InfoPopover extends Component {
}
};

handleOnMouseEnterButton = () => {
const { onOpen, showOnHover } = this.props;

if ( ! showOnHover ) {
return;
}

onOpen?.();
this.setState( { showPopover: true }, this.recordStats );
};

handleOnMouseLeave = () => {
setTimeout( () => {
const { showOnHover } = this.props;

if ( ! showOnHover ) {
return;
}

if ( this.inPopover ) {
return;
}

this.setState( { showPopover: false }, this.recordStats );
}, 250 );
};

handleOnMouseEnterPopover = () => {
this.inPopover = true;
};

handleOnMouseLeavePopover = () => {
this.inPopover = false;
this.handleOnMouseLeave();
};

render() {
return (
<Fragment>
Expand All @@ -92,6 +137,8 @@ export default class InfoPopover extends Component {
aria-expanded={ this.state.showPopover }
aria-label={ translate( 'More information' ) }
onClick={ this.handleClick }
onMouseEnter={ this.handleOnMouseEnterButton }
onMouseLeave={ this.handleOnMouseLeave }
ref={ this.iconRef }
className={ classNames( 'info-popover', this.props.className, {
'is-active': this.state.showPopover,
Expand All @@ -109,6 +156,8 @@ export default class InfoPopover extends Component {
position={ this.props.position }
onClose={ this.handleClose }
className={ classNames( 'info-popover__tooltip', this.props.className ) }
onMouseEnter={ this.handleOnMouseEnterPopover }
onMouseLeave={ this.handleOnMouseLeavePopover }
>
{ this.props.children }
</Popover>
Expand Down
20 changes: 19 additions & 1 deletion client/components/popover/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import React, { Component } from 'react';
import ReactDom from 'react-dom';
import debugFactory from 'debug';
import classNames from 'classnames';
import { defer, noop } from 'lodash';
import { defer } from 'lodash';
import { useRtl } from 'i18n-calypso';

/**
Expand All @@ -31,6 +31,8 @@ import './style.scss';
*/
const debug = debugFactory( 'calypso:popover' );

const noop = () => {};

class PopoverInner extends Component {
static defaultProps = {
autoPosition: true,
Expand All @@ -41,6 +43,8 @@ class PopoverInner extends Component {
isFocusEnabled: true,
position: 'top',
onClose: noop,
onMouseEnter: noop,
onMouseLeave: noop,
};

/**
Expand Down Expand Up @@ -325,6 +329,18 @@ class PopoverInner extends Component {
this.props.onClose( wasCanceled );
}

handleOnMouseEnter = () => {
const { onMouseEnter } = this.props;

onMouseEnter?.();
};

handleOnMouseLeave = () => {
const { onMouseLeave } = this.props;

onMouseLeave?.();
};

render() {
if ( ! this.props.context ) {
debug( 'No `context` to tie. return no render' );
Expand All @@ -342,6 +358,8 @@ class PopoverInner extends Component {
tabIndex="-1"
style={ this.getStylePosition() }
className={ classes }
onMouseEnter={ this.handleOnMouseEnter }
onMouseLeave={ this.handleOnMouseLeave }
>
<div className="popover__arrow" />
<div ref={ this.popoverInnerNodeRef } className="popover__inner">
Expand Down
6 changes: 5 additions & 1 deletion client/my-sites/sidebar/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -712,7 +712,11 @@ export class MySitesSidebar extends Component {
className="sidebar__store"
>
{ isCalypsoStoreDeprecated && isBusiness( site.plan ) && (
<InfoPopover className="sidebar__store-tooltip" position="bottom right">
<InfoPopover
className="sidebar__store-tooltip"
position="bottom right"
showOnHover={ true }
>
{ infoCopy }
</InfoPopover>
) }
Expand Down

0 comments on commit 7ecca39

Please sign in to comment.