Files
Basilosaurusrex f027651f9b main repo
2025-11-24 18:09:40 +01:00

104 lines
3.5 KiB
JavaScript

"use client";
// packages/react/avatar/src/Avatar.tsx
import * as React from "react";
import { createContextScope } from "@radix-ui/react-context";
import { useCallbackRef } from "@radix-ui/react-use-callback-ref";
import { useLayoutEffect } from "@radix-ui/react-use-layout-effect";
import { Primitive } from "@radix-ui/react-primitive";
import { jsx } from "react/jsx-runtime";
var AVATAR_NAME = "Avatar";
var [createAvatarContext, createAvatarScope] = createContextScope(AVATAR_NAME);
var [AvatarProvider, useAvatarContext] = createAvatarContext(AVATAR_NAME);
var Avatar = React.forwardRef(
(props, forwardedRef) => {
const { __scopeAvatar, ...avatarProps } = props;
const [imageLoadingStatus, setImageLoadingStatus] = React.useState("idle");
return /* @__PURE__ */ jsx(
AvatarProvider,
{
scope: __scopeAvatar,
imageLoadingStatus,
onImageLoadingStatusChange: setImageLoadingStatus,
children: /* @__PURE__ */ jsx(Primitive.span, { ...avatarProps, ref: forwardedRef })
}
);
}
);
Avatar.displayName = AVATAR_NAME;
var IMAGE_NAME = "AvatarImage";
var AvatarImage = React.forwardRef(
(props, forwardedRef) => {
const { __scopeAvatar, src, onLoadingStatusChange = () => {
}, ...imageProps } = props;
const context = useAvatarContext(IMAGE_NAME, __scopeAvatar);
const imageLoadingStatus = useImageLoadingStatus(src, imageProps.referrerPolicy);
const handleLoadingStatusChange = useCallbackRef((status) => {
onLoadingStatusChange(status);
context.onImageLoadingStatusChange(status);
});
useLayoutEffect(() => {
if (imageLoadingStatus !== "idle") {
handleLoadingStatusChange(imageLoadingStatus);
}
}, [imageLoadingStatus, handleLoadingStatusChange]);
return imageLoadingStatus === "loaded" ? /* @__PURE__ */ jsx(Primitive.img, { ...imageProps, ref: forwardedRef, src }) : null;
}
);
AvatarImage.displayName = IMAGE_NAME;
var FALLBACK_NAME = "AvatarFallback";
var AvatarFallback = React.forwardRef(
(props, forwardedRef) => {
const { __scopeAvatar, delayMs, ...fallbackProps } = props;
const context = useAvatarContext(FALLBACK_NAME, __scopeAvatar);
const [canRender, setCanRender] = React.useState(delayMs === void 0);
React.useEffect(() => {
if (delayMs !== void 0) {
const timerId = window.setTimeout(() => setCanRender(true), delayMs);
return () => window.clearTimeout(timerId);
}
}, [delayMs]);
return canRender && context.imageLoadingStatus !== "loaded" ? /* @__PURE__ */ jsx(Primitive.span, { ...fallbackProps, ref: forwardedRef }) : null;
}
);
AvatarFallback.displayName = FALLBACK_NAME;
function useImageLoadingStatus(src, referrerPolicy) {
const [loadingStatus, setLoadingStatus] = React.useState("idle");
useLayoutEffect(() => {
if (!src) {
setLoadingStatus("error");
return;
}
let isMounted = true;
const image = new window.Image();
const updateStatus = (status) => () => {
if (!isMounted) return;
setLoadingStatus(status);
};
setLoadingStatus("loading");
image.onload = updateStatus("loaded");
image.onerror = updateStatus("error");
image.src = src;
if (referrerPolicy) {
image.referrerPolicy = referrerPolicy;
}
return () => {
isMounted = false;
};
}, [src, referrerPolicy]);
return loadingStatus;
}
var Root = Avatar;
var Image = AvatarImage;
var Fallback = AvatarFallback;
export {
Avatar,
AvatarFallback,
AvatarImage,
Fallback,
Image,
Root,
createAvatarScope
};
//# sourceMappingURL=index.mjs.map