radix-ui / primitives

Radix Primitives is an open-source UI component library for building high-quality, accessible design systems and web apps. Maintained by @workos.
https://radix-ui.com/primitives
MIT License
15.52k stars 792 forks source link

[Avatar] Avatar.Image doesn't implement lazy loading #2512

Open revuwem opened 10 months ago

revuwem commented 10 months ago

Bug report

Current Behavior

The <Avatar.Image /> accepts loading="lazy" but it actually has no effect, the image loads on page loading time.

Screenshot 2023-11-08 at 20 15 37 Screenshot 2023-11-08 at 20 09 59

Expected behavior

The <Avatar.Image /> with loading="lazy" provided loads image only when user navigates to it.

Your environment

Software Name(s) Version
Radix Package(s) @radix-ui/react-avatar ^1.0.4
React n/a
Browser
Assistive tech
Node n/a
npm/yarn
Operating System
revuwem commented 10 months ago

It looks like the useImageLoadingStatus in Avatar.tsx doesn't handle the lazy attribute for created image.

function useImageLoadingStatus(src?: string) {
  const [loadingStatus, setLoadingStatus] = React.useState<ImageLoadingStatus>('idle');

  useLayoutEffect(() => {
    if (!src) {
      setLoadingStatus('error');
      return;
    }

    let isMounted = true;
    const image = new window.Image();

    const updateStatus = (status: ImageLoadingStatus) => () => {
      if (!isMounted) return;
      setLoadingStatus(status);
    };

    setLoadingStatus('loading');
    image.onload = updateStatus('loaded');
    image.onerror = updateStatus('error');
    image.src = src;

    return () => {
      isMounted = false;
    };
  }, [src]);

  return loadingStatus;
}