import clsx from 'clsx'; import { motion, MotionConfigProps } from 'motion/react'; import { type ImgHTMLAttributes } from 'react'; import { Img } from 'react-image'; import { InView } from 'react-intersection-observer'; import styles from './image.module.css'; import { animationProps } from '/@/shared/components/animations/animation-props'; import { Icon } from '/@/shared/components/icon/icon'; import { Skeleton } from '/@/shared/components/skeleton/skeleton'; interface ImageContainerProps extends MotionConfigProps { children: React.ReactNode; className?: string; enableAnimation?: boolean; } interface ImageLoaderProps { className?: string; } interface ImageProps extends Omit, 'src'> { containerClassName?: string; enableAnimation?: boolean; imageContainerProps?: Omit; includeLoader?: boolean; includeUnloader?: boolean; src: string | string[] | undefined; thumbHash?: string; } interface ImageUnloaderProps { className?: string; } const FALLBACK_SVG = 'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIzMDAiIGhlaWdodD0iMzAwIj48ZmlsdGVyIGlkPSJhIiB4PSIwIiB5PSIwIj48ZmVUdXJidWxlbmNlIHR5cGU9ImZyYWN0YWxOb2lzZSIgYmFzZUZyZXF1ZW5jeT0iLjc1IiBzdGl0Y2hUaWxlcz0ic3RpdGNoIi8+PGZlQ29sb3JNYXRyaXggdHlwZT0ic2F0dXJhdGUiIHZhbHVlcz0iMCIvPjwvZmlsdGVyPjxwYXRoIGZpbHRlcj0idXJsKCNhKSIgb3BhY2l0eT0iLjA1IiBkPSJNMCAwaDMwMHYzMDBIMHoiLz48L3N2Zz4='; export function Image({ className, containerClassName, enableAnimation, imageContainerProps, includeLoader = true, includeUnloader = true, src, }: ImageProps) { if (src) { return ( {({ inView, ref }) => (
( {children} )} loader={ includeLoader ? ( ) : null } src={inView ? src : FALLBACK_SVG} unloader={ includeUnloader ? ( ) : null } />
)}
); } return ; } function ImageContainer({ children, className, enableAnimation, ...props }: ImageContainerProps) { if (!enableAnimation) { return (
{children}
); } return ( {children} ); } function ImageLoader({ className }: ImageLoaderProps) { return (
); } function ImageUnloader({ className }: ImageUnloaderProps) { return (
); }