From ca2952e604d60fc99951e8d9234992b7bd90c9fe Mon Sep 17 00:00:00 2001 From: Dominik Buszowiecki Date: Mon, 6 Jul 2026 13:47:55 -0400 Subject: [PATCH] fix(replays): Fix web vital tooltip rendering in the replay timeline Web vital markers in the replay timeline render an expandable JSON block plus an "All Web Vitals" link. In the default 291px tooltip the JSON column was squeezed so narrow that even a short key like "value" wrapped to two characters per line, and the nowrap link could overflow the tooltip. Widen the tooltip to 400px only for web vital frames (other breadcrumb tooltips keep their width), and stack the link below the full-width JSON block so it can never be pushed outside the tooltip. --- .../replays/breadcrumbs/breadcrumbWebVital.tsx | 5 +++-- .../replays/breadcrumbs/replayTimelineEvents.tsx | 13 ++++++++++--- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/static/app/components/replays/breadcrumbs/breadcrumbWebVital.tsx b/static/app/components/replays/breadcrumbs/breadcrumbWebVital.tsx index f045e1674c38..d2e7a3ad0f1b 100644 --- a/static/app/components/replays/breadcrumbs/breadcrumbWebVital.tsx +++ b/static/app/components/replays/breadcrumbs/breadcrumbWebVital.tsx @@ -102,8 +102,8 @@ export function BreadcrumbWebVital({ } return ( - - + + { @@ -156,6 +156,7 @@ const SelectorButton = styled(Button)` `; const NoMarginWrapper = styled(Flex)` + width: 100%; pre { margin: 0; flex: 1; diff --git a/static/app/components/replays/breadcrumbs/replayTimelineEvents.tsx b/static/app/components/replays/breadcrumbs/replayTimelineEvents.tsx index ea4cf55fca9d..c1b3ef0b7f16 100644 --- a/static/app/components/replays/breadcrumbs/replayTimelineEvents.tsx +++ b/static/app/components/replays/breadcrumbs/replayTimelineEvents.tsx @@ -13,6 +13,7 @@ import {getFrameDetails} from 'sentry/utils/replays/getFrameDetails'; import {useActiveReplayTab} from 'sentry/utils/replays/hooks/useActiveReplayTab'; import {useCrumbHandlers} from 'sentry/utils/replays/hooks/useCrumbHandlers'; import type {ReplayFrame} from 'sentry/utils/replays/types'; +import {isWebVitalFrame} from 'sentry/utils/replays/types'; import type {GraphicsVariant} from 'sentry/utils/theme'; const NODE_SIZES = [8, 12, 16]; @@ -106,14 +107,20 @@ function Event({ ); + // Web vital frames render an expandable JSON block that needs more room than + // the default tooltip width, otherwise its content wraps to a very tall sliver. + const hasWebVitalFrame = frames.some(isWebVitalFrame); + const tooltipWidth = hasWebVitalFrame ? 400 : 291; + const mobileMaxWidth = hasWebVitalFrame ? 300 : 220; + const overlayStyle = css` /* We make sure to override existing styles */ padding: ${theme.space.xs} !important; - max-width: 291px !important; - width: 291px; + max-width: ${tooltipWidth}px !important; + width: ${tooltipWidth}px; @media screen and (max-width: ${theme.breakpoints.sm}) { - max-width: 220px !important; + max-width: ${mobileMaxWidth}px !important; } `;