Use FloatingTooltip from zen.

This commit is contained in:
Mike Cao 2025-03-13 17:52:45 -07:00
parent 556cc1b205
commit a9ba2504d7
9 changed files with 37 additions and 149 deletions

View file

@ -1,8 +1,8 @@
import { useMemo, useState } from 'react';
import { BarChartTooltip } from '@/components/charts/BarChartTooltip';
import { Chart, ChartProps } from '@/components/charts/Chart';
import { useTheme } from '@/components/hooks';
import { renderNumberLabels } from '@/lib/charts';
import { useMemo, useState } from 'react';
export interface BarChartProps extends ChartProps {
unit: string;

View file

@ -1,7 +1,7 @@
import { useLocale } from '@/components/hooks';
import { formatDate } from '@/lib/date';
import { formatLongCurrency, formatLongNumber } from '@/lib/format';
import { Flexbox, StatusLight } from '@umami/react-zen';
import { Column, Row, StatusLight, FloatingTooltip, TooltipBubble } from '@umami/react-zen';
const formats = {
millisecond: 'T',
@ -20,18 +20,25 @@ export function BarChartTooltip({ tooltip, unit, currency }) {
const { labelColors, dataPoints } = tooltip;
return (
<Flexbox direction="column" gap={10}>
<div>
{formatDate(new Date(dataPoints[0].raw.d || dataPoints[0].raw.x), formats[unit], locale)}
</div>
<div>
<StatusLight color={labelColors?.[0]?.backgroundColor}>
{currency
? formatLongCurrency(dataPoints[0].raw.y, currency)
: formatLongNumber(dataPoints[0].raw.y)}{' '}
{dataPoints[0].dataset.label}
</StatusLight>
</div>
</Flexbox>
<FloatingTooltip>
<TooltipBubble>
<Column gap="3" fontSize="1">
<Row alignItems="center">
{formatDate(
new Date(dataPoints[0].raw.d || dataPoints[0].raw.x),
formats[unit],
locale,
)}
</Row>
<Row alignItems="center">
<StatusLight color={labelColors?.[0]?.backgroundColor}>
{currency
? formatLongCurrency(dataPoints[0].raw.y, currency)
: `${formatLongNumber(dataPoints[0].raw.y)} ${dataPoints[0].dataset.label}`}
</StatusLight>
</Row>
</Column>
</TooltipBubble>
</FloatingTooltip>
);
}

View file

@ -2,7 +2,6 @@ import { useState, useRef, useEffect, useMemo, ReactNode } from 'react';
import { Loading } from '@umami/react-zen';
import classNames from 'classnames';
import ChartJS, { LegendItem, ChartOptions } from 'chart.js/auto';
import { HoverTooltip } from '@/components/common/HoverTooltip';
import { Legend } from '@/components/metrics/Legend';
import { DEFAULT_ANIMATION_DURATION } from '@/lib/constants';
import styles from './Chart.module.css';
@ -34,7 +33,7 @@ export function Chart({
className,
chartOptions,
}: ChartProps) {
const canvas = useRef();
const canvas = useRef(null);
const chart = useRef(null);
const [legendItems, setLegendItems] = useState([]);
@ -143,11 +142,7 @@ export function Chart({
<canvas ref={canvas} />
</div>
<Legend items={legendItems} onClick={handleLegendClick} />
{tooltip && (
<HoverTooltip>
<div className={styles.tooltip}>{tooltip}</div>
</HoverTooltip>
)}
{tooltip}
</>
);
}

View file

@ -1,6 +0,0 @@
.tooltip {
position: fixed;
pointer-events: none;
z-index: var(--z-index-popup);
transform: translate(-50%, calc(-100% - 5px));
}

View file

@ -1,25 +0,0 @@
import { ReactNode, useEffect, useState } from 'react';
import { Tooltip } from '@umami/react-zen';
import styles from './HoverTooltip.module.css';
export function HoverTooltip({ children }: { children: ReactNode }) {
const [position, setPosition] = useState({ x: -1000, y: -1000 });
useEffect(() => {
const handler = e => {
setPosition({ x: e.clientX, y: e.clientY });
};
document.addEventListener('mousemove', handler);
return () => {
document.removeEventListener('mousemove', handler);
};
}, []);
return (
<Tooltip className={styles.tooltip} style={{ left: position.x, top: position.y }}>
{children}
</Tooltip>
);
}

View file

@ -1,22 +0,0 @@
import { Button, Icon, Icons, TooltipPopup } from '@umami/react-zen';
import Link from 'next/link';
import { useMessages } from '@/components/hooks';
export function LogoutButton({
tooltipPosition = 'top',
}: {
tooltipPosition?: 'top' | 'bottom' | 'left' | 'right';
}) {
const { formatMessage, labels } = useMessages();
return (
<Link href="/src/app/logout/LogoutPage">
<TooltipPopup label={formatMessage(labels.logout)} position={tooltipPosition}>
<Button variant="quiet">
<Icon>
<Icons.Logout />
</Icon>
</Button>
</TooltipPopup>
</Link>
);
}

View file

@ -2,7 +2,6 @@ import { useState, useMemo, HTMLAttributes } from 'react';
import { ComposableMap, Geographies, Geography, ZoomableGroup } from 'react-simple-maps';
import classNames from 'classnames';
import { colord } from 'colord';
import { HoverTooltip } from '@/components/common/HoverTooltip';
import { ISO_COUNTRIES, MAP_FILE } from '@/lib/constants';
import { useDateRange, useTheme, useWebsiteMetrics } from '@/components/hooks';
import { useCountryNames } from '@/components/hooks';
@ -11,6 +10,7 @@ import { useMessages } from '@/components/hooks';
import { formatLongNumber } from '@/lib/format';
import { percentFilter } from '@/lib/filters';
import styles from './WorldMap.module.css';
import { FloatingTooltip } from '@umami/react-zen';
export function WorldMap({
websiteId,
@ -104,7 +104,7 @@ export function WorldMap({
</Geographies>
</ZoomableGroup>
</ComposableMap>
{tooltip && <HoverTooltip>{tooltip}</HoverTooltip>}
{tooltip && <FloatingTooltip>{tooltip}</FloatingTooltip>}
</div>
);
}