- client: Use the same tooltip style everywhere
Close #1866
Squashed commit of the following:
commit 3347832caa33b01a0155b212987f02dc4824ab08
Merge: 7766502d d794b11e
Author: ArtemBaskal <a.baskal@adguard.com>
Date: Fri Jul 17 15:12:45 2020 +0300
Merge branch 'master' into fix/1866
commit 7766502d4a904ad0a4d240481f7eabf0e25cfb62
Author: ArtemBaskal <a.baskal@adguard.com>
Date: Fri Jul 17 12:16:59 2020 +0300
Fix icon color classes
commit 90191bf74b5eb1855c733c226f7acb4e906c7ad9
Author: ArtemBaskal <a.baskal@adguard.com>
Date: Fri Jul 17 11:46:22 2020 +0300
Use logs icons, use pointer cursor, fix review markup formatting
commit 0ba50fcd956101f5054ce38c2329df3e8abdfcd2
Author: ArtemBaskal <a.baskal@adguard.com>
Date: Thu Jul 16 18:05:30 2020 +0300
Use help cursor on tooltips
commit bf4e14afe69f874d29be73d8cd4cfbe240ca0304
Author: ArtemBaskal <a.baskal@adguard.com>
Date: Thu Jul 16 17:41:47 2020 +0300
Use tooltip in logs, rename tooltip classes
commit 00568fdc8e8484c5bae67c51ee8189a3a558e219
Author: ArtemBaskal <a.baskal@adguard.com>
Date: Thu Jul 16 17:01:49 2020 +0300
- client: Use the same tooltip style everywhere
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
.dropdown-item.active,
|
||||
.dropdown-item:active {
|
||||
background-color: #66b574;
|
||||
background-color: var(--green-74);
|
||||
}
|
||||
|
||||
.dropdown-menu {
|
||||
|
||||
@@ -1,73 +0,0 @@
|
||||
.tooltip-custom {
|
||||
position: relative;
|
||||
top: -1px;
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
flex-shrink: 0;
|
||||
background-image: url("./svg/help-circle.svg");
|
||||
background-size: 100%;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.tooltip-custom:before {
|
||||
content: attr(data-tooltip);
|
||||
display: block;
|
||||
position: absolute;
|
||||
bottom: calc(100% + 10px);
|
||||
left: 50%;
|
||||
padding: 10px 15px;
|
||||
font-size: 0.85rem;
|
||||
text-align: center;
|
||||
color: #fff;
|
||||
background-color: #585965;
|
||||
border-radius: 3px;
|
||||
transform: translateX(-50%);
|
||||
visibility: hidden;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.tooltip-custom:after {
|
||||
content: "";
|
||||
position: relative;
|
||||
top: -7px;
|
||||
left: calc(50% - 6px);
|
||||
visibility: hidden;
|
||||
opacity: 0;
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-left: 6px solid transparent;
|
||||
border-right: 6px solid transparent;
|
||||
border-top: 6px solid #585965;
|
||||
}
|
||||
|
||||
.tooltip-custom:hover:before,
|
||||
.tooltip-custom:hover:after {
|
||||
visibility: visible;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.tooltip-custom--narrow:before {
|
||||
width: 220px;
|
||||
}
|
||||
|
||||
.tooltip-custom--logs {
|
||||
border-radius: 50%;
|
||||
background-image: url("./svg/help-circle-gray.svg");
|
||||
}
|
||||
|
||||
.tooltip-custom--logs:before {
|
||||
bottom: initial;
|
||||
top: calc(100% + 10px);
|
||||
right: -10px;
|
||||
left: initial;
|
||||
width: 255px;
|
||||
transform: none;
|
||||
}
|
||||
|
||||
.tooltip-custom--logs:after {
|
||||
top: 8px;
|
||||
border-top: none;
|
||||
border-bottom: 6px solid #585965;
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import './IconTooltip.css';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
const IconTooltip = ({ text, type = '' }) => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
return <div data-tooltip={t(text)}
|
||||
className={`tooltip-custom ml-1 ${type}`} />;
|
||||
};
|
||||
|
||||
IconTooltip.propTypes = {
|
||||
text: PropTypes.string.isRequired,
|
||||
type: PropTypes.string,
|
||||
};
|
||||
|
||||
export default IconTooltip;
|
||||
@@ -4,24 +4,36 @@
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.icon--small {
|
||||
width: 1.5rem;
|
||||
height: 1.5rem;
|
||||
.icon--24 {
|
||||
--size: 1.5rem;
|
||||
width: var(--size);
|
||||
height: var(--size);
|
||||
}
|
||||
|
||||
.icon--smallest {
|
||||
width: 1.2rem;
|
||||
height: 1.2rem;
|
||||
.icon--20 {
|
||||
--size: 1.25rem;
|
||||
width: var(--size);
|
||||
height: var(--size);
|
||||
}
|
||||
|
||||
.icon--18 {
|
||||
--size: 1.125rem;
|
||||
width: var(--size);
|
||||
height: var(--size);
|
||||
}
|
||||
|
||||
.icon--gray {
|
||||
color: var(--gray-a5);
|
||||
}
|
||||
|
||||
.icon--green {
|
||||
color: var(--green-74);
|
||||
}
|
||||
|
||||
.icon--disabled {
|
||||
color: var(--gray-d8);
|
||||
}
|
||||
|
||||
.icon--active {
|
||||
color: #66b574;
|
||||
.icon--lightgray {
|
||||
color: var(--gray-8);
|
||||
}
|
||||
|
||||
@@ -1,151 +0,0 @@
|
||||
.popover-wrap {
|
||||
position: relative;
|
||||
top: 1px;
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
align-self: flex-start;
|
||||
}
|
||||
|
||||
.popover__trigger {
|
||||
position: relative;
|
||||
top: 3px;
|
||||
margin: 0 8px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.popover__trigger:after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: -6px;
|
||||
left: -3px;
|
||||
width: 26px;
|
||||
height: 24px;
|
||||
}
|
||||
|
||||
.popover__trigger--address {
|
||||
top: 0;
|
||||
margin: 0;
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
.popover__trigger--address:after {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.popover__body {
|
||||
content: "";
|
||||
display: flex;
|
||||
position: absolute;
|
||||
bottom: calc(100% + 3px);
|
||||
left: 50%;
|
||||
z-index: 1;
|
||||
min-width: 275px;
|
||||
padding: 10px 15px;
|
||||
font-size: 0.8rem;
|
||||
white-space: normal;
|
||||
color: #fff;
|
||||
background-color: #585965;
|
||||
border-radius: 3px;
|
||||
transition: opacity 0.2s ease-in-out, visibility 0.2s ease-in-out;
|
||||
transform: translateX(-50%);
|
||||
visibility: hidden;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.popover__body--filter {
|
||||
min-width: 100%;
|
||||
}
|
||||
|
||||
.popover__body:after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
bottom: -5px;
|
||||
left: calc(50% - 6px);
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-left: 6px solid transparent;
|
||||
border-right: 6px solid transparent;
|
||||
border-top: 6px solid #585965;
|
||||
}
|
||||
|
||||
.popover__body--address {
|
||||
top: calc(100% + 10px);
|
||||
right: 0;
|
||||
left: initial;
|
||||
bottom: initial;
|
||||
z-index: 1;
|
||||
min-width: 100px;
|
||||
padding: 12px 18px;
|
||||
font-weight: 700;
|
||||
text-align: left;
|
||||
white-space: nowrap;
|
||||
transform: none;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.popover__body--address:after {
|
||||
top: -11px;
|
||||
left: initial;
|
||||
right: 40px;
|
||||
border-top: 6px solid transparent;
|
||||
border-bottom: 6px solid #585965;
|
||||
}
|
||||
|
||||
.popover__body--address:before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: -7px;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 10px;
|
||||
}
|
||||
|
||||
.popover__trigger:hover + .popover__body,
|
||||
.popover__body:hover {
|
||||
visibility: visible;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.popover__icon {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
stroke: #9aa0ac;
|
||||
color: #9aa0ac;
|
||||
}
|
||||
|
||||
.popover__icon--green {
|
||||
color: #66b574;
|
||||
stroke: #66b574;
|
||||
}
|
||||
|
||||
.popover__list--bold {
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.popover__list-title {
|
||||
margin-bottom: 3px;
|
||||
}
|
||||
|
||||
.popover__list-item {
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
|
||||
.popover__list-item--nowrap {
|
||||
max-width: 300px;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.popover__list-item:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.popover__link {
|
||||
color: #66b586;
|
||||
}
|
||||
|
||||
.popover__link:hover,
|
||||
.popover__link:focus {
|
||||
color: #66b586;
|
||||
}
|
||||
@@ -1,69 +0,0 @@
|
||||
import React, { Component } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { Trans, withTranslation } from 'react-i18next';
|
||||
import { getSourceData } from '../../helpers/trackers/trackers';
|
||||
import { captitalizeWords } from '../../helpers/helpers';
|
||||
|
||||
import './Popover.css';
|
||||
|
||||
class Popover extends Component {
|
||||
render() {
|
||||
const { data } = this.props;
|
||||
|
||||
const sourceData = getSourceData(data);
|
||||
|
||||
const source = (
|
||||
<div className="popover__list-item">
|
||||
<Trans>source_label</Trans>: <a className="popover__link" target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
href={sourceData.url}>
|
||||
<strong>{sourceData.name}</strong>
|
||||
</a>
|
||||
</div>
|
||||
);
|
||||
|
||||
const tracker = (
|
||||
<div className="popover__list-item">
|
||||
<Trans>name_table_header</Trans>: <a className="popover__link" target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
href={data.url}>
|
||||
<strong>{data.name}</strong>
|
||||
</a>
|
||||
</div>
|
||||
);
|
||||
|
||||
const categoryName = captitalizeWords(data.category);
|
||||
|
||||
return (
|
||||
<div className="popover-wrap">
|
||||
<div className="popover__trigger">
|
||||
<svg className="popover__icon" xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24" fill="none" strokeWidth="2" strokeLinecap="round"
|
||||
strokeLinejoin="round">
|
||||
<path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"></path>
|
||||
<circle cx="12" cy="12" r="3"></circle>
|
||||
</svg>
|
||||
</div>
|
||||
<div className="popover__body">
|
||||
<div className="popover__list">
|
||||
<div className="popover__list-title">
|
||||
<Trans>found_in_known_domain_db</Trans>
|
||||
</div>
|
||||
{tracker}
|
||||
<div className="popover__list-item">
|
||||
<Trans>category_label</Trans>: <strong>
|
||||
<Trans>{categoryName}</Trans></strong>
|
||||
</div>
|
||||
{source}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Popover.propTypes = {
|
||||
data: PropTypes.object.isRequired,
|
||||
};
|
||||
|
||||
export default withTranslation()(Popover);
|
||||
@@ -1,52 +0,0 @@
|
||||
import React, { Component } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { Trans, withTranslation } from 'react-i18next';
|
||||
|
||||
import './Popover.css';
|
||||
|
||||
class PopoverFilter extends Component {
|
||||
render() {
|
||||
const { rule, filter, service } = this.props;
|
||||
|
||||
if (!rule && !service) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="popover-wrap">
|
||||
<div className="popover__trigger popover__trigger--filter">
|
||||
<svg className="popover__icon popover__icon--green">
|
||||
<use xlinkHref="#question" />
|
||||
</svg>
|
||||
</div>
|
||||
<div className="popover__body popover__body--filter">
|
||||
<div className="popover__list">
|
||||
{rule && (
|
||||
<div className="popover__list-item popover__list-item--nowrap">
|
||||
<Trans>rule_label</Trans>: <strong>{rule}</strong>
|
||||
</div>
|
||||
)}
|
||||
{filter && (
|
||||
<div className="popover__list-item popover__list-item--nowrap">
|
||||
<Trans>list_label</Trans>: <strong>{filter}</strong>
|
||||
</div>
|
||||
)}
|
||||
{service && (
|
||||
<div className="popover__list-item popover__list-item--nowrap">
|
||||
<Trans>blocked_service</Trans>: <strong>{service}</strong>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
PopoverFilter.propTypes = {
|
||||
rule: PropTypes.string,
|
||||
filter: PropTypes.string,
|
||||
service: PropTypes.string,
|
||||
};
|
||||
|
||||
export default withTranslation()(PopoverFilter);
|
||||
@@ -19,10 +19,13 @@ Dashboard UI
|
||||
--orange: #fd9644;
|
||||
--yellow: #f1c40f;
|
||||
--green: #5eba00;
|
||||
--green-74: #66b574;
|
||||
--green-86: #66b586;
|
||||
--teal: #2bcbba;
|
||||
--cyan: #17a2b8;
|
||||
--white: #fff;
|
||||
--gray: #868e96;
|
||||
--gray-ac: #9aa0ac;
|
||||
--gray-dark: #343a40;
|
||||
--azure: #45aaf2;
|
||||
--lime: #7bd235;
|
||||
|
||||
27
client/src/components/ui/Tooltip.css
Normal file
27
client/src/components/ui/Tooltip.css
Normal file
@@ -0,0 +1,27 @@
|
||||
.tooltip-custom--narrow {
|
||||
max-width: 13.75rem;
|
||||
}
|
||||
|
||||
.tooltip-custom--wide {
|
||||
max-width: 18rem;
|
||||
}
|
||||
|
||||
.tooltip-custom__trigger {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.tooltip-custom__content-title {
|
||||
margin-bottom: 0.1875rem;
|
||||
}
|
||||
|
||||
.tooltip-custom__content-item {
|
||||
margin-bottom: 0.125rem;
|
||||
}
|
||||
|
||||
.tooltip-custom__content-item:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.tooltip-custom__content-link {
|
||||
color: var(--green-86);
|
||||
}
|
||||
58
client/src/components/ui/Tooltip.js
Normal file
58
client/src/components/ui/Tooltip.js
Normal file
@@ -0,0 +1,58 @@
|
||||
import React from 'react';
|
||||
import TooltipTrigger from 'react-popper-tooltip';
|
||||
import propTypes from 'prop-types';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { HIDE_TOOLTIP_DELAY } from '../../helpers/constants';
|
||||
import 'react-popper-tooltip/dist/styles.css';
|
||||
import './Tooltip.css';
|
||||
|
||||
const Tooltip = ({
|
||||
children,
|
||||
content,
|
||||
triggerClass = 'tooltip-custom__trigger',
|
||||
className = 'tooltip-container',
|
||||
placement = 'bottom',
|
||||
trigger = 'hover',
|
||||
delayHide = HIDE_TOOLTIP_DELAY,
|
||||
}) => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
return <TooltipTrigger
|
||||
placement={placement}
|
||||
trigger={trigger}
|
||||
delayHide={delayHide}
|
||||
tooltip={({
|
||||
tooltipRef,
|
||||
getTooltipProps,
|
||||
}) => <div {...getTooltipProps({
|
||||
ref: tooltipRef,
|
||||
className,
|
||||
})}>
|
||||
{typeof content === 'string' ? t(content) : content}
|
||||
</div>
|
||||
}>{({ getTriggerProps, triggerRef }) => <span
|
||||
{...getTriggerProps({
|
||||
ref: triggerRef,
|
||||
className: triggerClass,
|
||||
})}
|
||||
>{children}</span>}
|
||||
</TooltipTrigger>;
|
||||
};
|
||||
|
||||
Tooltip.propTypes = {
|
||||
children: propTypes.element.isRequired,
|
||||
content: propTypes.oneOfType(
|
||||
[
|
||||
propTypes.string,
|
||||
propTypes.element,
|
||||
propTypes.arrayOf(propTypes.element),
|
||||
],
|
||||
).isRequired,
|
||||
placement: propTypes.string,
|
||||
trigger: propTypes.string,
|
||||
delayHide: propTypes.string,
|
||||
className: propTypes.string,
|
||||
triggerClass: propTypes.string,
|
||||
};
|
||||
|
||||
export default Tooltip;
|
||||
@@ -1 +1,6 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#66b574" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-help-circle"><circle cx="12" cy="12" r="10"></circle><path d="M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3"></path><line x1="12" y1="17" x2="12" y2="17"></line></svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#66b574"
|
||||
stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-help-circle">
|
||||
<circle cx="12" cy="12" r="10"></circle>
|
||||
<path d="M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3"></path>
|
||||
<line x1="12" y1="17" x2="12" y2="17"></line>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 357 B After Width: | Height: | Size: 379 B |
Reference in New Issue
Block a user