Files
mtdb_movie/common/resources/client/ui/images/avatar.tsx
maher 703f50a09d
Some checks failed
Build / run (push) Has been cancelled
first commit
2025-10-29 11:42:25 +01:00

96 lines
2.1 KiB
TypeScript
Executable File

import clsx from 'clsx';
import React, {
ComponentProps,
ComponentPropsWithoutRef,
forwardRef,
} from 'react';
import {Link} from 'react-router-dom';
import {Tooltip} from '@common/ui/tooltip/tooltip';
import {AvatarPlaceholderIcon} from '@common/auth/ui/account-settings/avatar/avatar-placeholder-icon';
type Size = 'xs' | 'sm' | 'md' | 'lg' | 'xl' | string;
export interface AvatarProps extends ComponentPropsWithoutRef<any> {
className?: string;
src?: string;
label?: string;
circle?: boolean;
size?: Size;
link?: string;
fallback?: 'initials' | 'generic';
lazy?: boolean;
}
export const Avatar = forwardRef<HTMLImageElement, AvatarProps>(
(
{
className,
circle,
size = 'md',
src,
link,
label,
fallback = 'generic',
lazy = true,
...domProps
},
ref,
) => {
let renderedAvatar = src ? (
<img
ref={ref}
src={src}
alt={label}
loading={lazy ? 'lazy' : undefined}
className="block h-full w-full object-cover"
/>
) : (
<div className="h-full w-full bg-alt dark:bg-chip">
<AvatarPlaceholderIcon
viewBox="0 0 48 48"
className="h-full w-full text-muted"
/>
</div>
);
if (label) {
renderedAvatar = <Tooltip label={label}>{renderedAvatar}</Tooltip>;
}
const wrapperProps: ComponentProps<any> = {
...domProps,
className: clsx(
className,
'relative block overflow-hidden select-none flex-shrink-0',
getSizeClassName(size),
circle ? 'rounded-full' : 'rounded',
),
};
return link ? (
<Link {...wrapperProps} to={link}>
{renderedAvatar}
</Link>
) : (
<div {...wrapperProps}>{renderedAvatar}</div>
);
},
);
function getSizeClassName(size: Size) {
switch (size) {
case 'xs':
return 'w-18 h-18';
case 'sm':
return 'w-24 h-24';
case 'md':
return 'w-32 h-32';
case 'lg':
return 'w-40 h-40';
case 'xl':
return 'w-60 h-60';
// allow overriding with custom classNames
default:
return size;
}
}