@lobehub/ui
Version:
Lobe UI is an open-source UI component library for building AIGC web apps
99 lines (98 loc) • 3.65 kB
JavaScript
"use client";
import Center from "../../Flex/Center.mjs";
import { safeReadableColor } from "../../utils/safeReadableColor.mjs";
import Icon from "../../Icon/Icon.mjs";
import FluentEmoji from "../../FluentEmoji/FluentEmoji.mjs";
import { styles, variants } from "./style.mjs";
import { calculateEmojiSize, formatAvatarText, hasValidBackground, isDefaultAntAvatar } from "./utils.mjs";
import { memo, useMemo, useState } from "react";
import { jsx, jsxs } from "react/jsx-runtime";
import { cssVar, cx } from "antd-style";
import { Loader2 } from "lucide-react";
import { getEmoji } from "@lobehub/fluent-emoji";
//#region src/base-ui/Avatar/Avatar.tsx
const Avatar = memo(({ alt, animation, avatar, background, bordered, borderedColor, className, classNames, crossOrigin, draggable = false, emojiScaleWithBackground = true, loading, ref, shadow, shape = "square", size = 48, sliceText = true, style, styles: customStyles, title, tooltipProps, unoptimized, variant = "borderless", ...rest }) => {
const isStringAvatar = typeof avatar === "string";
const [isImgError, setIsImgError] = useState(false);
const isUrlOrElement = useMemo(() => isDefaultAntAvatar(avatar), [avatar]);
const emoji = useMemo(() => avatar && isStringAvatar && !isUrlOrElement ? getEmoji(avatar) : void 0, [
avatar,
isStringAvatar,
isUrlOrElement
]);
const text = String(isUrlOrElement ? title : avatar);
const imgAlt = alt || title || "avatar";
const hasBackground = hasValidBackground(background);
const showImage = isUrlOrElement && isStringAvatar && !isImgError;
const showElement = isUrlOrElement && !isStringAvatar && !isImgError;
const customAvatar = useMemo(() => emoji ? /* @__PURE__ */ jsx(FluentEmoji, {
emoji,
size: calculateEmojiSize(size, hasBackground, emojiScaleWithBackground),
type: animation ? "anim" : "3d",
unoptimized
}) : formatAvatarText(text || title, sliceText), [
animation,
emoji,
hasBackground,
size,
sliceText,
text,
title,
unoptimized,
emojiScaleWithBackground
]);
return /* @__PURE__ */ jsxs("div", {
...rest,
className: cx(variants({
shadow,
variant
}), className, classNames?.root),
ref,
style: {
backgroundColor: isUrlOrElement && !isImgError || emoji ? background : background || cssVar.colorBorder,
borderRadius: shape === "circle" ? "50%" : size < 24 ? "33%" : Math.max(size / 6, 2),
boxShadow: bordered ? `${cssVar.colorBgLayout} 0 0 0 2px, ${borderedColor || cssVar.colorTextTertiary} 0 0 0 4px` : void 0,
color: safeReadableColor(background || cssVar.colorBorder),
cursor: rest?.onClick ? "pointer" : void 0,
fontSize: size * (emoji ? .7 : .5),
height: size,
width: size,
...style,
...customStyles?.root
},
children: [
loading && /* @__PURE__ */ jsx(Center, {
className: cx(styles.loading, classNames?.loading),
flex: "none",
height: "100%",
style: customStyles?.loading,
width: "100%",
children: /* @__PURE__ */ jsx(Icon, {
spin: true,
icon: Loader2
})
}),
typeof avatar === "string" && showImage && /* @__PURE__ */ jsx("img", {
alt: imgAlt,
className: cx(styles.img, classNames?.img),
crossOrigin,
draggable,
height: size,
loading: "lazy",
src: avatar,
style: customStyles?.img,
width: size,
onError: () => setIsImgError(true)
}),
!showImage && /* @__PURE__ */ jsx("span", {
className: cx(styles.content, classNames?.content),
style: customStyles?.content,
children: showElement ? avatar : customAvatar
})
]
});
});
Avatar.displayName = "Avatar";
//#endregion
export { Avatar as default };
//# sourceMappingURL=Avatar.mjs.map