UNPKG

@loke/ui

Version:
2 lines (1 loc) 3.33 kB
import{createContextScope}from"@loke/ui/context";import{Primitive}from"@loke/ui/primitive";import{useCallbackRef}from"@loke/ui/use-callback-ref";import{useIsHydrated}from"@loke/ui/use-is-hydrated";import{useLayoutEffect}from"@loke/ui/use-layout-effect";import{forwardRef,useEffect,useRef,useState}from"react";import{jsx}from"react/jsx-runtime";var AVATAR_NAME="Avatar",[createAvatarContext,createAvatarScope]=createContextScope(AVATAR_NAME),[AvatarProvider,useAvatarContext]=createAvatarContext(AVATAR_NAME),Avatar=forwardRef((props,forwardedRef)=>{let{__scopeAvatar,...avatarProps}=props,[imageLoadingStatus,setImageLoadingStatus]=useState("idle");return jsx(AvatarProvider,{imageLoadingStatus,onImageLoadingStatusChange:setImageLoadingStatus,scope:__scopeAvatar,children:jsx(Primitive.span,{...avatarProps,ref:forwardedRef})})});Avatar.displayName=AVATAR_NAME;var IMAGE_NAME="AvatarImage",AvatarImage=forwardRef((props,forwardedRef)=>{let{__scopeAvatar,src,onLoadingStatusChange=()=>{},...imageProps}=props,context=useAvatarContext(IMAGE_NAME,__scopeAvatar),imageLoadingStatus=useImageLoadingStatus(src,imageProps),handleLoadingStatusChange=useCallbackRef((status)=>{onLoadingStatusChange(status),context.onImageLoadingStatusChange(status)});return useLayoutEffect(()=>{if(imageLoadingStatus!=="idle")handleLoadingStatusChange(imageLoadingStatus)},[imageLoadingStatus,handleLoadingStatusChange]),imageLoadingStatus==="loaded"?jsx(Primitive.img,{...imageProps,ref:forwardedRef,src}):null});AvatarImage.displayName=IMAGE_NAME;var FALLBACK_NAME="AvatarFallback",AvatarFallback=forwardRef((props,forwardedRef)=>{let{__scopeAvatar,delayMs,...fallbackProps}=props,context=useAvatarContext(FALLBACK_NAME,__scopeAvatar),[canRender,setCanRender]=useState(delayMs===void 0);return useEffect(()=>{if(delayMs!==void 0){let timerId=window.setTimeout(()=>setCanRender(!0),delayMs);return()=>window.clearTimeout(timerId)}},[delayMs]),canRender&&context.imageLoadingStatus!=="loaded"?jsx(Primitive.span,{...fallbackProps,ref:forwardedRef}):null});AvatarFallback.displayName=FALLBACK_NAME;function resolveLoadingStatus(image,src){if(!image)return"idle";if(!src)return"error";if(image.src!==src)image.src=src;return image.complete&&image.naturalWidth>0?"loaded":"loading"}function useImageLoadingStatus(src,{referrerPolicy,crossOrigin}){let isHydrated=useIsHydrated(),imageRef=useRef(null),image=(()=>{if(!isHydrated)return null;if(!imageRef.current)imageRef.current=new window.Image;return imageRef.current})(),[loadingStatus,setLoadingStatus]=useState(()=>resolveLoadingStatus(image,src));return useLayoutEffect(()=>{setLoadingStatus(resolveLoadingStatus(image,src))},[image,src]),useLayoutEffect(()=>{let updateStatus=(status)=>()=>{setLoadingStatus(status)};if(!image)return;let handleLoad=updateStatus("loaded"),handleError=updateStatus("error");if(image.addEventListener("load",handleLoad),image.addEventListener("error",handleError),referrerPolicy)image.referrerPolicy=referrerPolicy;if(typeof crossOrigin==="string")image.crossOrigin=crossOrigin;return()=>{image.removeEventListener("load",handleLoad),image.removeEventListener("error",handleError)}},[image,crossOrigin,referrerPolicy]),loadingStatus}var Root=Avatar,Image=AvatarImage,Fallback=AvatarFallback;export{createAvatarScope,Root,Image,Fallback,AvatarImage,AvatarFallback,Avatar};