forked from
slices.network/slices
Highly ambitious ATProtocol AppView service and sdks
1import { ActorAvatar } from "./ActorAvatar.tsx";
2import { Text } from "./Text.tsx";
3import { cn } from "../../utils/cn.ts";
4import type { NetworkSlicesWaitlistDefsRequestView } from "../../client.ts";
5
6interface AvatarStackProps {
7 requests: NetworkSlicesWaitlistDefsRequestView[];
8 maxDisplay?: number;
9 size?: number;
10 className?: string;
11}
12
13export function AvatarStack({
14 requests,
15 maxDisplay = 20,
16 size = 24,
17 className,
18}: AvatarStackProps) {
19 const displayedRequests = requests.slice(0, maxDisplay);
20 const remainingCount = requests.length - maxDisplay;
21 const overlapClass = size === 32 ? "-ml-2.5" : "-ml-2";
22
23 return (
24 <div className={cn("flex justify-center", className)}>
25 {displayedRequests.map((request, index) => (
26 <div
27 key={index}
28 className={cn(
29 "relative transition-transform duration-200 hover:scale-110 hover:z-10",
30 index > 0 && overlapClass
31 )}
32 >
33 <ActorAvatar
34 profile={request.profile || { handle: "user" }}
35 size={size}
36 className="border-2 border-white dark:border-zinc-800 hover:border-blue-500 dark:hover:border-blue-400 transition-colors duration-200"
37 />
38 </div>
39 ))}
40 {remainingCount > 0 && (
41 <div
42 className={cn(
43 "bg-zinc-100 dark:bg-zinc-800 border-2 border-white dark:border-zinc-800 rounded-full flex items-center justify-center transition-transform duration-200 hover:scale-110 hover:z-10",
44 size === 32 ? "w-8 h-8 -ml-2.5" : "w-6 h-6 -ml-2"
45 )}
46 >
47 <Text size="xs" variant="muted">
48 +{remainingCount}
49 </Text>
50 </div>
51 )}
52 </div>
53 );
54}