From 73f46a7a0573aaf7a392e90c55da215ff8883fe9 Mon Sep 17 00:00:00 2001 From: Stephane Jolicuoeur Date: Mon, 15 May 2017 16:49:10 -0700 Subject: [PATCH] feat(Tooltip): 8pt Tooltips: Hover behavior 8pt Tooltips: Hover now has the option to be sticky as to offer a wider hover area for the user. [Finishes #138673781] Signed-off-by: Anushka Makhija --- .../pivotal-ui-react/tooltip/tooltip_spec.js | 39 +++++++++++++++++-- .../tooltip/tooltip_trigger_spec.js | 8 ++++ .../src/pivotal-ui-react/tooltip/tooltip.js | 19 +++++---- .../components/tooltips/tooltips.scss | 21 +++++++--- styleguide/docs/react/tooltip.js | 9 +++++ 5 files changed, 81 insertions(+), 15 deletions(-) diff --git a/library/spec/pivotal-ui-react/tooltip/tooltip_spec.js b/library/spec/pivotal-ui-react/tooltip/tooltip_spec.js index e89190612..f906347a5 100644 --- a/library/spec/pivotal-ui-react/tooltip/tooltip_spec.js +++ b/library/spec/pivotal-ui-react/tooltip/tooltip_spec.js @@ -1,9 +1,10 @@ import '../spec_helper' -; + ; import {Tooltip} from 'pui-react-tooltip'; describe('Tooltip Component', () => { - const renderComponent = props => ReactTestUtils.renderIntoDocument(Some default tooltip); + const renderComponent = props => ReactTestUtils.renderIntoDocument(Some default + tooltip); it('renders', () => { const result = renderComponent(); @@ -70,4 +71,36 @@ describe('Tooltip Component', () => { expect(content).toHaveClass('tooltip-lg'); }); }); -}); \ No newline at end of file + + describe('sticky', () => { + let renderComponent; + beforeEach(() => { + renderComponent = props => ReactTestUtils.renderIntoDocument(Some default tooltip); + }); + + describe('is not set', () => { + it('does not render with the hoverable class', () => { + const result = renderComponent({isSticky: false}); + const content = ReactTestUtils.findRenderedDOMComponentWithClass(result, 'tooltip-container'); + expect(content).not.toHaveClass('tooltip-hoverable'); + }); + }); + + describe('is set to false', () => { + it('does not render with the hoverable class', () => { + const result = renderComponent({isSticky: false}); + const content = ReactTestUtils.findRenderedDOMComponentWithClass(result, 'tooltip-container'); + expect(content).not.toHaveClass('tooltip-hoverable'); + }); + }); + + describe('is set to true', () => { + it('renders with the hoverable class', () => { + const result = renderComponent({isSticky: true}); + const content = ReactTestUtils.findRenderedDOMComponentWithClass(result, 'tooltip-container'); + expect(content).toHaveClass('tooltip-hoverable'); + }); + }); + }); +}) +; \ No newline at end of file diff --git a/library/spec/pivotal-ui-react/tooltip/tooltip_trigger_spec.js b/library/spec/pivotal-ui-react/tooltip/tooltip_trigger_spec.js index 0e69d3b17..981ed97ee 100644 --- a/library/spec/pivotal-ui-react/tooltip/tooltip_trigger_spec.js +++ b/library/spec/pivotal-ui-react/tooltip/tooltip_trigger_spec.js @@ -164,4 +164,12 @@ describe('TooltipTrigger Component', () => { expect(tooltip).toHaveClass('tooltip-container-hidden'); }); }); + + describe('isSticky', () => { + it('renders the tooltip with the "isSticky" prop', () => { + const result = renderComponent({isSticky: true, tooltip: 'Some tooltip content'}); + const content = ReactTestUtils.findRenderedDOMComponentWithClass(result, 'tooltip-container'); + expect(content).toHaveClass('tooltip-hoverable'); + }); + }); }); \ No newline at end of file diff --git a/library/src/pivotal-ui-react/tooltip/tooltip.js b/library/src/pivotal-ui-react/tooltip/tooltip.js index fe3fc0a4e..cd25af5f4 100644 --- a/library/src/pivotal-ui-react/tooltip/tooltip.js +++ b/library/src/pivotal-ui-react/tooltip/tooltip.js @@ -6,12 +6,14 @@ import classnames from 'classnames'; export class Tooltip extends React.Component { static propTypes = { visible: PropTypes.bool, - size: PropTypes.oneOf(['auto','sm', 'md', 'lg']) + size: PropTypes.oneOf(['auto','sm', 'md', 'lg']), + isSticky: PropTypes.bool } static defaultProps = { visible: true, - size: 'auto' + size: 'auto', + isSticky: false } constructor(props) { @@ -19,10 +21,11 @@ export class Tooltip extends React.Component { } render() { - let {visible, size, className, children, ...others} = this.props; + let {isSticky, visible, size, className, children, ...others} = this.props; const newClasses = classnames('tooltip-container', visible ? 'tooltip-container-visible' : 'tooltip-container-hidden', size === 'auto' ? null : `tooltip-${size}`, + isSticky? 'tooltip-hoverable': null, className); return ( @@ -42,7 +45,8 @@ export class TooltipTrigger extends React.Component { onEntered: PropTypes.func, onExited: PropTypes.func, theme: PropTypes.oneOf(['dark', 'light']), - size: PropTypes.oneOf(['auto', 'sm', 'md', 'lg']) + size: PropTypes.oneOf(['auto', 'sm', 'md', 'lg']), + isSticky: PropTypes.bool } static defaultProps = { @@ -52,7 +56,8 @@ export class TooltipTrigger extends React.Component { onEntered: () => {}, onExited: () => {}, theme: 'dark', - size: 'auto' + size: 'auto', + isSticky: false } constructor(props) { @@ -80,7 +85,7 @@ export class TooltipTrigger extends React.Component { } render() { - const {placement, tooltip, trigger, className, clickHideDelay, onEntered, onExited, theme, size, ...others} = this.props; + const {isSticky, placement, tooltip, trigger, className, clickHideDelay, onEntered, onExited, theme, size, ...others} = this.props; const {visible} = this.state; let placementClass; @@ -108,7 +113,7 @@ export class TooltipTrigger extends React.Component { return (
{this.props.children} - {tooltip} + {tooltip}
); } diff --git a/library/src/pivotal-ui/components/tooltips/tooltips.scss b/library/src/pivotal-ui/components/tooltips/tooltips.scss index d863e1c34..0b93313f6 100644 --- a/library/src/pivotal-ui/components/tooltips/tooltips.scss +++ b/library/src/pivotal-ui/components/tooltips/tooltips.scss @@ -9,11 +9,6 @@ .tooltip-container { //Hover Effect for HTML & CSS ONLY - - &.tooltip-container-visible { - visibility: visible; - } - visibility: hidden; transition: opacity $tooltip-opacity-transition; z-index: $tooltip-container-z; @@ -24,6 +19,22 @@ margin: 0 0 $tooltip-margin 0; //space for the triangle indicator text-align: left; + &.tooltip-container-visible { + visibility: visible; + } + + &.tooltip-hoverable { + &:after { + content:""; + position: absolute; + width:calc(100% + 16px); + height:calc(100% + 16px); + top:50%; + left:50%; + transform: translateX(-50%) translateY(-50%); + } + } + .tooltip-content { white-space: nowrap; padding: $tooltip-padding; diff --git a/styleguide/docs/react/tooltip.js b/styleguide/docs/react/tooltip.js index bb1130a31..81d5f3ad1 100644 --- a/styleguide/docs/react/tooltip.js +++ b/styleguide/docs/react/tooltip.js @@ -25,6 +25,7 @@ Property | Required | Type | Default ---------------|----------|-------------------------------------------|----------|---------------------------------- visible | no | Boolean | true | Whether the tooltip contents are visible size | no | oneOf(['auto', 'sm', 'md', 'lg']) | auto | Size of the tooltip +isSticky | no | Boolean | false | Whether the tooltip hover is sticky or not * See [React proptype definitions here](https://facebook.github.io/react/docs/typechecking-with-proptypes.html) @@ -67,6 +68,7 @@ pin | no | Boolean | true | placement | no | oneOf('top', 'bottom', 'left', 'right') | 'right' | Placement of overlay in relation to target theme | no | oneOf(['light', 'dark']) | dark | Theme of tooltip background and text trigger | no | oneOf('hover', 'click', 'focus', 'manual') | 'hover' | Action to trigger showing overlay +isSticky | no | Boolean | false | Whether the tooltip hover is sticky or not ## Basic usage @@ -143,6 +145,8 @@ onEntered | no | Func | () => {} onExited | no | Func | () => {} | Callback that is called after the tooltip is hidden theme | no | oneOf(['light', 'dark']) | dark | Theme of tooltip background and text size | no | oneOf(['auto', 'sm', 'md', 'lg']) | auto | Size of the tooltip +isSticky | no | Boolean | false | Whether the tooltip hover is sticky or not + * See [React proptype definitions here](https://facebook.github.io/react/docs/typechecking-with-proptypes.html) @@ -170,6 +174,11 @@ the TooltipTrigger will add a lot of markup to the DOM if you are using it in a +
+ + + +
```