Docs
Realtime Avatar Stack
Realtime Avatar Stack
Avatar stack in realtime
Installation
Folder structure
1import { cva, type VariantProps } from 'class-variance-authority'
2import * as React from 'react'
3
4import { cn } from '@/lib/utils'
5import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar'
6import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip'
7
8const avatarStackVariants = cva('flex -space-x-4 -space-y-4', {
9 variants: {
10 orientation: {
11 vertical: 'flex-row',
12 horizontal: 'flex-col',
13 },
14 },
15 defaultVariants: {
16 orientation: 'vertical',
17 },
18})
19
20export interface AvatarStackProps
21 extends React.HTMLAttributes<HTMLDivElement>, VariantProps<typeof avatarStackVariants> {
22 avatars: { name: string; image: string }[]
23 maxAvatarsAmount?: number
24}
25
26const AvatarStack = ({
27 className,
28 orientation,
29 avatars,
30 maxAvatarsAmount = 3,
31 ...props
32}: AvatarStackProps) => {
33 const shownAvatars = avatars.slice(0, maxAvatarsAmount)
34 const hiddenAvatars = avatars.slice(maxAvatarsAmount)
35
36 return (
37 <div
38 className={cn(
39 avatarStackVariants({ orientation }),
40 className,
41 orientation === 'horizontal' ? 'space-x-0' : 'space-y-0'
42 )}
43 {...props}
44 >
45 {shownAvatars.map(({ name, image }, index) => (
46 <Tooltip key={`${name}-${image}-${index}`}>
47 <TooltipTrigger asChild>
48 <Avatar className="hover:z-10">
49 <AvatarImage src={image} />
50 <AvatarFallback>
51 {name
52 ?.split(' ')
53 ?.map((word) => word[0])
54 ?.join('')
55 ?.toUpperCase()}
56 </AvatarFallback>
57 </Avatar>
58 </TooltipTrigger>
59 <TooltipContent>
60 <p>{name}</p>
61 </TooltipContent>
62 </Tooltip>
63 ))}
64
65 {hiddenAvatars.length ? (
66 <Tooltip key="hidden-avatars">
67 <TooltipTrigger asChild>
68 <Avatar>
69 <AvatarFallback>+{avatars.length - shownAvatars.length}</AvatarFallback>
70 </Avatar>
71 </TooltipTrigger>
72 <TooltipContent>
73 {hiddenAvatars.map(({ name }, index) => (
74 <p key={`${name}-${index}`}>{name}</p>
75 ))}
76 </TooltipContent>
77 </Tooltip>
78 ) : null}
79 </div>
80 )
81}
82
83export { AvatarStack, avatarStackVariants }Usage
The RealtimeAvatarStack component renders stacked avatars which are connected to Supabase Realtime. It uses the Presence feature of Supabase Realtime. You can use this to show currently online users in a chatroom, game session or collaborative app.
import { RealtimeAvatarStack } from '@/components/realtime-avatar-stack'
export default function Page() {
return (
<Header className="flex items-center justify-between">
<h1>Lumon Industries</h1>
<RealtimeAvatarStack roomName="break_room" />
</Header>
)
}Props
| Prop | Type | Default | Description |
|---|---|---|---|
roomName | string | null | The name of the Supabase Realtime room to connect to |