1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-02-09 00:18:00 +01:00

chore: new user avatar tooltip (#9050)

https://linear.app/unleash/issue/2-3109/improve-avatar-tooltip

I noticed our current user avatar tooltip is a bit poor.

This PR tries to improve it a bit using only the data we already have
available, without any drastic changes.

### Before


![image](https://github.com/user-attachments/assets/2eeb87ca-791a-422d-9e8b-27537b6f38ef)

### After


![image](https://github.com/user-attachments/assets/38bc1bb1-9187-4bf8-88ec-e57f4c95a0c8)

### Other examples after the changes


![image](https://github.com/user-attachments/assets/f25172aa-24aa-4c8c-8d46-65e2b61a33b9)


![image](https://github.com/user-attachments/assets/a420cafb-e690-4495-bf7f-b7b3d3ddf311)


![image](https://github.com/user-attachments/assets/66b2efa3-269e-4384-96a5-1b089333a9d1)


![image](https://github.com/user-attachments/assets/7c56dcf0-b6f1-4433-840a-e975baec6785)

---------

Co-authored-by: Thomas Heartman <thomas@getunleash.io>
This commit is contained in:
Nuno Góis 2025-01-03 10:26:02 +00:00 committed by GitHub
parent 4a52247bd9
commit 7eced2962f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -1,14 +1,15 @@
import { import {
Avatar, Avatar,
type AvatarProps, type AvatarProps,
Box,
styled, styled,
type SxProps, type SxProps,
type Theme, type Theme,
} from '@mui/material'; } from '@mui/material';
import type { IUser } from 'interfaces/user'; import type { IUser } from 'interfaces/user';
import { forwardRef } from 'react'; import { forwardRef } from 'react';
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
import { HtmlTooltip } from '../HtmlTooltip/HtmlTooltip'; import { HtmlTooltip } from '../HtmlTooltip/HtmlTooltip';
const StyledAvatar = styled(Avatar)(({ theme }) => ({ const StyledAvatar = styled(Avatar)(({ theme }) => ({
width: theme.spacing(3.5), width: theme.spacing(3.5),
height: theme.spacing(3.5), height: theme.spacing(3.5),
@ -19,6 +20,23 @@ const StyledAvatar = styled(Avatar)(({ theme }) => ({
fontWeight: theme.fontWeight.bold, fontWeight: theme.fontWeight.bold,
})); }));
const StyledTooltip = styled(Box)(({ theme }) => ({
display: 'flex',
gap: theme.spacing(2),
}));
const StyledTooltipAvatar = styled(StyledAvatar)(({ theme }) => ({
width: theme.spacing(5),
height: theme.spacing(5),
fontSize: theme.fontSizes.smallBody,
}));
const StyledTooltipContent = styled(Box)({
display: 'flex',
flexDirection: 'column',
justifyContent: 'center',
});
export interface IUserAvatarProps extends AvatarProps { export interface IUserAvatarProps extends AvatarProps {
user?: Partial< user?: Partial<
Pick<IUser, 'id' | 'name' | 'email' | 'username' | 'imageUrl'> Pick<IUser, 'id' | 'name' | 'email' | 'username' | 'imageUrl'>
@ -37,8 +55,8 @@ const tooltipContent = (
} }
const [mainIdentifier, secondaryInfo] = [ const [mainIdentifier, secondaryInfo] = [
user.email || user.username,
user.name, user.name,
user.email || user.username,
]; ];
if (mainIdentifier) { if (mainIdentifier) {
@ -56,8 +74,10 @@ const TooltipSecondaryContent = styled('div')(({ theme }) => ({
color: theme.palette.text.secondary, color: theme.palette.text.secondary,
fontSize: theme.typography.body2.fontSize, fontSize: theme.typography.body2.fontSize,
})); }));
const TooltipMainContent = styled('div')(({ theme }) => ({ const TooltipMainContent = styled('div')(({ theme }) => ({
fontSize: theme.typography.body1.fontSize, fontSize: theme.typography.body1.fontSize,
overflowWrap: 'anywhere',
})); }));
export const UserAvatar = forwardRef<HTMLDivElement, IUserAvatarProps>( export const UserAvatar = forwardRef<HTMLDivElement, IUserAvatarProps>(
@ -84,29 +104,45 @@ export const UserAvatar = forwardRef<HTMLDivElement, IUserAvatarProps>(
alt={user?.name || user?.email || user?.username || 'Gravatar'} alt={user?.name || user?.email || user?.username || 'Gravatar'}
src={src || user?.imageUrl} src={src || user?.imageUrl}
> >
<ConditionallyRender {fallback ? fallback : children}
condition={Boolean(fallback)}
show={fallback}
elseShow={children}
/>
</StyledAvatar> </StyledAvatar>
); );
const tooltip = disableTooltip ? undefined : tooltipContent(user); const tooltip = disableTooltip ? undefined : tooltipContent(user);
if (tooltip) { if (tooltip) {
const { main, secondary } = tooltip;
return ( return (
<HtmlTooltip <HtmlTooltip
arrow arrow
describeChild describeChild
maxWidth={400}
title={ title={
<> <StyledTooltip>
<TooltipSecondaryContent> <StyledTooltipAvatar
{tooltip.secondary} src={src || user?.imageUrl}
</TooltipSecondaryContent> alt={
<TooltipMainContent> user?.name ||
{tooltip.main} user?.email ||
</TooltipMainContent> user?.username ||
</> 'Gravatar'
}
>
{fallback ? fallback : children}
</StyledTooltipAvatar>
<StyledTooltipContent>
{main && (
<TooltipMainContent>
{main}
</TooltipMainContent>
)}
{secondary && (
<TooltipSecondaryContent>
{secondary}
</TooltipSecondaryContent>
)}
</StyledTooltipContent>
</StyledTooltip>
} }
> >
{Avatar} {Avatar}