From ceba73832e61689673744f1ab274f5abb26f505b Mon Sep 17 00:00:00 2001 From: Daniel Yamuza Date: Tue, 30 Apr 2019 11:39:58 +0200 Subject: [PATCH] Tooltip component, a react-tooltip wrapper (#938) (#1050) * Added Tooltip component to Apps-UI a react-tooltip Wrapper (#938) * Made the trigger prop mandatory to enforce the usage of different ids over controlled triggers, removed some unneeded blank lines --- packages/apps/public/index.html | 2 + packages/ui-app/src/Labelled.tsx | 68 ++++++++++++++--------- packages/ui-app/src/RecentlyOffline.tsx | 13 ++--- packages/ui-app/src/Tooltip.tsx | 61 ++++++++++++++++++++ packages/ui-app/src/styles/components.css | 6 ++ 5 files changed, 116 insertions(+), 34 deletions(-) create mode 100644 packages/ui-app/src/Tooltip.tsx diff --git a/packages/apps/public/index.html b/packages/apps/public/index.html index 4110f68845..b0ba21a66c 100644 --- a/packages/apps/public/index.html +++ b/packages/apps/public/index.html @@ -13,5 +13,7 @@ You need to enable JavaScript to run this app.
+
+ diff --git a/packages/ui-app/src/Labelled.tsx b/packages/ui-app/src/Labelled.tsx index b3eae1ceaf..13e51c1d2c 100644 --- a/packages/ui-app/src/Labelled.tsx +++ b/packages/ui-app/src/Labelled.tsx @@ -10,6 +10,7 @@ import styled from 'styled-components'; import Icon from './Icon'; import media from './media'; import { classes } from './util'; +import Tooltip from './Tooltip'; type Props = BareProps & { help?: React.ReactNode, @@ -20,6 +21,10 @@ type Props = BareProps & { withLabel?: boolean }; +type State = { + tooltipOpen: boolean +}; + const defaultLabel: any = (// node?
 
); @@ -32,28 +37,10 @@ const Wrapper = styled.div` padding-right: 0.5rem; position: relative; - .help-hover { - background: #222; - border-radius: 0.25rem; - color: #fff; - display: none; - padding: 0.5rem 1rem; - position: absolute; - text-align: left; - top: 0.5rem; - left: 2.5rem; - right: -5rem; - z-index: 10; - opacity: .9; - } - i.icon.help { margin: 0 0 0 0.25rem; line-height: 1rem; - } - - &.with-help:hover .help-hover { - display: block; + cursor: help; } } @@ -92,9 +79,42 @@ const Wrapper = styled.div` `} `; -export default class Labelled extends React.PureComponent { +export default class Labelled extends React.PureComponent { + constructor (props: Props) { + super(props); + this.state = { + tooltipOpen: false + }; + } + + toggleTooltip () { + const { tooltipOpen } = this.state; + this.setState({ tooltipOpen: !tooltipOpen }); + } + + renderLabel () { + const { help, label = defaultLabel } = this.props; + const { tooltipOpen } = this.state; + + return help + ? + : ; + } render () { - const { className, children, help, isSmall, isHidden, label = defaultLabel, style, withLabel = true } = this.props; + const { className, children, isSmall, isHidden, style, withLabel = true } = this.props; if (isHidden) { return null; @@ -104,16 +124,12 @@ export default class Labelled extends React.PureComponent { ); } - const labelNode = help - ? - : ; - return ( - {labelNode} + {this.renderLabel()}
{children}
diff --git a/packages/ui-app/src/RecentlyOffline.tsx b/packages/ui-app/src/RecentlyOffline.tsx index 26e27db596..63729e1cb8 100644 --- a/packages/ui-app/src/RecentlyOffline.tsx +++ b/packages/ui-app/src/RecentlyOffline.tsx @@ -9,7 +9,7 @@ import BN from 'bn.js'; import React from 'react'; import { formatNumber } from '@polkadot/util'; -import ReactTooltip from 'react-tooltip'; +import Tooltip from './Tooltip'; import translate from './translate'; @@ -70,14 +70,11 @@ class RecentlyOffline extends React.PureComponent {
{text}
- - {text} - + {text} + ); } diff --git a/packages/ui-app/src/Tooltip.tsx b/packages/ui-app/src/Tooltip.tsx new file mode 100644 index 0000000000..aabe412874 --- /dev/null +++ b/packages/ui-app/src/Tooltip.tsx @@ -0,0 +1,61 @@ +// Copyright 2017-2019 @polkadot/ui-app authors & contributors +// This software may be modified and distributed under the terms +// of the Apache-2.0 license. See the LICENSE file for details. + +import React from 'react'; +import ReactDOM from 'react-dom'; +import ReactTooltip from 'react-tooltip'; + +import { BareProps } from './types'; + +const rootElement = document.getElementById('tooltips'); + +type Props = BareProps & { + trigger: string, + delayShow?: number, + place?: 'bottom' | 'top' | 'right' | 'left', + effect?: 'solid' | 'float' +}; + +export default class Tooltip extends React.PureComponent { + static defaultProps = { + delayShow: 250, + effect: 'solid', + place: 'bottom', + className: 'ui--Tooltip' + }; + + tooltipContainer: HTMLElement; + + constructor (props: Props) { + super(props); + this.tooltipContainer = document.createElement('div'); + } + + componentDidMount () { + if (rootElement !== null) { + rootElement.appendChild(this.tooltipContainer); + } + } + + componentWillUnmount () { + if (rootElement !== null) { + rootElement.removeChild(this.tooltipContainer); + } + } + + render () { + const { children, trigger, delayShow, effect, place, className } = this.props; + return ReactDOM.createPortal( + + {children} + , + this.tooltipContainer); + } +} diff --git a/packages/ui-app/src/styles/components.css b/packages/ui-app/src/styles/components.css index 1d14b83be8..723ae691e3 100644 --- a/packages/ui-app/src/styles/components.css +++ b/packages/ui-app/src/styles/components.css @@ -410,3 +410,9 @@ header .ui--Button-Group { .ui.tiny.progress { font-size: .5rem; } + +.ui--Tooltip { + text-align: center; + z-index: 1002; + max-width: 300px; +} \ No newline at end of file