update tooltip component to show on hover and add different directions

This commit is contained in:
Sean Yesmunt 2018-05-22 20:11:20 -04:00
parent 7c4e4c24ad
commit f86bb14591
11 changed files with 181 additions and 140 deletions

View file

@ -223,6 +223,7 @@ class CategoryList extends React.PureComponent<Props, State> {
{category &&
category.match(/^community/i) && (
<ToolTip
direction="bottom"
label={__("What's this?")}
body={__(
'Community Content is a public space where anyone can share content with the rest of the LBRY community. Bid on the names "one," "two," "three," "four" and "five" to put your content here!'

View file

@ -2,22 +2,35 @@
import React from 'react';
import * as FeatherIcons from 'react-feather';
import * as icons from 'constants/icons';
import Tooltip from 'component/common/tooltip';
const RED_COLOR = '#e2495e';
const PURPLE_COLOR = '#8165b0';
type Props = {
icon: string,
tooltip: ?string, // tooltip direction
};
class IconComponent extends React.PureComponent<Props> {
// TODO: Move all icons to constants and add titles for all
// Add some some sort of hover flyout with the title?
getTooltip = (icon: string) => {
switch (icon) {
case icons.FEATURED:
return __('Featured content. Earn rewards for watching.');
case icons.LOCAL:
return __('This file is downloaded.');
default:
return null;
}
};
render() {
const { icon } = this.props;
const { icon, tooltip } = this.props;
const Icon = FeatherIcons[icon];
if (!Icon) {
return null;
}
let color;
if (icon === icons.TRASH || icon === icons.FEATURED) {
color = RED_COLOR;
@ -30,7 +43,19 @@ class IconComponent extends React.PureComponent<Props> {
size = 20;
}
return Icon ? <Icon size={size} className="icon" color={color} /> : null;
let tooltipText;
if (tooltip) {
tooltipText = this.getTooltip(icon);
}
const inner = <Icon size={size} className="icon" color={color} />;
return tooltip ? (
<Tooltip icon body={tooltipText} direction={tooltip}>
{inner}
</Tooltip>
) : (
inner
);
}
}

View file

@ -1,55 +1,41 @@
// @flow
import React from 'react';
import * as React from 'react';
import classnames from 'classnames';
import Icon from 'component/common/icon';
import Button from 'component/button';
import * as icons from 'constants/icons';
type Props = {
body: string,
label: string,
body: ?string,
label?: string,
children: ?React.Node,
icon: ?boolean,
direction: string,
};
type State = {
showTooltip: boolean,
};
class ToolTip extends React.PureComponent<Props, State> {
constructor(props: Props) {
super(props);
this.state = {
showTooltip: false,
};
(this: any).handleClick = this.handleClick.bind(this);
}
handleClick() {
const { showTooltip } = this.state;
if (!showTooltip) {
document.addEventListener('click', this.handleClick);
} else {
document.removeEventListener('click', this.handleClick);
}
this.setState({
showTooltip: !showTooltip,
});
}
class ToolTip extends React.PureComponent<Props> {
static defaultProps = {
direction: 'top',
};
render() {
const { label, body } = this.props;
const { showTooltip } = this.state;
const { children, label, body, icon, direction } = this.props;
const tooltipContent = children || label;
return (
<span className="tooltip">
<Button button="link" className="help tooltip__link" onClick={this.handleClick}>
{label}
{showTooltip && <Icon icon={icons.CLOSE} />}
</Button>
<div className={classnames('tooltip__body', { hidden: !showTooltip })}>{body}</div>
<span
className={classnames('tooltip', {
'tooltip--label': label && !icon,
'tooltip--icon': icon,
'tooltip--top': direction === 'top',
'tooltip--right': direction === 'right',
'tooltip--bottom': direction === 'bottom',
'tooltip--left': direction === 'left',
})}
>
{tooltipContent}
{body && (
// body may be undefined for some icons until we add messages for them
<span className="tooltip__body">{body}</span>
)}
</span>
);
}

View file

@ -98,14 +98,16 @@ class FileCard extends React.PureComponent<Props> {
<div className="card__title--small">
<TruncatedText lines={3}>{title}</TruncatedText>
</div>
<div className="card__subtitle card__subtitle--file-info">
<div className="card__subtitle">
{pending ? (
<div>Pending...</div>
) : (
<React.Fragment>
<UriIndicator uri={uri} link />
{isRewardContent && <Icon icon={icons.FEATURED} />}
{fileInfo && <Icon icon={icons.LOCAL} />}
<div>
{isRewardContent && <Icon icon={icons.FEATURED} />}
{fileInfo && <Icon icon={icons.LOCAL} />}
</div>
</React.Fragment>
)}
</div>

View file

@ -158,7 +158,7 @@ class FilePage extends React.Component<Props> {
<h1 className="card__title card__title--file">{title}</h1>
<div className="card__title-identity-icons">
<FilePrice uri={normalizeURI(uri)} />
{isRewardContent && <Icon icon={icons.FEATURED} />}
{isRewardContent && <Icon tooltip="bottom" icon={icons.FEATURED} />}
</div>
</div>
<span className="card__subtitle card__subtitle--file">

View file

@ -5,6 +5,8 @@ import FileTile from 'component/fileTile';
import FileListSearch from 'component/fileListSearch';
import ToolTip from 'component/common/tooltip';
import Page from 'component/page';
import Icon from 'component/common/icon';
import * as icons from 'constants/icons';
const MODAL_ANIMATION_TIME = 250;
@ -50,10 +52,11 @@ class SearchPage extends React.PureComponent<Props> {
<div className="file-list__header">
{__('Exact URL')}
<ToolTip
label="?"
icon
body={__('This is the resolution of a LBRY URL and not controlled by LBRY Inc.')}
className="tooltip--header"
/>
>
<Icon icon={icons.HELP} />
</ToolTip>
</div>
<FileTile fullWidth uri={normalizeURI(query)} showUri />
</React.Fragment>

View file

@ -122,12 +122,11 @@ input::placeholder {
}
select {
min-width: 100px;
min-width: 60px;
height: 30px;
border-radius: 8px;
background-color: var(--input-select-bg-color);
font: normal 12px/30px 'metropolis-medium';
text-indent: 12px;
color: var(--input-select-color);
&:disabled {

View file

@ -161,9 +161,8 @@ $large-breakpoint: 1760px;
--modal-btn-bg-color: var(--btn-bg-alt);
// /* Tooltip */
--tooltip-width: 300px;
--tooltip-bg: var(--color-bg);
--tooltip-color: var(--text-color);
--tooltip-bg: #555;
--tooltip-color: var(--color-white);
/* Scrollbar */
--scrollbar-radius: 10px;

View file

@ -17,7 +17,6 @@
.card--small {
width: var(--card-small-width);
overflow-x: hidden;
white-space: normal;
.card__media {
@ -86,8 +85,7 @@
align-items: center;
.credit-amount,
.icon {
margin-top: $spacing-vertical * 1/3;
margin-left: $spacing-vertical * 2/3;
margin: $spacing-vertical * 1/3;
}
}
@ -126,7 +124,11 @@
color: var(--card-text-color);
.icon {
margin-left: $spacing-vertical * 1/3;
margin-top: $spacing-vertical * 1/6;
&:not(:first-of-type) {
margin: 0 $spacing-vertical * 1/3;
}
}
}
@ -134,11 +136,6 @@
padding-top: $spacing-vertical * 1/3;
}
.card__subtitle--file-info {
display: flex;
align-items: center;
}
.card__subtitle--block {
display: block;
}
@ -243,12 +240,11 @@
}
/*
.card-row is used on the discover/subscriptions page
.card-row is used on the discover page
It is a list of cards that extend past the right edge of the screen
There are left/right arrows to scroll the cards and view hidden content
*/
.card-row {
overflow: hidden;
white-space: nowrap;
width: 100%;
min-width: var(--card-small-width);
@ -289,6 +285,18 @@
padding-top: $spacing-vertical * 2/3;
overflow: hidden;
.card {
display: inline-block;
vertical-align: top;
overflow-y: visible;
// 31 px to handle to padding between cards
width: calc((100% / 4) - 31px);
}
.card:not(:first-of-type) {
margin-left: 20px;
}
.card:first-of-type {
margin-left: $spacing-width;
}
@ -327,27 +335,6 @@
}
}
.card-row__scrollhouse {
padding-top: $spacing-vertical * 2/3;
overflow: hidden;
.card {
display: inline-block;
vertical-align: top;
overflow: visible;
// 31 px to handle to padding between cards
width: calc((100% / 4) - 31px);
}
.card:not(:first-of-type) {
margin-left: 20px;
}
.card:last-of-type {
margin-right: 20px;
}
}
.card__success-msg {
border-left: 2px solid var(--success-msg-border);
color: var(--success-msg-color);

View file

@ -1,30 +1,97 @@
@import '../mixin/link.scss';
.tooltip {
position: relative;
padding: 0 $spacing-vertical / 3;
font-size: 12px;
display: inline-block;
}
.tooltip__body {
// When there is a label for the tooltip and not just using a button or icon
.tooltip.tooltip--label {
font-size: 12px;
padding-left: $spacing-vertical * 1/3;
.tooltip__body {
margin-top: 5px;
}
}
.tooltip.tooltip--icon {
margin-top: 5px;
}
/* Tooltip text */
.tooltip .tooltip__body {
background-color: var(--tooltip-bg);
font-family: 'metropolis-medium';
font-size: 12px;
color: var(--tooltip-color);
border-radius: 8px;
position: absolute;
z-index: 1;
left: 50%;
margin-left: calc(var(--tooltip-width) * -1 / 2);
white-space: normal;
box-sizing: border-box;
padding: $spacing-vertical / 2;
width: var(--tooltip-width);
color: var(--tooltip-color);
background-color: var(--tooltip-bg);
font-size: calc(var(--font-size) * 7 / 8);
line-height: var(--font-line-height);
box-shadow: var(--box-shadow-layer);
border-radius: var(--card-radius);
width: 200px;
text-align: center;
white-space: pre-wrap;
padding: $spacing-vertical * 1/3;
visibility: hidden;
}
.tooltip__link {
font-size: calc(var(--font-size) * 3 / 4);
margin-left: var(--button-padding);
vertical-align: middle;
.tooltip .tooltip__body::after {
content: ' ';
width: 0;
height: 0;
position: absolute;
border-width: 5px;
border-style: solid;
}
.tooltip.tooltip--top .tooltip__body {
bottom: 100%;
left: 50%;
margin-left: -100px;
&::after {
top: 100%;
left: 50%;
margin-left: -5px;
border-color: var(--tooltip-bg) transparent transparent transparent;
}
}
.tooltip.tooltip--right .tooltip__body {
margin-top: -5px;
margin-left: 10px;
&::after {
top: 17px;
right: 100%; /* To the left of the tooltip */
margin-top: -5px;
border-color: transparent var(--tooltip-bg) transparent transparent;
}
}
.tooltip.tooltip--bottom .tooltip__body {
top: 90%;
left: 50%;
margin-left: -100px;
&::after {
bottom: 100%;
left: 50%;
margin-left: -5px;
border-color: transparent transparent var(--tooltip-bg) transparent;
}
}
.tooltip.tooltip--left .tooltip__body {
top: -5px;
right: 105%;
&::after {
top: 17px;
left: 100%;
margin-top: -5px;
border-color: transparent transparent transparent var(--tooltip-bg);
}
}
.tooltip:hover .tooltip__body {
visibility: visible;
}

View file

@ -1,28 +0,0 @@
@mixin text-link($color: var(--color-primary), $hover-opacity: 0.7) {
.icon {
&:first-child {
padding-right: 5px;
}
&:last-child:not(:only-child) {
padding-left: 5px;
}
}
&:not(.no-underline) {
text-decoration: underline;
.icon {
text-decoration: none;
}
}
&:hover {
opacity: $hover-opacity;
transition: opacity var(--transition-duration) var(--transition-type);
text-decoration: underline;
.icon {
text-decoration: none;
}
}
color: $color;
cursor: pointer;
}