WeightedBubble Component

The WeightedBubble component displays a group of user avatars arranged in a bubble layout where each avatar's size and position is determined by its weight. Higher-weighted users appear larger and closer to the center, creating a visual hierarchy that represents relative importance or activity.

Usage

Basic Usage

Pass an array of users with weights to create a weighted bubble visualization.

E
D
C
B
A
import { WeightedBubble } from "@228-co/reef/components";
import type { WeightedUserDetails } from "@228-co/reef/user-details";

const users: WeightedUserDetails[] = [
  { avatarId: "user1", displayName: "Alice", weight: 50 },
  { avatarId: "user2", displayName: "Bob", weight: 30 },
  { avatarId: "user3", displayName: "Charlie", weight: 20 },
  { avatarId: "user4", displayName: "Diana", weight: 15 },
  { avatarId: "user5", displayName: "Eve", weight: 10 },
];

<WeightedBubble users={users} />

Single User

With a single user, the avatar takes center position at maximum size.

S
const singleUser: WeightedUserDetails[] = [
  { avatarId: "solo", displayName: "Solo User", weight: 100 },
];

<WeightedBubble users={singleUser} />

Two Users

With two users, the higher-weighted user is centered and larger.

S
F
const twoUsers: WeightedUserDetails[] = [
  { avatarId: "first", displayName: "First User", weight: 70 },
  { avatarId: "second", displayName: "Second User", weight: 30 },
];

<WeightedBubble users={twoUsers} />

Many Users (Overflow Handling)

When more than 8 users are provided, the component displays the top 7 by weight and groups the remaining users into a "+N" indicator. The overflow indicator's size is proportional to the combined weight of the hidden users.

G
F
E
D
C
+
B
A
const manyUsers: WeightedUserDetails[] = [
  { avatarId: "user1", displayName: "Alice", weight: 100 },
  { avatarId: "user2", displayName: "Bob", weight: 80 },
  { avatarId: "user3", displayName: "Charlie", weight: 60 },
  // ... 9 more users
];

// Displays top 7 users + "+5" indicator
<WeightedBubble users={manyUsers} />

Props

NameTypeDefaultDescription
usersWeightedUserDetails[]required

Array of users with weights. Each user has avatarId, displayName, optional profilePicture, optional presence, and a weight number.

WeightedUserDetails Type

Each user in the array must conform to the WeightedUserDetails type, which extends the base UserDetails with a weight property.

NameTypeDefaultDescription
avatarIdstringrequired

Unique identifier for the user's avatar.

displayNamestringrequired

The user's display name, shown in tooltips and aria labels.

profilePicturestringundefined

URL to the user's profile picture.

presencebooleanundefined

Whether the user is currently online/present.

weightnumberrequired

Numeric weight determining the user's visual prominence. Higher weights result in larger avatars positioned closer to the center.

Layout Algorithm

The WeightedBubble uses a circle-packing algorithm to position avatars:

Center placement - The highest-weighted user is placed at the center of the container.

Size scaling - Avatar sizes are proportional to the square root of their weight ratio (area-based scaling).

Collision detection - Each avatar is positioned to avoid overlapping with existing avatars while staying as close to the center as possible.

Size constraints - Avatars have minimum (15%) and maximum (50%) size constraints relative to the container.

Accessibility

The component includes an aria-label that lists all user display names in the group, ensuring screen readers can announce the full group membership.

// Generated aria-label example:
// "group: Alice, Bob, Charlie, Diana, Eve"

Related Components

Avatar - The underlying avatar component used for each user.

AvatarList - For displaying avatars in a linear horizontal list.

MultipleAvatars - For displaying stacked/overlapping avatars.