All files / src/components/shared/profile-image index.tsx

100% Statements 60/60
100% Branches 1/1
100% Functions 1/1
100% Lines 60/60

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 611x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 69x 69x 69x 69x 69x 69x 69x 69x 69x 69x 69x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x  
import type { ImageProps } from 'next/image';
 
import { cva, type VariantProps } from 'class-variance-authority';
import { DEFAULT_PROFILE_IMAGE } from 'constants/default-images';
 
import { ImageWithFallback } from '@/components/ui';
import { cn } from '@/lib/utils';
 
const profileVariants = cva('object-cover overflow-hidden rounded-full select-none', {
  variants: {
    size: {
      xl: 'size-24',
      lg: 'size-16',
      md: 'size-12',
      sm: 'size-10',
      xs: 'size-4',
    },
  },
});
 
interface Props extends Omit<ImageProps, 'src' | 'onError' | 'alt'> {
  src: string | null;
  size: NonNullable<VariantProps<typeof profileVariants>['size']>;
}
 
export const ProfileImage = ({ src, size, className, ...rest }: Props) => {
  return (
    <ImageWithFallback
      {...rest}
      {...DEFAULT_WIDTH_HEIGHT[size]}
      className={cn(profileVariants({ size }), className)}
      alt='프로필 이미지'
      fallbackSrc={DEFAULT_PROFILE_IMAGE}
      src={src}
    />
  );
};
 
const DEFAULT_WIDTH_HEIGHT = Object.freeze({
  xl: {
    width: 96,
    height: 96,
  },
  lg: {
    width: 64,
    height: 64,
  },
  md: {
    width: 48,
    height: 48,
  },
  sm: {
    width: 40,
    height: 40,
  },
  xs: {
    width: 16,
    height: 16,
  },
});