fix: replace react-tooltip with AppTooltip and refactor MenuItemAvatar (#17846)

This PR addresses TODO comments and improves code quality:

### 1. PullRequestItem.tsx
- Replaced `react-tooltip` with `twenty-ui` `AppTooltip` component
- Removed TODO comment
- Uses internal component library for consistency

### 2. MenuItemAvatar.tsx  
- Refactored to use `MenuItem` internally, eliminating code duplication
- Removed about 63 lines of duplicate code
- Removed TODO comment as the merge is now complete

---------

Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
This commit is contained in:
kpdev
2026-02-13 08:12:16 -08:00
committed by GitHub
parent a48b69d1e5
commit cda70a70ca
3 changed files with 38 additions and 64 deletions
@@ -1,14 +1,7 @@
import { useTheme } from '@emotion/react';
import { Avatar, type AvatarProps, IconChevronRight } from '@ui/display';
import { LightIconButtonGroup } from '@ui/input';
import { type MenuItemIconButton } from '@ui/navigation/menu/menu-item/components/MenuItem';
import { MenuItemLeftContent } from '@ui/navigation/menu/menu-item/internals/components/MenuItemLeftContent';
import { Avatar, type AvatarProps } from '@ui/display';
import { type MenuItemIconButton, MenuItem } from '@ui/navigation/menu/menu-item/components/MenuItem';
import { type MouseEvent, type ReactNode } from 'react';
import { isDefined } from 'twenty-shared/utils';
import {
StyledHoverableMenuItemBase,
StyledMenuItemLeftContent,
} from '../internals/components/StyledMenuItemBase';
import { type MenuItemAccent } from '../types/MenuItemAccent';
export type MenuItemAvatarProps = {
@@ -30,12 +23,12 @@ export type MenuItemAvatarProps = {
contextualText?: ReactNode;
};
// TODO: merge with MenuItem
export const MenuItemAvatar = ({
accent = 'default',
className,
iconButtons,
isIconDisplayedOnHoverOnly = true,
isTooltipOpen,
onClick,
onMouseEnter,
onMouseLeave,
@@ -45,56 +38,31 @@ export const MenuItemAvatar = ({
text,
contextualText,
}: MenuItemAvatarProps) => {
const theme = useTheme();
const showIconButtons = Array.isArray(iconButtons) && iconButtons.length > 0;
const handleMenuItemClick = (event: MouseEvent<HTMLDivElement>) => {
if (!onClick) return;
event.preventDefault();
event.stopPropagation();
onClick?.(event);
};
return (
<StyledHoverableMenuItemBase
data-testid={testId ?? undefined}
onClick={handleMenuItemClick}
className={className}
<MenuItem
accent={accent}
className={className}
iconButtons={iconButtons}
isIconDisplayedOnHoverOnly={isIconDisplayedOnHoverOnly}
isTooltipOpen={isTooltipOpen}
LeftComponent={
isDefined(avatar) ? (
<Avatar
placeholder={avatar.placeholder}
avatarUrl={avatar.avatarUrl}
placeholderColorSeed={avatar.placeholderColorSeed}
size={avatar.size}
type={avatar.type}
/>
) : undefined
}
onClick={onClick}
onMouseEnter={onMouseEnter}
onMouseLeave={onMouseLeave}
>
<StyledMenuItemLeftContent>
<MenuItemLeftContent
LeftIcon={undefined}
LeftComponent={
isDefined(avatar) ? (
<Avatar
placeholder={avatar.placeholder}
avatarUrl={avatar.avatarUrl}
placeholderColorSeed={avatar.placeholderColorSeed}
size={avatar.size}
type={avatar.type}
/>
) : undefined
}
text={text}
contextualText={contextualText}
/>
</StyledMenuItemLeftContent>
<div className="hoverable-buttons">
{showIconButtons && (
<LightIconButtonGroup iconButtons={iconButtons} size="small" />
)}
</div>
{hasSubMenu && (
<IconChevronRight
size={theme.icon.size.sm}
color={theme.font.color.tertiary}
/>
)}
</StyledHoverableMenuItemBase>
testId={testId}
text={text}
contextualText={contextualText}
hasSubMenu={hasSubMenu}
/>
);
};
@@ -1,13 +1,10 @@
import { Tooltip } from 'react-tooltip';
import styled from '@emotion/styled';
import { format } from 'date-fns';
import { PullRequestIcon } from '@/app/_components/ui/icons/SvgIcons';
import { Theme } from '@/app/_components/ui/theme/theme';
import { formatIntoRelativeDate } from '@/shared-utils/formatIntoRelativeDate';
// TODO: use twenty-ui Tooltip
const StyledTooltip = styled(Tooltip)``;
import { AppTooltip } from 'twenty-ui/display';
const Item = styled.div`
display: flex;
@@ -89,7 +86,8 @@ export const PullRequestItem = ({
<StyledDescription>
<StyledPrLink
href={'https://github.com/twentyhq/twenty/pull/' + prNumber}
target="__blank"
target="_blank"
rel="noopener noreferrer"
>
#{prNumber}
</StyledPrLink>{' '}
@@ -97,7 +95,7 @@ export const PullRequestItem = ({
<span id={`date-${prNumber}`}>
{formatIntoRelativeDate(mergedAt ? mergedAt : createdAt)}
</span>
<StyledTooltip
<AppTooltip
anchorSelect={`#date-${prNumber}`}
content={format(
new Date(mergedAt ? mergedAt : createdAt),
@@ -2,8 +2,9 @@
import { useState } from 'react';
import createCache from '@emotion/cache';
import { CacheProvider } from '@emotion/react';
import { CacheProvider, ThemeProvider } from '@emotion/react';
import { useServerInsertedHTML } from 'next/navigation';
import { THEME_LIGHT } from 'twenty-ui/theme';
export default function RootStyleRegistry({
children,
@@ -47,5 +48,12 @@ export default function RootStyleRegistry({
);
});
return <CacheProvider value={cache}>{children}</CacheProvider>;
return (
<CacheProvider value={cache}>
<ThemeProvider theme={THEME_LIGHT}>
{/* Cast for ReactNode type compatibility between Next and Emotion's @types/react */}
{children as any}
</ThemeProvider>
</CacheProvider>
);
}