Make popover hide delay configurable to enable better UX

pull/14914/head
Dominik Prokop 7 years ago
parent 2b34933554
commit d86d063900
  1. 2
      packages/grafana-ui/src/components/ColorPicker/ColorPicker.tsx
  2. 1
      packages/grafana-ui/src/components/ColorPicker/ColorPickerPopover.tsx
  3. 10
      packages/grafana-ui/src/components/Tooltip/Popper.tsx
  4. 22
      packages/grafana-ui/src/components/Tooltip/PopperController.tsx

@ -37,7 +37,7 @@ export const colorPickerFactory = <T extends ColorPickerProps>(
}; };
return ( return (
<PopperController content={popoverElement} placement="bottom-start"> <PopperController content={popoverElement} hideAfter={500}>
{(showPopper, hidePopper, popperProps) => { {(showPopper, hidePopper, popperProps) => {
return ( return (
<> <>

@ -6,7 +6,6 @@ import { ColorPickerProps } from './ColorPicker';
import { GrafanaTheme, Themeable } from '../../types'; import { GrafanaTheme, Themeable } from '../../types';
import { PopperContentProps } from '../Tooltip/PopperController'; import { PopperContentProps } from '../Tooltip/PopperController';
// const DEFAULT_COLOR = '#000000';
export interface Props extends ColorPickerProps, Themeable, PopperContentProps {} export interface Props extends ColorPickerProps, Themeable, PopperContentProps {}

@ -13,8 +13,8 @@ const defaultTransitionStyles = {
const transitionStyles: { [key: string]: object } = { const transitionStyles: { [key: string]: object } = {
exited: { opacity: 0 }, exited: { opacity: 0 },
entering: { opacity: 0 }, entering: { opacity: 0 },
entered: { opacity: 1 }, entered: { opacity: 1, transitionDelay: '0s' },
exiting: { opacity: 0 }, exiting: { opacity: 0, transitionDelay: '500ms' },
}; };
export type RenderPopperArrowFn = ( export type RenderPopperArrowFn = (
@ -41,7 +41,8 @@ class Popper extends PureComponent<Props> {
return ( return (
<Manager> <Manager>
<Transition in={show} timeout={100} mountOnEnter={true} unmountOnExit={true}> <Transition in={show} timeout={100} mountOnEnter={true} unmountOnExit={true}>
{transitionState => ( {transitionState => {
return (
<Portal> <Portal>
<ReactPopper <ReactPopper
placement={placement} placement={placement}
@ -80,7 +81,8 @@ class Popper extends PureComponent<Props> {
}} }}
</ReactPopper> </ReactPopper>
</Portal> </Portal>
)} );
}}
</Transition> </Transition>
</Manager> </Manager>
); );

@ -1,9 +1,11 @@
import React from 'react'; import React from 'react';
import * as PopperJS from 'popper.js'; 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 // updatePopperPosition is delivered to content by react-popper
export interface PopperContentProps { updatePopperPosition?: () => void; } export interface PopperContentProps {
updatePopperPosition?: () => void;
}
export type PopperContent<T extends PopperContentProps> = string | React.ReactElement<T>; export type PopperContent<T extends PopperContentProps> = string | React.ReactElement<T>;
@ -29,6 +31,7 @@ interface Props {
content: PopperContent<any>; content: PopperContent<any>;
className?: string; className?: string;
children: PopperControllerRenderProp; children: PopperControllerRenderProp;
hideAfter?: number;
} }
interface State { interface State {
@ -37,6 +40,8 @@ interface State {
} }
class PopperController extends React.Component<Props, State> { class PopperController extends React.Component<Props, State> {
private hideTimeout: any;
constructor(props: Props) { constructor(props: Props) {
super(props); super(props);
@ -58,6 +63,10 @@ class PopperController extends React.Component<Props, State> {
} }
showPopper = () => { showPopper = () => {
if (this.hideTimeout) {
clearTimeout(this.hideTimeout);
}
this.setState(prevState => ({ this.setState(prevState => ({
...prevState, ...prevState,
show: true, show: true,
@ -65,6 +74,15 @@ class PopperController extends React.Component<Props, State> {
}; };
hidePopper = () => { hidePopper = () => {
if (this.props.hideAfter !== 0) {
this.hideTimeout = setTimeout(() => {
this.setState(prevState => ({
...prevState,
show: false,
}));
}, this.props.hideAfter);
return;
}
this.setState(prevState => ({ this.setState(prevState => ({
...prevState, ...prevState,
show: false, show: false,

Loading…
Cancel
Save