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
This commit is contained in:
Daniel Yamuza 2019-04-30 11:39:58 +02:00 committed by Jaco Greeff
parent 112e188649
commit ceba73832e
5 changed files with 116 additions and 34 deletions

View File

@ -13,5 +13,7 @@
You need to enable JavaScript to run this app.
</noscript>
<div id="root"></div>
<div id="tooltips"></div>
</body>
</html>

View File

@ -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?
<div>&nbsp;</div>
);
@ -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<Props> {
export default class Labelled extends React.PureComponent<Props, State> {
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
? <label className='with-help' >
{label}
<Icon
name='help circle'
data-tip
data-for='controlled-trigger'
onMouseOver={() => this.toggleTooltip()}
onMouseOut={() => this.toggleTooltip()}
/>
{tooltipOpen && (
<Tooltip trigger={'controlled-trigger'}>
{help}
</Tooltip>)}
</label>
: <label>{label}</label>;
}
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<Props> {
);
}
const labelNode = help
? <label className='with-help'>{label}<Icon name='help circle' /><div className='help-hover'>{help}</div></label>
: <label>{label}</label>;
return (
<Wrapper
className={classes('ui--Labelled', isSmall ? 'label-small' : '', className)}
style={style}
>
{labelNode}
{this.renderLabel()}
<div className='ui--Labelled-content'>
{children}
</div>

View File

@ -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<Props, State> {
<div className='detail'>
{text}
</div>
<ReactTooltip
delayShow={250}
effect='solid'
id={`offline-${accountId}`}
place='bottom'
<Tooltip
trigger={`offline-${accountId}`}
>
{text}
</ReactTooltip>
{text}
</Tooltip>
</div>
);
}

View File

@ -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<Props> {
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(
<ReactTooltip
id={trigger}
delayShow={delayShow}
effect={effect}
place={place}
className={className}
>
{children}
</ReactTooltip>,
this.tooltipContainer);
}
}

View File

@ -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;
}