From ab0838e27210f871d105b16a49baa246ee750442 Mon Sep 17 00:00:00 2001 From: Mike Cao Date: Thu, 15 Jun 2023 20:15:31 -0700 Subject: [PATCH] Fixed issue with hover tooltips. --- components/common/HoverTooltip.js | 6 +-- components/common/HoverTooltip.module.css | 39 +------------------ components/common/WorldMap.js | 6 +-- components/input/LanguageButton.js | 3 +- components/input/LanguageButton.module.css | 2 +- components/input/LogoutButton.js | 6 +-- components/input/RefreshButton.js | 6 +-- components/layout/AppLayout.module.css | 1 + components/layout/NavGroup.js | 6 +-- components/metrics/BarChart.js | 10 ++--- components/metrics/BarChart.module.css | 6 --- components/metrics/EventsChart.js | 4 +- components/metrics/PageviewsChart.js | 4 +- components/pages/reports/ReportHeader.js | 2 +- .../pages/reports/funnel/FunnelChart.js | 8 ++-- .../pages/reports/funnel/FunnelParameters.js | 10 ++--- hooks/useCountryNames.js | 4 +- lib/charts.js | 8 ++-- package.json | 2 +- yarn.lock | 8 ++-- 20 files changed, 50 insertions(+), 91 deletions(-) diff --git a/components/common/HoverTooltip.js b/components/common/HoverTooltip.js index 59fd6277..614841df 100644 --- a/components/common/HoverTooltip.js +++ b/components/common/HoverTooltip.js @@ -18,9 +18,9 @@ export function HoverTooltip({ children }) { }, []); return ( -
- -
+ + {children} + ); } diff --git a/components/common/HoverTooltip.module.css b/components/common/HoverTooltip.module.css index ec1abc1c..c4bb76ea 100644 --- a/components/common/HoverTooltip.module.css +++ b/components/common/HoverTooltip.module.css @@ -1,43 +1,6 @@ -.chart { - position: relative; -} - .tooltip { position: fixed; pointer-events: none; z-index: var(--z-index-popup); -} - -.content { - display: flex; - flex-direction: column; - justify-content: center; - align-items: center; - text-align: center; -} - -.title { - font-size: var(--font-size-xs); - font-weight: 600; -} - -.metric { - display: flex; - justify-content: center; - align-items: center; - font-size: var(--font-size-sm); - font-weight: 600; -} - -.dot { - position: relative; - overflow: hidden; - border-radius: 100%; - margin-right: 8px; - background: var(--base50); -} - -.color { - width: 10px; - height: 10px; + transform: translate(-50%, calc(-100% - 5px)); } diff --git a/components/common/WorldMap.js b/components/common/WorldMap.js index 985160d8..9c91e4a4 100644 --- a/components/common/WorldMap.js +++ b/components/common/WorldMap.js @@ -14,7 +14,7 @@ import styles from './WorldMap.module.css'; export function WorldMap({ data, className }) { const { basePath } = useRouter(); - const [tooltip, setTooltip] = useState(); + const [tooltip, setTooltipPopup] = useState(); const { theme, colors } = useTheme(); const { locale } = useLocale(); const countryNames = useCountryNames(locale); @@ -40,7 +40,7 @@ export function WorldMap({ data, className }) { function handleHover(code) { if (code === 'AQ') return; const country = metrics?.find(({ x }) => x === code); - setTooltip(`${countryNames[code]}: ${formatLongNumber(country?.y || 0)} visitors`); + setTooltipPopup(`${countryNames[code]}: ${formatLongNumber(country?.y || 0)} visitors`); } return ( @@ -69,7 +69,7 @@ export function WorldMap({ data, className }) { pressed: { outline: 'none' }, }} onMouseOver={() => handleHover(code)} - onMouseOut={() => setTooltip(null)} + onMouseOut={() => setTooltipPopup(null)} /> ); }); diff --git a/components/input/LanguageButton.js b/components/input/LanguageButton.js index 049b49f3..d4c1cbc3 100644 --- a/components/input/LanguageButton.js +++ b/components/input/LanguageButton.js @@ -9,7 +9,8 @@ export function LanguageButton() { const { locale, saveLocale, dir } = useLocale(); const items = Object.keys(languages).map(key => ({ ...languages[key], value: key })); - function handleSelect(value, close) { + function handleSelect(value, close, e) { + e.stopPropagation(); saveLocale(value); close(); } diff --git a/components/input/LanguageButton.module.css b/components/input/LanguageButton.module.css index e46729c0..3d4c0c56 100644 --- a/components/input/LanguageButton.module.css +++ b/components/input/LanguageButton.module.css @@ -1,7 +1,7 @@ .menu { display: flex; flex-flow: row wrap; - max-width: 640px; + min-width: 640px; padding: 10px; background: var(--base50); z-index: var(--z-index-popup); diff --git a/components/input/LogoutButton.js b/components/input/LogoutButton.js index 3314956e..4a15cd68 100644 --- a/components/input/LogoutButton.js +++ b/components/input/LogoutButton.js @@ -1,4 +1,4 @@ -import { Button, Icon, Icons, Tooltip } from 'react-basics'; +import { Button, Icon, Icons, TooltipPopup } from 'react-basics'; import Link from 'next/link'; import useMessages from 'hooks/useMessages'; @@ -6,13 +6,13 @@ export function LogoutButton({ tooltipPosition = 'top' }) { const { formatMessage, labels } = useMessages(); return ( - + - + ); } diff --git a/components/input/RefreshButton.js b/components/input/RefreshButton.js index b3e2b815..444f3247 100644 --- a/components/input/RefreshButton.js +++ b/components/input/RefreshButton.js @@ -1,4 +1,4 @@ -import { LoadingButton, Icon, Tooltip } from 'react-basics'; +import { LoadingButton, Icon, TooltipPopup } from 'react-basics'; import { setWebsiteDateRange } from 'store/websites'; import useDateRange from 'hooks/useDateRange'; import Icons from 'components/icons'; @@ -19,13 +19,13 @@ export function RefreshButton({ websiteId, isLoading }) { } return ( - + - + ); } diff --git a/components/layout/AppLayout.module.css b/components/layout/AppLayout.module.css index 6cc9e414..a83039ce 100644 --- a/components/layout/AppLayout.module.css +++ b/components/layout/AppLayout.module.css @@ -2,6 +2,7 @@ display: grid; grid-template-rows: max-content 1fr; grid-template-columns: 1fr; + overflow: hidden; } .nav { diff --git a/components/layout/NavGroup.js b/components/layout/NavGroup.js index b9e7155d..94f9d8e6 100644 --- a/components/layout/NavGroup.js +++ b/components/layout/NavGroup.js @@ -1,5 +1,5 @@ import { useState } from 'react'; -import { Icon, Text, Tooltip } from 'react-basics'; +import { Icon, Text, TooltipPopup } from 'react-basics'; import classNames from 'classnames'; import { useRouter } from 'next/router'; import Link from 'next/link'; @@ -36,7 +36,7 @@ export function NavGroup({
{items.map(({ label, url, icon, divider }) => { return ( - + {icon} {label} - + ); })}
diff --git a/components/metrics/BarChart.js b/components/metrics/BarChart.js index 2aba3ea5..c086017e 100644 --- a/components/metrics/BarChart.js +++ b/components/metrics/BarChart.js @@ -20,14 +20,14 @@ export function BarChart({ renderYLabel, XAxisType = 'time', YAxisType = 'linear', - renderTooltip, + renderTooltipPopup, onCreate, onUpdate, className, }) { const canvas = useRef(); const chart = useRef(null); - const [tooltip, setTooltip] = useState(null); + const [tooltip, setTooltipPopup] = useState(null); const { locale } = useLocale(); const { theme, colors } = useTheme(); @@ -50,7 +50,7 @@ export function BarChart({ }, tooltip: { enabled: false, - external: renderTooltip ? renderTooltip.bind(null, setTooltip) : undefined, + external: renderTooltipPopup ? renderTooltipPopup.bind(null, setTooltipPopup) : undefined, }, }, scales: { @@ -93,7 +93,7 @@ export function BarChart({ }; }, [ animationDuration, - renderTooltip, + renderTooltipPopup, renderXLabel, XAxisType, YAxisType, @@ -120,7 +120,7 @@ export function BarChart({ }; const updateChart = () => { - setTooltip(null); + setTooltipPopup(null); datasets.forEach((dataset, index) => { chart.current.data.datasets[index].data = dataset.data; diff --git a/components/metrics/BarChart.module.css b/components/metrics/BarChart.module.css index 850d1ea7..f2e26db1 100644 --- a/components/metrics/BarChart.module.css +++ b/components/metrics/BarChart.module.css @@ -13,9 +13,3 @@ .tooltip .value { text-transform: lowercase; } - -@media only screen and (max-width: 992px) { - .chart { - /*height: 200px;*/ - } -} diff --git a/components/metrics/EventsChart.js b/components/metrics/EventsChart.js index 334ee591..82b8c8f7 100644 --- a/components/metrics/EventsChart.js +++ b/components/metrics/EventsChart.js @@ -5,7 +5,7 @@ import BarChart from './BarChart'; import { getDateArray } from 'lib/date'; import { useApi, useLocale, useDateRange, useTimezone, usePageQuery } from 'hooks'; import { EVENT_COLORS } from 'lib/constants'; -import { renderDateLabels, renderStatusTooltip } from 'lib/charts'; +import { renderDateLabels, renderStatusTooltipPopup } from 'lib/charts'; export function EventsChart({ websiteId, className, token }) { const { get, useQuery } = useApi(); @@ -72,7 +72,7 @@ export function EventsChart({ websiteId, className, token }) { loading={isLoading} stacked renderXLabel={renderDateLabels(unit, locale)} - renderTooltip={renderStatusTooltip(unit, locale)} + renderTooltipPopup={renderStatusTooltipPopup(unit, locale)} /> ); } diff --git a/components/metrics/PageviewsChart.js b/components/metrics/PageviewsChart.js index bf56a0bd..362c616e 100644 --- a/components/metrics/PageviewsChart.js +++ b/components/metrics/PageviewsChart.js @@ -1,7 +1,7 @@ import { useMemo } from 'react'; import BarChart from './BarChart'; import { useLocale, useTheme, useMessages } from 'hooks'; -import { renderDateLabels, renderStatusTooltip } from 'lib/charts'; +import { renderDateLabels, renderStatusTooltipPopup } from 'lib/charts'; export function PageviewsChart({ websiteId, data, unit, className, loading, ...props }) { const { formatMessage, labels } = useMessages(); @@ -36,7 +36,7 @@ export function PageviewsChart({ websiteId, data, unit, className, loading, ...p unit={unit} loading={loading} renderXLabel={renderDateLabels(unit, locale)} - renderTooltip={renderStatusTooltip(unit, locale)} + renderTooltipPopup={renderStatusTooltipPopup(unit, locale)} /> ); } diff --git a/components/pages/reports/ReportHeader.js b/components/pages/reports/ReportHeader.js index 0b2054d0..7de45d9a 100644 --- a/components/pages/reports/ReportHeader.js +++ b/components/pages/reports/ReportHeader.js @@ -39,7 +39,7 @@ export function ReportHeader({ icon }) { }; const handleNameChange = name => { - updateReport({ name }); + updateReport({ name: name || 'Untitled' }); }; const handleDescriptionChange = description => { diff --git a/components/pages/reports/funnel/FunnelChart.js b/components/pages/reports/funnel/FunnelChart.js index 3dfeb19e..7253c3fa 100644 --- a/components/pages/reports/funnel/FunnelChart.js +++ b/components/pages/reports/funnel/FunnelChart.js @@ -21,15 +21,15 @@ export function FunnelChart({ className, loading }) { [parameters], ); - const renderTooltip = useCallback((setTooltip, model) => { + const renderTooltipPopup = useCallback((setTooltipPopup, model) => { const { opacity, dataPoints } = model.tooltip; if (!dataPoints?.length || !opacity) { - setTooltip(null); + setTooltipPopup(null); return; } - setTooltip(`${formatLongNumber(dataPoints[0].raw.y)} ${formatMessage(labels.visitors)}`); + setTooltipPopup(`${formatLongNumber(dataPoints[0].raw.y)} ${formatMessage(labels.visitors)}`); }, []); const datasets = useMemo(() => { @@ -54,7 +54,7 @@ export function FunnelChart({ className, loading }) { unit="day" loading={loading} renderXLabel={renderXLabel} - renderTooltip={renderTooltip} + renderTooltipPopup={renderTooltipPopup} XAxisType="category" /> ); diff --git a/components/pages/reports/funnel/FunnelParameters.js b/components/pages/reports/funnel/FunnelParameters.js index 77f0fdf5..4c788798 100644 --- a/components/pages/reports/funnel/FunnelParameters.js +++ b/components/pages/reports/funnel/FunnelParameters.js @@ -11,7 +11,7 @@ import { SubmitButton, Text, TextField, - Tooltip, + TooltipPopup, } from 'react-basics'; import Icons from 'components/icons'; import UrlAddForm from './UrlAddForm'; @@ -62,7 +62,7 @@ export function FunnelParameters() { return (
{url} - - +
); })} @@ -90,11 +90,11 @@ function AddUrlButton({ onAdd }) { return ( - + - + {close => { return ; diff --git a/hooks/useCountryNames.js b/hooks/useCountryNames.js index 60c992a5..51cabf34 100644 --- a/hooks/useCountryNames.js +++ b/hooks/useCountryNames.js @@ -1,6 +1,6 @@ import { useState, useEffect } from 'react'; import { useRouter } from 'next/router'; -import { get } from 'next-basics'; +import { httpGet } from 'next-basics'; import enUS from 'public/intl/country/en-US.json'; const countryNames = { @@ -12,7 +12,7 @@ export function useCountryNames(locale) { const { basePath } = useRouter(); async function loadData(locale) { - const { data } = await get(`${basePath}/intl/country/${locale}.json`); + const { data } = await httpGet(`${basePath}/intl/country/${locale}.json`); if (data) { countryNames[locale] = data; diff --git a/lib/charts.js b/lib/charts.js index c9d54218..0571a9a9 100644 --- a/lib/charts.js +++ b/lib/charts.js @@ -27,12 +27,12 @@ export function renderDateLabels(unit, locale) { }; } -export function renderStatusTooltip(unit, locale) { - return (setTooltip, model) => { +export function renderStatusTooltipPopup(unit, locale) { + return (setTooltipPopup, model) => { const { opacity, labelColors, dataPoints } = model.tooltip; if (!dataPoints?.length || !opacity) { - setTooltip(null); + setTooltipPopup(null); return; } @@ -48,7 +48,7 @@ export function renderStatusTooltip(unit, locale) { year: 'yyyy', }; - setTooltip( + setTooltipPopup( <>
{dateFormat(new Date(dataPoints[0].raw.x), formats[unit], locale)}
diff --git a/package.json b/package.json index 5cfc9823..3bf8343f 100644 --- a/package.json +++ b/package.json @@ -95,7 +95,7 @@ "node-fetch": "^3.2.8", "npm-run-all": "^4.1.5", "react": "^18.2.0", - "react-basics": "^0.84.0", + "react-basics": "^0.85.0", "react-beautiful-dnd": "^13.1.0", "react-dom": "^18.2.0", "react-error-boundary": "^4.0.4", diff --git a/yarn.lock b/yarn.lock index aa847d57..55adc5e8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8191,10 +8191,10 @@ rc@^1.2.7: minimist "^1.2.0" strip-json-comments "~2.0.1" -react-basics@^0.84.0: - version "0.84.0" - resolved "https://registry.yarnpkg.com/react-basics/-/react-basics-0.84.0.tgz#cfea2ae6b64d9318406a0c6cf0d5d9e8a0790a28" - integrity sha512-QWnUkw7kVbBK0Z1xvvsNgrUBlUI0FzL39jQAZR5EutE83BlkAtYeisXooPZk3PJuGHZzJvY6+JzMYmvALLjqnQ== +react-basics@^0.85.0: + version "0.85.0" + resolved "https://registry.yarnpkg.com/react-basics/-/react-basics-0.85.0.tgz#407c413e56b004120b5e11074a7d9f17a697c6b7" + integrity sha512-RPxYiMdOmlWZXh2tKbUay97lsOFWtNYTzx5Jpcd9IUxBrNzYWgTCgtSHJLHAuycUCDNVepX+do+HdRG3uMkE0Q== dependencies: classnames "^2.3.1" date-fns "^2.29.3"