From fa3e703ab9a47dcbe11d1a27de70055c3a4126bd Mon Sep 17 00:00:00 2001 From: jamaljsr Date: Sun, 24 May 2020 00:37:56 -0400 Subject: [PATCH 1/5] ui: add tooltips to icons and some labels --- app/package.json | 1 + app/src/App.scss | 3 + app/src/assets/icons/bolt.svg | 2 +- app/src/assets/icons/menu.svg | 2 +- app/src/components/NodeStatus.tsx | 29 +++-- app/src/components/common/PageHeader.tsx | 16 ++- app/src/components/common/Tile.tsx | 13 ++- app/src/components/common/Tip.tsx | 104 ++++++++++++++++++ app/src/components/common/icons.tsx | 3 +- app/src/components/common/text.tsx | 2 +- app/src/components/layout/Layout.tsx | 15 ++- app/src/components/layout/Sidebar.tsx | 2 +- .../components/loop/processing/FailedSwap.tsx | 25 ++--- .../loop/processing/ProcessingSwaps.tsx | 17 +-- app/src/components/loop/swap/SwapWizard.tsx | 8 +- app/src/components/theme.tsx | 2 + app/src/i18n/locales/en-US.json | 8 ++ app/yarn.lock | 74 ++++++++++++- 18 files changed, 264 insertions(+), 62 deletions(-) create mode 100644 app/src/components/common/Tip.tsx diff --git a/app/package.json b/app/package.json index 8ab1b5af2..b5d7c3f44 100644 --- a/app/package.json +++ b/app/package.json @@ -32,6 +32,7 @@ "mobx": "5.15.4", "mobx-react-lite": "2.0.6", "mobx-utils": "5.5.7", + "rc-tooltip": "4.2.0", "react": "^16.13.1", "react-dom": "^16.13.1", "react-i18next": "11.4.0", diff --git a/app/src/App.scss b/app/src/App.scss index accde9a75..1d5f6dec4 100644 --- a/app/src/App.scss +++ b/app/src/App.scss @@ -14,6 +14,9 @@ @import '../node_modules/bootstrap/scss/grid'; @import '../node_modules/bootstrap/scss/custom-forms'; +// rc-tooltip component styles +@import '../node_modules/rc-tooltip/assets/bootstrap_white.css'; + @font-face { font-family: 'OpenSans Light'; src: url('./assets/fonts/OpenSans-Light.ttf') format('truetype'); diff --git a/app/src/assets/icons/bolt.svg b/app/src/assets/icons/bolt.svg index 3e747e6dd..a98273562 100644 --- a/app/src/assets/icons/bolt.svg +++ b/app/src/assets/icons/bolt.svg @@ -10,7 +10,7 @@ - + diff --git a/app/src/assets/icons/menu.svg b/app/src/assets/icons/menu.svg index 8574e8b8b..ab0e97410 100644 --- a/app/src/assets/icons/menu.svg +++ b/app/src/assets/icons/menu.svg @@ -10,7 +10,7 @@ - + diff --git a/app/src/components/NodeStatus.tsx b/app/src/components/NodeStatus.tsx index 343d19182..fee5434a0 100644 --- a/app/src/components/NodeStatus.tsx +++ b/app/src/components/NodeStatus.tsx @@ -4,6 +4,7 @@ import { usePrefixedTranslation } from 'hooks'; import { useStore } from 'store'; import { HeaderFour, Jumbo, Small } from 'components/common/text'; import { Bitcoin, Bolt } from './common/icons'; +import Tip from './common/Tip'; import Unit from './common/Unit'; import { styled } from './theme'; @@ -31,18 +32,22 @@ const NodeStatus: React.FC = () => { return ( {l('title')} - - - - - - - - - - - - + + + + + + + + + + + + + + + + ); diff --git a/app/src/components/common/PageHeader.tsx b/app/src/components/common/PageHeader.tsx index 302ba9e8e..90ff7b484 100644 --- a/app/src/components/common/PageHeader.tsx +++ b/app/src/components/common/PageHeader.tsx @@ -1,8 +1,10 @@ import React from 'react'; import { observer } from 'mobx-react-lite'; +import { usePrefixedTranslation } from 'hooks'; import { styled } from 'components/theme'; import { ArrowLeft, Clock, Download } from './icons'; import { HeaderThree } from './text'; +import Tip from './Tip'; const Styled = { Wrapper: styled.div` @@ -52,6 +54,8 @@ const PageHeader: React.FC = ({ onHistoryClick, onExportClick, }) => { + const { l } = usePrefixedTranslation('cmps.common.PageHeader'); + const { Wrapper, Left, Center, Right, BackLink } = Styled; return ( @@ -67,8 +71,16 @@ const PageHeader: React.FC = ({ {title} - {onHistoryClick && } - {onExportClick && } + {onHistoryClick && ( + + + + )} + {onExportClick && ( + + + + )} ); diff --git a/app/src/components/common/Tile.tsx b/app/src/components/common/Tile.tsx index 0ea0fc211..b3f4d0e8c 100644 --- a/app/src/components/common/Tile.tsx +++ b/app/src/components/common/Tile.tsx @@ -1,7 +1,9 @@ import React, { ReactNode } from 'react'; +import { usePrefixedTranslation } from 'hooks'; import { styled } from 'components/theme'; import { Maximize } from './icons'; import { HeaderFour } from './text'; +import Tip from './Tip'; const Styled = { TileWrap: styled.div` @@ -19,11 +21,9 @@ const Styled = { height: 20px; padding: 4px; margin-top: -5px; - cursor: pointer; &:hover { border-radius: 24px; - background-color: ${props => props.theme.colors.purple}; } `, Text: styled.div` @@ -52,13 +52,18 @@ interface Props { } const Tile: React.FC = ({ title, text, onMaximizeClick, children }) => { - const { TileWrap, Header, MaximizeIcon, Text } = Styled; + const { l } = usePrefixedTranslation('cmps.common.Tile'); + const { TileWrap, Header, MaximizeIcon, Text } = Styled; return (
{title} - {onMaximizeClick && } + {onMaximizeClick && ( + + + + )}
{text ? {text} : children}
diff --git a/app/src/components/common/Tip.tsx b/app/src/components/common/Tip.tsx new file mode 100644 index 000000000..5022896cb --- /dev/null +++ b/app/src/components/common/Tip.tsx @@ -0,0 +1,104 @@ +import React from 'react'; +import Tooltip from 'rc-tooltip'; +import { TooltipProps } from 'rc-tooltip/lib/Tooltip'; +import { styled } from 'components/theme'; + +/** + * Returns an offset array to create a 10px gap between the + * tooltip arrow and the target element + * @param placement the placement of the tooltip + */ +const getOffset = (placement: string) => { + let offset: number[] | undefined = undefined; + + switch (placement) { + case 'top': + case 'topLeft': + case 'topRight': + offset = [0, 10]; + break; + case 'bottom': + case 'bottomLeft': + case 'bottomRight': + offset = [0, -10]; + break; + case 'left': + offset = [10, 0]; + break; + case 'right': + offset = [-10, 0]; + break; + } + + return offset; +}; + +interface Props extends TooltipProps { + className?: string; +} + +/** + * Wrap the Tooltip component to add some reusable configuration + * for all tooltips throughout the entire site and to pass + * className as overlayClassName to the Tooltip component + */ +const TooltipWrapper: React.FC = ({ + className, + placement = 'top', + children, + ...props +}) => { + const targetOffset = getOffset(placement); + return ( + + {children} + + ); +}; + +/** + * Style our wrapper component so that our styles can be passed into the + * `overlayClassName` prop of the Tooltip component. We cannot style the + * Tooltip component directly because it does not accept a `className` + * prop. So we basically proxy the className using the TooltipWrapper + * above, then export this styled component for the rest of the app to use + */ +const Tip = styled(TooltipWrapper)` + color: ${props => props.theme.colors.blue}; + font-family: ${props => props.theme.fonts.open.semiBold}; + font-size: ${props => props.theme.sizes.xs}; + text-transform: uppercase; + opacity: 0.95; + + &.rc-tooltip-placement-bottom .rc-tooltip-arrow, + &.rc-tooltip-placement-bottomLeft .rc-tooltip-arrow, + &.rc-tooltip-placement-bottomRight .rc-tooltip-arrow { + border-bottom-color: ${props => props.theme.colors.white}; + } + + &.rc-tooltip-placement-top .rc-tooltip-arrow, + &.rc-tooltip-placement-topLeft .rc-tooltip-arrow, + &.rc-tooltip-placement-topRight .rc-tooltip-arrow { + border-top-color: ${props => props.theme.colors.white}; + } + + &.rc-tooltip-placement-left .rc-tooltip-arrow { + border-left-color: ${props => props.theme.colors.white}; + } + + &.rc-tooltip-placement-right .rc-tooltip-arrow { + border-right-color: ${props => props.theme.colors.white}; + } + + .rc-tooltip-inner { + text-align: center; + border: 1px solid ${props => props.theme.colors.white}; + } +`; + +export default Tip; diff --git a/app/src/components/common/icons.tsx b/app/src/components/common/icons.tsx index c4e1f05d6..7448934f0 100644 --- a/app/src/components/common/icons.tsx +++ b/app/src/components/common/icons.tsx @@ -29,7 +29,8 @@ const Icon = styled.span` border-radius: 36px; cursor: pointer; &:hover { - background-color: ${props.theme.colors.purple}; + color: ${props.theme.colors.blue}; + background-color: ${props.theme.colors.offWhite}; } `} diff --git a/app/src/components/common/text.tsx b/app/src/components/common/text.tsx index 8b5c8a90f..9f6cd57a2 100644 --- a/app/src/components/common/text.tsx +++ b/app/src/components/common/text.tsx @@ -38,7 +38,7 @@ export const HeaderFive = styled.h5` font-size: ${props => props.theme.sizes.m}; `; -export const Small = styled.p` +export const Small = styled.span` font-size: ${props => props.theme.sizes.xs}; line-height: 20px; `; diff --git a/app/src/components/layout/Layout.tsx b/app/src/components/layout/Layout.tsx index 51ae7e6d6..4e9b989c2 100644 --- a/app/src/components/layout/Layout.tsx +++ b/app/src/components/layout/Layout.tsx @@ -21,13 +21,16 @@ const Styled = { Hamburger: styled.span` display: inline-block; position: absolute; - top: 20px; - left: 20px; + top: 35px; + left: 10px; z-index: 1; - cursor: pointer; + padding: 4px; &:hover { - opacity: 0.8; + color: ${props => props.theme.colors.blue}; + background-color: ${props => props.theme.colors.offWhite}; + border-radius: 24px; + cursor: pointer; } `, Aside: styled.aside` @@ -49,7 +52,7 @@ const Styled = { `, Content: styled.div` margin-left: ${props => (props.collapsed ? '0' : '285px')}; - padding: 15px; + padding: 0 15px; transition: all 0.2s; `, }; @@ -62,7 +65,7 @@ const Layout: React.FC = ({ children }) => { - +