Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Show tooltips on hovering over icons with no labels #3711

Merged
merged 5 commits into from
Dec 20, 2023
Merged
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion ui/_locales/en/messages.json
Original file line number Diff line number Diff line change
@@ -340,6 +340,7 @@
"networksBanner": "Not seeing NFTs from all your networks? Activate a network by switching to it on the Wallet tab.",
"filters": {
"title": "Filter collections",
"tooltip": "Filter",
"warning": "Changing filters here will affect your Portfolio page as well.",
"sortType": {
"priceDesc": "Floor price: Descending",
@@ -620,6 +621,7 @@
"connectedWebsitesSettings": {
"title": "Connected websites",
"disconnected": "Website disconnected",
"disconnectTooltip": "Disconnect website",
"ariaLabel": "Manage connected websites",
"emptyList": "Not connected to any websites"
},
@@ -804,6 +806,7 @@
},
"topMenu": {
"showCurrentDappConnection": "Show current website connection",
"currentDappConnection": "Current website connection",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would change it to have it in one line - Dapp connection or something like that? cc @VladUXUI
image

"connectToWebsiteUsing": "Connect to website using:",
"setTahoAsDefault": "Set Taho as default",
"setOtherAsDefault": "Set MetaMask/other wallet as default",
@@ -818,6 +821,7 @@
"connectedDappInfo": {
"dAppTitle": "Account connected to",
"dappConnections": "Website connections",
"disconnectDapp": "Disconnect Dapp",
"guideline": {
"title": "How to connect to websites",
"step1": "Connect using Taho",
@@ -963,7 +967,7 @@
"submitSpamBtn": "Yes, report & delete",
"snackbar": "Ability deleted"
},
"filter": {
"filters": {
"title": "Filter Abilities",
"tooltip": "Filter",
"abilityState": {
7 changes: 4 additions & 3 deletions ui/_locales/es/messages.json
Original file line number Diff line number Diff line change
@@ -68,10 +68,11 @@
"bugReport": "Informe de errores",
"connectedWebsites": "Sitios Web a los que está conectado",
"connectedWebsitesSettings": {
"ariaLabel": "Administrar sitios web conectados",
"title": "Sitios web a los que está conectado",
"disconnected": "Sitios web desconectados",
"emptyList": "No está conectado a ningún sitio web",
"title": "Sitios web a los que está conectado"
"disconnectTooltip": "Desconectar sitios web",
"ariaLabel": "Administrar sitios web conectados",
"emptyList": "No está conectado a ningún sitio web"
},
"enableTestNetworks": "Habilitar redes de prueba",
"exportLogs": {
7 changes: 4 additions & 3 deletions ui/_locales/zh_Hant/messages.json
Original file line number Diff line number Diff line change
@@ -69,10 +69,11 @@
"bugReport": "問題回報",
"connectedWebsites": "已連結的網站",
"connectedWebsitesSettings": {
"ariaLabel": "管理已連結的網站",
"title": "已連結的網站",
"disconnected": "網站已斷開",
"emptyList": "尚未與任何網站連結",
"title": "已連結的網站"
"disconnectTooltip": "斷開網站連接",
"ariaLabel": "管理已連結的網站",
"emptyList": "尚未與任何網站連結"
},
"enableTestNetworks": "啟用測試網路",
"exportLogs": {
32 changes: 23 additions & 9 deletions ui/components/DAppConnection/ActiveDAppConnection.tsx
Original file line number Diff line number Diff line change
@@ -4,6 +4,7 @@ import React, { ReactElement, useCallback, useState } from "react"
import { useTranslation } from "react-i18next"
import { useBackgroundDispatch } from "../../hooks"
import TopMenuConnectedDAppInfo from "../TopMenu/TopMenuConnectedDAppInfo"
import SharedTooltip from "../Shared/SharedTooltip"

type Props = {
isConnectedToDApp: boolean
@@ -54,16 +55,29 @@ export default function ActiveDAppConnection({
isConnected={isConnectedToDApp}
/>
) : null}
<button
type="button"
aria-label={t("showCurrentDappConnection")}
className="connection_button"
onClick={() => {
setIsActiveDAppConnectionInfoOpen(!isActiveDAppConnectionInfoOpen)
}}
<SharedTooltip
type="dark"
width={160}
horizontalShift={160}
verticalShift={-15}
verticalPosition="bottom"
horizontalPosition="left"
IconComponent={() => (
<button
type="button"
aria-label={t("showCurrentDappConnection")}
className="connection_button"
onClick={() => {
setIsActiveDAppConnectionInfoOpen(!isActiveDAppConnectionInfoOpen)
}}
>
<div className="connection_img" />
</button>
)}
>
<div className="connection_img" />
</button>
{t("currentDappConnection")}
</SharedTooltip>

<style jsx>{`
.connection_button {
width: 32px;
25 changes: 6 additions & 19 deletions ui/components/NFTs/NFTsHeader.tsx
Original file line number Diff line number Diff line change
@@ -12,9 +12,9 @@ import {
import SharedLoadingSpinner from "../Shared/SharedLoadingSpinner"
import { HeaderContainer, EmptyHeader } from "./NFTsHeaderBase"
import { useBackgroundSelector, useTotalNFTsFloorPrice } from "../../hooks"
import SharedIcon from "../Shared/SharedIcon"
import SharedSlideUpMenu from "../Shared/SharedSlideUpMenu"
import NFTsFilters from "./Filters/NFTsFilters"
import SharedFilterTooltip from "../Shared/SharedFilterTooltip"

export default function NFTsHeader(): ReactElement {
const { t } = useTranslation("translation", {
@@ -60,17 +60,11 @@ export default function NFTsHeader(): ReactElement {
<div className="stats_container">
<div className="stats_title">{t("header.title")}</div>
{allNftCount > 0 && (
<div className="filters_container">
<SharedIcon
width={24}
icon="toggle.svg"
ariaLabel={t("filters.title")}
color="var(--green-40)"
hoverColor="var(--green-20)"
onClick={handleToggleClick}
disabled={isLoading}
/>
</div>
<SharedFilterTooltip
keyPrefix="nfts"
isOpen={openFiltersMenu}
setIsOpen={setOpenFiltersMenu}
/>
)}
<div className="stats_totals">
<span className="currency_sign">{mainCurrencySign}</span>
@@ -123,13 +117,6 @@ export default function NFTsHeader(): ReactElement {
color: var(--green-20);
}

.filters_container {
position: absolute;
width: 90vw;
display: flex;
justify-content: end;
}

.stats_spinner {
position: absolute;
right: -25px;
60 changes: 60 additions & 0 deletions ui/components/Shared/SharedFilterTooltip.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import React, { Dispatch, SetStateAction, useCallback } from "react"
import { KeyPrefix, useTranslation } from "react-i18next"
import SharedTooltip from "./SharedTooltip"
import SharedIcon from "./SharedIcon"

type SharedFilterTooltipProps = {
keyPrefix: KeyPrefix<"translation">
isOpen: boolean
setIsOpen: Dispatch<SetStateAction<boolean>>
}

export default function SharedFilterTooltip({
keyPrefix,
isOpen,
setIsOpen,
}: SharedFilterTooltipProps) {
const { t } = useTranslation("translation", {
keyPrefix,
})

const handleToggleClick = useCallback(() => {
setIsOpen((currentlyOpen) => !currentlyOpen)
}, [setIsOpen])

return (
<>
<div className="filters_container">
<SharedTooltip
width={36}
height={32}
verticalPosition="bottom"
horizontalPosition="center"
horizontalShift={8}
type="dark"
isOpen={isOpen}
IconComponent={() => (
<SharedIcon
width={24}
icon="toggle.svg"
ariaLabel={t("filters.title")}
color="var(--green-40)"
hoverColor="var(--green-20)"
onClick={handleToggleClick}
/>
)}
>
{t("filters.tooltip")}
</SharedTooltip>
</div>
<style jsx>{`
.filters_container {
position: absolute;
width: 90vw;
display: flex;
justify-content: end;
}
`}</style>
</>
)
}
47 changes: 34 additions & 13 deletions ui/components/Shared/SharedIconRouterLink.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
import React, { ReactElement } from "react"
import { Link } from "react-router-dom"
import SharedTooltip from "./SharedTooltip"

type Props = {
path: string
state: { [key: string]: unknown }
iconClass: string
disabled?: boolean
isTooltip?: boolean
tooltipText?: string
}

export default function SharedIconRouterLink(props: Props): ReactElement {
const { path, state, iconClass, disabled } = props
const { path, state, iconClass, disabled, isTooltip, tooltipText } = props

if (disabled) {
return (
@@ -28,16 +31,33 @@ export default function SharedIconRouterLink(props: Props): ReactElement {
}

return (
<Link
to={{
pathname: path,
state,
}}
className="router_link_container"
>
<div className="icon_wrapper">
<i className={`asset_icon hoverable ${iconClass}`} />
</div>
<>
{isTooltip && tooltipText ? (
<SharedTooltip
type="dark"
horizontalPosition="center"
verticalPosition="top"
verticalShift={-10}
IconComponent={() => (
<Link
to={{ pathname: path, state }}
className="router_link_container"
>
<div className="icon_wrapper">
<i className={`asset_icon hoverable ${iconClass}`} />
</div>
</Link>
)}
>
{tooltipText}
</SharedTooltip>
) : (
<Link to={{ pathname: path, state }} className="router_link_container">
<div className="icon_wrapper">
<i className={`asset_icon hoverable ${iconClass}`} />
</div>
</Link>
)}
<style jsx global>{`
.router_link_container {
margin: auto 4px;
@@ -46,21 +66,22 @@ export default function SharedIconRouterLink(props: Props): ReactElement {
.icon_wrapper {
display: flex;
padding: 0.5em;
border-radius: 4px;
}
.disabled_asset_icon {
mask-size: cover;
background-color: var(--green-60);
width: 12px;
height: 12px;
}
.router_link_container:hover {
.router_link_container:hover .icon_wrapper {
background-color: var(--hunter-green);
color: var(--trophy-gold);
}
.router_link_container:hover .asset_icon {
background-color: var(--trophy-gold);
}
`}</style>
</Link>
</>
)
}
8 changes: 5 additions & 3 deletions ui/components/Shared/SharedTooltip.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import classNames from "classnames"
import React, { ReactElement, useEffect, useState } from "react"
import React, { CSSProperties, ReactElement, useEffect, useState } from "react"

type VerticalPosition = "top" | "bottom"
type HorizontalPosition = "left" | "center" | "right"
@@ -15,7 +15,8 @@ interface Props {
isOpen?: boolean
disabled?: boolean
children: React.ReactNode
customStyles?: React.CSSProperties & Record<string, string>
customStyles?: CSSProperties & Record<string, string>
style?: CSSProperties
// TODO: find a better way to tell the IconComponent that the tooltip it open
IconComponent?: ({
isShowingTooltip,
@@ -70,6 +71,7 @@ export default function SharedTooltip(props: Props): ReactElement {
disabled = false,
IconComponent,
customStyles = {},
style,
} = props
const [isShowingTooltip, setIsShowingTooltip] = useState(isOpen)

@@ -87,7 +89,7 @@ export default function SharedTooltip(props: Props): ReactElement {
onMouseLeave={() => {
setIsShowingTooltip(false)
}}
style={customStyles}
style={{ ...style, ...customStyles }}
>
{IconComponent ? (
<IconComponent isShowingTooltip={isShowingTooltip} />
26 changes: 19 additions & 7 deletions ui/components/TopMenu/TopMenuConnectedDAppInfo.tsx
Original file line number Diff line number Diff line change
@@ -6,6 +6,7 @@ import DAppConnectionDefaultToggle from "../DAppConnection/DAppConnectionDefault
import SharedAccordion from "../Shared/SharedAccordion"
import SharedLink from "../Shared/SharedLink"
import SharedPanelSwitcher from "../Shared/SharedPanelSwitcher"
import SharedTooltip from "../Shared/SharedTooltip"

function ConnectionDAppGuideline({
isConnected,
@@ -245,12 +246,23 @@ export default function TopMenuConnectedDAppInfo(props: {
<div className="url text ellipsis" title={url}>
{url}
</div>
<button
aria-label="disconnect"
type="button"
className="disconnect_icon"
onClick={disconnect}
/>
<SharedTooltip
width={120}
verticalPosition="bottom"
horizontalPosition="center"
verticalShift={-20}
type="dark"
IconComponent={() => (
<button
aria-label="disconnect"
type="button"
className="disconnect_icon"
onClick={disconnect}
/>
)}
>
{t("disconnectDapp")}
</SharedTooltip>
</div>
</div>
<ConnectionDAppGuideline isConnected={isConnected} />
@@ -351,7 +363,7 @@ export default function TopMenuConnectedDAppInfo(props: {
background-size: cover;
width: 16px;
height: 18px;
margin: 16px 0 32px;
margin: 16px 0 40px;
}
.dAppInfo_wrap {
width: 100%;
Loading