import React, { type MouseEvent, useCallback, useMemo, ElementType } from 'react'; import { getGlobalMetricType, getMetricRunInfo } from '@bundle-stats/utils'; import { Focusable } from 'ariakit/focusable'; import { Stack } from '../../layout/stack'; import { FlexStack } from '../../layout/flex-stack'; import { Icon } from '../../ui/icon'; import { RunInfo, RunInfoProps } from '../run-info'; import css from './metric-run-info.module.css'; interface MetricInfoProps { title: string; description?: string; url?: string; } const MetricHoverCard = ({ title, description, url }: MetricInfoProps) => { // The component parent can be rendered inside a link or a button // use a focusable element with onClick to prevent DOM issues (a > button, a > a, etc) const onClick = useCallback( (event: MouseEvent) => { if (!url) { return; } event.preventDefault(); event.stopPropagation(); window.open(url); }, [url], ); return (

{title}

{description}

{url && (
Learn more
)}
); }; export interface MetricRunInfoProps { metricId: string; current: number; baseline?: number; showDelta?: boolean; showMetricDescription?: boolean; showBaseline?: boolean; titleWrapper?: ElementType; size?: RunInfoProps['size']; loading?: RunInfoProps['loading']; } export const MetricRunInfo = (props: MetricRunInfoProps & React.ComponentProps<'div'>) => { const { metricId, current, baseline = 0, showDelta = true, showMetricDescription = true, showBaseline = true, titleWrapper: CustomTitleWrapper = React.Fragment, ...restProps } = props; const metric = getGlobalMetricType(metricId); const metricRunInfo = getMetricRunInfo(metric, current, baseline || 0); const titleHoverCard = useMemo(() => { if (showMetricDescription && (metric.description || metric.url)) { return ( ); } return null; }, [showMetricDescription, metric]); const title = useMemo( () => {metric.label}, [CustomTitleWrapper, metric.label], ); const deltaProps = useMemo(() => { if (!showDelta || metric.skipDelta || !('delta' in metricRunInfo)) { return {}; } return { delta: metricRunInfo.displayDeltaPercentage, deltaType: metricRunInfo.deltaType, }; }, [metricRunInfo]); return ( ); };