From d86d0639001114abe61715c8560a23a1e27717af Mon Sep 17 00:00:00 2001 From: Dominik Prokop Date: Tue, 22 Jan 2019 09:10:47 +0100 Subject: [PATCH] Make popover hide delay configurable to enable better UX --- .../components/ColorPicker/ColorPicker.tsx | 4 +- .../ColorPicker/ColorPickerPopover.tsx | 1 - .../src/components/Tooltip/Popper.tsx | 82 ++++++++++--------- .../components/Tooltip/PopperController.tsx | 22 ++++- 4 files changed, 64 insertions(+), 45 deletions(-) diff --git a/packages/grafana-ui/src/components/ColorPicker/ColorPicker.tsx b/packages/grafana-ui/src/components/ColorPicker/ColorPicker.tsx index eac97548157..68edf8abcd1 100644 --- a/packages/grafana-ui/src/components/ColorPicker/ColorPicker.tsx +++ b/packages/grafana-ui/src/components/ColorPicker/ColorPicker.tsx @@ -37,7 +37,7 @@ export const colorPickerFactory = ( }; return ( - + {(showPopper, hidePopper, popperProps) => { return ( <> @@ -79,5 +79,5 @@ export const colorPickerFactory = ( }; }; -export const ColorPicker = colorPickerFactory(ColorPickerPopover, 'ColorPicker'); +export const ColorPicker = colorPickerFactory(ColorPickerPopover, 'ColorPicker'); export const SeriesColorPicker = colorPickerFactory(SeriesColorPickerPopover, 'SeriesColorPicker'); diff --git a/packages/grafana-ui/src/components/ColorPicker/ColorPickerPopover.tsx b/packages/grafana-ui/src/components/ColorPicker/ColorPickerPopover.tsx index c9242f72ebf..5ac0d38a40a 100644 --- a/packages/grafana-ui/src/components/ColorPicker/ColorPickerPopover.tsx +++ b/packages/grafana-ui/src/components/ColorPicker/ColorPickerPopover.tsx @@ -6,7 +6,6 @@ import { ColorPickerProps } from './ColorPicker'; import { GrafanaTheme, Themeable } from '../../types'; import { PopperContentProps } from '../Tooltip/PopperController'; -// const DEFAULT_COLOR = '#000000'; export interface Props extends ColorPickerProps, Themeable, PopperContentProps {} diff --git a/packages/grafana-ui/src/components/Tooltip/Popper.tsx b/packages/grafana-ui/src/components/Tooltip/Popper.tsx index fa49596755c..93a896d97ed 100644 --- a/packages/grafana-ui/src/components/Tooltip/Popper.tsx +++ b/packages/grafana-ui/src/components/Tooltip/Popper.tsx @@ -13,8 +13,8 @@ const defaultTransitionStyles = { const transitionStyles: { [key: string]: object } = { exited: { opacity: 0 }, entering: { opacity: 0 }, - entered: { opacity: 1 }, - exiting: { opacity: 0 }, + entered: { opacity: 1, transitionDelay: '0s' }, + exiting: { opacity: 0, transitionDelay: '500ms' }, }; export type RenderPopperArrowFn = ( @@ -41,46 +41,48 @@ class Popper extends PureComponent { return ( - {transitionState => ( - - - {({ ref, style, placement, arrowProps, scheduleUpdate }) => { - return ( -
-
- {typeof content === 'string' - ? content - : React.cloneElement(content, { - updatePopperPosition: scheduleUpdate, + {transitionState => { + return ( + + + {({ ref, style, placement, arrowProps, scheduleUpdate }) => { + return ( +
+
+ {typeof content === 'string' + ? content + : React.cloneElement(content, { + updatePopperPosition: scheduleUpdate, + })} + {renderArrow && + renderArrow({ + arrowProps, + placement, })} - {renderArrow && - renderArrow({ - arrowProps, - placement, - })} +
-
- ); - }} - - - )} + ); + }} + + + ); + }} ); diff --git a/packages/grafana-ui/src/components/Tooltip/PopperController.tsx b/packages/grafana-ui/src/components/Tooltip/PopperController.tsx index a4bc555a4db..770d1ce9f37 100644 --- a/packages/grafana-ui/src/components/Tooltip/PopperController.tsx +++ b/packages/grafana-ui/src/components/Tooltip/PopperController.tsx @@ -1,9 +1,11 @@ import React from 'react'; import * as PopperJS from 'popper.js'; -// This API allows popovers to update Popper's position when e.g. popover content chaanges +// This API allows popovers to update Popper's position when e.g. popover content changes // updatePopperPosition is delivered to content by react-popper -export interface PopperContentProps { updatePopperPosition?: () => void; } +export interface PopperContentProps { + updatePopperPosition?: () => void; +} export type PopperContent = string | React.ReactElement; @@ -29,6 +31,7 @@ interface Props { content: PopperContent; className?: string; children: PopperControllerRenderProp; + hideAfter?: number; } interface State { @@ -37,6 +40,8 @@ interface State { } class PopperController extends React.Component { + private hideTimeout: any; + constructor(props: Props) { super(props); @@ -58,6 +63,10 @@ class PopperController extends React.Component { } showPopper = () => { + if (this.hideTimeout) { + clearTimeout(this.hideTimeout); + } + this.setState(prevState => ({ ...prevState, show: true, @@ -65,6 +74,15 @@ class PopperController extends React.Component { }; hidePopper = () => { + if (this.props.hideAfter !== 0) { + this.hideTimeout = setTimeout(() => { + this.setState(prevState => ({ + ...prevState, + show: false, + })); + }, this.props.hideAfter); + return; + } this.setState(prevState => ({ ...prevState, show: false,