Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 | 268x 36441x 6894x 34478x 13792x 6896x 856x 856x 38324x 48638x 48638x 48638x 3015x 3015x 48638x 268x 19058x 19058x 268x | import React from "react";
import {
AvatarGroup as AvatarGroupRaw,
Avatar as AvatarRaw,
useAvatarGroupContext,
} from "@heroui/avatar";
import { BeamAvatar } from "~components/beam-avatar";
import { cn } from "~components/utils";
const avatarComponents: React.ComponentProps<typeof BeamAvatar>["components"] =
{
Svg: (props) => <svg {...props} />,
Mask: (props) => <mask {...props} />,
Rect: (props) => <rect {...props} />,
G: (props) => <g {...props} />,
Path: (props) => <path {...props} />,
Filter: (props) => <filter {...props} />,
FeColorMatrix: (props) => <feColorMatrix {...props} />,
};
export type Props = {
size?: "sm" | "md" | "lg";
className?: string;
dimmed?: boolean;
fallback?: React.ReactNode;
image?: {
url: string;
alt: string;
};
hashId?: string;
onPress?: () => void;
testID?: string;
};
export const useAvatarProps = ({
className,
dimmed,
fallback,
image,
hashId,
onPress,
testID = "user-avatar",
...props
}: Props): React.ComponentProps<typeof AvatarRaw> => {
const ref = React.useRef<HTMLSpanElement>(null);
const [actualSize, setActualSize] = React.useState(0);
React.useEffect(() => {
Iif (!ref.current) {
return;
}
setActualSize(Math.max(ref.current.offsetHeight, ref.current.offsetWidth));
// We calculate actual size depending on the prop
// oxlint-disable-next-line react/exhaustive-effect-dependencies
}, [props.size]);
return {
...props,
ref,
// oxlint-disable-next-line typescript/strict-boolean-expressions
fallback: fallback || (
<BeamAvatar
size={actualSize}
name={hashId ?? "unknown"}
components={avatarComponents}
dimmed={dimmed}
/>
),
imgProps: image
? {
alt: image.alt,
width: actualSize,
height: actualSize,
}
: undefined,
src: image?.url,
radius: "full",
classNames: {
fallback: "size-full",
base: cn(
// The hover=true is needed to remove default translation of avatars in avatar group
"shrink-0 bg-transparent data-[hover=true]:translate-x-0",
dimmed ? "grayscale" : undefined,
className,
),
},
onClick: onPress,
"data-testid": testID,
};
};
export const Avatar: React.FC<Props> = (props) => {
const avatarGroupContext = useAvatarGroupContext();
return <AvatarRaw {...useAvatarProps({ ...avatarGroupContext, ...props })} />;
};
export type GroupContext = {
size?: Props["size"];
};
export type GroupProps = GroupContext &
React.PropsWithChildren<{
max?: number;
className?: string;
}>;
export const AvatarGroup: React.FC<GroupProps> = AvatarGroupRaw;
|