Do not bubble up legend click

This commit is contained in:
Nate Kelley 2025-09-09 22:22:32 -06:00
parent c221bf51e1
commit 5ece7d6838
No known key found for this signature in database
GPG Key ID: FD90372AB8D98B4F
2 changed files with 94 additions and 97 deletions

View File

@ -38,9 +38,7 @@ const chartJSThemefontFamily = isServer
const chartJSThemecolor = isServer
? '#575859'
: getComputedStyle(document.documentElement).getPropertyValue('--color-text-secondary');
const chartJSThemebackgroundColor = isServer
? '#ffffff'
: getComputedStyle(document.documentElement).getPropertyValue('--color-background');
const chartJSThemebackgroundColor = isServer ? '#ffffff' : 'transparent'; //used to be white but the report selected state made it weird
ChartJS.register(
LineController,

View File

@ -58,107 +58,106 @@ const headlinePreTextAnimation = {
exit: { opacity: 0, width: 0, marginRight: 0 },
};
const LegendItemStandard = React.memo(
React.forwardRef<
HTMLDivElement,
{
onClickItem: BusterChartLegendProps['onClickItem'];
onHoverItemPreflight: (hover: boolean) => void;
onFocusItem: (() => void) | undefined;
item: BusterChartLegendItem;
}
>(({ onClickItem, onHoverItemPreflight, onFocusItem, item }, ref) => {
const clickable = onClickItem !== undefined;
const { formattedName, inactive, headline } = item;
const hasHeadline = headline?.type;
const LegendItemStandard = React.forwardRef<
HTMLDivElement,
{
onClickItem: BusterChartLegendProps['onClickItem'];
onHoverItemPreflight: (hover: boolean) => void;
onFocusItem: (() => void) | undefined;
item: BusterChartLegendItem;
}
>(({ onClickItem, onHoverItemPreflight, onFocusItem, item }, ref) => {
const clickable = onClickItem !== undefined;
const { formattedName, inactive, headline } = item;
const hasHeadline = headline?.type;
const headlinePreText = useMemo(() => {
if (hasHeadline && headline.type) return headlineTypeToText[headline.type];
return '';
}, [hasHeadline, headline]);
const headlinePreText = useMemo(() => {
if (hasHeadline && headline.type) return headlineTypeToText[headline.type];
return '';
}, [hasHeadline, headline]);
const onClickItemHandler = useMemoizedFn(() => {
if (onClickItem) onClickItem(item);
});
const onClickItemHandler = useMemoizedFn((e: React.MouseEvent<HTMLDivElement>) => {
e.stopPropagation();
if (onClickItem) onClickItem(item);
});
const onMouseEnterHandler = useMemoizedFn(() => {
if (onHoverItemPreflight) onHoverItemPreflight(true);
});
const onMouseEnterHandler = useMemoizedFn(() => {
if (onHoverItemPreflight) onHoverItemPreflight(true);
});
const onMouseLeaveHandler = useMemoizedFn(() => {
if (onHoverItemPreflight) onHoverItemPreflight(false);
});
const onMouseLeaveHandler = useMemoizedFn(() => {
if (onHoverItemPreflight) onHoverItemPreflight(false);
});
const itemWrapperAnimation = useMemo(() => {
return {
height: hasHeadline ? 38 : 24,
borderRadius: hasHeadline ? 8 : 4,
};
}, [hasHeadline]);
const itemWrapperAnimation = useMemo(() => {
return {
height: hasHeadline ? 38 : 24,
borderRadius: hasHeadline ? 8 : 4,
};
}, [hasHeadline]);
return (
<motion.div
ref={ref}
initial={false}
animate={itemWrapperAnimation}
onClick={onClickItemHandler}
onMouseEnter={onMouseEnterHandler}
onMouseLeave={onMouseLeaveHandler}
className={cn(
'flex h-[24px] flex-col justify-center space-y-0 rounded-sm px-2.5',
clickable && 'transition-background hover:bg-item-hover cursor-pointer duration-100'
)}
>
<AnimatePresence initial={false}>
{hasHeadline && (
<motion.div {...headlineAnimation} className="flex items-center space-x-1.5">
<span
className={cn(
'text-[15px] leading-none font-semibold!',
!inactive ? 'text-foreground' : 'text-text-secondary'
)}
>
{headline?.titleAmount}
</span>
</motion.div>
)}
</AnimatePresence>
<div
className={cn('flex flex-nowrap items-center space-x-1.5 whitespace-nowrap', {
clickable: clickable,
})}
>
<LegendItemDot
size={!hasHeadline ? 'default' : 'sm'}
onFocusItem={onFocusItem}
color={item.color}
type={item.type}
inactive={item.inactive}
/>
{/*We use text 13px because blake modified the base in different envs */}
<div
className={cn(
'flex max-w-[185px] items-center truncate text-base transition-all duration-100 select-none',
!inactive ? 'text-foreground' : 'text-text-secondary'
)}
>
<AnimatePresence mode="wait" initial={false}>
{headlinePreText && (
<motion.div
key={hasHeadline ? 'hasHeadline' : 'noHeadline'}
{...headlinePreTextAnimation}
>
{headlinePreText}
</motion.div>
return (
<motion.div
ref={ref}
initial={false}
animate={itemWrapperAnimation}
onClick={onClickItemHandler}
onMouseEnter={onMouseEnterHandler}
onMouseLeave={onMouseLeaveHandler}
className={cn(
'flex h-[24px] flex-col justify-center space-y-0 rounded-sm px-2.5',
clickable && 'transition-background hover:bg-item-hover cursor-pointer duration-100'
)}
>
<AnimatePresence initial={false}>
{hasHeadline && (
<motion.div {...headlineAnimation} className="flex items-center space-x-1.5">
<span
className={cn(
'text-[15px] leading-none font-semibold!',
!inactive ? 'text-foreground' : 'text-text-secondary'
)}
</AnimatePresence>
>
{headline?.titleAmount}
</span>
</motion.div>
)}
</AnimatePresence>
<span>{formattedName}</span>
</div>
<div
className={cn('flex flex-nowrap items-center space-x-1.5 whitespace-nowrap', {
clickable: clickable,
})}
>
<LegendItemDot
size={!hasHeadline ? 'default' : 'sm'}
onFocusItem={onFocusItem}
color={item.color}
type={item.type}
inactive={item.inactive}
/>
{/*We use text 13px because blake modified the base in different envs */}
<div
className={cn(
'flex max-w-[185px] items-center truncate text-base transition-all duration-100 select-none',
!inactive ? 'text-foreground' : 'text-text-secondary'
)}
>
<AnimatePresence mode="wait" initial={false}>
{headlinePreText && (
<motion.div
key={hasHeadline ? 'hasHeadline' : 'noHeadline'}
{...headlinePreTextAnimation}
>
{headlinePreText}
</motion.div>
)}
</AnimatePresence>
<span>{formattedName}</span>
</div>
</motion.div>
);
})
);
</div>
</motion.div>
);
});
LegendItemStandard.displayName = 'LegendItemStandard';