From 981ee6a2d7604ea0ded1f3354385d288875bde2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emmanuel=20Hern=C3=A1ndez=20Baz=C3=A1n?= <126545166+emmanuelhb56@users.noreply.github.com> Date: Thu, 25 Jun 2026 05:12:11 -0600 Subject: [PATCH] fix: stabilize tooltip anchor ID with useRef to prevent hover glitch (#21888) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Context Tooltip components were generating a new anchor ID on every render. This caused a flicker/glitch when hovering: the tooltip would briefly disappear and reappear because React reconciled the changed ID as a different element. ## Solution Changed the anchor ID generation from inline (re-created every render) to `useRef` (stable across renders). The ID is now created once on mount and stays the same for the lifetime of the component. ## Test plan - [x] Hover over any element with a tooltip — no flicker or disappear/reappear behavior - [x] Multiple tooltips on the same page still work independently 🤖 Generated with [Claude Code](https://claude.ai/claude-code) Review in cubic --------- Co-authored-by: Emmanuel Hernandez Co-authored-by: Charles Bochet --- .../show-page/components/ShowPageSummaryCard.tsx | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/packages/twenty-front/src/modules/ui/layout/show-page/components/ShowPageSummaryCard.tsx b/packages/twenty-front/src/modules/ui/layout/show-page/components/ShowPageSummaryCard.tsx index 6082d30ba2..d4b4702c77 100644 --- a/packages/twenty-front/src/modules/ui/layout/show-page/components/ShowPageSummaryCard.tsx +++ b/packages/twenty-front/src/modules/ui/layout/show-page/components/ShowPageSummaryCard.tsx @@ -1,7 +1,13 @@ import { SKELETON_LOADER_HEIGHT_SIZES } from '@/activities/components/SkeletonLoader'; import { styled } from '@linaria/react'; import { Trans } from '@lingui/react/macro'; -import { type ChangeEvent, type ReactNode, useContext, useRef } from 'react'; +import { + type ChangeEvent, + type ReactNode, + useContext, + useId, + useRef, +} from 'react'; import Skeleton, { SkeletonTheme } from 'react-loading-skeleton'; import { isDefined } from 'twenty-shared/utils'; import { Avatar, type AvatarType } from 'twenty-ui/data-display'; @@ -9,7 +15,6 @@ import { type IconComponent } from 'twenty-ui/icon'; import { AppTooltip } from 'twenty-ui/surfaces'; import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue'; import { ThemeContext, themeCssVariables } from 'twenty-ui/theme-constants'; -import { v4 as uuidV4 } from 'uuid'; import { dateLocaleState } from '~/localization/states/dateLocaleState'; import { beautifyExactDateTime, @@ -125,7 +130,8 @@ export const ShowPageSummaryCard = ({ const beautifiedCreatedAt = date !== '' ? beautifyPastDateRelativeToNow(date, localeCatalog) : ''; const exactCreatedAt = date !== '' ? beautifyExactDateTime(date) : ''; - const dateElementId = `date-id-${uuidV4()}`; + const instanceId = useId(); + const dateElementId = `date-id-${instanceId}`; const inputFileRef = useRef(null); const onFileChange = (e: ChangeEvent) => { if (isDefined(e.target.files)) onUploadPicture?.(e.target.files[0]);